]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 13 Jul 2009 17:23:03 +0000 (10:23 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 13 Jul 2009 17:23:03 +0000 (10:23 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (48 commits)
  USB: otg: fix module reinsert issue
  USB: handle zero-length usbfs submissions correctly
  USB: EHCI: report actual_length for iso transfers
  USB: option: remove unnecessary and erroneous code
  USB: cypress_m8: remove invalid Clear-Halt
  USB: musb_host: undo incorrect change in musb_advance_schedule()
  USB: fix LANGID=0 regression
  USB: serial: sierra driver id_table additions
  USB serial: Add ID for Turtelizer, an FT2232L-based JTAG/RS-232 adapter.
  USB: fix race leading to a write after kfree in usbfs
  USB: Sierra: fix oops upon device close
  USB: option.c: add A-Link 3GU device id
  USB: Serial: Add support for Arkham Technology adapters
  USB: Fix option_ms regression in 2.6.31-rc2
  USB: gadget audio: select SND_PCM
  USB: ftdi: support NDI devices
  Revert USB: usbfs: deprecate and hide option for !embedded
  USB: usb.h: fix kernel-doc notation
  USB: RNDIS gadget, fix issues talking from PXA
  USB: serial: FTDI with product code FB80 and vendor id 0403
  ...

48 files changed:
drivers/usb/class/cdc-acm.c
drivers/usb/class/usbtmc.c
drivers/usb/core/Kconfig
drivers/usb/core/devices.c
drivers/usb/core/devio.c
drivers/usb/core/hcd.h
drivers/usb/core/hub.c
drivers/usb/core/hub.h
drivers/usb/core/message.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/audio.c
drivers/usb/gadget/ether.c
drivers/usb/gadget/pxa25x_udc.c
drivers/usb/gadget/rndis.c
drivers/usb/host/Kconfig
drivers/usb/host/ehci-au1xxx.c
drivers/usb/host/ehci-fsl.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-ixp4xx.c
drivers/usb/host/ehci-orion.c
drivers/usb/host/ehci-pci.c
drivers/usb/host/ehci-ppc-of.c
drivers/usb/host/ehci-ps3.c
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/ehci.h
drivers/usb/host/fhci-sched.c
drivers/usb/host/isp1760-if.c
drivers/usb/musb/davinci.c
drivers/usb/musb/musb_host.c
drivers/usb/otg/Kconfig
drivers/usb/otg/Makefile
drivers/usb/otg/langwell_otg.c [deleted file]
drivers/usb/otg/nop-usb-xceiv.c
drivers/usb/serial/console.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/cypress_m8.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.h
drivers/usb/serial/option.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/pl2303.h
drivers/usb/serial/sierra.c
drivers/usb/serial/ti_usb_3410_5052.c
drivers/usb/serial/usb-serial.c
drivers/usb/storage/option_ms.c
include/linux/usb.h
include/linux/usb/langwell_otg.h [deleted file]

index 3f1045993474ce9ea9474920b870d6d75f6a1a15..5b15d9d8896b9b0efe08a7d44303486e6f290811 100644 (file)
@@ -387,6 +387,7 @@ static void acm_rx_tasklet(unsigned long _acm)
        struct acm_ru *rcv;
        unsigned long flags;
        unsigned char throttled;
+       struct usb_host_endpoint *ep;
 
        dbg("Entering acm_rx_tasklet");
 
@@ -462,11 +463,20 @@ urbs:
 
                rcv->buffer = buf;
 
-               usb_fill_bulk_urb(rcv->urb, acm->dev,
-                                 acm->rx_endpoint,
-                                 buf->base,
-                                 acm->readsize,
-                                 acm_read_bulk, rcv);
+               ep = (usb_pipein(acm->rx_endpoint) ? acm->dev->ep_in : acm->dev->ep_out)
+                               [usb_pipeendpoint(acm->rx_endpoint)];
+               if (usb_endpoint_xfer_int(&ep->desc))
+                       usb_fill_int_urb(rcv->urb, acm->dev,
+                                        acm->rx_endpoint,
+                                        buf->base,
+                                        acm->readsize,
+                                        acm_read_bulk, rcv, ep->desc.bInterval);
+               else
+                       usb_fill_bulk_urb(rcv->urb, acm->dev,
+                                         acm->rx_endpoint,
+                                         buf->base,
+                                         acm->readsize,
+                                         acm_read_bulk, rcv);
                rcv->urb->transfer_dma = buf->dma;
                rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
@@ -1227,9 +1237,14 @@ made_compressed_probe:
                        goto alloc_fail7;
                }
 
-               usb_fill_bulk_urb(snd->urb, usb_dev,
-                       usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
-                       NULL, acm->writesize, acm_write_bulk, snd);
+               if (usb_endpoint_xfer_int(epwrite))
+                       usb_fill_int_urb(snd->urb, usb_dev,
+                               usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
+                               NULL, acm->writesize, acm_write_bulk, snd, epwrite->bInterval);
+               else
+                       usb_fill_bulk_urb(snd->urb, usb_dev,
+                               usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
+                               NULL, acm->writesize, acm_write_bulk, snd);
                snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
                snd->instance = acm;
        }
index 3703789d0d2af8a7459138adb5903c548e704425..b09a527f73411499e2ab712c0f4d1b6f7d2c1946 100644 (file)
@@ -751,7 +751,7 @@ static int get_capabilities(struct usbtmc_device_data *data)
 {
        struct device *dev = &data->usb_dev->dev;
        char *buffer;
-       int rv;
+       int rv = 0;
 
        buffer = kmalloc(0x18, GFP_KERNEL);
        if (!buffer)
@@ -763,7 +763,7 @@ static int get_capabilities(struct usbtmc_device_data *data)
                             0, 0, buffer, 0x18, USBTMC_TIMEOUT);
        if (rv < 0) {
                dev_err(dev, "usb_control_msg returned %d\n", rv);
-               return rv;
+               goto err_out;
        }
 
        dev_dbg(dev, "GET_CAPABILITIES returned %x\n", buffer[0]);
@@ -773,7 +773,8 @@ static int get_capabilities(struct usbtmc_device_data *data)
        dev_dbg(dev, "USB488 device capabilities are %x\n", buffer[15]);
        if (buffer[0] != USBTMC_STATUS_SUCCESS) {
                dev_err(dev, "GET_CAPABILITIES returned %x\n", buffer[0]);
-               return -EPERM;
+               rv = -EPERM;
+               goto err_out;
        }
 
        data->capabilities.interface_capabilities = buffer[4];
@@ -781,8 +782,9 @@ static int get_capabilities(struct usbtmc_device_data *data)
        data->capabilities.usb488_interface_capabilities = buffer[14];
        data->capabilities.usb488_device_capabilities = buffer[15];
 
+err_out:
        kfree(buffer);
-       return 0;
+       return rv;
 }
 
 #define capability_attribute(name)                                     \
index 69280c35b5cbc6d93cc50c99d7f4a7f747c1fc99..ad925946f869ea1ed435851b1efebd0cf7d200b4 100644 (file)
@@ -28,7 +28,7 @@ comment "Miscellaneous USB options"
        depends on USB
 
 config USB_DEVICEFS
-       bool "USB device filesystem (DEPRECATED)" if EMBEDDED
+       bool "USB device filesystem (DEPRECATED)"
        depends on USB
        ---help---
          If you say Y here (and to "/proc file system support" in the "File
index 73c108d117b4b3da95587c5366a4498a695a8e74..96f11715cd269b4cb8594c12c4c027ae50350af8 100644 (file)
@@ -136,17 +136,19 @@ static const struct class_info clas_info[] =
        {USB_CLASS_AUDIO,               "audio"},
        {USB_CLASS_COMM,                "comm."},
        {USB_CLASS_HID,                 "HID"},
-       {USB_CLASS_HUB,                 "hub"},
        {USB_CLASS_PHYSICAL,            "PID"},
+       {USB_CLASS_STILL_IMAGE,         "still"},
        {USB_CLASS_PRINTER,             "print"},
        {USB_CLASS_MASS_STORAGE,        "stor."},
+       {USB_CLASS_HUB,                 "hub"},
        {USB_CLASS_CDC_DATA,            "data"},
-       {USB_CLASS_APP_SPEC,            "app."},
-       {USB_CLASS_VENDOR_SPEC,         "vend."},
-       {USB_CLASS_STILL_IMAGE,         "still"},
        {USB_CLASS_CSCID,               "scard"},
        {USB_CLASS_CONTENT_SEC,         "c-sec"},
        {USB_CLASS_VIDEO,               "video"},
+       {USB_CLASS_WIRELESS_CONTROLLER, "wlcon"},
+       {USB_CLASS_MISC,                "misc"},
+       {USB_CLASS_APP_SPEC,            "app."},
+       {USB_CLASS_VENDOR_SPEC,         "vend."},
        {-1,                            "unk."}         /* leave as last */
 };
 
index 308609039c73e1bbf1252adee9f2e276cc73c852..38b8bce782d6d12cbcb01a8b83452948e48570f7 100644 (file)
@@ -325,21 +325,34 @@ static void async_completed(struct urb *urb)
        struct async *as = urb->context;
        struct dev_state *ps = as->ps;
        struct siginfo sinfo;
+       struct pid *pid = NULL;
+       uid_t uid = 0;
+       uid_t euid = 0;
+       u32 secid = 0;
+       int signr;
 
        spin_lock(&ps->lock);
        list_move_tail(&as->asynclist, &ps->async_completed);
-       spin_unlock(&ps->lock);
        as->status = urb->status;
-       if (as->signr) {
+       signr = as->signr;
+       if (signr) {
                sinfo.si_signo = as->signr;
                sinfo.si_errno = as->status;
                sinfo.si_code = SI_ASYNCIO;
                sinfo.si_addr = as->userurb;
-               kill_pid_info_as_uid(as->signr, &sinfo, as->pid, as->uid,
-                                     as->euid, as->secid);
+               pid = as->pid;
+               uid = as->uid;
+               euid = as->euid;
+               secid = as->secid;
        }
        snoop(&urb->dev->dev, "urb complete\n");
        snoop_urb(urb, as->userurb);
+       spin_unlock(&ps->lock);
+
+       if (signr)
+               kill_pid_info_as_uid(sinfo.si_signo, &sinfo, pid, uid,
+                                     euid, secid);
+
        wake_up(&ps->wait);
 }
 
@@ -982,7 +995,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
                                USBDEVFS_URB_ZERO_PACKET |
                                USBDEVFS_URB_NO_INTERRUPT))
                return -EINVAL;
-       if (!uurb->buffer)
+       if (uurb->buffer_length > 0 && !uurb->buffer)
                return -EINVAL;
        if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL &&
            (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) {
@@ -1038,11 +1051,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
                        is_in = 0;
                        uurb->endpoint &= ~USB_DIR_IN;
                }
-               if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
-                               uurb->buffer, uurb->buffer_length)) {
-                       kfree(dr);
-                       return -EFAULT;
-               }
                snoop(&ps->dev->dev, "control urb: bRequest=%02x "
                        "bRrequestType=%02x wValue=%04x "
                        "wIndex=%04x wLength=%04x\n",
@@ -1062,9 +1070,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
                uurb->number_of_packets = 0;
                if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
                        return -EINVAL;
-               if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
-                               uurb->buffer, uurb->buffer_length))
-                       return -EFAULT;
                snoop(&ps->dev->dev, "bulk urb\n");
                break;
 
@@ -1106,28 +1111,35 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
                        return -EINVAL;
                if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
                        return -EINVAL;
-               if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
-                               uurb->buffer, uurb->buffer_length))
-                       return -EFAULT;
                snoop(&ps->dev->dev, "interrupt urb\n");
                break;
 
        default:
                return -EINVAL;
        }
-       as = alloc_async(uurb->number_of_packets);
-       if (!as) {
+       if (uurb->buffer_length > 0 &&
+                       !access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
+                               uurb->buffer, uurb->buffer_length)) {
                kfree(isopkt);
                kfree(dr);
-               return -ENOMEM;
+               return -EFAULT;
        }
-       as->urb->transfer_buffer = kmalloc(uurb->buffer_length, GFP_KERNEL);
-       if (!as->urb->transfer_buffer) {
+       as = alloc_async(uurb->number_of_packets);
+       if (!as) {
                kfree(isopkt);
                kfree(dr);
-               free_async(as);
                return -ENOMEM;
        }
+       if (uurb->buffer_length > 0) {
+               as->urb->transfer_buffer = kmalloc(uurb->buffer_length,
+                               GFP_KERNEL);
+               if (!as->urb->transfer_buffer) {
+                       kfree(isopkt);
+                       kfree(dr);
+                       free_async(as);
+                       return -ENOMEM;
+               }
+       }
        as->urb->dev = ps->dev;
        as->urb->pipe = (uurb->type << 30) |
                        __create_pipe(ps->dev, uurb->endpoint & 0xf) |
@@ -1169,7 +1181,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
        kfree(isopkt);
        as->ps = ps;
        as->userurb = arg;
-       if (uurb->endpoint & USB_DIR_IN)
+       if (is_in && uurb->buffer_length > 0)
                as->userbuffer = uurb->buffer;
        else
                as->userbuffer = NULL;
@@ -1179,9 +1191,9 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
        as->uid = cred->uid;
        as->euid = cred->euid;
        security_task_getsecid(current, &as->secid);
-       if (!is_in) {
+       if (!is_in && uurb->buffer_length > 0) {
                if (copy_from_user(as->urb->transfer_buffer, uurb->buffer,
-                               as->urb->transfer_buffer_length)) {
+                               uurb->buffer_length)) {
                        free_async(as);
                        return -EFAULT;
                }
@@ -1231,22 +1243,22 @@ static int processcompl(struct async *as, void __user * __user *arg)
        if (as->userbuffer)
                if (copy_to_user(as->userbuffer, urb->transfer_buffer,
                                 urb->transfer_buffer_length))
-                       return -EFAULT;
+                       goto err_out;
        if (put_user(as->status, &userurb->status))
-               return -EFAULT;
+               goto err_out;
        if (put_user(urb->actual_length, &userurb->actual_length))
-               return -EFAULT;
+               goto err_out;
        if (put_user(urb->error_count, &userurb->error_count))
-               return -EFAULT;
+               goto err_out;
 
        if (usb_endpoint_xfer_isoc(&urb->ep->desc)) {
                for (i = 0; i < urb->number_of_packets; i++) {
                        if (put_user(urb->iso_frame_desc[i].actual_length,
                                     &userurb->iso_frame_desc[i].actual_length))
-                               return -EFAULT;
+                               goto err_out;
                        if (put_user(urb->iso_frame_desc[i].status,
                                     &userurb->iso_frame_desc[i].status))
-                               return -EFAULT;
+                               goto err_out;
                }
        }
 
@@ -1255,6 +1267,10 @@ static int processcompl(struct async *as, void __user * __user *arg)
        if (put_user(addr, (void __user * __user *)arg))
                return -EFAULT;
        return 0;
+
+err_out:
+       free_async(as);
+       return -EFAULT;
 }
 
 static struct async *reap_as(struct dev_state *ps)
index d397ecfd5b178d881f97c72e51989bfccbe2a064..ec5c67ea07b745a95b92e8db88349abadc1bbca1 100644 (file)
@@ -227,6 +227,10 @@ struct hc_driver {
                /* has a port been handed over to a companion? */
        int     (*port_handed_over)(struct usb_hcd *, int);
 
+               /* CLEAR_TT_BUFFER completion callback */
+       void    (*clear_tt_buffer_complete)(struct usb_hcd *,
+                               struct usb_host_endpoint *);
+
        /* xHCI specific functions */
                /* Called by usb_alloc_dev to alloc HC device structures */
        int     (*alloc_dev)(struct usb_hcd *, struct usb_device *);
index 2af3b4f0605405dd723b1ccd4f853f7f85dc1848..71f86c60d83c3962cf8b7eabe1d709d2d87b7a76 100644 (file)
@@ -450,10 +450,10 @@ hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt)
  * talking to TTs must queue control transfers (not just bulk and iso), so
  * both can talk to the same hub concurrently.
  */
-static void hub_tt_kevent (struct work_struct *work)
+static void hub_tt_work(struct work_struct *work)
 {
        struct usb_hub          *hub =
-               container_of(work, struct usb_hub, tt.kevent);
+               container_of(work, struct usb_hub, tt.clear_work);
        unsigned long           flags;
        int                     limit = 100;
 
@@ -462,6 +462,7 @@ static void hub_tt_kevent (struct work_struct *work)
                struct list_head        *next;
                struct usb_tt_clear     *clear;
                struct usb_device       *hdev = hub->hdev;
+               const struct hc_driver  *drv;
                int                     status;
 
                next = hub->tt.clear_list.next;
@@ -471,21 +472,25 @@ static void hub_tt_kevent (struct work_struct *work)
                /* drop lock so HCD can concurrently report other TT errors */
                spin_unlock_irqrestore (&hub->tt.lock, flags);
                status = hub_clear_tt_buffer (hdev, clear->devinfo, clear->tt);
-               spin_lock_irqsave (&hub->tt.lock, flags);
-
                if (status)
                        dev_err (&hdev->dev,
                                "clear tt %d (%04x) error %d\n",
                                clear->tt, clear->devinfo, status);
+
+               /* Tell the HCD, even if the operation failed */
+               drv = clear->hcd->driver;
+               if (drv->clear_tt_buffer_complete)
+                       (drv->clear_tt_buffer_complete)(clear->hcd, clear->ep);
+
                kfree(clear);
+               spin_lock_irqsave(&hub->tt.lock, flags);
        }
        spin_unlock_irqrestore (&hub->tt.lock, flags);
 }
 
 /**
- * usb_hub_tt_clear_buffer - clear control/bulk TT state in high speed hub
- * @udev: the device whose split transaction failed
- * @pipe: identifies the endpoint of the failed transaction
+ * usb_hub_clear_tt_buffer - clear control/bulk TT state in high speed hub
+ * @urb: an URB associated with the failed or incomplete split transaction
  *
  * High speed HCDs use this to tell the hub driver that some split control or
  * bulk transaction failed in a way that requires clearing internal state of
@@ -495,8 +500,10 @@ static void hub_tt_kevent (struct work_struct *work)
  * It may not be possible for that hub to handle additional full (or low)
  * speed transactions until that state is fully cleared out.
  */
-void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
+int usb_hub_clear_tt_buffer(struct urb *urb)
 {
+       struct usb_device       *udev = urb->dev;
+       int                     pipe = urb->pipe;
        struct usb_tt           *tt = udev->tt;
        unsigned long           flags;
        struct usb_tt_clear     *clear;
@@ -508,7 +515,7 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
        if ((clear = kmalloc (sizeof *clear, GFP_ATOMIC)) == NULL) {
                dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n");
                /* FIXME recover somehow ... RESET_TT? */
-               return;
+               return -ENOMEM;
        }
 
        /* info that CLEAR_TT_BUFFER needs */
@@ -520,14 +527,19 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
                        : (USB_ENDPOINT_XFER_BULK << 11);
        if (usb_pipein (pipe))
                clear->devinfo |= 1 << 15;
-       
+
+       /* info for completion callback */
+       clear->hcd = bus_to_hcd(udev->bus);
+       clear->ep = urb->ep;
+
        /* tell keventd to clear state for this TT */
        spin_lock_irqsave (&tt->lock, flags);
        list_add_tail (&clear->clear_list, &tt->clear_list);
-       schedule_work (&tt->kevent);
+       schedule_work(&tt->clear_work);
        spin_unlock_irqrestore (&tt->lock, flags);
+       return 0;
 }
