Merge 3.5-rc5 into usb-next
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 5 Jul 2012 15:57:24 +0000 (08:57 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 5 Jul 2012 15:58:03 +0000 (08:58 -0700)
This resolves a merge issue with the option.c USB serial driver.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
35 files changed:
arch/arm/mach-omap2/clock3xxx_data.c
drivers/usb/class/cdc-wdm.c
drivers/usb/core/driver.c
drivers/usb/core/file.c
drivers/usb/core/message.c
drivers/usb/core/sysfs.c
drivers/usb/early/ehci-dbgp.c
drivers/usb/host/Kconfig
drivers/usb/host/ehci-fsl.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-omap.c
drivers/usb/host/ehci.h
drivers/usb/host/fhci-dbg.c
drivers/usb/host/fhci-hcd.c
drivers/usb/host/fhci-hub.c
drivers/usb/host/fhci-sched.c
drivers/usb/host/fhci-tds.c
drivers/usb/host/fhci.h
drivers/usb/host/ohci-nxp.c
drivers/usb/host/ohci-omap.c
drivers/usb/host/ohci.h
drivers/usb/serial/keyspan.c
drivers/usb/serial/option.c
drivers/usb/serial/quatech2.c
drivers/usb/storage/protocol.c
drivers/usb/storage/uas.c
include/linux/mod_devicetable.h
include/linux/usb.h
include/linux/usb/ehci_def.h
include/linux/usb/hcd.h
include/linux/usb/renesas_usbhs.h
include/linux/usb/uas.h
scripts/mod/file2alias.c
tools/usb/testusb.c

index 1efdec236ae89dac6671bbd8f09d7cffb2067deb..d5c0cba6a340ef6f556930b8a35d249bd2599cee 100644 (file)
@@ -3391,15 +3391,15 @@ static struct omap_clk omap3xxx_clks[] = {
        CLK(NULL,       "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
        CLK(NULL,       "usbhost_ick",  &usbhost_ick,   CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
        CLK("usbhs_omap",       "usbhost_ick",  &usbhost_ick,   CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-       CLK("usbhs_omap",       "utmi_p1_gfclk",        &dummy_ck,      CK_3XXX),
-       CLK("usbhs_omap",       "utmi_p2_gfclk",        &dummy_ck,      CK_3XXX),
-       CLK("usbhs_omap",       "xclk60mhsp1_ck",       &dummy_ck,      CK_3XXX),
-       CLK("usbhs_omap",       "xclk60mhsp2_ck",       &dummy_ck,      CK_3XXX),
-       CLK("usbhs_omap",       "usb_host_hs_utmi_p1_clk",      &dummy_ck,      CK_3XXX),
-       CLK("usbhs_omap",       "usb_host_hs_utmi_p2_clk",      &dummy_ck,      CK_3XXX),
+       CLK(NULL,       "utmi_p1_gfclk",        &dummy_ck,      CK_3XXX),
+       CLK(NULL,       "utmi_p2_gfclk",        &dummy_ck,      CK_3XXX),
+       CLK(NULL,       "xclk60mhsp1_ck",       &dummy_ck,      CK_3XXX),
+       CLK(NULL,       "xclk60mhsp2_ck",       &dummy_ck,      CK_3XXX),
+       CLK(NULL,       "usb_host_hs_utmi_p1_clk",      &dummy_ck,      CK_3XXX),
+       CLK(NULL,       "usb_host_hs_utmi_p2_clk",      &dummy_ck,      CK_3XXX),
        CLK("usbhs_omap",       "usb_tll_hs_usb_ch0_clk",       &dummy_ck,      CK_3XXX),
        CLK("usbhs_omap",       "usb_tll_hs_usb_ch1_clk",       &dummy_ck,      CK_3XXX),
-       CLK("usbhs_omap",       "init_60m_fclk",        &dummy_ck,      CK_3XXX),
+       CLK(NULL,       "init_60m_fclk",        &dummy_ck,      CK_3XXX),
        CLK(NULL,       "usim_fck",     &usim_fck,      CK_3430ES2PLUS | CK_36XX),
        CLK(NULL,       "gpt1_fck",     &gpt1_fck,      CK_3XXX),
        CLK(NULL,       "wkup_32k_fck", &wkup_32k_fck,  CK_3XXX),
index 8fd398dffced7fe90afb5a6b13464279f3a7c5c6..25e7d72f339e9eabecce2006e0ecf9f146ee3a62 100644 (file)
@@ -32,8 +32,6 @@
 #define DRIVER_AUTHOR "Oliver Neukum"
 #define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management"
 
-#define HUAWEI_VENDOR_ID       0x12D1
-
 static const struct usb_device_id wdm_ids[] = {
        {
                .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS |
@@ -41,29 +39,6 @@ static const struct usb_device_id wdm_ids[] = {
                .bInterfaceClass = USB_CLASS_COMM,
                .bInterfaceSubClass = USB_CDC_SUBCLASS_DMM
        },
-       {
-               /* 
-                * Huawei E392, E398 and possibly other Qualcomm based modems
-                * embed the Qualcomm QMI protocol inside CDC on CDC ECM like
-                * control interfaces.  Userspace access to this is required
-                * to configure the accompanying data interface
-                */
-               .match_flags        = USB_DEVICE_ID_MATCH_VENDOR |
-                                       USB_DEVICE_ID_MATCH_INT_INFO,
-               .idVendor           = HUAWEI_VENDOR_ID,
-               .bInterfaceClass    = USB_CLASS_VENDOR_SPEC,
-               .bInterfaceSubClass = 1,
-               .bInterfaceProtocol = 9, /* NOTE: CDC ECM control interface! */
-       },
-       {
-                /* Vodafone/Huawei K5005 (12d1:14c8) and similar modems */
-               .match_flags        = USB_DEVICE_ID_MATCH_VENDOR |
-                                     USB_DEVICE_ID_MATCH_INT_INFO,
-               .idVendor           = HUAWEI_VENDOR_ID,
-               .bInterfaceClass    = USB_CLASS_VENDOR_SPEC,
-               .bInterfaceSubClass = 1,
-               .bInterfaceProtocol = 57, /* NOTE: CDC ECM control interface! */
-       },
        { }
 };
 
index f536aebc958e71d459f71ee5b9ae19f717a851c6..69781016a266816af9feab64ad91d56d2001e1f4 100644 (file)
@@ -367,6 +367,7 @@ static int usb_probe_interface(struct device *dev)
        return error;
 
  err:
+       usb_set_intfdata(intf, NULL);
        intf->needs_remote_wakeup = 0;
        intf->condition = USB_INTERFACE_UNBOUND;
        usb_cancel_queued_reset(intf);
@@ -622,14 +623,15 @@ int usb_match_one_id(struct usb_interface *interface,
        if (!usb_match_device(dev, id))
                return 0;
 
-       /* The interface class, subclass, and protocol should never be
+       /* The interface class, subclass, protocol and number should never be
         * checked for a match if the device class is Vendor Specific,
         * unless the match record specifies the Vendor ID. */
        if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC &&
                        !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
                        (id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS |
                                USB_DEVICE_ID_MATCH_INT_SUBCLASS |
-                               USB_DEVICE_ID_MATCH_INT_PROTOCOL)))
+                               USB_DEVICE_ID_MATCH_INT_PROTOCOL |
+                               USB_DEVICE_ID_MATCH_INT_NUMBER)))
                return 0;
 
        if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
@@ -644,6 +646,10 @@ int usb_match_one_id(struct usb_interface *interface,
            (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol))
                return 0;
 
+       if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER) &&
+           (id->bInterfaceNumber != intf->desc.bInterfaceNumber))
+               return 0;
+
        return 1;
 }
 EXPORT_SYMBOL_GPL(usb_match_one_id);
index e673b26e598f3391627550bff784c21f2be97486..e5387a47ef6fea27f978782bbed9375f4ff22d1d 100644 (file)
@@ -92,7 +92,7 @@ static int init_usb_class(void)
        }
 
        kref_init(&usb_class->kref);
-       usb_class->class = class_create(THIS_MODULE, "usb");
+       usb_class->class = class_create(THIS_MODULE, "usbmisc");
        if (IS_ERR(usb_class->class)) {
                result = IS_ERR(usb_class->class);
                printk(KERN_ERR "class_create failed for usb devices\n");
index bdd1c6749d88a9206208a27f7cbd7d966ebeb386..8b9d669e37845a2fa08824fc04ee5ddcd966f037 100644 (file)
@@ -1559,7 +1559,7 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
 
        if (add_uevent_var(env,
                   "MODALIAS=usb:"
-                  "v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
+                  "v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02Xin%02X",
                   le16_to_cpu(usb_dev->descriptor.idVendor),
                   le16_to_cpu(usb_dev->descriptor.idProduct),
                   le16_to_cpu(usb_dev->descriptor.bcdDevice),
@@ -1568,7 +1568,8 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
                   usb_dev->descriptor.bDeviceProtocol,
                   alt->desc.bInterfaceClass,
                   alt->desc.bInterfaceSubClass,
-                  alt->desc.bInterfaceProtocol))
+                  alt->desc.bInterfaceProtocol,
+                  alt->desc.bInterfaceNumber))
                return -ENOMEM;
 
        return 0;
index 9a56e3adf476f07073500f7a9364b2e4290b8adc..777f03c3772506526e69c4d1e14eab2f61dfd274 100644 (file)
@@ -840,7 +840,7 @@ static ssize_t show_modalias(struct device *dev,
        alt = intf->cur_altsetting;
 
        return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02X"
-                       "ic%02Xisc%02Xip%02X\n",
+                       "ic%02Xisc%02Xip%02Xin%02X\n",
                        le16_to_cpu(udev->descriptor.idVendor),
                        le16_to_cpu(udev->descriptor.idProduct),
                        le16_to_cpu(udev->descriptor.bcdDevice),
@@ -849,7 +849,8 @@ static ssize_t show_modalias(struct device *dev,
                        udev->descriptor.bDeviceProtocol,
                        alt->desc.bInterfaceClass,
                        alt->desc.bInterfaceSubClass,
-                       alt->desc.bInterfaceProtocol);
+                       alt->desc.bInterfaceProtocol,
+                       alt->desc.bInterfaceNumber);
 }
 static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
 
