diff --git a/usbutils.c b/usbutils.c index 10a9dea0..a088a39d 100644 --- a/usbutils.c +++ b/usbutils.c @@ -254,6 +254,8 @@ static const char *C_SETMODEM_S = "SetModemCtrl"; static const char *C_PURGERX_S = "PurgeRx"; static const char *C_PURGETX_S = "PurgeTx"; static const char *C_FLASHREPLY_S = "FlashReply"; +static const char *C_REQUESTDETAILS_S = "RequestDetails"; +static const char *C_GETDETAILS_S = "GetDetails"; #ifdef EOL #undef EOL @@ -711,6 +713,8 @@ static void cgusb_check_init() usb_commands[C_PURGERX] = C_PURGERX_S; usb_commands[C_PURGETX] = C_PURGETX_S; usb_commands[C_FLASHREPLY] = C_FLASHREPLY_S; + usb_commands[C_REQUESTDETAILS] = C_REQUESTDETAILS_S; + usb_commands[C_GETDETAILS] = C_GETDETAILS_S; stats_initialised = true; } @@ -1559,6 +1563,8 @@ static void rejected_inc(struct cgpu_info *cgpu) } #endif +#define USB_MAX_READ 8192 + int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, const char *end, enum usb_cmds cmd, bool ftdi) { struct cg_usb_device *usbdev = cgpu->usbdev; @@ -1570,9 +1576,16 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro double max, done; int err, got, tot; bool first = true; - char *search; + unsigned char *search; int endlen; + // We add 4: 1 for null, 2 for FTDI status and 1 to round to 4 bytes + unsigned char usbbuf[USB_MAX_READ+4], *ptr; + size_t usbbufread; + + if (bufsiz > USB_MAX_READ) + quit(1, "%s USB read request %d too large (max=%d)", cgpu->drv->name, bufsiz, USB_MAX_READ); + if (cgpu->usbinfo.nodev) { *buf = '\0'; *processed = 0; @@ -1586,27 +1599,32 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro timeout = usbdev->found->timeout; if (end == NULL) { + if (ftdi) + usbbufread = bufsiz + 2; + else + usbbufread = bufsiz; got = 0; STATS_TIMEVAL(&tv_start); err = libusb_bulk_transfer(usbdev->handle, usbdev->found->eps[ep].ep, - (unsigned char *)buf, - bufsiz, &got, timeout); + usbbuf, usbbufread, &got, timeout); STATS_TIMEVAL(&tv_finish); USB_STATS(cgpu, &tv_start, &tv_finish, err, cmd, SEQ0); + usbbuf[got] = '\0'; if (ftdi) { // first 2 bytes returned are an FTDI status if (got > 2) { got -= 2; - memmove(buf, buf+2, got+1); + memmove(usbbuf, usbbuf+2, got+1); } else { got = 0; - *buf = '\0'; + usbbuf[0] = '\0'; } } *processed = got; + memcpy((char *)buf, (const char *)usbbuf, (got < (int)bufsiz) ? got + 1 : (int)bufsiz); if (NODEV(err)) release_cgpu(cgpu); @@ -1615,29 +1633,34 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro } tot = 0; + ptr = usbbuf; endlen = strlen(end); err = LIBUSB_SUCCESS; initial_timeout = timeout; max = ((double)timeout) / 1000.0; gettimeofday(&read_start, NULL); while (bufsiz) { + if (ftdi) + usbbufread = bufsiz + 2; + else + usbbufread = bufsiz; got = 0; STATS_TIMEVAL(&tv_start); err = libusb_bulk_transfer(usbdev->handle, usbdev->found->eps[ep].ep, - (unsigned char *)buf, - bufsiz, &got, timeout); + ptr, usbbufread, &got, timeout); gettimeofday(&tv_finish, NULL); USB_STATS(cgpu, &tv_start, &tv_finish, err, cmd, first ? SEQ0 : SEQ1); + ptr[got] = '\0'; if (ftdi) { // first 2 bytes returned are an FTDI status if (got > 2) { got -= 2; - memmove(buf, buf+2, got+1); + memmove(ptr, ptr+2, got+1); } else { got = 0; - *buf = '\0'; + *ptr = '\0'; } } @@ -1650,21 +1673,21 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro if (endlen <= tot) { // If END is only 1 char - do a faster search if (endlen == 1) { - if (strchr(buf, *end)) + if (strchr((char *)ptr, *end)) break; } else { // must allow END to have been chopped in 2 transfers if ((tot - got) >= (endlen - 1)) - search = buf - (endlen - 1); + search = ptr - (endlen - 1); else - search = buf - (tot - got); + search = ptr - (tot - got); - if (strstr(search, end)) + if (strstr((char *)search, end)) break; } } - buf += got; + ptr += got; bufsiz -= got; first = false; @@ -1678,6 +1701,7 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro } *processed = tot; + memcpy((char *)buf, (const char *)usbbuf, (tot < (int)bufsiz) ? tot + 1 : (int)bufsiz); if (NODEV(err)) release_cgpu(cgpu); diff --git a/usbutils.h b/usbutils.h index 5b5c133b..1454faae 100644 --- a/usbutils.h +++ b/usbutils.h @@ -123,6 +123,8 @@ enum usb_cmds { C_PURGERX, C_PURGETX, C_FLASHREPLY, + C_REQUESTDETAILS, + C_GETDETAILS, C_MAX };