Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 19207
b: refs/heads/master
c: 0e42a62
h: refs/heads/master
i:
  19205: 8218ab4
  19203: 1f767d2
  19199: bca27f5
v: v3
  • Loading branch information
Duncan Sands authored and Greg Kroah-Hartman committed Feb 1, 2006
1 parent ee0c84d commit 3e69d33
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 20 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 233c08e0ff303e659a9003d49b15608f59f08a64
refs/heads/master: 0e42a627ec3d8defa0c43cff94b8f2080a070716
66 changes: 47 additions & 19 deletions trunk/drivers/usb/atm/usbatm.c
Original file line number Diff line number Diff line change
Expand Up @@ -602,8 +602,12 @@ static int usbatm_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)

vdbg("%s called (skb 0x%p, len %u)", __func__, skb, skb->len);

if (!instance) {
dbg("%s: NULL data!", __func__);
/* racy disconnection check - fine */
if (!instance || instance->disconnected) {
#ifdef DEBUG
if (printk_ratelimit())
printk(KERN_DEBUG "%s: %s!\n", __func__, instance ? "disconnected" : "NULL instance");
#endif
err = -ENODEV;
goto fail;
}
Expand Down Expand Up @@ -715,15 +719,19 @@ static int usbatm_atm_proc_read(struct atm_dev *atm_dev, loff_t * pos, char *pag
atomic_read(&atm_dev->stats.aal5.rx_err),
atomic_read(&atm_dev->stats.aal5.rx_drop));

if (!left--)
switch (atm_dev->signal) {
case ATM_PHY_SIG_FOUND:
return sprintf(page, "Line up\n");
case ATM_PHY_SIG_LOST:
return sprintf(page, "Line down\n");
default:
return sprintf(page, "Line state unknown\n");
}
if (!left--) {
if (instance->disconnected)
return sprintf(page, "Disconnected\n");
else
switch (atm_dev->signal) {
case ATM_PHY_SIG_FOUND:
return sprintf(page, "Line up\n");
case ATM_PHY_SIG_LOST:
return sprintf(page, "Line down\n");
default:
return sprintf(page, "Line state unknown\n");
}
}

return 0;
}
Expand Down Expand Up @@ -757,6 +765,12 @@ static int usbatm_atm_open(struct atm_vcc *vcc)

down(&instance->serialize); /* vs self, usbatm_atm_close, usbatm_usb_disconnect */

if (instance->disconnected) {
atm_dbg(instance, "%s: disconnected!\n", __func__);
ret = -ENODEV;
goto fail;
}

if (usbatm_find_vcc(instance, vpi, vci)) {
atm_dbg(instance, "%s: %hd/%d already in use!\n", __func__, vpi, vci);
ret = -EADDRINUSE;
Expand Down Expand Up @@ -845,6 +859,13 @@ static void usbatm_atm_close(struct atm_vcc *vcc)
static int usbatm_atm_ioctl(struct atm_dev *atm_dev, unsigned int cmd,
void __user * arg)
{
struct usbatm_data *instance = atm_dev->dev_data;

if (!instance || instance->disconnected) {
dbg("%s: %s!", __func__, instance ? "disconnected" : "NULL instance");
return -ENODEV;
}

switch (cmd) {
case ATM_QUERYLOOP:
return put_user(ATM_LM_NONE, (int __user *)arg) ? -EFAULT : 0;
Expand Down Expand Up @@ -1129,6 +1150,7 @@ void usbatm_usb_disconnect(struct usb_interface *intf)
{
struct device *dev = &intf->dev;
struct usbatm_data *instance = usb_get_intfdata(intf);
struct usbatm_vcc_data *vcc_data;
int i;

dev_dbg(dev, "%s entered\n", __func__);
Expand All @@ -1141,12 +1163,18 @@ void usbatm_usb_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL);

down(&instance->serialize);
instance->disconnected = 1;
if (instance->thread_pid >= 0)
kill_proc(instance->thread_pid, SIGTERM, 1);
up(&instance->serialize);

wait_for_completion(&instance->thread_exited);

down(&instance->serialize);
list_for_each_entry(vcc_data, &instance->vcc_list, list)
vcc_release_async(vcc_data->vcc, -EPIPE);
up(&instance->serialize);

tasklet_disable(&instance->rx_channel.tasklet);
tasklet_disable(&instance->tx_channel.tasklet);

Expand All @@ -1156,6 +1184,14 @@ void usbatm_usb_disconnect(struct usb_interface *intf)
del_timer_sync(&instance->rx_channel.delay);
del_timer_sync(&instance->tx_channel.delay);

/* turn usbatm_[rt]x_process into something close to a no-op */
/* no need to take the spinlock */
INIT_LIST_HEAD(&instance->rx_channel.list);
INIT_LIST_HEAD(&instance->tx_channel.list);

tasklet_enable(&instance->rx_channel.tasklet);
tasklet_enable(&instance->tx_channel.tasklet);

if (instance->atm_dev && instance->driver->atm_stop)
instance->driver->atm_stop(instance, instance->atm_dev);

Expand All @@ -1164,14 +1200,6 @@ void usbatm_usb_disconnect(struct usb_interface *intf)

instance->driver_data = NULL;

/* turn usbatm_[rt]x_process into noop */
/* no need to take the spinlock */
INIT_LIST_HEAD(&instance->rx_channel.list);
INIT_LIST_HEAD(&instance->tx_channel.list);

tasklet_enable(&instance->rx_channel.tasklet);
tasklet_enable(&instance->tx_channel.tasklet);

for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) {
kfree(instance->urbs[i]->transfer_buffer);
usb_free_urb(instance->urbs[i]);
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/usb/atm/usbatm.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ struct usbatm_data {

struct kref refcount;
struct semaphore serialize;
int disconnected;

/* heavy init */
int thread_pid;
Expand Down

0 comments on commit 3e69d33

Please sign in to comment.