ChangeSet 1.966, 2003/01/21 15:11:37+08:00, [EMAIL PROTECTED]

[PATCH] USB: turn speedtouch micro race into a nano race

  speedtouch: turn a micro race into a nano race.  The race is that an ATM device can
  be used the moment atm_dev_register returns, but you only get to fill out the
  atm_dev structure after atm_dev_register returns (this is a design flaw in the
  ATM layer).  Thus there is a small window during which you can be called with an
  incompletely set up data structure.  Workaround this by causing all ATM callbacks
  to fail if the dev_data field has not been set.  There is still a nano race if
  writing/reading the dev_data field is not atomic.  Is it atomic on all architectures?


diff -Nru a/drivers/usb/misc/speedtouch.c b/drivers/usb/misc/speedtouch.c
--- a/drivers/usb/misc/speedtouch.c     Tue Feb  4 15:18:13 2003
+++ b/drivers/usb/misc/speedtouch.c     Tue Feb  4 15:18:13 2003
@@ -257,11 +257,16 @@
        return NULL;
 }
 
-static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page)
+static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page)
 {
        struct udsl_instance_data *instance = atm_dev->dev_data;
        int left = *pos;
 
+       if (!instance) {
+               PDEBUG ("NULL instance!\n");
+               return -ENODEV;
+       }
+
        if (!left--)
                return sprintf (page, "SpeedTouch USB %s-%s 
(%02x:%02x:%02x:%02x:%02x:%02x)\n",
                                instance->usb_dev->bus->bus_name, 
instance->usb_dev->devpath,
@@ -302,8 +307,10 @@
 
        PDEBUG ("udsl_atm_send called\n");
 
-       if (!dev_data)
+       if (!dev_data || !instance) {
+               PDEBUG ("NULL data!\n");
                return -EINVAL;
+       }
 
        switch (vcc->qos.aal) {
        case ATM_AAL5:
@@ -403,6 +410,11 @@
 
        PDEBUG ("udsl_atm_open called\n");
 
+       if (!instance) {
+               PDEBUG ("NULL instance!\n");
+               return -ENODEV;
+       }
+
        /* at the moment only AAL5 support */
        if (vcc->qos.aal != ATM_AAL5)
                return -EINVAL;
@@ -441,6 +453,11 @@
 
        PDEBUG ("udsl_atm_close called\n");
 
+       if (!dev_data || !instance) {
+               PDEBUG ("NULL data!\n");
+               return;
+       }
+
        /* freeing resources */
        /* cancel all sends on this vcc */
        udsl_usb_cancelsends (instance, vcc);
@@ -832,7 +849,6 @@
                goto fail_atm;
        }
 
-       instance->atm_dev->dev_data = instance;
        instance->atm_dev->ci_range.vpi_bits = ATM_CI_MAX;
        instance->atm_dev->ci_range.vci_bits = ATM_CI_MAX;
        instance->atm_dev->signal = ATM_PHY_SIG_LOST;
@@ -848,6 +864,10 @@
        PDEBUG ("MAC is %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], 
mac[3], mac[4], mac[5]);
 
        memcpy (instance->atm_dev->esi, mac, 6);
+
+       wmb ();
+
+       instance->atm_dev->dev_data = instance;
 
        usb_set_intfdata (intf, instance);
 



-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to