-EXPORT_SYMBOL_GPL(usb_hub_tt_clear_buffer);
+EXPORT_SYMBOL_GPL(usb_hub_clear_tt_buffer);
 
 /* If do_delay is false, return the number of milliseconds the caller
  * needs to delay.
@@ -818,7 +830,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type)
        if (hub->has_indicators)
                cancel_delayed_work_sync(&hub->leds);
        if (hub->tt.hub)
-               cancel_work_sync(&hub->tt.kevent);
+               cancel_work_sync(&hub->tt.clear_work);
 }
 
 /* caller has locked the hub device */
@@ -935,7 +947,7 @@ static int hub_configure(struct usb_hub *hub,
 
        spin_lock_init (&hub->tt.lock);
        INIT_LIST_HEAD (&hub->tt.clear_list);
-       INIT_WORK (&hub->tt.kevent, hub_tt_kevent);
+       INIT_WORK(&hub->tt.clear_work, hub_tt_work);
        switch (hdev->descriptor.bDeviceProtocol) {
                case 0:
                        break;
index 889c0f32a40b729431f2dab51d13aead39f5f3e8..de8081f065edda76ae95a415b98c6db86a0d9a57 100644 (file)
@@ -188,16 +188,18 @@ struct usb_tt {
        /* for control/bulk error recovery (CLEAR_TT_BUFFER) */
        spinlock_t              lock;
        struct list_head        clear_list;     /* of usb_tt_clear */
-       struct work_struct                      kevent;
+       struct work_struct      clear_work;
 };
 
 struct usb_tt_clear {
        struct list_head        clear_list;
        unsigned                tt;
        u16                     devinfo;
+       struct usb_hcd          *hcd;
+       struct usb_host_endpoint        *ep;
 };
 
-extern void usb_hub_tt_clear_buffer(struct usb_device *dev, int pipe);
+extern int usb_hub_clear_tt_buffer(struct urb *urb);
 extern void usb_ep0_reinit(struct usb_device *);
 
 #endif /* __LINUX_HUB_H */
index 2bed83caacb1a0c714a2e05af21242bbb504dcad..9720e699f4729737cbdd90946f234e567fc0d874 100644 (file)
@@ -806,6 +806,48 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
        return rc;
 }
 
+static int usb_get_langid(struct usb_device *dev, unsigned char *tbuf)
+{
+       int err;
+
+       if (dev->have_langid)
+               return 0;
+
+       if (dev->string_langid < 0)
+               return -EPIPE;
+
+       err = usb_string_sub(dev, 0, 0, tbuf);
+
+       /* If the string was reported but is malformed, default to english
+        * (0x0409) */
+       if (err == -ENODATA || (err > 0 && err < 4)) {
+               dev->string_langid = 0x0409;
+               dev->have_langid = 1;
+               dev_err(&dev->dev,
+                       "string descriptor 0 malformed (err = %d), "
+                       "defaulting to 0x%04x\n",
+                               err, dev->string_langid);
+               return 0;
+       }
+
+       /* In case of all other errors, we assume the device is not able to
+        * deal with strings at all. Set string_langid to -1 in order to
+        * prevent any string to be retrieved from the device */
+       if (err < 0) {
+               dev_err(&dev->dev, "string descriptor 0 read error: %d\n",
+                                       err);
+               dev->string_langid = -1;
+               return -EPIPE;
+       }
+
+       /* always use the first langid listed */
+       dev->string_langid = tbuf[2] | (tbuf[3] << 8);
+       dev->have_langid = 1;
+       dev_dbg(&dev->dev, "default language 0x%04x\n",
+                               dev->string_langid);
+       return 0;
+}
+
 /**
  * usb_string - returns UTF-8 version of a string descriptor
  * @dev: the device whose string descriptor is being retrieved
@@ -837,24 +879,9 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
        if (!tbuf)
                return -ENOMEM;
 
-       /* get langid for strings if it's not yet known */
-       if (!dev->have_langid) {
-               err = usb_string_sub(dev, 0, 0, tbuf);
-               if (err < 0) {
-                       dev_err(&dev->dev,
-                               "string descriptor 0 read error: %d\n",
-                               err);
-               } else if (err < 4) {
-                       dev_err(&dev->dev, "string descriptor 0 too short\n");
-               } else {
-                       dev->string_langid = tbuf[2] | (tbuf[3] << 8);
-                       /* always use the first langid listed */
-                       dev_dbg(&dev->dev, "default language 0x%04x\n",
-                               dev->string_langid);
-               }
-
-               dev->have_langid = 1;
-       }
+       err = usb_get_langid(dev, tbuf);
+       if (err < 0)
+               goto errout;
 
        err = usb_string_sub(dev, dev->string_langid, index, tbuf);
        if (err < 0)
index 5d1ddf485d1eb6d5d55e12a4eca7536e10a75838..7f8e83a954ac6881861bdc0d2e334ea85944db7a 100644 (file)
@@ -286,6 +286,27 @@ config USB_S3C_HSOTG
        default USB_GADGET
        select USB_GADGET_SELECTED
 
+config USB_GADGET_IMX
+       boolean "Freescale IMX USB Peripheral Controller"
+       depends on ARCH_MX1
+       help
+          Freescale's IMX series include an integrated full speed
+          USB 1.1 device controller.  The controller in the IMX series
+          is register-compatible.
+
+          It has Six fixed-function endpoints, as well as endpoint
+          zero (for control transfers).
+
+          Say "y" to link the driver statically, or "m" to build a
+          dynamically linked module called "imx_udc" and force all
+          gadget drivers to also be dynamically linked.
+
+config USB_IMX
+       tristate
+       depends on USB_GADGET_IMX
+       default USB_GADGET
+       select USB_GADGET_SELECTED
+
 config USB_GADGET_S3C2410
        boolean "S3C2410 USB Device Controller"
        depends on ARCH_S3C2410
@@ -321,27 +342,6 @@ config USB_GADGET_MUSB_HDRC
          This OTG-capable silicon IP is used in dual designs including
          the TI DaVinci, OMAP 243x, OMAP 343x, TUSB 6010, and ADI Blackfin
 
-config USB_GADGET_IMX
-       boolean "Freescale IMX USB Peripheral Controller"
-       depends on ARCH_MX1
-       help
-          Freescale's IMX series include an integrated full speed
-          USB 1.1 device controller.  The controller in the IMX series
-          is register-compatible.
-
-          It has Six fixed-function endpoints, as well as endpoint
-          zero (for control transfers).
-
-          Say "y" to link the driver statically, or "m" to build a
-          dynamically linked module called "imx_udc" and force all
-          gadget drivers to also be dynamically linked.
-
-config USB_IMX
-       tristate
-       depends on USB_GADGET_IMX
-       default USB_GADGET
-       select USB_GADGET_SELECTED
-
 config USB_GADGET_M66592
        boolean "Renesas M66592 USB Peripheral Controller"
        select USB_GADGET_DUALSPEED
@@ -604,6 +604,7 @@ config USB_ZERO_HNPTEST
 config USB_AUDIO
        tristate "Audio Gadget (EXPERIMENTAL)"
        depends on SND
+       select SND_PCM
        help
          Gadget Audio is compatible with USB Audio Class specification 1.0.
          It will include at least one AudioControl interface, zero or more
index 94de7e864614961f322412d2855289041fdda22e..9f80f4e970bd00693cf3140483940eb46843cdef 100644 (file)
@@ -42,9 +42,9 @@
  * Instead:  allocate your own, using normal USB-IF procedures.
  */
 
-/* Thanks to NetChip Technologies for donating this product ID. */
-#define AUDIO_VENDOR_NUM               0x0525  /* NetChip */
-#define AUDIO_PRODUCT_NUM              0xa4a1  /* Linux-USB Audio Gadget */
+/* Thanks to Linux Foundation for donating this product ID. */
+#define AUDIO_VENDOR_NUM               0x1d6b  /* Linux Foundation */
+#define AUDIO_PRODUCT_NUM              0x0101  /* Linux-USB Audio Gadget */
 
 /*-------------------------------------------------------------------------*/
 
index d006dc652e025558e3157691b0f855b43452a6ad..bd102f5052ba67453c3a2dd30a2eefde46ce59ee 100644 (file)
@@ -293,15 +293,16 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
                /* CDC Subset */
                eth_config_driver.label = "CDC Subset/SAFE";
 
-               device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM),
-               device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM),
-               device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
+               device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM);
+               device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM);
+               if (!has_rndis())
+                       device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
        }
 
        if (has_rndis()) {
                /* RNDIS plus ECM-or-Subset */
-               device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM),
-               device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM),
+               device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM);
+               device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM);
                device_desc.bNumConfigurations = 2;
        }
 
index 0ce4e2819847c13fb7548fcf910923495d4588ba..ed21e263f832f05d977aa4c4acd41881dd013002 100644 (file)
@@ -139,7 +139,7 @@ static int is_vbus_present(void)
 {
        struct pxa2xx_udc_mach_info             *mach = the_controller->mach;
 
-       if (mach->gpio_vbus) {
+       if (gpio_is_valid(mach->gpio_vbus)) {
                int value = gpio_get_value(mach->gpio_vbus);
 
                if (mach->gpio_vbus_inverted)
@@ -158,7 +158,7 @@ static void pullup_off(void)
        struct pxa2xx_udc_mach_info             *mach = the_controller->mach;
        int off_level = mach->gpio_pullup_inverted;
 
-       if (mach->gpio_pullup)
+       if (gpio_is_valid(mach->gpio_pullup))
                gpio_set_value(mach->gpio_pullup, off_level);
        else if (mach->udc_command)
                mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
@@ -169,7 +169,7 @@ static void pullup_on(void)
        struct pxa2xx_udc_mach_info             *mach = the_controller->mach;
        int on_level = !mach->gpio_pullup_inverted;
 
-       if (mach->gpio_pullup)
+       if (gpio_is_valid(mach->gpio_pullup))
                gpio_set_value(mach->gpio_pullup, on_level);
        else if (mach->udc_command)
                mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
@@ -1000,7 +1000,7 @@ static int pxa25x_udc_pullup(struct usb_gadget *_gadget, int is_active)
        udc = container_of(_gadget, struct pxa25x_udc, gadget);
 
        /* not all boards support pullup control */
-       if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
+       if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command)
                return -EOPNOTSUPP;
 
        udc->pullup = (is_active != 0);
@@ -1802,11 +1802,13 @@ pxa25x_udc_irq(int irq, void *_dev)
                                        USIR0 |= tmp;
                                        handled = 1;
                                }
+#ifndef        CONFIG_USB_PXA25X_SMALL
                                if (usir1 & tmp) {
                                        handle_ep(&dev->ep[i+8]);
                                        USIR1 |= tmp;
                                        handled = 1;
                                }
+#endif
                        }
                }
 
@@ -2160,7 +2162,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
        dev->dev = &pdev->dev;
        dev->mach = pdev->dev.platform_data;
 
