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>

+12 -2
+10 -2
drivers/media/video/em28xx/em28xx-core.c
··· 76 76 77 77 em28xx_regdbg("req=%02x, reg=%02x ", req, reg); 78 78 79 + mutex_lock(&dev->ctrl_urb_lock); 79 80 ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, 80 81 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 81 82 0x0000, reg, dev->urb_buf, len, HZ); 82 83 if (ret < 0) { 83 84 if (reg_debug) 84 85 printk(" failed!\n"); 86 + mutex_unlock(&dev->ctrl_urb_lock); 85 87 return ret; 86 88 } 87 89 88 90 if (len) 89 91 memcpy(buf, dev->urb_buf, len); 92 + 93 + mutex_unlock(&dev->ctrl_urb_lock); 90 94 91 95 if (reg_debug) { 92 96 printk("%02x values: ", ret); ··· 116 112 117 113 em28xx_regdbg("req=%02x, reg=%02x:", req, reg); 118 114 115 + mutex_lock(&dev->ctrl_urb_lock); 119 116 ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, 120 117 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 121 118 0x0000, reg, dev->urb_buf, 1, HZ); 119 + val = dev->urb_buf[0]; 120 + mutex_unlock(&dev->ctrl_urb_lock); 121 + 122 122 if (ret < 0) { 123 123 printk(" failed!\n"); 124 124 return ret; 125 125 } 126 - 127 - val = dev->urb_buf[0]; 128 126 129 127 if (reg_debug) 130 128 printk("%02x\n", (unsigned char) val); ··· 162 156 printk("\n"); 163 157 } 164 158 159 + mutex_lock(&dev->ctrl_urb_lock); 165 160 memcpy(dev->urb_buf, buf, len); 166 161 ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req, 167 162 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 168 163 0x0000, reg, dev->urb_buf, len, HZ); 164 + mutex_unlock(&dev->ctrl_urb_lock); 169 165 170 166 if (dev->wait_after_write) 171 167 msleep(dev->wait_after_write);
+1
drivers/media/video/em28xx/em28xx-video.c
··· 1936 1936 1937 1937 dev->udev = udev; 1938 1938 mutex_init(&dev->lock); 1939 + mutex_init(&dev->ctrl_urb_lock); 1939 1940 spin_lock_init(&dev->slock); 1940 1941 init_waitqueue_head(&dev->open); 1941 1942 init_waitqueue_head(&dev->wait_frame);
+1
drivers/media/video/em28xx/em28xx.h
··· 433 433 434 434 /* locks */ 435 435 struct mutex lock; 436 + struct mutex ctrl_urb_lock; /* protects urb_buf */ 436 437 /* spinlock_t queue_lock; */ 437 438 struct list_head inqueue, outqueue; 438 439 wait_queue_head_t open, wait_frame, wait_stream;