Commit c0cebfa4 authored by Duncan Sands's avatar Duncan Sands Committed by Greg Kroah-Hartman

[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?
parent 652c510a
...@@ -257,11 +257,16 @@ static struct sk_buff *udsl_atm_alloc_tx (struct atm_vcc *vcc, unsigned int size ...@@ -257,11 +257,16 @@ static struct sk_buff *udsl_atm_alloc_tx (struct atm_vcc *vcc, unsigned int size
return NULL; 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; struct udsl_instance_data *instance = atm_dev->dev_data;
int left = *pos; int left = *pos;
if (!instance) {
PDEBUG ("NULL instance!\n");
return -ENODEV;
}
if (!left--) if (!left--)
return sprintf (page, "SpeedTouch USB %s-%s (%02x:%02x:%02x:%02x:%02x:%02x)\n", return sprintf (page, "SpeedTouch USB %s-%s (%02x:%02x:%02x:%02x:%02x:%02x)\n",
instance->usb_dev->bus->bus_name, instance->usb_dev->devpath, instance->usb_dev->bus->bus_name, instance->usb_dev->devpath,
...@@ -302,8 +307,10 @@ static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb) ...@@ -302,8 +307,10 @@ static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb)
PDEBUG ("udsl_atm_send called\n"); PDEBUG ("udsl_atm_send called\n");
if (!dev_data) if (!dev_data || !instance) {
PDEBUG ("NULL data!\n");
return -EINVAL; return -EINVAL;
}
switch (vcc->qos.aal) { switch (vcc->qos.aal) {
case ATM_AAL5: case ATM_AAL5:
...@@ -403,6 +410,11 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) ...@@ -403,6 +410,11 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
PDEBUG ("udsl_atm_open called\n"); PDEBUG ("udsl_atm_open called\n");
if (!instance) {
PDEBUG ("NULL instance!\n");
return -ENODEV;
}
/* at the moment only AAL5 support */ /* at the moment only AAL5 support */
if (vcc->qos.aal != ATM_AAL5) if (vcc->qos.aal != ATM_AAL5)
return -EINVAL; return -EINVAL;
...@@ -441,6 +453,11 @@ static void udsl_atm_close (struct atm_vcc *vcc) ...@@ -441,6 +453,11 @@ static void udsl_atm_close (struct atm_vcc *vcc)
PDEBUG ("udsl_atm_close called\n"); PDEBUG ("udsl_atm_close called\n");
if (!dev_data || !instance) {
PDEBUG ("NULL data!\n");
return;
}
/* freeing resources */ /* freeing resources */
/* cancel all sends on this vcc */ /* cancel all sends on this vcc */
udsl_usb_cancelsends (instance, vcc); udsl_usb_cancelsends (instance, vcc);
...@@ -832,7 +849,6 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i ...@@ -832,7 +849,6 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
goto fail_atm; goto fail_atm;
} }
instance->atm_dev->dev_data = instance;
instance->atm_dev->ci_range.vpi_bits = ATM_CI_MAX; instance->atm_dev->ci_range.vpi_bits = ATM_CI_MAX;
instance->atm_dev->ci_range.vci_bits = ATM_CI_MAX; instance->atm_dev->ci_range.vci_bits = ATM_CI_MAX;
instance->atm_dev->signal = ATM_PHY_SIG_LOST; instance->atm_dev->signal = ATM_PHY_SIG_LOST;
...@@ -849,6 +865,10 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i ...@@ -849,6 +865,10 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
memcpy (instance->atm_dev->esi, mac, 6); memcpy (instance->atm_dev->esi, mac, 6);
wmb ();
instance->atm_dev->dev_data = instance;
usb_set_intfdata (intf, instance); usb_set_intfdata (intf, instance);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment