diff options
Diffstat (limited to 'rbutil/jztool/src/usb.c')
-rw-r--r-- | rbutil/jztool/src/usb.c | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/rbutil/jztool/src/usb.c b/rbutil/jztool/src/usb.c index c101f2be77..cfc3ba60cb 100644 --- a/rbutil/jztool/src/usb.c +++ b/rbutil/jztool/src/usb.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "jztool_private.h" | 22 | #include "jztool_private.h" |
23 | #include <stdlib.h> | 23 | #include <stdlib.h> |
24 | #include <stdbool.h> | 24 | #include <stdbool.h> |
25 | #include <string.h> | ||
25 | 26 | ||
26 | #define VR_GET_CPU_INFO 0 | 27 | #define VR_GET_CPU_INFO 0 |
27 | #define VR_SET_DATA_ADDRESS 1 | 28 | #define VR_SET_DATA_ADDRESS 1 |
@@ -145,11 +146,12 @@ void jz_usb_close(jz_usbdev* dev) | |||
145 | 146 | ||
146 | // Does an Ingenic-specific vendor request | 147 | // Does an Ingenic-specific vendor request |
147 | // Written with X1000 in mind but other Ingenic CPUs have the same commands | 148 | // Written with X1000 in mind but other Ingenic CPUs have the same commands |
148 | static int jz_usb_vendor_req(jz_usbdev* dev, int req, uint32_t arg) | 149 | static int jz_usb_vendor_req(jz_usbdev* dev, int req, uint32_t arg, |
150 | void* buffer, int buflen) | ||
149 | { | 151 | { |
150 | int rc = libusb_control_transfer(dev->handle, | 152 | int rc = libusb_control_transfer(dev->handle, |
151 | LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, | 153 | LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, |
152 | req, arg >> 16, arg & 0xffff, NULL, 0, 1000); | 154 | req, arg >> 16, arg & 0xffff, buffer, buflen, 1000); |
153 | 155 | ||
154 | if(rc < 0) { | 156 | if(rc < 0) { |
155 | jz_log(dev->jz, JZ_LOG_ERROR, "libusb_control_transfer: %s", libusb_strerror(rc)); | 157 | jz_log(dev->jz, JZ_LOG_ERROR, "libusb_control_transfer: %s", libusb_strerror(rc)); |
@@ -200,11 +202,11 @@ static int jz_usb_sendrecv(jz_usbdev* dev, bool write, uint32_t addr, | |||
200 | size_t len, void* data) | 202 | size_t len, void* data) |
201 | { | 203 | { |
202 | int rc; | 204 | int rc; |
203 | rc = jz_usb_vendor_req(dev, VR_SET_DATA_ADDRESS, addr); | 205 | rc = jz_usb_vendor_req(dev, VR_SET_DATA_ADDRESS, addr, NULL, 0); |
204 | if(rc < 0) | 206 | if(rc < 0) |
205 | return rc; | 207 | return rc; |
206 | 208 | ||
207 | rc = jz_usb_vendor_req(dev, VR_SET_DATA_LENGTH, len); | 209 | rc = jz_usb_vendor_req(dev, VR_SET_DATA_LENGTH, len, NULL, 0); |
208 | if(rc < 0) | 210 | if(rc < 0) |
209 | return rc; | 211 | return rc; |
210 | 212 | ||
@@ -242,7 +244,7 @@ int jz_usb_recv(jz_usbdev* dev, uint32_t addr, size_t len, void* data) | |||
242 | */ | 244 | */ |
243 | int jz_usb_start1(jz_usbdev* dev, uint32_t addr) | 245 | int jz_usb_start1(jz_usbdev* dev, uint32_t addr) |
244 | { | 246 | { |
245 | return jz_usb_vendor_req(dev, VR_PROGRAM_START1, addr); | 247 | return jz_usb_vendor_req(dev, VR_PROGRAM_START1, addr, NULL, 0); |
246 | } | 248 | } |
247 | 249 | ||
248 | /** \brief Execute stage2 program jumping to the specified address | 250 | /** \brief Execute stage2 program jumping to the specified address |
@@ -252,7 +254,7 @@ int jz_usb_start1(jz_usbdev* dev, uint32_t addr) | |||
252 | */ | 254 | */ |
253 | int jz_usb_start2(jz_usbdev* dev, uint32_t addr) | 255 | int jz_usb_start2(jz_usbdev* dev, uint32_t addr) |
254 | { | 256 | { |
255 | return jz_usb_vendor_req(dev, VR_PROGRAM_START2, addr); | 257 | return jz_usb_vendor_req(dev, VR_PROGRAM_START2, addr, NULL, 0); |
256 | } | 258 | } |
257 | 259 | ||
258 | /** \brief Ask device to flush CPU caches | 260 | /** \brief Ask device to flush CPU caches |
@@ -261,5 +263,29 @@ int jz_usb_start2(jz_usbdev* dev, uint32_t addr) | |||
261 | */ | 263 | */ |
262 | int jz_usb_flush_caches(jz_usbdev* dev) | 264 | int jz_usb_flush_caches(jz_usbdev* dev) |
263 | { | 265 | { |
264 | return jz_usb_vendor_req(dev, VR_FLUSH_CACHES, 0); | 266 | return jz_usb_vendor_req(dev, VR_FLUSH_CACHES, 0, NULL, 0); |
267 | } | ||
268 | |||
269 | /** \brief Ask device for CPU info string | ||
270 | * \param dev USB device | ||
271 | * \param buffer Buffer to hold the info string | ||
272 | * \param buflen Size of the buffer, in bytes | ||
273 | * \return either JZ_SUCCESS on success or a failure code | ||
274 | * | ||
275 | * The buffer will always be null terminated, but to ensure the info string is | ||
276 | * not truncated the buffer needs to be at least `JZ_CPUINFO_BUFLEN` byes long. | ||
277 | */ | ||
278 | int jz_usb_get_cpu_info(jz_usbdev* dev, char* buffer, size_t buflen) | ||
279 | { | ||
280 | char tmpbuf[JZ_CPUINFO_BUFLEN]; | ||
281 | int rc = jz_usb_vendor_req(dev, VR_GET_CPU_INFO, 0, tmpbuf, 8); | ||
282 | if(rc != JZ_SUCCESS) | ||
283 | return rc; | ||
284 | |||
285 | if(buflen > 0) { | ||
286 | strncpy(buffer, tmpbuf, buflen); | ||
287 | buffer[buflen - 1] = 0; | ||
288 | } | ||
289 | |||
290 | return JZ_SUCCESS; | ||
265 | } | 291 | } |