disable usbip; patch to 2.6.28.10 hostorig
authorThomas Tanner <maemo@tannerlab.com>
Mon, 7 Jun 2010 20:35:08 +0000 (22:35 +0200)
committerThomas Tanner <maemo@tannerlab.com>
Mon, 7 Jun 2010 20:35:08 +0000 (22:35 +0200)
36 files changed:
kernel-power-2.6.28/debian/patches/series
usbhost/usb/class/cdc-acm.c
usbhost/usb/class/cdc-wdm.c
usbhost/usb/class/usbtmc.c
usbhost/usb/core/devio.c
usbhost/usb/core/driver.c
usbhost/usb/core/hub.c
usbhost/usb/core/inode.c
usbhost/usb/core/message.c
usbhost/usb/core/quirks.c
usbhost/usb/core/sysfs.c
usbhost/usb/core/usb.c
usbhost/usb/core/usb.h
usbhost/usb/gadget/f_rndis.c
usbhost/usb/gadget/u_ether.c
usbhost/usb/host/ehci-hcd.c
usbhost/usb/host/ehci-mem.c
usbhost/usb/host/ehci-q.c
usbhost/usb/host/ehci-sched.c
usbhost/usb/host/ehci.h
usbhost/usb/host/isp1760-if.c
usbhost/usb/misc/emi26.c
usbhost/usb/mon/mon_bin.c
usbhost/usb/serial/cp2101.c
usbhost/usb/serial/ftdi_sio.c
usbhost/usb/serial/ftdi_sio.h
usbhost/usb/serial/option.c
usbhost/usb/serial/ti_usb_3410_5052.c
usbhost/usb/serial/ti_usb_3410_5052.h
usbhost/usb/storage/cypress_atacb.c
usbhost/usb/storage/libusual.c
usbhost/usb/storage/scsiglue.c
usbhost/usb/storage/transport.c
usbhost/usb/storage/unusual_devs.h
usbhost/usb/storage/usb.c
usbhost/usb/storage/usb.h

index 844cbc1..ebde99d 100644 (file)
@@ -4,7 +4,7 @@ nokia-20101501+0m5.diff
 maemo-build.diff
 #unionfs-2.5.3.diff
 dm-loop.diff
-usbip.diff
+#usbip.diff
 #nilfs2-2.0.18.diff
 #minstrel-aziwoqpa.diff
 iphb-matan.diff
index d50a99f..4b3549b 100644 (file)
@@ -1370,6 +1370,8 @@ static struct usb_device_id acm_ids[] = {
        { USB_DEVICE(0x0572, 0x1321), /* Conexant USB MODEM CX93010 */
        .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
        },
+       { USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */
+       },
 
        /* control interfaces with various AT-command sets */
        { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
index 5a8ecc0..874d6a0 100644 (file)
@@ -652,7 +652,7 @@ next_desc:
 
        iface = &intf->altsetting[0];
        ep = &iface->endpoint[0].desc;
-       if (!usb_endpoint_is_int_in(ep)) {
+       if (!ep || !usb_endpoint_is_int_in(ep)) {
                rv = -EINVAL;
                goto err;
        }
index 43a863c..aeb188a 100644 (file)
@@ -49,6 +49,7 @@
 
 static struct usb_device_id usbtmc_devices[] = {
        { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 0), },
+       { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 1), },
        { 0, } /* terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, usbtmc_devices);
@@ -105,12 +106,13 @@ static int usbtmc_open(struct inode *inode, struct file *filp)
 {
        struct usb_interface *intf;
        struct usbtmc_device_data *data;
-       int retval = -ENODEV;
+       int retval = 0;
 
        intf = usb_find_interface(&usbtmc_driver, iminor(inode));
        if (!intf) {
                printk(KERN_ERR KBUILD_MODNAME
                       ": can not find device for minor %d", iminor(inode));
+               retval = -ENODEV;
                goto exit;
        }
 
index 2bccefe..7d6611a 100644 (file)
@@ -359,11 +359,6 @@ static void destroy_async(struct dev_state *ps, struct list_head *list)
                spin_lock_irqsave(&ps->lock, flags);
        }
        spin_unlock_irqrestore(&ps->lock, flags);
-       as = async_getcompleted(ps);
-       while (as) {
-               free_async(as);
-               as = async_getcompleted(ps);
-       }
 }
 
 static void destroy_async_on_interface(struct dev_state *ps,
@@ -642,6 +637,7 @@ static int usbdev_release(struct inode *inode, struct file *file)
        struct dev_state *ps = file->private_data;
        struct usb_device *dev = ps->dev;
        unsigned int ifnum;
+       struct async *as;
 
        usb_lock_device(dev);
 
@@ -660,6 +656,12 @@ static int usbdev_release(struct inode *inode, struct file *file)
        usb_unlock_device(dev);
        usb_put_dev(dev);
        put_pid(ps->disc_pid);
+
+       as = async_getcompleted(ps);
+       while (as) {
+               free_async(as);
+               as = async_getcompleted(ps);
+       }
        kfree(ps);
        return 0;
 }
@@ -1703,7 +1705,7 @@ const struct file_operations usbdev_file_operations = {
        .release =      usbdev_release,
 };
 
-void usb_fs_classdev_common_remove(struct usb_device *udev)
+static void usbdev_remove(struct usb_device *udev)
 {
        struct dev_state *ps;
        struct siginfo sinfo;
@@ -1745,10 +1747,15 @@ static void usb_classdev_remove(struct usb_device *dev)
 {
        if (dev->usb_classdev)
                device_unregister(dev->usb_classdev);
-       usb_fs_classdev_common_remove(dev);
 }
 
-static int usb_classdev_notify(struct notifier_block *self,
+#else
+#define usb_classdev_add(dev)          0
+#define usb_classdev_remove(dev)       do {} while (0)
+
+#endif
+
+static int usbdev_notify(struct notifier_block *self,
                               unsigned long action, void *dev)
 {
        switch (action) {
@@ -1758,15 +1765,15 @@ static int usb_classdev_notify(struct notifier_block *self,
                break;
        case USB_DEVICE_REMOVE:
                usb_classdev_remove(dev);
+               usbdev_remove(dev);
                break;
        }
        return NOTIFY_OK;
 }
 
 static struct notifier_block usbdev_nb = {
-       .notifier_call =        usb_classdev_notify,
+       .notifier_call =        usbdev_notify,
 };
-#endif
 
 static struct cdev usb_device_cdev;
 
@@ -1801,9 +1808,8 @@ int __init usb_devio_init(void)
         * to /sys/dev
         */
        usb_classdev_class->dev_kobj = NULL;
-
-       usb_register_notify(&usbdev_nb);
 #endif
+       usb_register_notify(&usbdev_nb);
 out:
        return retval;
 
@@ -1814,8 +1820,8 @@ error_cdev:
 
 void usb_devio_cleanup(void)
 {
-#ifdef CONFIG_USB_DEVICE_CLASS
        usb_unregister_notify(&usbdev_nb);
+#ifdef CONFIG_USB_DEVICE_CLASS
        class_destroy(usb_classdev_class);
 #endif
        cdev_del(&usb_device_cdev);
index 8c08130..f9473fb 100644 (file)
@@ -269,7 +269,7 @@ static int usb_unbind_interface(struct device *dev)
         * supports "soft" unbinding.
         */
        if (!driver->soft_unbind)
-               usb_disable_interface(udev, intf);
+               usb_disable_interface(udev, intf, false);
 
        driver->disconnect(intf);
 
@@ -279,9 +279,12 @@ static int usb_unbind_interface(struct device *dev)
         * altsetting means creating new endpoint device entries).
         * When either of these happens, defer the Set-Interface.
         */
-       if (intf->cur_altsetting->desc.bAlternateSetting == 0)
-               ;       /* Already in altsetting 0 so skip Set-Interface */
-       else if (!error && intf->dev.power.status == DPM_ON)
+       if (intf->cur_altsetting->desc.bAlternateSetting == 0) {
+               /* Already in altsetting 0 so skip Set-Interface.
+                * Just re-enable it without affecting the endpoint toggles.
+                */
+               usb_enable_interface(udev, intf, false);
+       } else if (!error && intf->dev.power.status == DPM_ON)
                usb_set_interface(udev, intf->altsetting[0].
                                desc.bInterfaceNumber, 0);
        else
index b19cbfc..da11baf 100644 (file)
@@ -2383,9 +2383,9 @@ static int hub_port_debounce(struct usb_hub *hub, int port1)
 
 void usb_ep0_reinit(struct usb_device *udev)
 {
-       usb_disable_endpoint(udev, 0 + USB_DIR_IN);
-       usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
-       usb_enable_endpoint(udev, &udev->ep0);
+       usb_disable_endpoint(udev, 0 + USB_DIR_IN, true);
+       usb_disable_endpoint(udev, 0 + USB_DIR_OUT, true);
+       usb_enable_endpoint(udev, &udev->ep0, true);
 }
 EXPORT_SYMBOL_GPL(usb_ep0_reinit);
 
index 9463226..3181d7d 100644 (file)
@@ -718,7 +718,6 @@ static void usbfs_remove_device(struct usb_device *dev)
                fs_remove_file (dev->usbfs_dentry);
                dev->usbfs_dentry = NULL;
        }
-       usb_fs_classdev_common_remove(dev);
 }
 
 static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev)
index 6d1048f..aaf6ea5 100644 (file)
@@ -651,7 +651,7 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type,
                if (result <= 0 && result != -ETIMEDOUT)
                        continue;
                if (result > 1 && ((u8 *)buf)[1] != type) {
-                       result = -EPROTO;
+                       result = -ENODATA;
                        continue;
                }
                break;
@@ -694,8 +694,13 @@ static int usb_get_string(struct usb_device *dev, unsigned short langid,
                        USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
                        (USB_DT_STRING << 8) + index, langid, buf, size,
                        USB_CTRL_GET_TIMEOUT);