index 1fc8f1249806ab964645b5395e2f2d099a80a757..ee0ebacf8227df070dc4a40daf8cd873007ca296 100644 (file)
@@ -334,7 +334,7 @@ static int dbgp_control_msg(unsigned devnum, int requesttype,
        int ret;
 
        read = (requesttype & USB_DIR_IN) != 0;
-       if (size > (read ? DBGP_MAX_PACKET:0))
+       if (size > (read ? DBGP_MAX_PACKET : 0))
                return -1;
 
        /* Compute the control message */
index 83e58df29fe3ad32b1a7fc3c27cecc84f4e0a472..18ba33da34ecd28e675cbfb4661d302eae0bb2d1 100644 (file)
@@ -652,7 +652,7 @@ config USB_HCD_BCMA
        select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD
        select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD
        help
-         Enbale support for the EHCI and OCHI host controller on an bcma bus.
+         Enable support for the EHCI and OCHI host controller on an bcma bus.
          It converts the bcma driver into two platform device drivers
          for ehci and ohci.
 
@@ -664,7 +664,7 @@ config USB_HCD_SSB
        select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD
        select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD
        help
-         Enbale support for the EHCI and OCHI host controller on an bcma bus.
+         Enable support for the EHCI and OCHI host controller on an bcma bus.
          It converts the bcma driver into two platform device drivers
          for ehci and ohci.
 
index 43362577b54afb6f42530c9743474e9c3ffe028c..3379945b095e23e47833b9c534ea1a98f2e5734a 100644 (file)
@@ -142,19 +142,19 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
        if (pdata->operating_mode == FSL_USB2_DR_OTG) {
                struct ehci_hcd *ehci = hcd_to_ehci(hcd);
 
-               ehci->transceiver = usb_get_transceiver();
-               dev_dbg(&pdev->dev, "hcd=0x%p  ehci=0x%p, transceiver=0x%p\n",
-                       hcd, ehci, ehci->transceiver);
+               hcd->phy = usb_get_transceiver();
+               dev_dbg(&pdev->dev, "hcd=0x%p  ehci=0x%p, phy=0x%p\n",
+                       hcd, ehci, hcd->phy);
 
-               if (ehci->transceiver) {
-                       retval = otg_set_host(ehci->transceiver->otg,
+               if (hcd->phy) {
+                       retval = otg_set_host(hcd->phy->otg,
                                              &ehci_to_hcd(ehci)->self);
                        if (retval) {
-                               usb_put_transceiver(ehci->transceiver);
+                               usb_put_transceiver(hcd->phy);
                                goto err4;
                        }
                } else {
-                       dev_err(&pdev->dev, "can't find transceiver\n");
+                       dev_err(&pdev->dev, "can't find phy\n");
                        retval = -ENODEV;
                        goto err4;
                }
@@ -190,11 +190,10 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd,
                               struct platform_device *pdev)
 {
        struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
-       struct ehci_hcd *ehci = hcd_to_ehci(hcd);
 
-       if (ehci->transceiver) {
-               otg_set_host(ehci->transceiver->otg, NULL);
-               usb_put_transceiver(ehci->transceiver);
+       if (hcd->phy) {
+               otg_set_host(hcd->phy->otg, NULL);
+               usb_put_transceiver(hcd->phy);
        }
 
        usb_remove_hcd(hcd);
index 800be38c78b47f5d7990243bc71bd8fb14c2bdc6..c49fc1e7895d190d595db061feec526817d5363a 100644 (file)
@@ -203,11 +203,9 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
 /* check TDI/ARC silicon is in host mode */
 static int tdi_in_host_mode (struct ehci_hcd *ehci)
 {
-       u32 __iomem     *reg_ptr;
        u32             tmp;
 
-       reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + USBMODE);
-       tmp = ehci_readl(ehci, reg_ptr);
+       tmp = ehci_readl(ehci, &ehci->regs->usbmode);
        return (tmp & 3) == USBMODE_CM_HC;
 }
 
@@ -303,11 +301,9 @@ static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr,
 /* put TDI/ARC silicon into EHCI mode */
 static void tdi_reset (struct ehci_hcd *ehci)
 {
-       u32 __iomem     *reg_ptr;
        u32             tmp;
 
-       reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + USBMODE);
-       tmp = ehci_readl(ehci, reg_ptr);
+       tmp = ehci_readl(ehci, &ehci->regs->usbmode);
        tmp |= USBMODE_CM_HC;
        /* The default byte access to MMR space is LE after
         * controller reset. Set the required endian mode
@@ -315,7 +311,7 @@ static void tdi_reset (struct ehci_hcd *ehci)
         */
        if (ehci_big_endian_mmio(ehci))
                tmp |= USBMODE_BE;
-       ehci_writel(ehci, tmp, reg_ptr);
+       ehci_writel(ehci, tmp, &ehci->regs->usbmode);
 }
 
 /* reset a non-running (STS_HALT == 1) controller */
@@ -339,9 +335,8 @@ static int ehci_reset (struct ehci_hcd *ehci)
 
        if (ehci->has_hostpc) {
                ehci_writel(ehci, USBMODE_EX_HC | USBMODE_EX_VBPS,
-                       (u32 __iomem *)(((u8 *)ehci->regs) + USBMODE_EX));
-               ehci_writel(ehci, TXFIFO_DEFAULT,
-                       (u32 __iomem *)(((u8 *)ehci->regs) + TXFILLTUNING));
+                               &ehci->regs->usbmode_ex);
+               ehci_writel(ehci, TXFIFO_DEFAULT, &ehci->regs->txfill_tuning);
        }
        if (retval)
                return retval;
index fc9e7cc6ac9b90c7914625f90d12875263ceb202..db05e358677af4d1b6207ecf90a365b3fb1b1a64 100644 (file)
@@ -149,10 +149,8 @@ static __maybe_unused void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
        if (ehci->has_hostpc) {
                port = HCS_N_PORTS(ehci->hcs_params);
                while (port--) {
-                       u32 __iomem     *hostpc_reg;
+                       u32 __iomem     *hostpc_reg = &ehci->regs->hostpc[port];
 
-                       hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs
-                                       + HOSTPC0 + 4 * port);
                        temp = ehci_readl(ehci, hostpc_reg);
                        ehci_writel(ehci, temp & ~HOSTPC_PHCD, hostpc_reg);
                }
@@ -185,10 +183,8 @@ static __maybe_unused void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
        if (ehci->has_hostpc) {
                port = HCS_N_PORTS(ehci->hcs_params);
                while (port--) {
-                       u32 __iomem     *hostpc_reg;
+                       u32 __iomem     *hostpc_reg = &ehci->regs->hostpc[port];
 
-                       hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs
-                                       + HOSTPC0 + 4 * port);
                        temp = ehci_readl(ehci, hostpc_reg);
                        ehci_writel(ehci, temp | HOSTPC_PHCD, hostpc_reg);
                }
@@ -285,11 +281,9 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
 
                port = HCS_N_PORTS(ehci->hcs_params);
                while (port--) {
-                       u32 __iomem     *hostpc_reg;
+                       u32 __iomem     *hostpc_reg = &ehci->regs->hostpc[port];
                        u32             t3;
 
-                       hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs
-                                       + HOSTPC0 + 4 * port);
                        t3 = ehci_readl(ehci, hostpc_reg);
                        ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg);
                        t3 = ehci_readl(ehci, hostpc_reg);
@@ -388,10 +382,9 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
                i = HCS_N_PORTS(ehci->hcs_params);
                while (i--) {
                        if (test_bit(i, &ehci->bus_suspended)) {
-                               u32 __iomem     *hostpc_reg;
+                               u32 __iomem     *hostpc_reg =
+                                                       &ehci->regs->hostpc[i];
 
-                               hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs
-                                               + HOSTPC0 + 4 * i);
                                temp = ehci_readl(ehci, hostpc_reg);
                                ehci_writel(ehci, temp & ~HOSTPC_PHCD,
                                                hostpc_reg);
@@ -667,7 +660,7 @@ static int ehci_hub_control (
        int             ports = HCS_N_PORTS (ehci->hcs_params);
        u32 __iomem     *status_reg = &ehci->regs->port_status[
                                (wIndex & 0xff) - 1];
-       u32 __iomem     *hostpc_reg = NULL;
+       u32 __iomem     *hostpc_reg = &ehci->regs->hostpc[(wIndex & 0xff) - 1];
        u32             temp, temp1, status;
        unsigned long   flags;
        int             retval = 0;
@@ -680,9 +673,6 @@ static int ehci_hub_control (
         * power, "this is the one", etc.  EHCI spec supports this.
         */
 
-       if (ehci->has_hostpc)
-               hostpc_reg = (u32 __iomem *)((u8 *)ehci->regs
-                               + HOSTPC0 + 4 * ((wIndex & 0xff) - 1));
        spin_lock_irqsave (&ehci->lock, flags);
        switch (typeReq) {
        case ClearHubFeature:
@@ -724,7 +714,7 @@ static int ehci_hub_control (
 #ifdef CONFIG_USB_OTG
                        if ((hcd->self.otg_port == (wIndex + 1))
                            && hcd->self.b_hnp_enable) {
-                               otg_start_hnp(ehci->transceiver->otg);
+                               otg_start_hnp(hcd->phy->otg);
                                break;
                        }
 #endif
@@ -734,7 +724,7 @@ static int ehci_hub_control (
                                goto error;
 
                        /* clear phy low-power mode before resume */
-                       if (hostpc_reg) {
+                       if (ehci->has_hostpc) {
                                temp1 = ehci_readl(ehci, hostpc_reg);
                                ehci_writel(ehci, temp1 & ~HOSTPC_PHCD,
                                                hostpc_reg);
@@ -984,7 +974,7 @@ static int ehci_hub_control (
                        temp &= ~PORT_WKCONN_E;
                        temp |= PORT_WKDISC_E | PORT_WKOC_E;
                        ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
-                       if (hostpc_reg) {
+                       if (ehci->has_hostpc) {
                                spin_unlock_irqrestore(&ehci->lock, flags);
                                msleep(5);/* 5ms for HCD enter low pwr mode */
                                spin_lock_irqsave(&ehci->lock, flags);
index 17cfb8a1131c254b411364d86a527d24677d15c1..6e15fc87cf606ef0d8473b27dcfc967b52a416ff 100644 (file)
@@ -347,7 +347,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
        ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
        if (ret) {
                dev_err(dev, "failed to add hcd with err %d\n", ret);
-               goto err_add_hcd;
+               goto err_pm_runtime;
        }
 
        /* root ports should always stay powered */
@@ -424,8 +424,12 @@ err_utmi_p1_fck:
        clk_put(utmi_p1_fck);
 
 err_add_hcd:
+       usb_remove_hcd(hcd);
+
+err_pm_runtime:
        disable_put_regulator(pdata);
        pm_runtime_put_sync(dev);
+       usb_put_hcd(hcd);
 
 err_io:
        iounmap(regs);
index 2694ed6558d2d954c03a4ba3b77eabdc64f9c7f6..85c3572155d1faf992f271b1612e7f7d928ae4d6 100644 (file)
@@ -175,10 +175,6 @@ struct ehci_hcd {                  /* one per controller */
 #ifdef DEBUG
        struct dentry           *debug_dir;
 #endif
-       /*
-        * OTG controllers and transceivers need software interaction
-        */
-       struct usb_phy  *transceiver;
 };
 
 /* convert between an HCD pointer and the corresponding EHCI_HCD */
index 6fe55004911981bcf8f597781a886f6d677fb43c..f238cb37305c773443047347ebc2829f0fa6f4b2 100644 (file)
@@ -41,7 +41,7 @@ void fhci_dbg_isr(struct fhci_hcd *fhci, int usb_er)
 static int fhci_dfs_regs_show(struct seq_file *s, void *v)
 {
        struct fhci_hcd *fhci = s->private;
-       struct fhci_regs __iomem *regs = fhci->regs;
+       struct qe_usb_ctlr __iomem *regs = fhci->regs;
 
        seq_printf(s,
                "mode: 0x%x\n" "addr: 0x%x\n"
@@ -50,11 +50,11 @@ static int fhci_dfs_regs_show(struct seq_file *s, void *v)
                "status: 0x%x\n" "SOF timer: %d\n"
                "frame number: %d\n"
                "lines status: 0x%x\n",
-               in_8(&regs->usb_mod), in_8(&regs->usb_addr),
-               in_8(&regs->usb_comm), in_be16(&regs->usb_ep[0]),
-               in_be16(&regs->usb_event), in_be16(&regs->usb_mask),
-               in_8(&regs->usb_status), in_be16(&regs->usb_sof_tmr),
-               in_be16(&regs->usb_frame_num),
+               in_8(&regs->usb_usmod), in_8(&regs->usb_usadr),
+               in_8(&regs->usb_uscom), in_be16(&regs->usb_usep[0]),
+               in_be16(&regs->usb_usber), in_be16(&regs->usb_usbmr),
+               in_8(&regs->usb_usbs), in_be16(&regs->usb_ussft),
+               in_be16(&regs->usb_usfrn),
                fhci_ioports_check_bus_state(fhci));
 
        return 0;
index d2623747b489a90116a9876c89fd9fd289966f9e..7da1a26bed2e658e613634016d5421eb503b6d29 100644 (file)
@@ -40,8 +40,8 @@ void fhci_start_sof_timer(struct fhci_hcd *fhci)
        /* clear frame_n */
        out_be16(&fhci->pram->frame_num, 0);
 
-       out_be16(&fhci->regs->usb_sof_tmr, 0);
-       setbits8(&fhci->regs->usb_mod, USB_MODE_SFTE);
+       out_be16(&fhci->regs->usb_ussft, 0);
+       setbits8(&fhci->regs->usb_usmod, USB_MODE_SFTE);
 
        fhci_dbg(fhci, "<- %s\n", __func__);
 }
@@ -50,7 +50,7 @@ void fhci_stop_sof_timer(struct fhci_hcd *fhci)
 {
        fhci_dbg(fhci, "-> %s\n", __func__);
 
-       clrbits8(&fhci->regs->usb_mod, USB_MODE_SFTE);
+       clrbits8(&fhci->regs->usb_usmod, USB_MODE_SFTE);
        gtm_stop_timer16(fhci->timer);
 
        fhci_dbg(fhci, "<- %s\n", __func__);
@@ -58,7 +58,7 @@ void fhci_stop_sof_timer(struct fhci_hcd *fhci)
 
 u16 fhci_get_sof_timer_count(struct fhci_usb *usb)
 {
-       return be16_to_cpu(in_be16(&usb->fhci->regs->usb_sof_tmr) / 12);
+       return be16_to_cpu(in_be16(&usb->fhci->regs->usb_ussft) / 12);
 }
 
 /* initialize the endpoint zero */
@@ -88,8 +88,8 @@ void fhci_usb_enable_interrupt(struct fhci_usb *usb)
                enable_irq(fhci_to_hcd(fhci)->irq);
 
                /* initialize the event register and mask register */
-               out_be16(&usb->fhci->regs->usb_event, 0xffff);
-               out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk);
+               out_be16(&usb->fhci->regs->usb_usber, 0xffff);
+               out_be16(&usb->fhci->regs->usb_usbmr, usb->saved_msk);
 
                /* enable the timer interrupts */
                enable_irq(fhci->timer->irq);
@@ -109,7 +109,7 @@ void fhci_usb_disable_interrupt(struct fhci_usb *usb)
 
                /* disable the usb interrupt */
                disable_irq_nosync(fhci_to_hcd(fhci)->irq);
-               out_be16(&usb->fhci->regs->usb_mask, 0);
+               out_be16(&usb->fhci->regs->usb_usbmr, 0);
        }
        usb->intr_nesting_cnt++;
 }
@@ -119,9 +119,9 @@ static u32 fhci_usb_enable(struct fhci_hcd *fhci)
 {
        struct fhci_usb *usb = fhci->usb_lld;
 
-       out_be16(&usb->fhci->regs->usb_event, 0xffff);
-       out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk);
-       setbits8(&usb->fhci->regs->usb_mod, USB_MODE_EN);
+       out_be16(&usb->fhci->regs->usb_usber, 0xffff);
+       out_be16(&usb->fhci->regs->usb_usbmr, usb->saved_msk);
+       setbits8(&usb->fhci->regs->usb_usmod, USB_MODE_EN);
 
        mdelay(100);
 
@@ -141,7 +141,7 @@ static u32 fhci_usb_disable(struct fhci_hcd *fhci)
                        usb->port_status == FHCI_PORT_LOW)
                fhci_device_disconnected_interrupt(fhci);
 
-       clrbits8(&usb->fhci->regs->usb_mod, USB_MODE_EN);
+       clrbits8(&usb->fhci->regs->usb_usmod, USB_MODE_EN);
 
        return 0;
 }
@@ -285,13 +285,13 @@ static int fhci_usb_init(struct fhci_hcd *fhci)
                          USB_E_IDLE_MASK |
                          USB_E_RESET_MASK | USB_E_SFT_MASK | USB_E_MSF_MASK);
 
-       out_8(&usb->fhci->regs->usb_mod, USB_MODE_HOST | USB_MODE_EN);
+       out_8(&usb->fhci->regs->usb_usmod, USB_MODE_HOST | USB_MODE_EN);
 
        /* clearing the mask register */
-       out_be16(&usb->fhci->regs->usb_mask, 0);
+       out_be16(&usb->fhci->regs->usb_usbmr, 0);
 
        /* initialing the event register */
-       out_be16(&usb->fhci->regs->usb_event, 0xffff);
+       out_be16(&usb->fhci->regs->usb_usber, 0xffff);
 
        if (endpoint_zero_init(usb, DEFAULT_DATA_MEM, DEFAULT_RING_LEN) != 0) {
                fhci_usb_free(usb);
@@ -745,8 +745,8 @@ static int __devinit of_fhci_probe(struct platform_device *ofdev)
        }
 
        /* Clear and disable any pending interrupts. */
-       out_be16(&fhci->regs->usb_event, 0xffff);
-       out_be16(&fhci->regs->usb_mask, 0);
+       out_be16(&fhci->regs->usb_usber, 0xffff);
+       out_be16(&fhci->regs->usb_usbmr, 0);
 
        ret = usb_add_hcd(hcd, usb_irq, 0);
        if (ret < 0)
index 348fe62e94f7e6bddad59223559073a59cb06fbb..6af2512f8378ab7039f9f4d652177ea1380dca38 100644 (file)
@@ -97,7 +97,7 @@ void fhci_port_disable(struct fhci_hcd *fhci)
 
        /* Enable IDLE since we want to know if something comes along */
        usb->saved_msk |= USB_E_IDLE_MASK;
-       out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk);
+       out_be16(&usb->fhci->regs->usb_usbmr, usb->saved_msk);
 
        /* check if during the disconnection process attached new device */
        if (port_status == FHCI_PORT_WAITING)
@@ -158,21 +158,21 @@ void fhci_port_reset(void *lld)
 
        fhci_stop_sof_timer(fhci);
        /* disable the USB controller */
-       mode = in_8(&fhci->regs->usb_mod);
-       out_8(&fhci->regs->usb_mod, mode & (~USB_MODE_EN));
+       mode = in_8(&fhci->regs->usb_usmod);
+       out_8(&fhci->regs->usb_usmod, mode & (~USB_MODE_EN));
 
        /* disable idle interrupts */
-       mask = in_be16(&fhci->regs->usb_mask);
-       out_be16(&fhci->regs->usb_mask, mask & (~USB_E_IDLE_MASK));
+       mask = in_be16(&fhci->regs->usb_usbmr);
+       out_be16(&fhci->regs->usb_usbmr, mask & (~USB_E_IDLE_MASK));
 
        fhci_io_port_generate_reset(fhci);
 
        /* enable interrupt on this endpoint */
-       out_be16(&fhci->regs->usb_mask, mask);
+       out_be16(&fhci->regs->usb_usbmr, mask);
 
        /* enable the USB controller */
-       mode = in_8(&fhci->regs->usb_mod);
-       out_8(&fhci->regs->usb_mod, mode | USB_MODE_EN);
+       mode = in_8(&fhci->regs->usb_usmod);
+       out_8(&fhci->regs->usb_usmod, mode | USB_MODE_EN);
        fhci_start_sof_timer(fhci);
 
        fhci_dbg(fhci, "<- %s\n", __func__);
index 2df851b4bc7c1c474acdc65dc6e8143f38dbf7d1..2dc8a40e39d76e5d73023fdd7e433173ef5b01cf 100644 (file)
@@ -132,8 +132,8 @@ void fhci_flush_all_transmissions(struct fhci_usb *usb)
        u8 mode;
        struct td *td;
 
-       mode = in_8(&usb->fhci->regs->usb_mod);
-       clrbits8(&usb->fhci->regs->usb_mod, USB_MODE_EN);
+       mode = in_8(&usb->fhci->regs->usb_usmod);
+       clrbits8(&usb->fhci->regs->usb_usmod, USB_MODE_EN);
 
        fhci_flush_bds(usb);
 
@@ -147,9 +147,9 @@ void fhci_flush_all_transmissions(struct fhci_usb *usb)
        usb->actual_frame->frame_status = FRAME_END_TRANSMISSION;
 
        /* reset the event register */
-       out_be16(&usb->fhci->regs->usb_event, 0xffff);
+       out_be16(&usb->fhci->regs->usb_usber, 0xffff);
        /* enable the USB controller */
-       out_8(&usb->fhci->regs->usb_mod, mode | USB_MODE_EN);
+       out_8(&usb->fhci->regs->usb_usmod, mode | USB_MODE_EN);
 }
 
 /*
@@ -414,7 +414,7 @@ static void sof_interrupt(struct fhci_hcd *fhci)
                        usb->port_status = FHCI_PORT_FULL;
                /* Disable IDLE */
                usb->saved_msk &= ~USB_E_IDLE_MASK;
-               out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk);
+               out_be16(&usb->fhci->regs->usb_usbmr, usb->saved_msk);
        }
 
        gtm_set_exact_timer16(fhci->timer, usb->max_frame_usage, false);
@@ -433,14 +433,14 @@ void fhci_device_disconnected_interrupt(struct fhci_hcd *fhci)
        fhci_dbg(fhci, "-> %s\n", __func__);
 
        fhci_usb_disable_interrupt(usb);
-       clrbits8(&usb->fhci->regs->usb_mod, USB_MODE_LSS);
+       clrbits8(&usb->fhci->regs->usb_usmod, USB_MODE_LSS);
        usb->port_status = FHCI_PORT_DISABLED;
 
        fhci_stop_sof_timer(fhci);
 
        /* Enable IDLE since we want to know if something comes along */
        usb->saved_msk |= USB_E_IDLE_MASK;
-       out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk);
+       out_be16(&usb->fhci->regs->usb_usbmr, usb->saved_msk);
 
        usb->vroot_hub->port.wPortStatus &= ~USB_PORT_STAT_CONNECTION;
        usb->vroot_hub->port.wPortChange |= USB_PORT_STAT_C_CONNECTION;
@@ -473,7 +473,7 @@ void fhci_device_connected_interrupt(struct fhci_hcd *fhci)
                }
 
                usb->port_status = FHCI_PORT_LOW;
-               setbits8(&usb->fhci->regs->usb_mod, USB_MODE_LSS);
+               setbits8(&usb->fhci->regs->usb_usmod, USB_MODE_LSS);
                usb->vroot_hub->port.wPortStatus |=
                    (USB_PORT_STAT_LOW_SPEED |
                     USB_PORT_STAT_CONNECTION);
@@ -491,7 +491,7 @@ void fhci_device_connected_interrupt(struct fhci_hcd *fhci)
                }
 
                usb->port_status = FHCI_PORT_FULL;