-       if (dev->mach->gpio_vbus) {
+       if (gpio_is_valid(dev->mach->gpio_vbus)) {
                if ((retval = gpio_request(dev->mach->gpio_vbus,
                                "pxa25x_udc GPIO VBUS"))) {
                        dev_dbg(&pdev->dev,
@@ -2173,7 +2175,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
        } else
                vbus_irq = 0;
 
-       if (dev->mach->gpio_pullup) {
+       if (gpio_is_valid(dev->mach->gpio_pullup)) {
                if ((retval = gpio_request(dev->mach->gpio_pullup,
                                "pca25x_udc GPIO PULLUP"))) {
                        dev_dbg(&pdev->dev,
@@ -2256,10 +2258,10 @@ lubbock_fail0:
 #endif
        free_irq(irq, dev);
  err_irq1:
-       if (dev->mach->gpio_pullup)
+       if (gpio_is_valid(dev->mach->gpio_pullup))
                gpio_free(dev->mach->gpio_pullup);
  err_gpio_pullup:
-       if (dev->mach->gpio_vbus)
+       if (gpio_is_valid(dev->mach->gpio_vbus))
                gpio_free(dev->mach->gpio_vbus);
  err_gpio_vbus:
        clk_put(dev->clk);
@@ -2294,11 +2296,11 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev)
                free_irq(LUBBOCK_USB_IRQ, dev);
        }
 #endif
-       if (dev->mach->gpio_vbus) {
+       if (gpio_is_valid(dev->mach->gpio_vbus)) {
                free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev);
                gpio_free(dev->mach->gpio_vbus);
        }
-       if (dev->mach->gpio_pullup)
+       if (gpio_is_valid(dev->mach->gpio_pullup))
                gpio_free(dev->mach->gpio_pullup);
 
        clk_put(dev->clk);
@@ -2329,7 +2331,7 @@ static int pxa25x_udc_suspend(struct platform_device *dev, pm_message_t state)
        struct pxa25x_udc       *udc = platform_get_drvdata(dev);
        unsigned long flags;
 
-       if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
+       if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command)
                WARNING("USB host won't detect disconnect!\n");
        udc->suspended = 1;
 
index 2b4660e08c4db367af0e6c5159855b675616eb9a..ca41b0b5afb352233e86c5ccbd45dace08f4431a 100644 (file)
@@ -442,6 +442,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        case OID_802_3_MAC_OPTIONS:
                pr_debug("%s: OID_802_3_MAC_OPTIONS\n", __func__);
+               *outbuf = cpu_to_le32(0);
+               retval = 0;
                break;
 
        /* ieee802.3 statistics OIDs (table 4-4) */
index 0c03471f0d4197f718bf49aa95f315ba0ada5771..1a920c70b5a150f0a2670f8d170d579c582544ac 100644 (file)
@@ -181,26 +181,27 @@ config USB_OHCI_HCD_PPC_SOC
          Enables support for the USB controller on the MPC52xx or
          STB03xxx processor chip.  If unsure, say Y.
 
-config USB_OHCI_HCD_PPC_OF
-       bool "OHCI support for PPC USB controller on OF platform bus"
-       depends on USB_OHCI_HCD && PPC_OF
-       default y
-       ---help---
-         Enables support for the USB controller PowerPC present on the
-         OpenFirmware platform bus.
-
 config USB_OHCI_HCD_PPC_OF_BE
-       bool "Support big endian HC"
-       depends on USB_OHCI_HCD_PPC_OF
-       default y
+       bool "OHCI support for OF platform bus (big endian)"
+       depends on USB_OHCI_HCD && PPC_OF
        select USB_OHCI_BIG_ENDIAN_DESC
        select USB_OHCI_BIG_ENDIAN_MMIO
+       ---help---
+         Enables support for big-endian USB controllers present on the
+         OpenFirmware platform bus.
 
 config USB_OHCI_HCD_PPC_OF_LE
-       bool "Support little endian HC"
-       depends on USB_OHCI_HCD_PPC_OF
-       default n
+       bool "OHCI support for OF platform bus (little endian)"
+       depends on USB_OHCI_HCD && PPC_OF
        select USB_OHCI_LITTLE_ENDIAN
+       ---help---
+         Enables support for little-endian USB controllers present on the
+         OpenFirmware platform bus.
+
+config USB_OHCI_HCD_PPC_OF
+       bool
+       depends on USB_OHCI_HCD && PPC_OF
+       default USB_OHCI_HCD_PPC_OF_BE || USB_OHCI_HCD_PPC_OF_LE
 
 config USB_OHCI_HCD_PCI
        bool "OHCI support for PCI-bus USB controllers"
index c3a778bd359c9b883bd6e361e78951818fd3a280..59d208d94d4e772d5b1a8cc6f8a009d94132625f 100644 (file)
@@ -113,6 +113,8 @@ static const struct hc_driver ehci_au1xxx_hc_driver = {
        .bus_resume             = ehci_bus_resume,
        .relinquish_port        = ehci_relinquish_port,
        .port_handed_over       = ehci_port_handed_over,
+
+       .clear_tt_buffer_complete       = ehci_clear_tt_buffer_complete,
 };
 
 static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
index bf86809c5120795eac8521b68e2159d2fef37127..991174937db31ed5d829d6e1fdc0b3ea024e47bd 100644 (file)
@@ -325,6 +325,8 @@ static const struct hc_driver ehci_fsl_hc_driver = {
        .bus_resume = ehci_bus_resume,
        .relinquish_port = ehci_relinquish_port,
        .port_handed_over = ehci_port_handed_over,
+
+       .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
 };
 
 static int ehci_fsl_drv_probe(struct platform_device *pdev)
index 2b72473544d31d798034ed5aa92cb555384a8055..7d03549c3339ecc5ebdc5025db1d9f3b6d42f148 100644 (file)
@@ -1003,6 +1003,8 @@ idle_timeout:
                schedule_timeout_uninterruptible(1);
                goto rescan;
        case QH_STATE_IDLE:             /* fully unlinked */
+               if (qh->clearing_tt)
+                       goto idle_timeout;
                if (list_empty (&qh->qtd_list)) {
                        qh_put (qh);
                        break;
@@ -1030,12 +1032,14 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
        struct ehci_hcd         *ehci = hcd_to_ehci(hcd);
        struct ehci_qh          *qh;
        int                     eptype = usb_endpoint_type(&ep->desc);
+       int                     epnum = usb_endpoint_num(&ep->desc);
+       int                     is_out = usb_endpoint_dir_out(&ep->desc);
+       unsigned long           flags;
 
        if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
                return;
 
- rescan:
-       spin_lock_irq(&ehci->lock);
+       spin_lock_irqsave(&ehci->lock, flags);
        qh = ep->hcpriv;
 
        /* For Bulk and Interrupt endpoints we maintain the toggle state
@@ -1044,29 +1048,24 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
         * the toggle bit in the QH.
         */
        if (qh) {
+               usb_settoggle(qh->dev, epnum, is_out, 0);
                if (!list_empty(&qh->qtd_list)) {
                        WARN_ONCE(1, "clear_halt for a busy endpoint\n");
-               } else if (qh->qh_state == QH_STATE_IDLE) {
-                       qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
-               } else {
-                       /* It's not safe to write into the overlay area
-                        * while the QH is active.  Unlink it first and
-                        * wait for the unlink to complete.
+               } else if (qh->qh_state == QH_STATE_LINKED) {
+
+                       /* The toggle value in the QH can't be updated
+                        * while the QH is active.  Unlink it now;
+                        * re-linking will call qh_refresh().
                         */
-                       if (qh->qh_state == QH_STATE_LINKED) {
-                               if (eptype == USB_ENDPOINT_XFER_BULK) {
-                                       unlink_async(ehci, qh);
-                               } else {
-                                       intr_deschedule(ehci, qh);
-                                       (void) qh_schedule(ehci, qh);
-                               }
+                       if (eptype == USB_ENDPOINT_XFER_BULK) {
+                               unlink_async(ehci, qh);
+                       } else {
+                               intr_deschedule(ehci, qh);
+                               (void) qh_schedule(ehci, qh);
                        }
-                       spin_unlock_irq(&ehci->lock);
-                       schedule_timeout_uninterruptible(1);
-                       goto rescan;
                }
        }
-       spin_unlock_irq(&ehci->lock);
+       spin_unlock_irqrestore(&ehci->lock, flags);
 }
 
 static int ehci_get_frame (struct usb_hcd *hcd)
index a44bb4a949543d797f336827edb8ac6fa088d8ac..89b7c70c6ed6f015077a6a0233b78b080f581043 100644 (file)
@@ -61,6 +61,8 @@ static const struct hc_driver ixp4xx_ehci_hc_driver = {
 #endif
        .relinquish_port        = ehci_relinquish_port,
        .port_handed_over       = ehci_port_handed_over,
+
+       .clear_tt_buffer_complete       = ehci_clear_tt_buffer_complete,
 };
 
 static int ixp4xx_ehci_probe(struct platform_device *pdev)
index 770dd9aba62a9f07aabd9863e59fc4acae6a81dd..dc2ac613a9d1c34e2942ff55bf639fcb9d0be29b 100644 (file)
@@ -165,6 +165,8 @@ static const struct hc_driver ehci_orion_hc_driver = {
        .bus_resume = ehci_bus_resume,
        .relinquish_port = ehci_relinquish_port,
        .port_handed_over = ehci_port_handed_over,
+
+       .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
 };
 
 static void __init
index f3683e1da16134b3c20a6239b5edfd406af923aa..c2f1b7df918cd52ddd62385e3f02f5696d7f6f06 100644 (file)
@@ -404,6 +404,8 @@ static const struct hc_driver ehci_pci_hc_driver = {
        .bus_resume =           ehci_bus_resume,
        .relinquish_port =      ehci_relinquish_port,
        .port_handed_over =     ehci_port_handed_over,
+
+       .clear_tt_buffer_complete       = ehci_clear_tt_buffer_complete,
 };
 
 /*-------------------------------------------------------------------------*/
index fbd272288fc2cf799ef1d075adea282dd01aa863..36f96da129f5c637208031ec04913be3f0cc6e67 100644 (file)
@@ -79,6 +79,8 @@ static const struct hc_driver ehci_ppc_of_hc_driver = {
 #endif
        .relinquish_port        = ehci_relinquish_port,
        .port_handed_over       = ehci_port_handed_over,
+
+       .clear_tt_buffer_complete       = ehci_clear_tt_buffer_complete,
 };
 
 
index 93f7035d00a16ad1da984e9f1b81c521afa79cba..1dee33b9139e65d1f8714234c7ecde9e7b3d0d24 100644 (file)
@@ -75,6 +75,8 @@ static const struct hc_driver ps3_ehci_hc_driver = {
 #endif
        .relinquish_port        = ehci_relinquish_port,
        .port_handed_over       = ehci_port_handed_over,
+
+       .clear_tt_buffer_complete       = ehci_clear_tt_buffer_complete,
 };
 
 static int __devinit ps3_ehci_probe(struct ps3_system_bus_device *dev)
index 3192f683f8073293a6366b532ced3ff0dd5007f1..9a1384747f3bc8ca092b226d6de8fed5d6850276 100644 (file)
@@ -93,6 +93,22 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
        qh->hw_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma);
        qh->hw_alt_next = EHCI_LIST_END(ehci);
 
+       /* Except for control endpoints, we make hardware maintain data
+        * toggle (like OHCI) ... here (re)initialize the toggle in the QH,
+        * and set the pseudo-toggle in udev. Only usb_clear_halt() will
+        * ever clear it.
+        */
+       if (!(qh->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) {
+               unsigned        is_out, epnum;
+
+               is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8));
+               epnum = (hc32_to_cpup(ehci, &qh->hw_info1) >> 8) & 0x0f;
+               if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {
+                       qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
+                       usb_settoggle (qh->dev, epnum, is_out, 1);
+               }
+       }
+
        /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */
        wmb ();
        qh->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING);
@@ -123,6 +139,55 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh)
 
 /*-------------------------------------------------------------------------*/
 
+static void qh_link_async(struct ehci_hcd *ehci, struct ehci_qh *qh);
+
+static void ehci_clear_tt_buffer_complete(struct usb_hcd *hcd,
+               struct usb_host_endpoint *ep)
+{
+       struct ehci_hcd         *ehci = hcd_to_ehci(hcd);
+       struct ehci_qh          *qh = ep->hcpriv;
+       unsigned long           flags;
+
+       spin_lock_irqsave(&ehci->lock, flags);
+       qh->clearing_tt = 0;
+       if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list)
+                       && HC_IS_RUNNING(hcd->state))
+               qh_link_async(ehci, qh);
+       spin_unlock_irqrestore(&ehci->lock, flags);
+}
+
+static void ehci_clear_tt_buffer(struct ehci_hcd *ehci, struct ehci_qh *qh,
+               struct urb *urb, u32 token)
+{
+
+       /* If an async split transaction gets an error or is unlinked,
+        * the TT buffer may be left in an indeterminate state.  We
+        * have to clear the TT buffer.
+        *
+        * Note: this routine is never called for Isochronous transfers.
+        */
+       if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) {
+#ifdef DEBUG
+               struct usb_device *tt = urb->dev->tt->hub;
+               dev_dbg(&tt->dev,
+                       "clear tt buffer port %d, a%d ep%d t%08x\n",
+                       urb->dev->ttport, urb->dev->devnum,
+                       usb_pipeendpoint(urb->pipe), token);
+#endif /* DEBUG */
+               if (!ehci_is_TDI(ehci)
+                               || urb->dev->tt->hub !=
+                                  ehci_to_hcd(ehci)->self.root_hub) {
+                       if (usb_hub_clear_tt_buffer(urb) == 0)
+                               qh->clearing_tt = 1;
+               } else {
+
+                       /* REVISIT ARC-derived cores don't clear the root
+                        * hub TT buffer in this way...
+                        */
+               }
+       }
+}
+
 static int qtd_copy_status (
        struct ehci_hcd *ehci,
        struct urb *urb,
@@ -149,6 +214,14 @@ static int qtd_copy_status (
                if (token & QTD_STS_BABBLE) {
                        /* FIXME "must" disable babbling device's port too */
                        status = -EOVERFLOW;
+               /* CERR nonzero + halt --> stall */
+               } else if (QTD_CERR(token)) {
+                       status = -EPIPE;
+
+               /* In theory, more than one of the following bits can be set
+                * since they are sticky and the transaction is retried.
+                * Which to test first is rather arbitrary.
+                */
                } else if (token & QTD_STS_MMF) {
                        /* fs/ls interrupt xfer missed the complete-split */
                        status = -EPROTO;
@@ -157,21 +230,15 @@ static int qtd_copy_status (
                                ? -ENOSR  /* hc couldn't read data */
                                : -ECOMM; /* hc couldn't write data */
                } else if (token & QTD_STS_XACT) {
-                       /* timeout, bad crc, wrong PID, etc; retried */
-                       if (QTD_CERR (token))
-                               status = -EPIPE;
-                       else {
-                               ehci_dbg (ehci, "devpath %s ep%d%s 3strikes\n",
-                                       urb->dev->devpath,
-                                       usb_pipeendpoint (urb->pipe),
-                                       usb_pipein (urb->pipe) ? "in" : "out");
-                               status = -EPROTO;
-                       }
-               /* CERR nonzero + no errors + halt --> stall */
-               } else if (QTD_CERR (token))
-                       status = -EPIPE;
-               else    /* unknown */
+                       /* timeout, bad CRC, wrong PID, etc */
+                       ehci_dbg(ehci, "devpath %s ep%d%s 3strikes\n",
+                               urb->dev->devpath,
+                               usb_pipeendpoint(urb->pipe),
+                               usb_pipein(urb->pipe) ? "in" : "out");
+                       status = -EPROTO;
+               } else {        /* unknown */
                        status = -EPROTO;
+               }
 
                ehci_vdbg (ehci,
                        "dev%d ep%d%s qtd token %08x --> status %d\n",
@@ -179,28 +246,6 @@ static int qtd_copy_status (
                        usb_pipeendpoint (urb->pipe),
                        usb_pipein (urb->pipe) ? "in" : "out",
                        token, status);
-
-               /* if async CSPLIT failed, try cleaning out the TT buffer */
-               if (status != -EPIPE
-                               && urb->dev->tt
-                               && !usb_pipeint(urb->pipe)
-                               && ((token & QTD_STS_MMF) != 0
-                                       || QTD_CERR(token) == 0)
-                               && (!ehci_is_TDI(ehci)
-                                       || urb->dev->tt->hub !=
-                                          ehci_to_hcd(ehci)->self.root_hub)) {
-#ifdef DEBUG
-                       struct usb_device *tt = urb->dev->tt->hub;
-                       dev_dbg (&tt->dev,
-                               "clear tt buffer port %d, a%d ep%d t%08x\n",
-                               urb->dev->ttport, urb->dev->devnum,
-                               usb_pipeendpoint (urb->pipe), token);
-#endif /* DEBUG */
-                       /* REVISIT ARC-derived cores don't clear the root
-                        * hub TT buffer in this way...
-                        */
-                       usb_hub_tt_clear_buffer (urb->dev, urb->pipe);
-               }
        }
 
        return status;
@@ -391,9 +436,16 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
                        /* qh unlinked; token in overlay may be most current */
                        if (state == QH_STATE_IDLE
                                        && cpu_to_hc32(ehci, qtd->qtd_dma)
-                                               == qh->hw_current)
+                                               == qh->hw_current) {
                                token = hc32_to_cpu(ehci, qh->hw_token);
 
+                               /* An unlink may leave an incomplete
+                                * async transaction in the TT buffer.
+                                * We have to clear it.
+                                */
+                               ehci_clear_tt_buffer(ehci, qh, urb, token);
+                       }
+
                        /* force halt for unlinked or blocked qh, so we'll
                         * patch the qh later and so that completions can't
                         * activate it while we "know" it's stopped.
@@ -419,6 +471,13 @@ halt:
                                        && (qtd->hw_alt_next
                                                & EHCI_LIST_END(ehci)))
                                last_status = -EINPROGRESS;
+
+                       /* As part of low/full-speed endpoint-halt processing
+                        * we must clear the TT buffer (11.17.5).
+                        */
+                       if (unlikely(last_status != -EINPROGRESS &&
+                                       last_status != -EREMOTEIO))
+                               ehci_clear_tt_buffer(ehci, qh, urb, token);
                }
 
                /* if we're removing something not at the queue head,
@@ -834,6 +893,7 @@ done:
        qh->qh_state = QH_STATE_IDLE;
        qh->hw_info1 = cpu_to_hc32(ehci, info1);
        qh->hw_info2 = cpu_to_hc32(ehci, info2);
+       usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
        qh_refresh (ehci, qh);
        return qh;
 }
@@ -847,6 +907,10 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
        __hc32          dma = QH_NEXT(ehci, qh->qh_dma);
        struct ehci_qh  *head;
 
+       /* Don't link a QH if there's a Clear-TT-Buffer pending */
+       if (unlikely(qh->clearing_tt))
+               return;
+
        /* (re)start the async schedule? */
        head = ehci->async;
        timer_action_done (ehci, TIMER_ASYNC_OFF);
@@ -864,7 +928,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
                }
        }
 
-       /* clear halt and maybe recover from silicon quirk */
+       /* clear halt and/or toggle; and maybe recover from silicon quirk */
        if (qh->qh_state == QH_STATE_IDLE)
                qh_refresh (ehci, qh);
 
index 9d1babc7ff6553c64de8cec32fcfcff3f5ce5967..74f7f83b29ad9485ec9242afdbc1f91115a98f76 100644 (file)
@@ -1619,11 +1619,14 @@ itd_complete (
                                desc->status = -EPROTO;
 
                        /* HC need not update length with this error */
-                       if (!(t & EHCI_ISOC_BABBLE))
-                               desc->actual_length = EHCI_ITD_LENGTH (t);
+                       if (!(t & EHCI_ISOC_BABBLE)) {
+                               desc->actual_length = EHCI_ITD_LENGTH(t);
+                               urb->actual_length += desc->actual_length;
+                       }
                } else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) {
                        desc->status = 0;
-                       desc->actual_length = EHCI_ITD_LENGTH (t);
+                       desc->actual_length = EHCI_ITD_LENGTH(t);
+                       urb->actual_length += desc->actual_length;
                } else {
                        /* URB was too late */
                        desc->status = -EXDEV;
@@ -2014,7 +2017,8 @@ sitd_complete (
                        desc->status = -EPROTO;
        } else {
                desc->status = 0;
-               desc->actual_length = desc->length - SITD_LENGTH (t);
+               desc->actual_length = desc->length - SITD_LENGTH(t);
+               urb->actual_length += desc->actual_length;
        }
        stream->depth -= stream->interval << 3;
 
index 90ad3395bb21f0f96923ab21431dc7c44165badb..2bfff30f4704f7521678239df30c07323e0d3e59 100644 (file)
@@ -354,7 +354,9 @@ struct ehci_qh {
        unsigned short          period;         /* polling interval */
        unsigned short          start;          /* where polling starts */
 #define NO_FRAME ((unsigned short)~0)                  /* pick new start */
+
        struct usb_device       *dev;           /* access to TT */
+       unsigned                clearing_tt:1;  /* Clear-TT-Buf in progress */
 } __attribute__ ((aligned (32)));
 
 /*-------------------------------------------------------------------------*/
index bb63b68ddb7745486e841f3bdb73b011d1be12da..62a226b616707a2dcb0ba7667f537f4d8bb7481c 100644 (file)
@@ -576,9 +576,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd)
                        out_be16(&usb->fhci->regs->usb_event,
                                 usb->saved_msk);
                } else if (usb->port_status == FHCI_PORT_DISABLED) {
-                       if (fhci_ioports_check_bus_state(fhci) == 1 &&
-                                       usb->port_status != FHCI_PORT_LOW &&
-                                       usb->port_status != FHCI_PORT_FULL)
+                       if (fhci_ioports_check_bus_state(fhci) == 1)
                                fhci_device_connected_interrupt(fhci);
                }
                usb_er &= ~USB_E_RESET_MASK;
@@ -605,9 +603,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd)
        }
 
        if (usb_er & USB_E_IDLE_MASK) {
-               if (usb->port_status == FHCI_PORT_DISABLED &&
-                               usb->port_status != FHCI_PORT_LOW &&
-                               usb->port_status != FHCI_PORT_FULL) {
+               if (usb->port_status == FHCI_PORT_DISABLED) {
                        usb_er &= ~USB_E_RESET_MASK;
                        fhci_device_connected_interrupt(fhci);
                } else if (usb->port_status ==
index 3fa3a17027963af75a2d15d5c5da7990b7c5fc7f..d4feebfc63bd1b51088a9e22cc618db1eb0f092b 100644 (file)
@@ -361,7 +361,7 @@ static int __devexit isp1760_plat_remove(struct platform_device *pdev)
 
 static struct platform_driver isp1760_plat_driver = {
        .probe  = isp1760_plat_probe,
-       .remove = isp1760_plat_remove,
+       .remove = __devexit_p(isp1760_plat_remove),
        .driver = {
                .name   = "isp1760",
        },
index 180d7daa4099d50231f81f92c8ce537ab72dcbcc..e16ff605c458aa5a5b29e224deec2033adb96851 100644 (file)
 #include <mach/hardware.h>
 #include <mach/memory.h>
 #include <mach/gpio.h>
+#include <mach/cputype.h>
 
 #include <asm/mach-types.h>
 
 #include "musb_core.h"
 
 #ifdef CONFIG_MACH_DAVINCI_EVM
-#define GPIO_nVBUS_DRV         87
+#define GPIO_nVBUS_DRV         144
 #endif
 
 #include "davinci.h"
@@ -329,7 +330,6 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
                        mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
                        WARNING("VBUS error workaround (delay coming)\n");
                } else if (is_host_enabled(musb) && drvvbus) {
-                       musb->is_active = 1;
                        MUSB_HST_MODE(musb);
                        musb->xceiv->default_a = 1;
                        musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
@@ -343,7 +343,9 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
                        portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
                }
 
-               /* NOTE:  this must complete poweron within 100 msec */
+               /* NOTE:  this must complete poweron within 100 msec
+                * (OTG_TIME_A_WAIT_VRISE) but we don't check for that.
+                */
                davinci_source_power(musb, drvvbus, 0);
                DBG(2, "VBUS %s (%s)%s, devctl %02x\n",
                                drvvbus ? "on" : "off",
@@ -411,6 +413,21 @@ int __init musb_platform_init(struct musb *musb)
                __raw_writel(phy_ctrl, USB_PHY_CTRL);
        }
 
+       /* On dm355, the default-A state machine needs DRVVBUS control.
+        * If we won't be a host, there's no need to turn it on.
+        */
+       if (cpu_is_davinci_dm355()) {
+               u32     deepsleep = __raw_readl(DM355_DEEPSLEEP);
+
+               if (is_host_enabled(musb)) {
+                       deepsleep &= ~DRVVBUS_OVERRIDE;
+               } else {
+                       deepsleep &= ~DRVVBUS_FORCE;
+                       deepsleep |= DRVVBUS_OVERRIDE;
+               }
+               __raw_writel(deepsleep, DM355_DEEPSLEEP);
+       }
+
        /* reset the controller */
        musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1);
 
@@ -437,6 +454,15 @@ int musb_platform_exit(struct musb *musb)
        if (is_host_enabled(musb))
                del_timer_sync(&otg_workaround);
 
+       /* force VBUS off */
+       if (cpu_is_davinci_dm355()) {
+               u32     deepsleep = __raw_readl(DM355_DEEPSLEEP);
+
+               deepsleep &= ~DRVVBUS_FORCE;
+               deepsleep |= DRVVBUS_OVERRIDE;
+               __raw_writel(deepsleep, DM355_DEEPSLEEP);
+       }
+
        davinci_source_power(musb, 0 /*off*/, 1);
 
        /* delay, to avoid problems with module reload */
index 94a2a350a4141521e9e4d93426700ed3a31aaf6b..cf94511485f258a07d60186d43e3687fcf959a87 100644 (file)
@@ -373,7 +373,7 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb,
                musb_save_toggle(qh, is_in, urb);
                break;
        case USB_ENDPOINT_XFER_ISOC:
-               if (urb->error_count)
+               if (status == 0 && urb->error_count)
                        status = -EXDEV;
                break;
        }
@@ -2235,13 +2235,30 @@ static void musb_h_stop(struct usb_hcd *hcd)
 static int musb_bus_suspend(struct usb_hcd *hcd)
 {
        struct musb     *musb = hcd_to_musb(hcd);
+       u8              devctl;
 
-       if (musb->xceiv->state == OTG_STATE_A_SUSPEND)
+       if (!is_host_active(musb))
                return 0;
 
-       if (is_host_active(musb) && musb->is_active) {
-               WARNING("trying to suspend as %s is_active=%i\n",
-                       otg_state_string(musb), musb->is_active);
+       switch (musb->xceiv->state) {
+       case OTG_STATE_A_SUSPEND:
+               return 0;
+       case OTG_STATE_A_WAIT_VRISE:
+               /* ID could be grounded even if there's no device
+                * on the other end of the cable.  NOTE that the
+                * A_WAIT_VRISE timers are messy with MUSB...
+                */
+               devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+               if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS)
+                       musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
+               break;
+       default:
+               break;
+       }
+
+       if (musb->is_active) {
+               WARNING("trying to suspend as %s while active\n",
+                               otg_state_string(musb));
                return -EBUSY;
        } else
                return 0;
index 69feeec1628ce28bd8744ef5c6048d0b7a12746c..aa884d072f0b4c7202e5b421e52b0ca37a5163de 100644 (file)
@@ -59,18 +59,4 @@ config NOP_USB_XCEIV
         built-in with usb ip or which are autonomous and doesn't require any
         phy programming such as ISP1x04 etc.
 
-config USB_LANGWELL_OTG
-       tristate "Intel Langwell USB OTG dual-role support"
-       depends on USB && MRST
-       select USB_OTG
-       select USB_OTG_UTILS
-       help
-         Say Y here if you want to build Intel Langwell USB OTG
-         transciever driver in kernel. This driver implements role
-         switch between EHCI host driver and Langwell USB OTG
-         client driver.
-
-         To compile this driver as a module, choose M here: the
-         module will be called langwell_otg.
-
 endif # USB || OTG
index 6d1abdd3c0ac9cc1a2cd688dd9fda768ee2562a1..208167856529f26225807cd7edea4fb29a3640e9 100644 (file)
@@ -9,7 +9,6 @@ obj-$(CONFIG_USB_OTG_UTILS)     += otg.o
 obj-$(CONFIG_USB_GPIO_VBUS)    += gpio_vbus.o
 obj-$(CONFIG_ISP1301_OMAP)     += isp1301_omap.o
 obj-$(CONFIG_TWL4030_USB)      += twl4030-usb.o
-obj-$(CONFIG_USB_LANGWELL_OTG) += langwell_otg.o
 obj-$(CONFIG_NOP_USB_XCEIV)    += nop-usb-xceiv.o
 
 ccflags-$(CONFIG_USB_DEBUG)    += -DDEBUG
diff --git a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c
deleted file mode 100644 (file)
index 6f628d0..0000000
+++ /dev/null
@@ -1,1915 +0,0 @@
-/*
- * Intel Langwell USB OTG transceiver driver
- * Copyright (C) 2008 - 2009, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-/* This driver helps to switch Langwell OTG controller function between host
- * and peripheral. It works with EHCI driver and Langwell client controller
- * driver together.
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/moduleparam.h>
-#include <linux/usb/ch9.h>
-#include <linux/usb/gadget.h>
-#include <linux/usb.h>
-#include <linux/usb/otg.h>
-#include <linux/notifier.h>
-#include <asm/ipc_defs.h>
-#include <linux/delay.h>
-#include "../core/hcd.h"
-
-#include <linux/usb/langwell_otg.h>
-
-#define        DRIVER_DESC             "Intel Langwell USB OTG transceiver driver"
-#define        DRIVER_VERSION          "3.0.0.32L.0002"
-
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_AUTHOR("Henry Yuan <hang.yuan@intel.com>, Hao Wu <hao.wu@intel.com>");
-MODULE_VERSION(DRIVER_VERSION);
-MODULE_LICENSE("GPL");
-
-static const char driver_name[] = "langwell_otg";
-
-static int langwell_otg_probe(struct pci_dev *pdev,
-                       const struct pci_device_id *id);
-static void langwell_otg_remove(struct pci_dev *pdev);
-static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message);
-static int langwell_otg_resume(struct pci_dev *pdev);
-
-static int langwell_otg_set_host(struct otg_transceiver *otg,
-                               struct usb_bus *host);
-static int langwell_otg_set_peripheral(struct otg_transceiver *otg,
-                               struct usb_gadget *gadget);
-static int langwell_otg_start_srp(struct otg_transceiver *otg);
-
-static const struct pci_device_id pci_ids[] = {{
-       .class =        ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
-       .class_mask =   ~0,
-       .vendor =       0x8086,
-       .device =       0x0811,
-       .subvendor =    PCI_ANY_ID,
-       .subdevice =    PCI_ANY_ID,
-}, { /* end: all zeroes */ }
-};
-
-static struct pci_driver otg_pci_driver = {
-       .name =         (char *) driver_name,
-       .id_table =     pci_ids,
-
-       .probe =        langwell_otg_probe,
-       .remove =       langwell_otg_remove,
-
-       .suspend =      langwell_otg_suspend,
-       .resume =       langwell_otg_resume,
-};
-
-static const char *state_string(enum usb_otg_state state)
-{
-       switch (state) {
-       case OTG_STATE_A_IDLE:
-               return "a_idle";
-       case OTG_STATE_A_WAIT_VRISE:
-               return "a_wait_vrise";
-       case OTG_STATE_A_WAIT_BCON:
-               return "a_wait_bcon";
-       case OTG_STATE_A_HOST:
-               return "a_host";
-       case OTG_STATE_A_SUSPEND:
-               return "a_suspend";
-       case OTG_STATE_A_PERIPHERAL:
-               return "a_peripheral";
-       case OTG_STATE_A_WAIT_VFALL:
-               return "a_wait_vfall";
-       case OTG_STATE_A_VBUS_ERR:
-               return "a_vbus_err";
-       case OTG_STATE_B_IDLE:
-               return "b_idle";
-       case OTG_STATE_B_SRP_INIT:
-               return "b_srp_init";
-       case OTG_STATE_B_PERIPHERAL:
-               return "b_peripheral";
-       case OTG_STATE_B_WAIT_ACON:
-               return "b_wait_acon";
-       case OTG_STATE_B_HOST:
-               return "b_host";
-       default:
-               return "UNDEFINED";
-       }
-}
-
-/* HSM timers */
-static inline struct langwell_otg_timer *otg_timer_initializer
-(void (*function)(unsigned long), unsigned long expires, unsigned long data)
-{
-       struct langwell_otg_timer *timer;
-       timer = kmalloc(sizeof(struct langwell_otg_timer), GFP_KERNEL);
-       timer->function = function;
-       timer->expires = expires;
-       timer->data = data;
-       return timer;
-}
-
-static struct langwell_otg_timer *a_wait_vrise_tmr, *a_wait_bcon_tmr,
-       *a_aidl_bdis_tmr, *b_ase0_brst_tmr, *b_se0_srp_tmr, *b_srp_res_tmr,
-       *b_bus_suspend_tmr;
-
-static struct list_head active_timers;
-
-static struct langwell_otg *the_transceiver;
-
-/* host/client notify transceiver when event affects HNP state */
-void langwell_update_transceiver()
-{
-       otg_dbg("transceiver driver is notified\n");
-       queue_work(the_transceiver->qwork, &the_transceiver->work);
-}
-EXPORT_SYMBOL(langwell_update_transceiver);
-
-static int langwell_otg_set_host(struct otg_transceiver *otg,
-                                       struct usb_bus *host)
-{
-       otg->host = host;
-
-       return 0;
-}
-
-static int langwell_otg_set_peripheral(struct otg_transceiver *otg,
-                                       struct usb_gadget *gadget)
-{
-       otg->gadget = gadget;
-
-       return 0;
-}
-
-static int langwell_otg_set_power(struct otg_transceiver *otg,
-                               unsigned mA)
-{
-       return 0;
-}
-
-/* A-device drives vbus, controlled through PMIC CHRGCNTL register*/
-static void langwell_otg_drv_vbus(int on)
-{
-       struct ipc_pmic_reg_data        pmic_data = {0};
-       struct ipc_pmic_reg_data        battery_data;
-
-       /* Check if battery is attached or not */
-       battery_data.pmic_reg_data[0].register_address = 0xd2;
-       battery_data.ioc = 0;
-       battery_data.num_entries = 1;
-       if (ipc_pmic_register_read(&battery_data)) {
-               otg_dbg("Failed to read PMIC register 0xd2.\n");
-               return;
-       }
-
-       if ((battery_data.pmic_reg_data[0].value & 0x20) == 0) {
-               otg_dbg("no battery attached\n");
-               return;
-       }
-
-       /* Workaround for battery attachment issue */
-       if (battery_data.pmic_reg_data[0].value == 0x34) {
-               otg_dbg("battery \n");
-               return;
-       }
-
-       otg_dbg("battery attached\n");
-
-       pmic_data.ioc = 0;
-       pmic_data.pmic_reg_data[0].register_address = 0xD4;
-       pmic_data.num_entries = 1;
-       if (on)
-               pmic_data.pmic_reg_data[0].value = 0x20;
-       else
-               pmic_data.pmic_reg_data[0].value = 0xc0;
-
-       if (ipc_pmic_register_write(&pmic_data, TRUE))
-               otg_dbg("Failed to write PMIC.\n");
-
-}
-
-/* charge vbus or discharge vbus through a resistor to ground */
-static void langwell_otg_chrg_vbus(int on)
-{
-
-       u32     val;
-
-       val = readl(the_transceiver->regs + CI_OTGSC);
-
-       if (on)
-               writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VC,
-                               the_transceiver->regs + CI_OTGSC);
-       else
-               writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VD,
-                               the_transceiver->regs + CI_OTGSC);
-
-}
-
-/* Start SRP */
-static int langwell_otg_start_srp(struct otg_transceiver *otg)
-{
-       u32     val;
-
-       otg_dbg("Start SRP ->\n");
-
-       val = readl(the_transceiver->regs + CI_OTGSC);
-
-       writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HADP,
-               the_transceiver->regs + CI_OTGSC);
-
-       /* Check if the data plus is finished or not */
-       msleep(8);
-       val = readl(the_transceiver->regs + CI_OTGSC);
-       if (val & (OTGSC_HADP | OTGSC_DP))
-               otg_dbg("DataLine SRP Error\n");
-
-       /* FIXME: VBus SRP */
-
-       return 0;
-}
-
-
-/* stop SOF via bus_suspend */
-static void langwell_otg_loc_sof(int on)
-{
-       struct usb_hcd  *hcd;
-       int             err;
-
-       otg_dbg("loc_sof -> %d\n", on);
-
-       hcd = bus_to_hcd(the_transceiver->otg.host);
-       if (on)
-               err = hcd->driver->bus_resume(hcd);
-       else
-               err = hcd->driver->bus_suspend(hcd);
-
-       if (err)
-               otg_dbg("Failed to resume/suspend bus - %d\n", err);
-}
-
-static void langwell_otg_phy_low_power(int on)
-{
-       u32     val;
-
-       otg_dbg("phy low power mode-> %d\n", on);
-
-       val = readl(the_transceiver->regs + CI_HOSTPC1);
-       if (on)
-               writel(val | HOSTPC1_PHCD, the_transceiver->regs + CI_HOSTPC1);
-       else
-               writel(val & ~HOSTPC1_PHCD, the_transceiver->regs + CI_HOSTPC1);
-}
-
-/* Enable/Disable OTG interrupt */
-static void langwell_otg_intr(int on)
-{
-       u32 val;
-
-       otg_dbg("interrupt -> %d\n", on);
-
-       val = readl(the_transceiver->regs + CI_OTGSC);
-       if (on) {
-               val = val | (OTGSC_INTEN_MASK | OTGSC_IDPU);
-               writel(val, the_transceiver->regs + CI_OTGSC);
-       } else {
-               val = val & ~(OTGSC_INTEN_MASK | OTGSC_IDPU);
-               writel(val, the_transceiver->regs + CI_OTGSC);
-       }
-}
-
-/* set HAAR: Hardware Assist Auto-Reset */
-static void langwell_otg_HAAR(int on)
-{
-       u32     val;
-
-       otg_dbg("HAAR -> %d\n", on);
-
-       val = readl(the_transceiver->regs + CI_OTGSC);
-       if (on)
-               writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HAAR,
-                               the_transceiver->regs + CI_OTGSC);
-       else
-               writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HAAR,
-                               the_transceiver->regs + CI_OTGSC);
-}
-
-/* set HABA: Hardware Assist B-Disconnect to A-Connect */
-static void langwell_otg_HABA(int on)
-{
-       u32     val;
-
-       otg_dbg("HABA -> %d\n", on);
-
-       val = readl(the_transceiver->regs + CI_OTGSC);
-       if (on)
-               writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HABA,
-                               the_transceiver->regs + CI_OTGSC);
-       else
-               writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HABA,
-                               the_transceiver->regs + CI_OTGSC);
-}
-
-static int langwell_otg_check_se0_srp(int on)
-{
-       u32 val;
-
-       int delay_time = TB_SE0_SRP * 10; /* step is 100us */
-
-       otg_dbg("check_se0_srp -> \n");
-
-       do {
-               udelay(100);
-               if (!delay_time--)
-                       break;
-               val = readl(the_transceiver->regs + CI_PORTSC1);
-               val &= PORTSC_LS;
-       } while (!val);
-
-       otg_dbg("check_se0_srp <- \n");
-       return val;
-}
-
-/* The timeout callback function to set time out bit */
-static void set_tmout(unsigned long indicator)
-{
-       *(int *)indicator = 1;
-}
-
-void langwell_otg_nsf_msg(unsigned long indicator)
-{
-       switch (indicator) {
-       case 2:
-       case 4:
-       case 6:
-       case 7:
-               printk(KERN_ERR "OTG:NSF-%lu - deivce not responding\n",
-                               indicator);
-               break;
-       case 3:
-               printk(KERN_ERR "OTG:NSF-%lu - deivce not supported\n",
-                               indicator);
-               break;
-       default:
-               printk(KERN_ERR "Do not have this kind of NSF\n");
-               break;
-       }
-}
-
-/* Initialize timers */
-static void langwell_otg_init_timers(struct otg_hsm *hsm)
-{
-       /* HSM used timers */
-       a_wait_vrise_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_VRISE,
-                               (unsigned long)&hsm->a_wait_vrise_tmout);
-       a_wait_bcon_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_BCON,
-                               (unsigned long)&hsm->a_wait_bcon_tmout);
-       a_aidl_bdis_tmr = otg_timer_initializer(&set_tmout, TA_AIDL_BDIS,
-                               (unsigned long)&hsm->a_aidl_bdis_tmout);
-       b_ase0_brst_tmr = otg_timer_initializer(&set_tmout, TB_ASE0_BRST,
-                               (unsigned long)&hsm->b_ase0_brst_tmout);
-       b_se0_srp_tmr = otg_timer_initializer(&set_tmout, TB_SE0_SRP,
-                               (unsigned long)&hsm->b_se0_srp);
-       b_srp_res_tmr = otg_timer_initializer(&set_tmout, TB_SRP_RES,
-                               (unsigned long)&hsm->b_srp_res_tmout);
-       b_bus_suspend_tmr = otg_timer_initializer(&set_tmout, TB_BUS_SUSPEND,
-                               (unsigned long)&hsm->b_bus_suspend_tmout);
-}
-
-/* Free timers */
-static void langwell_otg_free_timers(void)
-{
-       kfree(a_wait_vrise_tmr);
-       kfree(a_wait_bcon_tmr);
-       kfree(a_aidl_bdis_tmr);
-       kfree(b_ase0_brst_tmr);
-       kfree(b_se0_srp_tmr);
-       kfree(b_srp_res_tmr);
-       kfree(b_bus_suspend_tmr);
-}
-
-/* Add timer to timer list */
-static void langwell_otg_add_timer(void *gtimer)
-{
-       struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer;
-       struct langwell_otg_timer *tmp_timer;
-       u32     val32;
-
-       /* Check if the timer is already in the active list,
-        * if so update timer count
-        */
-       list_for_each_entry(tmp_timer, &active_timers, list)
-               if (tmp_timer == timer) {
-                       timer->count = timer->expires;
-                       return;
-               }
-       timer->count = timer->expires;
-
-       if (list_empty(&active_timers)) {
-               val32 = readl(the_transceiver->regs + CI_OTGSC);
-               writel(val32 | OTGSC_1MSE, the_transceiver->regs + CI_OTGSC);
-       }
-
-       list_add_tail(&timer->list, &active_timers);
-}
-
-/* Remove timer from the timer list; clear timeout status */
-static void langwell_otg_del_timer(void *gtimer)
-{
-       struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer;
-       struct langwell_otg_timer *tmp_timer, *del_tmp;
-       u32 val32;
-
-       list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list)
-               if (tmp_timer == timer)
-                       list_del(&timer->list);
-
-       if (list_empty(&active_timers)) {
-               val32 = readl(the_transceiver->regs + CI_OTGSC);
-               writel(val32 & ~OTGSC_1MSE, the_transceiver->regs + CI_OTGSC);
-       }
-}
-
-/* Reduce timer count by 1, and find timeout conditions.*/
-static int langwell_otg_tick_timer(u32 *int_sts)
-{
-       struct langwell_otg_timer *tmp_timer, *del_tmp;
-       int expired = 0;
-
-       list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) {
-               tmp_timer->count--;
-               /* check if timer expires */
-               if (!tmp_timer->count) {
-                       list_del(&tmp_timer->list);
-                       tmp_timer->function(tmp_timer->data);
-                       expired = 1;
-               }
-       }
-
-       if (list_empty(&active_timers)) {
-               otg_dbg("tick timer: disable 1ms int\n");
-               *int_sts = *int_sts & ~OTGSC_1MSE;
-       }
-       return expired;
-}
-
-static void reset_otg(void)
-{
-       u32     val;
-       int     delay_time = 1000;
-
-       otg_dbg("reseting OTG controller ...\n");
-       val = readl(the_transceiver->regs + CI_USBCMD);
-       writel(val | USBCMD_RST, the_transceiver->regs + CI_USBCMD);
-       do {
-               udelay(100);
-               if (!delay_time--)
-                       otg_dbg("reset timeout\n");
-               val = readl(the_transceiver->regs + CI_USBCMD);
-               val &= USBCMD_RST;
-       } while (val != 0);
-       otg_dbg("reset done.\n");
-}
-
-static void set_host_mode(void)
-{
-       u32     val;
-
-       reset_otg();
-       val = readl(the_transceiver->regs + CI_USBMODE);
-       val = (val & (~USBMODE_CM)) | USBMODE_HOST;
-       writel(val, the_transceiver->regs + CI_USBMODE);
-}
-
-static void set_client_mode(void)
-{
-       u32     val;
-
-       reset_otg();
-       val = readl(the_transceiver->regs + CI_USBMODE);
-       val = (val & (~USBMODE_CM)) | USBMODE_DEVICE;
-       writel(val, the_transceiver->regs + CI_USBMODE);
-}
-
-static void init_hsm(void)
-{
-       struct langwell_otg     *langwell = the_transceiver;
-       u32                     val32;
-
-       /* read OTGSC after reset */
-       val32 = readl(langwell->regs + CI_OTGSC);
-       otg_dbg("%s: OTGSC init value = 0x%x\n", __func__, val32);
-
-       /* set init state */
-       if (val32 & OTGSC_ID) {
-               langwell->hsm.id = 1;
-               langwell->otg.default_a = 0;
-               set_client_mode();
-               langwell->otg.state = OTG_STATE_B_IDLE;
-               langwell_otg_drv_vbus(0);
-       } else {
-               langwell->hsm.id = 0;
-               langwell->otg.default_a = 1;
-               set_host_mode();
-               langwell->otg.state = OTG_STATE_A_IDLE;
-       }
-
-       /* set session indicator */
-       if (val32 & OTGSC_BSE)
-               langwell->hsm.b_sess_end = 1;
-       if (val32 & OTGSC_BSV)
-               langwell->hsm.b_sess_vld = 1;
-       if (val32 & OTGSC_ASV)
-               langwell->hsm.a_sess_vld = 1;
-       if (val32 & OTGSC_AVV)
-               langwell->hsm.a_vbus_vld = 1;
-
-       /* defautly power the bus */
-       langwell->hsm.a_bus_req = 1;
-       langwell->hsm.a_bus_drop = 0;
-       /* defautly don't request bus as B device */
-       langwell->hsm.b_bus_req = 0;
-       /* no system error */
-       langwell->hsm.a_clr_err = 0;
-}
-
-static irqreturn_t otg_dummy_irq(int irq, void *_dev)
-{
-       void __iomem    *reg_base = _dev;
-       u32     val;
-       u32     int_mask = 0;
-
-       val = readl(reg_base + CI_USBMODE);
-       if ((val & USBMODE_CM) != USBMODE_DEVICE)
-               return IRQ_NONE;
-
-       val = readl(reg_base + CI_USBSTS);
-       int_mask = val & INTR_DUMMY_MASK;
-
-       if (int_mask == 0)
-               return IRQ_NONE;
-
-       /* clear hsm.b_conn here since host driver can't detect it
-       *  otg_dummy_irq called means B-disconnect happened.
-       */
-       if (the_transceiver->hsm.b_conn) {
-               the_transceiver->hsm.b_conn = 0;
-               if (spin_trylock(&the_transceiver->wq_lock)) {
-                       queue_work(the_transceiver->qwork,
-                               &the_transceiver->work);
-                       spin_unlock(&the_transceiver->wq_lock);
-               }
-       }
-       /* Clear interrupts */
-       writel(int_mask, reg_base + CI_USBSTS);
-       return IRQ_HANDLED;
-}
-
-static irqreturn_t otg_irq(int irq, void *_dev)
-{
-       struct  langwell_otg *langwell = _dev;
-       u32     int_sts, int_en;
-       u32     int_mask = 0;
-       int     flag = 0;
-
-       int_sts = readl(langwell->regs + CI_OTGSC);
-       int_en = (int_sts & OTGSC_INTEN_MASK) >> 8;
-       int_mask = int_sts & int_en;
-       if (int_mask == 0)
-               return IRQ_NONE;
-
-       if (int_mask & OTGSC_IDIS) {
-               otg_dbg("%s: id change int\n", __func__);
-               langwell->hsm.id = (int_sts & OTGSC_ID) ? 1 : 0;
-               flag = 1;
-       }
-       if (int_mask & OTGSC_DPIS) {
-               otg_dbg("%s: data pulse int\n", __func__);
-               langwell->hsm.a_srp_det = (int_sts & OTGSC_DPS) ? 1 : 0;
-               flag = 1;
-       }
-       if (int_mask & OTGSC_BSEIS) {
-               otg_dbg("%s: b session end int\n", __func__);
-               langwell->hsm.b_sess_end = (int_sts & OTGSC_BSE) ? 1 : 0;
-               flag = 1;
-       }
-       if (int_mask & OTGSC_BSVIS) {
-               otg_dbg("%s: b session valid int\n", __func__);
-               langwell->hsm.b_sess_vld = (int_sts & OTGSC_BSV) ? 1 : 0;
-               flag = 1;
-       }
-       if (int_mask & OTGSC_ASVIS) {
-               otg_dbg("%s: a session valid int\n", __func__);
-               langwell->hsm.a_sess_vld = (int_sts & OTGSC_ASV) ? 1 : 0;
-               flag = 1;
-       }
-       if (int_mask & OTGSC_AVVIS) {
-               otg_dbg("%s: a vbus valid int\n", __func__);
-               langwell->hsm.a_vbus_vld = (int_sts & OTGSC_AVV) ? 1 : 0;
-               flag = 1;
-       }
-
-       if (int_mask & OTGSC_1MSS) {
-               /* need to schedule otg_work if any timer is expired */
-               if (langwell_otg_tick_timer(&int_sts))
-                       flag = 1;
-       }
-
-       writel((int_sts & ~OTGSC_INTSTS_MASK) | int_mask,
-                       langwell->regs + CI_OTGSC);
-       if (flag)
-               queue_work(langwell->qwork, &langwell->work);
-
-       return IRQ_HANDLED;
-}
-
-static void langwell_otg_work(struct work_struct *work)
-{
-       struct langwell_otg *langwell = container_of(work,
-                                       struct langwell_otg, work);
-       int     retval;
-
-       otg_dbg("%s: old state = %s\n", __func__,
-                       state_string(langwell->otg.state));
-
-       switch (langwell->otg.state) {
-       case OTG_STATE_UNDEFINED:
-       case OTG_STATE_B_IDLE:
-               if (!langwell->hsm.id) {
-                       langwell_otg_del_timer(b_srp_res_tmr);
-                       langwell->otg.default_a = 1;
-                       langwell->hsm.a_srp_det = 0;
-
-                       langwell_otg_chrg_vbus(0);
-                       langwell_otg_drv_vbus(0);
-
-                       set_host_mode();
-                       langwell->otg.state = OTG_STATE_A_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (langwell->hsm.b_srp_res_tmout) {
-                       langwell->hsm.b_srp_res_tmout = 0;
-                       langwell->hsm.b_bus_req = 0;
-                       langwell_otg_nsf_msg(6);
-               } else if (langwell->hsm.b_sess_vld) {
-                       langwell_otg_del_timer(b_srp_res_tmr);
-                       langwell->hsm.b_sess_end = 0;
-                       langwell->hsm.a_bus_suspend = 0;
-
-                       langwell_otg_chrg_vbus(0);
-                       if (langwell->client_ops) {
-                               langwell->client_ops->resume(langwell->pdev);
-                               langwell->otg.state = OTG_STATE_B_PERIPHERAL;
-                       } else
-                               otg_dbg("client driver not loaded.\n");
-
-               } else if (langwell->hsm.b_bus_req &&
-                               (langwell->hsm.b_sess_end)) {
-                       /* workaround for b_se0_srp detection */
-                       retval = langwell_otg_check_se0_srp(0);
-                       if (retval) {
-                               langwell->hsm.b_bus_req = 0;
-                               otg_dbg("LS is not SE0, try again later\n");
-                       } else {
-                               /* Start SRP */
-                               langwell_otg_start_srp(&langwell->otg);
-                               langwell_otg_add_timer(b_srp_res_tmr);
-                       }
-               }
-               break;
-       case OTG_STATE_B_SRP_INIT:
-               if (!langwell->hsm.id) {
-                       langwell->otg.default_a = 1;
-                       langwell->hsm.a_srp_det = 0;
-
-                       langwell_otg_drv_vbus(0);
-                       langwell_otg_chrg_vbus(0);
-
-                       langwell->otg.state = OTG_STATE_A_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (langwell->hsm.b_sess_vld) {
-                       langwell_otg_chrg_vbus(0);
-                       if (langwell->client_ops) {
-                               langwell->client_ops->resume(langwell->pdev);
-                               langwell->otg.state = OTG_STATE_B_PERIPHERAL;
-                       } else
-                               otg_dbg("client driver not loaded.\n");
-               }
-               break;
-       case OTG_STATE_B_PERIPHERAL:
-               if (!langwell->hsm.id) {
-                       langwell->otg.default_a = 1;
-                       langwell->hsm.a_srp_det = 0;
-
-                       langwell_otg_drv_vbus(0);
-                       langwell_otg_chrg_vbus(0);
-                       set_host_mode();
-
-                       if (langwell->client_ops) {
-                               langwell->client_ops->suspend(langwell->pdev,
-                                       PMSG_FREEZE);
-                       } else
-                               otg_dbg("client driver has been removed.\n");
-
-                       langwell->otg.state = OTG_STATE_A_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (!langwell->hsm.b_sess_vld) {
-                       langwell->hsm.b_hnp_enable = 0;
-
-                       if (langwell->client_ops) {
-                               langwell->client_ops->suspend(langwell->pdev,
-                                       PMSG_FREEZE);
-                       } else
-                               otg_dbg("client driver has been removed.\n");
-
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-               } else if (langwell->hsm.b_bus_req && langwell->hsm.b_hnp_enable
-                       && langwell->hsm.a_bus_suspend) {
-
-                       if (langwell->client_ops) {
-                               langwell->client_ops->suspend(langwell->pdev,
-                                       PMSG_FREEZE);
-                       } else
-                               otg_dbg("client driver has been removed.\n");
-
-                       langwell_otg_HAAR(1);
-                       langwell->hsm.a_conn = 0;
-
-                       if (langwell->host_ops) {
-                               langwell->host_ops->probe(langwell->pdev,
-                                       langwell->host_ops->id_table);
-                               langwell->otg.state = OTG_STATE_B_WAIT_ACON;
-                       } else
-                               otg_dbg("host driver not loaded.\n");
-
-                       langwell->hsm.a_bus_resume = 0;
-                       langwell->hsm.b_ase0_brst_tmout = 0;
-                       langwell_otg_add_timer(b_ase0_brst_tmr);
-               }
-               break;
-
-       case OTG_STATE_B_WAIT_ACON:
-               if (!langwell->hsm.id) {
-                       langwell_otg_del_timer(b_ase0_brst_tmr);
-                       langwell->otg.default_a = 1;
-                       langwell->hsm.a_srp_det = 0;
-
-                       langwell_otg_drv_vbus(0);
-                       langwell_otg_chrg_vbus(0);
-                       set_host_mode();
-
-                       langwell_otg_HAAR(0);
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell->otg.state = OTG_STATE_A_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (!langwell->hsm.b_sess_vld) {
-                       langwell_otg_del_timer(b_ase0_brst_tmr);
-                       langwell->hsm.b_hnp_enable = 0;
-                       langwell->hsm.b_bus_req = 0;
-                       langwell_otg_chrg_vbus(0);
-                       langwell_otg_HAAR(0);
-
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-               } else if (langwell->hsm.a_conn) {
-                       langwell_otg_del_timer(b_ase0_brst_tmr);
-                       langwell_otg_HAAR(0);
-                       langwell->otg.state = OTG_STATE_B_HOST;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (langwell->hsm.a_bus_resume ||
-                               langwell->hsm.b_ase0_brst_tmout) {
-                       langwell_otg_del_timer(b_ase0_brst_tmr);
-                       langwell_otg_HAAR(0);
-                       langwell_otg_nsf_msg(7);
-
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-
-                       langwell->hsm.a_bus_suspend = 0;
-                       langwell->hsm.b_bus_req = 0;
-
-                       if (langwell->client_ops)
-                               langwell->client_ops->resume(langwell->pdev);
-                       else
-                               otg_dbg("client driver not loaded.\n");
-
-                       langwell->otg.state = OTG_STATE_B_PERIPHERAL;
-               }
-               break;
-
-       case OTG_STATE_B_HOST:
-               if (!langwell->hsm.id) {
-                       langwell->otg.default_a = 1;
-                       langwell->hsm.a_srp_det = 0;
-
-                       langwell_otg_drv_vbus(0);
-                       langwell_otg_chrg_vbus(0);
-                       set_host_mode();
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell->otg.state = OTG_STATE_A_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (!langwell->hsm.b_sess_vld) {
-                       langwell->hsm.b_hnp_enable = 0;
-                       langwell->hsm.b_bus_req = 0;
-                       langwell_otg_chrg_vbus(0);
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-               } else if ((!langwell->hsm.b_bus_req) ||
-                               (!langwell->hsm.a_conn)) {
-                       langwell->hsm.b_bus_req = 0;
-                       langwell_otg_loc_sof(0);
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-
-                       langwell->hsm.a_bus_suspend = 0;
-
-                       if (langwell->client_ops)
-                               langwell->client_ops->resume(langwell->pdev);
-                       else
-                               otg_dbg("client driver not loaded.\n");
-
-                       langwell->otg.state = OTG_STATE_B_PERIPHERAL;
-               }
-               break;
-
-       case OTG_STATE_A_IDLE:
-               langwell->otg.default_a = 1;
-               if (langwell->hsm.id) {
-                       langwell->otg.default_a = 0;
-                       langwell->hsm.b_bus_req = 0;
-                       langwell_otg_drv_vbus(0);
-                       langwell_otg_chrg_vbus(0);
-
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (langwell->hsm.a_sess_vld) {
-                       langwell_otg_drv_vbus(1);
-                       langwell->hsm.a_srp_det = 1;
-                       langwell->hsm.a_wait_vrise_tmout = 0;
-                       langwell_otg_add_timer(a_wait_vrise_tmr);
-                       langwell->otg.state = OTG_STATE_A_WAIT_VRISE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (!langwell->hsm.a_bus_drop &&
-                       (langwell->hsm.a_srp_det || langwell->hsm.a_bus_req)) {
-                       langwell_otg_drv_vbus(1);
-                       langwell->hsm.a_wait_vrise_tmout = 0;
-                       langwell_otg_add_timer(a_wait_vrise_tmr);
-                       langwell->otg.state = OTG_STATE_A_WAIT_VRISE;
-                       queue_work(langwell->qwork, &langwell->work);
-               }
-               break;
-       case OTG_STATE_A_WAIT_VRISE:
-               if (langwell->hsm.id) {
-                       langwell_otg_del_timer(a_wait_vrise_tmr);
-                       langwell->hsm.b_bus_req = 0;
-                       langwell->otg.default_a = 0;
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-               } else if (langwell->hsm.a_vbus_vld) {
-                       langwell_otg_del_timer(a_wait_vrise_tmr);
-                       if (langwell->host_ops)
-                               langwell->host_ops->probe(langwell->pdev,
-                                               langwell->host_ops->id_table);
-                       else
-                               otg_dbg("host driver not loaded.\n");
-                       langwell->hsm.b_conn = 0;
-                       langwell->hsm.a_set_b_hnp_en = 0;
-                       langwell->hsm.a_wait_bcon_tmout = 0;
-                       langwell_otg_add_timer(a_wait_bcon_tmr);
-                       langwell->otg.state = OTG_STATE_A_WAIT_BCON;
-               } else if (langwell->hsm.a_wait_vrise_tmout) {
-                       if (langwell->hsm.a_vbus_vld) {
-                               if (langwell->host_ops)
-                                       langwell->host_ops->probe(
-                                               langwell->pdev,
-                                               langwell->host_ops->id_table);
-                               else
-                                       otg_dbg("host driver not loaded.\n");
-                               langwell->hsm.b_conn = 0;
-                               langwell->hsm.a_set_b_hnp_en = 0;
-                               langwell->hsm.a_wait_bcon_tmout = 0;
-                               langwell_otg_add_timer(a_wait_bcon_tmr);
-                               langwell->otg.state = OTG_STATE_A_WAIT_BCON;
-                       } else {
-                               langwell_otg_drv_vbus(0);
-                               langwell->otg.state = OTG_STATE_A_VBUS_ERR;
-                       }
-               }
-               break;
-       case OTG_STATE_A_WAIT_BCON:
-               if (langwell->hsm.id) {
-                       langwell_otg_del_timer(a_wait_bcon_tmr);
-
-                       langwell->otg.default_a = 0;
-                       langwell->hsm.b_bus_req = 0;
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (!langwell->hsm.a_vbus_vld) {
-                       langwell_otg_del_timer(a_wait_bcon_tmr);
-
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_A_VBUS_ERR;
-               } else if (langwell->hsm.a_bus_drop ||
-                               (langwell->hsm.a_wait_bcon_tmout &&
-                               !langwell->hsm.a_bus_req)) {
-                       langwell_otg_del_timer(a_wait_bcon_tmr);
-
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_A_WAIT_VFALL;
-               } else if (langwell->hsm.b_conn) {
-                       langwell_otg_del_timer(a_wait_bcon_tmr);
-
-                       langwell->hsm.a_suspend_req = 0;
-                       langwell->otg.state = OTG_STATE_A_HOST;
-                       if (!langwell->hsm.a_bus_req &&
-                               langwell->hsm.a_set_b_hnp_en) {
-                               /* It is not safe enough to do a fast
-                                * transistion from A_WAIT_BCON to
-                                * A_SUSPEND */
-                               msleep(10000);
-                               if (langwell->hsm.a_bus_req)
-                                       break;
-
-                               if (request_irq(langwell->pdev->irq,
-                                       otg_dummy_irq, IRQF_SHARED,
-                                       driver_name, langwell->regs) != 0) {
-                                       otg_dbg("request interrupt %d fail\n",
-                                       langwell->pdev->irq);
-                               }
-
-                               langwell_otg_HABA(1);
-                               langwell->hsm.b_bus_resume = 0;
-                               langwell->hsm.a_aidl_bdis_tmout = 0;
-                               langwell_otg_add_timer(a_aidl_bdis_tmr);
-
-                               langwell_otg_loc_sof(0);
-                               langwell->otg.state = OTG_STATE_A_SUSPEND;
-                       } else if (!langwell->hsm.a_bus_req &&
-                               !langwell->hsm.a_set_b_hnp_en) {
-                               struct pci_dev *pdev = langwell->pdev;
-                               if (langwell->host_ops)
-                                       langwell->host_ops->remove(pdev);
-                               else
-                                       otg_dbg("host driver removed.\n");
-                               langwell_otg_drv_vbus(0);
-                               langwell->otg.state = OTG_STATE_A_WAIT_VFALL;
-                       }
-               }
-               break;
-       case OTG_STATE_A_HOST:
-               if (langwell->hsm.id) {
-                       langwell->otg.default_a = 0;
-                       langwell->hsm.b_bus_req = 0;
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (langwell->hsm.a_bus_drop ||
-               (!langwell->hsm.a_set_b_hnp_en && !langwell->hsm.a_bus_req)) {
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_A_WAIT_VFALL;
-               } else if (!langwell->hsm.a_vbus_vld) {
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_A_VBUS_ERR;
-               } else if (langwell->hsm.a_set_b_hnp_en
-                               && !langwell->hsm.a_bus_req) {
-                       /* Set HABA to enable hardware assistance to signal
-                        *  A-connect after receiver B-disconnect. Hardware
-                        *  will then set client mode and enable URE, SLE and
-                        *  PCE after the assistance. otg_dummy_irq is used to
-                        *  clean these ints when client driver is not resumed.
-                        */
-                       if (request_irq(langwell->pdev->irq,
-                               otg_dummy_irq, IRQF_SHARED, driver_name,
-                               langwell->regs) != 0) {
-                               otg_dbg("request interrupt %d failed\n",
-                                               langwell->pdev->irq);
-                       }
-
-                       /* set HABA */
-                       langwell_otg_HABA(1);
-                       langwell->hsm.b_bus_resume = 0;
-                       langwell->hsm.a_aidl_bdis_tmout = 0;
-                       langwell_otg_add_timer(a_aidl_bdis_tmr);
-                       langwell_otg_loc_sof(0);
-                       langwell->otg.state = OTG_STATE_A_SUSPEND;
-               } else if (!langwell->hsm.b_conn || !langwell->hsm.a_bus_req) {
-                       langwell->hsm.a_wait_bcon_tmout = 0;
-                       langwell->hsm.a_set_b_hnp_en = 0;
-                       langwell_otg_add_timer(a_wait_bcon_tmr);
-                       langwell->otg.state = OTG_STATE_A_WAIT_BCON;
-               }
-               break;
-       case OTG_STATE_A_SUSPEND:
-               if (langwell->hsm.id) {
-                       langwell_otg_del_timer(a_aidl_bdis_tmr);
-                       langwell_otg_HABA(0);
-                       free_irq(langwell->pdev->irq, langwell->regs);
-                       langwell->otg.default_a = 0;
-                       langwell->hsm.b_bus_req = 0;
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (langwell->hsm.a_bus_req ||
-                               langwell->hsm.b_bus_resume) {
-                       langwell_otg_del_timer(a_aidl_bdis_tmr);
-                       langwell_otg_HABA(0);
-                       free_irq(langwell->pdev->irq, langwell->regs);
-                       langwell->hsm.a_suspend_req = 0;
-                       langwell_otg_loc_sof(1);
-                       langwell->otg.state = OTG_STATE_A_HOST;
-               } else if (langwell->hsm.a_aidl_bdis_tmout ||
-                               langwell->hsm.a_bus_drop) {
-                       langwell_otg_del_timer(a_aidl_bdis_tmr);
-                       langwell_otg_HABA(0);
-                       free_irq(langwell->pdev->irq, langwell->regs);
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_A_WAIT_VFALL;
-               } else if (!langwell->hsm.b_conn &&
-                               langwell->hsm.a_set_b_hnp_en) {
-                       langwell_otg_del_timer(a_aidl_bdis_tmr);
-                       langwell_otg_HABA(0);
-                       free_irq(langwell->pdev->irq, langwell->regs);
-
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-
-                       langwell->hsm.b_bus_suspend = 0;
-                       langwell->hsm.b_bus_suspend_vld = 0;
-                       langwell->hsm.b_bus_suspend_tmout = 0;
-
-                       /* msleep(200); */
-                       if (langwell->client_ops)
-                               langwell->client_ops->resume(langwell->pdev);
-                       else
-                               otg_dbg("client driver not loaded.\n");
-
-                       langwell_otg_add_timer(b_bus_suspend_tmr);
-                       langwell->otg.state = OTG_STATE_A_PERIPHERAL;
-                       break;
-               } else if (!langwell->hsm.a_vbus_vld) {
-                       langwell_otg_del_timer(a_aidl_bdis_tmr);
-                       langwell_otg_HABA(0);
-                       free_irq(langwell->pdev->irq, langwell->regs);
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_A_VBUS_ERR;
-               }
-               break;
-       case OTG_STATE_A_PERIPHERAL:
-               if (langwell->hsm.id) {
-                       langwell_otg_del_timer(b_bus_suspend_tmr);
-                       langwell->otg.default_a = 0;
-                       langwell->hsm.b_bus_req = 0;
-                       if (langwell->client_ops)
-                               langwell->client_ops->suspend(langwell->pdev,
-                                       PMSG_FREEZE);
-                       else
-                               otg_dbg("client driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (!langwell->hsm.a_vbus_vld) {
-                       langwell_otg_del_timer(b_bus_suspend_tmr);
-                       if (langwell->client_ops)
-                               langwell->client_ops->suspend(langwell->pdev,
-                                       PMSG_FREEZE);
-                       else
-                               otg_dbg("client driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_A_VBUS_ERR;
-               } else if (langwell->hsm.a_bus_drop) {
-                       langwell_otg_del_timer(b_bus_suspend_tmr);
-                       if (langwell->client_ops)
-                               langwell->client_ops->suspend(langwell->pdev,
-                                       PMSG_FREEZE);
-                       else
-                               otg_dbg("client driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_A_WAIT_VFALL;
-               } else if (langwell->hsm.b_bus_suspend) {
-                       langwell_otg_del_timer(b_bus_suspend_tmr);
-                       if (langwell->client_ops)
-                               langwell->client_ops->suspend(langwell->pdev,
-                                       PMSG_FREEZE);
-                       else
-                               otg_dbg("client driver has been removed.\n");
-
-                       if (langwell->host_ops)
-                               langwell->host_ops->probe(langwell->pdev,
-                                               langwell->host_ops->id_table);
-                       else
-                               otg_dbg("host driver not loaded.\n");
-                       langwell->hsm.a_set_b_hnp_en = 0;
-                       langwell->hsm.a_wait_bcon_tmout = 0;
-                       langwell_otg_add_timer(a_wait_bcon_tmr);
-                       langwell->otg.state = OTG_STATE_A_WAIT_BCON;
-               } else if (langwell->hsm.b_bus_suspend_tmout) {
-                       u32     val;
-                       val = readl(langwell->regs + CI_PORTSC1);
-                       if (!(val & PORTSC_SUSP))
-                               break;
-                       if (langwell->client_ops)
-                               langwell->client_ops->suspend(langwell->pdev,
-                                               PMSG_FREEZE);
-                       else
-                               otg_dbg("client driver has been removed.\n");
-                       if (langwell->host_ops)
-                               langwell->host_ops->probe(langwell->pdev,
-                                               langwell->host_ops->id_table);
-                       else
-                               otg_dbg("host driver not loaded.\n");
-                       langwell->hsm.a_set_b_hnp_en = 0;
-                       langwell->hsm.a_wait_bcon_tmout = 0;
-                       langwell_otg_add_timer(a_wait_bcon_tmr);
-                       langwell->otg.state = OTG_STATE_A_WAIT_BCON;
-               }
-               break;
-       case OTG_STATE_A_VBUS_ERR:
-               if (langwell->hsm.id) {
-                       langwell->otg.default_a = 0;
-                       langwell->hsm.a_clr_err = 0;
-                       langwell->hsm.a_srp_det = 0;
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (langwell->hsm.a_clr_err) {
-                       langwell->hsm.a_clr_err = 0;
-                       langwell->hsm.a_srp_det = 0;
-                       reset_otg();
-                       init_hsm();
-                       if (langwell->otg.state == OTG_STATE_A_IDLE)
-                               queue_work(langwell->qwork, &langwell->work);
-               }
-               break;
-       case OTG_STATE_A_WAIT_VFALL:
-               if (langwell->hsm.id) {
-                       langwell->otg.default_a = 0;
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (langwell->hsm.a_bus_req) {
-                       langwell_otg_drv_vbus(1);
-                       langwell->hsm.a_wait_vrise_tmout = 0;
-                       langwell_otg_add_timer(a_wait_vrise_tmr);
-                       langwell->otg.state = OTG_STATE_A_WAIT_VRISE;
-               } else if (!langwell->hsm.a_sess_vld) {
-                       langwell->hsm.a_srp_det = 0;
-                       langwell_otg_drv_vbus(0);
-                       set_host_mode();
-                       langwell->otg.state = OTG_STATE_A_IDLE;
-               }
-               break;
-       default:
-               ;
-       }
-
-       otg_dbg("%s: new state = %s\n", __func__,
-                       state_string(langwell->otg.state));
-}
-
-       static ssize_t
-show_registers(struct device *_dev, struct device_attribute *attr, char *buf)
-{
-       struct langwell_otg *langwell;
-       char *next;
-       unsigned size;
-       unsigned t;
-
-       langwell = the_transceiver;
-       next = buf;
-       size = PAGE_SIZE;
-
-       t = scnprintf(next, size,
-               "\n"
-               "USBCMD = 0x%08x \n"
-               "USBSTS = 0x%08x \n"
-               "USBINTR = 0x%08x \n"
-               "ASYNCLISTADDR = 0x%08x \n"
-               "PORTSC1 = 0x%08x \n"
-               "HOSTPC1 = 0x%08x \n"
-               "OTGSC = 0x%08x \n"
-               "USBMODE = 0x%08x \n",
-               readl(langwell->regs + 0x30),
-               readl(langwell->regs + 0x34),
-               readl(langwell->regs + 0x38),
-               readl(langwell->regs + 0x48),
-               readl(langwell->regs + 0x74),
-               readl(langwell->regs + 0xb4),
-               readl(langwell->regs + 0xf4),
-               readl(langwell->regs + 0xf8)
-               );
-       size -= t;
-       next += t;
-
-       return PAGE_SIZE - size;
-}
-static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
-
-static ssize_t
-show_hsm(struct device *_dev, struct device_attribute *attr, char *buf)
-{
-       struct langwell_otg *langwell;
-       char *next;
-       unsigned size;
-       unsigned t;
-
-       langwell = the_transceiver;
-       next = buf;
-       size = PAGE_SIZE;
-
-       t = scnprintf(next, size,
-               "\n"
-               "current state = %s\n"
-               "a_bus_resume = \t%d\n"
-               "a_bus_suspend = \t%d\n"
-               "a_conn = \t%d\n"
-               "a_sess_vld = \t%d\n"
-               "a_srp_det = \t%d\n"
-               "a_vbus_vld = \t%d\n"
-               "b_bus_resume = \t%d\n"
-               "b_bus_suspend = \t%d\n"
-               "b_conn = \t%d\n"
-               "b_se0_srp = \t%d\n"
-               "b_sess_end = \t%d\n"
-               "b_sess_vld = \t%d\n"
-               "id = \t%d\n"
-               "a_set_b_hnp_en = \t%d\n"
-               "b_srp_done = \t%d\n"
-               "b_hnp_enable = \t%d\n"
-               "a_wait_vrise_tmout = \t%d\n"
-               "a_wait_bcon_tmout = \t%d\n"
-               "a_aidl_bdis_tmout = \t%d\n"
-               "b_ase0_brst_tmout = \t%d\n"
-               "a_bus_drop = \t%d\n"
-               "a_bus_req = \t%d\n"
-               "a_clr_err = \t%d\n"
-               "a_suspend_req = \t%d\n"
-               "b_bus_req = \t%d\n"
-               "b_bus_suspend_tmout = \t%d\n"
-               "b_bus_suspend_vld = \t%d\n",
-               state_string(langwell->otg.state),
-               langwell->hsm.a_bus_resume,
-               langwell->hsm.a_bus_suspend,
-               langwell->hsm.a_conn,
-               langwell->hsm.a_sess_vld,
-               langwell->hsm.a_srp_det,
-               langwell->hsm.a_vbus_vld,
-               langwell->hsm.b_bus_resume,
-               langwell->hsm.b_bus_suspend,
-               langwell->hsm.b_conn,
-               langwell->hsm.b_se0_srp,
-               langwell->hsm.b_sess_end,
-               langwell->hsm.b_sess_vld,
-               langwell->hsm.id,
-               langwell->hsm.a_set_b_hnp_en,
-               langwell->hsm.b_srp_done,
-               langwell->hsm.b_hnp_enable,
-               langwell->hsm.a_wait_vrise_tmout,
-               langwell->hsm.a_wait_bcon_tmout,
-               langwell->hsm.a_aidl_bdis_tmout,
-               langwell->hsm.b_ase0_brst_tmout,
-               langwell->hsm.a_bus_drop,
-               langwell->hsm.a_bus_req,
-               langwell->hsm.a_clr_err,
-               langwell->hsm.a_suspend_req,
-               langwell->hsm.b_bus_req,
-               langwell->hsm.b_bus_suspend_tmout,
-               langwell->hsm.b_bus_suspend_vld
-               );
-       size -= t;
-       next += t;
-
-       return PAGE_SIZE - size;
-}
-static DEVICE_ATTR(hsm, S_IRUGO, show_hsm, NULL);
-
-static ssize_t
-get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct langwell_otg *langwell;
-       char *next;
-       unsigned size;
-       unsigned t;
-
-       langwell =  the_transceiver;
-       next = buf;
-       size = PAGE_SIZE;
-
-       t = scnprintf(next, size, "%d", langwell->hsm.a_bus_req);
-       size -= t;
-       next += t;
-
-       return PAGE_SIZE - size;
-}
-
-static ssize_t
-set_a_bus_req(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
-{
-       struct langwell_otg *langwell;
-       langwell = the_transceiver;
-       if (!langwell->otg.default_a)
-               return -1;
-       if (count > 2)
-               return -1;
-
-       if (buf[0] == '0') {
-               langwell->hsm.a_bus_req = 0;
-               otg_dbg("a_bus_req = 0\n");
-       } else if (buf[0] == '1') {
-               /* If a_bus_drop is TRUE, a_bus_req can't be set */
-               if (langwell->hsm.a_bus_drop)
-                       return -1;
-               langwell->hsm.a_bus_req = 1;
-               otg_dbg("a_bus_req = 1\n");
-       }
-       if (spin_trylock(&langwell->wq_lock)) {
-               queue_work(langwell->qwork, &langwell->work);
-               spin_unlock(&langwell->wq_lock);
-       }
-       return count;
-}
-static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUGO, get_a_bus_req, set_a_bus_req);
-
-static ssize_t
-get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct langwell_otg *langwell;
-       char *next;
-       unsigned size;
-       unsigned t;
-
-       langwell =  the_transceiver;
-       next = buf;
-       size = PAGE_SIZE;
-
-       t = scnprintf(next, size, "%d", langwell->hsm.a_bus_drop);
-       size -= t;
-       next += t;
-
-       return PAGE_SIZE - size;
-}
-
-static ssize_t
-set_a_bus_drop(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
-{
-       struct langwell_otg *langwell;
-       langwell = the_transceiver;
-       if (!langwell->otg.default_a)
-               return -1;
-       if (count > 2)
-               return -1;
-
-       if (buf[0] == '0') {
-               langwell->hsm.a_bus_drop = 0;
-               otg_dbg("a_bus_drop = 0\n");
-       } else if (buf[0] == '1') {
-               langwell->hsm.a_bus_drop = 1;
-               langwell->hsm.a_bus_req = 0;
-               otg_dbg("a_bus_drop = 1, then a_bus_req = 0\n");
-       }
-       if (spin_trylock(&langwell->wq_lock)) {
-               queue_work(langwell->qwork, &langwell->work);
-               spin_unlock(&langwell->wq_lock);
-       }
-       return count;
-}
-static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUGO,
-       get_a_bus_drop, set_a_bus_drop);
-
-static ssize_t
-get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct langwell_otg *langwell;
-       char *next;
-       unsigned size;
-       unsigned t;
-
-       langwell =  the_transceiver;
-       next = buf;
-       size = PAGE_SIZE;
-
-       t = scnprintf(next, size, "%d", langwell->hsm.b_bus_req);
-       size -= t;
-       next += t;
-
-       return PAGE_SIZE - size;
-}
-
-static ssize_t
-set_b_bus_req(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
-{
-       struct langwell_otg *langwell;
-       langwell = the_transceiver;
-
-       if (langwell->otg.default_a)
-               return -1;
-
-       if (count > 2)
-               return -1;
-
-       if (buf[0] == '0') {
-               langwell->hsm.b_bus_req = 0;
-               otg_dbg("b_bus_req = 0\n");
-       } else if (buf[0] == '1') {
-               langwell->hsm.b_bus_req = 1;
-               otg_dbg("b_bus_req = 1\n");
-       }
-       if (spin_trylock(&langwell->wq_lock)) {
-               queue_work(langwell->qwork, &langwell->work);
-               spin_unlock(&langwell->wq_lock);
-       }
-       return count;
-}
-static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUGO, get_b_bus_req, set_b_bus_req);
-
-static ssize_t
-set_a_clr_err(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
-{
-       struct langwell_otg *langwell;
-       langwell = the_transceiver;
-
-       if (!langwell->otg.default_a)
-               return -1;
-       if (count > 2)
-               return -1;
-
-       if (buf[0] == '1') {
-               langwell->hsm.a_clr_err = 1;
-               otg_dbg("a_clr_err = 1\n");
-       }
-       if (spin_trylock(&langwell->wq_lock)) {
-               queue_work(langwell->qwork, &langwell->work);
-               spin_unlock(&langwell->wq_lock);
-       }
-       return count;
-}
-static DEVICE_ATTR(a_clr_err, S_IWUGO, NULL, set_a_clr_err);
-
-static struct attribute *inputs_attrs[] = {
-       &dev_attr_a_bus_req.attr,
-       &dev_attr_a_bus_drop.attr,
-       &dev_attr_b_bus_req.attr,
-       &dev_attr_a_clr_err.attr,
-       NULL,
-};
-
-static struct attribute_group debug_dev_attr_group = {
-       .name = "inputs",
-       .attrs = inputs_attrs,
-};
-
-int langwell_register_host(struct pci_driver *host_driver)
-{
-       int     ret = 0;
-
-       the_transceiver->host_ops = host_driver;
-       queue_work(the_transceiver->qwork, &the_transceiver->work);
-       otg_dbg("host controller driver is registered\n");
-
-       return ret;
-}
-EXPORT_SYMBOL(langwell_register_host);
-
-void langwell_unregister_host(struct pci_driver *host_driver)
-{
-       if (the_transceiver->host_ops)
-               the_transceiver->host_ops->remove(the_transceiver->pdev);
-       the_transceiver->host_ops = NULL;
-       the_transceiver->hsm.a_bus_drop = 1;
-       queue_work(the_transceiver->qwork, &the_transceiver->work);
-       otg_dbg("host controller driver is unregistered\n");
-}
-EXPORT_SYMBOL(langwell_unregister_host);
-
-int langwell_register_peripheral(struct pci_driver *client_driver)
-{
-       int     ret = 0;
-
-       if (client_driver)
-               ret = client_driver->probe(the_transceiver->pdev,
-                               client_driver->id_table);
-       if (!ret) {
-               the_transceiver->client_ops = client_driver;
-               queue_work(the_transceiver->qwork, &the_transceiver->work);
-               otg_dbg("client controller driver is registered\n");
-       }
-
-       return ret;
-}
-EXPORT_SYMBOL(langwell_register_peripheral);
-
-void langwell_unregister_peripheral(struct pci_driver *client_driver)
-{
-       if (the_transceiver->client_ops)
-               the_transceiver->client_ops->remove(the_transceiver->pdev);
-       the_transceiver->client_ops = NULL;
-       the_transceiver->hsm.b_bus_req = 0;
-       queue_work(the_transceiver->qwork, &the_transceiver->work);
-       otg_dbg("client controller driver is unregistered\n");
-}
-EXPORT_SYMBOL(langwell_unregister_peripheral);
-
-static int langwell_otg_probe(struct pci_dev *pdev,
-               const struct pci_device_id *id)
-{
-       unsigned long           resource, len;
-       void __iomem            *base = NULL;
-       int                     retval;
-       u32                     val32;
-       struct langwell_otg     *langwell;
-       char                    qname[] = "langwell_otg_queue";
-
-       retval = 0;
-       otg_dbg("\notg controller is detected.\n");
-       if (pci_enable_device(pdev) < 0) {
-               retval = -ENODEV;
-               goto done;
-       }
-
-       langwell = kzalloc(sizeof *langwell, GFP_KERNEL);
-       if (langwell == NULL) {
-               retval = -ENOMEM;
-               goto done;
-       }
-       the_transceiver = langwell;
-
-       /* control register: BAR 0 */
-       resource = pci_resource_start(pdev, 0);
-       len = pci_resource_len(pdev, 0);
-       if (!request_mem_region(resource, len, driver_name)) {
-               retval = -EBUSY;
-               goto err;
-       }
-       langwell->region = 1;
-
-       base = ioremap_nocache(resource, len);
-       if (base == NULL) {
-               retval = -EFAULT;
-               goto err;
-       }
-       langwell->regs = base;
-
-       if (!pdev->irq) {
-               otg_dbg("No IRQ.\n");
-               retval = -ENODEV;
-               goto err;
-       }
-
-       langwell->qwork = create_workqueue(qname);
-       if (!langwell->qwork) {
-               otg_dbg("cannot create workqueue %s\n", qname);
-               retval = -ENOMEM;
-               goto err;
-       }
-       INIT_WORK(&langwell->work, langwell_otg_work);
-
-       /* OTG common part */
-       langwell->pdev = pdev;
-       langwell->otg.dev = &pdev->dev;
-       langwell->otg.label = driver_name;
-       langwell->otg.set_host = langwell_otg_set_host;
-       langwell->otg.set_peripheral = langwell_otg_set_peripheral;
-       langwell->otg.set_power = langwell_otg_set_power;
-       langwell->otg.start_srp = langwell_otg_start_srp;
-       langwell->otg.state = OTG_STATE_UNDEFINED;
-       if (otg_set_transceiver(&langwell->otg)) {
-               otg_dbg("can't set transceiver\n");
-               retval = -EBUSY;
-               goto err;
-       }
-
-       reset_otg();
-       init_hsm();
-
-       spin_lock_init(&langwell->lock);
-       spin_lock_init(&langwell->wq_lock);
-       INIT_LIST_HEAD(&active_timers);
-       langwell_otg_init_timers(&langwell->hsm);
-
-       if (request_irq(pdev->irq, otg_irq, IRQF_SHARED,
-                               driver_name, langwell) != 0) {
-               otg_dbg("request interrupt %d failed\n", pdev->irq);
-               retval = -EBUSY;
-               goto err;
-       }
-
-       /* enable OTGSC int */
-       val32 = OTGSC_DPIE | OTGSC_BSEIE | OTGSC_BSVIE |
-               OTGSC_ASVIE | OTGSC_AVVIE | OTGSC_IDIE | OTGSC_IDPU;
-       writel(val32, langwell->regs + CI_OTGSC);
-
-       retval = device_create_file(&pdev->dev, &dev_attr_registers);
-       if (retval < 0) {
-               otg_dbg("Can't register sysfs attribute: %d\n", retval);
-               goto err;
-       }
-
-       retval = device_create_file(&pdev->dev, &dev_attr_hsm);
-       if (retval < 0) {
-               otg_dbg("Can't hsm sysfs attribute: %d\n", retval);
-               goto err;
-       }
-
-       retval = sysfs_create_group(&pdev->dev.kobj, &debug_dev_attr_group);
-       if (retval < 0) {
-               otg_dbg("Can't register sysfs attr group: %d\n", retval);
-               goto err;
-       }
-
-       if (langwell->otg.state == OTG_STATE_A_IDLE)
-               queue_work(langwell->qwork, &langwell->work);
-
-       return 0;
-
-err:
-       if (the_transceiver)
-               langwell_otg_remove(pdev);
-done:
-       return retval;
-}
-
-static void langwell_otg_remove(struct pci_dev *pdev)
-{
-       struct langwell_otg *langwell;
-
-       langwell = the_transceiver;
-
-       if (langwell->qwork) {
-               flush_workqueue(langwell->qwork);
-               destroy_workqueue(langwell->qwork);
-       }
-       langwell_otg_free_timers();
-
-       /* disable OTGSC interrupt as OTGSC doesn't change in reset */
-       writel(0, langwell->regs + CI_OTGSC);
-
-       if (pdev->irq)
-               free_irq(pdev->irq, langwell);
-       if (langwell->regs)
-               iounmap(langwell->regs);
-       if (langwell->region)
-               release_mem_region(pci_resource_start(pdev, 0),
-                               pci_resource_len(pdev, 0));
-
-       otg_set_transceiver(NULL);
-       pci_disable_device(pdev);
-       sysfs_remove_group(&pdev->dev.kobj, &debug_dev_attr_group);
-       device_remove_file(&pdev->dev, &dev_attr_hsm);
-       device_remove_file(&pdev->dev, &dev_attr_registers);
-       kfree(langwell);
-       langwell = NULL;
-}
-
-static void transceiver_suspend(struct pci_dev *pdev)
-{
-       pci_save_state(pdev);
-       pci_set_power_state(pdev, PCI_D3hot);
-       langwell_otg_phy_low_power(1);
-}
-
-static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message)
-{
-       int     ret = 0;
-       struct langwell_otg *langwell;
-
-       langwell = the_transceiver;
-
-       /* Disbale OTG interrupts */
-       langwell_otg_intr(0);
-
-       if (pdev->irq)
-               free_irq(pdev->irq, langwell);
-
-       /* Prevent more otg_work */
-       flush_workqueue(langwell->qwork);
-       spin_lock(&langwell->wq_lock);
-
-       /* start actions */
-       switch (langwell->otg.state) {
-       case OTG_STATE_A_IDLE:
-       case OTG_STATE_B_IDLE:
-       case OTG_STATE_A_WAIT_VFALL:
-       case OTG_STATE_A_VBUS_ERR:
-               transceiver_suspend(pdev);
-               break;
-       case OTG_STATE_A_WAIT_VRISE:
-               langwell_otg_del_timer(a_wait_vrise_tmr);
-               langwell->hsm.a_srp_det = 0;
-               langwell_otg_drv_vbus(0);
-               langwell->otg.state = OTG_STATE_A_IDLE;
-               transceiver_suspend(pdev);
-               break;
-       case OTG_STATE_A_WAIT_BCON:
-               langwell_otg_del_timer(a_wait_bcon_tmr);
-               if (langwell->host_ops)
-                       ret = langwell->host_ops->suspend(pdev, message);
-               langwell_otg_drv_vbus(0);
-               break;
-       case OTG_STATE_A_HOST:
-               if (langwell->host_ops)
-                       ret = langwell->host_ops->suspend(pdev, message);
-               langwell_otg_drv_vbus(0);
-               langwell_otg_phy_low_power(1);
-               break;
-       case OTG_STATE_A_SUSPEND:
-               langwell_otg_del_timer(a_aidl_bdis_tmr);
-               langwell_otg_HABA(0);
-               if (langwell->host_ops)
-                       langwell->host_ops->remove(pdev);
-               else
-                       otg_dbg("host driver has been removed.\n");
-               langwell_otg_drv_vbus(0);
-               transceiver_suspend(pdev);
-               langwell->otg.state = OTG_STATE_A_WAIT_VFALL;
-               break;
-       case OTG_STATE_A_PERIPHERAL:
-               if (langwell->client_ops)
-                       ret = langwell->client_ops->suspend(pdev, message);
-               else
-                       otg_dbg("client driver has been removed.\n");
-               langwell_otg_drv_vbus(0);
-               transceiver_suspend(pdev);
-               langwell->otg.state = OTG_STATE_A_WAIT_VFALL;
-               break;
-       case OTG_STATE_B_HOST:
-               if (langwell->host_ops)
-                       langwell->host_ops->remove(pdev);
-               else
-                       otg_dbg("host driver has been removed.\n");
-               langwell->hsm.b_bus_req = 0;
-               transceiver_suspend(pdev);
-               langwell->otg.state = OTG_STATE_B_IDLE;
-               break;
-       case OTG_STATE_B_PERIPHERAL:
-               if (langwell->client_ops)
-                       ret = langwell->client_ops->suspend(pdev, message);
-               else
-                       otg_dbg("client driver has been removed.\n");
-               break;
-       case OTG_STATE_B_WAIT_ACON:
-               langwell_otg_del_timer(b_ase0_brst_tmr);
-               langwell_otg_HAAR(0);
-               if (langwell->host_ops)
-                       langwell->host_ops->remove(pdev);
-               else
-                       otg_dbg("host driver has been removed.\n");
-               langwell->hsm.b_bus_req = 0;
-               langwell->otg.state = OTG_STATE_B_IDLE;
-               transceiver_suspend(pdev);
-               break;
-       default:
-               otg_dbg("error state before suspend\n ");
-               break;
-       }
-       spin_unlock(&langwell->wq_lock);
-
-       return ret;
-}
-
-static void transceiver_resume(struct pci_dev *pdev)
-{
-       pci_restore_state(pdev);
-       pci_set_power_state(pdev, PCI_D0);
-       langwell_otg_phy_low_power(0);
-}
-
-static int langwell_otg_resume(struct pci_dev *pdev)
-{
-       int     ret = 0;
-       struct langwell_otg *langwell;
-
-       langwell = the_transceiver;
-
-       spin_lock(&langwell->wq_lock);
-
-       switch (langwell->otg.state) {
-       case OTG_STATE_A_IDLE:
-       case OTG_STATE_B_IDLE:
-       case OTG_STATE_A_WAIT_VFALL:
-       case OTG_STATE_A_VBUS_ERR:
-               transceiver_resume(pdev);
-               break;
-       case OTG_STATE_A_WAIT_BCON:
-               langwell_otg_add_timer(a_wait_bcon_tmr);
-               langwell_otg_drv_vbus(1);
-               if (langwell->host_ops)
-                       ret = langwell->host_ops->resume(pdev);
-               break;
-       case OTG_STATE_A_HOST:
-               langwell_otg_drv_vbus(1);
-               langwell_otg_phy_low_power(0);
-               if (langwell->host_ops)
-                       ret = langwell->host_ops->resume(pdev);
-               break;
-       case OTG_STATE_B_PERIPHERAL:
-               if (langwell->client_ops)
-                       ret = langwell->client_ops->resume(pdev);
-               else
-                       otg_dbg("client driver not loaded.\n");
-               break;
-       default:
-               otg_dbg("error state before suspend\n ");
-               break;
-       }
-
-       if (request_irq(pdev->irq, otg_irq, IRQF_SHARED,
-                               driver_name, the_transceiver) != 0) {
-               otg_dbg("request interrupt %d failed\n", pdev->irq);
-               ret = -EBUSY;
-       }
-
-       /* enable OTG interrupts */
-       langwell_otg_intr(1);
-
-       spin_unlock(&langwell->wq_lock);
-
-       queue_work(langwell->qwork, &langwell->work);
-
-
-       return ret;
-}
-
-static int __init langwell_otg_init(void)
-{
-       return pci_register_driver(&otg_pci_driver);
-}
-module_init(langwell_otg_init);
-
-static void __exit langwell_otg_cleanup(void)
-{
-       pci_unregister_driver(&otg_pci_driver);
-}
-module_exit(langwell_otg_cleanup);
index 9ed5ea568679c3715eae4a03700d1ff8bd05e409..af456b48985f06f3ebe09ae43363f47f7d0bfec7 100644 (file)
@@ -53,6 +53,7 @@ EXPORT_SYMBOL(usb_nop_xceiv_register);
 void usb_nop_xceiv_unregister(void)
 {
        platform_device_unregister(pd);
+       pd = NULL;
 }
 EXPORT_SYMBOL(usb_nop_xceiv_unregister);
 
index 247b61bfb7f45f4d179abd6ef36f9611eea046da..0e4f2e41ace5b064193a46d3409d98df9099c117 100644 (file)
@@ -169,9 +169,11 @@ static int usb_console_setup(struct console *co, char *options)
                        kfree(tty);
                }
        }
-       /* So we know not to kill the hardware on a hangup on this
-          port. We have also bumped the use count by one so it won't go
-          idle */
+       /* Now that any required fake tty operations are completed restore
+        * the tty port count */
+       --port->port.count;
+       /* The console is special in terms of closing the device so
+        * indicate this port is now acting as a system console. */
        port->console = 1;
        retval = 0;
 
@@ -204,7 +206,7 @@ static void usb_console_write(struct console *co,
 
        dbg("%s - port %d, %d byte(s)", __func__, port->number, count);
 
-       if (!port->port.count) {
+       if (!port->console) {
                dbg("%s - port not opened", __func__);
                return;
        }
@@ -300,8 +302,7 @@ void usb_serial_console_exit(void)
 {
        if (usbcons_info.port) {
                unregister_console(&usbcons);
-               if (usbcons_info.port->port.count)
-                       usbcons_info.port->port.count--;
+               usbcons_info.port->console = 0;
                usbcons_info.port = NULL;
        }
 }
index 2b9eeda62bfe7beb12a4b3abb8aec6b3954e9f9c..e9a40b820fd4b28eac8053e40efa4082f7880b46 100644 (file)
@@ -67,6 +67,8 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
        { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */
        { USB_DEVICE(0x10C4, 0x0F91) }, /* Vstabi */
+       { USB_DEVICE(0x10C4, 0x1101) }, /* Arkham Technology DS101 Bus Monitor */
+       { USB_DEVICE(0x10C4, 0x1601) }, /* Arkham Technology DS101 Adapter */
        { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */
        { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */
        { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */
index 9734085fd2fee19f99051320db97ae22d867dc1e..59adfe123110b5e3c631f2ffa111d5b3c56680a7 100644 (file)
@@ -1228,8 +1228,8 @@ static void cypress_read_int_callback(struct urb *urb)
                /* precursor to disconnect so just go away */
                return;
        case -EPIPE:
-               usb_clear_halt(port->serial->dev, 0x81);
-               break;
+               /* Can't call usb_clear_halt while in_interrupt */
+               /* FALLS THROUGH */
        default:
                /* something ugly is going on... */
                dev_err(&urb->dev->dev,
index 5a8ae274d2583deebbe699f5439e87295af44bcf..60c64cc5be2ae9dbbcef5720dc537af008839f67 100644 (file)
@@ -108,6 +108,7 @@ struct ftdi_sio_quirk {
 
 static int   ftdi_jtag_probe(struct usb_serial *serial);
 static int   ftdi_mtxorb_hack_setup(struct usb_serial *serial);
+static int   ftdi_NDI_device_setup(struct usb_serial *serial);
 static void  ftdi_USB_UIRT_setup(struct ftdi_private *priv);
 static void  ftdi_HE_TIRA1_setup(struct ftdi_private *priv);
 
@@ -119,6 +120,10 @@ static struct ftdi_sio_quirk ftdi_mtxorb_hack_quirk = {
        .probe  = ftdi_mtxorb_hack_setup,
 };
 
+static struct ftdi_sio_quirk ftdi_NDI_device_quirk = {
+       .probe  = ftdi_NDI_device_setup,
+};
+
 static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
        .port_probe = ftdi_USB_UIRT_setup,
 };
@@ -192,6 +197,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) },
        { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) },
        { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) },
        { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) },
@@ -580,6 +586,9 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_CCSMACHX_2_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_CCSLOAD_N_GO_3_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_CCSICDU64_4_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_CCSPRIME8_5_PID) },
        { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) },
        { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) },
        { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) },
@@ -645,6 +654,16 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) },
        { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID),
+               .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
+       { USB_DEVICE(FTDI_VID, FTDI_NDI_SPECTRA_SCU_PID),
+               .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
+       { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_2_PID),
+               .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
+       { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_3_PID),
+               .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
+       { USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID),
+               .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
        { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) },
@@ -661,6 +680,8 @@ static struct usb_device_id id_table_combined [] = {
                .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
        { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID),
                .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+       { USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID),
+               .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
        { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
        { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) },
        { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) },
@@ -668,7 +689,6 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) },
        { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) },
        { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) },
-       { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID) },
        { USB_DEVICE(ATMEL_VID, STK541_PID) },
        { USB_DEVICE(DE_VID, STB_PID) },
        { USB_DEVICE(DE_VID, WHT_PID) },
@@ -1024,6 +1044,16 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty,
        case FT2232C: /* FT2232C chip */
        case FT232RL:
                if (baud <= 3000000) {
+                       __u16 product_id = le16_to_cpu(
+                               port->serial->dev->descriptor.idProduct);
+                       if (((FTDI_NDI_HUC_PID == product_id) ||
+                            (FTDI_NDI_SPECTRA_SCU_PID == product_id) ||
+                            (FTDI_NDI_FUTURE_2_PID == product_id) ||
+                            (FTDI_NDI_FUTURE_3_PID == product_id) ||
+                            (FTDI_NDI_AURORA_SCU_PID == product_id)) &&
+                           (baud == 19200)) {
+                               baud = 1200000;
+                       }
                        div_value = ftdi_232bm_baud_to_divisor(baud);
                } else {
                        dbg("%s - Baud rate too high!", __func__);
@@ -1554,6 +1584,39 @@ static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv)
        priv->force_rtscts = 1;
 } /* ftdi_HE_TIRA1_setup */
 