-               if (!(result == 0 || result == -EPIPE))
-                       break;
+               if (result == 0 || result == -EPIPE)
+                       continue;
+               if (result > 1 && ((u8 *) buf)[1] != USB_DT_STRING) {
+                       result = -ENODATA;
+                       continue;
+               }
+               break;
        }
        return result;
 }
@@ -1009,14 +1014,15 @@ EXPORT_SYMBOL_GPL(usb_clear_halt);
  * @dev: the device whose endpoint is being disabled
  * @epaddr: the endpoint's address.  Endpoint number for output,
  *     endpoint number + USB_DIR_IN for input
+ * @reset_hardware: flag to erase any endpoint state stored in the
+ *     controller hardware
  *
- * Deallocates hcd/hardware state for this endpoint ... and nukes all
- * pending urbs.
- *
- * If the HCD hasn't registered a disable() function, this sets the
- * endpoint's maxpacket size to 0 to prevent further submissions.
+ * Disables the endpoint for URB submission and nukes all pending URBs.
+ * If @reset_hardware is set then also deallocates hcd/hardware state
+ * for the endpoint.
  */
-void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr)
+void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr,
+               bool reset_hardware)
 {
        unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
        struct usb_host_endpoint *ep;
@@ -1026,15 +1032,18 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr)
 
        if (usb_endpoint_out(epaddr)) {
                ep = dev->ep_out[epnum];
-               dev->ep_out[epnum] = NULL;
+               if (reset_hardware)
+                       dev->ep_out[epnum] = NULL;
        } else {
                ep = dev->ep_in[epnum];
-               dev->ep_in[epnum] = NULL;
+               if (reset_hardware)
+                       dev->ep_in[epnum] = NULL;
        }
        if (ep) {
                ep->enabled = 0;
                usb_hcd_flush_endpoint(dev, ep);
-               usb_hcd_disable_endpoint(dev, ep);
+               if (reset_hardware)
+                       usb_hcd_disable_endpoint(dev, ep);
        }
 }
 
@@ -1042,17 +1051,21 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr)
  * usb_disable_interface -- Disable all endpoints for an interface
  * @dev: the device whose interface is being disabled
  * @intf: pointer to the interface descriptor
+ * @reset_hardware: flag to erase any endpoint state stored in the
+ *     controller hardware
  *
  * Disables all the endpoints for the interface's current altsetting.
  */
-void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf)
+void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf,
+               bool reset_hardware)
 {
        struct usb_host_interface *alt = intf->cur_altsetting;
        int i;
 
        for (i = 0; i < alt->desc.bNumEndpoints; ++i) {
                usb_disable_endpoint(dev,
-                               alt->endpoint[i].desc.bEndpointAddress);
+                               alt->endpoint[i].desc.bEndpointAddress,
+                               reset_hardware);
        }
 }
 
@@ -1073,8 +1086,8 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
        dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__,
                skip_ep0 ? "non-ep0" : "all");
        for (i = skip_ep0; i < 16; ++i) {
-               usb_disable_endpoint(dev, i);
-               usb_disable_endpoint(dev, i + USB_DIR_IN);
+               usb_disable_endpoint(dev, i, true);
+               usb_disable_endpoint(dev, i + USB_DIR_IN, true);
        }
        dev->toggle[0] = dev->toggle[1] = 0;
 
@@ -1113,22 +1126,26 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
  * usb_enable_endpoint - Enable an endpoint for USB communications
  * @dev: the device whose interface is being enabled
  * @ep: the endpoint
+ * @reset_toggle: flag to set the endpoint's toggle back to 0
  *
- * Resets the endpoint toggle, and sets dev->ep_{in,out} pointers.
+ * Resets the endpoint toggle if asked, and sets dev->ep_{in,out} pointers.
  * For control endpoints, both the input and output sides are handled.
  */
-void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep)
+void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep,
+               bool reset_toggle)
 {
        int epnum = usb_endpoint_num(&ep->desc);
        int is_out = usb_endpoint_dir_out(&ep->desc);
        int is_control = usb_endpoint_xfer_control(&ep->desc);
 
        if (is_out || is_control) {
-               usb_settoggle(dev, epnum, 1, 0);
+               if (reset_toggle)
+                       usb_settoggle(dev, epnum, 1, 0);
                dev->ep_out[epnum] = ep;
        }
        if (!is_out || is_control) {
-               usb_settoggle(dev, epnum, 0, 0);
+               if (reset_toggle)
+                       usb_settoggle(dev, epnum, 0, 0);
                dev->ep_in[epnum] = ep;
        }
        ep->enabled = 1;
@@ -1138,17 +1155,18 @@ void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep)
  * usb_enable_interface - Enable all the endpoints for an interface
  * @dev: the device whose interface is being enabled
  * @intf: pointer to the interface descriptor
+ * @reset_toggles: flag to set the endpoints' toggles back to 0
  *
  * Enables all the endpoints for the interface's current altsetting.
  */
-static void usb_enable_interface(struct usb_device *dev,
-                                struct usb_interface *intf)
+void usb_enable_interface(struct usb_device *dev,
+               struct usb_interface *intf, bool reset_toggles)
 {
        struct usb_host_interface *alt = intf->cur_altsetting;
        int i;
 
        for (i = 0; i < alt->desc.bNumEndpoints; ++i)
-               usb_enable_endpoint(dev, &alt->endpoint[i]);
+               usb_enable_endpoint(dev, &alt->endpoint[i], reset_toggles);
 }
 
 /**
@@ -1237,7 +1255,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
        /* prevent submissions using previous endpoint settings */
        if (iface->cur_altsetting != alt)
                usb_remove_sysfs_intf_files(iface);
-       usb_disable_interface(dev, iface);
+       usb_disable_interface(dev, iface, true);
 
        iface->cur_altsetting = alt;
 
@@ -1271,7 +1289,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
         * during the SETUP stage - hence EP0 toggles are "don't care" here.
         * (Likewise, EP0 never "halts" on well designed devices.)
         */
-       usb_enable_interface(dev, iface);
+       usb_enable_interface(dev, iface, true);
        if (device_is_registered(&iface->dev))
                usb_create_sysfs_intf_files(iface);
 
@@ -1315,8 +1333,8 @@ int usb_reset_configuration(struct usb_device *dev)
         */
 
        for (i = 1; i < 16; ++i) {
-               usb_disable_endpoint(dev, i);
-               usb_disable_endpoint(dev, i + USB_DIR_IN);
+               usb_disable_endpoint(dev, i, true);
+               usb_disable_endpoint(dev, i + USB_DIR_IN, true);
        }
 
        config = dev->actconfig;
@@ -1346,7 +1364,7 @@ int usb_reset_configuration(struct usb_device *dev)
                        alt = &intf->altsetting[0];
 
                intf->cur_altsetting = alt;
-               usb_enable_interface(dev, intf);
+               usb_enable_interface(dev, intf, true);
                if (device_is_registered(&intf->dev))
                        usb_create_sysfs_intf_files(intf);
        }
@@ -1604,7 +1622,7 @@ free_interfaces:
                        alt = &intf->altsetting[0];
 
                intf->cur_altsetting = alt;
-               usb_enable_interface(dev, intf);
+               usb_enable_interface(dev, intf, true);
                intf->dev.parent = &dev->dev;
                intf->dev.driver = NULL;
                intf->dev.bus = &usb_bus_type;
@@ -1619,7 +1637,8 @@ free_interfaces:
        }
        kfree(new_interfaces);
 
-       if (cp->string == NULL)
+       if (cp->string == NULL &&
+                       !(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))
                cp->string = usb_cache_string(dev, cp->desc.iConfiguration);
 
        /* Now that all the interfaces are set up, register them
index c070b34..ab93918 100644 (file)
@@ -54,6 +54,10 @@ static const struct usb_device_id usb_quirk_list[] = {
        { USB_DEVICE(0x0638, 0x0a13), .driver_info =
          USB_QUIRK_STRING_FETCH_255 },
 
+       /* Saitek Cyborg Gold Joystick */
+       { USB_DEVICE(0x06a3, 0x0006), .driver_info =
+                       USB_QUIRK_CONFIG_INTF_STRINGS },
+
        /* M-Systems Flash Disk Pioneers */
        { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
 
index 4fb65fd..813b337 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/usb.h>
+#include <linux/usb/quirks.h>
 #include "usb.h"
 
 /* Active configuration fields */
@@ -847,7 +848,8 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf)
         * and missing in others.  Hence its attribute cannot be created
         * before the uevent is broadcast.
         */
-       if (alt->string == NULL)
+       if (alt->string == NULL &&
+                       !(udev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))
                alt->string = usb_cache_string(udev, alt->desc.iInterface);
        if (alt->string)
                retval = device_create_file(&intf->dev, &dev_attr_interface);
index be1fa07..956bf1e 100644 (file)
@@ -362,7 +362,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
        dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE;
        dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT;
        /* ep0 maxpacket comes later, from device descriptor */
-       usb_enable_endpoint(dev, &dev->ep0);
+       usb_enable_endpoint(dev, &dev->ep0, true);
        dev->can_submit = 1;
 
        /* Save readable and stable topology id, distinguishing devices
index 9a1a45a..6c90be1 100644 (file)
@@ -10,10 +10,13 @@ extern int usb_create_ep_files(struct device *parent,
 extern void usb_remove_ep_files(struct usb_host_endpoint *endpoint);
 
 extern void usb_enable_endpoint(struct usb_device *dev,
-               struct usb_host_endpoint *ep);
-extern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr);
+               struct usb_host_endpoint *ep, bool reset_toggle);
+extern void usb_enable_interface(struct usb_device *dev,
+               struct usb_interface *intf, bool reset_toggles);
+extern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr,
+               bool reset_hardware);
 extern void usb_disable_interface(struct usb_device *dev,
-               struct usb_interface *intf);
+               struct usb_interface *intf, bool reset_hardware);
 extern void usb_release_interface_cache(struct kref *ref);
 extern void usb_disable_device(struct usb_device *dev, int skip_ep0);
 extern int usb_deauthorize_device(struct usb_device *);
@@ -145,7 +148,6 @@ extern struct usb_driver usbfs_driver;
 extern const struct file_operations usbfs_devices_fops;
 extern const struct file_operations usbdev_file_operations;
 extern void usbfs_conn_disc_event(void);
-extern void usb_fs_classdev_common_remove(struct usb_device *udev);
 
 extern int usb_devio_init(void);
 extern void usb_devio_cleanup(void);
index 3a8bb53..fd7b356 100644 (file)
@@ -437,7 +437,7 @@ invalid:
                DBG(cdev, "rndis req%02x.%02x v%04x i%04x l%d\n",
                        ctrl->bRequestType, ctrl->bRequest,
                        w_value, w_index, w_length);
-               req->zero = 0;
+               req->zero = (value < w_length);
                req->length = value;
                value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
                if (value < 0)
index ab83a71..89b18d6 100644 (file)
@@ -174,12 +174,6 @@ static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p)
        strlcpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof p->bus_info);
 }
 
-static u32 eth_get_link(struct net_device *net)
-{
-       struct eth_dev  *dev = netdev_priv(net);
-       return dev->gadget->speed != USB_SPEED_UNKNOWN;
-}
-
 /* REVISIT can also support:
  *   - WOL (by tracking suspends and issuing remote wakeup)
  *   - msglevel (implies updated messaging)
@@ -188,7 +182,7 @@ static u32 eth_get_link(struct net_device *net)
 
 static struct ethtool_ops ops = {
        .get_drvinfo = eth_get_drvinfo,
-       .get_link = eth_get_link
+       .get_link = ethtool_op_get_link,
 };
 
 static void defer_kevent(struct eth_dev *dev, int flag)
index d2cb45a..d832a94 100644 (file)
@@ -485,6 +485,7 @@ static int ehci_init(struct usb_hcd *hcd)
         * periodic_size can shrink by USBCMD update if hcc_params allows.
         */
        ehci->periodic_size = DEFAULT_I_TDPS;
+       INIT_LIST_HEAD(&ehci->cached_itd_list);
        if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0)
                return retval;
 
@@ -497,6 +498,7 @@ static int ehci_init(struct usb_hcd *hcd)
 
        ehci->reclaim = NULL;
        ehci->next_uframe = -1;
+       ehci->clock_frame = -1;
 
        /*
         * dedicate a qh for the async ring head, since we couldn't unlink
index 0431397..10d5291 100644 (file)
@@ -128,6 +128,7 @@ static inline void qh_put (struct ehci_qh *qh)
 
 static void ehci_mem_cleanup (struct ehci_hcd *ehci)
 {
+       free_cached_itd_list(ehci);
        if (ehci->async)
                qh_put (ehci->async);
        ehci->async = NULL;
index 3712b92..01132ac 100644 (file)
@@ -333,12 +333,40 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
                token = hc32_to_cpu(ehci, qtd->hw_token);
 
                /* always clean up qtds the hc de-activated */
+ retry_xacterr:
                if ((token & QTD_STS_ACTIVE) == 0) {
 
                        /* on STALL, error, and short reads this urb must
                         * complete and all its qtds must be recycled.
                         */
                        if ((token & QTD_STS_HALT) != 0) {
+
+                               /* retry transaction errors until we
+                                * reach the software xacterr limit
+                                */
+                               if ((token & QTD_STS_XACT) &&
+                                               QTD_CERR(token) == 0 &&
+                                               --qh->xacterrs > 0 &&
+                                               !urb->unlinked) {
+                                       ehci_dbg(ehci,
+       "detected XactErr len %d/%d retry %d\n",
+       qtd->length - QTD_LENGTH(token), qtd->length,
+       QH_XACTERR_MAX - qh->xacterrs);
+
+                                       /* reset the token in the qtd and the
+                                        * qh overlay (which still contains
+                                        * the qtd) so that we pick up from
+                                        * where we left off
+                                        */
+                                       token &= ~QTD_STS_HALT;
+                                       token |= QTD_STS_ACTIVE |
+                                                       (EHCI_TUNE_CERR << 10);
+                                       qtd->hw_token = cpu_to_hc32(ehci,
+                                                       token);
+                                       wmb();
+                                       qh->hw_token = cpu_to_hc32(ehci, token);
+                                       goto retry_xacterr;
+                               }
                                stopped = 1;
 
                        /* magic dummy for some short reads; qh won't advance.
@@ -421,6 +449,9 @@ halt:
                /* remove qtd; it's recycled after possible urb completion */
                list_del (&qtd->qtd_list);
                last = qtd;
+
+               /* reinit the xacterr counter for the next qtd */
+               qh->xacterrs = QH_XACTERR_MAX;
        }
 
        /* last urb's completion might still need calling */
@@ -862,6 +893,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
        head->qh_next.qh = qh;
        head->hw_next = dma;
 
+       qh->xacterrs = QH_XACTERR_MAX;
        qh->qh_state = QH_STATE_LINKED;
        /* qtd completions reported later by interrupt */
 }
@@ -1095,7 +1127,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
        prev->qh_next = qh->qh_next;
        wmb ();
 
-       if (unlikely (ehci_to_hcd(ehci)->state == HC_STATE_HALT)) {
+       /* If the controller isn't running, we don't have to wait for it */
+       if (unlikely(!HC_IS_RUNNING(ehci_to_hcd(ehci)->state))) {
                /* if (unlikely (qh->reclaim != 0))
                 *      this will recurse, probably not much
                 */
index a081ee6..1d0b49e 100644 (file)
@@ -1004,7 +1004,8 @@ iso_stream_put(struct ehci_hcd *ehci, struct ehci_iso_stream *stream)
 
                is_in = (stream->bEndpointAddress & USB_DIR_IN) ? 0x10 : 0;
                stream->bEndpointAddress &= 0x0f;
-               stream->ep->hcpriv = NULL;
+               if (stream->ep)
+                       stream->ep->hcpriv = NULL;
 
                if (stream->rescheduled) {
                        ehci_info (ehci, "ep%d%s-iso rescheduled "
@@ -1535,7 +1536,7 @@ itd_link_urb (
                                        struct ehci_itd, itd_list);
                        list_move_tail (&itd->itd_list, &stream->td_list);
                        itd->stream = iso_stream_get (stream);
-                       itd->urb = usb_get_urb (urb);
+                       itd->urb = urb;
                        itd_init (ehci, stream, itd);
                }
 
@@ -1644,7 +1645,7 @@ itd_complete (
        (void) disable_periodic(ehci);
        ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
 
-       if (unlikely (list_empty (&stream->td_list))) {
+       if (unlikely(list_is_singular(&stream->td_list))) {
                ehci_to_hcd(ehci)->self.bandwidth_allocated
                                -= stream->bandwidth;
                ehci_vdbg (ehci,
@@ -1653,14 +1654,27 @@ itd_complete (
                        (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
        }
        iso_stream_put (ehci, stream);
-       /* OK to recycle this ITD now that its completion callback ran. */
+
 done:
-       usb_put_urb(urb);
        itd->urb = NULL;
-       itd->stream = NULL;
-       list_move(&itd->itd_list, &stream->free_list);
-       iso_stream_put(ehci, stream);
-
+       if (ehci->clock_frame != itd->frame || itd->index[7] != -1) {
+               /* OK to recycle this ITD now. */
+               itd->stream = NULL;
+               list_move(&itd->itd_list, &stream->free_list);
+               iso_stream_put(ehci, stream);
+       } else {
+               /* HW might remember this ITD, so we can't recycle it yet.
+                * Move it to a safe place until a new frame starts.
+                */
+               list_move(&itd->itd_list, &ehci->cached_itd_list);
+               if (stream->refcount == 2) {
+                       /* If iso_stream_put() were called here, stream
+                        * would be freed.  Instead, just prevent reuse.
+                        */
+                       stream->ep->hcpriv = NULL;
+                       stream->ep = NULL;
+               }
+       }
        return retval;
 }
 
@@ -1934,7 +1948,7 @@ sitd_link_urb (
                                struct ehci_sitd, sitd_list);
                list_move_tail (&sitd->sitd_list, &stream->td_list);
                sitd->stream = iso_stream_get (stream);
-               sitd->urb = usb_get_urb (urb);
+               sitd->urb = urb;
 
                sitd_patch(ehci, stream, sitd, sched, packet);
                sitd_link (ehci, (next_uframe >> 3) % ehci->periodic_size,
@@ -2019,7 +2033,7 @@ sitd_complete (
        (void) disable_periodic(ehci);
        ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
 
-       if (list_empty (&stream->td_list)) {
+       if (list_is_singular(&stream->td_list)) {
                ehci_to_hcd(ehci)->self.bandwidth_allocated
                                -= stream->bandwidth;
                ehci_vdbg (ehci,
@@ -2030,7 +2044,6 @@ sitd_complete (
        iso_stream_put (ehci, stream);
        /* OK to recycle this SITD now that its completion callback ran. */
 done:
-       usb_put_urb(urb);
        sitd->urb = NULL;
        sitd->stream = NULL;
        list_move(&sitd->sitd_list, &stream->free_list);
@@ -2101,6 +2114,20 @@ done:
 
 /*-------------------------------------------------------------------------*/
 
+static void free_cached_itd_list(struct ehci_hcd *ehci)
+{
+       struct ehci_itd *itd, *n;
+
+       list_for_each_entry_safe(itd, n, &ehci->cached_itd_list, itd_list) {
+               struct ehci_iso_stream  *stream = itd->stream;
+               itd->stream = NULL;
+               list_move(&itd->itd_list, &stream->free_list);
+               iso_stream_put(ehci, stream);
+       }
+}
+
+/*-------------------------------------------------------------------------*/
+
 static void
 scan_periodic (struct ehci_hcd *ehci)
 {
@@ -2115,10 +2142,17 @@ scan_periodic (struct ehci_hcd *ehci)
         * Touches as few pages as possible:  cache-friendly.
         */
        now_uframe = ehci->next_uframe;
-       if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state))
+       if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) {
                clock = ehci_readl(ehci, &ehci->regs->frame_index);
-       else
+               clock_frame = (clock >> 3) % ehci->periodic_size;
+       } else  {
                clock = now_uframe + mod - 1;
+               clock_frame = -1;
+       }
+       if (ehci->clock_frame != clock_frame) {
+               free_cached_itd_list(ehci);
+               ehci->clock_frame = clock_frame;
+       }
        clock %= mod;
        clock_frame = clock >> 3;
 
@@ -2277,6 +2311,10 @@ restart:
                        /* rescan the rest of this frame, then ... */
                        clock = now;
                        clock_frame = clock >> 3;
+                       if (ehci->clock_frame != clock_frame) {
+                               free_cached_itd_list(ehci);
+                               ehci->clock_frame = clock_frame;
+                       }
                } else {
                        now_uframe++;
                        now_uframe %= mod;
index c7d4b5a..a8c201a 100644 (file)
@@ -87,6 +87,10 @@ struct ehci_hcd {                    /* one per controller */
        int                     next_uframe;    /* scan periodic, start here */
        unsigned                periodic_sched; /* periodic activity count */
 
+       /* list of itds completed while clock_frame was still active */
+       struct list_head        cached_itd_list;
+       unsigned                clock_frame;
+
        /* per root hub port */
        unsigned long           reset_done [EHCI_MAX_ROOT_PORTS];
 
@@ -210,6 +214,8 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
        }
 }
 
+static void free_cached_itd_list(struct ehci_hcd *ehci);
+
 /*-------------------------------------------------------------------------*/
 
 #include <linux/usb/ehci_def.h>
@@ -360,6 +366,9 @@ struct ehci_qh {
 #define        QH_STATE_UNLINK_WAIT    4               /* LINKED and on reclaim q */
 #define        QH_STATE_COMPLETING     5               /* don't touch token.HALT */
 
+       u8                      xacterrs;       /* XactErr retry counter */
+#define        QH_XACTERR_MAX          32              /* XactErr retry limit */
+
        /* periodic schedule info */
        u8                      usecs;          /* intr bandwidth */
        u8                      gap_uf;         /* uframes split/csplit gap */
index b87ca7c..2545306 100644 (file)
@@ -129,23 +129,23 @@ static struct of_platform_driver isp1760_of_driver = {
 #endif
 
 #ifdef CONFIG_PCI
-static u32 nxp_pci_io_base;
-static u32 iolength;
-static u32 pci_mem_phy0;
-static u32 length;
-static u8 __iomem *chip_addr;
-static u8 __iomem *iobase;
-
 static int __devinit isp1761_pci_probe(struct pci_dev *dev,
                const struct pci_device_id *id)
 {
        u8 latency, limit;
        __u32 reg_data;
        int retry_count;
-       int length;
-       int status = 1;
        struct usb_hcd *hcd;
        unsigned int devflags = 0;
+       int ret_status = 0;
+
+       resource_size_t pci_mem_phy0;
+       resource_size_t memlength;
+
+       u8 __iomem *chip_addr;
+       u8 __iomem *iobase;
+       resource_size_t nxp_pci_io_base;
+       resource_size_t iolength;
 
        if (usb_disabled())
                return -ENODEV;
@@ -168,26 +168,30 @@ static int __devinit isp1761_pci_probe(struct pci_dev *dev,
        iobase = ioremap_nocache(nxp_pci_io_base, iolength);
        if (!iobase) {
                printk(KERN_ERR "ioremap #1\n");
-               release_mem_region(nxp_pci_io_base, iolength);
-               return -ENOMEM;
+               ret_status = -ENOMEM;
+               goto cleanup1;
        }
        /* Grab the PLX PCI shared memory of the ISP 1761 we need  */
        pci_mem_phy0 = pci_resource_start(dev, 3);
-       length = pci_resource_len(dev, 3);
-
-       if (length < 0xffff) {
-               printk(KERN_ERR "memory length for this resource is less than "
-                               "required\n");
-               release_mem_region(nxp_pci_io_base, iolength);
-               iounmap(iobase);
-               return  -ENOMEM;
+       memlength = pci_resource_len(dev, 3);
+       if (memlength < 0xffff) {
+               printk(KERN_ERR "memory length for this resource is wrong\n");
+               ret_status = -ENOMEM;
+               goto cleanup2;
        }
 
-       if (!request_mem_region(pci_mem_phy0, length, "ISP-PCI")) {
+       if (!request_mem_region(pci_mem_phy0, memlength, "ISP-PCI")) {
                printk(KERN_ERR "host controller already in use\n");
-               release_mem_region(nxp_pci_io_base, iolength);
-               iounmap(iobase);
-               return -EBUSY;
+               ret_status = -EBUSY;
+               goto cleanup2;
+       }
+
+       /* map available memory */
+       chip_addr = ioremap_nocache(pci_mem_phy0,memlength);
+       if (!chip_addr) {
+               printk(KERN_ERR "Error ioremap failed\n");
+               ret_status = -ENOMEM;
+               goto cleanup3;
        }
 
        /* bad pci latencies can contribute to overruns */
@@ -210,39 +214,54 @@ static int __devinit isp1761_pci_probe(struct pci_dev *dev,
                 * */
                writel(0xface, chip_addr + HC_SCRATCH_REG);
                udelay(100);
-               reg_data = readl(chip_addr + HC_SCRATCH_REG);
+               reg_data = readl(chip_addr + HC_SCRATCH_REG) & 0x0000ffff;
                retry_count--;
        }
 
+       iounmap(chip_addr);
+
        /* Host Controller presence is detected by writing to scratch register
         * and reading back and checking the contents are same or not
         */
        if (reg_data != 0xFACE) {
                dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data);
-               goto clean;
+               ret_status = -ENOMEM;
+               goto cleanup3;
        }
 
        pci_set_master(dev);
 
-       status = readl(iobase + 0x68);
-       status |= 0x900;
-       writel(status, iobase + 0x68);
+       /* configure PLX PCI chip to pass interrupts */
+#define PLX_INT_CSR_REG 0x68
+       reg_data = readl(iobase + PLX_INT_CSR_REG);
+       reg_data |= 0x900;
+       writel(reg_data, iobase + PLX_INT_CSR_REG);
 
        dev->dev.dma_mask = NULL;
-       hcd = isp1760_register(pci_mem_phy0, length, dev->irq,
+       hcd = isp1760_register(pci_mem_phy0, memlength, dev->irq,
                IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev),
                devflags);
-       if (!IS_ERR(hcd)) {
-               pci_set_drvdata(dev, hcd);
-               return 0;
+       if (IS_ERR(hcd)) {
+               ret_status = -ENODEV;
+               goto cleanup3;
        }
-clean:
-       status = -ENODEV;
+
+       /* done with PLX IO access */
        iounmap(iobase);
-       release_mem_region(pci_mem_phy0, length);
        release_mem_region(nxp_pci_io_base, iolength);
-       return status;
+
+       pci_set_drvdata(dev, hcd);
+       return 0;
+
+cleanup3:
+       release_mem_region(pci_mem_phy0, memlength);
+cleanup2:
+       iounmap(iobase);
+cleanup1:
+       release_mem_region(nxp_pci_io_base, iolength);
+       return ret_status;
 }
+
 static void isp1761_pci_remove(struct pci_dev *dev)
 {
        struct usb_hcd *hcd;
@@ -255,12 +274,6 @@ static void isp1761_pci_remove(struct pci_dev *dev)
        usb_put_hcd(hcd);
 
        pci_disable_device(dev);
-
-       iounmap(iobase);
-       iounmap(chip_addr);
-
-       release_mem_region(nxp_pci_io_base, iolength);
-       release_mem_region(pci_mem_phy0, length);
 }
 
 static void isp1761_pci_shutdown(struct pci_dev *dev)
@@ -268,12 +281,16 @@ static void isp1761_pci_shutdown(struct pci_dev *dev)
        printk(KERN_ERR "ips1761_pci_shutdown\n");
 }
 
-static const struct pci_device_id isp1760_plx [] = { {
-       /* handle any USB 2.0 EHCI controller */
-       PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_OTHER << 8) | (0x06 << 16)), ~0),
-               .driver_data = 0,
-},
-{ /* end: all zeroes */ }
+static const struct pci_device_id isp1760_plx [] = {
+       {
+               .class          = PCI_CLASS_BRIDGE_OTHER << 8,
+               .class_mask     = ~0,
+               .vendor         = PCI_VENDOR_ID_PLX,
+               .device         = 0x5406,
+               .subvendor      = PCI_VENDOR_ID_PLX,
+               .subdevice      = 0x9054,
+       },
+       { }
 };
 MODULE_DEVICE_TABLE(pci, isp1760_plx);
 
index e762beb..879a980 100644 (file)
@@ -160,7 +160,7 @@ static int emi26_load_firmware (struct usb_device *dev)
                        err("%s - error loading firmware: error = %d", __func__, err);
                        goto wraperr;
                }
-       } while (i > 0);
+       } while (rec);
 
        /* Assert reset (stop the CPU in the EMI) */
        err = emi26_set_reset(dev,1);
index e06810a..4cf27c7 100644 (file)
@@ -37,6 +37,7 @@
 #define MON_IOCX_GET   _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get)
 #define MON_IOCX_MFETCH _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch)
 #define MON_IOCH_MFLUSH _IO(MON_IOC_MAGIC, 8)
+
 #ifdef CONFIG_COMPAT
 #define MON_IOCX_GET32 _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get32)
 #define MON_IOCX_MFETCH32 _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch32)
@@ -921,21 +922,6 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file,
                }
                break;
 
-#ifdef CONFIG_COMPAT
-       case MON_IOCX_GET32: {
-               struct mon_bin_get32 getb;
-
-               if (copy_from_user(&getb, (void __user *)arg,
-                                           sizeof(struct mon_bin_get32)))
-                       return -EFAULT;
-
-               ret = mon_bin_get_event(file, rp,
-                   compat_ptr(getb.hdr32), compat_ptr(getb.data32),
-                   getb.alloc32);
-               }
-               break;
-#endif
-
        case MON_IOCX_MFETCH:
                {
                struct mon_bin_mfetch mfetch;
@@ -962,7 +948,57 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file,
                }
                break;
 
+       case MON_IOCG_STATS: {
+               struct mon_bin_stats __user *sp;
+               unsigned int nevents;
+               unsigned int ndropped;
+
+               spin_lock_irqsave(&rp->b_lock, flags);
+               ndropped = rp->cnt_lost;
+               rp->cnt_lost = 0;
+               spin_unlock_irqrestore(&rp->b_lock, flags);
+               nevents = mon_bin_queued(rp);
+
+               sp = (struct mon_bin_stats __user *)arg;
+               if (put_user(rp->cnt_lost, &sp->dropped))
+                       return -EFAULT;
+               if (put_user(nevents, &sp->queued))
+                       return -EFAULT;
+
+               }
+               break;
+
+       default:
+               return -ENOTTY;
+       }
+
+       return ret;
+}
+
 #ifdef CONFIG_COMPAT
+static long mon_bin_compat_ioctl(struct file *file,
+    unsigned int cmd, unsigned long arg)
+{
+       struct mon_reader_bin *rp = file->private_data;
+       int ret;
+
+       switch (cmd) {
+
+       case MON_IOCX_GET32: {
+               struct mon_bin_get32 getb;
+
+               if (copy_from_user(&getb, (void __user *)arg,
+                                           sizeof(struct mon_bin_get32)))
+                       return -EFAULT;
+
+               ret = mon_bin_get_event(file, rp,
+                   compat_ptr(getb.hdr32), compat_ptr(getb.data32),
+                   getb.alloc32);
+               if (ret < 0)
+                       return ret;
+               }
+               return 0;
+
        case MON_IOCX_MFETCH32:
                {
                struct mon_bin_mfetch32 mfetch;
@@ -986,37 +1022,25 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file,
                        return ret;
                if (put_user(ret, &uptr->nfetch32))
                        return -EFAULT;
-               ret = 0;
                }
-               break;
-#endif
-
-       case MON_IOCG_STATS: {
-               struct mon_bin_stats __user *sp;
-               unsigned int nevents;
-               unsigned int ndropped;
-
-               spin_lock_irqsave(&rp->b_lock, flags);
-               ndropped = rp->cnt_lost;
-               rp->cnt_lost = 0;
-               spin_unlock_irqrestore(&rp->b_lock, flags);
-               nevents = mon_bin_queued(rp);
+               return 0;
 
-               sp = (struct mon_bin_stats __user *)arg;
-               if (put_user(rp->cnt_lost, &sp->dropped))
-                       return -EFAULT;
-               if (put_user(nevents, &sp->queued))
-                       return -EFAULT;
+       case MON_IOCG_STATS:
+               return mon_bin_ioctl(NULL, file, cmd,
+                                           (unsigned long) compat_ptr(arg));
 
-               }
-               break;
+       case MON_IOCQ_URB_LEN:
+       case MON_IOCQ_RING_SIZE:
+       case MON_IOCT_RING_SIZE:
+       case MON_IOCH_MFLUSH:
+               return mon_bin_ioctl(NULL, file, cmd, arg);
 
        default:
-               return -ENOTTY;
+               ;
        }
-
-       return ret;
+       return -ENOTTY;
 }
+#endif /* CONFIG_COMPAT */
 
 static unsigned int
 mon_bin_poll(struct file *file, struct poll_table_struct *wait)
@@ -1094,6 +1118,9 @@ static const struct file_operations mon_fops_binary = {
        /* .write =     mon_text_write, */
        .poll =         mon_bin_poll,
        .ioctl =        mon_bin_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = mon_bin_compat_ioctl,
+#endif
        .release =      mon_bin_release,
        .mmap =         mon_bin_mmap,
 };
index cfaf1f0..4294e6e 100644 (file)
@@ -79,6 +79,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
        { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
        { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
+       { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */
        { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */
        { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */
        { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
index fb6f293..a0fbe1c 100644 (file)
@@ -660,6 +660,12 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) },
+       { USB_DEVICE(ATMEL_VID, STK541_PID) },
+       { USB_DEVICE(DE_VID, STB_PID) },
+       { USB_DEVICE(DE_VID, WHT_PID) },
+       { USB_DEVICE(ADI_VID, ADI_GNICE_PID),
+               .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+       { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },
        { },                                    /* Optional parameter entry */
        { }                                     /* Terminating entry */
 };
index 373ee09..27fe244 100644 (file)
 #define RATOC_PRODUCT_ID_USB60F        0xb020
 
 /*
+ * Atmel STK541
+ */
+#define ATMEL_VID              0x03eb /* Vendor ID */
+#define STK541_PID             0x2109 /* Zigbee Controller */
+
+/*
+ * Dresden Elektronic Sensor Terminal Board
+ */
+#define DE_VID                 0x1cf1 /* Vendor ID */
+#define STB_PID                        0x0001 /* Sensor Terminal Board */
+#define WHT_PID                        0x0004 /* Wireless Handheld Terminal */
+
+/*
+ * Blackfin gnICE JTAG
+ * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice
+ */
+#define ADI_VID                0x0456
+#define ADI_GNICE_PID          0xF000
+
+/*
+ * JETI SPECTROMETER SPECBOS 1201
+ * http://www.jeti.com/products/sys/scb/scb1201.php
+ */
+#define JETI_VID               0x0c6c
+#define JETI_SPC1201_PID       0x04b2
+
+/*
  *   BmRequestType:  1100 0000b
  *   bRequest:       FTDI_E2_READ
  *   wValue:         0
index 809697b..be88c84 100644 (file)
@@ -89,6 +89,7 @@ static int  option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
 #define OPTION_PRODUCT_ETNA_MODEM_GT           0x7041
 #define OPTION_PRODUCT_ETNA_MODEM_EX           0x7061
 #define OPTION_PRODUCT_ETNA_KOI_MODEM          0x7100
+#define OPTION_PRODUCT_GTM380_MODEM            0x7201
 
 #define HUAWEI_VENDOR_ID                       0x12D1
 #define HUAWEI_PRODUCT_E600                    0x1001
@@ -190,16 +191,18 @@ static int  option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
 /* OVATION PRODUCTS */
 #define NOVATELWIRELESS_PRODUCT_MC727          0x4100
 #define NOVATELWIRELESS_PRODUCT_MC950D         0x4400
+#define NOVATELWIRELESS_PRODUCT_U727           0x5010
 
 /* FUTURE NOVATEL PRODUCTS */
-#define NOVATELWIRELESS_PRODUCT_EVDO_1         0x6000
-#define NOVATELWIRELESS_PRODUCT_HSPA_1         0x7000
-#define NOVATELWIRELESS_PRODUCT_EMBEDDED_1     0x8000
-#define NOVATELWIRELESS_PRODUCT_GLOBAL_1       0x9000
-#define NOVATELWIRELESS_PRODUCT_EVDO_2         0x6001
-#define NOVATELWIRELESS_PRODUCT_HSPA_2         0x7001
-#define NOVATELWIRELESS_PRODUCT_EMBEDDED_2     0x8001
-#define NOVATELWIRELESS_PRODUCT_GLOBAL_2       0x9001
+#define NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED 0X6000
+#define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001
+#define NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED 0X7000
+#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED 0X7001
+#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED        0X8000
+#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED        0X8001
+#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED        0X9000
+#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED        0X9001
+#define NOVATELWIRELESS_PRODUCT_GLOBAL         0XA001
 
 /* AMOI PRODUCTS */
 #define AMOI_VENDOR_ID                         0x1614
@@ -209,6 +212,27 @@ static int  option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
 
 #define DELL_VENDOR_ID                         0x413C
 
+/* Dell modems */
+#define DELL_PRODUCT_5700_MINICARD             0x8114
+#define DELL_PRODUCT_5500_MINICARD             0x8115
+#define DELL_PRODUCT_5505_MINICARD             0x8116
+#define DELL_PRODUCT_5700_EXPRESSCARD          0x8117
+#define DELL_PRODUCT_5510_EXPRESSCARD          0x8118
+
+#define DELL_PRODUCT_5700_MINICARD_SPRINT      0x8128
+#define DELL_PRODUCT_5700_MINICARD_TELUS       0x8129
+
+#define DELL_PRODUCT_5720_MINICARD_VZW         0x8133
+#define DELL_PRODUCT_5720_MINICARD_SPRINT      0x8134
+#define DELL_PRODUCT_5720_MINICARD_TELUS       0x8135
+#define DELL_PRODUCT_5520_MINICARD_CINGULAR    0x8136
+#define DELL_PRODUCT_5520_MINICARD_GENERIC_L   0x8137
+#define DELL_PRODUCT_5520_MINICARD_GENERIC_I   0x8138
+
+#define DELL_PRODUCT_5730_MINICARD_SPRINT      0x8180
+#define DELL_PRODUCT_5730_MINICARD_TELUS       0x8181
+#define DELL_PRODUCT_5730_MINICARD_VZW         0x8182
+
 #define KYOCERA_VENDOR_ID                      0x0c88
 #define KYOCERA_PRODUCT_KPC650                 0x17da
 #define KYOCERA_PRODUCT_KPC680                 0x180a
@@ -259,19 +283,13 @@ static int  option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
 
 /* ZTE PRODUCTS */
 #define ZTE_VENDOR_ID                          0x19d2
+#define ZTE_PRODUCT_MF622                      0x0001
 #define ZTE_PRODUCT_MF628                      0x0015
 #define ZTE_PRODUCT_MF626                      0x0031
 #define ZTE_PRODUCT_CDMA_TECH                  0xfffe
 
-/* Ericsson products */
-#define ERICSSON_VENDOR_ID                     0x0bdb
-#define ERICSSON_PRODUCT_F3507G                        0x1900
-
-/* Pantech products */
-#define PANTECH_VENDOR_ID                      0x106c
-#define PANTECH_PRODUCT_PC5740                 0x3701
-#define PANTECH_PRODUCT_PC5750                 0x3702  /* PX-500 */
-#define PANTECH_PRODUCT_UM150                  0x3711
+#define BENQ_VENDOR_ID                         0x04a5
+#define BENQ_PRODUCT_H10                       0x4068
 
 static struct usb_device_id option_ids[] = {
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
@@ -298,6 +316,7 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_GT) },
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_EX) },
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTM380_MODEM) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) },
@@ -383,31 +402,37 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */
-       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_1) }, /* Novatel EVDO product */
-       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_1) }, /* Novatel HSPA product */
-       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_1) }, /* Novatel Embedded product */
-       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL_1) }, /* Novatel Global product */
-       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_2) }, /* Novatel EVDO product */
-       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_2) }, /* Novatel HSPA product */
-       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_2) }, /* Novatel Embedded product */
-       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL_2) }, /* Novatel Global product */
+       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */
+       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED) }, /* Novatel EVDO product */
+       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */
+       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */
+       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */
+       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) }, /* Novatel EVDO product */
+       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED) }, /* Novatel HSPA product */
+       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED) }, /* Novatel EVDO Embedded product */
+       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED) }, /* Novatel HSPA Embedded product */
+       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL) }, /* Novatel Global product */
 
        { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) },
        { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },
        { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H02) },
 
