Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 21 Jan 2010 15:35:43 +0000 (07:35 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 21 Jan 2010 15:35:43 +0000 (07:35 -0800)
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6:
  USB: isp1362: fix build failure on ARM systems via irq_flags cleanup
  USB: isp1362: better 64bit printf warning fixes
  USB: fix usbstorage for 2770:915d delivers no FAT
  USB: Fix level of isp1760 Reloading ptd error message
  USB: FHCI: avoid NULL pointer dereference
  USB: Fix duplicate sysfs problem after device reset.
  USB: add speed values for USB 3.0 and wireless controllers
  USB: add missing delay during remote wakeup
  USB: EHCI & UHCI: fix race between root-hub suspend and port resume
  USB: EHCI: fix handling of unusual interrupt intervals
  USB: Don't use GFP_KERNEL while we cannot reset a storage device
  USB: fix bitmask merge error
  usb: serial: fix memory leak in generic driver
  USB: serial: fix USB serial fix kfifo_len locking

17 files changed:
drivers/usb/core/devices.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/core/message.c
drivers/usb/core/sysfs.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-q.c
drivers/usb/host/fhci-hcd.c
drivers/usb/host/isp1362-hcd.c
drivers/usb/host/isp1760-hcd.c
drivers/usb/host/uhci-hcd.c
drivers/usb/host/uhci-hub.c
drivers/usb/serial/generic.c
drivers/usb/storage/unusual_devs.h
drivers/usb/storage/usb.c
include/linux/usb.h

index 96f11715cd269b4cb8594c12c4c027ae50350af8..355dffcc23b0f33a341e53d8b27218b175f7e221 100644 (file)
@@ -494,7 +494,7 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
                return 0;
        /* allocate 2^1 pages = 8K (on i386);
         * should be more than enough for one device */
-       pages_start = (char *)__get_free_pages(GFP_KERNEL, 1);
+       pages_start = (char *)__get_free_pages(GFP_NOIO, 1);
        if (!pages_start)
                return -ENOMEM;
 
index 0495fa651225546836af7ac78bad141df77eaf91..80995ef0868c17e553dd6575a951b71973df27f1 100644 (file)
@@ -1684,6 +1684,24 @@ int usb_hcd_alloc_bandwidth(struct usb_device *udev,
                }
        }
        if (cur_alt && new_alt) {
+               struct usb_interface *iface = usb_ifnum_to_if(udev,
+                               cur_alt->desc.bInterfaceNumber);
+
+               if (iface->resetting_device) {
+                       /*
+                        * The USB core just reset the device, so the xHCI host
+                        * and the device will think alt setting 0 is installed.
+                        * However, the USB core will pass in the alternate
+                        * setting installed before the reset as cur_alt.  Dig
+                        * out the alternate setting 0 structure, or the first
+                        * alternate setting if a broken device doesn't have alt
+                        * setting 0.
+                        */
+                       cur_alt = usb_altnum_to_altsetting(iface, 0);
+                       if (!cur_alt)
+                               cur_alt = &iface->altsetting[0];
+               }
+
                /* Drop all the endpoints in the current alt setting */
                for (i = 0; i < cur_alt->desc.bNumEndpoints; i++) {
                        ret = hcd->driver->drop_endpoint(hcd, udev,
index 0cec6caf6e9b26ca385927c6e6b19b67fabbfae2..35cc8b9ba1f5bfab21331d6241a529ca2b3de304 100644 (file)
@@ -3347,6 +3347,9 @@ static void hub_events(void)
                                        USB_PORT_FEAT_C_SUSPEND);
                                udev = hdev->children[i-1];
                                if (udev) {
+                                       /* TRSMRCY = 10 msec */
+                                       msleep(10);
+
                                        usb_lock_device(udev);
                                        ret = remote_wakeup(hdev->
                                                        children[i-1]);
@@ -3692,19 +3695,14 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
                        usb_enable_interface(udev, intf, true);
                        ret = 0;
                } else {
-                       /* We've just reset the device, so it will think alt
-                        * setting 0 is installed.  For usb_set_interface() to
-                        * work properly, we need to set the current alternate
-                        * interface setting to 0 (or the first alt setting, if
-                        * the device doesn't have alt setting 0).
+                       /* Let the bandwidth allocation function know that this
+                        * device has been reset, and it will have to use
+                        * alternate setting 0 as the current alternate setting.
                         */
-                       intf->cur_altsetting =
-                               usb_find_alt_setting(config, i, 0);
-                       if (!intf->cur_altsetting)
-                               intf->cur_altsetting =
-                                       &config->intf_cache[i]->altsetting[0];
+                       intf->resetting_device = 1;
                        ret = usb_set_interface(udev, desc->bInterfaceNumber,
                                        desc->bAlternateSetting);
+                       intf->resetting_device = 0;
                }
                if (ret < 0) {
                        dev_err(&udev->dev, "failed to restore interface %d "
index 1b994846e8e01bec12219873eb6926e97cbc3e81..9bc95fec793fa674727d19c53820853c128afabb 100644 (file)
@@ -906,11 +906,11 @@ char *usb_cache_string(struct usb_device *udev, int index)
        if (index <= 0)
                return NULL;
 
-       buf = kmalloc(MAX_USB_STRING_SIZE, GFP_KERNEL);
+       buf = kmalloc(MAX_USB_STRING_SIZE, GFP_NOIO);
        if (buf) {
                len = usb_string(udev, index, buf, MAX_USB_STRING_SIZE);
                if (len > 0) {
-                       smallbuf = kmalloc(++len, GFP_KERNEL);
+                       smallbuf = kmalloc(++len, GFP_NOIO);
                        if (!smallbuf)
                                return buf;
                        memcpy(smallbuf, buf, len);
@@ -1731,7 +1731,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
        if (cp) {
                nintf = cp->desc.bNumInterfaces;
                new_interfaces = kmalloc(nintf * sizeof(*new_interfaces),
-                               GFP_KERNEL);
+                               GFP_NOIO);
                if (!new_interfaces) {
                        dev_err(&dev->dev, "Out of memory\n");
                        return -ENOMEM;
@@ -1740,7 +1740,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
                for (; n < nintf; ++n) {
                        new_interfaces[n] = kzalloc(
                                        sizeof(struct usb_interface),
-                                       GFP_KERNEL);
+                                       GFP_NOIO);
                        if (!new_interfaces[n]) {
                                dev_err(&dev->dev, "Out of memory\n");
                                ret = -ENOMEM;
index 485edf937f257ae846b921eae465f2655841f1b7..5f3908f6e2dc12f455b9036da9621478976a3dd9 100644 (file)
@@ -115,6 +115,12 @@ show_speed(struct device *dev, struct device_attribute *attr, char *buf)
        case USB_SPEED_HIGH:
                speed = "480";
                break;
+       case USB_SPEED_VARIABLE:
+               speed = "480";
+               break;
+       case USB_SPEED_SUPER:
+               speed = "5000";
+               break;
        default:
                speed = "unknown";
        }
index 5859522d6edd9f0dde4fc8241d5398b0f4381698..1ec3857f22e65c3cb9474529eea85e62a377b722 100644 (file)
@@ -787,9 +787,10 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
 
                        /* start 20 msec resume signaling from this port,
                         * and make khubd collect PORT_STAT_C_SUSPEND to
-                        * stop that signaling.
+                        * stop that signaling.  Use 5 ms extra for safety,
+                        * like usb_port_resume() does.
                         */
-                       ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
+                       ehci->reset_done[i] = jiffies + msecs_to_jiffies(25);
                        ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
                        mod_timer(&hcd->rh_timer, ehci->reset_done[i]);
                }
index 2c6571c05f35c99398d973382680137f56363dcb..c75d9270c752921ee8751e2106ce522c6db2ee85 100644 (file)
@@ -120,9 +120,26 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
        del_timer_sync(&ehci->watchdog);
        del_timer_sync(&ehci->iaa_watchdog);
 
-       port = HCS_N_PORTS (ehci->hcs_params);
        spin_lock_irq (&ehci->lock);
 
+       /* Once the controller is stopped, port resumes that are already
+        * in progress won't complete.  Hence if remote wakeup is enabled
+        * for the root hub and any ports are in the middle of a resume or
+        * remote wakeup, we must fail the suspend.
+        */
+       if (hcd->self.root_hub->do_remote_wakeup) {
+               port = HCS_N_PORTS(ehci->hcs_params);
+               while (port--) {
+                       if (ehci->reset_done[port] != 0) {
+                               spin_unlock_irq(&ehci->lock);
+                               ehci_dbg(ehci, "suspend failed because "
+                                               "port %d is resuming\n",
+                                               port + 1);
+                               return -EBUSY;
+                       }
+               }
+       }
+
        /* stop schedules, clean any completed work */
        if (HC_IS_RUNNING(hcd->state)) {
                ehci_quiesce (ehci);
@@ -138,6 +155,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
         */
        ehci->bus_suspended = 0;
        ehci->owned_ports = 0;
+       port = HCS_N_PORTS(ehci->hcs_params);
        while (port--) {
                u32 __iomem     *reg = &ehci->regs->port_status [port];
                u32             t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
index a427d3b0063468659bd73351ecf6aba86e9210fb..89521775c567abeaeb856e2ca3106ec4996ef9e0 100644 (file)
@@ -849,9 +849,10 @@ qh_make (
                                 * But interval 1 scheduling is simpler, and
                                 * includes high bandwidth.
                                 */
-                               dbg ("intr period %d uframes, NYET!",
-                                               urb->interval);
-                               goto done;
+                               urb->interval = 1;
+                       } else if (qh->period > ehci->periodic_size) {
+                               qh->period = ehci->periodic_size;
+                               urb->interval = qh->period << 3;
                        }
                } else {
                        int             think_time;
@@ -874,6 +875,10 @@ qh_make (
                                        usb_calc_bus_time (urb->dev->speed,
                                        is_input, 0, max_packet (maxp)));
                        qh->period = urb->interval;
+                       if (qh->period > ehci->periodic_size) {
+                               qh->period = ehci->periodic_size;
+                               urb->interval = qh->period;
+                       }
                }
        }
 
index 0951818ef93b8838651597b3acef7795a193eca3..78e7c3cfcb7282757d85fc331de14ab559580e4c 100644 (file)
@@ -242,9 +242,10 @@ err:
 static void fhci_usb_free(void *lld)
 {
        struct fhci_usb *usb = lld;
-       struct fhci_hcd *fhci = usb->fhci;
+       struct fhci_hcd *fhci;
 
        if (usb) {
+               fhci = usb->fhci;
                fhci_config_transceiver(fhci, FHCI_PORT_POWER_OFF);
                fhci_ep0_free(usb);
                kfree(usb->actual_frame);
index 73352f3739b5ee654cdcd24f0be85495eeebcc58..42971657fde2953f2d7798e5b45d4d14796fb16d 100644 (file)
@@ -2270,10 +2270,10 @@ static int isp1362_mem_config(struct usb_hcd *hcd)
        dev_info(hcd->self.controller, "ISP1362 Memory usage:\n");
        dev_info(hcd->self.controller, "  ISTL:    2 * %4d:     %4d @ $%04x:$%04x\n",
                 istl_size / 2, istl_size, 0, istl_size / 2);
-       dev_info(hcd->self.controller, "  INTL: %4d * (%3lu+8):  %4d @ $%04x\n",
+       dev_info(hcd->self.controller, "  INTL: %4d * (%3zu+8):  %4d @ $%04x\n",
                 ISP1362_INTL_BUFFERS, intl_blksize - PTD_HEADER_SIZE,
                 intl_size, istl_size);
-       dev_info(hcd->self.controller, "  ATL : %4d * (%3lu+8):  %4d @ $%04x\n",
+       dev_info(hcd->self.controller, "  ATL : %4d * (%3zu+8):  %4d @ $%04x\n",
                 atl_buffers, atl_blksize - PTD_HEADER_SIZE,
                 atl_size, istl_size + intl_size);
        dev_info(hcd->self.controller, "  USED/FREE:   %4d      %4d\n", total,
@@ -2697,6 +2697,8 @@ static int __init isp1362_probe(struct platform_device *pdev)
        void __iomem *data_reg;
        int irq;
        int retval = 0;
+       struct resource *irq_res;
+       unsigned int irq_flags = 0;
 
        /* basic sanity checks first.  board-specific init logic should
         * have initialized this the three resources and probably board
@@ -2710,11 +2712,12 @@ static int __init isp1362_probe(struct platform_device *pdev)
 
        data = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        addr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-       irq = platform_get_irq(pdev, 0);
-       if (!addr || !data || irq < 0) {
+       irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (!addr || !data || !irq_res) {
                retval = -ENODEV;
                goto err1;
        }
+       irq = irq_res->start;
 
 #ifdef CONFIG_USB_HCD_DMA
        if (pdev->dev.dma_mask) {
@@ -2781,12 +2784,16 @@ static int __init isp1362_probe(struct platform_device *pdev)
        }
 #endif
 
-#ifdef CONFIG_ARM
-       if (isp1362_hcd->board)
-               set_irq_type(irq, isp1362_hcd->board->int_act_high ? IRQT_RISING : IRQT_FALLING);
-#endif
+       if (irq_res->flags & IORESOURCE_IRQ_HIGHEDGE)
+               irq_flags |= IRQF_TRIGGER_RISING;
+       if (irq_res->flags & IORESOURCE_IRQ_LOWEDGE)
+               irq_flags |= IRQF_TRIGGER_FALLING;
+       if (irq_res->flags & IORESOURCE_IRQ_HIGHLEVEL)
+               irq_flags |= IRQF_TRIGGER_HIGH;
+       if (irq_res->flags & IORESOURCE_IRQ_LOWLEVEL)
+               irq_flags |= IRQF_TRIGGER_LOW;
 
-       retval = usb_add_hcd(hcd, irq, IRQF_TRIGGER_LOW | IRQF_DISABLED | IRQF_SHARED);
+       retval = usb_add_hcd(hcd, irq, irq_flags | IRQF_DISABLED | IRQF_SHARED);
        if (retval != 0)
                goto err6;
        pr_info("%s, irq %d\n", hcd->product_desc, irq);
index 9600a58299db3f8c29ac575fccda0d97dacccbc2..27b8f7cb4471e8399f8262feaca409388b11957f 100644 (file)
@@ -1039,12 +1039,12 @@ static void do_atl_int(struct usb_hcd *usb_hcd)
                if (!nakcount && (dw3 & DW3_QTD_ACTIVE)) {
                        u32 buffstatus;
 
-                       /* XXX
+                       /*
                         * NAKs are handled in HW by the chip. Usually if the
                         * device is not able to send data fast enough.
-                        * This did not trigger for a long time now.
+                        * This happens mostly on slower hardware.
                         */
-                       printk(KERN_ERR "Reloading ptd %p/%p... qh %p readed: "
+                       printk(KERN_NOTICE "Reloading ptd %p/%p... qh %p read: "
                                        "%d of %zu done: %08x cur: %08x\n", qtd,
                                        urb, qh, PTD_XFERRED_LENGTH(dw3),
                                        qtd->length, done_map,
index 5cd0e48f67fb13b3df18ed077cd72a76995ae10c..99cd00fd3514c7f25abb0b42977e14c61edbb6ca 100644 (file)
@@ -749,7 +749,20 @@ static int uhci_rh_suspend(struct usb_hcd *hcd)
        spin_lock_irq(&uhci->lock);
        if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
                rc = -ESHUTDOWN;
-       else if (!uhci->dead)
+       else if (uhci->dead)
+               ;               /* Dead controllers tell no tales */
+
+       /* Once the controller is stopped, port resumes that are already
+        * in progress won't complete.  Hence if remote wakeup is enabled
+        * for the root hub and any ports are in the middle of a resume or
+        * remote wakeup, we must fail the suspend.
+        */
+       else if (hcd->self.root_hub->do_remote_wakeup &&
+                       uhci->resuming_ports) {
+               dev_dbg(uhci_dev(uhci), "suspend failed because a port "
+                               "is resuming\n");
+               rc = -EBUSY;
+       } else
                suspend_rh(uhci, UHCI_RH_SUSPENDED);
        spin_unlock_irq(&uhci->lock);
        return rc;
index 885b585360b967f23661c015dd8945371f5fa058..8270055848cacd2a8e32379d873b1f624006db71 100644 (file)
@@ -167,7 +167,7 @@ static void uhci_check_ports(struct uhci_hcd *uhci)
                                /* Port received a wakeup request */
                                set_bit(port, &uhci->resuming_ports);
                                uhci->ports_timeout = jiffies +
-                                               msecs_to_jiffies(20);
+                                               msecs_to_jiffies(25);
 
                                /* Make sure we see the port again
                                 * after the resuming period is over. */
index f1ea3a33b6e6378ad767e7c4783cebf8defb34a6..83443d6306d60e03f5b60ea0f9c4b70ae01f292b 100644 (file)
@@ -386,12 +386,12 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
 
        dbg("%s - port %d", __func__, port->number);
 
-       if (serial->type->max_in_flight_urbs) {
-               spin_lock_irqsave(&port->lock, flags);
+       spin_lock_irqsave(&port->lock, flags);
+       if (serial->type->max_in_flight_urbs)
                chars = port->tx_bytes_flight;
-               spin_unlock_irqrestore(&port->lock, flags);
-       } else if (serial->num_bulk_out)
+       else if (serial->num_bulk_out)
                chars = kfifo_len(&port->write_fifo);
+       spin_unlock_irqrestore(&port->lock, flags);
 
        dbg("%s - returns %d", __func__, chars);
        return chars;
@@ -489,6 +489,8 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb)
        dbg("%s - port %d", __func__, port->number);
 
        if (port->serial->type->max_in_flight_urbs) {
+               kfree(urb->transfer_buffer);
+
                spin_lock_irqsave(&port->lock, flags);
                --port->urbs_in_flight;
                port->tx_bytes_flight -= urb->transfer_buffer_length;
index 64a0a2c27e12b4478734ae9683fead5750abfe67..c932f9053188b32857a6b331ad188b3d88b97706 100644 (file)
@@ -1807,13 +1807,6 @@ UNUSUAL_DEV(  0x2735, 0x100b, 0x0000, 0x9999,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_GO_SLOW ),
 
-/* Reported by Rohan Hart <rohan.hart17@gmail.com> */
-UNUSUAL_DEV(  0x2770, 0x915d, 0x0010, 0x0010,
-               "INTOVA",
-               "Pixtreme",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY ),
-
 /* Reported by Frederic Marchal <frederic.marchal@wowcompany.com>
  * Mio Moov 330
  */
index 5a53d4f0dd11cb547f58430afc17c8501ef4a8a7..e9f995486ec1b1fa46021ed0bd3202044d0a425a 100644 (file)
@@ -434,7 +434,8 @@ static void adjust_quirks(struct us_data *us)
        u16 vid = le16_to_cpu(us->pusb_dev->descriptor.idVendor);
        u16 pid = le16_to_cpu(us->pusb_dev->descriptor.idProduct);
        unsigned f = 0;
-       unsigned int mask = (US_FL_SANE_SENSE | US_FL_FIX_CAPACITY |
+       unsigned int mask = (US_FL_SANE_SENSE | US_FL_BAD_SENSE |
+                       US_FL_FIX_CAPACITY |
                        US_FL_CAPACITY_HEURISTICS | US_FL_IGNORE_DEVICE |
                        US_FL_NOT_LOCKABLE | US_FL_MAX_SECTORS_64 |
                        US_FL_CAPACITY_OK | US_FL_IGNORE_RESIDUE |
index e101a2d04d7588843083bfd466831e4fb807347e..d7ace1b80f09d0936c1f2f23e8a62b82f1c5baa7 100644 (file)
@@ -192,6 +192,7 @@ struct usb_interface {
        unsigned needs_altsetting0:1;   /* switch to altsetting 0 is pending */
        unsigned needs_binding:1;       /* needs delayed unbind/rebind */
        unsigned reset_running:1;
+       unsigned resetting_device:1;    /* true: bandwidth alloc after reset */
 
        struct device dev;              /* interface specific device info */
        struct device *usb_dev;