+/*
+ * Module parameter to control latency timer for NDI FTDI-based USB devices.
+ * If this value is not set in modprobe.conf.local its value will be set to 1ms.
+ */
+static int ndi_latency_timer = 1;
+
+/* Setup for the NDI FTDI-based USB devices, which requires hardwired
+ * baudrate (19200 gets mapped to 1200000).
+ *
+ * Called from usbserial:serial_probe.
+ */
+static int ftdi_NDI_device_setup(struct usb_serial *serial)
+{
+       struct usb_device *udev = serial->dev;
+       int latency = ndi_latency_timer;
+       int rv = 0;
+       char buf[1];
+
+       if (latency == 0)
+               latency = 1;
+       if (latency > 99)
+               latency = 99;
+
+       dbg("%s setting NDI device latency to %d", __func__, latency);
+       dev_info(&udev->dev, "NDI device with a latency value of %d", latency);
+
+       rv = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+                               FTDI_SIO_SET_LATENCY_TIMER_REQUEST,
+                               FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE,
+                               latency, 0, buf, 0, WDR_TIMEOUT);
+       return 0;
+}
+
 /*
  * First port on JTAG adaptors such as Olimex arm-usb-ocd or the FIC/OpenMoko
  * Neo1973 Debug Board is reserved for JTAG interface and can be accessed from
@@ -2623,3 +2686,5 @@ MODULE_PARM_DESC(vendor, "User specified vendor ID (default="
 module_param(product, ushort, 0);
 MODULE_PARM_DESC(product, "User specified product ID");
 
+module_param(ndi_latency_timer, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(ndi_latency_timer, "NDI device latency timer override");
index f1d440a728a376770617ad7776a52eba590cc282..c9fbd74150929d6849b773bf10d5cb8b7d92ffe1 100644 (file)
  *
  * Armin Laeuger originally sent the PID for the UM 100 module.
  */