-               clrbits8(&usb->fhci->regs->usb_mod, USB_MODE_LSS);
+               clrbits8(&usb->fhci->regs->usb_usmod, USB_MODE_LSS);
                usb->vroot_hub->port.wPortStatus &=
                    ~USB_PORT_STAT_LOW_SPEED;
                usb->vroot_hub->port.wPortStatus |=
@@ -535,7 +535,7 @@ static void abort_transmission(struct fhci_usb *usb)
        /* issue stop Tx command */
        qe_issue_cmd(QE_USB_STOP_TX, QE_CR_SUBBLOCK_USB, EP_ZERO, 0);
        /* flush Tx FIFOs */
-       out_8(&usb->fhci->regs->usb_comm, USB_CMD_FLUSH_FIFO | EP_ZERO);
+       out_8(&usb->fhci->regs->usb_uscom, USB_CMD_FLUSH_FIFO | EP_ZERO);
        udelay(1000);
        /* reset Tx BDs */
        fhci_flush_bds(usb);
@@ -555,11 +555,11 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd)
 
        usb = fhci->usb_lld;
 
-       usb_er |= in_be16(&usb->fhci->regs->usb_event) &
-                 in_be16(&usb->fhci->regs->usb_mask);
+       usb_er |= in_be16(&usb->fhci->regs->usb_usber) &
+                 in_be16(&usb->fhci->regs->usb_usbmr);
 
        /* clear event bits for next time */
-       out_be16(&usb->fhci->regs->usb_event, usb_er);
+       out_be16(&usb->fhci->regs->usb_usber, usb_er);
 
        fhci_dbg_isr(fhci, usb_er);
 
@@ -573,7 +573,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd)
 
                        /* Turn on IDLE since we want to disconnect */
                        usb->saved_msk |= USB_E_IDLE_MASK;
-                       out_be16(&usb->fhci->regs->usb_event,
+                       out_be16(&usb->fhci->regs->usb_usber,
                                 usb->saved_msk);
                } else if (usb->port_status == FHCI_PORT_DISABLED) {
                        if (fhci_ioports_check_bus_state(fhci) == 1)
@@ -611,7 +611,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd)
                        /* XXX usb->port_status = FHCI_PORT_WAITING; */
                        /* Disable IDLE */
                        usb->saved_msk &= ~USB_E_IDLE_MASK;
-                       out_be16(&usb->fhci->regs->usb_mask,
+                       out_be16(&usb->fhci->regs->usb_usbmr,
                                 usb->saved_msk);
                } else {
                        fhci_dbg_isr(fhci, -1);
index c5ed881992928be6fcf24f01d301bc1c27b210b5..1498061f0aea8cafdfc66f56ad986a1d51c49259 100644 (file)
@@ -249,7 +249,7 @@ void fhci_init_ep_registers(struct fhci_usb *usb, struct endpoint *ep,
        u8 rt;
 
        /* set the endpoint registers according to the endpoint */
-       out_be16(&usb->fhci->regs->usb_ep[0],
+       out_be16(&usb->fhci->regs->usb_usep[0],
                 USB_TRANS_CTR | USB_EP_MF | USB_EP_RTE);
        out_be16(&usb->fhci->pram->ep_ptr[0],
                 cpm_muram_offset(ep->ep_pram_ptr));
@@ -463,7 +463,7 @@ u32 fhci_host_transaction(struct fhci_usb *usb,
        cq_put(&ep->conf_frame_Q, pkt);
 
        if (cq_howmany(&ep->conf_frame_Q) == 1)
-               out_8(&usb->fhci->regs->usb_comm, USB_CMD_STR_FIFO);
+               out_8(&usb->fhci->regs->usb_uscom, USB_CMD_STR_FIFO);
 
        return 0;
 }
@@ -535,8 +535,8 @@ void fhci_flush_actual_frame(struct fhci_usb *usb)
        struct endpoint *ep = usb->ep0;
 
        /* disable the USB controller */
-       mode = in_8(&usb->fhci->regs->usb_mod);
-       out_8(&usb->fhci->regs->usb_mod, mode & ~USB_MODE_EN);
+       mode = in_8(&usb->fhci->regs->usb_usmod);
+       out_8(&usb->fhci->regs->usb_usmod, mode & ~USB_MODE_EN);
 
        tb_ptr = in_be16(&ep->ep_pram_ptr->tx_bd_ptr);
        td = cpm_muram_addr(tb_ptr);
@@ -571,9 +571,9 @@ void fhci_flush_actual_frame(struct fhci_usb *usb)
        usb->actual_frame->frame_status = FRAME_TIMER_END_TRANSMISSION;
 
        /* reset the event register */
-       out_be16(&usb->fhci->regs->usb_event, 0xffff);
+       out_be16(&usb->fhci->regs->usb_usber, 0xffff);
        /* enable the USB controller */
-       out_8(&usb->fhci->regs->usb_mod, mode | USB_MODE_EN);
+       out_8(&usb->fhci->regs->usb_usmod, mode | USB_MODE_EN);
 }
 
 /* handles Tx confirm and Tx error interrupt */
@@ -613,7 +613,7 @@ void fhci_host_transmit_actual_frame(struct fhci_usb *usb)
 
                /* start transmit only if we have something in the TDs */
                if (in_be16(&td->status) & TD_R)
-                       out_8(&usb->fhci->regs->usb_comm, USB_CMD_STR_FIFO);
+                       out_8(&usb->fhci->regs->usb_uscom, USB_CMD_STR_FIFO);
 
                if (in_be32(&ep->conf_td->buf_ptr) == DUMMY_BD_BUFFER) {
                        out_be32(&old_td->buf_ptr, 0);
index dc6939a44a1add3b958ba6c34f20740b000c5789..7cc1c32dc36cdf2c2a05aa4a4a43aa875bb8a9dc 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/usb.h>
 #include <linux/usb/hcd.h>
 #include <asm/qe.h>
+#include <asm/immap_qe.h>
 
 #define USB_CLOCK      48000000
 
 #define USB_E_TXB_MASK         0x0002
 #define USB_E_RXB_MASK         0x0001
 
-/* Freescale USB Host controller registers */
-struct fhci_regs {
-       u8 usb_mod;             /* mode register */
-       u8 usb_addr;            /* address register */
-       u8 usb_comm;            /* command register */
-       u8 reserved1[1];
-       __be16 usb_ep[4];       /* endpoint register */
-       u8 reserved2[4];
-       __be16 usb_event;       /* event register */
-       u8 reserved3[2];
-       __be16 usb_mask;        /* mask register */
-       u8 reserved4[1];
-       u8 usb_status;          /* status register */
-       __be16 usb_sof_tmr;     /* Start Of Frame timer */
-       u8 reserved5[2];
-       __be16 usb_frame_num;   /* frame number register */
-       u8 reserved6[1];
-};
-
 /* Freescale USB HOST */
 struct fhci_pram {
        __be16 ep_ptr[4];       /* Endpoint porter reg */
@@ -267,7 +249,7 @@ struct fhci_hcd {
        int gpios[NUM_GPIOS];
        bool alow_gpios[NUM_GPIOS];
 
-       struct fhci_regs __iomem *regs; /* I/O memory used to communicate */
+       struct qe_usb_ctlr __iomem *regs; /* I/O memory used to communicate */
        struct fhci_pram __iomem *pram; /* Parameter RAM */
        struct gtm_timer *timer;
 
index 1e364ec962fb90ea75573c92fc6a92ec6b25612c..a446386bf779208518b760ffcfb94cc346dc4f5b 100644 (file)
 #define USB_HOST_NEED_CLK_EN   (1 << 21)
 #define PAD_CONTROL_LAST_DRIVEN        (1 << 19)
 
-#define USB_OTG_CLK_CTRL       IO_ADDRESS(USB_CONFIG_BASE + 0xFF4)
-#define USB_OTG_CLK_STAT       IO_ADDRESS(USB_CONFIG_BASE + 0xFF8)
-
-/* USB_OTG_CLK_CTRL bit defines */
-#define AHB_M_CLOCK_ON         (1 << 4)
-#define OTG_CLOCK_ON           (1 << 3)
-#define I2C_CLOCK_ON           (1 << 2)
-#define DEV_CLOCK_ON           (1 << 1)
-#define HOST_CLOCK_ON          (1 << 0)
-
 #define USB_OTG_STAT_CONTROL   IO_ADDRESS(USB_CONFIG_BASE + 0x110)
 
 /* USB_OTG_STAT_CONTROL bit defines */
@@ -72,7 +62,9 @@ static struct i2c_client *isp1301_i2c_client;
 
 extern int usb_disabled(void);
 
-static struct clk *usb_clk;
+static struct clk *usb_pll_clk;
+static struct clk *usb_dev_clk;
+static struct clk *usb_otg_clk;
 
 static void isp1301_configure_pnx4008(void)
 {
@@ -249,8 +241,6 @@ static const struct hc_driver ohci_nxp_hc_driver = {
        .start_port_reset = ohci_start_port_reset,
 };
 
-#define USB_CLOCK_MASK (AHB_M_CLOCK_ON| OTG_CLOCK_ON | HOST_CLOCK_ON | I2C_CLOCK_ON)
-
 static void nxp_set_usb_bits(void)
 {
        if (machine_is_pnx4008()) {
@@ -327,41 +317,63 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev)
        /* Enable AHB slave USB clock, needed for further USB clock control */
        __raw_writel(USB_SLAVE_HCLK_EN | PAD_CONTROL_LAST_DRIVEN, USB_CTRL);
 
-       isp1301_configure();
-
        /* Enable USB PLL */
-       usb_clk = clk_get(&pdev->dev, "ck_pll5");
-       if (IS_ERR(usb_clk)) {
+       usb_pll_clk = clk_get(&pdev->dev, "ck_pll5");
+       if (IS_ERR(usb_pll_clk)) {
                dev_err(&pdev->dev, "failed to acquire USB PLL\n");
-               ret = PTR_ERR(usb_clk);
+               ret = PTR_ERR(usb_pll_clk);
                goto out1;
        }
 
-       ret = clk_enable(usb_clk);
+       ret = clk_enable(usb_pll_clk);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to start USB PLL\n");
                goto out2;
        }
 
-       ret = clk_set_rate(usb_clk, 48000);
+       ret = clk_set_rate(usb_pll_clk, 48000);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to set USB clock rate\n");
                goto out3;
        }
 
+       /* Enable USB device clock */
+       usb_dev_clk = clk_get(&pdev->dev, "ck_usbd");
+       if (IS_ERR(usb_dev_clk)) {
+               dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n");
+               ret = PTR_ERR(usb_dev_clk);
+               goto out4;
+       }
+
+       ret = clk_enable(usb_dev_clk);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to start USB DEV Clock\n");
+               goto out5;
+       }
+
+       /* Enable USB otg clocks */
+       usb_otg_clk = clk_get(&pdev->dev, "ck_usb_otg");
+       if (IS_ERR(usb_otg_clk)) {
+               dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n");
+               ret = PTR_ERR(usb_dev_clk);
+               goto out6;
+       }
+
        __raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL);
 
-       /* Set to enable all needed USB clocks */
-       __raw_writel(USB_CLOCK_MASK, USB_OTG_CLK_CTRL);
+       ret = clk_enable(usb_otg_clk);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to start USB DEV Clock\n");
+               goto out7;
+       }
 
-       while ((__raw_readl(USB_OTG_CLK_STAT) & USB_CLOCK_MASK) !=
-              USB_CLOCK_MASK) ;
+       isp1301_configure();
 
        hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
        if (!hcd) {
                dev_err(&pdev->dev, "Failed to allocate HC buffer\n");
                ret = -ENOMEM;
-               goto out3;
+               goto out8;
        }
 
        /* Set all USB bits in the Start Enable register */
@@ -371,14 +383,14 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev)
        if (!res) {
                dev_err(&pdev->dev, "Failed to get MEM resource\n");
                ret =  -ENOMEM;
-               goto out4;
+               goto out8;
        }
 
        hcd->regs = devm_request_and_ioremap(&pdev->dev, res);
        if (!hcd->regs) {
                dev_err(&pdev->dev, "Failed to devm_request_and_ioremap\n");
                ret =  -ENOMEM;
-               goto out4;
+               goto out8;
        }
        hcd->rsrc_start = res->start;
        hcd->rsrc_len = resource_size(res);
@@ -386,7 +398,7 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev)
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
                ret = -ENXIO;
-               goto out4;
+               goto out8;
        }
 
        nxp_start_hc();
@@ -400,13 +412,21 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev)
                return ret;
 
        nxp_stop_hc();
-out4:
+out8:
        nxp_unset_usb_bits();
        usb_put_hcd(hcd);
+out7:
+       clk_disable(usb_otg_clk);
+out6:
+       clk_put(usb_otg_clk);
+out5:
+       clk_disable(usb_dev_clk);
+out4:
+       clk_put(usb_dev_clk);
 out3:
-       clk_disable(usb_clk);
+       clk_disable(usb_pll_clk);
 out2:
-       clk_put(usb_clk);
+       clk_put(usb_pll_clk);
 out1:
        isp1301_i2c_client = NULL;
 out:
@@ -422,8 +442,10 @@ static int usb_hcd_nxp_remove(struct platform_device *pdev)
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
        usb_put_hcd(hcd);
        nxp_unset_usb_bits();
-       clk_disable(usb_clk);
-       clk_put(usb_clk);
+       clk_disable(usb_pll_clk);
+       clk_put(usb_pll_clk);
+       clk_disable(usb_dev_clk);
+       clk_put(usb_dev_clk);
        i2c_unregister_device(isp1301_i2c_client);
        isp1301_i2c_client = NULL;
 
