From 84de52c1c659da16c361f3471c6214f976e090ac Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 13 Oct 2013 10:11:46 +1100 Subject: [PATCH] Use a write lock when performing any USB control transfers to prevent concurrent transfers. --- usbutils.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/usbutils.c b/usbutils.c index 2ec6df5f..00bfcce7 100644 --- a/usbutils.c +++ b/usbutils.c @@ -2812,21 +2812,22 @@ out_: return err; } +/* We use the write devlock for control transfers since some control transfers + * are rare but may be changing settings within the device causing problems + * if concurrent transfers are happening. Using the write lock serialises + * any transfers. */ 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; - DEVRLOCK(cgpu, pstate); + DEVWLOCK(cgpu, pstate); err = __usb_transfer(cgpu, request_type, bRequest, wValue, wIndex, data, siz, timeout, cmd); - if (NOCONTROLDEV(err)) { - cg_ruwlock(&cgpu->usbinfo.devlock); + if (NOCONTROLDEV(err)) release_cgpu(cgpu); - cg_dwlock(&cgpu->usbinfo.devlock); - } - DEVRUNLOCK(cgpu, pstate); + DEVWUNLOCK(cgpu, pstate); return err; } @@ -2840,7 +2841,7 @@ int _usb_transfer_read(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRe unsigned char tbuf[64]; int err, pstate; - DEVRLOCK(cgpu, pstate); + DEVWLOCK(cgpu, pstate); USBDEBUG("USB debug: _usb_transfer_read(%s (nodev=%s),type=%"PRIu8",req=%"PRIu8",value=%"PRIu16",index=%"PRIu16",bufsiz=%d,timeout=%u,cmd=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), request_type, bRequest, wValue, wIndex, bufsiz, timeout, usb_cmdname(cmd)); @@ -2896,13 +2897,10 @@ int _usb_transfer_read(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRe err, libusb_error_name(err)); } out_noerrmsg: - if (NOCONTROLDEV(err)) { - cg_ruwlock(&cgpu->usbinfo.devlock); + if (NOCONTROLDEV(err)) release_cgpu(cgpu); - cg_dwlock(&cgpu->usbinfo.devlock); - } - DEVRUNLOCK(cgpu, pstate); + DEVWUNLOCK(cgpu, pstate); return err; }