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);
|
||||
|
||||
if (cgusb->buffer)
|
||||
free(cgusb->buffer);
|
||||
|
||||
free(cgusb);
|
||||
|
||||
return NULL;
|
||||
@ -2024,6 +2027,36 @@ static void rejected_inc(struct cgpu_info *cgpu, uint32_t mode)
|
||||
}
|
||||
#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
|
||||
|
||||
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;
|
||||
double max, done;
|
||||
int bufleft, err, got, tot;
|
||||
__maybe_unused bool first = true;
|
||||
unsigned char *search;
|
||||
bool first = true;
|
||||
char *search;
|
||||
int endlen;
|
||||
|
||||
// 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;
|
||||
|
||||
if (end == NULL) {
|
||||
tot = 0;
|
||||
ptr = usbbuf;
|
||||
bufleft = bufsiz;
|
||||
if (usbdev->buffer && usbdev->bufamt) {
|
||||
tot = usbdev->bufamt;
|
||||
bufleft = bufsiz - tot;
|
||||
memcpy(usbbuf, usbdev->buffer, tot);
|
||||
ptr = usbbuf + tot;
|
||||
usbdev->bufamt = 0;
|
||||
} else {
|
||||
tot = 0;
|
||||
bufleft = bufsiz;
|
||||
ptr = usbbuf;
|
||||
}
|
||||
|
||||
err = LIBUSB_SUCCESS;
|
||||
initial_timeout = timeout;
|
||||
max = ((double)timeout) / 1000.0;
|
||||
cgtime(&read_start);
|
||||
while (bufleft > 0) {
|
||||
if (ftdi)
|
||||
usbbufread = bufleft + 2;
|
||||
else
|
||||
usbbufread = bufleft;
|
||||
// TODO: use (USB_MAX_READ - tot) always?
|
||||
if (usbdev->buffer)
|
||||
usbbufread = USB_MAX_READ - tot;
|
||||
else {
|
||||
if (ftdi)
|
||||
usbbufread = bufleft + 2;
|
||||
else
|
||||
usbbufread = bufleft;
|
||||
}
|
||||
got = 0;
|
||||
|
||||
STATS_TIMEVAL(&tv_start);
|
||||
err = libusb_bulk_transfer(usbdev->handle,
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
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;
|
||||
}
|
||||
|
||||
tot = 0;
|
||||
ptr = usbbuf;
|
||||
bufleft = bufsiz;
|
||||
if (usbdev->buffer && usbdev->bufamt) {
|
||||
tot = usbdev->bufamt;
|
||||
bufleft = bufsiz - tot;
|
||||
memcpy(usbbuf, usbdev->buffer, tot);
|
||||
ptr = usbbuf + tot;
|
||||
usbdev->bufamt = 0;
|
||||
} else {
|
||||
tot = 0;
|
||||
bufleft = bufsiz;
|
||||
ptr = usbbuf;
|
||||
}
|
||||
|
||||
endlen = strlen(end);
|
||||
err = LIBUSB_SUCCESS;
|
||||
initial_timeout = timeout;
|
||||
max = ((double)timeout) / 1000.0;
|
||||
cgtime(&read_start);
|
||||
while (bufleft > 0) {
|
||||
if (ftdi)
|
||||
usbbufread = bufleft + 2;
|
||||
else
|
||||
usbbufread = bufleft;
|
||||
// TODO: use (USB_MAX_READ - tot) always?
|
||||
if (usbdev->buffer)
|
||||
usbbufread = USB_MAX_READ - tot;
|
||||
else {
|
||||
if (ftdi)
|
||||
usbbufread = bufleft + 2;
|
||||
else
|
||||
usbbufread = bufleft;
|
||||
}
|
||||
got = 0;
|
||||
STATS_TIMEVAL(&tv_start);
|
||||
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)
|
||||
break;
|
||||
|
||||
// WARNING - this will return data past END ('if' there is extra data)
|
||||
if (endlen <= tot) {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
if (find_end(usbbuf, ptr, got, tot, (char *)end, endlen, first))
|
||||
break;
|
||||
|
||||
ptr += got;
|
||||
bufleft -= got;
|
||||
@ -2204,6 +2261,38 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
struct cgpu_info *cgpu;
|
||||
|
@ -167,6 +167,9 @@ struct cg_usb_device {
|
||||
char *serial_string;
|
||||
unsigned char fwVersion; // ??
|
||||
unsigned char interfaceVersion; // ??
|
||||
char *buffer;
|
||||
uint32_t bufsiz;
|
||||
uint32_t bufamt;
|
||||
};
|
||||
|
||||
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_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);
|
||||
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_initialise();
|
||||
void *usb_resource_thread(void *userdata);
|
||||
|
Loading…
x
Reference in New Issue
Block a user