Browse Source

Merge pull request #445 from kanoi/lock

usb lock out transfers during open/close
nfactor-troky
kanoi 12 years ago
parent
commit
326116f6ed
  1. 2
      cgminer.c
  2. 1
      miner.h
  3. 19
      usbutils.c

2
cgminer.c

@ -185,6 +185,7 @@ int hotplug_time = 5;
#ifdef USE_USBUTILS #ifdef USE_USBUTILS
pthread_mutex_t cgusb_lock; pthread_mutex_t cgusb_lock;
pthread_mutex_t cgusbres_lock; pthread_mutex_t cgusbres_lock;
cglock_t cgusb_fd_lock;
#endif #endif
pthread_mutex_t hash_lock; pthread_mutex_t hash_lock;
@ -7339,6 +7340,7 @@ int main(int argc, char *argv[])
#ifdef USE_USBUTILS #ifdef USE_USBUTILS
mutex_init(&cgusb_lock); mutex_init(&cgusb_lock);
mutex_init(&cgusbres_lock); mutex_init(&cgusbres_lock);
cglock_init(&cgusb_fd_lock);
#endif #endif
#endif #endif

1
miner.h

@ -897,6 +897,7 @@ extern int opt_expiry;
#ifdef USE_USBUTILS #ifdef USE_USBUTILS
extern pthread_mutex_t cgusb_lock; extern pthread_mutex_t cgusb_lock;
extern pthread_mutex_t cgusbres_lock; extern pthread_mutex_t cgusbres_lock;
extern cglock_t cgusb_fd_lock;
#endif #endif
extern cglock_t control_lock; extern cglock_t control_lock;

19
usbutils.c

@ -1338,8 +1338,11 @@ 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, cgpu->usbdev->found->interface)) if (!libusb_release_interface(cgpu->usbdev->handle, cgpu->usbdev->found->interface)) {
cg_wlock(&cgusb_fd_lock);
libusb_close(cgpu->usbdev->handle); libusb_close(cgpu->usbdev->handle);
cg_wunlock(&cgusb_fd_lock);
}
cgpu->usbdev = free_cgusb(cgpu->usbdev); cgpu->usbdev = free_cgusb(cgpu->usbdev);
} }
@ -1517,7 +1520,9 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u
goto dame; goto dame;
} }
cg_wlock(&cgusb_fd_lock);
err = libusb_open(dev, &(cgusb->handle)); err = libusb_open(dev, &(cgusb->handle));
cg_wunlock(&cgusb_fd_lock);
if (err) { if (err) {
switch (err) { switch (err) {
case LIBUSB_ERROR_ACCESS: case LIBUSB_ERROR_ACCESS:
@ -1727,7 +1732,9 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u
cldame: cldame:
cg_wlock(&cgusb_fd_lock);
libusb_close(cgusb->handle); libusb_close(cgusb->handle);
cg_wunlock(&cgusb_fd_lock);
dame: dame:
@ -2177,8 +2184,11 @@ usb_bulk_transfer(struct libusb_device_handle *dev_handle,
{ {
int err, tries = 0; int err, tries = 0;
cg_rlock(&cgusb_fd_lock);
err = libusb_bulk_transfer(dev_handle, endpoint, data, length, err = libusb_bulk_transfer(dev_handle, endpoint, data, length,
transferred, timeout); transferred, timeout);
cg_runlock(&cgusb_fd_lock);
if (unlikely(err == LIBUSB_ERROR_PIPE)) { if (unlikely(err == LIBUSB_ERROR_PIPE)) {
applog(LOG_WARNING, "%s: libusb pipe error, trying to clear", applog(LOG_WARNING, "%s: libusb pipe error, trying to clear",
cgpu->drv->name); cgpu->drv->name);
@ -2187,8 +2197,11 @@ usb_bulk_transfer(struct libusb_device_handle *dev_handle,
if (unlikely(err == LIBUSB_ERROR_NOT_FOUND || if (unlikely(err == LIBUSB_ERROR_NOT_FOUND ||
err == LIBUSB_ERROR_NO_DEVICE)) err == LIBUSB_ERROR_NO_DEVICE))
break; break;
cg_rlock(&cgusb_fd_lock);
err = libusb_bulk_transfer(dev_handle, endpoint, data, err = libusb_bulk_transfer(dev_handle, endpoint, data,
length, transferred, timeout); length, transferred, timeout);
cg_runlock(&cgusb_fd_lock);
} while (err == LIBUSB_ERROR_PIPE && tries++ < USB_RETRY_MAX); } while (err == LIBUSB_ERROR_PIPE && tries++ < USB_RETRY_MAX);
applog(LOG_DEBUG, "%s: libusb pipe error%scleared", applog(LOG_DEBUG, "%s: libusb pipe error%scleared",
cgpu->drv->name, err ? " not " : " "); cgpu->drv->name, err ? " not " : " ");
@ -2565,9 +2578,11 @@ int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest
USBDEBUG("USB debug: @_usb_transfer() buf=%s", bin2hex((unsigned char *)buf, (size_t)siz)); USBDEBUG("USB debug: @_usb_transfer() buf=%s", bin2hex((unsigned char *)buf, (size_t)siz));
STATS_TIMEVAL(&tv_start); STATS_TIMEVAL(&tv_start);
cg_rlock(&cgusb_fd_lock);
err = libusb_control_transfer(usbdev->handle, request_type, err = libusb_control_transfer(usbdev->handle, request_type,
bRequest, wValue, wIndex, (unsigned char *)buf, (uint16_t)siz, bRequest, wValue, wIndex, (unsigned char *)buf, (uint16_t)siz,
timeout == DEVTIMEOUT ? usbdev->found->timeout : timeout); timeout == DEVTIMEOUT ? usbdev->found->timeout : timeout);
cg_runlock(&cgusb_fd_lock);
STATS_TIMEVAL(&tv_finish); STATS_TIMEVAL(&tv_finish);
USB_STATS(cgpu, &tv_start, &tv_finish, err, MODE_CTRL_WRITE, cmd, SEQ0); USB_STATS(cgpu, &tv_start, &tv_finish, err, MODE_CTRL_WRITE, cmd, SEQ0);
@ -2610,10 +2625,12 @@ int _usb_transfer_read(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRe
*amount = 0; *amount = 0;
STATS_TIMEVAL(&tv_start); STATS_TIMEVAL(&tv_start);
cg_rlock(&cgusb_fd_lock);
err = libusb_control_transfer(usbdev->handle, request_type, err = libusb_control_transfer(usbdev->handle, request_type,
bRequest, wValue, wIndex, bRequest, wValue, wIndex,
(unsigned char *)buf, (uint16_t)bufsiz, (unsigned char *)buf, (uint16_t)bufsiz,
timeout == DEVTIMEOUT ? usbdev->found->timeout : timeout); timeout == DEVTIMEOUT ? usbdev->found->timeout : timeout);
cg_runlock(&cgusb_fd_lock);
STATS_TIMEVAL(&tv_finish); STATS_TIMEVAL(&tv_finish);
USB_STATS(cgpu, &tv_start, &tv_finish, err, MODE_CTRL_READ, cmd, SEQ0); USB_STATS(cgpu, &tv_start, &tv_finish, err, MODE_CTRL_READ, cmd, SEQ0);

Loading…
Cancel
Save