+#define FTDI_R2000KU_TRUE_RNG  0xFB80  /* R2000KU TRUE RNG */
 #define FTDI_ELV_UR100_PID     0xFB58  /* USB-RS232-Umsetzer (UR 100) */
 #define FTDI_ELV_UM100_PID     0xFB5A  /* USB-Modul UM 100 */
 #define FTDI_ELV_UO100_PID     0xFB5B  /* USB-Modul UO 100 */
 #define FTDI_CCSICDU20_0_PID    0xF9D0
 #define FTDI_CCSICDU40_1_PID    0xF9D1
 #define FTDI_CCSMACHX_2_PID     0xF9D2
+#define FTDI_CCSLOAD_N_GO_3_PID 0xF9D3
+#define FTDI_CCSICDU64_4_PID    0xF9D4
+#define FTDI_CCSPRIME8_5_PID    0xF9D5
 
 /* Inside Accesso contactless reader (http://www.insidefr.com) */
 #define INSIDE_ACCESSO         0xFAD0
 /* Pyramid Computer GmbH */
 #define FTDI_PYRAMID_PID       0xE6C8  /* Pyramid Appliance Display */
 
+/*
+ * NDI (www.ndigital.com) product ids
+ */
+#define FTDI_NDI_HUC_PID               0xDA70  /* NDI Host USB Converter */
+#define FTDI_NDI_SPECTRA_SCU_PID       0xDA71  /* NDI Spectra SCU */
+#define FTDI_NDI_FUTURE_2_PID          0xDA72  /* NDI future device #2 */
+#define FTDI_NDI_FUTURE_3_PID          0xDA73  /* NDI future device #3 */
+#define FTDI_NDI_AURORA_SCU_PID                0xDA74  /* NDI Aurora SCU */
+
 /*
  * Posiflex inc retail equipment (http://www.posiflex.com.tw)
  */
 #define TML_VID                        0x1B91  /* Vendor ID */
 #define TML_USB_SERIAL_PID     0x0064  /* USB - Serial Converter */
 
