Merge pull request #408 from kanoi/bflsc Make usbutils use its own internal read buffer.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
diff --git a/usbutils.c b/usbutils.c
index 10a9dea..a088a39 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 5b5c133..1454faa 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
};