Browse Source

Merge branch 'usb'

nfactor-troky
Kano 12 years ago
parent
commit
527fe05848
  1. 4
      driver-modminer.c
  2. 131
      usbutils.c
  3. 22
      usbutils.h

4
driver-modminer.c

@ -103,7 +103,7 @@ static void do_ping(struct cgpu_info *modminer)
modminer->drv->name, modminer->fpgaid, amount, err); modminer->drv->name, modminer->fpgaid, amount, err);
// Clear any outstanding data // Clear any outstanding data
while ((err = usb_read(modminer, buf, sizeof(buf)-1, &amount, C_CLEAR)) == 0 && amount > 0) while ((err = usb_read_once(modminer, buf, sizeof(buf)-1, &amount, C_CLEAR)) == 0 && amount > 0)
applog(LOG_DEBUG, "%s%u: clear got %d", applog(LOG_DEBUG, "%s%u: clear got %d",
modminer->drv->name, modminer->fpgaid, amount); modminer->drv->name, modminer->fpgaid, amount);
@ -141,7 +141,7 @@ static bool modminer_detect_one(struct libusb_device *dev, struct usb_find_devic
goto unshin; goto unshin;
} }
if ((err = usb_read(modminer, buf, sizeof(buf)-1, &amount, C_GETVERSION)) < 0 || amount < 1) { if ((err = usb_read_once(modminer, buf, sizeof(buf)-1, &amount, C_GETVERSION)) < 0 || amount < 1) {
if (err < 0) if (err < 0)
applog(LOG_ERR, "%s detect (%s) no version reply (%d)", applog(LOG_ERR, "%s detect (%s) no version reply (%d)",
modminer->drv->dname, devpath, err); modminer->drv->dname, devpath, err);

131
usbutils.c

@ -154,7 +154,7 @@ static struct usb_find_devices find_dev[] = {
.idProduct = 0x6001, .idProduct = 0x6001,
.kernel = 0, .kernel = 0,
.config = 1, .config = 1,
.interface = 1, .interface = 0,
.timeout = AVALON_TIMEOUT_MS, .timeout = AVALON_TIMEOUT_MS,
.epcount = ARRAY_SIZE(ava_eps), .epcount = ARRAY_SIZE(ava_eps),
.eps = ava_eps }, .eps = ava_eps },
@ -202,6 +202,17 @@ static const char *BLANK = "";
static const char *space = " "; static const char *space = " ";
static const char *nodatareturned = "no data returned "; static const char *nodatareturned = "no data returned ";
#if 0 // enable USBDEBUG - only during development testing
static const char *debug_true_str = "true";
static const char *debug_false_str = "false";
static const char *nodevstr = "=NODEV";
#define bool_str(boo) ((boo) ? debug_true_str : debug_false_str)
#define isnodev(err) (NODEV(err) ? nodevstr : BLANK)
#define USBDEBUG(fmt, ...) applog(LOG_WARNING, fmt, ##__VA_ARGS__)
#else
#define USBDEBUG(fmt, ...)
#endif
// For device limits by driver // For device limits by driver
static struct driver_count { static struct driver_count {
uint32_t count; uint32_t count;
@ -1311,6 +1322,8 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u
goto cldame; goto cldame;
} }
if (strcmp((char *)man, found->iManufacturer)) { if (strcmp((char *)man, found->iManufacturer)) {
applog(LOG_DEBUG, "USB init, iManufacturer mismatch %s",
devstr);
bad = USB_INIT_IGNORE; bad = USB_INIT_IGNORE;
goto cldame; goto cldame;
} }
@ -1329,6 +1342,8 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u
goto cldame; goto cldame;
} }
if (strcmp((char *)prod, found->iProduct)) { if (strcmp((char *)prod, found->iProduct)) {
applog(LOG_DEBUG, "USB init, iProduct mismatch %s",
devstr);
bad = USB_INIT_IGNORE; bad = USB_INIT_IGNORE;
goto cldame; goto cldame;
} }
@ -1358,8 +1373,11 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u
goto cldame; goto cldame;
} }
if ((int)(config->bNumInterfaces) <= found->interface) if ((int)(config->bNumInterfaces) <= found->interface) {
applog(LOG_DEBUG, "USB init bNumInterfaces <= interface %s",
devstr);
goto cldame; goto cldame;
}
for (i = 0; i < found->epcount; i++) for (i = 0; i < found->epcount; i++)
found->eps[i].found = false; found->eps[i].found = false;
@ -1381,9 +1399,13 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u
} }
} }
for (i = 0; i < found->epcount; i++) for (i = 0; i < found->epcount; i++) {
if (found->eps[i].found == false) if (found->eps[i].found == false) {
applog(LOG_DEBUG, "USB init found == false %s",
devstr);
goto cldame; goto cldame;
}
}
err = libusb_claim_interface(cgusb->handle, found->interface); err = libusb_claim_interface(cgusb->handle, found->interface);
if (err) { if (err) {
@ -1815,7 +1837,7 @@ static void rejected_inc(struct cgpu_info *cgpu)
#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, enum usb_cmds cmd, bool ftdi) 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, bool readonce)
{ {
struct cg_usb_device *usbdev = cgpu->usbdev; struct cg_usb_device *usbdev = cgpu->usbdev;
#if DO_USB_STATS #if DO_USB_STATS
@ -1824,7 +1846,7 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
struct timeval read_start, tv_finish; struct timeval read_start, tv_finish;
unsigned int initial_timeout; unsigned int initial_timeout;
double max, done; double max, done;
int err, got, tot; int bufleft, err, got, tot;
bool first = true; bool first = true;
unsigned char *search; unsigned char *search;
int endlen; int endlen;
@ -1833,6 +1855,8 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
unsigned char usbbuf[USB_MAX_READ+4], *ptr; unsigned char usbbuf[USB_MAX_READ+4], *ptr;
size_t usbbufread; size_t usbbufread;
USBDEBUG("USB debug: _usb_read(%s (nodev=%s),ep=%d,buf=%p,bufsiz=%zu,proc=%p,timeout=%u,end=%s,cmd=%s,ftdi=%s,readonce=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), ep, buf, bufsiz, processed, timeout, end ? (char *)str_text((char *)end) : "NULL", usb_cmdname(cmd), bool_str(ftdi), bool_str(readonce));
if (bufsiz > USB_MAX_READ) if (bufsiz > USB_MAX_READ)
quit(1, "%s USB read request %d too large (max=%d)", cgpu->drv->name, bufsiz, USB_MAX_READ); quit(1, "%s USB read request %d too large (max=%d)", cgpu->drv->name, bufsiz, USB_MAX_READ);
@ -1849,32 +1873,60 @@ 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) {
if (ftdi) tot = 0;
usbbufread = bufsiz + 2; ptr = usbbuf;
else bufleft = bufsiz;
usbbufread = bufsiz; err = LIBUSB_SUCCESS;
got = 0; initial_timeout = timeout;
STATS_TIMEVAL(&tv_start); max = ((double)timeout) / 1000.0;
err = libusb_bulk_transfer(usbdev->handle, cgtime(&read_start);
usbdev->found->eps[ep].ep, while (bufleft > 0) {
usbbuf, usbbufread, &got, timeout); if (ftdi)
STATS_TIMEVAL(&tv_finish); usbbufread = bufleft + 2;
USB_STATS(cgpu, &tv_start, &tv_finish, err, cmd, SEQ0); else
usbbuf[got] = '\0'; usbbufread = bufleft;
got = 0;
if (ftdi) { STATS_TIMEVAL(&tv_start);
// first 2 bytes returned are an FTDI status err = libusb_bulk_transfer(usbdev->handle,
if (got > 2) { usbdev->found->eps[ep].ep,
got -= 2; ptr, usbbufread, &got, timeout);
memmove(usbbuf, usbbuf+2, got+1); STATS_TIMEVAL(&tv_finish);
} else { USB_STATS(cgpu, &tv_start, &tv_finish, err, cmd, first ? SEQ0 : SEQ1);
got = 0; ptr[got] = '\0';
usbbuf[0] = '\0';
USBDEBUG("USB debug: @_usb_read(%s (nodev=%s)) first=%s err=%d%s got=%d ptr='%s' usbbufread=%zu", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), bool_str(first), err, isnodev(err), got, (char *)str_text((char *)ptr), usbbufread);
if (ftdi) {
// first 2 bytes returned are an FTDI status
if (got > 2) {
got -= 2;
memmove(ptr, ptr+2, got+1);
} else {
got = 0;
*ptr = '\0';
}
} }
tot += got;
if (err || readonce)
break;
ptr += got;
bufleft -= got;
first = false;
done = tdiff(&tv_finish, &read_start);
// N.B. this is return LIBUSB_SUCCESS with whatever size has already been read
if (unlikely(done >= max))
break;
timeout = initial_timeout - (done * 1000);
} }
*processed = got; *processed = tot;
memcpy((char *)buf, (const char *)usbbuf, (got < (int)bufsiz) ? got + 1 : (int)bufsiz); memcpy((char *)buf, (const char *)usbbuf, (tot < (int)bufsiz) ? tot + 1 : (int)bufsiz);
if (NODEV(err)) if (NODEV(err))
release_cgpu(cgpu); release_cgpu(cgpu);
@ -1884,16 +1936,17 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
tot = 0; tot = 0;
ptr = usbbuf; ptr = usbbuf;
bufleft = bufsiz;
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 (bufsiz) { while (bufleft > 0) {
if (ftdi) if (ftdi)
usbbufread = bufsiz + 2; usbbufread = bufleft + 2;
else else
usbbufread = bufsiz; 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,
@ -1903,6 +1956,8 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
USB_STATS(cgpu, &tv_start, &tv_finish, err, cmd, first ? SEQ0 : SEQ1); USB_STATS(cgpu, &tv_start, &tv_finish, err, cmd, first ? SEQ0 : SEQ1);
ptr[got] = '\0'; ptr[got] = '\0';
USBDEBUG("USB debug: @_usb_read(%s (nodev=%s)) first=%s err=%d%s got=%d ptr='%s' usbbufread=%zu", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), bool_str(first), err, isnodev(err), got, (char *)str_text((char *)ptr), usbbufread);
if (ftdi) { if (ftdi) {
// first 2 bytes returned are an FTDI status // first 2 bytes returned are an FTDI status
if (got > 2) { if (got > 2) {
@ -1916,7 +1971,7 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
tot += got; tot += got;
if (err) if (err || readonce)
break; break;
// WARNING - this will return data past END ('if' there is extra data) // WARNING - this will return data past END ('if' there is extra data)
@ -1938,7 +1993,7 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
} }
ptr += got; ptr += got;
bufsiz -= got; bufleft -= got;
first = false; first = false;
@ -1967,6 +2022,8 @@ int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pr
#endif #endif
int err, sent; int err, sent;
USBDEBUG("USB debug: _usb_write(%s (nodev=%s),ep=%d,buf='%s',bufsiz=%zu,proc=%p,timeout=%u,cmd=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), ep, (char *)str_text(buf), bufsiz, processed, timeout, usb_cmdname(cmd));
if (cgpu->usbinfo.nodev) { if (cgpu->usbinfo.nodev) {
*processed = 0; *processed = 0;
#if DO_USB_STATS #if DO_USB_STATS
@ -1985,6 +2042,8 @@ int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pr
STATS_TIMEVAL(&tv_finish); STATS_TIMEVAL(&tv_finish);
USB_STATS(cgpu, &tv_start, &tv_finish, err, cmd, SEQ0); USB_STATS(cgpu, &tv_start, &tv_finish, err, cmd, SEQ0);
USBDEBUG("USB debug: @_usb_write(%s (nodev=%s)) err=%d%s sent=%d", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), err, isnodev(err), sent);
*processed = sent; *processed = sent;
if (NODEV(err)) if (NODEV(err))
@ -2001,6 +2060,8 @@ int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest
#endif #endif
int err; int err;
USBDEBUG("USB debug: _usb_transfer(%s (nodev=%s),type=%"PRIu8",req=%"PRIu8",value=%"PRIu16",index=%"PRIu16",timeout=%u,cmd=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), request_type, bRequest, wValue, wIndex, timeout, usb_cmdname(cmd));
if (cgpu->usbinfo.nodev) { if (cgpu->usbinfo.nodev) {
#if DO_USB_STATS #if DO_USB_STATS
rejected_inc(cgpu); rejected_inc(cgpu);
@ -2015,6 +2076,8 @@ int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest
STATS_TIMEVAL(&tv_finish); STATS_TIMEVAL(&tv_finish);
USB_STATS(cgpu, &tv_start, &tv_finish, err, cmd, SEQ0); USB_STATS(cgpu, &tv_start, &tv_finish, err, cmd, SEQ0);
USBDEBUG("USB debug: @_usb_transfer(%s (nodev=%s)) err=%d%s", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), err, isnodev(err));
if (NODEV(err)) if (NODEV(err))
release_cgpu(cgpu); release_cgpu(cgpu);

22
usbutils.h

@ -150,26 +150,29 @@ bool usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct usb_find
void usb_detect(struct device_drv *drv, bool (*device_detect)(struct libusb_device *, struct usb_find_devices *)); void usb_detect(struct device_drv *drv, bool (*device_detect)(struct libusb_device *, struct usb_find_devices *));
struct api_data *api_usb_stats(int *count); struct api_data *api_usb_stats(int *count);
void update_usb_stats(struct cgpu_info *cgpu); void update_usb_stats(struct cgpu_info *cgpu);
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); 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, bool readonce);
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, 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, unsigned int timeout, enum usb_cmds cmd);
void usb_cleanup(); void usb_cleanup();
void usb_initialise(); void usb_initialise();
#define usb_read(cgpu, buf, bufsiz, read, cmd) \ #define usb_read(cgpu, buf, bufsiz, read, cmd) \
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false) _usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false, false)
#define usb_read_once(cgpu, buf, bufsiz, read, cmd) \
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false, true)
#define usb_read_nl(cgpu, buf, bufsiz, read, cmd) \ #define usb_read_nl(cgpu, buf, bufsiz, read, cmd) \
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "\n", cmd, false) _usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "\n", cmd, false, false)
#define usb_read_ep(cgpu, ep, buf, bufsiz, read, cmd) \ #define usb_read_ep(cgpu, ep, buf, bufsiz, read, cmd) \
_usb_read(cgpu, ep, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false) _usb_read(cgpu, ep, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false, false)
#define usb_read_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \ #define usb_read_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, false) _usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, false, false)
#define usb_read_ep_timeout(cgpu, ep, buf, bufsiz, read, timeout, cmd) \ #define usb_read_ep_timeout(cgpu, ep, buf, bufsiz, read, timeout, cmd) \
_usb_read(cgpu, ep, buf, bufsiz, read, timeout, NULL, cmd, false) _usb_read(cgpu, ep, buf, bufsiz, read, timeout, NULL, cmd, false, false)
#define usb_write(cgpu, buf, bufsiz, wrote, cmd) \ #define usb_write(cgpu, buf, bufsiz, wrote, cmd) \
_usb_write(cgpu, DEFAULT_EP_OUT, buf, bufsiz, wrote, DEVTIMEOUT, cmd) _usb_write(cgpu, DEFAULT_EP_OUT, buf, bufsiz, wrote, DEVTIMEOUT, cmd)
@ -183,11 +186,14 @@ void usb_initialise();
#define usb_write_ep_timeout(cgpu, ep, buf, bufsiz, wrote, timeout, cmd) \ #define usb_write_ep_timeout(cgpu, ep, buf, bufsiz, wrote, timeout, cmd) \
_usb_write(cgpu, ep, buf, bufsiz, wrote, timeout, cmd) _usb_write(cgpu, ep, buf, bufsiz, wrote, timeout, cmd)
#define usb_ftdi_read(cgpu, buf, bufsiz, read, cmd) \
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, true, false)
#define usb_ftdi_read_nl(cgpu, buf, bufsiz, read, cmd) \ #define usb_ftdi_read_nl(cgpu, buf, bufsiz, read, cmd) \
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "\n", cmd, true) _usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "\n", cmd, true, false)
#define usb_ftdi_read_ok(cgpu, buf, bufsiz, read, cmd) \ #define usb_ftdi_read_ok(cgpu, buf, bufsiz, read, cmd) \
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "OK\n", cmd, true) _usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "OK\n", cmd, true, false)
#define usb_transfer(cgpu, typ, req, val, idx, cmd) \ #define usb_transfer(cgpu, typ, req, val, idx, cmd) \
_usb_transfer(cgpu, typ, req, val, idx, DEVTIMEOUT, cmd) _usb_transfer(cgpu, typ, req, val, idx, DEVTIMEOUT, cmd)

Loading…
Cancel
Save