-/* NDI Polaris System */
-#define FTDI_NDI_HUC_PID        0xDA70
-
 /* Propox devices */
 #define FTDI_PROPOX_JTAGCABLEII_PID    0xD738
 
 #define MARVELL_VID            0x9e88
 #define MARVELL_SHEEVAPLUG_PID 0x9e8f
 
+#define FTDI_TURTELIZER_PID    0xBDC8 /* JTAG/RS-232 adapter by egnite GmBH */
+
 /*
  *   BmRequestType:  1100 0000b
  *   bRequest:       FTDI_E2_READ
index 575816e6ba371fb4ef5fbeeba3668e559b86bfe2..98262dd552bb58c8b4d3b487b7dfb285cc9d64da 100644 (file)
@@ -206,6 +206,7 @@ static int  option_resume(struct usb_serial *serial);
 #define NOVATELWIRELESS_PRODUCT_MC950D         0x4400
 #define NOVATELWIRELESS_PRODUCT_U727           0x5010
 #define NOVATELWIRELESS_PRODUCT_MC760          0x6000
+#define NOVATELWIRELESS_PRODUCT_OVMC760                0x6002
 
 /* FUTURE NOVATEL PRODUCTS */
 #define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001
@@ -307,11 +308,20 @@ static int  option_resume(struct usb_serial *serial);
 #define DLINK_VENDOR_ID                                0x1186
 #define DLINK_PRODUCT_DWM_652                  0x3e04
 
