Use a NULL device when calling tty_register_device to prevent
tty layer from creating sysfs entries that references the device.
This prevents oops in sysfs_hash_and_remove when tty_unregister_device
is called after usb device is disconnected during use.

Signed-off-by: Paul Fulghum <[EMAIL PROTECTED]>

--

Sequence is:

acm_disconnect intf=ce99f720 acm=ce24eca0 usb_dev=ce24f4b8
acm_disconnect acm->used=1 acm->dev=ce24f4b8 acm->tty=cd254af8
acm_disconnect intf=cefb6760 acm=00000000 usb_dev=ce24f4b8
acm_tty_close tty=cd254af8 filp=ce96511c acm=ce24eca0
acm_tty_close acm->used=1 acm->dev=00000000
Unable to handle kernel paging request at virtual address 6b6b6bfb
EIP is at __mutex_lock_slowpath+0x70/0x286
Call Trace:
 [<c017585e>] sysfs_hash_and_remove+0x34/0x10a

I think what is happening is that control_interface->dev is used
to back 2 sysfs entries (one usb, and one tty). When the usb
device is disconnected, the usb sysfs entries are removed and
the backing device is released. But the tty sysfs entry is
not removed until later after the tty is closed. This removal oops
because the backing device (or some sysfs entity associated with
the backing device) has already been freed. The slab poisoning
is needed to catch this.

The above change does not associate the device
with the tty object, and no tty sysfs entry is made that
references the device. No function is lost, but some info
is not exported to userland.

A more thorough approach would be to somehow not release
the usb device until the tty close completes. But that sounds
kind of messy, as the usb code would need to know about any
other class sysfs entries besides usb. (tty, maybe storage, etc)

For more details see lkml thread:
Re: 2.6.16-rc5 pppd oops on disconnects



--- linux-2.6.16-rc5/drivers/usb/class/cdc-acm.c        2006-02-27 
09:24:29.000000000 -0600
+++ b/drivers/usb/class/cdc-acm.c       2006-03-12 10:22:21.000000000 -0600
@@ -980,7 +980,7 @@ skip_normal_probe:
        usb_driver_claim_interface(&acm_driver, data_interface, acm);
 
        usb_get_intf(control_interface);
-       tty_register_device(acm_tty_driver, minor, &control_interface->dev);
+       tty_register_device(acm_tty_driver, minor, NULL);
 
        acm_table[minor] = acm;
        usb_set_intfdata (intf, acm);




-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to