index 9ce35d0d9d5daad531209e6b651a1fcc714efb18..eccddb461396d58ee6b10636f2379e21c0f67fc0 100644 (file)
@@ -167,14 +167,15 @@ static int omap_1510_local_bus_init(void)
 
 static void start_hnp(struct ohci_hcd *ohci)
 {
-       const unsigned  port = ohci_to_hcd(ohci)->self.otg_port - 1;
+       struct usb_hcd *hcd = ohci_to_hcd(ohci);
+       const unsigned  port = hcd->self.otg_port - 1;
        unsigned long   flags;
        u32 l;
 
-       otg_start_hnp(ohci->transceiver->otg);
+       otg_start_hnp(hcd->phy->otg);
 
        local_irq_save(flags);
-       ohci->transceiver->state = OTG_STATE_A_SUSPEND;
+       hcd->phy->state = OTG_STATE_A_SUSPEND;
        writel (RH_PS_PSS, &ohci->regs->roothub.portstatus [port]);
        l = omap_readl(OTG_CTRL);
        l &= ~OTG_A_BUSREQ;
@@ -211,18 +212,18 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 
 #ifdef CONFIG_USB_OTG
        if (need_transceiver) {
-               ohci->transceiver = usb_get_transceiver();
-               if (ohci->transceiver) {
-                       int     status = otg_set_host(ohci->transceiver->otg,
+               hcd->phy = usb_get_transceiver();
+               if (hcd->phy) {
+                       int     status = otg_set_host(hcd->phy->otg,
                                                &ohci_to_hcd(ohci)->self);
-                       dev_dbg(hcd->self.controller, "init %s transceiver, status %d\n",
-                                       ohci->transceiver->label, status);
+                       dev_dbg(hcd->self.controller, "init %s phy, status %d\n",
+                                       hcd->phy->label, status);
                        if (status) {
-                               usb_put_transceiver(ohci->transceiver);
+                               usb_put_transceiver(hcd->phy);
                                return status;
                        }
                } else {
-                       dev_err(hcd->self.controller, "can't find transceiver\n");
+                       dev_err(hcd->self.controller, "can't find phy\n");
                        return -ENODEV;
                }
                ohci->start_hnp = start_hnp;
@@ -403,9 +404,9 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
        struct ohci_hcd         *ohci = hcd_to_ohci (hcd);
 
        usb_remove_hcd(hcd);
-       if (ohci->transceiver) {
-               (void) otg_set_host(ohci->transceiver->otg, 0);
-               usb_put_transceiver(ohci->transceiver);
+       if (hcd->phy) {
+               (void) otg_set_host(hcd->phy->otg, 0);
+               usb_put_transceiver(hcd->phy);
        }
        if (machine_is_omap_osk())
                gpio_free(9);
index 1b19aea25a2bc1281d601cbe64de7e74274c1a24..d3299143d9e2cbc8c0f4a2f307da6318252010b8 100644 (file)
@@ -372,11 +372,6 @@ struct ohci_hcd {
        struct ed               *ed_controltail;        /* last in ctrl list */
        struct ed               *periodic [NUM_INTS];   /* shadow int_table */
 
-       /*
-        * OTG controllers and transceivers need software interaction;
-        * other external transceivers should be software-transparent
-        */
-       struct usb_phy  *transceiver;
        void (*start_hnp)(struct ohci_hcd *ohci);
 
        /*
index a1b99243dac9e77ac83be2e1b94316ff5014601c..9a0ca83559053c47fb8866b9a66c617eeb11378f 100644 (file)
@@ -1036,15 +1036,12 @@ static int keyspan_write_room(struct tty_struct *tty)
 static int keyspan_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
        struct keyspan_port_private     *p_priv;
-       struct keyspan_serial_private   *s_priv;
-       struct usb_serial               *serial = port->serial;
        const struct keyspan_device_details     *d_details;
        int                             i, err;
        int                             baud_rate, device_port;
        struct urb                      *urb;
        unsigned int                    cflag = 0;
 
-       s_priv = usb_get_serial_data(serial);
        p_priv = usb_get_serial_port_data(port);
        d_details = p_priv->device_details;
 
@@ -1130,10 +1127,8 @@ static void keyspan_close(struct usb_serial_port *port)
 {
        int                     i;
        struct usb_serial       *serial = port->serial;
-       struct keyspan_serial_private   *s_priv;
        struct keyspan_port_private     *p_priv;
 
-       s_priv = usb_get_serial_data(serial);
        p_priv = usb_get_serial_port_data(port);
 
        p_priv->rts_state = 0;
index adf8ce72be50fb9fed94377fc54a7e22814a832f..a0382b24866e2d65c87011e9c45b91d30bdee4b0 100644 (file)
@@ -1284,6 +1284,10 @@ static struct usb_serial_driver * const serial_drivers[] = {
 
 static bool debug;
 
+struct option_private {
+       u8 bInterfaceNumber;
+};
+
 module_usb_serial_driver(serial_drivers, option_ids);
 
 static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason,
@@ -1314,51 +1318,78 @@ static int option_probe(struct usb_serial *serial,
                        const struct usb_device_id *id)
 {
        struct usb_wwan_intf_private *data;
-
-       /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */
-       if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID &&
-               serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 &&
-               serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8)
+       struct option_private *priv;
+       struct usb_interface_descriptor *iface_desc =
+                               &serial->interface->cur_altsetting->desc;
+       struct usb_device_descriptor *dev_desc = &serial->dev->descriptor;
+
+       /*
+        * D-Link DWM 652 still exposes CD-Rom emulation interface in modem
+        * mode.
+        */
+       if (dev_desc->idVendor == DLINK_VENDOR_ID &&
+               dev_desc->idProduct == DLINK_PRODUCT_DWM_652 &&
+               iface_desc->bInterfaceClass == 0x08)
                return -ENODEV;
 
        /* Bandrich modem and AT command interface is 0xff */
-       if ((serial->dev->descriptor.idVendor == BANDRICH_VENDOR_ID ||
-               serial->dev->descriptor.idVendor == PIRELLI_VENDOR_ID) &&
-               serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff)
+       if ((dev_desc->idVendor == BANDRICH_VENDOR_ID ||
+               dev_desc->idVendor == PIRELLI_VENDOR_ID) &&
+               iface_desc->bInterfaceClass != 0xff)
                return -ENODEV;
-
-       /* Don't bind reserved interfaces (like network ones) which often have
+       /*
+        * Don't bind reserved interfaces (like network ones) which often have
         * the same class/subclass/protocol as the serial interfaces.  Look at
         * the Windows driver .INF files for reserved interface numbers.
         */
        if (is_blacklisted(
-               serial->interface->cur_altsetting->desc.bInterfaceNumber,
+               iface_desc->bInterfaceNumber,
                OPTION_BLACKLIST_RESERVED_IF,
                (const struct option_blacklist_info *) id->driver_info))
                return -ENODEV;
-
-       /* Don't bind network interface on Samsung GT-B3730, it is handled by a separate module */
-       if (serial->dev->descriptor.idVendor == SAMSUNG_VENDOR_ID &&
-               serial->dev->descriptor.idProduct == SAMSUNG_PRODUCT_GT_B3730 &&
-               serial->interface->cur_altsetting->desc.bInterfaceClass != USB_CLASS_CDC_DATA)
+       /*
+        * Don't bind network interface on Samsung GT-B3730, it is handled by
+        * a separate module.
+        */
+       if (dev_desc->idVendor == SAMSUNG_VENDOR_ID &&
+               dev_desc->idProduct == SAMSUNG_PRODUCT_GT_B3730 &&
+               iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA)
                return -ENODEV;
 
-       data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL);
+       data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
-       data->send_setup = option_send_setup;
+
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+       if (!priv) {
+               kfree(data);
+               return -ENOMEM;
+       }
+
+       priv->bInterfaceNumber = iface_desc->bInterfaceNumber;
+       data->private = priv;
+
+       if (!is_blacklisted(iface_desc->bInterfaceNumber,
+                       OPTION_BLACKLIST_SENDSETUP,
+                       (struct option_blacklist_info *)id->driver_info)) {
+               data->send_setup = option_send_setup;
+       }
        spin_lock_init(&data->susp_lock);
-       data->private = (void *)id->driver_info;
+
+       usb_set_serial_data(serial, data);
+
        return 0;
 }
 
 static void option_release(struct usb_serial *serial)
 {
-       struct usb_wwan_intf_private *priv = usb_get_serial_data(serial);
+       struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
+       struct option_private *priv = intfdata->private;
 
        usb_wwan_release(serial);
 
        kfree(priv);
+       kfree(intfdata);
 }
 
 static void option_instat_callback(struct urb *urb)
@@ -1425,18 +1456,11 @@ static void option_instat_callback(struct urb *urb)
 static int option_send_setup(struct usb_serial_port *port)
 {
        struct usb_serial *serial = port->serial;
-       struct usb_wwan_intf_private *intfdata =
-               (struct usb_wwan_intf_private *) serial->private;
+       struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
+       struct option_private *priv = intfdata->private;
        struct usb_wwan_port_private *portdata;
-       int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
        int val = 0;
 
-       if (is_blacklisted(ifNum, OPTION_BLACKLIST_SENDSETUP,
-                       (struct option_blacklist_info *) intfdata->private)) {
-               dbg("No send_setup on blacklisted interface #%d\n", ifNum);
-               return -EIO;
-       }
-
        portdata = usb_get_serial_port_data(port);
 
        if (portdata->dtr_state)
@@ -1444,9 +1468,9 @@ static int option_send_setup(struct usb_serial_port *port)
        if (portdata->rts_state)
                val |= 0x02;
 
-       return usb_control_msg(serial->dev,
-               usb_rcvctrlpipe(serial->dev, 0),
-               0x22, 0x21, val, ifNum, NULL, 0, USB_CTRL_SET_TIMEOUT);
+       return usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+                               0x22, 0x21, val, priv->bInterfaceNumber, NULL,
+                               0, USB_CTRL_SET_TIMEOUT);
 }
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
index 8dd88ebe9863d34e5ca786417389a127d9900075..151670b6b72a9871bcf88fd5e611b3247bae9904 100644 (file)
@@ -345,7 +345,6 @@ static void qt2_set_termios(struct tty_struct *tty,
 static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
        struct usb_serial *serial;
-       struct qt2_serial_private *serial_priv;
        struct qt2_port_private *port_priv;
        u8 *data;
        u16 device_port;
@@ -357,7 +356,6 @@ static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port)
        serial = port->serial;
 
        port_priv = usb_get_serial_port_data(port);
-       serial_priv = usb_get_serial_data(serial);
 
        /* set the port to RS232 mode */
        status = qt2_control_msg(serial->dev, QT2_GET_SET_QMCR,
@@ -417,13 +415,11 @@ static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port)
 static void qt2_close(struct usb_serial_port *port)
 {
        struct usb_serial *serial;
-       struct qt2_serial_private *serial_priv;
        struct qt2_port_private *port_priv;
        unsigned long flags;
        int i;
 
        serial = port->serial;
-       serial_priv = usb_get_serial_data(serial);
        port_priv = usb_get_serial_port_data(port);
 
        port_priv->is_open = false;
index 82dd834709c78f7627b82a53d5e268fb006744a2..5dfb4c36a1b0a2aeb55dd4863c33fae132d2ce7b 100644 (file)
@@ -66,7 +66,7 @@ void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us)
         * NOTE: This only works because a scsi_cmnd struct field contains
         * a unsigned char cmnd[16], so we know we have storage available
         */
-       for (; srb->cmd_len<12; srb->cmd_len++)
+       for (; srb->cmd_len < 12; srb->cmd_len++)
                srb->cmnd[srb->cmd_len] = 0;
 
        /* send the command to the transport layer */
@@ -76,14 +76,14 @@ void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us)
 void usb_stor_ufi_command(struct scsi_cmnd *srb, struct us_data *us)
 {
        /* fix some commands -- this is a form of mode translation
-        * UFI devices only accept 12 byte long commands 
+        * UFI devices only accept 12 byte long commands
         *
         * NOTE: This only works because a scsi_cmnd struct field contains
         * a unsigned char cmnd[16], so we know we have storage available
         */
 
        /* Pad the ATAPI command with zeros */
-       for (; srb->cmd_len<12; srb->cmd_len++)
+       for (; srb->cmd_len < 12; srb->cmd_len++)
                srb->cmnd[srb->cmd_len] = 0;
 
        /* set command length to 12 bytes (this affects the transport layer) */
index 8ec8a6e66f504584c0a85acdfd41fa028fe775bb..638cd64f961014bf59fd75f10542595a651bc9bd 100644 (file)
@@ -41,16 +41,17 @@ struct sense_iu_old {
 struct uas_dev_info {
        struct usb_interface *intf;
        struct usb_device *udev;
-       int qdepth;
+       struct usb_anchor sense_urbs;
+       struct usb_anchor data_urbs;
+       int qdepth, resetting;
+       struct response_ui response;
        unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe;
        unsigned use_streams:1;
        unsigned uas_sense_old:1;
        struct scsi_cmnd *cmnd;
-       struct urb *status_urb; /* used only if stream support is available */
 };
 
 enum {
-       ALLOC_STATUS_URB        = (1 << 0),
        SUBMIT_STATUS_URB       = (1 << 1),
        ALLOC_DATA_IN_URB       = (1 << 2),
        SUBMIT_DATA_IN_URB      = (1 << 3),
@@ -58,18 +59,18 @@ enum {
        SUBMIT_DATA_OUT_URB     = (1 << 5),
        ALLOC_CMD_URB           = (1 << 6),
        SUBMIT_CMD_URB          = (1 << 7),
-       COMPLETED_DATA_IN       = (1 << 8),
-       COMPLETED_DATA_OUT      = (1 << 9),
-       DATA_COMPLETES_CMD      = (1 << 10),
+       COMMAND_INFLIGHT        = (1 << 8),
+       DATA_IN_URB_INFLIGHT    = (1 << 9),
+       DATA_OUT_URB_INFLIGHT   = (1 << 10),
+       COMMAND_COMPLETED       = (1 << 11),
 };
 
 /* Overrides scsi_pointer */
 struct uas_cmd_info {
        unsigned int state;
        unsigned int stream;
+       unsigned int aborted;
        struct urb *cmd_urb;
-       /* status_urb is used only if stream support isn't available */
-       struct urb *status_urb;
        struct urb *data_in_urb;
        struct urb *data_out_urb;
        struct list_head list;
@@ -114,7 +115,6 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd)
 {
        struct sense_iu *sense_iu = urb->transfer_buffer;
        struct scsi_device *sdev = cmnd->device;
-       struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
 
        if (urb->actual_length > 16) {
                unsigned len = be16_to_cpup(&sense_iu->len);
@@ -132,15 +132,12 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd)
        }
 
        cmnd->result = sense_iu->status;
-       if (!(cmdinfo->state & DATA_COMPLETES_CMD))
-               cmnd->scsi_done(cmnd);
 }
 
 static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd)
 {
        struct sense_iu_old *sense_iu = urb->transfer_buffer;
        struct scsi_device *sdev = cmnd->device;
-       struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
 
        if (urb->actual_length > 8) {
                unsigned len = be16_to_cpup(&sense_iu->len) - 2;
@@ -158,17 +155,51 @@ static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd)
        }
 
        cmnd->result = sense_iu->status;
-       if (!(cmdinfo->state & DATA_COMPLETES_CMD))
-               cmnd->scsi_done(cmnd);
+}
+
+static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *caller)
+{
+       struct uas_cmd_info *ci = (void *)&cmnd->SCp;
+
+       scmd_printk(KERN_INFO, cmnd, "%s %p tag %d, inflight:"
+                   "%s%s%s%s%s%s%s%s%s%s%s\n",
+                   caller, cmnd, cmnd->request->tag,
+                   (ci->state & SUBMIT_STATUS_URB)     ? " s-st"  : "",
+                   (ci->state & ALLOC_DATA_IN_URB)     ? " a-in"  : "",
+                   (ci->state & SUBMIT_DATA_IN_URB)    ? " s-in"  : "",
+                   (ci->state & ALLOC_DATA_OUT_URB)    ? " a-out" : "",
+                   (ci->state & SUBMIT_DATA_OUT_URB)   ? " s-out" : "",
+                   (ci->state & ALLOC_CMD_URB)         ? " a-cmd" : "",
+                   (ci->state & SUBMIT_CMD_URB)        ? " s-cmd" : "",
+                   (ci->state & COMMAND_INFLIGHT)      ? " CMD"   : "",
+                   (ci->state & DATA_IN_URB_INFLIGHT)  ? " IN"    : "",
+                   (ci->state & DATA_OUT_URB_INFLIGHT) ? " OUT"   : "",
+                   (ci->state & COMMAND_COMPLETED)     ? " done"  : "");
+}
+
+static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller)
+{
+       struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
+
+       if (cmdinfo->state & (COMMAND_INFLIGHT |
+                             DATA_IN_URB_INFLIGHT |
+                             DATA_OUT_URB_INFLIGHT))
+               return -EBUSY;
+       BUG_ON(cmdinfo->state & COMMAND_COMPLETED);
+       cmdinfo->state |= COMMAND_COMPLETED;
+       usb_free_urb(cmdinfo->data_in_urb);
+       usb_free_urb(cmdinfo->data_out_urb);
+       cmnd->scsi_done(cmnd);
+       return 0;
 }
 
 static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd,