+#define QISDA_VENDOR_ID                                0x1da5
+#define QISDA_PRODUCT_H21_4512                 0x4512
+#define QISDA_PRODUCT_H21_4523                 0x4523
+#define QISDA_PRODUCT_H20_4515                 0x4515
+#define QISDA_PRODUCT_H20_4519                 0x4519
+
 
 /* TOSHIBA PRODUCTS */
 #define TOSHIBA_VENDOR_ID                      0x0930
 #define TOSHIBA_PRODUCT_HSDPA_MINICARD         0x1302
 
+#define ALINK_VENDOR_ID                                0x1e0e
+#define ALINK_PRODUCT_3GU                      0x9200
+
 static struct usb_device_id option_ids[] = {
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -430,6 +440,7 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC760) }, /* Novatel MC760/U760/USB760 */
+       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_OVMC760) }, /* Novatel Ovation MC760 */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */
@@ -529,8 +540,13 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) },
        { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
        { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },
-       { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */
+       { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) },
+       { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) },
+       { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) },
+       { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4519) },
        { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */
+       { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
        { } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
@@ -732,7 +748,6 @@ static int option_write(struct tty_struct *tty, struct usb_serial_port *port,
                memcpy(this_urb->transfer_buffer, buf, todo);
                this_urb->transfer_buffer_length = todo;
 
-               this_urb->dev = port->serial->dev;
                err = usb_submit_urb(this_urb, GFP_ATOMIC);
                if (err) {
                        dbg("usb_submit_urb %p (write bulk) failed "
@@ -860,7 +875,6 @@ static void option_instat_callback(struct urb *urb)
 
        /* Resubmit urb so we continue receiving IRQ data */
        if (status != -ESHUTDOWN && status != -ENOENT) {
-               urb->dev = serial->dev;
                err = usb_submit_urb(urb, GFP_ATOMIC);
                if (err)
                        dbg("%s: resubmit intr urb failed. (%d)",
@@ -921,23 +935,11 @@ static int option_open(struct tty_struct *tty,
 
        dbg("%s", __func__);
 
-       /* Reset low level data toggle and start reading from endpoints */
+       /* Start reading from the IN endpoint */
        for (i = 0; i < N_IN_URB; i++) {
                urb = portdata->in_urbs[i];
                if (!urb)
                        continue;
-               if (urb->dev != serial->dev) {
-                       dbg("%s: dev %p != %p", __func__,
-                               urb->dev, serial->dev);
-                       continue;
-               }
-
-               /*
-                * make sure endpoint data toggle is synchronized with the
-                * device
-                */
-               usb_clear_halt(urb->dev, urb->pipe);
-
                err = usb_submit_urb(urb, GFP_KERNEL);
                if (err) {
                        dbg("%s: submit urb %d failed (%d) %d",
@@ -946,16 +948,6 @@ static int option_open(struct tty_struct *tty,
                }
        }
 
-       /* Reset low level data toggle on out endpoints */
-       for (i = 0; i < N_OUT_URB; i++) {
-               urb = portdata->out_urbs[i];
-               if (!urb)
-                       continue;
-               urb->dev = serial->dev;
-               /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
-                               usb_pipeout(urb->pipe), 0); */
-       }
-
        option_send_setup(port);
 
        return 0;
@@ -1218,7 +1210,6 @@ static int option_resume(struct usb_serial *serial)
                        dbg("%s: No interrupt URB for port %d\n", __func__, i);
                        continue;
                }
-               port->interrupt_in_urb->dev = serial->dev;
                err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
                dbg("Submitted interrupt URB for port %d (result %d)", i, err);
                if (err < 0) {
index efaf59c4f5d010685e0f00cfdd46efb4136c1f24..7d15bfa7c2dbfeb1c19768a2499ee2178d14efe0 100644 (file)
@@ -94,6 +94,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) },
        { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) },
        { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },
+       { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
        { }                                     /* Terminating entry */
 };
 
index 1d7a22e3a9fd1daa5df3c239185670763e7a5563..12aac7d2462dab327105a2fcf1f5344672efe121 100644 (file)
 /* Hewlett-Packard LD220-HP POS Pole Display */
 #define HP_VENDOR_ID           0x03f0
 #define HP_LD220_PRODUCT_ID    0x3524
+
+/* Cressi Edy (diving computer) PC interface */
+#define CRESSI_VENDOR_ID       0x04b8
+#define CRESSI_EDY_PRODUCT_ID  0x0521
index 032f7aeb40a42b17b71b1f4c2ae7b3d1ff221640..f48d05e0acc135e89a5e4a7518f3d1364b07e35d 100644 (file)
@@ -181,35 +181,50 @@ static const struct sierra_iface_info direct_ip_interface_blacklist = {
 };
 
 static struct usb_device_id id_table [] = {
+       { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
+       { USB_DEVICE(0x03F0, 0x1B1D) }, /* HP ev2200 a.k.a MC5720 */
+       { USB_DEVICE(0x03F0, 0x1E1D) }, /* HP hs2300 a.k.a MC8775 */
+
        { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
        { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */
        { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
-       { USB_DEVICE(0x03f0, 0x1b1d) }, /* HP ev2200 a.k.a MC5720 */
        { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
-       { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */
        { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */
+       { USB_DEVICE(0x1199, 0x0022) }, /* Sierra Wireless EM5725 */
+       { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */
+       { USB_DEVICE(0x1199, 0x0224) }, /* Sierra Wireless MC5727 */
        { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
        { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
+       { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
        { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */
-        /* Sierra Wireless C597 */
+       /* Sierra Wireless C597 */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) },
-        /* Sierra Wireless Device */
+       /* Sierra Wireless T598 */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) },
-       { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless Device */
-       { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless Device */
-       { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless Device */
+       { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless T11 */
+       { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless AC402 */
+       { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless MC5728 */
+       { USB_DEVICE(0x1199, 0x0029) }, /* Sierra Wireless Device */
 
        { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
-       { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
        { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */
+       { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
+       { USB_DEVICE(0x1199, 0x6805) }, /* Sierra Wireless MC8765 */
+       { USB_DEVICE(0x1199, 0x6808) }, /* Sierra Wireless MC8755 */
+       { USB_DEVICE(0x1199, 0x6809) }, /* Sierra Wireless MC8765 */
        { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */
-       { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 (Lenovo) */
+       { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 */
        { USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */
-       { USB_DEVICE(0x03f0, 0x1e1d) }, /* HP hs2300 a.k.a MC8775 */
+       { USB_DEVICE(0x1199, 0x6816) }, /* Sierra Wireless MC8775 */
        { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */
        { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */
+       { USB_DEVICE(0x1199, 0x6822) }, /* Sierra Wireless AirCard 875E */
        { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */
        { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */
+       { USB_DEVICE(0x1199, 0x6834) }, /* Sierra Wireless MC8780 */
+       { USB_DEVICE(0x1199, 0x6835) }, /* Sierra Wireless MC8781 */
+       { USB_DEVICE(0x1199, 0x6838) }, /* Sierra Wireless MC8780 */
+       { USB_DEVICE(0x1199, 0x6839) }, /* Sierra Wireless MC8781 */
        { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */
        { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */
        /* Sierra Wireless MC8790, MC8791, MC8792 Composite */
@@ -227,16 +242,13 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */
        /* Sierra Wireless C885 */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)},
-       /* Sierra Wireless Device */
+       /* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)},
-       /* Sierra Wireless Device */
+       /* Sierra Wireless C22/C33 */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6891, 0xFF, 0xFF, 0xFF)},
-       /* Sierra Wireless Device */
+       /* Sierra Wireless HSPA Non-Composite Device */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},
-
-       { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
-       { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
-
+       { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */
        { USB_DEVICE(0x1199, 0x68A3),   /* Sierra Wireless Direct IP modems */
          .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
        },
@@ -814,7 +826,7 @@ static int sierra_startup(struct usb_serial *serial)
        return 0;
 }
 
-static void sierra_disconnect(struct usb_serial *serial)
+static void sierra_release(struct usb_serial *serial)
 {
        int i;
        struct usb_serial_port *port;
@@ -830,7 +842,6 @@ static void sierra_disconnect(struct usb_serial *serial)
                if (!portdata)
                        continue;
                kfree(portdata);
-               usb_set_serial_port_data(port, NULL);
        }
 }
 
@@ -853,7 +864,7 @@ static struct usb_serial_driver sierra_device = {
        .tiocmget          = sierra_tiocmget,
        .tiocmset          = sierra_tiocmset,
        .attach            = sierra_startup,
-       .disconnect        = sierra_disconnect,
+       .release           = sierra_release,
        .read_int_callback = sierra_instat_callback,
 };
 
index 991d8232e3765c39de562ec8e09181d0e8d4c547..14971a926990575aa6afd30c5c364d4b7f1e8539 100644 (file)
@@ -191,7 +191,6 @@ static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
        { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
-       { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
 };
 
 static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = {
@@ -1658,7 +1657,7 @@ static int ti_do_download(struct usb_device *dev, int pipe,
        u8 cs = 0;
        int done;
        struct ti_firmware_header *header;
-       int status;
+       int status = 0;
        int len;
 
        for (pos = sizeof(struct ti_firmware_header); pos < size; pos++)
index 0c39b55aeef4f4ff75a1cf3827d833ab6e3314c8..bd7581b3a48afd3beb2f3eeef28ca604c8c08842 100644 (file)
@@ -221,7 +221,8 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
        tty->driver_data = port;
        tty_port_tty_set(&port->port, tty);
 
-       if (port->port.count == 1) {
+       /* If the console is attached, the device is already open */
+       if (port->port.count == 1 && !port->console) {
 
                /* lock this module before we call it
                 * this may fail, which means we must bail out,
index d41cc0a970f79a147660da239bdc014612396354..773a5cd38c5aa7773f5b7f1837351a8945b3f084 100644 (file)
@@ -118,6 +118,9 @@ static int option_inquiry(struct us_data *us)
 
        result = memcmp(buffer+8, "Option", 6);
 
+       if (result != 0)
+               result = memcmp(buffer+8, "ZCOPTION", 8);
+
        /* Read the CSW */
        usb_stor_bulk_transfer_buf(us,
                        us->recv_bulk_pipe,
index 84929e9140341583cbc8fd7050c4e5e5a12b8d29..b1e3c2fbfe1170fdd8fc4cdb023d628b1a0b4a43 100644 (file)
@@ -888,8 +888,6 @@ struct usb_driver {
  * struct usb_device_driver - identifies USB device driver to usbcore
  * @name: The driver name should be unique among USB drivers,
  *     and should normally be the same as the module name.
- * @nodename: Callback to provide a naming hint for a possible
- *     device node to create.
  * @probe: Called to see if the driver is willing to manage a particular
  *     device.  If it is, probe returns zero and uses dev_set_drvdata()
  *     to associate driver-specific data with the device.  If unwilling
@@ -924,6 +922,8 @@ extern struct bus_type usb_bus_type;
 /**
  * struct usb_class_driver - identifies a USB driver that wants to use the USB major number
  * @name: the usb class device name for this driver.  Will show up in sysfs.
+ * @nodename: Callback to provide a naming hint for a possible
+ *     device node to create.
  * @fops: pointer to the struct file_operations of this driver.
  * @minor_base: the start of the minor range for this driver.
  *
@@ -1046,6 +1046,8 @@ typedef void (*usb_complete_t)(struct urb *);
  *     the device driver is saying that it provided this DMA address,
  *     which the host controller driver should use in preference to the
  *     transfer_buffer.
+ * @sg: scatter gather buffer list
+ * @num_sgs: number of entries in the sg list
  * @transfer_buffer_length: How big is transfer_buffer.  The transfer may
  *     be broken up into chunks according to the current maximum packet
  *     size for the endpoint, which is a function of the configuration
diff --git a/include/linux/usb/langwell_otg.h b/include/linux/usb/langwell_otg.h
deleted file mode 100644 (file)
index e115ae6..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Intel Langwell USB OTG transceiver driver
- * Copyright (C) 2008, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef __LANGWELL_OTG_H__
-#define __LANGWELL_OTG_H__
-
-/* notify transceiver driver about OTG events */
-extern void langwell_update_transceiver(void);
-/* HCD register bus driver */
-extern int langwell_register_host(struct pci_driver *host_driver);
-/* HCD unregister bus driver */
-extern void langwell_unregister_host(struct pci_driver *host_driver);
-/* DCD register bus driver */
-extern int langwell_register_peripheral(struct pci_driver *client_driver);
-/* DCD unregister bus driver */
-extern void langwell_unregister_peripheral(struct pci_driver *client_driver);
-/* No silent failure, output warning message */
-extern void langwell_otg_nsf_msg(unsigned long message);
-
-#define CI_USBCMD              0x30
-#      define USBCMD_RST               BIT(1)
-#      define USBCMD_RS                BIT(0)
-#define CI_USBSTS              0x34
-#      define USBSTS_SLI               BIT(8)
-#      define USBSTS_URI               BIT(6)
-#      define USBSTS_PCI               BIT(2)
-#define CI_PORTSC1             0x74
-#      define PORTSC_PP                BIT(12)
-#      define PORTSC_LS                (BIT(11) | BIT(10))
-#      define PORTSC_SUSP              BIT(7)
-#      define PORTSC_CCS               BIT(0)
-#define CI_HOSTPC1             0xb4
-#      define HOSTPC1_PHCD             BIT(22)
-#define CI_OTGSC               0xf4
-#      define OTGSC_DPIE               BIT(30)
-#      define OTGSC_1MSE               BIT(29)
-#      define OTGSC_BSEIE              BIT(28)
-#      define OTGSC_BSVIE              BIT(27)
-#      define OTGSC_ASVIE              BIT(26)
-#      define OTGSC_AVVIE              BIT(25)
-#      define OTGSC_IDIE               BIT(24)
-#      define OTGSC_DPIS               BIT(22)
-#      define OTGSC_1MSS               BIT(21)
-#      define OTGSC_BSEIS              BIT(20)
-#      define OTGSC_BSVIS              BIT(19)
-#      define OTGSC_ASVIS              BIT(18)
-#      define OTGSC_AVVIS              BIT(17)
-#      define OTGSC_IDIS               BIT(16)
-#      define OTGSC_DPS                BIT(14)
-#      define OTGSC_1MST               BIT(13)
-#      define OTGSC_BSE                BIT(12)
-#      define OTGSC_BSV                BIT(11)
-#      define OTGSC_ASV                BIT(10)
-#      define OTGSC_AVV                BIT(9)
-#      define OTGSC_ID                 BIT(8)
-#      define OTGSC_HABA               BIT(7)
-#      define OTGSC_HADP               BIT(6)
-#      define OTGSC_IDPU               BIT(5)
-#      define OTGSC_DP                 BIT(4)
-#      define OTGSC_OT                 BIT(3)
-#      define OTGSC_HAAR               BIT(2)
-#      define OTGSC_VC                 BIT(1)
-#      define OTGSC_VD                 BIT(0)
-#      define OTGSC_INTEN_MASK         (0x7f << 24)
-#      define OTGSC_INTSTS_MASK        (0x7f << 16)
-#define CI_USBMODE             0xf8
-#      define USBMODE_CM               (BIT(1) | BIT(0))
-#      define USBMODE_IDLE             0
-#      define USBMODE_DEVICE           0x2
-#      define USBMODE_HOST             0x3
-
-#define INTR_DUMMY_MASK (USBSTS_SLI | USBSTS_URI | USBSTS_PCI)
-
-struct otg_hsm {
-       /* Input */
-       int a_bus_resume;
-       int a_bus_suspend;
-       int a_conn;
-       int a_sess_vld;
-       int a_srp_det;
-       int a_vbus_vld;
-       int b_bus_resume;
-       int b_bus_suspend;
-       int b_conn;
-       int b_se0_srp;
-       int b_sess_end;
-       int b_sess_vld;
-       int id;
-
-       /* Internal variables */
-       int a_set_b_hnp_en;
-       int b_srp_done;
-       int b_hnp_enable;
-
-       /* Timeout indicator for timers */
-       int a_wait_vrise_tmout;
-       int a_wait_bcon_tmout;
-       int a_aidl_bdis_tmout;
-       int b_ase0_brst_tmout;
-       int b_bus_suspend_tmout;
-       int b_srp_res_tmout;
-
-       /* Informative variables */
-       int a_bus_drop;
-       int a_bus_req;
-       int a_clr_err;
-       int a_suspend_req;
-       int b_bus_req;
-
-       /* Output */
-       int drv_vbus;
-       int loc_conn;
-       int loc_sof;
-
-       /* Others */
-       int b_bus_suspend_vld;
-};
-
-#define TA_WAIT_VRISE  100
-#define TA_WAIT_BCON   30000
-#define TA_AIDL_BDIS   15000
-#define TB_ASE0_BRST   5000
-#define TB_SE0_SRP     2
-#define TB_SRP_RES     100
-#define TB_BUS_SUSPEND 500
-
-struct langwell_otg_timer {
-       unsigned long expires;  /* Number of count increase to timeout */
-       unsigned long count;    /* Tick counter */
-       void (*function)(unsigned long);        /* Timeout function */
-       unsigned long data;     /* Data passed to function */
-       struct list_head list;
-};
-
-struct langwell_otg {
-       struct otg_transceiver  otg;
-       struct otg_hsm          hsm;
-       void __iomem            *regs;
-       unsigned                region;
-       struct pci_driver       *host_ops;
-       struct pci_driver       *client_ops;
-       struct pci_dev          *pdev;
-       struct work_struct      work;
-       struct workqueue_struct *qwork;
-       spinlock_t              lock;
-       spinlock_t              wq_lock;
-};
-
-static inline struct langwell_otg *otg_to_langwell(struct otg_transceiver *otg)
-{
-       return container_of(otg, struct langwell_otg, otg);
-}
-
-#ifdef DEBUG
-#define otg_dbg(fmt, args...) \
-       printk(KERN_DEBUG fmt , ## args)
-#else
-#define otg_dbg(fmt, args...) \
-       do { } while (0)
-#endif /* DEBUG */
-#endif /* __LANGWELL_OTG_H__ */