Browse Source

Merge pull request #498 from kanoi/master

usbutils interfaces working on windows - avalon type correction
nfactor-troky
kanoi 11 years ago
parent
commit
8fbd8a4744
  1. 2
      driver-avalon.c
  2. 18
      driver-icarus.c
  3. 347
      usbutils.c
  4. 50
      usbutils.h

2
driver-avalon.c

@ -1531,7 +1531,7 @@ static struct api_data *avalon_api_stats(struct cgpu_info *cgpu)
info->version1, info->version2, info->version3); info->version1, info->version2, info->version3);
root = api_add_string(root, "version", buf, true); root = api_add_string(root, "version", buf, true);
} }
root = api_add_int(root, "Controller Version", &(info->ctlr_ver), false); root = api_add_uint32(root, "Controller Version", &(info->ctlr_ver), false);
return root; return root;
} }

18
driver-icarus.c

@ -177,6 +177,8 @@ static const char *MODE_VALUE_STR = "value";
static const char *MODE_UNKNOWN_STR = "unknown"; static const char *MODE_UNKNOWN_STR = "unknown";
struct ICARUS_INFO { struct ICARUS_INFO {
int intinfo;
// time to calculate the golden_ob // time to calculate the golden_ob
uint64_t golden_hashes; uint64_t golden_hashes;
struct timeval golden_tv; struct timeval golden_tv;
@ -277,7 +279,7 @@ static void icarus_initialise(struct cgpu_info *icarus, int baud)
usb_set_cps(icarus, baud / 10); usb_set_cps(icarus, baud / 10);
usb_enable_cps(icarus); usb_enable_cps(icarus);
interface = usb_interface(icarus); interface = _usb_interface(icarus, info->intinfo);
ident = usb_ident(icarus); ident = usb_ident(icarus);
switch (ident) { switch (ident) {
@ -287,9 +289,6 @@ static void icarus_initialise(struct cgpu_info *icarus, int baud)
case IDENT_CMR2: case IDENT_CMR2:
usb_set_pps(icarus, BLT_PREF_PACKET); usb_set_pps(icarus, BLT_PREF_PACKET);
if (ident == IDENT_CMR2) // Chip hack
interface++;
// Reset // Reset
transfer(icarus, FTDI_TYPE_OUT, FTDI_REQUEST_RESET, FTDI_VALUE_RESET, transfer(icarus, FTDI_TYPE_OUT, FTDI_REQUEST_RESET, FTDI_VALUE_RESET,
interface, C_RESET); interface, C_RESET);
@ -434,6 +433,7 @@ static void rev(unsigned char *s, size_t l)
static int icarus_get_nonce(struct cgpu_info *icarus, unsigned char *buf, struct timeval *tv_start, struct timeval *tv_finish, struct thr_info *thr, int read_time) static int icarus_get_nonce(struct cgpu_info *icarus, unsigned char *buf, struct timeval *tv_start, struct timeval *tv_finish, struct thr_info *thr, int read_time)
{ {
struct ICARUS_INFO *info = (struct ICARUS_INFO *)(icarus->device_data);
struct timeval read_start, read_finish; struct timeval read_start, read_finish;
int err, amt; int err, amt;
int rc = 0; int rc = 0;
@ -446,7 +446,9 @@ static int icarus_get_nonce(struct cgpu_info *icarus, unsigned char *buf, struct
return ICA_NONCE_ERROR; return ICA_NONCE_ERROR;
cgtime(&read_start); cgtime(&read_start);
err = usb_read_timeout(icarus, (char *)buf, read_amount, &amt, ICARUS_WAIT_TIMEOUT, C_GETRESULTS); err = usb_read_ii_timeout(icarus, info->intinfo,
(char *)buf, read_amount, &amt,
ICARUS_WAIT_TIMEOUT, C_GETRESULTS);
cgtime(&read_finish); cgtime(&read_finish);
if (err < 0 && err != LIBUSB_ERROR_TIMEOUT) { if (err < 0 && err != LIBUSB_ERROR_TIMEOUT) {
applog(LOG_ERR, "%s%i: Comms error (rerr=%d amt=%d)", applog(LOG_ERR, "%s%i: Comms error (rerr=%d amt=%d)",
@ -879,7 +881,7 @@ static bool icarus_detect_one(struct libusb_device *dev, struct usb_find_devices
struct cgpu_info *cgtmp; struct cgpu_info *cgtmp;
struct ICARUS_INFO *intmp; struct ICARUS_INFO *intmp;
cgtmp = usb_init_intinfo(icarus, i); cgtmp = usb_copy_cgpu(icarus);
if (!cgtmp) { if (!cgtmp) {
applog(LOG_ERR, "%s%d: Init failed initinfo %d", applog(LOG_ERR, "%s%d: Init failed initinfo %d",
icarus->drv->name, icarus->device_id, i); icarus->drv->name, icarus->device_id, i);
@ -903,6 +905,8 @@ static bool icarus_detect_one(struct libusb_device *dev, struct usb_find_devices
// Initialise everything to match // Initialise everything to match
memcpy(intmp, info, sizeof(struct ICARUS_INFO)); memcpy(intmp, info, sizeof(struct ICARUS_INFO));
intmp->intinfo = i;
} }
} }
@ -976,7 +980,7 @@ static int64_t icarus_scanhash(struct thr_info *thr, struct work *work,
// We only want results for the work we are about to send // We only want results for the work we are about to send
usb_buffer_clear(icarus); usb_buffer_clear(icarus);
err = usb_write(icarus, (char *)ob_bin, sizeof(ob_bin), &amount, C_SENDWORK); err = usb_write_ii(icarus, info->intinfo, (char *)ob_bin, sizeof(ob_bin), &amount, C_SENDWORK);
if (err < 0 || amount != sizeof(ob_bin)) { if (err < 0 || amount != sizeof(ob_bin)) {
applog(LOG_ERR, "%s%i: Comms error (werr=%d amt=%d)", applog(LOG_ERR, "%s%i: Comms error (werr=%d amt=%d)",
icarus->drv->name, icarus->device_id, err, amount); icarus->drv->name, icarus->device_id, err, amount);

347
usbutils.c

@ -88,10 +88,18 @@
#define USB_EPS(_intx, _epinfosx) { \ #define USB_EPS(_intx, _epinfosx) { \
.interface = _intx, \ .interface = _intx, \
.ctrl_transfer = _intx, \
.epinfo_count = ARRAY_SIZE(_epinfosx), \ .epinfo_count = ARRAY_SIZE(_epinfosx), \
.epinfos = _epinfosx \ .epinfos = _epinfosx \
} }
#define USB_EPS_CTRL(_inty, _ctrlinty, _epinfosy) { \
.interface = _inty, \
.ctrl_transfer = _ctrlinty, \
.epinfo_count = ARRAY_SIZE(_epinfosy), \
.epinfos = _epinfosy \
}
#ifdef USE_BFLSC #ifdef USE_BFLSC
// N.B. transfer size is 512 with USB2.0, but only 64 with USB1.1 // N.B. transfer size is 512 with USB2.0, but only 64 with USB1.1
static struct usb_epinfo bas_epinfos[] = { static struct usb_epinfo bas_epinfos[] = {
@ -179,7 +187,6 @@ static struct usb_epinfo cmr2_epinfos0[] = {
{ LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(1), 0 }, { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(1), 0 },
{ LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(2), 0 } { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(2), 0 }
}; };
#ifndef WIN32
static struct usb_epinfo cmr2_epinfos1[] = { static struct usb_epinfo cmr2_epinfos1[] = {
{ LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(3), 0 }, { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(3), 0 },
{ LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(4), 0 }, { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(4), 0 },
@ -192,29 +199,24 @@ static struct usb_epinfo cmr2_epinfos3[] = {
{ LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(7), 0 }, { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(7), 0 },
{ LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(8), 0 } { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(8), 0 }
}; };
#endif
static struct usb_intinfo cmr2_ints[] = { static struct usb_intinfo cmr2_ints[] = {
USB_EPS(0, cmr2_epinfos0) USB_EPS_CTRL(0, 1, cmr2_epinfos0),
#ifndef WIN32 USB_EPS_CTRL(1, 2, cmr2_epinfos1),
, USB_EPS_CTRL(2, 3, cmr2_epinfos2),
USB_EPS(1, cmr2_epinfos1), USB_EPS_CTRL(3, 4, cmr2_epinfos3)
USB_EPS(2, cmr2_epinfos2),
USB_EPS(3, cmr2_epinfos3)
#endif
}; };
#endif #endif
#define IDVENDOR_FTDI 0x0403 #define IDVENDOR_FTDI 0x0403
#define INTINFO(_ints) \ #define INTINFO(_ints) \
.which_intinfo = 0, \
.intinfo_count = ARRAY_SIZE(_ints), \ .intinfo_count = ARRAY_SIZE(_ints), \
.intinfos = _ints .intinfos = _ints
#define USBEP(_usbdev, _epinfo) (_usbdev->found->intinfos[_usbdev->found->which_intinfo].epinfos[_epinfo].ep) #define USBEP(_usbdev, _intinfo, _epinfo) (_usbdev->found->intinfos[_intinfo].epinfos[_epinfo].ep)
#define FOUNDIF(_found) (_found->intinfos[_found->which_intinfo].interface) #define THISIF(_found, _this) (_found->intinfos[_this].interface)
#define USBIF(_usbdev) FOUNDIF(_usbdev->found) #define USBIF(_usbdev, _this) THISIF(_usbdev->found, _this)
// TODO: Add support for (at least) Isochronous endpoints // TODO: Add support for (at least) Isochronous endpoints
static struct usb_find_devices find_dev[] = { static struct usb_find_devices find_dev[] = {
@ -360,11 +362,10 @@ static struct usb_find_devices find_dev[] = {
.config = 1, .config = 1,
.timeout = 100, .timeout = 100,
.latency = LATENCY_UNUSED, .latency = LATENCY_UNUSED,
.which_intinfo = 0,
.intinfo_count = 0, .intinfo_count = 0,
.intinfos = NULL }, .intinfos = NULL },
#endif #endif
{ DRV_LAST, NULL, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, NULL } { DRV_LAST, NULL, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, NULL }
}; };
#ifdef USE_BFLSC #ifdef USE_BFLSC
@ -1269,6 +1270,8 @@ static struct cg_usb_device *free_cgusb(struct cg_usb_device *cgusb)
static void _usb_uninit(struct cgpu_info *cgpu) static void _usb_uninit(struct cgpu_info *cgpu)
{ {
int ifinfo;
applog(LOG_DEBUG, "USB uninit %s%i", applog(LOG_DEBUG, "USB uninit %s%i",
cgpu->drv->name, cgpu->device_id); cgpu->drv->name, cgpu->device_id);
@ -1278,7 +1281,10 @@ static void _usb_uninit(struct cgpu_info *cgpu)
return; return;
if (cgpu->usbdev->handle) { if (cgpu->usbdev->handle) {
libusb_release_interface(cgpu->usbdev->handle, USBIF(cgpu->usbdev)); for (ifinfo = cgpu->usbdev->found->intinfo_count - 1; ifinfo >= 0; ifinfo--) {
libusb_release_interface(cgpu->usbdev->handle,
THISIF(cgpu->usbdev->found, ifinfo));
}
cg_wlock(&cgusb_fd_lock); cg_wlock(&cgusb_fd_lock);
libusb_close(cgpu->usbdev->handle); libusb_close(cgpu->usbdev->handle);
cgpu->usbdev->handle = NULL; cgpu->usbdev->handle = NULL;
@ -1306,7 +1312,7 @@ static void release_cgpu(struct cgpu_info *cgpu)
{ {
struct cg_usb_device *cgusb = cgpu->usbdev; struct cg_usb_device *cgusb = cgpu->usbdev;
struct cgpu_info *lookcgpu; struct cgpu_info *lookcgpu;
int which_intinfo, i; int i;
applog(LOG_DEBUG, "USB release %s%i", applog(LOG_DEBUG, "USB release %s%i",
cgpu->drv->name, cgpu->device_id); cgpu->drv->name, cgpu->device_id);
@ -1324,7 +1330,6 @@ static void release_cgpu(struct cgpu_info *cgpu)
cgtime(&cgpu->usbinfo.last_nodev); cgtime(&cgpu->usbinfo.last_nodev);
// Any devices sharing the same USB device should be marked also // Any devices sharing the same USB device should be marked also
// Currently only MMQ shares a USB device
for (i = 0; i < total_devices; i++) { for (i = 0; i < total_devices; i++) {
lookcgpu = get_devices(i); lookcgpu = get_devices(i);
if (lookcgpu != cgpu && lookcgpu->usbdev == cgusb) { if (lookcgpu != cgpu && lookcgpu->usbdev == cgusb) {
@ -1339,15 +1344,12 @@ static void release_cgpu(struct cgpu_info *cgpu)
} }
} }
which_intinfo = cgpu->usbdev->found->which_intinfo;
_usb_uninit(cgpu); _usb_uninit(cgpu);
if (which_intinfo == 0) cgminer_usb_unlock_bd(cgpu->drv, cgpu->usbinfo.bus_number, cgpu->usbinfo.device_address);
cgminer_usb_unlock_bd(cgpu->drv, cgpu->usbinfo.bus_number, cgpu->usbinfo.device_address);
} }
/* /*
* Used by MMQ - use the same usbdev thus locking is across all 4 related devices * Use the same usbdev thus locking is across all related devices
* since they must use the same USB handle since they use the same interface
*/ */
struct cgpu_info *usb_copy_cgpu(struct cgpu_info *orig) struct cgpu_info *usb_copy_cgpu(struct cgpu_info *orig)
{ {
@ -1371,80 +1373,11 @@ struct cgpu_info *usb_copy_cgpu(struct cgpu_info *orig)
copy->usbinfo.nodev = (copy->usbdev == NULL); copy->usbinfo.nodev = (copy->usbdev == NULL);
copy->usbinfo.devlock = orig->usbinfo.devlock;
DEVUNLOCK(orig, pstate); DEVUNLOCK(orig, pstate);
return copy; return copy;
} }
/*
* Used by CMR - use a different usbdev - since they must use a different
* USB handle due to using different interfaces (libusb requirement)
* N.B. multiple interfaces don't as yet work in windows libusb
* so the CMR defines above that use them are defined out in windows
* Nothing else uses multiple interfaces as at 20130922
*/
static struct cgpu_info *usb_dup_cgpu(struct cgpu_info *orig, int intinfo)
{
struct cgpu_info *copy;
copy = calloc(1, sizeof(*copy));
if (unlikely(!copy))
quit(1, "Failed to calloc cgpu for %s in usb_dup_cgpu", orig->drv->dname);
copy->name = orig->name;
copy->drv = copy_drv(orig->drv);
copy->deven = orig->deven;
copy->threads = orig->threads;
if (orig->usbdev) {
copy->usbdev = calloc(1, sizeof(*(copy->usbdev)));
if (unlikely(!copy->usbdev))
quit(1, "Failed to calloc usbdev for %s in usb_dup_cgpu", orig->drv->dname);
copy->usbdev->found = malloc(sizeof(*(copy->usbdev->found)));
if (unlikely(!copy->usbdev->found))
quit(1, "Failed to malloc found for %s in usb_dup_cgpu", orig->drv->dname);
memcpy(copy->usbdev->found, orig->usbdev->found, sizeof(*(copy->usbdev->found)));
copy->usbdev->found->which_intinfo = intinfo;
copy->usbdev->descriptor = NULL; // don't need it
copy->usbdev->usb_type = orig->usbdev->usb_type;
copy->usbdev->ident = orig->usbdev->ident;
copy->usbdev->usbver = orig->usbdev->usbver;
copy->usbdev->cps = orig->usbdev->cps;
copy->usbdev->usecps = orig->usbdev->usecps;
if (orig->usbdev->prod_string == BLANK)
copy->usbdev->prod_string = (char *)BLANK;
else
copy->usbdev->prod_string = strdup(orig->usbdev->prod_string);
if (orig->usbdev->manuf_string == BLANK)
copy->usbdev->manuf_string = (char *)BLANK;
else
copy->usbdev->manuf_string = strdup(orig->usbdev->manuf_string);
if (orig->usbdev->serial_string == BLANK)
copy->usbdev->serial_string = (char *)BLANK;
else
copy->usbdev->serial_string = strdup(orig->usbdev->serial_string);
copy->usbdev->fwVersion = orig->usbdev->fwVersion;
copy->usbdev->interfaceVersion = orig->usbdev->interfaceVersion;
}
memcpy(&(copy->usbinfo), &(orig->usbinfo), sizeof(copy->usbinfo));
copy->usbinfo.nodev = (copy->usbdev == NULL);
copy->usbinfo.devlock = calloc(1, sizeof(*(copy->usbinfo.devlock)));
if (unlikely(!copy->usbinfo.devlock))
quit(1, "Failed to calloc devlock for %s in usb_dup_cgpu", orig->drv->dname);
rwlock_init(copy->usbinfo.devlock);
return copy;
}
struct cgpu_info *usb_alloc_cgpu(struct device_drv *drv, int threads) struct cgpu_info *usb_alloc_cgpu(struct device_drv *drv, int threads)
{ {
struct cgpu_info *cgpu = calloc(1, sizeof(*cgpu)); struct cgpu_info *cgpu = calloc(1, sizeof(*cgpu));
@ -1497,7 +1430,7 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u
char devstr[STRBUFLEN+1]; char devstr[STRBUFLEN+1];
int err, ifinfo, epinfo, alt, epnum, pstate; int err, ifinfo, epinfo, alt, epnum, pstate;
int bad = USB_INIT_FAIL; int bad = USB_INIT_FAIL;
int cfg; int cfg, claimed = 0;
DEVLOCK(cgpu, pstate); DEVLOCK(cgpu, pstate);
@ -1508,7 +1441,7 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u
snprintf(devpath, sizeof(devpath), "%d:%d-i%d", snprintf(devpath, sizeof(devpath), "%d:%d-i%d",
(int)(cgpu->usbinfo.bus_number), (int)(cgpu->usbinfo.bus_number),
(int)(cgpu->usbinfo.device_address), (int)(cgpu->usbinfo.device_address),
FOUNDIF(found)); THISIF(found, 0));
} else { } else {
snprintf(devpath, sizeof(devpath), "%d:%d", snprintf(devpath, sizeof(devpath), "%d:%d",
(int)(cgpu->usbinfo.bus_number), (int)(cgpu->usbinfo.bus_number),
@ -1570,18 +1503,22 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u
} }
#ifndef WIN32 #ifndef WIN32
if (libusb_kernel_driver_active(cgusb->handle, FOUNDIF(found)) == 1) { for (ifinfo = 0; ifinfo < found->intinfo_count; ifinfo++) {
applog(LOG_DEBUG, "USB init, kernel attached ... %s", devstr); if (libusb_kernel_driver_active(cgusb->handle, THISIF(found, ifinfo)) == 1) {
err = libusb_detach_kernel_driver(cgusb->handle, FOUNDIF(found)); applog(LOG_DEBUG, "USB init, kernel attached ... %s", devstr);
if (err == 0) { err = libusb_detach_kernel_driver(cgusb->handle, THISIF(found, ifinfo));
applog(LOG_DEBUG, if (err == 0) {
"USB init, kernel detached interface %d successfully %s", applog(LOG_DEBUG,
FOUNDIF(found), devstr); "USB init, kernel detached ifinfo %d interface %d"
} else { " successfully %s",
applog(LOG_WARNING, ifinfo, THISIF(found, ifinfo), devstr);
"USB init, kernel detach interface %d failed, err %d in use? %s", } else {
FOUNDIF(found), err, devstr); applog(LOG_WARNING,
goto cldame; "USB init, kernel detach ifinfo %d interface %d failed,"
" err %d in use? %s",
ifinfo, THISIF(found, ifinfo), err, devstr);
goto cldame;
}
} }
} }
#endif #endif
@ -1704,20 +1641,26 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u
goto cldame; goto cldame;
} }
err = libusb_claim_interface(cgusb->handle, FOUNDIF(found)); claimed = 0;
if (err) { for (ifinfo = 0; ifinfo < found->intinfo_count; ifinfo++) {
switch(err) { err = libusb_claim_interface(cgusb->handle, THISIF(found, ifinfo));
case LIBUSB_ERROR_BUSY: if (err == 0)
applog(LOG_WARNING, claimed++;
"USB init, claim interface %d in use %s", else {
FOUNDIF(found), devstr); switch(err) {
break; case LIBUSB_ERROR_BUSY:
default: applog(LOG_WARNING,
applog(LOG_DEBUG, "USB init, claim ifinfo %d interface %d in use %s",
"USB init, claim interface %d failed, err %d %s", ifinfo, THISIF(found, ifinfo), devstr);
FOUNDIF(found), err, devstr); break;
default:
applog(LOG_DEBUG,
"USB init, claim ifinfo %d interface %d failed,"
" err %d %s",
ifinfo, THISIF(found, ifinfo), err, devstr);
}
goto reldame;
} }
goto reldame;
} }
cfg = -1; cfg = -1;
@ -1784,7 +1727,9 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u
reldame: reldame:
libusb_release_interface(cgusb->handle, FOUNDIF(found)); ifinfo = claimed;
while (ifinfo-- > 0)
libusb_release_interface(cgusb->handle, THISIF(found, ifinfo));
cldame: cldame:
@ -1806,144 +1751,6 @@ out_unlock:
return bad; return bad;
} }
// To get the extra interfaces on a multi interface device
struct cgpu_info *usb_init_intinfo(struct cgpu_info *orig, int intinfo)
{
struct usb_find_devices *found;
struct libusb_device *dev;
struct cgpu_info *copy = NULL;
char msgstr[STRBUFLEN+1];
char devstr[STRBUFLEN+1];
char devpath[32];
int err, pstate;
DEVLOCK(orig, pstate);
snprintf(msgstr, sizeof(msgstr), "USB %s init_intinfo (%d:%d-i%d)",
orig->drv->dname,
(int)(orig->usbinfo.bus_number),
(int)(orig->usbinfo.device_address),
orig->usbdev->found->which_intinfo);
if (orig->usbinfo.nodev) {
applog(LOG_ERR, "%s cgpu has nodev", msgstr);
goto Hitagi;
}
if (orig->usbdev->found->which_intinfo != 0) {
applog(LOG_ERR, "%s incorrect cgpu (must be i0)", msgstr);
goto Hitagi;
}
if (orig->usbdev->found->intinfo_count < 2) {
applog(LOG_ERR, "%s cgpu only has 1 interface", msgstr);
goto Hitagi;
}
if (intinfo < 1 || intinfo >= orig->usbdev->found->intinfo_count) {
applog(LOG_ERR, "%s invalid intinfo (%d) must be > 0 && < %d",
msgstr, intinfo, orig->usbdev->found->intinfo_count);
goto Hitagi;
}
dev = libusb_get_device(orig->usbdev->handle);
copy = usb_dup_cgpu(orig, intinfo);
if (!copy)
goto Hitagi;
found = copy->usbdev->found;
snprintf(devpath, sizeof(devpath), "%d:%d-i%d",
(int)(copy->usbinfo.bus_number),
(int)(copy->usbinfo.device_address),
FOUNDIF(found));
copy->device_path = strdup(devpath);
snprintf(devstr, sizeof(devstr), "- %s device %s", found->name, devpath);
cg_wlock(&cgusb_fd_lock);
err = libusb_open(dev, &(copy->usbdev->handle));
cg_wunlock(&cgusb_fd_lock);
if (err) {
switch (err) {
case LIBUSB_ERROR_ACCESS:
applog(LOG_ERR,
"USB init_intinfo, open device failed, err %d, "
"you don't have privilege to access %s",
err, devstr);
break;
#ifdef WIN32
// Windows specific message
case LIBUSB_ERROR_NOT_SUPPORTED:
applog(LOG_ERR,
"USB init_intinfo, open device failed, err %d, "
"you need to install a WinUSB driver for %s",
err, devstr);
break;
#endif
default:
applog(LOG_DEBUG,
"USB init_intinfo, open failed, err %d %s",
err, devstr);
}
goto Hitagi;
}
#ifndef WIN32
if (libusb_kernel_driver_active(copy->usbdev->handle, FOUNDIF(found)) == 1) {
applog(LOG_DEBUG, "USB init_intinfo, kernel attached ... %s", devstr);
err = libusb_detach_kernel_driver(copy->usbdev->handle, FOUNDIF(found));
if (err == 0) {
applog(LOG_DEBUG,
"USB init_intinfo, kernel detached interface %d successfully %s",
FOUNDIF(found), devstr);
} else {
applog(LOG_WARNING,
"USB init_intinfo, kernel detach interface %d failed, err %d in use? %s",
FOUNDIF(found), err, devstr);
goto HitagiClose;
}
}
#endif
err = libusb_claim_interface(copy->usbdev->handle, FOUNDIF(found));
if (err) {
switch(err) {
case LIBUSB_ERROR_BUSY:
applog(LOG_WARNING,
"USB init_intinfo, claim interface %d in use %s",
FOUNDIF(found), devstr);
break;
default:
applog(LOG_DEBUG,
"USB init_intinfo, claim interface %d failed, err %d %s",
FOUNDIF(found), err, devstr);
}
goto HitagiClose;
}
goto Hitagi;
HitagiClose:
cg_wlock(&cgusb_fd_lock);
libusb_close(copy->usbdev->handle);
copy->usbdev->handle = NULL;
cg_wunlock(&cgusb_fd_lock);
copy->usbdev = free_cgusb(copy->usbdev);
copy = usb_free_cgpu(copy);
Hitagi:
DEVUNLOCK(orig, pstate);
return copy;
}
bool usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct usb_find_devices *found_match) bool usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct usb_find_devices *found_match)
{ {
struct usb_find_devices *found_use = NULL; struct usb_find_devices *found_use = NULL;
@ -2502,7 +2309,7 @@ usb_bulk_transfer(struct libusb_device_handle *dev_handle,
return err; return err;
} }
int _usb_read(struct cgpu_info *cgpu, int epinfo, char *buf, size_t bufsiz, int *processed, unsigned int timeout, const char *end, enum usb_cmds cmd, bool readonce) int _usb_read(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t bufsiz, int *processed, unsigned int timeout, const char *end, enum usb_cmds cmd, bool readonce)
{ {
struct cg_usb_device *usbdev; struct cg_usb_device *usbdev;
bool ftdi; bool ftdi;
@ -2530,7 +2337,7 @@ int _usb_read(struct cgpu_info *cgpu, int epinfo, char *buf, size_t bufsiz, int
usbdev = cgpu->usbdev; usbdev = cgpu->usbdev;
ftdi = (usbdev->usb_type == USB_TYPE_FTDI); ftdi = (usbdev->usb_type == USB_TYPE_FTDI);
USBDEBUG("USB debug: _usb_read(%s (nodev=%s),epinfo=%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), epinfo, buf, bufsiz, processed, timeout, end ? (char *)str_text((char *)end) : "NULL", usb_cmdname(cmd), bool_str(ftdi), bool_str(readonce)); USBDEBUG("USB debug: _usb_read(%s (nodev=%s),intinfo=%d,epinfo=%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), intinfo, epinfo, 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, (int)bufsiz, USB_MAX_READ); quit(1, "%s USB read request %d too large (max=%d)", cgpu->drv->name, (int)bufsiz, USB_MAX_READ);
@ -2584,7 +2391,7 @@ int _usb_read(struct cgpu_info *cgpu, int epinfo, char *buf, size_t bufsiz, int
} }
} }
err = usb_bulk_transfer(usbdev->handle, err = usb_bulk_transfer(usbdev->handle,
USBEP(usbdev, epinfo), USBEP(usbdev, intinfo, epinfo),
ptr, usbbufread, &got, timeout, ptr, usbbufread, &got, timeout,
cgpu, MODE_BULK_READ, cmd, first ? SEQ0 : SEQ1); cgpu, MODE_BULK_READ, cmd, first ? SEQ0 : SEQ1);
cgtime(&tv_finish); cgtime(&tv_finish);
@ -2688,7 +2495,7 @@ int _usb_read(struct cgpu_info *cgpu, int epinfo, char *buf, size_t bufsiz, int
} }
} }
err = usb_bulk_transfer(usbdev->handle, err = usb_bulk_transfer(usbdev->handle,
USBEP(usbdev, epinfo), ptr, USBEP(usbdev, intinfo, epinfo), ptr,
usbbufread, &got, timeout, usbbufread, &got, timeout,
cgpu, MODE_BULK_READ, cmd, first ? SEQ0 : SEQ1); cgpu, MODE_BULK_READ, cmd, first ? SEQ0 : SEQ1);
cgtime(&tv_finish); cgtime(&tv_finish);
@ -2775,7 +2582,7 @@ out_unlock:
return err; return err;
} }
int _usb_write(struct cgpu_info *cgpu, int epinfo, char *buf, size_t bufsiz, int *processed, unsigned int timeout, enum usb_cmds cmd) int _usb_write(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t bufsiz, int *processed, unsigned int timeout, enum usb_cmds cmd)
{ {
struct cg_usb_device *usbdev; struct cg_usb_device *usbdev;
struct timeval read_start, tv_finish; struct timeval read_start, tv_finish;
@ -2786,7 +2593,7 @@ int _usb_write(struct cgpu_info *cgpu, int epinfo, char *buf, size_t bufsiz, int
DEVLOCK(cgpu, pstate); DEVLOCK(cgpu, pstate);
USBDEBUG("USB debug: _usb_write(%s (nodev=%s),epinfo=%d,buf='%s',bufsiz=%zu,proc=%p,timeout=%u,cmd=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), epinfo, (char *)str_text(buf), bufsiz, processed, timeout, usb_cmdname(cmd)); USBDEBUG("USB debug: _usb_write(%s (nodev=%s),intinfo=%d,epinfo=%d,buf='%s',bufsiz=%zu,proc=%p,timeout=%u,cmd=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), intinfo, epinfo, (char *)str_text(buf), bufsiz, processed, timeout, usb_cmdname(cmd));
*processed = 0; *processed = 0;
@ -2829,7 +2636,7 @@ int _usb_write(struct cgpu_info *cgpu, int epinfo, char *buf, size_t bufsiz, int
usbdev->last_write_siz = bufsiz; usbdev->last_write_siz = bufsiz;
} }
err = usb_bulk_transfer(usbdev->handle, err = usb_bulk_transfer(usbdev->handle,
USBEP(usbdev, epinfo), USBEP(usbdev, intinfo, epinfo),
(unsigned char *)buf, bufsiz, &sent, (unsigned char *)buf, bufsiz, &sent,
timeout, cgpu, MODE_BULK_WRITE, cmd, first ? SEQ0 : SEQ1); timeout, cgpu, MODE_BULK_WRITE, cmd, first ? SEQ0 : SEQ1);
cgtime(&tv_finish); cgtime(&tv_finish);
@ -3046,7 +2853,7 @@ int usb_ftdi_cts(struct cgpu_info *cgpu)
return (ret & FTDI_RS0_CTS); return (ret & FTDI_RS0_CTS);
} }
int usb_ftdi_set_latency(struct cgpu_info *cgpu) int _usb_ftdi_set_latency(struct cgpu_info *cgpu, int intinfo)
{ {
int err = 0; int err = 0;
int pstate; int pstate;
@ -3067,7 +2874,7 @@ int usb_ftdi_set_latency(struct cgpu_info *cgpu)
if (!err) if (!err)
err = __usb_transfer(cgpu, FTDI_TYPE_OUT, FTDI_REQUEST_LATENCY, err = __usb_transfer(cgpu, FTDI_TYPE_OUT, FTDI_REQUEST_LATENCY,
cgpu->usbdev->found->latency, cgpu->usbdev->found->latency,
USBIF(cgpu->usbdev), USBIF(cgpu->usbdev, intinfo),
NULL, 0, DEVTIMEOUT, C_LATENCY); NULL, 0, DEVTIMEOUT, C_LATENCY);
} }
@ -3185,8 +2992,10 @@ void usb_disable_cps(struct cgpu_info *cgpu)
* The value returned (0) when usbdev is NULL * The value returned (0) when usbdev is NULL
* doesn't matter since it also means the next call to * doesn't matter since it also means the next call to
* any usbutils function will fail with a nodev * any usbutils function will fail with a nodev
* N.B. this is to get the interface number to use in a control_transfer
* which for some devices isn't actually the interface number
*/ */
int usb_interface(struct cgpu_info *cgpu) int _usb_interface(struct cgpu_info *cgpu, int intinfo)
{ {
int interface = 0; int interface = 0;
int pstate; int pstate;
@ -3194,7 +3003,7 @@ int usb_interface(struct cgpu_info *cgpu)
DEVLOCK(cgpu, pstate); DEVLOCK(cgpu, pstate);
if (cgpu->usbdev) if (cgpu->usbdev)
interface = USBIF(cgpu->usbdev); interface = cgpu->usbdev->found->intinfos[intinfo].ctrl_transfer;
DEVUNLOCK(cgpu, pstate); DEVUNLOCK(cgpu, pstate);

50
usbutils.h

@ -109,6 +109,9 @@
// Use the device defined timeout // Use the device defined timeout
#define DEVTIMEOUT 0 #define DEVTIMEOUT 0
// The default intinfo structure used is the first one
#define DEFAULT_INTINFO 0
// For endpoints defined in usb_find_devices.intinfos.epinfos, // For endpoints defined in usb_find_devices.intinfos.epinfos,
// the first two must be the default IN and OUT and both must always exist // the first two must be the default IN and OUT and both must always exist
#define DEFAULT_EP_IN 0 #define DEFAULT_EP_IN 0
@ -123,6 +126,7 @@ struct usb_epinfo {
struct usb_intinfo { struct usb_intinfo {
int interface; int interface;
int ctrl_transfer;
int epinfo_count; int epinfo_count;
struct usb_epinfo *epinfos; struct usb_epinfo *epinfos;
}; };
@ -158,7 +162,6 @@ struct usb_find_devices {
unsigned int timeout; unsigned int timeout;
uint16_t wMaxPacketSize; uint16_t wMaxPacketSize;
uint16_t latency; uint16_t latency;
int which_intinfo;
int intinfo_count; int intinfo_count;
struct usb_intinfo *intinfos; struct usb_intinfo *intinfos;
}; };
@ -341,17 +344,17 @@ struct cgpu_info *usb_alloc_cgpu(struct device_drv *drv, int threads);
struct cgpu_info *usb_free_cgpu_devlock(struct cgpu_info *cgpu, bool free_devlock); struct cgpu_info *usb_free_cgpu_devlock(struct cgpu_info *cgpu, bool free_devlock);
#define usb_free_cgpu(cgpu) usb_free_cgpu_devlock(cgpu, true) #define usb_free_cgpu(cgpu) usb_free_cgpu_devlock(cgpu, true)
void usb_uninit(struct cgpu_info *cgpu); void usb_uninit(struct cgpu_info *cgpu);
struct cgpu_info *usb_init_intinfo(struct cgpu_info *orig, int intinfo);
bool usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct usb_find_devices *found); bool usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct usb_find_devices *found);
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 readonce); int _usb_read(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t bufsiz, int *processed, unsigned int timeout, const char *end, enum usb_cmds cmd, 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 intinfo, int epinfo, 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);
int usb_ftdi_cts(struct cgpu_info *cgpu); int usb_ftdi_cts(struct cgpu_info *cgpu);
int usb_ftdi_set_latency(struct cgpu_info *cgpu); int _usb_ftdi_set_latency(struct cgpu_info *cgpu, int intinfo);
#define usb_ftdi_set_latency(_cgpu) _usb_ftdi_set_latency(_cgpu, DEFAULT_INTINFO)
void usb_buffer_enable(struct cgpu_info *cgpu); void usb_buffer_enable(struct cgpu_info *cgpu);
void usb_buffer_disable(struct cgpu_info *cgpu); void usb_buffer_disable(struct cgpu_info *cgpu);
void usb_buffer_clear(struct cgpu_info *cgpu); void usb_buffer_clear(struct cgpu_info *cgpu);
@ -359,7 +362,8 @@ uint32_t usb_buffer_size(struct cgpu_info *cgpu);
void usb_set_cps(struct cgpu_info *cgpu, int cps); void usb_set_cps(struct cgpu_info *cgpu, int cps);
void usb_enable_cps(struct cgpu_info *cgpu); void usb_enable_cps(struct cgpu_info *cgpu);
void usb_disable_cps(struct cgpu_info *cgpu); void usb_disable_cps(struct cgpu_info *cgpu);
int usb_interface(struct cgpu_info *cgpu); int _usb_interface(struct cgpu_info *cgpu, int intinfo);
#define usb_interface(_cgpu) _usb_interface(_cgpu, DEFAULT_INTINFO)
enum sub_ident usb_ident(struct cgpu_info *cgpu); enum sub_ident usb_ident(struct cgpu_info *cgpu);
void usb_set_pps(struct cgpu_info *cgpu, uint16_t PrefPacketSize); void usb_set_pps(struct cgpu_info *cgpu, uint16_t PrefPacketSize);
void usb_set_dev_start(struct cgpu_info *cgpu); void usb_set_dev_start(struct cgpu_info *cgpu);
@ -368,46 +372,52 @@ void usb_initialise();
void *usb_resource_thread(void *userdata); void *usb_resource_thread(void *userdata);
#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_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false)
#define usb_read_once(cgpu, buf, bufsiz, read, cmd) \ #define usb_read_once(cgpu, buf, bufsiz, read, cmd) \
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, true) _usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, true)
#define usb_read_once_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \ #define usb_read_once_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, true) _usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, 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_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "\n", cmd, false)
#define usb_read_nl_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \ #define usb_read_nl_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, timeout, "\n", cmd, false) _usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, timeout, "\n", cmd, false)
#define usb_read_ok(cgpu, buf, bufsiz, read, cmd) \ #define usb_read_ok(cgpu, buf, bufsiz, read, cmd) \
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "OK\n", cmd, false) _usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "OK\n", cmd, false)
#define usb_read_ok_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \ #define usb_read_ok_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, timeout, "OK\n", cmd, false) _usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, timeout, "OK\n", cmd, 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, DEFAULT_INTINFO, ep, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, 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_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, false)
#define usb_read_ii_timeout(cgpu, intinfo, buf, bufsiz, read, timeout, cmd) \
_usb_read(cgpu, intinfo, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, 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, DEFAULT_INTINFO, ep, buf, bufsiz, read, timeout, NULL, cmd, 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_INTINFO, DEFAULT_EP_OUT, buf, bufsiz, wrote, DEVTIMEOUT, cmd)
#define usb_write_ii(cgpu, intinfo, buf, bufsiz, wrote, cmd) \
_usb_write(cgpu, intinfo, DEFAULT_EP_OUT, buf, bufsiz, wrote, DEVTIMEOUT, cmd)
#define usb_write_ep(cgpu, ep, buf, bufsiz, wrote, cmd) \ #define usb_write_ep(cgpu, ep, buf, bufsiz, wrote, cmd) \
_usb_write(cgpu, ep, buf, bufsiz, wrote, DEVTIMEOUT, cmd) _usb_write(cgpu, DEFAULT_INTINFO, ep, buf, bufsiz, wrote, DEVTIMEOUT, cmd)
#define usb_write_timeout(cgpu, buf, bufsiz, wrote, timeout, cmd) \ #define usb_write_timeout(cgpu, buf, bufsiz, wrote, timeout, cmd) \
_usb_write(cgpu, DEFAULT_EP_OUT, buf, bufsiz, wrote, timeout, cmd) _usb_write(cgpu, DEFAULT_INTINFO, DEFAULT_EP_OUT, buf, bufsiz, wrote, timeout, cmd)
#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, DEFAULT_INTINFO, ep, buf, bufsiz, wrote, timeout, cmd)
#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, NULL, 0, DEVTIMEOUT, cmd) _usb_transfer(cgpu, typ, req, val, idx, NULL, 0, DEVTIMEOUT, cmd)

Loading…
Cancel
Save