-                                                       unsigned direction)
+                         unsigned direction)
 {
        struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
        int err;
 
-       cmdinfo->state = direction;
+       cmdinfo->state |= direction | SUBMIT_STATUS_URB;
        err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC);
        if (err) {
                spin_lock(&uas_work_lock);
@@ -186,12 +217,15 @@ static void uas_stat_cmplt(struct urb *urb)
        struct scsi_cmnd *cmnd;
        struct uas_cmd_info *cmdinfo;
        u16 tag;
-       int ret;
 
        if (urb->status) {
                dev_err(&urb->dev->dev, "URB BAD STATUS %d\n", urb->status);
-               if (devinfo->use_streams)
-                       usb_free_urb(urb);
+               usb_free_urb(urb);
+               return;
+       }
+
+       if (devinfo->resetting) {
+               usb_free_urb(urb);
                return;
        }
 
@@ -201,47 +235,34 @@ static void uas_stat_cmplt(struct urb *urb)
        else
                cmnd = scsi_host_find_tag(shost, tag - 1);
        if (!cmnd) {
-               if (devinfo->use_streams) {
+               if (iu->iu_id != IU_ID_RESPONSE) {
                        usb_free_urb(urb);
                        return;
                }
-               ret = usb_submit_urb(urb, GFP_ATOMIC);
-               if (ret)
-                       dev_err(&urb->dev->dev, "failed submit status urb\n");
-               return;
+       } else {
+               cmdinfo = (void *)&cmnd->SCp;
        }
-       cmdinfo = (void *)&cmnd->SCp;
 
        switch (iu->iu_id) {
        case IU_ID_STATUS:
                if (devinfo->cmnd == cmnd)
                        devinfo->cmnd = NULL;
 
-               if (!(cmdinfo->state & COMPLETED_DATA_IN) &&
-                               cmdinfo->data_in_urb) {
-                      if (devinfo->use_streams) {
-                              cmdinfo->state |= DATA_COMPLETES_CMD;
-                              usb_unlink_urb(cmdinfo->data_in_urb);
-                      } else {
-                              usb_free_urb(cmdinfo->data_in_urb);
-                      }
-               }
-               if (!(cmdinfo->state & COMPLETED_DATA_OUT) &&
-                               cmdinfo->data_out_urb) {
-                       if (devinfo->use_streams) {
-                               cmdinfo->state |= DATA_COMPLETES_CMD;
-                               usb_unlink_urb(cmdinfo->data_in_urb);
-                       } else {
-                               usb_free_urb(cmdinfo->data_out_urb);
-                       }
-               }
-
                if (urb->actual_length < 16)
                        devinfo->uas_sense_old = 1;
                if (devinfo->uas_sense_old)
                        uas_sense_old(urb, cmnd);
                else
                        uas_sense(urb, cmnd);
+               if (cmnd->result != 0) {
+                       /* cancel data transfers on error */
+                       if (cmdinfo->state & DATA_IN_URB_INFLIGHT)
+                               usb_unlink_urb(cmdinfo->data_in_urb);
+                       if (cmdinfo->state & DATA_OUT_URB_INFLIGHT)
+                               usb_unlink_urb(cmdinfo->data_out_urb);
+               }
+               cmdinfo->state &= ~COMMAND_INFLIGHT;
+               uas_try_complete(cmnd, __func__);
                break;
        case IU_ID_READ_READY:
                uas_xfer_data(urb, cmnd, SUBMIT_DATA_IN_URB);
@@ -249,74 +270,59 @@ static void uas_stat_cmplt(struct urb *urb)
        case IU_ID_WRITE_READY:
                uas_xfer_data(urb, cmnd, SUBMIT_DATA_OUT_URB);
                break;
+       case IU_ID_RESPONSE:
+               /* store results for uas_eh_task_mgmt() */
+               memcpy(&devinfo->response, iu, sizeof(devinfo->response));
+               break;
        default:
                scmd_printk(KERN_ERR, cmnd,
                        "Bogus IU (%d) received on status pipe\n", iu->iu_id);
        }
-
-       if (devinfo->use_streams) {
-               usb_free_urb(urb);
-               return;
-       }
-
-       ret = usb_submit_urb(urb, GFP_ATOMIC);
-       if (ret)
-               dev_err(&urb->dev->dev, "failed submit status urb\n");
-}
-
-static void uas_data_out_cmplt(struct urb *urb)
-{
-       struct scsi_cmnd *cmnd = urb->context;
-       struct scsi_data_buffer *sdb = scsi_out(cmnd);
-       struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
-
-       cmdinfo->state |= COMPLETED_DATA_OUT;
-
-       sdb->resid = sdb->length - urb->actual_length;
        usb_free_urb(urb);
-
-       if (cmdinfo->state & DATA_COMPLETES_CMD)
-               cmnd->scsi_done(cmnd);
 }
 
-static void uas_data_in_cmplt(struct urb *urb)
+static void uas_data_cmplt(struct urb *urb)
 {
        struct scsi_cmnd *cmnd = urb->context;
-       struct scsi_data_buffer *sdb = scsi_in(cmnd);
        struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
+       struct scsi_data_buffer *sdb = NULL;
 
-       cmdinfo->state |= COMPLETED_DATA_IN;
-
-       sdb->resid = sdb->length - urb->actual_length;
-       usb_free_urb(urb);
-
-       if (cmdinfo->state & DATA_COMPLETES_CMD)
-               cmnd->scsi_done(cmnd);
+       if (cmdinfo->data_in_urb == urb) {
+               sdb = scsi_in(cmnd);
+               cmdinfo->state &= ~DATA_IN_URB_INFLIGHT;
+       } else if (cmdinfo->data_out_urb == urb) {
+               sdb = scsi_out(cmnd);
+               cmdinfo->state &= ~DATA_OUT_URB_INFLIGHT;
+       }
+       BUG_ON(sdb == NULL);
+       if (urb->status) {
+               /* error: no data transfered */
+               sdb->resid = sdb->length;
+       } else {
+               sdb->resid = sdb->length - urb->actual_length;
+       }
+       if (cmdinfo->aborted) {
+               return;
+       }
+       uas_try_complete(cmnd, __func__);
 }
 
 static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp,
-               unsigned int pipe, struct scsi_cmnd *cmnd,
-               enum dma_data_direction dir)
+                                     unsigned int pipe, u16 stream_id,
+                                     struct scsi_cmnd *cmnd,
+                                     enum dma_data_direction dir)
 {
-       struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
        struct usb_device *udev = devinfo->udev;
        struct urb *urb = usb_alloc_urb(0, gfp);
-       struct scsi_data_buffer *sdb;
-       usb_complete_t complete_fn;
-       u16 stream_id = cmdinfo->stream;
+       struct scsi_data_buffer *sdb = (dir == DMA_FROM_DEVICE)
+               ? scsi_in(cmnd) : scsi_out(cmnd);
 
        if (!urb)
                goto out;
-       if (dir == DMA_FROM_DEVICE) {
-               sdb = scsi_in(cmnd);
-               complete_fn = uas_data_in_cmplt;
-       } else {
-               sdb = scsi_out(cmnd);
-               complete_fn = uas_data_out_cmplt;
-       }
        usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length,
-                       complete_fn, cmnd);
-       urb->stream_id = stream_id;
+                         uas_data_cmplt, cmnd);
+       if (devinfo->use_streams)
+               urb->stream_id = stream_id;
        urb->num_sgs = udev->bus->sg_tablesize ? sdb->table.nents : 0;
        urb->sg = sdb->table.sgl;
  out:
@@ -324,7 +330,7 @@ static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp,
 }
 
 static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp,
-               struct Scsi_Host *shost, u16 stream_id)
+                                      struct Scsi_Host *shost, u16 stream_id)
 {
        struct usb_device *udev = devinfo->udev;
        struct urb *urb = usb_alloc_urb(0, gfp);
@@ -388,38 +394,95 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp,
        return NULL;
 }
 
+static int uas_submit_task_urb(struct scsi_cmnd *cmnd, gfp_t gfp,
+                              u8 function, u16 stream_id)
+{
+       struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata;
+       struct usb_device *udev = devinfo->udev;
+       struct urb *urb = usb_alloc_urb(0, gfp);
+       struct task_mgmt_iu *iu;
+       int err = -ENOMEM;
+
+       if (!urb)
+               goto err;
+
+       iu = kzalloc(sizeof(*iu), gfp);
+       if (!iu)
+               goto err;
+
+       iu->iu_id = IU_ID_TASK_MGMT;
+       iu->tag = cpu_to_be16(stream_id);
+       int_to_scsilun(cmnd->device->lun, &iu->lun);
+
+       iu->function = function;
+       switch (function) {
+       case TMF_ABORT_TASK:
+               if (blk_rq_tagged(cmnd->request))
+                       iu->task_tag = cpu_to_be16(cmnd->request->tag + 2);
+               else
+                       iu->task_tag = cpu_to_be16(1);
+               break;
+       }
+
+       usb_fill_bulk_urb(urb, udev, devinfo->cmd_pipe, iu, sizeof(*iu),
+                         usb_free_urb, NULL);
+       urb->transfer_flags |= URB_FREE_BUFFER;
+
+       err = usb_submit_urb(urb, gfp);
+       if (err)
+               goto err;
+
+       return 0;
+
+err:
+       usb_free_urb(urb);
+       return err;
+}
+
 /*
  * Why should I request the Status IU before sending the Command IU?  Spec
  * says to, but also says the device may receive them in any order.  Seems
  * daft to me.
  */
 
