mirror of
https://github.com/GOSTSec/sgminer
synced 2025-01-23 04:54:26 +00:00
Merge pull request #436 from kanoi/master
usbutils optional read buffering
This commit is contained in:
commit
c30af6d663
194
usbutils.c
194
usbutils.c
@ -1311,6 +1311,9 @@ static struct cg_usb_device *free_cgusb(struct cg_usb_device *cgusb)
|
|||||||
|
|
||||||
free(cgusb->found);
|
free(cgusb->found);
|
||||||
|
|
||||||
|
if (cgusb->buffer)
|
||||||
|
free(cgusb->buffer);
|
||||||
|
|
||||||
free(cgusb);
|
free(cgusb);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -2024,6 +2027,36 @@ static void rejected_inc(struct cgpu_info *cgpu, uint32_t mode)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static char *find_end(unsigned char *buf, unsigned char *ptr, int ptrlen, int tot, char *end, int endlen, bool first)
|
||||||
|
{
|
||||||
|
unsigned char *search;
|
||||||
|
|
||||||
|
if (endlen > tot)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// If end is only 1 char - do a faster search
|
||||||
|
if (endlen == 1) {
|
||||||
|
if (first)
|
||||||
|
search = buf;
|
||||||
|
else
|
||||||
|
search = ptr;
|
||||||
|
|
||||||
|
return strchr((char *)search, *end);
|
||||||
|
} else {
|
||||||
|
if (first)
|
||||||
|
search = buf;
|
||||||
|
else {
|
||||||
|
// must allow end to have been chopped in 2
|
||||||
|
if ((tot - ptrlen) >= (endlen - 1))
|
||||||
|
search = ptr - (endlen - 1);
|
||||||
|
else
|
||||||
|
search = ptr - (tot - ptrlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
return strstr((char *)search, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define USB_MAX_READ 8192
|
#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, __maybe_unused enum usb_cmds cmd, bool readonce)
|
int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, const char *end, __maybe_unused enum usb_cmds cmd, bool readonce)
|
||||||
@ -2037,8 +2070,8 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
|
|||||||
unsigned int initial_timeout;
|
unsigned int initial_timeout;
|
||||||
double max, done;
|
double max, done;
|
||||||
int bufleft, err, got, tot;
|
int bufleft, err, got, tot;
|
||||||
__maybe_unused bool first = true;
|
bool first = true;
|
||||||
unsigned char *search;
|
char *search;
|
||||||
int endlen;
|
int endlen;
|
||||||
|
|
||||||
// We add 4: 1 for null, 2 for FTDI status and 1 to round to 4 bytes
|
// We add 4: 1 for null, 2 for FTDI status and 1 to round to 4 bytes
|
||||||
@ -2064,19 +2097,34 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
|
|||||||
timeout = usbdev->found->timeout;
|
timeout = usbdev->found->timeout;
|
||||||
|
|
||||||
if (end == NULL) {
|
if (end == NULL) {
|
||||||
tot = 0;
|
if (usbdev->buffer && usbdev->bufamt) {
|
||||||
ptr = usbbuf;
|
tot = usbdev->bufamt;
|
||||||
bufleft = bufsiz;
|
bufleft = bufsiz - tot;
|
||||||
|
memcpy(usbbuf, usbdev->buffer, tot);
|
||||||
|
ptr = usbbuf + tot;
|
||||||
|
usbdev->bufamt = 0;
|
||||||
|
} else {
|
||||||
|
tot = 0;
|
||||||
|
bufleft = bufsiz;
|
||||||
|
ptr = usbbuf;
|
||||||
|
}
|
||||||
|
|
||||||
err = LIBUSB_SUCCESS;
|
err = LIBUSB_SUCCESS;
|
||||||
initial_timeout = timeout;
|
initial_timeout = timeout;
|
||||||
max = ((double)timeout) / 1000.0;
|
max = ((double)timeout) / 1000.0;
|
||||||
cgtime(&read_start);
|
cgtime(&read_start);
|
||||||
while (bufleft > 0) {
|
while (bufleft > 0) {
|
||||||
if (ftdi)
|
// TODO: use (USB_MAX_READ - tot) always?
|
||||||
usbbufread = bufleft + 2;
|
if (usbdev->buffer)
|
||||||
else
|
usbbufread = USB_MAX_READ - tot;
|
||||||
usbbufread = bufleft;
|
else {
|
||||||
|
if (ftdi)
|
||||||
|
usbbufread = bufleft + 2;
|
||||||
|
else
|
||||||
|
usbbufread = bufleft;
|
||||||
|
}
|
||||||
got = 0;
|
got = 0;
|
||||||
|
|
||||||
STATS_TIMEVAL(&tv_start);
|
STATS_TIMEVAL(&tv_start);
|
||||||
err = libusb_bulk_transfer(usbdev->handle,
|
err = libusb_bulk_transfer(usbdev->handle,
|
||||||
usbdev->found->eps[ep].ep,
|
usbdev->found->eps[ep].ep,
|
||||||
@ -2120,6 +2168,16 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// N.B. usbdev->buffer was emptied before the while() loop
|
||||||
|
if (usbdev->buffer && tot > (int)bufsiz) {
|
||||||
|
usbdev->bufamt = tot - bufsiz;
|
||||||
|
memcpy(usbdev->buffer, ptr + bufsiz, usbdev->bufamt);
|
||||||
|
tot -= usbdev->bufamt;
|
||||||
|
usbbuf[tot] = '\0';
|
||||||
|
applog(LOG_ERR, "USB: %s%i read1 buffering %d extra bytes",
|
||||||
|
cgpu->drv->name, cgpu->device_id, usbdev->bufamt);
|
||||||
|
}
|
||||||
|
|
||||||
*processed = tot;
|
*processed = tot;
|
||||||
memcpy((char *)buf, (const char *)usbbuf, (tot < (int)bufsiz) ? tot + 1 : (int)bufsiz);
|
memcpy((char *)buf, (const char *)usbbuf, (tot < (int)bufsiz) ? tot + 1 : (int)bufsiz);
|
||||||
|
|
||||||
@ -2129,19 +2187,33 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
tot = 0;
|
if (usbdev->buffer && usbdev->bufamt) {
|
||||||
ptr = usbbuf;
|
tot = usbdev->bufamt;
|
||||||
bufleft = bufsiz;
|
bufleft = bufsiz - tot;
|
||||||
|
memcpy(usbbuf, usbdev->buffer, tot);
|
||||||
|
ptr = usbbuf + tot;
|
||||||
|
usbdev->bufamt = 0;
|
||||||
|
} else {
|
||||||
|
tot = 0;
|
||||||
|
bufleft = bufsiz;
|
||||||
|
ptr = usbbuf;
|
||||||
|
}
|
||||||
|
|
||||||
endlen = strlen(end);
|
endlen = strlen(end);
|
||||||
err = LIBUSB_SUCCESS;
|
err = LIBUSB_SUCCESS;
|
||||||
initial_timeout = timeout;
|
initial_timeout = timeout;
|
||||||
max = ((double)timeout) / 1000.0;
|
max = ((double)timeout) / 1000.0;
|
||||||
cgtime(&read_start);
|
cgtime(&read_start);
|
||||||
while (bufleft > 0) {
|
while (bufleft > 0) {
|
||||||
if (ftdi)
|
// TODO: use (USB_MAX_READ - tot) always?
|
||||||
usbbufread = bufleft + 2;
|
if (usbdev->buffer)
|
||||||
else
|
usbbufread = USB_MAX_READ - tot;
|
||||||
usbbufread = bufleft;
|
else {
|
||||||
|
if (ftdi)
|
||||||
|
usbbufread = bufleft + 2;
|
||||||
|
else
|
||||||
|
usbbufread = bufleft;
|
||||||
|
}
|
||||||
got = 0;
|
got = 0;
|
||||||
STATS_TIMEVAL(&tv_start);
|
STATS_TIMEVAL(&tv_start);
|
||||||
err = libusb_bulk_transfer(usbdev->handle,
|
err = libusb_bulk_transfer(usbdev->handle,
|
||||||
@ -2172,23 +2244,8 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
|
|||||||
if (err || readonce)
|
if (err || readonce)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// WARNING - this will return data past END ('if' there is extra data)
|
if (find_end(usbbuf, ptr, got, tot, (char *)end, endlen, first))
|
||||||
if (endlen <= tot) {
|
break;
|
||||||
// If END is only 1 char - do a faster search
|
|
||||||
if (endlen == 1) {
|
|
||||||
if (strchr((char *)ptr, *end))
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
// must allow END to have been chopped in 2 transfers
|
|
||||||
if ((tot - got) >= (endlen - 1))
|
|
||||||
search = ptr - (endlen - 1);
|
|
||||||
else
|
|
||||||
search = ptr - (tot - got);
|
|
||||||
|
|
||||||
if (strstr((char *)search, end))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr += got;
|
ptr += got;
|
||||||
bufleft -= got;
|
bufleft -= got;
|
||||||
@ -2204,6 +2261,38 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (usbdev->buffer) {
|
||||||
|
bool dobuffer = false;
|
||||||
|
|
||||||
|
if ((search = find_end(usbbuf, usbbuf, tot, tot, (char *)end, endlen, true))) {
|
||||||
|
// end finishes after bufsiz
|
||||||
|
if ((search + endlen - (char *)usbbuf) > (int)bufsiz) {
|
||||||
|
usbdev->bufamt = tot - bufsiz;
|
||||||
|
dobuffer = true;
|
||||||
|
} else {
|
||||||
|
// extra data after end
|
||||||
|
if (*(search + endlen)) {
|
||||||
|
usbdev->bufamt = tot - (search + endlen - (char *)usbbuf);
|
||||||
|
dobuffer = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// no end, but still bigger than bufsiz
|
||||||
|
if (tot > (int)bufsiz) {
|
||||||
|
usbdev->bufamt = tot - bufsiz;
|
||||||
|
dobuffer = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dobuffer) {
|
||||||
|
tot -= usbdev->bufamt;
|
||||||
|
memcpy(usbdev->buffer, usbbuf + tot, usbdev->bufamt);
|
||||||
|
usbbuf[tot] = '\0';
|
||||||
|
applog(LOG_ERR, "USB: %s%i read2 buffering %d extra bytes",
|
||||||
|
cgpu->drv->name, cgpu->device_id, usbdev->bufamt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
*processed = tot;
|
*processed = tot;
|
||||||
memcpy((char *)buf, (const char *)usbbuf, (tot < (int)bufsiz) ? tot + 1 : (int)bufsiz);
|
memcpy((char *)buf, (const char *)usbbuf, (tot < (int)bufsiz) ? tot + 1 : (int)bufsiz);
|
||||||
|
|
||||||
@ -2400,6 +2489,45 @@ int usb_ftdi_cts(struct cgpu_info *cgpu)
|
|||||||
return (ret & FTDI_RS0_CTS);
|
return (ret & FTDI_RS0_CTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void usb_buffer_enable(struct cgpu_info *cgpu)
|
||||||
|
{
|
||||||
|
struct cg_usb_device *cgusb = cgpu->usbdev;
|
||||||
|
|
||||||
|
if (!cgusb->buffer) {
|
||||||
|
cgusb->bufamt = 0;
|
||||||
|
cgusb->buffer = malloc(USB_MAX_READ+1);
|
||||||
|
if (!cgusb->buffer)
|
||||||
|
quit(1, "Failed to malloc buffer for USB %s%i",
|
||||||
|
cgpu->drv->name, cgpu->device_id);
|
||||||
|
cgusb->bufsiz = USB_MAX_READ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void usb_buffer_disable(struct cgpu_info *cgpu)
|
||||||
|
{
|
||||||
|
struct cg_usb_device *cgusb = cgpu->usbdev;
|
||||||
|
|
||||||
|
if (cgusb->buffer) {
|
||||||
|
cgusb->bufamt = 0;
|
||||||
|
cgusb->bufsiz = 0;
|
||||||
|
free(cgusb->buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void usb_buffer_clear(struct cgpu_info *cgpu)
|
||||||
|
{
|
||||||
|
struct cg_usb_device *cgusb = cgpu->usbdev;
|
||||||
|
|
||||||
|
cgusb->bufamt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t usb_buffer_size(struct cgpu_info *cgpu)
|
||||||
|
{
|
||||||
|
struct cg_usb_device *cgusb = cgpu->usbdev;
|
||||||
|
|
||||||
|
return cgusb->bufamt;
|
||||||
|
}
|
||||||
|
|
||||||
void usb_cleanup()
|
void usb_cleanup()
|
||||||
{
|
{
|
||||||
struct cgpu_info *cgpu;
|
struct cgpu_info *cgpu;
|
||||||
|
@ -167,6 +167,9 @@ struct cg_usb_device {
|
|||||||
char *serial_string;
|
char *serial_string;
|
||||||
unsigned char fwVersion; // ??
|
unsigned char fwVersion; // ??
|
||||||
unsigned char interfaceVersion; // ??
|
unsigned char interfaceVersion; // ??
|
||||||
|
char *buffer;
|
||||||
|
uint32_t bufsiz;
|
||||||
|
uint32_t bufamt;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cg_usb_info {
|
struct cg_usb_info {
|
||||||
@ -258,6 +261,10 @@ int usb_ftdi_ctw(struct cgpu_info *cgpu);
|
|||||||
int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, enum usb_cmds);
|
int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, enum usb_cmds);
|
||||||
int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint32_t *data, int siz, unsigned int timeout, enum usb_cmds cmd);
|
int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint32_t *data, int siz, unsigned int timeout, enum usb_cmds cmd);
|
||||||
int _usb_transfer_read(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, char *buf, int bufsiz, int *amount, unsigned int timeout, enum usb_cmds cmd);
|
int _usb_transfer_read(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, char *buf, int bufsiz, int *amount, unsigned int timeout, enum usb_cmds cmd);
|
||||||
|
void usb_buffer_enable(struct cgpu_info *cgpu);
|
||||||
|
void usb_buffer_disable(struct cgpu_info *cgpu);
|
||||||
|
void usb_buffer_clear(struct cgpu_info *cgpu);
|
||||||
|
uint32_t usb_buffer_size(struct cgpu_info *cgpu);
|
||||||
void usb_cleanup();
|
void usb_cleanup();
|
||||||
void usb_initialise();
|
void usb_initialise();
|
||||||
void *usb_resource_thread(void *userdata);
|
void *usb_resource_thread(void *userdata);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user