This is an automatic generated email to let you know that the following patch 
were queued at the 
http://git.linuxtv.org/media_tree.git tree:

Subject: [media] em28xx: use atomic bit operations for devices-in-use mask
Author:  Chris Rankin <[email protected]>
Date:    Sat Aug 20 08:21:03 2011 -0300

Use atomic bit operations for the em28xx_devused mask, to prevent an
unlikely race condition should two adapters be plugged in
simultaneously. The operations also clearer than explicit bit
manipulation anyway.

Signed-off-by: Chris Rankin <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>

 drivers/media/video/em28xx/em28xx-cards.c |   33 ++++++++++++++---------------
 1 files changed, 16 insertions(+), 17 deletions(-)

---

http://git.linuxtv.org/media_tree.git?a=commitdiff;h=38b61eb2dac06fdc42815b004e9824d8196cfcfb

diff --git a/drivers/media/video/em28xx/em28xx-cards.c 
b/drivers/media/video/em28xx/em28xx-cards.c
index d947026..677db14 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -60,7 +60,7 @@ static unsigned int card[]     = {[0 ... (EM28XX_MAXBOARDS - 
1)] = UNSET };
 module_param_array(card,  int, NULL, 0444);
 MODULE_PARM_DESC(card,     "card type");
 
-/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */
+/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS - 1 */
 static unsigned long em28xx_devused;
 
 struct em28xx_hash_table {
@@ -2793,7 +2793,7 @@ void em28xx_release_resources(struct em28xx *dev)
        usb_put_dev(dev->udev);
 
        /* Mark device as unused */
-       em28xx_devused &= ~(1 << dev->devno);
+       clear_bit(dev->devno, &em28xx_devused);
 };
 
 /*
@@ -3015,8 +3015,16 @@ static int em28xx_usb_probe(struct usb_interface 
*interface,
        udev = usb_get_dev(interface_to_usbdev(interface));
 
        /* Check to see next free device and mark as used */
-       nr = find_first_zero_bit(&em28xx_devused, EM28XX_MAXBOARDS);
-       em28xx_devused |= 1<<nr;
+       do {
+               nr = find_first_zero_bit(&em28xx_devused, EM28XX_MAXBOARDS);
+               if (nr >= EM28XX_MAXBOARDS) {
+                       /* No free device slots */
+                       printk(DRIVER_NAME ": Supports only %i em28xx 
boards.\n",
+                                       EM28XX_MAXBOARDS);
+                       retval = -ENOMEM;
+                       goto err_no_slot;
+               }
+       } while (test_and_set_bit(nr, &em28xx_devused));
 
        /* Don't register audio interfaces */
        if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
@@ -3027,7 +3035,6 @@ static int em28xx_usb_probe(struct usb_interface 
*interface,
                        ifnum,
                        interface->altsetting[0].desc.bInterfaceClass);
 
-               em28xx_devused &= ~(1<<nr);
                retval = -ENODEV;
                goto err;
        }
@@ -3132,24 +3139,14 @@ static int em28xx_usb_probe(struct usb_interface 
*interface,
                printk(DRIVER_NAME ": Device initialization failed.\n");
                printk(DRIVER_NAME ": Device must be connected to a high-speed"
                       " USB 2.0 port.\n");
-               em28xx_devused &= ~(1<<nr);
                retval = -ENODEV;
                goto err;
        }
 
-       if (nr >= EM28XX_MAXBOARDS) {
-               printk(DRIVER_NAME ": Supports only %i em28xx boards.\n",
-                               EM28XX_MAXBOARDS);
-               em28xx_devused &= ~(1<<nr);
-               retval = -ENOMEM;
-               goto err;
-       }
-
        /* allocate memory for our device state and initialize it */
        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
        if (dev == NULL) {
                em28xx_err(DRIVER_NAME ": out of memory!\n");
-               em28xx_devused &= ~(1<<nr);
                retval = -ENOMEM;
                goto err;
        }
@@ -3177,7 +3174,6 @@ static int em28xx_usb_probe(struct usb_interface 
*interface,
 
        if (dev->alt_max_pkt_size == NULL) {
                em28xx_errdev("out of memory!\n");
-               em28xx_devused &= ~(1<<nr);
                kfree(dev);
                retval = -ENOMEM;
                goto err;
@@ -3204,7 +3200,6 @@ static int em28xx_usb_probe(struct usb_interface 
*interface,
        mutex_lock(&dev->lock);
        retval = em28xx_init_dev(&dev, udev, interface, nr);
        if (retval) {
-               em28xx_devused &= ~(1<<dev->devno);
                mutex_unlock(&dev->lock);
                kfree(dev);
                goto err;
@@ -3220,6 +3215,10 @@ static int em28xx_usb_probe(struct usb_interface 
*interface,
        return 0;
 
 err:
+       clear_bit(nr, &em28xx_devused);
+
+err_no_slot:
+       usb_put_dev(udev);
        return retval;
 }
 

_______________________________________________
linuxtv-commits mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to