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