Thanks Phil,

Your patch disables the USB Storage card all together in order to get access
to the modem. We have other such hacks in the tree, but is there no way to
simply "eject" the USB Storage device so we don't have to actually disable
it for all users and they can choose which component of the device they'd
like to use?

We are actually using the 2.6.17.7 kernel ( old I know ) but we found a way from some other GPL code in the "zy" driver to actually eject the device. I don't know if you want to work it into ~/drivers/usb/storage/usb.c or not. The way we are ejecting is actually not propor since it will eject _any_ unusual device, but we don't look for any other unusual devices in our embedded platform. Possibly a better way to go would to have a define to be used in unusual_devs.h called US_FL_EJECT_DEVICE to eject only certain devices. I know the patch is crappy, but if I was using a more recent kernel, I would have written it better.

The Novatel X950D modem comes with a virtual CD, which has MAC OS/Wind*ws installer. So it is useless to Linux. But until the virtual CD is ejected, you can't access the modem ( times out after about 5 minutes, which is too long to wait ).

-Brian

--- linux-2.6.17.7/drivers/usb/storage/usb.c.orig  2008-01-05 
16:05:35.000000000 -0600
+++ linux-2.6.17.7/drivers/usb/storage/usb.c       2008-01-05 
19:50:06.000000000 -0600
@@ -885,6 +895,55 @@
       complete_and_exit(&threads_gone, 0);
}

+//Added eject routine, modeled from zy driver
+static int eject_installer(struct usb_interface *intf)
+{
+       struct usb_device *udev = interface_to_usbdev(intf);
+       struct usb_host_interface *iface_desc = &intf->altsetting[0];
+       struct usb_endpoint_descriptor *endpoint;
+       unsigned char *cmd;
+       u8 bulk_out_ep;
+       int r;
+
+       /* Find bulk out endpoint */
+       endpoint = &iface_desc->endpoint[1].desc;
+       if ((endpoint->bEndpointAddress & USB_TYPE_MASK) == USB_DIR_OUT &&
+           (endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+           USB_ENDPOINT_XFER_BULK) {
+               bulk_out_ep = endpoint->bEndpointAddress;
+       } else {
+               dev_err(&udev->dev,
+                       "zd1211rw: Could not find bulk out endpoint\n");
+               return -ENODEV;
+       }
+
+       cmd = kzalloc(31, GFP_KERNEL);
+       if (cmd == NULL)
+               return -ENODEV;
+
+       /* USB bulk command block */
+       cmd[0] = 0x55;  /* bulk command signature */
+       cmd[1] = 0x53;  /* bulk command signature */
+       cmd[2] = 0x42;  /* bulk command signature */
+       cmd[3] = 0x43;  /* bulk command signature */
+       cmd[14] = 6;    /* command length */
+
+       cmd[15] = 0x1b; /* SCSI command: START STOP UNIT */
+       cmd[19] = 0x2;  /* eject disc */
+
+       dev_info(&udev->dev, "Ejecting virtual installer media...\n");
+       r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, bulk_out_ep),
+               cmd, 31, NULL, 2000);
+       kfree(cmd);
+       if (r)
+               return r;
+
+       /* At this point, the device disconnects and reconnects with the real
+        * ID numbers. */
+
+       usb_set_intfdata(intf, NULL);
+       return 0;
+}

/* Probe to see if we can drive a newly-connected USB device */
static int storage_probe(struct usb_interface *intf,
@@ -930,7 +989,10 @@
        * of the match from the usb_device_id table, so we can find the
        * corresponding entry in the private table.
        */
-       get_device_info(us, id);
+       result = get_device_info(us, id);
+       if (result)
+               goto BadDevice;

       /* Get the transport, protocol, and pipe settings */
       result = get_transport(us);
@@ -975,7 +1037,11 @@

       /* We come here if there are any problems */
BadDevice:
-       US_DEBUGP("storage_probe() failed\n");
+       US_DEBUGP("storage_probe() failed, result %d\n", result);
+       if (0 == eject_installer(intf))
+               printk(KERN_INFO USB_STORAGE "Ejected Unusual Device \n");
+       else
+               printk(KERN_INFO USB_STORAGE "Eject Failed on Unusual 
Device\n");
       release_everything(us);
       return result;
}
-
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to