On Wed, 2004-09-29 at 13:57 +0200, Duncan Sands wrote:
> this races with modem_run: since the firmware loading is done in a separate
> kernel thread, it is possible to do:
> 
> (1) probe completes
> (2) hotplug call - modem_run tries to grab the interface and fails
> (3) firmware loading code fails to load the firmware - releases the interface
> but too late.

 <...>

> By the way, do revision 0 modems really have no altsetting 2 for interface 1?

Incremental patch... we don't claim interface #2 until we actually
_have_ the first stage of the firmware loaded now, and I dropped the
duplicate (and wrong) usb_set_interface() for interface #1, leaving only
the one in udsl_got_firmware().

--- speedtch.c.firmware 2004-09-29 13:30:20.306991256 +0100
+++ speedtch.c  2004-09-29 13:40:42.485405760 +0100
@@ -1294,21 +1294,30 @@
                return; /* deep doggy do */
        }
 
-       if (!(intf = usb_ifnum_to_if (instance->usb_dev, 2))) {
-               dbg ("udsl_firmware_stage1: interface not found!");
+       if (!fw) {
+               dbg ("udsl_firmware_stage1: no firmware!");
                goto finish;
        }
 
        if (!(buffer = kmalloc (0x1000, GFP_KERNEL))) {
                dbg ("udsl_firmware_stage1: no memory for buffer!");
-               goto fail;
+               goto finish;
        }
 
-       if (!fw) {
-               dbg ("udsl_firmware_stage1: no firmware!");
-               goto fail;
+       if (!(intf = usb_ifnum_to_if (instance->usb_dev, 2))) {
+               dbg ("udsl_firmware_stage1: interface not found!");
+               goto fail_buf;
+       }
+
+       /* OK, we have the firmware. So try to claim interface #2 and actually
+          try uploading it. There's a slight possibility that the userspace
+          modem_run could be running too, and may have beaten us to it */
+        if ((ret = usb_driver_claim_interface (&udsl_usb_driver, intf, NULL)) < 0) {
+               dbg ("udsl_firmware_start: interface in use (%d)!", ret);
+               goto fail_buf;
        }
 
+
        /* URB 7 */
        if (dl_512_first) { /* some modems need a read before writing the firmware */
                ret = usb_bulk_msg (instance->usb_dev,
@@ -1376,11 +1385,12 @@
        kfree (buffer);
        return;
 
-fail:
-       kfree (buffer);
+ fail:
        usb_driver_release_interface (&udsl_usb_driver, intf);
-finish:
-       udsl_got_firmware (instance, (ret < 0) ? 0 : 1);
+ fail_buf:
+       kfree (buffer);
+ finish:
+       udsl_got_firmware (instance, 0);
        udsl_put_instance (instance);
 }
 
@@ -1389,7 +1399,6 @@
 static void udsl_firmware_start (struct udsl_instance_data *instance)
 {
 #ifdef CONFIG_FW_LOADER
-       struct usb_interface *intf;
        int ret;
 #endif
 
@@ -1408,16 +1417,6 @@
        udsl_get_instance (instance);
 
 #ifdef CONFIG_FW_LOADER
-       if (!(intf = usb_ifnum_to_if (instance->usb_dev, 2))) {
-               dbg ("udsl_firmware_start: interface not found!");
-               goto finish;
-       }
-
-        if ((ret = usb_driver_claim_interface (&udsl_usb_driver, intf, NULL)) < 0) {
-               dbg ("udsl_firmware_start: interface in use (%d)!", ret);
-               goto finish;
-       }
-
        ret = request_firmware_nowait (THIS_MODULE,
                                       "speedtch_fw1",
                                       &instance->usb_dev->dev,
@@ -1426,14 +1425,9 @@
 
        if (ret < 0) {
                dbg ("udsl_firmware_start: request_firmware_nowait failed (%d)!", ret);
-               goto fail;
        }
 
-       return;
-
-fail:
-       usb_driver_release_interface (&udsl_usb_driver, intf);
-finish:
+       /* Just pretend it never happened... hope modem_run happens */
 #endif /* CONFIG_FW_LOADER */
        udsl_got_firmware (instance, 0);
        udsl_put_instance (instance);
@@ -1751,9 +1745,6 @@
        if ((err = usb_set_interface (dev, 0, 0)) < 0)
                return err;
 
-       if ((err = usb_set_interface (dev, 1, instance->revision?2:1)) < 0)
-               return err;
-
        if ((err = usb_set_interface (dev, 2, 0)) < 0)
                return err;
 


-- 
dwmw2



-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to