-static int uas_submit_urbs(struct scsi_cmnd *cmnd,
-                                       struct uas_dev_info *devinfo, gfp_t gfp)
+static int uas_submit_sense_urb(struct Scsi_Host *shost,
+                               gfp_t gfp, unsigned int stream)
 {
-       struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
+       struct uas_dev_info *devinfo = (void *)shost->hostdata[0];
+       struct urb *urb;
 
-       if (cmdinfo->state & ALLOC_STATUS_URB) {
-               cmdinfo->status_urb = uas_alloc_sense_urb(devinfo, gfp,
-                               cmnd->device->host, cmdinfo->stream);
-               if (!cmdinfo->status_urb)
-                       return SCSI_MLQUEUE_DEVICE_BUSY;
-               cmdinfo->state &= ~ALLOC_STATUS_URB;
+       urb = uas_alloc_sense_urb(devinfo, gfp, shost, stream);
+       if (!urb)
+               return SCSI_MLQUEUE_DEVICE_BUSY;
+       if (usb_submit_urb(urb, gfp)) {
+               shost_printk(KERN_INFO, shost,
+                            "sense urb submission failure\n");
+               usb_free_urb(urb);
+               return SCSI_MLQUEUE_DEVICE_BUSY;
        }
+       usb_anchor_urb(urb, &devinfo->sense_urbs);
+       return 0;
+}
+
+static int uas_submit_urbs(struct scsi_cmnd *cmnd,
+                          struct uas_dev_info *devinfo, gfp_t gfp)
+{
+       struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
+       int err;
 
        if (cmdinfo->state & SUBMIT_STATUS_URB) {
-               if (usb_submit_urb(cmdinfo->status_urb, gfp)) {
-                       scmd_printk(KERN_INFO, cmnd,
-                                       "sense urb submission failure\n");
-                       return SCSI_MLQUEUE_DEVICE_BUSY;
+               err = uas_submit_sense_urb(cmnd->device->host, gfp,
+                                          cmdinfo->stream);
+               if (err) {
+                       return err;
                }
                cmdinfo->state &= ~SUBMIT_STATUS_URB;
        }
 
        if (cmdinfo->state & ALLOC_DATA_IN_URB) {
                cmdinfo->data_in_urb = uas_alloc_data_urb(devinfo, gfp,
-                                       devinfo->data_in_pipe, cmnd,
-                                       DMA_FROM_DEVICE);
+                                       devinfo->data_in_pipe, cmdinfo->stream,
+                                       cmnd, DMA_FROM_DEVICE);
                if (!cmdinfo->data_in_urb)
                        return SCSI_MLQUEUE_DEVICE_BUSY;
                cmdinfo->state &= ~ALLOC_DATA_IN_URB;
@@ -432,12 +495,14 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
                        return SCSI_MLQUEUE_DEVICE_BUSY;
                }
                cmdinfo->state &= ~SUBMIT_DATA_IN_URB;
+               cmdinfo->state |= DATA_IN_URB_INFLIGHT;
+               usb_anchor_urb(cmdinfo->data_in_urb, &devinfo->data_urbs);
        }
 
        if (cmdinfo->state & ALLOC_DATA_OUT_URB) {
                cmdinfo->data_out_urb = uas_alloc_data_urb(devinfo, gfp,
-                                       devinfo->data_out_pipe, cmnd,
-                                       DMA_TO_DEVICE);
+                                       devinfo->data_out_pipe, cmdinfo->stream,
+                                       cmnd, DMA_TO_DEVICE);
                if (!cmdinfo->data_out_urb)
                        return SCSI_MLQUEUE_DEVICE_BUSY;
                cmdinfo->state &= ~ALLOC_DATA_OUT_URB;
@@ -450,6 +515,8 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
                        return SCSI_MLQUEUE_DEVICE_BUSY;
                }
                cmdinfo->state &= ~SUBMIT_DATA_OUT_URB;
+               cmdinfo->state |= DATA_OUT_URB_INFLIGHT;
+               usb_anchor_urb(cmdinfo->data_out_urb, &devinfo->data_urbs);
        }
 
        if (cmdinfo->state & ALLOC_CMD_URB) {
@@ -467,6 +534,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
                        return SCSI_MLQUEUE_DEVICE_BUSY;
                }
                cmdinfo->state &= ~SUBMIT_CMD_URB;
+               cmdinfo->state |= COMMAND_INFLIGHT;
        }
 
        return 0;
@@ -494,8 +562,9 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
 
        cmnd->scsi_done = done;
 
-       cmdinfo->state = ALLOC_STATUS_URB | SUBMIT_STATUS_URB |
+       cmdinfo->state = SUBMIT_STATUS_URB |
                        ALLOC_CMD_URB | SUBMIT_CMD_URB;
+       cmdinfo->aborted = 0;
 
        switch (cmnd->sc_data_direction) {
        case DMA_FROM_DEVICE:
@@ -510,8 +579,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
        }
 
        if (!devinfo->use_streams) {
-               cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB |
-                               ALLOC_STATUS_URB | SUBMIT_STATUS_URB);
+               cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB);
                cmdinfo->stream = 0;
        }
 
@@ -519,7 +587,6 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
        if (err) {
                /* If we did nothing, give up now */
                if (cmdinfo->state & SUBMIT_STATUS_URB) {
-                       usb_free_urb(cmdinfo->status_urb);
                        return SCSI_MLQUEUE_DEVICE_BUSY;
                }
                spin_lock(&uas_work_lock);
@@ -533,36 +600,66 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
 
 static DEF_SCSI_QCMD(uas_queuecommand)
 
-static int uas_eh_abort_handler(struct scsi_cmnd *cmnd)
+static int uas_eh_task_mgmt(struct scsi_cmnd *cmnd,
+                           const char *fname, u8 function)
 {
-       struct scsi_device *sdev = cmnd->device;
-       sdev_printk(KERN_INFO, sdev, "%s tag %d\n", __func__,
-                                                       cmnd->request->tag);
-
-/* XXX: Send ABORT TASK Task Management command */
-       return FAILED;
+       struct Scsi_Host *shost = cmnd->device->host;
+       struct uas_dev_info *devinfo = (void *)shost->hostdata[0];
+       u16 tag = 9999; /* FIXME */
+
+       memset(&devinfo->response, 0, sizeof(devinfo->response));
+       if (uas_submit_sense_urb(shost, GFP_NOIO, tag)) {
+               shost_printk(KERN_INFO, shost,
+                            "%s: %s: submit sense urb failed\n",
+                            __func__, fname);
+               return FAILED;
+       }
+       if (uas_submit_task_urb(cmnd, GFP_NOIO, function, tag)) {
+               shost_printk(KERN_INFO, shost,
+                            "%s: %s: submit task mgmt urb failed\n",
+                            __func__, fname);
+               return FAILED;
+       }
+       if (0 == usb_wait_anchor_empty_timeout(&devinfo->sense_urbs, 3000)) {
+               shost_printk(KERN_INFO, shost,
+                            "%s: %s timed out\n", __func__, fname);
+               return FAILED;
+       }
+       if (be16_to_cpu(devinfo->response.tag) != tag) {
+               shost_printk(KERN_INFO, shost,
+                            "%s: %s failed (wrong tag %d/%d)\n", __func__,
+                            fname, be16_to_cpu(devinfo->response.tag), tag);
+               return FAILED;
+       }
+       if (devinfo->response.response_code != RC_TMF_COMPLETE) {
+               shost_printk(KERN_INFO, shost,
+                            "%s: %s failed (rc 0x%x)\n", __func__,
+                            fname, devinfo->response.response_code);
+               return FAILED;
+       }
+       return SUCCESS;
 }
 
-static int uas_eh_device_reset_handler(struct scsi_cmnd *cmnd)
+static int uas_eh_abort_handler(struct scsi_cmnd *cmnd)
 {
-       struct scsi_device *sdev = cmnd->device;
-       sdev_printk(KERN_INFO, sdev, "%s tag %d\n", __func__,
-                                                       cmnd->request->tag);
+       struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
+       int ret;
 
-/* XXX: Send LOGICAL UNIT RESET Task Management command */
-       return FAILED;
+       uas_log_cmd_state(cmnd, __func__);
+       cmdinfo->aborted = 1;
+       ret = uas_eh_task_mgmt(cmnd, "ABORT TASK", TMF_ABORT_TASK);
+       if (cmdinfo->state & DATA_IN_URB_INFLIGHT)
+               usb_kill_urb(cmdinfo->data_in_urb);
+       if (cmdinfo->state & DATA_OUT_URB_INFLIGHT)
+               usb_kill_urb(cmdinfo->data_out_urb);
+       return ret;
 }
 
-static int uas_eh_target_reset_handler(struct scsi_cmnd *cmnd)
+static int uas_eh_device_reset_handler(struct scsi_cmnd *cmnd)
 {
-       struct scsi_device *sdev = cmnd->device;
-       sdev_printk(KERN_INFO, sdev, "%s tag %d\n", __func__,
-                                                       cmnd->request->tag);
-
-/* XXX: Can we reset just the one USB interface?
- * Would calling usb_set_interface() have the right effect?
- */
-       return FAILED;
+       sdev_printk(KERN_INFO, cmnd->device, "%s\n", __func__);
+       return uas_eh_task_mgmt(cmnd, "LOGICAL UNIT RESET",
+                               TMF_LOGICAL_UNIT_RESET);
 }
 
 static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd)
@@ -570,14 +667,21 @@ static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd)
        struct scsi_device *sdev = cmnd->device;
        struct uas_dev_info *devinfo = sdev->hostdata;
        struct usb_device *udev = devinfo->udev;
+       int err;
 
-       sdev_printk(KERN_INFO, sdev, "%s tag %d\n", __func__,
-                                                       cmnd->request->tag);
+       devinfo->resetting = 1;
+       usb_kill_anchored_urbs(&devinfo->sense_urbs);
+       usb_kill_anchored_urbs(&devinfo->data_urbs);
+       err = usb_reset_device(udev);
+       devinfo->resetting = 0;
 
-       if (usb_reset_device(udev))
-               return SUCCESS;
+       if (err) {
+               shost_printk(KERN_INFO, sdev->host, "%s FAILED\n", __func__);
+               return FAILED;
+       }
 
-       return FAILED;
+       shost_printk(KERN_INFO, sdev->host, "%s success\n", __func__);
+       return SUCCESS;
 }
 
 static int uas_slave_alloc(struct scsi_device *sdev)
@@ -602,7 +706,6 @@ static struct scsi_host_template uas_host_template = {
        .slave_configure = uas_slave_configure,
        .eh_abort_handler = uas_eh_abort_handler,
        .eh_device_reset_handler = uas_eh_device_reset_handler,
-       .eh_target_reset_handler = uas_eh_target_reset_handler,
        .eh_bus_reset_handler = uas_eh_bus_reset_handler,
        .can_queue = 65536,     /* Is there a limit on the _host_ ? */
        .this_id = -1,
@@ -722,29 +825,6 @@ static void uas_configure_endpoints(struct uas_dev_info *devinfo)
        }
 }
 
-static int uas_alloc_status_urb(struct uas_dev_info *devinfo,
-               struct Scsi_Host *shost)
-{
-       if (devinfo->use_streams) {
-               devinfo->status_urb = NULL;
-               return 0;
-       }
-
-       devinfo->status_urb = uas_alloc_sense_urb(devinfo, GFP_KERNEL,
-                       shost, 0);
-       if (!devinfo->status_urb)
-               goto err_s_urb;
-
-       if (usb_submit_urb(devinfo->status_urb, GFP_KERNEL))
-               goto err_submit_urb;
-
-       return 0;
-err_submit_urb:
-       usb_free_urb(devinfo->status_urb);
-err_s_urb:
-       return -ENOMEM;
-}
-
 static void uas_free_streams(struct uas_dev_info *devinfo)
 {
        struct usb_device *udev = devinfo->udev;
@@ -787,6 +867,9 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
 
        devinfo->intf = intf;
        devinfo->udev = udev;
+       devinfo->resetting = 0;
+       init_usb_anchor(&devinfo->sense_urbs);
+       init_usb_anchor(&devinfo->data_urbs);
        uas_configure_endpoints(devinfo);
 
        result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 2);
@@ -799,17 +882,10 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
 
        shost->hostdata[0] = (unsigned long)devinfo;
 
-       result = uas_alloc_status_urb(devinfo, shost);
-       if (result)
-               goto err_alloc_status;
-
        scsi_scan_host(shost);
        usb_set_intfdata(intf, shost);
        return result;
 
-err_alloc_status:
-       scsi_remove_host(shost);
-       shost = NULL;
 deconfig_eps:
        uas_free_streams(devinfo);
  free:
