V4L/DVB (9647): em28xx: void having two concurrent control URB's
Now that we have a polling task for IR, there's a race condition, since IR can be polling while other operations are being doing. Also, we are now sharing the same urb_buf for both read and write control urb operations. So, we need a mutex. Thanks to Davin Heitmueller <devin.heitmueller@gmail.com> for warning me. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
c4a98793a6
commit
f2a2e49105
|
@ -76,18 +76,22 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
|
||||||
|
|
||||||
em28xx_regdbg("req=%02x, reg=%02x ", req, reg);
|
em28xx_regdbg("req=%02x, reg=%02x ", req, reg);
|
||||||
|
|
||||||
|
mutex_lock(&dev->ctrl_urb_lock);
|
||||||
ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
|
ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
|
||||||
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||||
0x0000, reg, dev->urb_buf, len, HZ);
|
0x0000, reg, dev->urb_buf, len, HZ);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (reg_debug)
|
if (reg_debug)
|
||||||
printk(" failed!\n");
|
printk(" failed!\n");
|
||||||
|
mutex_unlock(&dev->ctrl_urb_lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len)
|
if (len)
|
||||||
memcpy(buf, dev->urb_buf, len);
|
memcpy(buf, dev->urb_buf, len);
|
||||||
|
|
||||||
|
mutex_unlock(&dev->ctrl_urb_lock);
|
||||||
|
|
||||||
if (reg_debug) {
|
if (reg_debug) {
|
||||||
printk("%02x values: ", ret);
|
printk("%02x values: ", ret);
|
||||||
for (byte = 0; byte < len; byte++)
|
for (byte = 0; byte < len; byte++)
|
||||||
|
@ -112,16 +116,18 @@ int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg)
|
||||||
|
|
||||||
em28xx_regdbg("req=%02x, reg=%02x:", req, reg);
|
em28xx_regdbg("req=%02x, reg=%02x:", req, reg);
|
||||||
|
|
||||||
|
mutex_lock(&dev->ctrl_urb_lock);
|
||||||
ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
|
ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
|
||||||
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||||
0x0000, reg, dev->urb_buf, 1, HZ);
|
0x0000, reg, dev->urb_buf, 1, HZ);
|
||||||
|
val = dev->urb_buf[0];
|
||||||
|
mutex_unlock(&dev->ctrl_urb_lock);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(" failed!\n");
|
printk(" failed!\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = dev->urb_buf[0];
|
|
||||||
|
|
||||||
if (reg_debug)
|
if (reg_debug)
|
||||||
printk("%02x\n", (unsigned char) val);
|
printk("%02x\n", (unsigned char) val);
|
||||||
|
|
||||||
|
@ -156,10 +162,12 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
|
||||||
printk("\n");
|
printk("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_lock(&dev->ctrl_urb_lock);
|
||||||
memcpy(dev->urb_buf, buf, len);
|
memcpy(dev->urb_buf, buf, len);
|
||||||
ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req,
|
ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req,
|
||||||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||||
0x0000, reg, dev->urb_buf, len, HZ);
|
0x0000, reg, dev->urb_buf, len, HZ);
|
||||||
|
mutex_unlock(&dev->ctrl_urb_lock);
|
||||||
|
|
||||||
if (dev->wait_after_write)
|
if (dev->wait_after_write)
|
||||||
msleep(dev->wait_after_write);
|
msleep(dev->wait_after_write);
|
||||||
|
|
|
@ -1936,6 +1936,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
|
||||||
|
|
||||||
dev->udev = udev;
|
dev->udev = udev;
|
||||||
mutex_init(&dev->lock);
|
mutex_init(&dev->lock);
|
||||||
|
mutex_init(&dev->ctrl_urb_lock);
|
||||||
spin_lock_init(&dev->slock);
|
spin_lock_init(&dev->slock);
|
||||||
init_waitqueue_head(&dev->open);
|
init_waitqueue_head(&dev->open);
|
||||||
init_waitqueue_head(&dev->wait_frame);
|
init_waitqueue_head(&dev->wait_frame);
|
||||||
|
|
|
@ -433,6 +433,7 @@ struct em28xx {
|
||||||
|
|
||||||
/* locks */
|
/* locks */
|
||||||
struct mutex lock;
|
struct mutex lock;
|
||||||
|
struct mutex ctrl_urb_lock; /* protects urb_buf */
|
||||||
/* spinlock_t queue_lock; */
|
/* spinlock_t queue_lock; */
|
||||||
struct list_head inqueue, outqueue;
|
struct list_head inqueue, outqueue;
|
||||||
wait_queue_head_t open, wait_frame, wait_stream;
|
wait_queue_head_t open, wait_frame, wait_stream;
|
||||||
|
|
Loading…
Reference in New Issue