-       { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */
-       { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
-       { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
-       { USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */
-       { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */
-       { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */
-       { USB_DEVICE(DELL_VENDOR_ID, 0x8129) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite ET620 CDMA/EV-DO */
-       { USB_DEVICE(DELL_VENDOR_ID, 0x8133) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */
-       { USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */
-       { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */
-       { USB_DEVICE(DELL_VENDOR_ID, 0x8138) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */
-       { USB_DEVICE(DELL_VENDOR_ID, 0x8147) }, /* Dell Wireless 5530 Mobile Broadband (3G HSPA) Mini-Card */
+       { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD) },             /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */
+       { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5500_MINICARD) },             /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
+       { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5505_MINICARD) },             /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
+       { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_EXPRESSCARD) },          /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */
+       { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5510_EXPRESSCARD) },          /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */
+       { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD_SPRINT) },      /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */
+       { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD_TELUS) },       /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite ET620 CDMA/EV-DO */
+       { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_VZW) },         /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */
+       { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_SPRINT) },      /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */
+       { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_TELUS) },       /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */
+       { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_CINGULAR) },    /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */
+       { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_L) },   /* Dell Wireless HSDPA 5520 */
+       { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_I) },   /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */
+       { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) },      /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
+       { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) },       /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
+       { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) },         /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
        { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },   /* ADU-E100, ADU-310 */
        { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
        { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) },
