diff --git a/usbutils.c b/usbutils.c index 6710d480..fd0c64bb 100644 --- a/usbutils.c +++ b/usbutils.c @@ -2542,16 +2542,14 @@ out_unlock: return err; } -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, __maybe_unused 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, __maybe_unused enum usb_cmds cmd) { struct cg_usb_device *usbdev; #if DO_USB_STATS struct timeval tv_start, tv_finish; #endif uint32_t *buf = NULL; - int err, i, bufsiz, pstate; - - DEVLOCK(cgpu, pstate); + int err, i, bufsiz; USBDEBUG("USB debug: _usb_transfer(%s (nodev=%s),type=%"PRIu8",req=%"PRIu8",value=%"PRIu16",index=%"PRIu16",siz=%d,timeout=%u,cmd=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), request_type, bRequest, wValue, wIndex, siz, timeout, usb_cmdname(cmd)); @@ -2559,7 +2557,7 @@ int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest USB_REJECT(cgpu, MODE_CTRL_WRITE); err = LIBUSB_ERROR_NO_DEVICE; - goto out_unlock; + goto out_; } usbdev = cgpu->usbdev; @@ -2591,13 +2589,23 @@ int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest IOERR_CHECK(cgpu, err); - if (buf) - free(buf); + free(buf); if (NOCONTROLDEV(err)) release_cgpu(cgpu); -out_unlock: +out_: + return err; +} + +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 pstate, err; + + DEVLOCK(cgpu, pstate); + + err = __usb_transfer(cgpu, request_type, bRequest, wValue, wIndex, data, siz, timeout, cmd); + DEVUNLOCK(cgpu, pstate); return err; @@ -2677,23 +2685,30 @@ int usb_ftdi_cts(struct cgpu_info *cgpu) int usb_ftdi_set_latency(struct cgpu_info *cgpu) { - int err; + int err = 0; + int pstate; - if (cgpu->usbdev->usb_type != USB_TYPE_FTDI) { - applog(LOG_ERR, "%s: cgid %d latency request on non-FTDI device", - cgpu->drv->name, cgpu->cgminer_id); - return LIBUSB_ERROR_NOT_SUPPORTED; - } + DEVLOCK(cgpu, pstate); + + if (cgpu->usbdev) { + if (cgpu->usbdev->usb_type != USB_TYPE_FTDI) { + applog(LOG_ERR, "%s: cgid %d latency request on non-FTDI device", + cgpu->drv->name, cgpu->cgminer_id); + err = LIBUSB_ERROR_NOT_SUPPORTED; + } else if (cgpu->usbdev->found->latency == LATENCY_UNUSED) { + applog(LOG_ERR, "%s: cgid %d invalid latency (UNUSED)", + cgpu->drv->name, cgpu->cgminer_id); + err = LIBUSB_ERROR_NOT_SUPPORTED; + } - if (cgpu->usbdev->found->latency == LATENCY_UNUSED) { - applog(LOG_ERR, "%s: cgid %d invalid latency (UNUSED)", - cgpu->drv->name, cgpu->cgminer_id); - return LIBUSB_ERROR_NOT_SUPPORTED; + if (!err) + err = __usb_transfer(cgpu, FTDI_TYPE_OUT, FTDI_REQUEST_LATENCY, + cgpu->usbdev->found->latency, + cgpu->usbdev->found->interface, + NULL, 0, DEVTIMEOUT, C_LATENCY); } - err = usb_transfer_data(cgpu, FTDI_TYPE_OUT, FTDI_REQUEST_LATENCY, - cgpu->usbdev->found->latency, - cgpu->usbdev->found->interface, NULL, 0, C_LATENCY); + DEVUNLOCK(cgpu, pstate); applog(LOG_DEBUG, "%s: cgid %d %s got err %d", cgpu->drv->name, cgpu->cgminer_id, @@ -2704,9 +2719,13 @@ int usb_ftdi_set_latency(struct cgpu_info *cgpu) void usb_buffer_enable(struct cgpu_info *cgpu) { - struct cg_usb_device *cgusb = cgpu->usbdev; + struct cg_usb_device *cgusb; + int pstate; + + DEVLOCK(cgpu, pstate); - if (!cgusb->buffer) { + cgusb = cgpu->usbdev; + if (cgusb && !cgusb->buffer) { cgusb->bufamt = 0; cgusb->buffer = malloc(USB_MAX_READ+1); if (!cgusb->buffer) @@ -2714,40 +2733,66 @@ void usb_buffer_enable(struct cgpu_info *cgpu) cgpu->drv->name, cgpu->device_id); cgusb->bufsiz = USB_MAX_READ; } + + DEVUNLOCK(cgpu, pstate); } void usb_buffer_disable(struct cgpu_info *cgpu) { - struct cg_usb_device *cgusb = cgpu->usbdev; + struct cg_usb_device *cgusb; + int pstate; + + DEVLOCK(cgpu, pstate); - if (cgusb->buffer) { + cgusb = cgpu->usbdev; + if (cgusb && cgusb->buffer) { cgusb->bufamt = 0; cgusb->bufsiz = 0; free(cgusb->buffer); cgusb->buffer = NULL; } + + DEVUNLOCK(cgpu, pstate); } void usb_buffer_clear(struct cgpu_info *cgpu) { - struct cg_usb_device *cgusb = cgpu->usbdev; + int pstate; - cgusb->bufamt = 0; + DEVLOCK(cgpu, pstate); + + if (cgpu->usbdev) + cgpu->usbdev->bufamt = 0; + + DEVUNLOCK(cgpu, pstate); } uint32_t usb_buffer_size(struct cgpu_info *cgpu) { - struct cg_usb_device *cgusb = cgpu->usbdev; + uint32_t ret = 0; + int pstate; - return cgusb->bufamt; + DEVLOCK(cgpu, pstate); + + if (cgpu->usbdev) + ret = cgpu->usbdev->bufamt; + + DEVUNLOCK(cgpu, pstate); + + return ret; } // Need to set all devices with matching usbdev void usb_set_dev_start(struct cgpu_info *cgpu) { - struct cg_usb_device *cgusb = cgpu->usbdev; + struct cg_usb_device *cgusb; struct cgpu_info *cgpu2; struct timeval now; + int pstate; + + DEVLOCK(cgpu, pstate); + + cgusb = cgpu->usbdev; // If the device wasn't dropped if (cgusb != NULL) { @@ -2761,6 +2806,8 @@ void usb_set_dev_start(struct cgpu_info *cgpu) copy_time(&(cgpu2->dev_start_tv), &now); } } + + DEVUNLOCK(cgpu, pstate); } void usb_cleanup()