Browse Source

usbutils specifically track handles and interfaces

nfactor-troky
Kano 11 years ago
parent
commit
67b9ee4448
  1. 71
      usbutils.c
  2. 1
      usbutils.h

71
usbutils.c

@ -25,6 +25,22 @@
#define NOCONTROLDEV(err) ((err) == LIBUSB_ERROR_NO_DEVICE || \ #define NOCONTROLDEV(err) ((err) == LIBUSB_ERROR_NO_DEVICE || \
(err) == LIBUSB_ERROR_OTHER) (err) == LIBUSB_ERROR_OTHER)
/*
* WARNING - these assume DEVLOCK(cgpu, pstate) is called first and
* DEVUNLOCK(cgpu, pstate) in called in the same function with the same pstate
* given to DEVLOCK.
* You must call DEVUNLOCK(cgpu, pstate) before exiting the function or it will leave
* the thread Cancelability unrestored
*/
#define DEVLOCK(cgpu, _pth_state) do { \
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &_pth_state); \
wr_lock(cgpu->usbinfo.devlock); \
} while (0)
#define DEVUNLOCK(cgpu, _pth_state) do { \
wr_unlock(cgpu->usbinfo.devlock); \
pthread_setcancelstate(_pth_state, NULL); \
} while (0)
#ifdef USE_BFLSC #ifdef USE_BFLSC
#define DRV_BFLSC 1 #define DRV_BFLSC 1
@ -1387,7 +1403,7 @@ static struct cg_usb_device *free_cgusb(struct cg_usb_device *cgusb)
return NULL; return NULL;
} }
void usb_uninit(struct cgpu_info *cgpu) void _usb_uninit(struct cgpu_info *cgpu)
{ {
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);
@ -1396,14 +1412,34 @@ void usb_uninit(struct cgpu_info *cgpu)
// if release_cgpu() was called due to a USB NODEV(err) // if release_cgpu() was called due to a USB NODEV(err)
if (!cgpu->usbdev) if (!cgpu->usbdev)
return; return;
if (!libusb_release_interface(cgpu->usbdev->handle, USBIF(cgpu->usbdev))) { if (cgpu->usbdev->handle) {
int ifinfo = 0;
while (cgpu->usbdev->claimed > 0) {
libusb_release_interface(cgpu->usbdev->handle,
cgpu->usbdev->found->intinfos[ifinfo].interface);
ifinfo++;
cgpu->usbdev->claimed--;
}
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->claimed = 0;
cg_wunlock(&cgusb_fd_lock); cg_wunlock(&cgusb_fd_lock);
} }
cgpu->usbdev = free_cgusb(cgpu->usbdev); cgpu->usbdev = free_cgusb(cgpu->usbdev);
} }
void usb_uninit(struct cgpu_info *cgpu)
{
int pstate;
DEVLOCK(cgpu, pstate);
_usb_uninit(cgpu);
DEVUNLOCK(cgpu, pstate);
}
/* /*
* N.B. this is always called inside * N.B. this is always called inside
* DEVLOCK(cgpu, pstate); * DEVLOCK(cgpu, pstate);
@ -1445,7 +1481,7 @@ static void release_cgpu(struct cgpu_info *cgpu)
} }
} }
usb_uninit(cgpu); _usb_uninit(cgpu);
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);
} }
@ -1515,23 +1551,6 @@ struct cgpu_info *usb_free_cgpu_devlock(struct cgpu_info *cgpu, bool free_devloc
#define USB_INIT_OK 1 #define USB_INIT_OK 1
#define USB_INIT_IGNORE 2 #define USB_INIT_IGNORE 2
/*
* WARNING - these assume DEVLOCK(cgpu, pstate) is called first and
* DEVUNLOCK(cgpu, pstate) in called in the same function with the same pstate
* given to DEVLOCK.
* You must call DEVUNLOCK(cgpu, pstate) before exiting the function or it will leave
* the thread Cancelability unrestored
*/
#define DEVLOCK(cgpu, _pth_state) do { \
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &_pth_state); \
wr_lock(cgpu->usbinfo.devlock); \
} while (0)
#define DEVUNLOCK(cgpu, _pth_state) do { \
wr_unlock(cgpu->usbinfo.devlock); \
pthread_setcancelstate(_pth_state, NULL); \
} while (0)
static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct usb_find_devices *found) static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct usb_find_devices *found)
{ {
struct cg_usb_device *cgusb = NULL; struct cg_usb_device *cgusb = NULL;
@ -1543,7 +1562,6 @@ 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 claimed = -1;
int cfg; int cfg;
DEVLOCK(cgpu, pstate); DEVLOCK(cgpu, pstate);
@ -1744,6 +1762,7 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u
goto cldame; goto cldame;
} }
cgusb->claimed = 0;
for (ifinfo = 0; ifinfo < found->intinfo_count; ifinfo++) { for (ifinfo = 0; ifinfo < found->intinfo_count; ifinfo++) {
int interface = found->intinfos[ifinfo].interface; int interface = found->intinfos[ifinfo].interface;
err = libusb_claim_interface(cgusb->handle, interface); err = libusb_claim_interface(cgusb->handle, interface);
@ -1761,7 +1780,7 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u
} }
goto reldame; goto reldame;
} }
claimed = ifinfo; cgusb->claimed++;
} }
cfg = -1; cfg = -1;
@ -1828,13 +1847,19 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u
reldame: reldame:
for (ifinfo = claimed; ifinfo >= 0; ifinfo--) ifinfo = 0;
while (cgusb->claimed > 0) {
libusb_release_interface(cgusb->handle, found->intinfos[ifinfo].interface); libusb_release_interface(cgusb->handle, found->intinfos[ifinfo].interface);
ifinfo++;
cgusb->claimed--;
}
cldame: cldame:
cg_wlock(&cgusb_fd_lock); cg_wlock(&cgusb_fd_lock);
libusb_close(cgusb->handle); libusb_close(cgusb->handle);
cgusb->handle = NULL;
cgusb->claimed = 0;
cg_wunlock(&cgusb_fd_lock); cg_wunlock(&cgusb_fd_lock);
dame: dame:

1
usbutils.h

@ -178,6 +178,7 @@ enum usb_types {
struct cg_usb_device { struct cg_usb_device {
struct usb_find_devices *found; struct usb_find_devices *found;
libusb_device_handle *handle; libusb_device_handle *handle;
int claimed;
pthread_mutex_t *mutex; pthread_mutex_t *mutex;
struct libusb_device_descriptor *descriptor; struct libusb_device_descriptor *descriptor;
enum usb_types usb_type; enum usb_types usb_type;

Loading…
Cancel
Save