@@ -472,13 +497,12 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
        { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
+       { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622) },
        { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626) },
        { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) },
        { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) },
-       { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G) },
-       { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_PC5740) },
-       { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_PC5750) },
-       { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_UM150) },
+       { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
+       { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */
        { } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
index 01d0c70..8a1e797 100644 (file)
@@ -176,25 +176,32 @@ static unsigned int product_5052_count;
 /* the array dimension is the number of default entries plus */
 /* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */
 /* null entry */
-static struct usb_device_id ti_id_table_3410[1+TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_3410[10+TI_EXTRA_VID_PID_COUNT+1] = {
        { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
+       { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
+       { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
+       { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
 };
 
-static struct usb_device_id ti_id_table_5052[4+TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
+       { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
 };
 
-static struct usb_device_id ti_id_table_combined[] = {
+static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = {
        { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
+       { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
+       { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
+       { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
        { }
 };
 
index b5541bf..d4e4d7e 100644 (file)
 
 /* Vendor and product ids */
 #define TI_VENDOR_ID                   0x0451
+#define IBM_VENDOR_ID                  0x04b3
 #define TI_3410_PRODUCT_ID             0x3410
+#define IBM_4543_PRODUCT_ID            0x4543
+#define IBM_454B_PRODUCT_ID            0x454b
+#define IBM_454C_PRODUCT_ID            0x454c
 #define TI_3410_EZ430_ID               0xF430  /* TI ez430 development tool */
 #define TI_5052_BOOT_PRODUCT_ID                0x5052  /* no EEPROM, no firmware */
 #define TI_5152_BOOT_PRODUCT_ID                0x5152  /* no EEPROM, no firmware */
index 898e67d..9466a99 100644 (file)
@@ -133,19 +133,18 @@ void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
 
                /* build the command for
                 * reading the ATA registers */
-               scsi_eh_prep_cmnd(srb, &ses, NULL, 0, 0);
-               srb->sdb.length = sizeof(regs);
-               sg_init_one(&ses.sense_sgl, regs, srb->sdb.length);
-               srb->sdb.table.sgl = &ses.sense_sgl;
-               srb->sc_data_direction = DMA_FROM_DEVICE;
-               srb->sdb.table.nents = 1;
+               scsi_eh_prep_cmnd(srb, &ses, NULL, 0, sizeof(regs));
+
                /* we use the same command as before, but we set
                 * the read taskfile bit, for not executing atacb command,
                 * but reading register selected in srb->cmnd[4]
                 */
+               srb->cmd_len = 16;
+               srb->cmnd = ses.cmnd;
                srb->cmnd[2] = 1;
 
                usb_stor_transparent_scsi_command(srb, us);
+               memcpy(regs, srb->sense_buffer, sizeof(regs));
                tmp_result = srb->result;
                scsi_eh_restore_cmnd(srb, &ses);
                /* we fail to get registers, report invalid command */
@@ -162,8 +161,8 @@ void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
 
                /* XXX we should generate sk, asc, ascq from status and error
                 * regs
-                * (see 11.1 Error translation Â­ ATA device error to SCSI error map)
-                * and ata_to_sense_error from libata.
+                * (see 11.1 Error translation ATA device error to SCSI error
+                *  map, and ata_to_sense_error from libata.)
                 */
 
                /* Sense data is current and format is descriptor. */
index d617e8a..f970b27 100644 (file)
@@ -46,6 +46,12 @@ static int usu_probe_thread(void *arg);
 { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
   .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
 
+#define COMPLIANT_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+                   vendorName, productName, useProtocol, useTransport, \
+                   initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+  .driver_info = (flags) }
+
 #define USUAL_DEV(useProto, useTrans, useType) \
 { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
   .driver_info = ((useType)<<24) }
@@ -57,6 +63,7 @@ struct usb_device_id storage_usb_ids [] = {
 
 #undef USUAL_DEV
 #undef UNUSUAL_DEV
+#undef COMPLIANT_DEV
 
 MODULE_DEVICE_TABLE(usb, storage_usb_ids);
 EXPORT_SYMBOL_GPL(storage_usb_ids);
index 09779f6..5f484ae 100644 (file)
 #include "transport.h"
 #include "protocol.h"
 
+/* Vendor IDs for companies that seem to include the READ CAPACITY bug
+ * in all their devices
+ */
+#define VENDOR_ID_NOKIA                0x0421
+#define VENDOR_ID_NIKON                0x04b0
+#define VENDOR_ID_PENTAX       0x0a17
+#define VENDOR_ID_MOTOROLA     0x22b8
+
 /***********************************************************************
  * Host functions 
  ***********************************************************************/
@@ -127,6 +135,12 @@ static int slave_configure(struct scsi_device *sdev)
                if (sdev->request_queue->max_sectors > max_sectors)
                        blk_queue_max_sectors(sdev->request_queue,
                                              max_sectors);
+       } else if (sdev->type == TYPE_TAPE) {
+               /* Tapes need much higher max_sector limits, so just
+                * raise it to the maximum possible (4 GB / 512) and
+                * let the queue segment size sort out the real limit.
+                */
+               blk_queue_max_sectors(sdev->request_queue, 0x7FFFFF);
        }
 
        /* We can't put these settings in slave_alloc() because that gets
@@ -134,6 +148,23 @@ static int slave_configure(struct scsi_device *sdev)
         * settings can't be overridden via the scsi devinfo mechanism. */
        if (sdev->type == TYPE_DISK) {
 
+               /* Some vendors seem to put the READ CAPACITY bug into
+                * all their devices -- primarily makers of cell phones
+                * and digital cameras.  Since these devices always use
+                * flash media and can be expected to have an even number
+                * of sectors, we will always enable the CAPACITY_HEURISTICS
+                * flag unless told otherwise. */
+               switch (le16_to_cpu(us->pusb_dev->descriptor.idVendor)) {
+               case VENDOR_ID_NOKIA:
+               case VENDOR_ID_NIKON:
+               case VENDOR_ID_PENTAX:
+               case VENDOR_ID_MOTOROLA:
+                       if (!(us->fflags & (US_FL_FIX_CAPACITY |
+                                       US_FL_CAPACITY_OK)))
+                               us->fflags |= US_FL_CAPACITY_HEURISTICS;
+                       break;
+               }
+
                /* Disk-type devices use MODE SENSE(6) if the protocol
                 * (SubClass) is Transparent SCSI, otherwise they use
                 * MODE SENSE(10). */
@@ -196,6 +227,14 @@ static int slave_configure(struct scsi_device *sdev)
                 * sector in a larger then 1 sector read, since the performance
                 * impact is negible we set this flag for all USB disks */
                sdev->last_sector_bug = 1;
+
+               /* Enable last-sector hacks for single-target devices using
+                * the Bulk-only transport, unless we already know the
+                * capacity will be decremented or is correct. */
+               if (!(us->fflags & (US_FL_FIX_CAPACITY | US_FL_CAPACITY_OK |
+                                       US_FL_SCM_MULT_TARG)) &&
+                               us->protocol == US_PR_BULK)
+                       us->use_last_sector_hacks = 1;
        } else {
 
                /* Non-disk-type devices don't need to blacklist any pages
index 79108d5..95de764 100644 (file)
@@ -57,6 +57,9 @@
 #include "scsiglue.h"
 #include "debug.h"
 
+#include <linux/blkdev.h>
+#include "../../scsi/sd.h"
+
 
 /***********************************************************************
  * Data transfer routines
@@ -511,6 +514,80 @@ int usb_stor_bulk_transfer_sg(struct us_data* us, unsigned int pipe,
  * Transport routines
  ***********************************************************************/
 
+/* There are so many devices that report the capacity incorrectly,
+ * this routine was written to counteract some of the resulting
+ * problems.
+ */
+static void last_sector_hacks(struct us_data *us, struct scsi_cmnd *srb)
+{
+       struct gendisk *disk;
+       struct scsi_disk *sdkp;
+       u32 sector;
+
+       /* To Report "Medium Error: Record Not Found */
+       static unsigned char record_not_found[18] = {
+               [0]     = 0x70,                 /* current error */
+               [2]     = MEDIUM_ERROR,         /* = 0x03 */
+               [7]     = 0x0a,                 /* additional length */
+               [12]    = 0x14                  /* Record Not Found */
+       };
+
+       /* If last-sector problems can't occur, whether because the
+        * capacity was already decremented or because the device is
+        * known to report the correct capacity, then we don't need
+        * to do anything.
+        */
+       if (!us->use_last_sector_hacks)
+               return;
+
+       /* Was this command a READ(10) or a WRITE(10)? */
+       if (srb->cmnd[0] != READ_10 && srb->cmnd[0] != WRITE_10)
+               goto done;
+
+       /* Did this command access the last sector? */
+       sector = (srb->cmnd[2] << 24) | (srb->cmnd[3] << 16) |
+                       (srb->cmnd[4] << 8) | (srb->cmnd[5]);
+       disk = srb->request->rq_disk;
+       if (!disk)
+               goto done;
+       sdkp = scsi_disk(disk);
+       if (!sdkp)
+               goto done;
+       if (sector + 1 != sdkp->capacity)
+               goto done;
+
+       if (srb->result == SAM_STAT_GOOD && scsi_get_resid(srb) == 0) {
+
+               /* The command succeeded.  We know this device doesn't
+                * have the last-sector bug, so stop checking it.
+                */
+               us->use_last_sector_hacks = 0;
+
+       } else {
+               /* The command failed.  Allow up to 3 retries in case this
+                * is some normal sort of failure.  After that, assume the
+                * capacity is wrong and we're trying to access the sector
+                * beyond the end.  Replace the result code and sense data
+                * with values that will cause the SCSI core to fail the
+                * command immediately, instead of going into an infinite
+                * (or even just a very long) retry loop.
+                */
+               if (++us->last_sector_retries < 3)
+                       return;
+               srb->result = SAM_STAT_CHECK_CONDITION;
+               memcpy(srb->sense_buffer, record_not_found,
+                               sizeof(record_not_found));
+       }
+
+ done:
+       /* Don't reset the retry counter for TEST UNIT READY commands,
+        * because they get issued after device resets which might be
+        * caused by a failed last-sector access.
+        */
+       if (srb->cmnd[0] != TEST_UNIT_READY)
+               us->last_sector_retries = 0;
+}
+
 /* Invoke the transport and basic error-handling/recovery methods
  *
  * This is used by the protocol layers to actually send the message to
@@ -544,6 +621,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
        /* if the transport provided its own sense data, don't auto-sense */
        if (result == USB_STOR_TRANSPORT_NO_SENSE) {
                srb->result = SAM_STAT_CHECK_CONDITION;
+               last_sector_hacks(us, srb);
                return;
        }
 
@@ -667,6 +745,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
                        scsi_bufflen(srb) - scsi_get_resid(srb) < srb->underflow)
                srb->result = (DID_ERROR << 16) | (SUGGEST_RETRY << 24);
 
+       last_sector_hacks(us, srb);
        return;
 
        /* Error and abort processing: try to resynchronize with the device
@@ -694,6 +773,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
                us->transport_reset(us);
        }
        clear_bit(US_FLIDX_RESETTING, &us->dflags);
+       last_sector_hacks(us, srb);
 }
 
 /* Stop the current URB transfer */
index bfcc1fe..40dd32f 100644 (file)
@@ -27,7 +27,8 @@
 
 /* IMPORTANT NOTE: This file must be included in another file which does
  * the following thing for it to work:
- * The macro UNUSUAL_DEV() must be defined before this file is included
+ * The UNUSUAL_DEV, COMPLIANT_DEV, and USUAL_DEV macros must be defined
+ * before this file is included.
  */
 
 /* If you edit this file, please try to keep it sorted first by VendorID,
  * <usb-storage@lists.one-eyed-alien.net>
  */
 
+/* Note: If you add an entry only in order to set the CAPACITY_OK flag,
+ * use the COMPLIANT_DEV macro instead of UNUSUAL_DEV.  This is
+ * because such entries mark devices which actually work correctly,
+ * as opposed to devices that do something strangely or wrongly.
+ */
+
 /* patch submitted by Vivian Bregier <Vivian.Bregier@imag.fr>
  */
 UNUSUAL_DEV(  0x03eb, 0x2002, 0x0100, 0x0100,
@@ -160,34 +167,6 @@ UNUSUAL_DEV(  0x0421, 0x0019, 0x0592, 0x0592,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_MAX_SECTORS_64 ),
 
-/* Reported by Filip Joelsson <filip@blueturtle.nu> */
-UNUSUAL_DEV(  0x0421, 0x005d, 0x0001, 0x0600,
-               "Nokia",
-               "Nokia 3110c",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY ),
-
-/* Reported by Ozan Sener <themgzzy@gmail.com> */
-UNUSUAL_DEV(  0x0421, 0x0060, 0x0551, 0x0551,
-               "Nokia",
-               "3500c",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY ),
-
-/* Reported by CSECSY Laszlo <boobaa@frugalware.org> */
-UNUSUAL_DEV(  0x0421, 0x0063, 0x0001, 0x0601,
-               "Nokia",
-               "Nokia 3109c",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY ),
-
-/* Patch for Nokia 5310 capacity */
-UNUSUAL_DEV(  0x0421, 0x006a, 0x0000, 0x0701,
-               "Nokia",
-               "5310",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY ),
-
 /* Reported by Mario Rettig <mariorettig@web.de> */
 UNUSUAL_DEV(  0x0421, 0x042e, 0x0100, 0x0100,
                "Nokia",
@@ -240,7 +219,7 @@ UNUSUAL_DEV(  0x0421, 0x047c, 0x0370, 0x0610,
                US_FL_MAX_SECTORS_64 ),
 
 /* Reported by Manuel Osdoba <manuel.osdoba@tu-ilmenau.de> */
-UNUSUAL_DEV( 0x0421, 0x0492, 0x0452, 0x0452,
+UNUSUAL_DEV( 0x0421, 0x0492, 0x0452, 0x9999,
                "Nokia",
                "Nokia 6233",
                US_SC_DEVICE, US_PR_DEVICE, NULL,
@@ -253,35 +232,6 @@ UNUSUAL_DEV(  0x0421, 0x0495, 0x0370, 0x0370,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_MAX_SECTORS_64 ),
 
-/* Reported by Cedric Godin <cedric@belbone.be> */
-UNUSUAL_DEV(  0x0421, 0x04b9, 0x0500, 0x0551,
-               "Nokia",
-               "5300",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY ),
-
-/* Reported by Richard Nauber <RichardNauber@web.de> */
-UNUSUAL_DEV(  0x0421, 0x04fa, 0x0550, 0x0660,
-               "Nokia",
-               "6300",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY ),
-
-/* Patch for Nokia 5310 capacity */
-UNUSUAL_DEV(  0x0421, 0x006a, 0x0000, 0x0591,
-       "Nokia",
-       "5310",
-       US_SC_DEVICE, US_PR_DEVICE, NULL,
-       US_FL_FIX_CAPACITY ),
-
-/* Submitted by Ricky Wong Yung Fei <evilbladewarrior@gmail.com> */
-/* Nokia 7610 Supernova - Too many sectors reported in usb storage mode */
-UNUSUAL_DEV(  0x0421, 0x00f5, 0x0000, 0x0470,
-       "Nokia",
-       "7610 Supernova",
-       US_SC_DEVICE, US_PR_DEVICE, NULL,
-       US_FL_FIX_CAPACITY ),
-
 /* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */
 UNUSUAL_DEV(  0x0424, 0x0fdc, 0x0210, 0x0210,
                "SMSC",
@@ -396,83 +346,6 @@ UNUSUAL_DEV(  0x04b0, 0x0301, 0x0010, 0x0010,
                US_SC_DEVICE, US_PR_DEVICE,NULL,
                US_FL_NOT_LOCKABLE ),
 
-/* Reported by Stefan de Konink <skinkie@xs4all.nl> */
-UNUSUAL_DEV(  0x04b0, 0x0401, 0x0200, 0x0200,
-               "NIKON",
-               "NIKON DSC D100",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY),
-
-/* Reported by Tobias Kunze Briseno <t-linux@fictive.com> */
-UNUSUAL_DEV(  0x04b0, 0x0403, 0x0200, 0x0200,
-               "NIKON",
-               "NIKON DSC D2H",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY),
-
-/* Reported by Milinevsky Dmitry <niam.niam@gmail.com> */
-UNUSUAL_DEV(  0x04b0, 0x0409, 0x0100, 0x0100,
-               "NIKON",
-               "NIKON DSC D50",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY),
-
-/* Reported by Andreas Bockhold <andreas@bockionline.de> */
-UNUSUAL_DEV(  0x04b0, 0x0405, 0x0100, 0x0100,
-               "NIKON",
-               "NIKON DSC D70",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY),
-
-/* Reported by Jamie Kitson <jamie@staberinde.fsnet.co.uk> */
-UNUSUAL_DEV(  0x04b0, 0x040d, 0x0100, 0x0100,
-               "NIKON",
-               "NIKON DSC D70s",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY),
-
-/* Reported by Graber and Mike Pagano <mpagano-kernel@mpagano.com> */
-UNUSUAL_DEV(  0x04b0, 0x040f, 0x0100, 0x0200,
-               "NIKON",
-               "NIKON DSC D200",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY),
-
-/* Reported by Emil Larsson <emil@swip.net> */
-UNUSUAL_DEV(  0x04b0, 0x0411, 0x0100, 0x0111,
-               "NIKON",
-               "NIKON DSC D80",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY),
-
-/* Reported by Ortwin Glueck <odi@odi.ch> */
-UNUSUAL_DEV(  0x04b0, 0x0413, 0x0110, 0x0111,
-               "NIKON",
-               "NIKON DSC D40",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY),
-
-/* Reported by Paul Check <paul@openstreet.com> */
-UNUSUAL_DEV(  0x04b0, 0x0415, 0x0100, 0x0100,
-               "NIKON",
-               "NIKON DSC D2Xs",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY),
-
-/* Reported by Shan Destromp (shansan@gmail.com) */
-UNUSUAL_DEV(  0x04b0, 0x0417, 0x0100, 0x0100,
-               "NIKON",
-               "NIKON DSC D40X",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY),
-
-/* Reported by paul ready <lxtwin@homecall.co.uk> */
-UNUSUAL_DEV(  0x04b0, 0x0419, 0x0100, 0x0200,
-               "NIKON",
-               "NIKON DSC D300",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY),
-
 /* Reported by Doug Maxey (dwm@austin.ibm.com) */
 UNUSUAL_DEV(  0x04b3, 0x4001, 0x0110, 0x0110,
                "IBM",
@@ -685,6 +558,13 @@ UNUSUAL_DEV(  0x0525, 0xa140, 0x0100, 0x0100,
                US_SC_8070, US_PR_DEVICE, NULL,
                US_FL_FIX_INQUIRY ),
 
+/* Added by Alan Stern <stern@rowland.harvard.edu> */
+COMPLIANT_DEV(0x0525, 0xa4a5, 0x0000, 0x9999,
+               "Linux",
+               "File-backed Storage Gadget",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_CAPACITY_OK ),
+
 /* Yakumo Mega Image 37
  * Submitted by Stephan Fuhrmann <atomenergie@t-online.de> */
 UNUSUAL_DEV(  0x052b, 0x1801, 0x0100, 0x0100,
@@ -996,13 +876,13 @@ UNUSUAL_DEV(  0x05e3, 0x0701, 0x0000, 0xffff,
                "Genesys Logic",
                "USB to IDE Optical",
                US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ),
+               US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 | US_FL_IGNORE_RESIDUE ),
 
 UNUSUAL_DEV(  0x05e3, 0x0702, 0x0000, 0xffff,
                "Genesys Logic",
                "USB to IDE Disk",
                US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ),
+               US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 | US_FL_IGNORE_RESIDUE ),
 
 /* Reported by Hanno Boeck <hanno@gmx.de>
  * Taken from the Lycoris Kernel */
@@ -1033,14 +913,16 @@ UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001,
                US_FL_FIX_CAPACITY ),
 
 /* Reported by Richard -=[]=- <micro_flyer@hotmail.com> */
-UNUSUAL_DEV( 0x067b, 0x2507, 0x0100, 0x0100,
+/* Change to bcdDeviceMin (0x0100 to 0x0001) reported by
+ * Thomas Bartosik <tbartdev@gmx-topmail.de> */
+UNUSUAL_DEV( 0x067b, 0x2507, 0x0001, 0x0100,
                "Prolific Technology Inc.",
                "Mass Storage Device",
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_CAPACITY | US_FL_GO_SLOW ),
 
 /* Reported by Alex Butcher <alex.butcher@assursys.co.uk> */
-UNUSUAL_DEV( 0x067b, 0x3507, 0x0001, 0x0001,
+UNUSUAL_DEV( 0x067b, 0x3507, 0x0001, 0x0101,
                "Prolific Technology Inc.",
                "ATAPI-6 Bridge Controller",
                US_SC_DEVICE, US_PR_DEVICE, NULL,
@@ -1282,12 +1164,14 @@ UNUSUAL_DEV(  0x07c4, 0xa400, 0x0000, 0xffff,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_INQUIRY ),
 
-/* Reported by Rauch Wolke <rauchwolke@gmx.net> */
+/* Reported by Rauch Wolke <rauchwolke@gmx.net>
+ * and augmented by binbin <binbinsh@gmail.com> (Bugzilla #12882)
+ */
 UNUSUAL_DEV(  0x07c4, 0xa4a5, 0x0000, 0xffff,
                "Simple Tech/Datafab",
                "CF+SM Reader",
                US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_IGNORE_RESIDUE ),
+               US_FL_IGNORE_RESIDUE | US_FL_MAX_SECTORS_64 ),
 
 /* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant
  * to the USB storage specification in two ways:
@@ -1320,6 +1204,13 @@ UNUSUAL_DEV( 0x0840, 0x0082, 0x0001, 0x0001,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_CAPACITY),
 
+/* Reported and patched by Nguyen Anh Quynh <aquynh@gmail.com> */
+UNUSUAL_DEV( 0x0840, 0x0084, 0x0001, 0x0001,
+               "Argosy",
+               "Storage",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_FIX_CAPACITY),
+
 /* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
  * Flag will support Bulk devices which use a standards-violating 32-byte
  * Command Block Wrapper. Here, the "DC2MEGA" cameras (several brands) with
@@ -1417,14 +1308,6 @@ UNUSUAL_DEV( 0x0a17, 0x0004, 0x1000, 0x1000,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_INQUIRY ),
 
-
-/* Submitted by Per Winkvist <per.winkvist@uk.com> */
-UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff,
-               "Pentax",
-               "Optio S/S4",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_INQUIRY ),
-
 /* These are virtual windows driver CDs, which the zd1211rw driver
  * automatically converts into WLAN devices. */
 UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101,
@@ -1449,6 +1332,16 @@ UNUSUAL_DEV( 0x0af0, 0x7401, 0x0000, 0x0000,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                0 ),
 
+/* Reported by Jan Dumon <j.dumon@option.com>
+ * This device (wrongly) has a vendor-specific device descriptor.
+ * The entry is needed so usb-storage can bind to it's mass-storage
+ * interface as an interface driver */
+UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0000,
+               "Option",
+               "GI 0431 SD-Card",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               0 ),
+
 #ifdef CONFIG_USB_STORAGE_ISD200
 UNUSUAL_DEV(  0x0bf6, 0xa001, 0x0100, 0x0110,
                "ATI",
@@ -2076,6 +1969,12 @@ UNUSUAL_DEV(  0x19d2, 0x2000, 0x0000, 0x0000,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_IGNORE_DEVICE),
 
+UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001,
+               "ST",
+               "2A",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_FIX_CAPACITY),
+
 /* patch submitted by Davide Perini <perini.davide@dpsoftware.org>
  * and Renato Perini <rperini@email.it>
  */
@@ -2086,27 +1985,6 @@ UNUSUAL_DEV(  0x22b8, 0x3010, 0x0001, 0x0001,
                US_FL_FIX_CAPACITY | US_FL_IGNORE_RESIDUE ),
 
 /*
- * Patch by Pete Zaitcev <zaitcev@redhat.com>
- * Report by Mark Patton. Red Hat bz#208928.
- * Added support for rev 0x0002 (Motorola ROKR W5)
- * by Javier Smaldone <javier@smaldone.com.ar>
- */
-UNUSUAL_DEV(  0x22b8, 0x4810, 0x0001, 0x0002,
-               "Motorola",
-               "RAZR V3i/ROKR W5",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY),
-
-/*
- * Patch by Jost Diederichs <jost@qdusa.com>
- */
-UNUSUAL_DEV(0x22b8, 0x6410, 0x0001, 0x9999,
-               "Motorola Inc.",
-               "Motorola Phone (RAZRV3xx)",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY),
-
-/*
  * Patch by Constantin Baranov <const@tltsu.ru>
  * Report by Andreas Koenecke.
  * Motorola ROKR Z6.
index 27016fd..ceb8ac3 100644 (file)
@@ -126,6 +126,8 @@ MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device");
 { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
   .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
 
+#define COMPLIANT_DEV  UNUSUAL_DEV
+
 #define USUAL_DEV(useProto, useTrans, useType) \
 { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
   .driver_info = (USB_US_TYPE_STOR<<24) }
@@ -134,6 +136,7 @@ static struct usb_device_id storage_usb_ids [] = {
 
 #      include "unusual_devs.h"
 #undef UNUSUAL_DEV
+#undef COMPLIANT_DEV
 #undef USUAL_DEV
        /* Terminating entry */
        { }
@@ -164,6 +167,8 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids);
        .initFunction = init_function,  \
 }
 
+#define COMPLIANT_DEV  UNUSUAL_DEV
+
 #define USUAL_DEV(use_protocol, use_transport, use_type) \
 { \
        .useProtocol = use_protocol,    \
@@ -173,6 +178,7 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids);
 static struct us_unusual_dev us_unusual_dev_list[] = {
 #      include "unusual_devs.h" 
 #      undef UNUSUAL_DEV
+#      undef COMPLIANT_DEV
 #      undef USUAL_DEV
 
        /* Terminating entry */
index a4ad73b..2e995c9 100644 (file)
@@ -155,6 +155,10 @@ struct us_data {
 #ifdef CONFIG_PM
        pm_hook                 suspend_resume_hook;
 #endif
+
+       /* hacks for READ CAPACITY bug handling */
+       int                     use_last_sector_hacks;
+       int                     last_sector_retries;
 };
 
 /* Convert between us_data and the corresponding Scsi_Host */