On Sunday 25 January 2004 16:49, David Brownell wrote:
> Duncan Sands wrote:
> > How about this instead:
> >
> >  * This can be used by drivers to release an interface without waiting
> >  * for their disconnect() methods to be called.  Since it calls
> > disconnect * (except possibly when used from a probe() method), drivers
> > that use it * from their disconnect method need to protect themselves
> > against infinite * recursion.
> >
> > By the way, hopefully the infinite recursion bit will be dealt with in
> > the driver core, at which point that part of the comment can go away.
>
> Seems fair to me.  That was your text!

Will you take care of it then?  My plan (which I hope you agree with) is
that you push the core changes to Greg, and I send the usbfs changes
(= things in devio.c, including your changes, except for the ->driver to
->dev->driver changes).  By the way, my current patch for fixing up
drivers looks like this:

===== drivers/bluetooth/hci_usb.c 1.37 vs edited =====
--- 1.37/drivers/bluetooth/hci_usb.c    Tue Jan 20 17:57:57 2004
+++ edited/drivers/bluetooth/hci_usb.c  Wed Jan 21 00:44:19 2004
@@ -945,8 +945,11 @@
 
        hci_usb_close(hdev);
 
-       if (husb->isoc_iface)
+       if (husb->isoc_iface) {
+               /* ensure immediate exit from hci_usb_disconnect */
+               usb_set_intfdata(husb->isoc_iface, NULL);
                usb_driver_release_interface(&hci_usb_driver, husb->isoc_iface);
+       }
 
        if (hci_unregister_dev(hdev) < 0)
                BT_ERR("Can't unregister HCI device %s", hdev->name);
===== drivers/media/video/cpia_usb.c 1.29 vs edited =====
--- 1.29/drivers/media/video/cpia_usb.c Mon Aug  4 19:46:50 2003
+++ edited/drivers/media/video/cpia_usb.c       Wed Jan 21 00:42:10 2004
@@ -620,6 +620,8 @@
                wake_up_interruptible(&ucpia->wq_stream);
 
        udev = interface_to_usbdev(intf);
+       /* ensure immediate exit from cpia_disconnect */
+       usb_set_intfdata(udev->actconfig->interface[0], NULL);
        usb_driver_release_interface(&cpia_driver,
                                     udev->actconfig->interface[0]);
 
===== drivers/usb/class/cdc-acm.c 1.70 vs edited =====
--- 1.70/drivers/usb/class/cdc-acm.c    Tue Dec 30 19:25:12 2003
+++ edited/drivers/usb/class/cdc-acm.c  Wed Jan 21 00:56:50 2004
@@ -721,6 +721,8 @@
 
        kfree(acm->ctrlurb->transfer_buffer);
 
+       /* ensure immediate exit from acm_disconnect */
+       usb_set_intfdata (acm->data, NULL);
        usb_driver_release_interface(&acm_driver, acm->data);
 
        if (!acm->used) {
===== drivers/usb/image/mdc800.c 1.43 vs edited =====
--- 1.43/drivers/usb/image/mdc800.c     Wed Sep  3 17:47:18 2003
+++ edited/drivers/usb/image/mdc800.c   Sun Jan 25 17:58:28 2004
@@ -469,7 +469,6 @@
        }
 
 
-       usb_driver_claim_interface (&mdc800_usb_driver, intf, mdc800);
        if (usb_set_interface (dev, intf_desc->desc.bInterfaceNumber, 0) < 0)
        {
                err ("MDC800 Configuration fails.");
@@ -540,6 +539,8 @@
        dbg ("(mdc800_usb_disconnect) called");
 
        if (mdc800) {
+               usb_set_intfdata(intf, NULL);
+
                if (mdc800->state == NOT_CONNECTED)
                        return;
 
@@ -551,10 +552,7 @@
                usb_unlink_urb (mdc800->write_urb);
                usb_unlink_urb (mdc800->download_urb);
 
-               usb_driver_release_interface (&mdc800_usb_driver, intf);
-
                mdc800->dev=0;
-               usb_set_intfdata(intf, NULL);
        }
        info ("Mustek MDC800 disconnected from USB.");
 }