@@ -837,8 +913,8 @@ static void uas_disconnect(struct usb_interface *intf)
        struct uas_dev_info *devinfo = (void *)shost->hostdata[0];
 
        scsi_remove_host(shost);
-       usb_kill_urb(devinfo->status_urb);
-       usb_free_urb(devinfo->status_urb);
+       usb_kill_anchored_urbs(&devinfo->sense_urbs);
+       usb_kill_anchored_urbs(&devinfo->data_urbs);
        uas_free_streams(devinfo);
        kfree(devinfo);
 }
index 5db93821f9c7d473d1d4fe87f9e3fc5d988044bb..6955045199b09c006bce030bf21b8b0bdb011d15 100644 (file)
@@ -78,6 +78,9 @@ struct ieee1394_device_id {
  *     of a given interface; other interfaces may support other classes.
  * @bInterfaceSubClass: Subclass of interface; associated with bInterfaceClass.
  * @bInterfaceProtocol: Protocol of interface; associated with bInterfaceClass.
+ * @bInterfaceNumber: Number of interface; composite devices may use
+ *     fixed interface numbers to differentiate between vendor-specific
+ *     interfaces.
  * @driver_info: Holds information used by the driver.  Usually it holds
  *     a pointer to a descriptor understood by the driver, or perhaps
  *     device flags.
@@ -115,8 +118,12 @@ struct usb_device_id {
        __u8            bInterfaceSubClass;
        __u8            bInterfaceProtocol;
 
+       /* Used for vendor-specific interface matches */
+       __u8            bInterfaceNumber;
+
        /* not matched against */
-       kernel_ulong_t  driver_info;
+       kernel_ulong_t  driver_info
+               __attribute__((aligned(sizeof(kernel_ulong_t))));
 };
 
 /* Some useful macros to use to create struct usb_device_id */
@@ -130,6 +137,7 @@ struct usb_device_id {
 #define USB_DEVICE_ID_MATCH_INT_CLASS          0x0080
 #define USB_DEVICE_ID_MATCH_INT_SUBCLASS       0x0100
 #define USB_DEVICE_ID_MATCH_INT_PROTOCOL       0x0200
+#define USB_DEVICE_ID_MATCH_INT_NUMBER         0x0400
 
 #define HID_ANY_ID                             (~0)
 #define HID_BUS_ANY                            0xffff
index dea39dc551d44c3602f1b7c33800dfba57a0a5b3..f717fbdaee8e1726ef6e1ce08ce9175b4765b205 100644 (file)
@@ -776,6 +776,22 @@ static inline int usb_make_path(struct usb_device *dev, char *buf, size_t size)
        .idProduct = (prod), \
        .bInterfaceProtocol = (pr)
 
+/**
+ * USB_DEVICE_INTERFACE_NUMBER - describe a usb device with a specific interface number
+ * @vend: the 16 bit USB Vendor ID
+ * @prod: the 16 bit USB Product ID
+ * @num: bInterfaceNumber value
+ *
+ * This macro is used to create a struct usb_device_id that matches a
+ * specific interface number of devices.
+ */
+#define USB_DEVICE_INTERFACE_NUMBER(vend, prod, num) \
+       .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
+                      USB_DEVICE_ID_MATCH_INT_NUMBER, \
+       .idVendor = (vend), \
+       .idProduct = (prod), \
+       .bInterfaceNumber = (num)
+
 /**
  * USB_DEVICE_INFO - macro used to describe a class of usb devices
  * @cl: bDeviceClass value
index 7cc95ee3606bcc415978f316f5c1f0d94c2ca0bb..de4b9ed5d5ddf42491b5976b328075b234947dbc 100644 (file)
@@ -111,7 +111,13 @@ struct ehci_regs {
        /* ASYNCLISTADDR: offset 0x18 */
        u32             async_next;     /* address of next async queue head */
 
-       u32             reserved[9];
+       u32             reserved1[2];
+
+       /* TXFILLTUNING: offset 0x24 */
+       u32             txfill_tuning;  /* TX FIFO Tuning register */
+#define TXFIFO_DEFAULT (8<<16)         /* FIFO burst threshold 8 */
+
+       u32             reserved2[6];
 
        /* CONFIGFLAG: offset 0x40 */
        u32             configured_flag;
@@ -155,26 +161,34 @@ struct ehci_regs {
 #define PORT_CSC       (1<<1)          /* connect status change */
 #define PORT_CONNECT   (1<<0)          /* device connected */
 #define PORT_RWC_BITS   (PORT_CSC | PORT_PEC | PORT_OCC)
-};
 
-#define USBMODE                0x68            /* USB Device mode */
+       u32             reserved3[9];
+
+       /* USBMODE: offset 0x68 */
+       u32             usbmode;        /* USB Device mode */
 #define USBMODE_SDIS   (1<<3)          /* Stream disable */
 #define USBMODE_BE     (1<<2)          /* BE/LE endianness select */
 #define USBMODE_CM_HC  (3<<0)          /* host controller mode */
 #define USBMODE_CM_IDLE        (0<<0)          /* idle state */
 
+       u32             reserved4[7];
+
 /* Moorestown has some non-standard registers, partially due to the fact that
  * its EHCI controller has both TT and LPM support. HOSTPCx are extensions to
  * PORTSCx
  */
-#define HOSTPC0                0x84            /* HOSTPC extension */
+       /* HOSTPC: offset 0x84 */
+       u32             hostpc[0];      /* HOSTPC extension */
 #define HOSTPC_PHCD    (1<<22)         /* Phy clock disable */
 #define HOSTPC_PSPD    (3<<25)         /* Port speed detection */
-#define USBMODE_EX     0xc8            /* USB Device mode extension */
+
+       u32             reserved5[17];
+
+       /* USBMODE_EX: offset 0xc8 */
+       u32             usbmode_ex;     /* USB Device mode extension */
 #define USBMODE_EX_VBPS        (1<<5)          /* VBus Power Select On */
 #define USBMODE_EX_HC  (3<<0)          /* host controller mode */
-#define TXFILLTUNING   0x24            /* TX FIFO Tuning register */
-#define TXFIFO_DEFAULT (8<<16)         /* FIFO burst threshold 8 */
+};
 
 /* Appendix C, Debug port ... intended for use with special "debug devices"
  * that can help if there's no serial console.  (nonstandard enumeration.)
index 49b3ac29726adf3040d47384b51948401ac44887..c5fdb148fc02ccea72ca2b911caa0ab0f7f4be88 100644 (file)
@@ -93,6 +93,12 @@ struct usb_hcd {
         */
        const struct hc_driver  *driver;        /* hw-specific hooks */
 
+       /*
+        * OTG and some Host controllers need software interaction with phys;
+        * other external phys should be software-transparent
+        */
+       struct usb_phy  *phy;
+
        /* Flags that need to be manipulated atomically because they can
         * change while the host controller is running.  Always use
         * set_bit() or clear_bit() to change their values.
index 547e59cc00eadfb4a9992f5238fc2b42e7646314..c5d36c65c33bfe7e77f6a984a66f7a06e1683f84 100644 (file)
@@ -132,6 +132,14 @@ struct renesas_usbhs_driver_param {
         * option:
         *
         * dma id for dmaengine
+        * The data transfer direction on D0FIFO/D1FIFO should be
+        * fixed for keeping consistency.
+        * So, the platform id settings will be..
+        *      .d0_tx_id = xx_TX,
+        *      .d1_rx_id = xx_RX,
+        * or
+        *      .d1_tx_id = xx_TX,
+        *      .d0_rx_id = xx_RX,
         */
        int d0_tx_id;
        int d0_rx_id;
index 9a988e4136942442b4847f787e22360f29aca409..5499ab5c94bd486cf96d198ac310d29d2ab7e393 100644 (file)
@@ -20,6 +20,28 @@ enum {
        IU_ID_WRITE_READY       = 0x07,
 };
 
+enum {
+       TMF_ABORT_TASK          = 0x01,
+       TMF_ABORT_TASK_SET      = 0x02,
+       TMF_CLEAR_TASK_SET      = 0x04,
+       TMF_LOGICAL_UNIT_RESET  = 0x08,
+       TMF_I_T_NEXUS_RESET     = 0x10,
+       TMF_CLEAR_ACA           = 0x40,
+       TMF_QUERY_TASK          = 0x80,
+       TMF_QUERY_TASK_SET      = 0x81,
+       TMF_QUERY_ASYNC_EVENT   = 0x82,
+};
+
+enum {
+       RC_TMF_COMPLETE         = 0x00,
+       RC_INVALID_INFO_UNIT    = 0x02,
+       RC_TMF_NOT_SUPPORTED    = 0x04,
+       RC_TMF_FAILED           = 0x05,
+       RC_TMF_SUCCEEDED        = 0x08,
+       RC_INCORRECT_LUN        = 0x09,
+       RC_OVERLAPPED_TAG       = 0x0a,
+};
+
 struct command_iu {
        __u8 iu_id;
        __u8 rsvd1;
@@ -32,6 +54,16 @@ struct command_iu {
        __u8 cdb[16];   /* XXX: Overflow-checking tools may misunderstand */
 };
 
+struct task_mgmt_iu {
+       __u8 iu_id;
+       __u8 rsvd1;
+       __be16 tag;
+       __u8 function;
+       __u8 rsvd2;
+       __be16 task_tag;
+       struct scsi_lun lun;
+};
+
 /*
  * Also used for the Read Ready and Write Ready IUs since they have the
  * same first four bytes
@@ -47,6 +79,14 @@ struct sense_iu {
        __u8 sense[SCSI_SENSE_BUFFERSIZE];
 };
 
+struct response_ui {
+       __u8 iu_id;
+       __u8 rsvd1;
+       __be16 tag;
+       __be16 add_response_info;
+       __u8 response_code;
+};
+
 struct usb_pipe_usage_descriptor {
        __u8  bLength;
        __u8  bDescriptorType;
index 5759751a1f61212ec02e16de995a8a0482b37c11..7ed6864ef65b7372a0e671280fe80a35794606ae 100644 (file)
@@ -156,7 +156,7 @@ static void device_id_check(const char *modname, const char *device_id,
 }
 
 /* USB is special because the bcdDevice can be matched against a numeric range */
-/* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipN" */
+/* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipNinN" */
 static void do_usb_entry(struct usb_device_id *id,
                         unsigned int bcdDevice_initial, int bcdDevice_initial_digits,
                         unsigned char range_lo, unsigned char range_hi,
@@ -210,6 +210,9 @@ static void do_usb_entry(struct usb_device_id *id,
        ADD(alias, "ip",
            id->match_flags&USB_DEVICE_ID_MATCH_INT_PROTOCOL,
            id->bInterfaceProtocol);
+       ADD(alias, "in",
+           id->match_flags&USB_DEVICE_ID_MATCH_INT_NUMBER,
+           id->bInterfaceNumber);
 
        add_wildcard(alias);
        buf_printf(&mod->dev_table_buf,
index 82d7c590c02601c17477fff14ce7643d8af69a22..b0adb2710c0220660b0e76bc7a1d6cab73916c34 100644 (file)
@@ -425,7 +425,7 @@ int main (int argc, char **argv)
        /* for easy use when hotplugging */
        device = getenv ("DEVICE");
 
-       while ((c = getopt (argc, argv, "D:aA:c:g:hns:t:v:")) != EOF)
+       while ((c = getopt (argc, argv, "D:aA:c:g:hlns:t:v:")) != EOF)
        switch (c) {
        case 'D':       /* device, if only one */
                device = optarg;
@@ -468,10 +468,21 @@ int main (int argc, char **argv)
        case 'h':
        default:
 usage:
-               fprintf (stderr, "usage: %s [-n] [-D dev | -a | -A usbfs-dir]\n"
-                       "\t[-c iterations]  [-t testnum]\n"
-                       "\t[-s packetsize] [-g sglen] [-v vary]\n",
-                       argv [0]);
+               fprintf (stderr,
+                       "usage: %s [options]\n"
+                       "Options:\n"
+                       "\t-D dev               only test specific device\n"
+                       "\t-A usbfs-dir\n"
+                       "\t-a           test all recognized devices\n"
+                       "\t-l           loop forever(for stress test)\n"
+                       "\t-t testnum   only run specified case\n"
+                       "\t-n           no test running, show devices to be tested\n"
+                       "Case arguments:\n"
+                       "\t-c iterations        default 1000\n"
+                       "\t-s packetsize        default 512\n"
+                       "\t-g sglen     default 32\n"
+                       "\t-v vary              default 512\n",
+                       argv[0]);
                return 1;
        }
        if (optind != argc)