===== drivers/usb/image/scanner.c 1.101 vs edited =====
--- 1.101/drivers/usb/image/scanner.c   Wed Dec 31 20:35:44 2003
+++ edited/drivers/usb/image/scanner.c  Wed Jan 21 00:54:59 2004
@@ -1161,11 +1161,14 @@
 {
        struct scn_usb_data *scn = usb_get_intfdata(intf);
 
+       if (!scn)
+               return;
+       usb_set_intfdata(intf, NULL);
+
        /* disable open() */
        dbg("%s: De-allocating minor:%d", __FUNCTION__, scn->scn_minor);
        usb_deregister_dev(intf, &scanner_class);
 
-       usb_set_intfdata(intf, NULL);
        if(scn->intr_ep) {
                dbg("%s(%d): Unlinking IRQ URB", __FUNCTION__, scn->scn_minor);
                usb_unlink_urb(scn->scn_irq);
===== drivers/usb/net/usbnet.c 1.115 vs edited =====
--- 1.115/drivers/usb/net/usbnet.c      Thu Dec 25 15:53:47 2003
+++ edited/drivers/usb/net/usbnet.c     Wed Jan 21 00:15:13 2004
@@ -1049,6 +1049,8 @@
                return status;
        status = get_endpoints (dev, info->data);
        if (status < 0) {
+               /* ensure immediate exit from usbnet_disconnect */
+               usb_set_intfdata(info->data, NULL);
                usb_driver_release_interface (&usbnet_driver, info->data);
                return status;
        }
@@ -1072,12 +1074,16 @@
 
        /* disconnect master --> disconnect slave */
        if (intf == info->control && info->data) {
+               /* ensure immediate exit from usbnet_disconnect */
+               usb_set_intfdata(info->data, NULL);
                usb_driver_release_interface (&usbnet_driver, info->data);
                info->data = 0;
        }
 
        /* and vice versa (just in case) */
        else if (intf == info->data && info->control) {
+               /* ensure immediate exit from usbnet_disconnect */
+               usb_set_intfdata(info->control, NULL);
                usb_driver_release_interface (&usbnet_driver, info->control);
                info->control = 0;
        }
===== sound/usb/usbaudio.c 1.27 vs edited =====
--- 1.27/sound/usb/usbaudio.c   Mon Oct  6 19:47:35 2003
+++ edited/sound/usb/usbaudio.c Wed Jan 21 00:15:14 2004
@@ -2370,7 +2370,10 @@
                /* release interfaces */
                list_for_each(p, &subs->fmt_list) {
                        struct audioformat *fp = list_entry(p, struct audioformat, 
list);
-                       usb_driver_release_interface(driver, 
usb_ifnum_to_if(subs->dev, fp->iface));
+                       struct usb_interface *intf = usb_ifnum_to_if(subs->dev, 
fp->iface);
+                        /* ensure immediate exit from usb_audio_disconnect */
+                       usb_set_intfdata(intf, NULL);
+                       usb_driver_release_interface(driver, intf);
                }
        }
 }
@@ -2425,7 +2428,7 @@
                                snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer 
device\n", dev->devnum, ctrlif, j);
                                continue;
                        }
-                       usb_driver_claim_interface(&usb_audio_driver, iface, (void 
*)-1L);
+                       usb_driver_claim_interface(&usb_audio_driver, iface, NULL);
                        continue;
                }
                if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
@@ -2437,7 +2440,7 @@
                }
                if (! parse_audio_endpoints(chip, j)) {
                        usb_set_interface(dev, j, 0); /* reset the current interface */
-                       usb_driver_claim_interface(&usb_audio_driver, iface, (void 
*)-1L);
+                       usb_driver_claim_interface(&usb_audio_driver, iface, NULL);
                }
        }
 
@@ -2535,7 +2538,7 @@
                if (err < 0)
                        return err;
                if (quirk->ifnum != probed_ifnum)
-                       usb_driver_claim_interface(&usb_audio_driver, iface, (void 
*)-1L);
+                       usb_driver_claim_interface(&usb_audio_driver, iface, NULL);
        }
        return 0;
 }
@@ -2833,9 +2836,6 @@
        snd_card_t *card;
        struct list_head *p;
 
-       if (ptr == (void *)-1L)
-               return;
-
        chip = snd_magic_cast(snd_usb_audio_t, ptr, return);
        card = chip->card;
        down(&register_mutex);
@@ -2875,8 +2875,13 @@
 
 static void usb_audio_disconnect(struct usb_interface *intf)
 {
-       snd_usb_audio_disconnect(interface_to_usbdev(intf),
-                                dev_get_drvdata(&intf->dev));
+       void *data = usb_get_intfdata(intf);
+
+       if (!data)
+               return;
+
+       usb_set_intfdata(intf, NULL);
+       snd_usb_audio_disconnect(interface_to_usbdev(intf), data);
 }
 
 
===== sound/usb/usbmidi.c 1.15 vs edited =====
--- 1.15/sound/usb/usbmidi.c    Tue Dec 30 20:01:01 2003
+++ edited/sound/usb/usbmidi.c  Wed Jan 21 00:58:50 2004
@@ -699,6 +699,8 @@
        int i;
 
        umidi = list_entry(p, snd_usb_midi_t, list);
+       /* ensure immediate exit from disconnect() method */
+       usb_set_intfdata(umidi->iface, NULL);
        usb_driver_release_interface(driver, umidi->iface);
        for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
                snd_usb_midi_endpoint_t* ep = &umidi->endpoints[i];


-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to