diff options
Diffstat (limited to 'drivers/usb')
68 files changed, 667 insertions, 582 deletions
diff --git a/drivers/usb/chipidea/ci_hdrc_pci.c b/drivers/usb/chipidea/ci_hdrc_pci.c index 241ae34..4df6694 100644 --- a/drivers/usb/chipidea/ci_hdrc_pci.c +++ b/drivers/usb/chipidea/ci_hdrc_pci.c @@ -111,6 +111,9 @@ static void ci_hdrc_pci_remove(struct pci_dev *pdev) * PCI device structure * * Check "pci.h" for details + * + * Note: ehci-pci driver may try to probe the device first. You have to add an + * ID to the bypass_pci_id_table in ehci-pci driver to prevent this. */ static const struct pci_device_id ci_hdrc_pci_id_table[] = { { diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 546a17e8..e78720b 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1091,6 +1091,7 @@ static int acm_probe(struct usb_interface *intf, unsigned long quirks; int num_rx_buf; int i; + unsigned int elength = 0; int combined_interfaces = 0; struct device *tty_dev; int rv = -ENOMEM; @@ -1136,9 +1137,12 @@ static int acm_probe(struct usb_interface *intf, dev_err(&intf->dev, "skipping garbage\n"); goto next_desc; } + elength = buffer[0]; switch (buffer[2]) { case USB_CDC_UNION_TYPE: /* we've found it */ + if (elength < sizeof(struct usb_cdc_union_desc)) + goto next_desc; if (union_header) { dev_err(&intf->dev, "More than one " "union descriptor, skipping ...\n"); @@ -1147,29 +1151,36 @@ static int acm_probe(struct usb_interface *intf, union_header = (struct usb_cdc_union_desc *)buffer; break; case USB_CDC_COUNTRY_TYPE: /* export through sysfs*/ + if (elength < sizeof(struct usb_cdc_country_functional_desc)) + goto next_desc; cfd = (struct usb_cdc_country_functional_desc *)buffer; break; case USB_CDC_HEADER_TYPE: /* maybe check version */ break; /* for now we ignore it */ case USB_CDC_ACM_TYPE: + if (elength < 4) + goto next_desc; ac_management_function = buffer[3]; break; case USB_CDC_CALL_MANAGEMENT_TYPE: + if (elength < 5) + goto next_desc; call_management_function = buffer[3]; call_interface_num = buffer[4]; break; default: - /* there are LOTS more CDC descriptors that + /* + * there are LOTS more CDC descriptors that * could legitimately be found here. */ dev_dbg(&intf->dev, "Ignoring descriptor: " - "type %02x, length %d\n", - buffer[2], buffer[0]); + "type %02x, length %ud\n", + buffer[2], elength); break; } next_desc: - buflen -= buffer[0]; - buffer += buffer[0]; + buflen -= elength; + buffer += elength; } if (!union_header) { @@ -1287,10 +1298,8 @@ made_compressed_probe: dev_dbg(&intf->dev, "interfaces are valid\n"); acm = kzalloc(sizeof(struct acm), GFP_KERNEL); - if (acm == NULL) { - dev_err(&intf->dev, "out of memory (acm kzalloc)\n"); + if (acm == NULL) goto alloc_fail; - } minor = acm_alloc_minor(acm); if (minor == ACM_TTY_MINORS) { @@ -1329,42 +1338,32 @@ made_compressed_probe: acm->quirks = quirks; buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); - if (!buf) { - dev_err(&intf->dev, "out of memory (ctrl buffer alloc)\n"); + if (!buf) goto alloc_fail2; - } acm->ctrl_buffer = buf; - if (acm_write_buffers_alloc(acm) < 0) { - dev_err(&intf->dev, "out of memory (write buffer alloc)\n"); + if (acm_write_buffers_alloc(acm) < 0) goto alloc_fail4; - } acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); - if (!acm->ctrlurb) { - dev_err(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); + if (!acm->ctrlurb) goto alloc_fail5; - } + for (i = 0; i < num_rx_buf; i++) { struct acm_rb *rb = &(acm->read_buffers[i]); struct urb *urb; rb->base = usb_alloc_coherent(acm->dev, readsize, GFP_KERNEL, &rb->dma); - if (!rb->base) { - dev_err(&intf->dev, "out of memory " - "(read bufs usb_alloc_coherent)\n"); + if (!rb->base) goto alloc_fail6; - } rb->index = i; rb->instance = acm; urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) { - dev_err(&intf->dev, - "out of memory (read urbs usb_alloc_urb)\n"); + if (!urb) goto alloc_fail6; - } + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; urb->transfer_dma = rb->dma; if (acm->is_int_ep) { @@ -1389,11 +1388,8 @@ made_compressed_probe: struct acm_wb *snd = &(acm->wb[i]); snd->urb = usb_alloc_urb(0, GFP_KERNEL); - if (snd->urb == NULL) { - dev_err(&intf->dev, - "out of memory (write urbs usb_alloc_urb)\n"); + if (snd->urb == NULL) goto alloc_fail7; - } if (usb_endpoint_xfer_int(epwrite)) usb_fill_int_urb(snd->urb, usb_dev, diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index 684ef70..506b969 100644 --- a/drivers/usb/core/buffer.c +++ b/drivers/usb/core/buffer.c @@ -22,17 +22,25 @@ */ /* FIXME tune these based on pool statistics ... */ -static const size_t pool_max[HCD_BUFFER_POOLS] = { - /* platforms without dma-friendly caches might need to - * prevent cacheline sharing... - */ - 32, - 128, - 512, - PAGE_SIZE / 2 - /* bigger --> allocate pages */ +static size_t pool_max[HCD_BUFFER_POOLS] = { + 32, 128, 512, 2048, }; +void __init usb_init_pool_max(void) +{ + /* + * The pool_max values must never be smaller than + * ARCH_KMALLOC_MINALIGN. + */ + if (ARCH_KMALLOC_MINALIGN <= 32) + ; /* Original value is okay */ + else if (ARCH_KMALLOC_MINALIGN <= 64) + pool_max[0] = 64; + else if (ARCH_KMALLOC_MINALIGN <= 128) + pool_max[0] = 0; /* Don't use this pool */ + else + BUILD_BUG(); /* We don't allow this */ +} /* SETUP primitives */ diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 0b59731..66abdbc 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1689,7 +1689,7 @@ static struct async *reap_as(struct usb_dev_state *ps) for (;;) { __set_current_state(TASK_INTERRUPTIBLE); as = async_getcompleted(ps); - if (as) + if (as || !connected(ps)) break; if (signal_pending(current)) break; @@ -1712,7 +1712,7 @@ static int proc_reapurb(struct usb_dev_state *ps, void __user *arg) } if (signal_pending(current)) return -EINTR; - return -EIO; + return -ENODEV; } static int proc_reapurbnonblock(struct usb_dev_state *ps, void __user *arg) @@ -1721,10 +1721,11 @@ static int proc_reapurbnonblock(struct usb_dev_state *ps, void __user *arg) struct async *as; as = async_getcompleted(ps); - retval = -EAGAIN; if (as) { retval = processcompl(as, (void __user * __user *)arg); free_async(as); + } else { + retval = (connected(ps) ? -EAGAIN : -ENODEV); } return retval; } @@ -1854,7 +1855,7 @@ static int proc_reapurb_compat(struct usb_dev_state *ps, void __user *arg) } if (signal_pending(current)) return -EINTR; - return -EIO; + return -ENODEV; } static int proc_reapurbnonblock_compat(struct usb_dev_state *ps, void __user *arg) @@ -1862,11 +1863,12 @@ static int proc_reapurbnonblock_compat(struct usb_dev_state *ps, void __user *ar int retval; struct async *as; - retval = -EAGAIN; as = async_getcompleted(ps); if (as) { retval = processcompl_compat(as, (void __user * __user *)arg); free_async(as); + } else { + retval = (connected(ps) ? -EAGAIN : -ENODEV); } return retval; } @@ -2038,7 +2040,8 @@ static int proc_get_capabilities(struct usb_dev_state *ps, void __user *arg) { __u32 caps; - caps = USBDEVFS_CAP_ZERO_PACKET | USBDEVFS_CAP_NO_PACKET_SIZE_LIM; + caps = USBDEVFS_CAP_ZERO_PACKET | USBDEVFS_CAP_NO_PACKET_SIZE_LIM | + USBDEVFS_CAP_REAP_AFTER_DISCONNECT; if (!ps->dev->bus->no_stop_on_short) caps |= USBDEVFS_CAP_BULK_CONTINUATION; if (ps->dev->bus->sg_tablesize) @@ -2138,6 +2141,32 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd, return -EPERM; usb_lock_device(dev); + + /* Reap operations are allowed even after disconnection */ + switch (cmd) { + case USBDEVFS_REAPURB: + snoop(&dev->dev, "%s: REAPURB\n", __func__); + ret = proc_reapurb(ps, p); + goto done; + + case USBDEVFS_REAPURBNDELAY: + snoop(&dev->dev, "%s: REAPURBNDELAY\n", __func__); + ret = proc_reapurbnonblock(ps, p); + goto done; + +#ifdef CONFIG_COMPAT + case USBDEVFS_REAPURB32: + snoop(&dev->dev, "%s: REAPURB32\n", __func__); + ret = proc_reapurb_compat(ps, p); + goto done; + + case USBDEVFS_REAPURBNDELAY32: + snoop(&dev->dev, "%s: REAPURBNDELAY32\n", __func__); + ret = proc_reapurbnonblock_compat(ps, p); + goto done; +#endif + } + if (!connected(ps)) { usb_unlock_device(dev); return -ENODEV; @@ -2231,16 +2260,6 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd, inode->i_mtime = CURRENT_TIME; break; - case USBDEVFS_REAPURB32: - snoop(&dev->dev, "%s: REAPURB32\n", __func__); - ret = proc_reapurb_compat(ps, p); - break; - - case USBDEVFS_REAPURBNDELAY32: - snoop(&dev->dev, "%s: REAPURBNDELAY32\n", __func__); - ret = proc_reapurbnonblock_compat(ps, p); - break; - case USBDEVFS_IOCTL32: snoop(&dev->dev, "%s: IOCTL32\n", __func__); ret = proc_ioctl_compat(ps, ptr_to_compat(p)); @@ -2252,16 +2271,6 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd, ret = proc_unlinkurb(ps, p); break; - case USBDEVFS_REAPURB: - snoop(&dev->dev, "%s: REAPURB\n", __func__); - ret = proc_reapurb(ps, p); - break; - - case USBDEVFS_REAPURBNDELAY: - snoop(&dev->dev, "%s: REAPURBNDELAY\n", __func__); - ret = proc_reapurbnonblock(ps, p); - break; - case USBDEVFS_DISCSIGNAL: snoop(&dev->dev, "%s: DISCSIGNAL\n", __func__); ret = proc_disconnectsignal(ps, p); @@ -2304,6 +2313,8 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd, ret = proc_free_streams(ps, p); break; } + + done: usb_unlock_device(dev); if (ret >= 0) inode->i_atime = CURRENT_TIME; diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 874dec3..818369a 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -275,21 +275,6 @@ static int usb_unbind_device(struct device *dev) return 0; } -/* - * Cancel any pending scheduled resets - * - * [see usb_queue_reset_device()] - * - * Called after unconfiguring / when releasing interfaces. See - * comments in __usb_queue_reset_device() regarding - * udev->reset_running. - */ -static void usb_cancel_queued_reset(struct usb_interface *iface) -{ - if (iface->reset_running == 0) - cancel_work_sync(&iface->reset_ws); -} - /* called from driver core with dev locked */ static int usb_probe_interface(struct device *dev) { @@ -380,7 +365,6 @@ static int usb_probe_interface(struct device *dev) usb_set_intfdata(intf, NULL); intf->needs_remote_wakeup = 0; intf->condition = USB_INTERFACE_UNBOUND; - usb_cancel_queued_reset(intf); /* If the LPM disable succeeded, balance the ref counts. */ if (!lpm_disable_error) @@ -425,7 +409,6 @@ static int usb_unbind_interface(struct device *dev) usb_disable_interface(udev, intf, false); driver->disconnect(intf); - usb_cancel_queued_reset(intf); /* Free streams */ for (i = 0, j = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { @@ -1797,6 +1780,18 @@ static int autosuspend_check(struct usb_device *udev) dev_dbg(&udev->dev, "remote wakeup needed for autosuspend\n"); return -EOPNOTSUPP; } + + /* + * If the device is a direct child of the root hub and the HCD + * doesn't handle wakeup requests, don't allow autosuspend when + * wakeup is needed. + */ + if (w && udev->parent == udev->bus->root_hub && + bus_to_hcd(udev->bus)->cant_recv_wakeups) { + dev_dbg(&udev->dev, "HCD doesn't handle wakeup requests\n"); + return -EOPNOTSUPP; + } + udev->do_remote_wakeup = w; return 0; } diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 11cee55..45a915c 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1618,6 +1618,7 @@ static int unlink1(struct usb_hcd *hcd, struct urb *urb, int status) int usb_hcd_unlink_urb (struct urb *urb, int status) { struct usb_hcd *hcd; + struct usb_device *udev = urb->dev; int retval = -EIDRM; unsigned long flags; @@ -1629,20 +1630,19 @@ int usb_hcd_unlink_urb (struct urb *urb, int status) spin_lock_irqsave(&hcd_urb_unlink_lock, flags); if (atomic_read(&urb->use_count) > 0) { retval = 0; - usb_get_dev(urb->dev); + usb_get_dev(udev); } spin_unlock_irqrestore(&hcd_urb_unlink_lock, flags); if (retval == 0) { hcd = bus_to_hcd(urb->dev->bus); retval = unlink1(hcd, urb, status); - usb_put_dev(urb->dev); + if (retval == 0) + retval = -EINPROGRESS; + else if (retval != -EIDRM && retval != -EBUSY) + dev_dbg(&udev->dev, "hcd_unlink_urb %p fail %d\n", + urb, retval); + usb_put_dev(udev); } - - if (retval == 0) - retval = -EINPROGRESS; - else if (retval != -EIDRM && retval != -EBUSY) - dev_dbg(&urb->dev->dev, "hcd_unlink_urb %p fail %d\n", - urb, retval); return retval; } diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index aeb50bb..58d2cde 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2896,10 +2896,12 @@ static int port_is_suspended(struct usb_hub *hub, unsigned portstatus) */ static int check_port_resume_type(struct usb_device *udev, struct usb_hub *hub, int port1, - int status, unsigned portchange, unsigned portstatus) + int status, u16 portchange, u16 portstatus) { struct usb_port *port_dev = hub->ports[port1 - 1]; + int retries = 3; + retry: /* Is a warm reset needed to recover the connection? */ if (status == 0 && udev->reset_resume && hub_port_warm_reset_required(hub, port1, portstatus)) { @@ -2907,10 +2909,17 @@ static int check_port_resume_type(struct usb_device *udev, } /* Is the device still present? */ else if (status || port_is_suspended(hub, portstatus) || - !port_is_power_on(hub, portstatus) || - !(portstatus & USB_PORT_STAT_CONNECTION)) { + !port_is_power_on(hub, portstatus)) { if (status >= 0) status = -ENODEV; + } else if (!(portstatus & USB_PORT_STAT_CONNECTION)) { + if (retries--) { + usleep_range(200, 300); + status = hub_port_status(hub, port1, &portstatus, + &portchange); + goto retry; + } + status = -ENODEV; } /* Can't do a normal resume if the port isn't enabled, @@ -4655,9 +4664,13 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, if (!(portstatus & USB_PORT_STAT_CONNECTION) || test_bit(port1, hub->removed_bits)) { - /* maybe switch power back on (e.g. root hub was reset) */ + /* + * maybe switch power back on (e.g. root hub was reset) + * but only if the port isn't owned by someone else. + */ if (hub_is_port_power_switchable(hub) - && !port_is_power_on(hub, portstatus)) + && !port_is_power_on(hub, portstatus) + && !port_dev->port_owner) set_port_feature(hdev, port1, USB_PORT_FEAT_POWER); if (portstatus & USB_PORT_STAT_ENABLE) @@ -4882,7 +4895,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, static void port_event(struct usb_hub *hub, int port1) __must_hold(&port_dev->status_lock) { - int connect_change, reset_device = 0; + int connect_change; struct usb_port *port_dev = hub->ports[port1 - 1]; struct usb_device *udev = port_dev->child; struct usb_device *hdev = hub->hdev; @@ -4970,30 +4983,14 @@ static void port_event(struct usb_hub *hub, int port1) if (hub_port_reset(hub, port1, NULL, HUB_BH_RESET_TIME, true) < 0) hub_port_disable(hub, port1, 1); - } else - reset_device = 1; - } - - /* - * On disconnect USB3 protocol ports transit from U0 to - * SS.Inactive to Rx.Detect. If this happens a warm- - * reset is not needed, but a (re)connect may happen - * before hub_wq runs and sees the disconnect, and the - * device may be an unknown state. - * - * If the port went through SS.Inactive without hub_wq - * seeing it the C_LINK_STATE change flag will be set, - * and we reset the dev to put it in a known state. - */ - if (reset_device || (udev && hub_is_superspeed(hub->hdev) - && (portchange & USB_PORT_STAT_C_LINK_STATE) - && (portstatus & USB_PORT_STAT_CONNECTION))) { - usb_unlock_port(port_dev); - usb_lock_device(udev); - usb_reset_device(udev); - usb_unlock_device(udev); - usb_lock_port(port_dev); - connect_change = 0; + } else { + usb_unlock_port(port_dev); + usb_lock_device(udev); + usb_reset_device(udev); + usb_unlock_device(udev); + usb_lock_port(port_dev); + connect_change = 0; + } } if (connect_change) @@ -5589,26 +5586,19 @@ EXPORT_SYMBOL_GPL(usb_reset_device); * possible; depending on how the driver attached to each interface * handles ->pre_reset(), the second reset might happen or not. * - * - If a driver is unbound and it had a pending reset, the reset will - * be cancelled. - * - * - This function can be called during .probe() or .disconnect() - * times. On return from .disconnect(), any pending resets will be - * cancelled. - * - * There is no no need to lock/unlock the @reset_ws as schedule_work() - * does its own. + * - If the reset is delayed so long that the interface is unbound from + * its driver, the reset will be skipped. * - * NOTE: We don't do any reference count tracking because it is not - * needed. The lifecycle of the work_struct is tied to the - * usb_interface. Before destroying the interface we cancel the - * work_struct, so the fact that work_struct is queued and or - * running means the interface (and thus, the device) exist and - * are referenced. + * - This function can be called during .probe(). It can also be called + * during .disconnect(), but doing so is pointless because the reset + * will not occur. If you really want to reset the device during + * .disconnect(), call usb_reset_device() directly -- but watch out + * for nested unbinding issues! */ void usb_queue_reset_device(struct usb_interface *iface) { - schedule_work(&iface->reset_ws); + if (schedule_work(&iface->reset_ws)) + usb_get_intf(iface); } EXPORT_SYMBOL_GPL(usb_queue_reset_device); diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f7b7713..f368d20 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1551,6 +1551,7 @@ static void usb_release_interface(struct device *dev) altsetting_to_usb_interface_cache(intf->altsetting); kref_put(&intfc->ref, usb_release_interface_cache); + usb_put_dev(interface_to_usbdev(intf)); kfree(intf); } @@ -1626,24 +1627,6 @@ static struct usb_interface_assoc_descriptor *find_iad(struct usb_device *dev, /* * Internal function to queue a device reset - * - * This is initialized into the workstruct in 'struct - * usb_device->reset_ws' that is launched by - * message.c:usb_set_configuration() when initializing each 'struct - * usb_interface'. - * - * It is safe to get the USB device without reference counts because - * the life cycle of @iface is bound to the life cycle of @udev. Then, - * this function will be ran only if @iface is alive (and before - * freeing it any scheduled instances of it will have been cancelled). - * - * We need to set a flag (usb_dev->reset_running) because when we call - * the reset, the interfaces might be unbound. The current interface - * cannot try to remove the queued work as it would cause a deadlock - * (you cannot remove your work from within your executing - * workqueue). This flag lets it know, so that - * usb_cancel_queued_reset() doesn't try to do it. - * * See usb_queue_reset_device() for more details */ static void __usb_queue_reset_device(struct work_struct *ws) @@ -1655,11 +1638,10 @@ static void __usb_queue_reset_device(struct work_struct *ws) rc = usb_lock_device_for_reset(udev, iface); if (rc >= 0) { - iface->reset_running = 1; usb_reset_device(udev); - iface->reset_running = 0; usb_unlock_device(udev); } + usb_put_intf(iface); /* Undo _get_ in usb_queue_reset_device() */ } @@ -1854,6 +1836,7 @@ free_interfaces: dev_set_name(&intf->dev, "%d-%s:%d.%d", dev->bus->busnum, dev->devpath, configuration, alt->desc.bInterfaceNumber); + usb_get_dev(dev); } kfree(new_interfaces); diff --git a/drivers/usb/core/otg_whitelist.h b/drivers/usb/core/otg_whitelist.h index de0c9c9..a6315ab 100644 --- a/drivers/usb/core/otg_whitelist.h +++ b/drivers/usb/core/otg_whitelist.h @@ -55,6 +55,11 @@ static int is_targeted(struct usb_device *dev) le16_to_cpu(dev->descriptor.idProduct) == 0xbadd)) return 0; + /* OTG PET device is always targeted (see OTG 2.0 ECN 6.4.2) */ + if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a && + le16_to_cpu(dev->descriptor.idProduct) == 0x0200)) + return 1; + /* NOTE: can't use usb_match_id() since interface caches * aren't set up yet. this is cut/paste from that code. */ diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 0ffb4ed..41e510a 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -179,6 +179,10 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x0b05, 0x17e0), .driver_info = USB_QUIRK_IGNORE_REMOTE_WAKEUP }, + /* Protocol and OTG Electrical Test Device */ + { USB_DEVICE(0x1a0a, 0x0200), .driver_info = + USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, + { } /* terminating entry must be last */ }; diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 2a92b97..b1fb9ae 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -1049,6 +1049,7 @@ static int __init usb_init(void) pr_info("%s: USB support disabled\n", usbcore_name); return 0; } + usb_init_pool_max(); retval = usb_debugfs_init(); if (retval) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index ad43c5b..02e3e2d 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -476,13 +476,13 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) u32 gintsts; irqreturn_t retval = IRQ_NONE; + spin_lock(&hsotg->lock); + if (!dwc2_is_controller_alive(hsotg)) { dev_warn(hsotg->dev, "Controller is dead\n"); goto out; } - spin_lock(&hsotg->lock); - gintsts = dwc2_read_common_intr(hsotg); if (gintsts & ~GINTSTS_PRTINT) retval = IRQ_HANDLED; @@ -515,8 +515,8 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) } } - spin_unlock(&hsotg->lock); out: + spin_unlock(&hsotg->lock); return retval; } EXPORT_SYMBOL_GPL(dwc2_handle_common_intr); diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 3de291b6..5ad60e4 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -219,7 +219,7 @@ config USB_EHCI_TEGRA config USB_EHCI_HCD_PPC_OF bool "EHCI support for PPC USB controller on OF platform bus" - depends on PPC_OF + depends on PPC default y ---help--- Enables support for the USB controller present on the PowerPC @@ -480,7 +480,7 @@ config USB_OHCI_ATH79 config USB_OHCI_HCD_PPC_OF_BE bool "OHCI support for OF platform bus (big endian)" - depends on PPC_OF + depends on PPC select USB_OHCI_BIG_ENDIAN_DESC select USB_OHCI_BIG_ENDIAN_MMIO ---help--- @@ -489,7 +489,7 @@ config USB_OHCI_HCD_PPC_OF_BE config USB_OHCI_HCD_PPC_OF_LE bool "OHCI support for OF platform bus (little endian)" - depends on PPC_OF + depends on PPC select USB_OHCI_LITTLE_ENDIAN ---help--- Enables support for little-endian USB controllers present on the @@ -497,7 +497,7 @@ config USB_OHCI_HCD_PPC_OF_LE config USB_OHCI_HCD_PPC_OF bool - depends on PPC_OF + depends on PPC default USB_OHCI_HCD_PPC_OF_BE || USB_OHCI_HCD_PPC_OF_LE config USB_OHCI_HCD_PCI diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index 56a8850..663f790 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -27,44 +27,66 @@ #define DRIVER_DESC "EHCI Atmel driver" static const char hcd_name[] = "ehci-atmel"; -static struct hc_driver __read_mostly ehci_atmel_hc_driver; /* interface and function clocks */ -static struct clk *iclk, *fclk, *uclk; -static int clocked; +#define hcd_to_atmel_ehci_priv(h) \ + ((struct atmel_ehci_priv *)hcd_to_ehci(h)->priv) + +struct atmel_ehci_priv { + struct clk *iclk; + struct clk *fclk; + struct clk *uclk; + bool clocked; +}; + +static struct hc_driver __read_mostly ehci_atmel_hc_driver; + +static const struct ehci_driver_overrides ehci_atmel_drv_overrides __initconst = { + .extra_priv_size = sizeof(struct atmel_ehci_priv), +}; /*-------------------------------------------------------------------------*/ -static void atmel_start_clock(void) +static void atmel_start_clock(struct atmel_ehci_priv *atmel_ehci) { + if (atmel_ehci->clocked) + return; if (IS_ENABLED(CONFIG_COMMON_CLK)) { - clk_set_rate(uclk, 48000000); - clk_prepare_enable(uclk); + clk_set_rate(atmel_ehci->uclk, 48000000); + clk_prepare_enable(atmel_ehci->uclk); } - clk_prepare_enable(iclk); - clk_prepare_enable(fclk); - clocked = 1; + clk_prepare_enable(atmel_ehci->iclk); + clk_prepare_enable(atmel_ehci->fclk); + atmel_ehci->clocked = true; } -static void atmel_stop_clock(void) +static void atmel_stop_clock(struct atmel_ehci_priv *atmel_ehci) { - clk_disable_unprepare(fclk); - clk_disable_unprepare(iclk); + if (!atmel_ehci->clocked) + return; + clk_disable_unprepare(atmel_ehci->fclk); + clk_disable_unprepare(atmel_ehci->iclk); if (IS_ENABLED(CONFIG_COMMON_CLK)) - clk_disable_unprepare(uclk); - clocked = 0; + clk_disable_unprepare(atmel_ehci->uclk); + atmel_ehci->clocked = false; } static void atmel_start_ehci(struct platform_device *pdev) { + struct usb_hcd *hcd = platform_get_drvdata(pdev); + struct atmel_ehci_priv *atmel_ehci = hcd_to_atmel_ehci_priv(hcd); + dev_dbg(&pdev->dev, "start\n"); - atmel_start_clock(); + atmel_start_clock(atmel_ehci); } static void atmel_stop_ehci(struct platform_device *pdev) { + struct usb_hcd *hcd = platform_get_drvdata(pdev); + struct atmel_ehci_priv *atmel_ehci = hcd_to_atmel_ehci_priv(hcd); + dev_dbg(&pdev->dev, "stop\n"); - atmel_stop_clock(); + atmel_stop_clock(atmel_ehci); } /*-------------------------------------------------------------------------*/ @@ -75,6 +97,7 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev) const struct hc_driver *driver = &ehci_atmel_hc_driver; struct resource *res; struct ehci_hcd *ehci; + struct atmel_ehci_priv *atmel_ehci; int irq; int retval; @@ -105,6 +128,7 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev) retval = -ENOMEM; goto fail_create_hcd; } + atmel_ehci = hcd_to_atmel_ehci_priv(hcd); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&pdev->dev, res); @@ -116,23 +140,23 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev) hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); - iclk = devm_clk_get(&pdev->dev, "ehci_clk"); - if (IS_ERR(iclk)) { + atmel_ehci->iclk = devm_clk_get(&pdev->dev, "ehci_clk"); + if (IS_ERR(atmel_ehci->iclk)) { dev_err(&pdev->dev, "Error getting interface clock\n"); retval = -ENOENT; goto fail_request_resource; } - fclk = devm_clk_get(&pdev->dev, "uhpck"); - if (IS_ERR(fclk)) { + atmel_ehci->fclk = devm_clk_get(&pdev->dev, "uhpck"); + if (IS_ERR(atmel_ehci->fclk)) { dev_err(&pdev->dev, "Error getting function clock\n"); retval = -ENOENT; goto fail_request_resource; } if (IS_ENABLED(CONFIG_COMMON_CLK)) { - uclk = devm_clk_get(&pdev->dev, "usb_clk"); - if (IS_ERR(uclk)) { + atmel_ehci->uclk = devm_clk_get(&pdev->dev, "usb_clk"); + if (IS_ERR(atmel_ehci->uclk)) { dev_err(&pdev->dev, "failed to get uclk\n"); - retval = PTR_ERR(uclk); + retval = PTR_ERR(atmel_ehci->uclk); goto fail_request_resource; } } @@ -169,11 +193,35 @@ static int ehci_atmel_drv_remove(struct platform_device *pdev) usb_put_hcd(hcd); atmel_stop_ehci(pdev); - fclk = iclk = NULL; return 0; } +#ifdef CONFIG_PM +static int ehci_atmel_drv_suspend(struct device *dev) +{ + struct usb_hcd *hcd = dev_get_drvdata(dev); + struct atmel_ehci_priv *atmel_ehci = hcd_to_atmel_ehci_priv(hcd); + int ret; + + ret = ehci_suspend(hcd, false); + if (ret) + return ret; + + atmel_stop_clock(atmel_ehci); + return 0; +} + +static int ehci_atmel_drv_resume(struct device *dev) +{ + struct usb_hcd *hcd = dev_get_drvdata(dev); + struct atmel_ehci_priv *atmel_ehci = hcd_to_atmel_ehci_priv(hcd); + + atmel_start_clock(atmel_ehci); + return ehci_resume(hcd, false); +} +#endif + #ifdef CONFIG_OF static const struct of_device_id atmel_ehci_dt_ids[] = { { .compatible = "atmel,at91sam9g45-ehci" }, @@ -183,12 +231,16 @@ static const struct of_device_id atmel_ehci_dt_ids[] = { MODULE_DEVICE_TABLE(of, atmel_ehci_dt_ids); #endif +static SIMPLE_DEV_PM_OPS(ehci_atmel_pm_ops, ehci_atmel_drv_suspend, + ehci_atmel_drv_resume); + static struct platform_driver ehci_atmel_driver = { .probe = ehci_atmel_drv_probe, .remove = ehci_atmel_drv_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "atmel-ehci", + .pm = &ehci_atmel_pm_ops, .of_match_table = of_match_ptr(atmel_ehci_dt_ids), }, }; @@ -199,7 +251,7 @@ static int __init ehci_atmel_init(void) return -ENODEV; pr_info("%s: " DRIVER_DESC "\n", hcd_name); - ehci_init_driver(&ehci_atmel_hc_driver, NULL); + ehci_init_driver(&ehci_atmel_hc_driver, &ehci_atmel_drv_overrides); return platform_driver_register(&ehci_atmel_driver); } module_init(ehci_atmel_init); diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index fb7bd0c..ab4eee3 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -709,7 +709,6 @@ static struct platform_driver ehci_fsl_driver = { .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "fsl-ehci", - .owner = THIS_MODULE, .pm = EHCI_FSL_PM_OPS, }, }; diff --git a/drivers/usb/host/ehci-grlib.c b/drivers/usb/host/ehci-grlib.c index 495b6fb..2165004 100644 --- a/drivers/usb/host/ehci-grlib.c +++ b/drivers/usb/host/ehci-grlib.c @@ -187,7 +187,6 @@ static struct platform_driver ehci_grlib_driver = { .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "grlib-ehci", - .owner = THIS_MODULE, .of_match_table = ehci_hcd_grlib_of_match, }, }; diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 38bfeed..85e56d1 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1110,7 +1110,7 @@ int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup) EXPORT_SYMBOL_GPL(ehci_suspend); /* Returns 0 if power was preserved, 1 if power was lost */ -int ehci_resume(struct usb_hcd *hcd, bool hibernated) +int ehci_resume(struct usb_hcd *hcd, bool force_reset) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); @@ -1124,12 +1124,12 @@ int ehci_resume(struct usb_hcd *hcd, bool hibernated) return 0; /* Controller is dead */ /* - * If CF is still set and we aren't resuming from hibernation + * If CF is still set and reset isn't forced * then we maintained suspend power. * Just undo the effect of ehci_suspend(). */ if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF && - !hibernated) { + !force_reset) { int mask = INTR_MASK; ehci_prepare_ports_for_controller_resume(ehci); diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 118edb7..87cf86f 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -700,15 +700,15 @@ ehci_hub_descriptor ( memset(&desc->u.hs.DeviceRemovable[0], 0, temp); memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); - temp = 0x0008; /* per-port overcurrent reporting */ + temp = HUB_CHAR_INDV_PORT_OCPM; /* per-port overcurrent reporting */ if (HCS_PPC (ehci->hcs_params)) - temp |= 0x0001; /* per-port power control */ + temp |= HUB_CHAR_INDV_PORT_LPSM; /* per-port power control */ else - temp |= 0x0002; /* no power switching */ + temp |= HUB_CHAR_NO_LPSM; /* no power switching */ #if 0 // re-enable when we support USB_PORT_FEAT_INDICATOR below. if (HCS_INDICATOR (ehci->hcs_params)) - temp |= 0x0080; /* per-port indicators (LEDs) */ + temp |= HUB_CHAR_PORTIND; /* per-port indicators (LEDs) */ #endif desc->wHubCharacteristics = cpu_to_le16(temp); } diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 851006a..2a5d2fd 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -43,6 +43,24 @@ static inline bool is_intel_quark_x1000(struct pci_dev *pdev) } /* + * This is the list of PCI IDs for the devices that have EHCI USB class and + * specific drivers for that. One of the example is a ChipIdea device installed + * on some Intel MID platforms. + */ +static const struct pci_device_id bypass_pci_id_table[] = { + /* ChipIdea on Intel MID platform */ + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0811), }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0829), }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe006), }, + {} +}; + +static inline bool is_bypassed_id(struct pci_dev *pdev) +{ + return !!pci_match_id(bypass_pci_id_table, pdev); +} + +/* * 0x84 is the offset of in/out threshold register, * and it is the same offset as the register of 'hostpc'. */ @@ -352,6 +370,13 @@ static const struct ehci_driver_overrides pci_overrides __initconst = { /*-------------------------------------------------------------------------*/ +static int ehci_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + if (is_bypassed_id(pdev)) + return -ENODEV; + return usb_hcd_pci_probe(pdev, id); +} + /* PCI driver selection metadata; PCI hotplugging uses this */ static const struct pci_device_id pci_ids [] = { { /* handle any USB 2.0 EHCI controller */ @@ -370,7 +395,7 @@ static struct pci_driver ehci_pci_driver = { .name = (char *) hcd_name, .id_table = pci_ids, - .probe = usb_hcd_pci_probe, + .probe = ehci_pci_probe, .remove = usb_hcd_pci_remove, .shutdown = usb_hcd_pci_shutdown, diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index 8557803..d8a75a5 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -43,7 +43,8 @@ struct ehci_platform_priv { struct clk *clks[EHCI_MAX_CLKS]; struct reset_control *rst; - struct phy *phy; + struct phy **phys; + int num_phys; }; static const char hcd_name[] = "ehci-platform"; @@ -78,7 +79,7 @@ static int ehci_platform_power_on(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); - int clk, ret; + int clk, ret, phy_num; for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) { ret = clk_prepare_enable(priv->clks[clk]); @@ -86,20 +87,28 @@ static int ehci_platform_power_on(struct platform_device *dev) goto err_disable_clks; } - if (priv->phy) { - ret = phy_init(priv->phy); - if (ret) - goto err_disable_clks; - - ret = phy_power_on(priv->phy); - if (ret) - goto err_exit_phy; + for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { + if (priv->phys[phy_num]) { + ret = phy_init(priv->phys[phy_num]); + if (ret) + goto err_exit_phy; + ret = phy_power_on(priv->phys[phy_num]); + if (ret) { + phy_exit(priv->phys[phy_num]); + goto err_exit_phy; + } + } } return 0; err_exit_phy: - phy_exit(priv->phy); + while (--phy_num >= 0) { + if (priv->phys[phy_num]) { + phy_power_off(priv->phys[phy_num]); + phy_exit(priv->phys[phy_num]); + } + } err_disable_clks: while (--clk >= 0) clk_disable_unprepare(priv->clks[clk]); @@ -111,11 +120,13 @@ static void ehci_platform_power_off(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); - int clk; + int clk, phy_num; - if (priv->phy) { - phy_power_off(priv->phy); - phy_exit(priv->phy); + for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { + if (priv->phys[phy_num]) { + phy_power_off(priv->phys[phy_num]); + phy_exit(priv->phys[phy_num]); + } } for (clk = EHCI_MAX_CLKS - 1; clk >= 0; clk--) @@ -143,7 +154,8 @@ static int ehci_platform_probe(struct platform_device *dev) struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); struct ehci_platform_priv *priv; struct ehci_hcd *ehci; - int err, irq, clk = 0; + const char *phy_name; + int err, irq, phy_num, clk = 0; if (usb_disabled()) return -ENODEV; @@ -155,7 +167,8 @@ static int ehci_platform_probe(struct platform_device *dev) if (!pdata) pdata = &ehci_platform_defaults; - err = dma_coerce_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32)); + err = dma_coerce_mask_and_coherent(&dev->dev, + pdata->dma_mask_64 ? DMA_BIT_MASK(64) : DMA_BIT_MASK(32)); if (err) return err; @@ -185,12 +198,42 @@ static int ehci_platform_probe(struct platform_device *dev) if (of_property_read_bool(dev->dev.of_node, "big-endian")) ehci->big_endian_mmio = ehci->big_endian_desc = 1; - priv->phy = devm_phy_get(&dev->dev, "usb"); - if (IS_ERR(priv->phy)) { - err = PTR_ERR(priv->phy); - if (err == -EPROBE_DEFER) - goto err_put_hcd; - priv->phy = NULL; + if (of_property_read_bool(dev->dev.of_node, + "needs-reset-on-resume")) + pdata->reset_on_resume = 1; + + priv->num_phys = of_count_phandle_with_args(dev->dev.of_node, + "phys", "#phy-cells"); + priv->num_phys = priv->num_phys > 0 ? priv->num_phys : 1; + + priv->phys = devm_kcalloc(&dev->dev, priv->num_phys, + sizeof(struct phy *), GFP_KERNEL); + if (!priv->phys) + return -ENOMEM; + + for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { + err = of_property_read_string_index( + dev->dev.of_node, + "phy-names", phy_num, + &phy_name); + + if (err < 0) { + if (priv->num_phys > 1) { + dev_err(&dev->dev, "phy-names not provided"); + goto err_put_hcd; + } else + phy_name = "usb"; + } + + priv->phys[phy_num] = devm_phy_get(&dev->dev, + phy_name); + if (IS_ERR(priv->phys[phy_num])) { + err = PTR_ERR(priv->phys[phy_num]); + if ((priv->num_phys > 1) || + (err == -EPROBE_DEFER)) + goto err_put_hcd; + priv->phys[phy_num] = NULL; + } } for (clk = 0; clk < EHCI_MAX_CLKS; clk++) { @@ -340,7 +383,7 @@ static int ehci_platform_resume(struct device *dev) return err; } - ehci_resume(hcd, false); + ehci_resume(hcd, pdata->reset_on_resume); return 0; } #endif /* CONFIG_PM_SLEEP */ @@ -349,6 +392,7 @@ static const struct of_device_id vt8500_ehci_ids[] = { { .compatible = "via,vt8500-ehci", }, { .compatible = "wm,prizm-ehci", }, { .compatible = "generic-ehci", }, + { .compatible = "cavium,octeon-6335-ehci", }, {} }; MODULE_DEVICE_TABLE(of, vt8500_ehci_ids); diff --git a/drivers/usb/host/ehci-pmcmsp.c b/drivers/usb/host/ehci-pmcmsp.c index 7d75465..342816a 100644 --- a/drivers/usb/host/ehci-pmcmsp.c +++ b/drivers/usb/host/ehci-pmcmsp.c @@ -325,6 +325,5 @@ static struct platform_driver ehci_hcd_msp_driver = { .remove = ehci_hcd_msp_drv_remove, .driver = { .name = "pmcmsp-ehci", - .owner = THIS_MODULE, }, }; diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index 5479247..1a10c8d 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c @@ -234,7 +234,6 @@ static struct platform_driver ehci_hcd_ppc_of_driver = { .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "ppc-of-ehci", - .owner = THIS_MODULE, .of_match_table = ehci_hcd_ppc_of_match, }, }; diff --git a/drivers/usb/host/ehci-sead3.c b/drivers/usb/host/ehci-sead3.c index 9b6e8d0..3d86cc2 100644 --- a/drivers/usb/host/ehci-sead3.c +++ b/drivers/usb/host/ehci-sead3.c @@ -178,7 +178,6 @@ static struct platform_driver ehci_hcd_sead3_driver = { .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "sead3-ehci", - .owner = THIS_MODULE, .pm = SEAD3_EHCI_PMOPS, } }; diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c index 0e0ce68..5caf88d 100644 --- a/drivers/usb/host/ehci-sh.c +++ b/drivers/usb/host/ehci-sh.c @@ -189,7 +189,6 @@ static struct platform_driver ehci_hcd_sh_driver = { .shutdown = ehci_hcd_sh_shutdown, .driver = { .name = "sh_ehci", - .owner = THIS_MODULE, }, }; diff --git a/drivers/usb/host/ehci-tilegx.c b/drivers/usb/host/ehci-tilegx.c index 0d24767..bdb93b6 100644 --- a/drivers/usb/host/ehci-tilegx.c +++ b/drivers/usb/host/ehci-tilegx.c @@ -210,7 +210,6 @@ static struct platform_driver ehci_hcd_tilegx_driver = { .shutdown = ehci_hcd_tilegx_drv_shutdown, .driver = { .name = "tilegx-ehci", - .owner = THIS_MODULE, } }; diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c index a232836..f544808 100644 --- a/drivers/usb/host/ehci-xilinx-of.c +++ b/drivers/usb/host/ehci-xilinx-of.c @@ -236,7 +236,6 @@ static struct platform_driver ehci_hcd_xilinx_of_driver = { .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "xilinx-of-ehci", - .owner = THIS_MODULE, .of_match_table = ehci_hcd_xilinx_of_match, }, }; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 6f0577b..52ef084 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -871,7 +871,7 @@ extern int ehci_handshake(struct ehci_hcd *ehci, void __iomem *ptr, #ifdef CONFIG_PM extern int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup); -extern int ehci_resume(struct usb_hcd *hcd, bool hibernated); +extern int ehci_resume(struct usb_hcd *hcd, bool force_reset); #endif /* CONFIG_PM */ extern int ehci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, diff --git a/drivers/usb/host/fhci-hub.c b/drivers/usb/host/fhci-hub.c index 6af2512..70116a6 100644 --- a/drivers/usb/host/fhci-hub.c +++ b/drivers/usb/host/fhci-hub.c @@ -32,8 +32,8 @@ static u8 root_hub_des[] = { 0x09, /* blength */ 0x29, /* bDescriptorType;hub-descriptor */ 0x01, /* bNbrPorts */ - 0x00, /* wHubCharacteristics */ - 0x00, + HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_NO_OCPM, /* wHubCharacteristics */ + 0x00, /* per-port power, no overcurrent */ 0x01, /* bPwrOn2pwrGood;2ms */ 0x00, /* bHubContrCurrent;0mA */ 0x00, /* DeviceRemoveable */ @@ -208,7 +208,6 @@ int fhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, { struct fhci_hcd *fhci = hcd_to_fhci(hcd); int retval = 0; - int len = 0; struct usb_hub_status *hub_status; struct usb_port_status *port_status; unsigned long flags; @@ -272,8 +271,6 @@ int fhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, break; case GetHubDescriptor: memcpy(buf, root_hub_des, sizeof(root_hub_des)); - buf[3] = 0x11; /* per-port power, no ovrcrnt */ - len = (buf[0] < wLength) ? buf[0] : wLength; break; case GetHubStatus: hub_status = (struct usb_hub_status *)buf; @@ -281,7 +278,6 @@ int fhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, cpu_to_le16(fhci->vroot_hub->hub.wHubStatus); hub_status->wHubChange = cpu_to_le16(fhci->vroot_hub->hub.wHubChange); - len = 4; break; case GetPortStatus: port_status = (struct usb_port_status *)buf; @@ -289,7 +285,6 @@ int fhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, cpu_to_le16(fhci->vroot_hub->port.wPortStatus); port_status->wPortChange = cpu_to_le16(fhci->vroot_hub->port.wPortChange); - len = 4; break; case SetHubFeature: switch (wValue) { diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c index ecf02b26..475b21f 100644 --- a/drivers/usb/host/fotg210-hcd.c +++ b/drivers/usb/host/fotg210-hcd.c @@ -1521,8 +1521,8 @@ fotg210_hub_descriptor( memset(&desc->u.hs.DeviceRemovable[0], 0, temp); memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); - temp = 0x0008; /* per-port overcurrent reporting */ - temp |= 0x0002; /* no power switching */ + temp = HUB_CHAR_INDV_PORT_OCPM; /* per-port overcurrent reporting */ + temp |= HUB_CHAR_NO_LPSM; /* no power switching */ desc->wHubCharacteristics = cpu_to_le16(temp); } diff --git a/drivers/usb/host/fusbh200-hcd.c b/drivers/usb/host/fusbh200-hcd.c index 664d2aa..a83eefe 100644 --- a/drivers/usb/host/fusbh200-hcd.c +++ b/drivers/usb/host/fusbh200-hcd.c @@ -1479,8 +1479,8 @@ fusbh200_hub_descriptor ( memset(&desc->u.hs.DeviceRemovable[0], 0, temp); memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); - temp = 0x0008; /* per-port overcurrent reporting */ - temp |= 0x0002; /* no power switching */ + temp = HUB_CHAR_INDV_PORT_OCPM; /* per-port overcurrent reporting */ + temp |= HUB_CHAR_NO_LPSM; /* no power switching */ desc->wHubCharacteristics = cpu_to_le16(temp); } diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index eb4efba..6a2ad55 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c @@ -1482,9 +1482,8 @@ static int get_hub_descriptor(struct usb_hcd *hcd, desc->bDescLength = 9; desc->bPwrOn2PwrGood = 0; desc->wHubCharacteristics = (__force __u16) cpu_to_le16( - 0x0002 | /* No power switching */ - 0x0010 | /* No over current protection */ - 0); + HUB_CHAR_NO_LPSM | /* No power switching */ + HUB_CHAR_NO_OCPM); /* No over current protection */ desc->u.hs.DeviceRemovable[0] = 1 << 1; desc->u.hs.DeviceRemovable[1] = ~0; diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 31c9c4d..113d0cc 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -948,7 +948,10 @@ static void isp116x_hub_descriptor(struct isp116x *isp116x, desc->bHubContrCurrent = 0; desc->bNbrPorts = (u8) (reg & 0x3); /* Power switching, device type, overcurrent. */ - desc->wHubCharacteristics = cpu_to_le16((u16) ((reg >> 8) & 0x1f)); + desc->wHubCharacteristics = cpu_to_le16((u16) ((reg >> 8) & + (HUB_CHAR_LPSM | + HUB_CHAR_COMPOUND | + HUB_CHAR_OCPM))); desc->bPwrOn2PwrGood = (u8) ((reg >> 24) & 0xff); /* ports removable, and legacy PortPwrCtrlMask */ desc->u.hs.DeviceRemovable[0] = 0; diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 75e5876..b32ab60 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c @@ -1543,8 +1543,12 @@ static void isp1362_hub_descriptor(struct isp1362_hcd *isp1362_hcd, desc->bHubContrCurrent = 0; desc->bNbrPorts = reg & 0x3; /* Power switching, device type, overcurrent. */ - desc->wHubCharacteristics = cpu_to_le16((reg >> 8) & 0x1f); - DBG(0, "%s: hubcharacteristics = %02x\n", __func__, cpu_to_le16((reg >> 8) & 0x1f)); + desc->wHubCharacteristics = cpu_to_le16((reg >> 8) & + (HUB_CHAR_LPSM | + HUB_CHAR_COMPOUND | + HUB_CHAR_OCPM)); + DBG(0, "%s: hubcharacteristics = %02x\n", __func__, + desc->wHubCharacteristics); desc->bPwrOn2PwrGood = (reg >> 24) & 0xff; /* ports removable, and legacy PortPwrCtrlMask */ desc->u.hs.DeviceRemovable[0] = desc->bNbrPorts == 1 ? 1 << 1 : 3 << 1; diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c index 6234c75d..a98833c 100644 --- a/drivers/usb/host/max3421-hcd.c +++ b/drivers/usb/host/max3421-hcd.c @@ -55,6 +55,7 @@ * single thread (max3421_spi_thread). */ +#include <linux/jiffies.h> #include <linux/module.h> #include <linux/spi/spi.h> #include <linux/usb.h> @@ -1291,7 +1292,7 @@ max3421_handle_irqs(struct usb_hcd *hcd) char sbuf[16 * 16], *dp, *end; int i; - if (jiffies - last_time > 5*HZ) { + if (time_after(jiffies, last_time + 5*HZ)) { dp = sbuf; end = sbuf + sizeof(sbuf); *dp = '\0'; @@ -1660,7 +1661,8 @@ hub_descriptor(struct usb_hub_descriptor *desc) */ desc->bDescriptorType = 0x29; /* hub descriptor */ desc->bDescLength = 9; - desc->wHubCharacteristics = cpu_to_le16(0x0001); + desc->wHubCharacteristics = cpu_to_le16(HUB_CHAR_INDV_PORT_LPSM | + HUB_CHAR_COMMON_OCPM); desc->bNbrPorts = 1; } diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index dc9e4e6..7cce85a 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -33,7 +33,17 @@ for ((index) = 0; (index) < AT91_MAX_USBH_PORTS; (index)++) /* interface, function and usb clocks; sometimes also an AHB clock */ -static struct clk *iclk, *fclk, *uclk, *hclk; +#define hcd_to_ohci_at91_priv(h) \ + ((struct ohci_at91_priv *)hcd_to_ohci(h)->priv) + +struct ohci_at91_priv { + struct clk *iclk; + struct clk *fclk; + struct clk *uclk; + struct clk *hclk; + bool clocked; + bool wakeup; /* Saved wake-up state for resume */ +}; /* interface and function clocks; sometimes also an AHB clock */ #define DRIVER_DESC "OHCI Atmel driver" @@ -41,45 +51,53 @@ static struct clk *iclk, *fclk, *uclk, *hclk; static const char hcd_name[] = "ohci-atmel"; static struct hc_driver __read_mostly ohci_at91_hc_driver; -static int clocked; + +static const struct ohci_driver_overrides ohci_at91_drv_overrides __initconst = { + .extra_priv_size = sizeof(struct ohci_at91_priv), +}; extern int usb_disabled(void); /*-------------------------------------------------------------------------*/ -static void at91_start_clock(void) +static void at91_start_clock(struct ohci_at91_priv *ohci_at91) { + if (ohci_at91->clocked) + return; if (IS_ENABLED(CONFIG_COMMON_CLK)) { - clk_set_rate(uclk, 48000000); - clk_prepare_enable(uclk); + clk_set_rate(ohci_at91->uclk, 48000000); + clk_prepare_enable(ohci_at91->uclk); } - clk_prepare_enable(hclk); - clk_prepare_enable(iclk); - clk_prepare_enable(fclk); - clocked = 1; + clk_prepare_enable(ohci_at91->hclk); + clk_prepare_enable(ohci_at91->iclk); + clk_prepare_enable(ohci_at91->fclk); + ohci_at91->clocked = true; } -static void at91_stop_clock(void) +static void at91_stop_clock(struct ohci_at91_priv *ohci_at91) { - clk_disable_unprepare(fclk); - clk_disable_unprepare(iclk); - clk_disable_unprepare(hclk); + if (!ohci_at91->clocked) + return; + clk_disable_unprepare(ohci_at91->fclk); + clk_disable_unprepare(ohci_at91->iclk); + clk_disable_unprepare(ohci_at91->hclk); if (IS_ENABLED(CONFIG_COMMON_CLK)) - clk_disable_unprepare(uclk); - clocked = 0; + clk_disable_unprepare(ohci_at91->uclk); + ohci_at91->clocked = false; } static void at91_start_hc(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct ohci_regs __iomem *regs = hcd->regs; + struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd); dev_dbg(&pdev->dev, "start\n"); /* * Start the USB clocks. */ - at91_start_clock(); + at91_start_clock(ohci_at91); /* * The USB host controller must remain in reset. @@ -91,6 +109,7 @@ static void at91_stop_hc(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct ohci_regs __iomem *regs = hcd->regs; + struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd); dev_dbg(&pdev->dev, "stop\n"); @@ -102,7 +121,7 @@ static void at91_stop_hc(struct platform_device *pdev) /* * Stop the USB clocks. */ - at91_stop_clock(); + at91_stop_clock(ohci_at91); } @@ -128,7 +147,8 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, struct at91_usbh_data *board; struct ohci_hcd *ohci; int retval; - struct usb_hcd *hcd = NULL; + struct usb_hcd *hcd; + struct ohci_at91_priv *ohci_at91; struct device *dev = &pdev->dev; struct resource *res; int irq; @@ -142,6 +162,7 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, hcd = usb_create_hcd(driver, dev, "at91"); if (!hcd) return -ENOMEM; + ohci_at91 = hcd_to_ohci_at91_priv(hcd); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(dev, res); @@ -152,29 +173,29 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); - iclk = devm_clk_get(dev, "ohci_clk"); - if (IS_ERR(iclk)) { + ohci_at91->iclk = devm_clk_get(dev, "ohci_clk"); + if (IS_ERR(ohci_at91->iclk)) { dev_err(dev, "failed to get ohci_clk\n"); - retval = PTR_ERR(iclk); + retval = PTR_ERR(ohci_at91->iclk); goto err; } - fclk = devm_clk_get(dev, "uhpck"); - if (IS_ERR(fclk)) { + ohci_at91->fclk = devm_clk_get(dev, "uhpck"); + if (IS_ERR(ohci_at91->fclk)) { dev_err(dev, "failed to get uhpck\n"); - retval = PTR_ERR(fclk); + retval = PTR_ERR(ohci_at91->fclk); goto err; } - hclk = devm_clk_get(dev, "hclk"); - if (IS_ERR(hclk)) { + ohci_at91->hclk = devm_clk_get(dev, "hclk"); + if (IS_ERR(ohci_at91->hclk)) { dev_err(dev, "failed to get hclk\n"); - retval = PTR_ERR(hclk); + retval = PTR_ERR(ohci_at91->hclk); goto err; } if (IS_ENABLED(CONFIG_COMMON_CLK)) { - uclk = devm_clk_get(dev, "usb_clk"); - if (IS_ERR(uclk)) { + ohci_at91->uclk = devm_clk_get(dev, "usb_clk"); + if (IS_ERR(ohci_at91->uclk)) { dev_err(dev, "failed to get uclk\n"); - retval = PTR_ERR(uclk); + retval = PTR_ERR(ohci_at91->uclk); goto err; } } @@ -347,11 +368,13 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, */ desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_LPSM); - desc->wHubCharacteristics |= cpu_to_le16(0x0001); + desc->wHubCharacteristics |= + cpu_to_le16(HUB_CHAR_INDV_PORT_LPSM); if (pdata->overcurrent_supported) { desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_OCPM); - desc->wHubCharacteristics |= cpu_to_le16(0x0008|0x0001); + desc->wHubCharacteristics |= + cpu_to_le16(HUB_CHAR_INDV_PORT_OCPM); } dev_dbg(hcd->self.controller, "wHubCharacteristics after 0x%04x\n", @@ -593,19 +616,27 @@ static int ohci_hcd_at91_drv_remove(struct platform_device *pdev) #ifdef CONFIG_PM static int -ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg) +ohci_hcd_at91_drv_suspend(struct device *dev) { - struct usb_hcd *hcd = platform_get_drvdata(pdev); + struct usb_hcd *hcd = dev_get_drvdata(dev); struct ohci_hcd *ohci = hcd_to_ohci(hcd); - bool do_wakeup = device_may_wakeup(&pdev->dev); + struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd); int ret; - if (do_wakeup) + /* + * Disable wakeup if we are going to sleep with slow clock mode + * enabled. + */ + ohci_at91->wakeup = device_may_wakeup(dev) + && !at91_suspend_entering_slow_clock(); + + if (ohci_at91->wakeup) enable_irq_wake(hcd->irq); - ret = ohci_suspend(hcd, do_wakeup); + ret = ohci_suspend(hcd, ohci_at91->wakeup); if (ret) { - disable_irq_wake(hcd->irq); + if (ohci_at91->wakeup) + disable_irq_wake(hcd->irq); return ret; } /* @@ -615,7 +646,7 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg) * * REVISIT: some boards will be able to turn VBUS off... */ - if (at91_suspend_entering_slow_clock()) { + if (!ohci_at91->wakeup) { ohci->hc_control = ohci_readl(ohci, &ohci->regs->control); ohci->hc_control &= OHCI_CTRL_RWC; ohci_writel(ohci, ohci->hc_control, &ohci->regs->control); @@ -623,38 +654,37 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg) /* flush the writes */ (void) ohci_readl (ohci, &ohci->regs->control); - at91_stop_clock(); + at91_stop_clock(ohci_at91); } return ret; } -static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) +static int ohci_hcd_at91_drv_resume(struct device *dev) { - struct usb_hcd *hcd = platform_get_drvdata(pdev); + struct usb_hcd *hcd = dev_get_drvdata(dev); + struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd); - if (device_may_wakeup(&pdev->dev)) + if (ohci_at91->wakeup) disable_irq_wake(hcd->irq); - if (!clocked) - at91_start_clock(); + at91_start_clock(ohci_at91); ohci_resume(hcd, false); return 0; } -#else -#define ohci_hcd_at91_drv_suspend NULL -#define ohci_hcd_at91_drv_resume NULL #endif +static SIMPLE_DEV_PM_OPS(ohci_hcd_at91_pm_ops, ohci_hcd_at91_drv_suspend, + ohci_hcd_at91_drv_resume); + static struct platform_driver ohci_hcd_at91_driver = { .probe = ohci_hcd_at91_drv_probe, .remove = ohci_hcd_at91_drv_remove, .shutdown = usb_hcd_platform_shutdown, - .suspend = ohci_hcd_at91_drv_suspend, - .resume = ohci_hcd_at91_drv_resume, .driver = { .name = "at91_ohci", + .pm = &ohci_hcd_at91_pm_ops, .of_match_table = of_match_ptr(at91_ohci_dt_ids), }, }; @@ -665,7 +695,7 @@ static int __init ohci_at91_init(void) return -ENODEV; pr_info("%s: " DRIVER_DESC "\n", hcd_name); - ohci_init_driver(&ohci_at91_hc_driver, NULL); + ohci_init_driver(&ohci_at91_hc_driver, &ohci_at91_drv_overrides); /* * The Atmel HW has some unusual quirks, which require Atmel-specific diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c index 1c76999..e5c33bc 100644 --- a/drivers/usb/host/ohci-da8xx.c +++ b/drivers/usb/host/ohci-da8xx.c @@ -431,7 +431,6 @@ static struct platform_driver ohci_hcd_da8xx_driver = { .resume = ohci_da8xx_resume, #endif .driver = { - .owner = THIS_MODULE, .name = "ohci", }, }; diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 0aa17c9..fe2aedd 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -544,15 +544,15 @@ ohci_hub_descriptor ( temp = 1 + (ohci->num_ports / 8); desc->bDescLength = 7 + 2 * temp; - temp = 0; + temp = HUB_CHAR_COMMON_LPSM | HUB_CHAR_COMMON_OCPM; if (rh & RH_A_NPS) /* no power switching? */ - temp |= 0x0002; + temp |= HUB_CHAR_NO_LPSM; if (rh & RH_A_PSM) /* per-port power switching? */ - temp |= 0x0001; + temp |= HUB_CHAR_INDV_PORT_LPSM; if (rh & RH_A_NOCP) /* no overcurrent reporting? */ - temp |= 0x0010; + temp |= HUB_CHAR_NO_OCPM; else if (rh & RH_A_OCPM) /* per-port overcurrent reporting? */ - temp |= 0x0008; + temp |= HUB_CHAR_INDV_PORT_OCPM; desc->wHubCharacteristics = cpu_to_le16(temp); /* ports removable, and usb 1.0 legacy PortPwrCtrlMask */ diff --git a/drivers/usb/host/ohci-jz4740.c b/drivers/usb/host/ohci-jz4740.c index 8ddd8f5..4db78f1 100644 --- a/drivers/usb/host/ohci-jz4740.c +++ b/drivers/usb/host/ohci-jz4740.c @@ -239,7 +239,6 @@ static struct platform_driver ohci_hcd_jz4740_driver = { .remove = jz4740_ohci_remove, .driver = { .name = "jz4740-ohci", - .owner = THIS_MODULE, }, }; diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index b81d202..185ceee 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -38,7 +38,8 @@ struct ohci_platform_priv { struct clk *clks[OHCI_MAX_CLKS]; struct reset_control *rst; - struct phy *phy; + struct phy **phys; + int num_phys; }; static const char hcd_name[] = "ohci-platform"; @@ -47,7 +48,7 @@ static int ohci_platform_power_on(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd); - int clk, ret; + int clk, ret, phy_num; for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++) { ret = clk_prepare_enable(priv->clks[clk]); @@ -55,20 +56,28 @@ static int ohci_platform_power_on(struct platform_device *dev) goto err_disable_clks; } - if (priv->phy) { - ret = phy_init(priv->phy); - if (ret) - goto err_disable_clks; - - ret = phy_power_on(priv->phy); - if (ret) - goto err_exit_phy; + for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { + if (priv->phys[phy_num]) { + ret = phy_init(priv->phys[phy_num]); + if (ret) + goto err_exit_phy; + ret = phy_power_on(priv->phys[phy_num]); + if (ret) { + phy_exit(priv->phys[phy_num]); + goto err_exit_phy; + } + } } return 0; err_exit_phy: - phy_exit(priv->phy); + while (--phy_num >= 0) { + if (priv->phys[phy_num]) { + phy_power_off(priv->phys[phy_num]); + phy_exit(priv->phys[phy_num]); + } + } err_disable_clks: while (--clk >= 0) clk_disable_unprepare(priv->clks[clk]); @@ -80,11 +89,13 @@ static void ohci_platform_power_off(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd); - int clk; + int clk, phy_num; - if (priv->phy) { - phy_power_off(priv->phy); - phy_exit(priv->phy); + for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { + if (priv->phys[phy_num]) { + phy_power_off(priv->phys[phy_num]); + phy_exit(priv->phys[phy_num]); + } } for (clk = OHCI_MAX_CLKS - 1; clk >= 0; clk--) @@ -112,7 +123,8 @@ static int ohci_platform_probe(struct platform_device *dev) struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev); struct ohci_platform_priv *priv; struct ohci_hcd *ohci; - int err, irq, clk = 0; + const char *phy_name; + int err, irq, phy_num, clk = 0; if (usb_disabled()) return -ENODEV; @@ -160,12 +172,38 @@ static int ohci_platform_probe(struct platform_device *dev) of_property_read_u32(dev->dev.of_node, "num-ports", &ohci->num_ports); - priv->phy = devm_phy_get(&dev->dev, "usb"); - if (IS_ERR(priv->phy)) { - err = PTR_ERR(priv->phy); - if (err == -EPROBE_DEFER) - goto err_put_hcd; - priv->phy = NULL; + priv->num_phys = of_count_phandle_with_args(dev->dev.of_node, + "phys", "#phy-cells"); + priv->num_phys = priv->num_phys > 0 ? priv->num_phys : 1; + + priv->phys = devm_kcalloc(&dev->dev, priv->num_phys, + sizeof(struct phy *), GFP_KERNEL); + if (!priv->phys) + return -ENOMEM; + + for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { + err = of_property_read_string_index( + dev->dev.of_node, + "phy-names", phy_num, + &phy_name); + + if (err < 0) { + if (priv->num_phys > 1) { + dev_err(&dev->dev, "phy-names not provided"); + goto err_put_hcd; + } else + phy_name = "usb"; + } + + priv->phys[phy_num] = devm_phy_get(&dev->dev, + phy_name); + if (IS_ERR(priv->phys[phy_num])) { + err = PTR_ERR(priv->phys[phy_num]); + if ((priv->num_phys > 1) || + (err == -EPROBE_DEFER)) + goto err_put_hcd; + priv->phys[phy_num] = NULL; + } } for (clk = 0; clk < OHCI_MAX_CLKS; clk++) { @@ -328,6 +366,7 @@ static int ohci_platform_resume(struct device *dev) static const struct of_device_id ohci_platform_ids[] = { { .compatible = "generic-ohci", }, + { .compatible = "cavium,octeon-6335-ohci", }, { } }; MODULE_DEVICE_TABLE(of, ohci_platform_ids); diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index 965e3e9..4f87a5c 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c @@ -229,7 +229,6 @@ static struct platform_driver ohci_hcd_ppc_of_driver = { .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "ppc-of-ohci", - .owner = THIS_MODULE, .of_match_table = ohci_hcd_ppc_of_match, }, }; diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 095113e..7a1919c 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -249,14 +249,14 @@ static int ohci_s3c2410_hub_control( */ desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_LPSM); - desc->wHubCharacteristics |= cpu_to_le16(0x0001); + desc->wHubCharacteristics |= cpu_to_le16( + HUB_CHAR_INDV_PORT_LPSM); if (info->enable_oc) { desc->wHubCharacteristics &= ~cpu_to_le16( HUB_CHAR_OCPM); desc->wHubCharacteristics |= cpu_to_le16( - 0x0008 | - 0x0001); + HUB_CHAR_INDV_PORT_OCPM); } dev_dbg(hcd->self.controller, "wHubCharacteristics after 0x%04x\n", diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index 4e81c80..a8b8d8b 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c @@ -265,7 +265,6 @@ static struct platform_driver ohci_hcd_sm501_driver = { .suspend = ohci_sm501_suspend, .resume = ohci_sm501_resume, .driver = { - .owner = THIS_MODULE, .name = "sm501-usb", }, }; diff --git a/drivers/usb/host/ohci-tilegx.c b/drivers/usb/host/ohci-tilegx.c index bef6dfb..e1b208d 100644 --- a/drivers/usb/host/ohci-tilegx.c +++ b/drivers/usb/host/ohci-tilegx.c @@ -199,7 +199,6 @@ static struct platform_driver ohci_hcd_tilegx_driver = { .shutdown = ohci_hcd_tilegx_drv_shutdown, .driver = { .name = "tilegx-ohci", - .owner = THIS_MODULE, } }; diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c index bb40958..e9a6eec 100644 --- a/drivers/usb/host/ohci-tmio.c +++ b/drivers/usb/host/ohci-tmio.c @@ -368,6 +368,5 @@ static struct platform_driver ohci_hcd_tmio_driver = { .resume = ohci_hcd_tmio_drv_resume, .driver = { .name = "tmio-ohci", - .owner = THIS_MODULE, }, }; diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index 036924e..ef7efb2 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c @@ -457,11 +457,11 @@ static void ehci_hub_descriptor(struct oxu_hcd *oxu, memset(&desc->u.hs.DeviceRemovable[0], 0, temp); memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); - temp = 0x0008; /* per-port overcurrent reporting */ + temp = HUB_CHAR_INDV_PORT_OCPM; /* per-port overcurrent reporting */ if (HCS_PPC(oxu->hcs_params)) - temp |= 0x0001; /* per-port power control */ + temp |= HUB_CHAR_INDV_PORT_LPSM; /* per-port power control */ else - temp |= 0x0002; /* no power switching */ + temp |= HUB_CHAR_NO_LPSM; /* no power switching */ desc->wHubCharacteristics = (__force __u16)cpu_to_le16(temp); } @@ -2598,9 +2598,7 @@ static int oxu_hcd_init(struct usb_hcd *hcd) spin_lock_init(&oxu->lock); - init_timer(&oxu->watchdog); - oxu->watchdog.function = oxu_watchdog; - oxu->watchdog.data = (unsigned long) oxu; + setup_timer(&oxu->watchdog, oxu_watchdog, (unsigned long)oxu); /* * hw default: 1K periodic list heads, one per frame. diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index ce63646..f940056 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -603,9 +603,9 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev) msleep(10); } if (wait_time <= 0) - dev_warn(&pdev->dev, "OHCI: BIOS handoff failed" - " (BIOS bug?) %08x\n", - readl(base + OHCI_CONTROL)); + dev_warn(&pdev->dev, + "OHCI: BIOS handoff failed (BIOS bug?) %08x\n", + readl(base + OHCI_CONTROL)); } #endif @@ -733,8 +733,9 @@ static void ehci_bios_handoff(struct pci_dev *pdev, * and hope nothing goes too wrong */ if (try_handoff) - dev_warn(&pdev->dev, "EHCI: BIOS handoff failed" - " (BIOS bug?) %08x\n", cap); + dev_warn(&pdev->dev, + "EHCI: BIOS handoff failed (BIOS bug?) %08x\n", + cap); pci_write_config_byte(pdev, offset + 2, 0); } @@ -781,8 +782,9 @@ static void quirk_usb_disable_ehci(struct pci_dev *pdev) case 0: /* Illegal reserved cap, set cap=0 so we exit */ cap = 0; /* then fallthrough... */ default: - dev_warn(&pdev->dev, "EHCI: unrecognized capability " - "%02x\n", cap & 0xff); + dev_warn(&pdev->dev, + "EHCI: unrecognized capability %02x\n", + cap & 0xff); } offset = (cap >> 8) & 0xff; } @@ -893,8 +895,7 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev) */ if (!IS_ENABLED(CONFIG_USB_XHCI_HCD)) { dev_warn(&xhci_pdev->dev, - "CONFIG_USB_XHCI_HCD is turned off, " - "defaulting to EHCI.\n"); + "CONFIG_USB_XHCI_HCD is turned off, defaulting to EHCI.\n"); dev_warn(&xhci_pdev->dev, "USB 3.0 devices will work at USB 2.0 speeds.\n"); usb_disable_xhci_ports(xhci_pdev); @@ -919,8 +920,9 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev) pci_read_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, &ports_available); - dev_dbg(&xhci_pdev->dev, "USB 3.0 ports that are now enabled " - "under xHCI: 0x%x\n", ports_available); + dev_dbg(&xhci_pdev->dev, + "USB 3.0 ports that are now enabled under xHCI: 0x%x\n", + ports_available); /* Read XUSB2PRM, xHCI USB 2.0 Port Routing Mask Register * Indicate the USB 2.0 ports to be controlled by the xHCI host. @@ -941,8 +943,9 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev) pci_read_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, &ports_available); - dev_dbg(&xhci_pdev->dev, "USB 2.0 ports that are now switched over " - "to xHCI: 0x%x\n", ports_available); + dev_dbg(&xhci_pdev->dev, + "USB 2.0 ports that are now switched over to xHCI: 0x%x\n", + ports_available); } EXPORT_SYMBOL_GPL(usb_enable_intel_xhci_ports); @@ -1010,8 +1013,9 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev) /* Assume a buggy BIOS and take HC ownership anyway */ if (timeout) { - dev_warn(&pdev->dev, "xHCI BIOS handoff failed" - " (BIOS bug ?) %08x\n", val); + dev_warn(&pdev->dev, + "xHCI BIOS handoff failed (BIOS bug ?) %08x\n", + val); writel(val & ~XHCI_HC_BIOS_OWNED, base + ext_cap_offset); } } @@ -1039,8 +1043,8 @@ hc_init: if (timeout) { val = readl(op_reg_base + XHCI_STS_OFFSET); dev_warn(&pdev->dev, - "xHCI HW not ready after 5 sec (HC bug?) " - "status = 0x%x\n", val); + "xHCI HW not ready after 5 sec (HC bug?) status = 0x%x\n", + val); } /* Send the halt and disable interrupts command */ @@ -1054,8 +1058,8 @@ hc_init: if (timeout) { val = readl(op_reg_base + XHCI_STS_OFFSET); dev_warn(&pdev->dev, - "xHCI HW did not halt within %d usec " - "status = 0x%x\n", XHCI_MAX_HALT_USEC, val); + "xHCI HW did not halt within %d usec status = 0x%x\n", + XHCI_MAX_HALT_USEC, val); } iounmap(base); @@ -1075,8 +1079,8 @@ static void quirk_usb_early_handoff(struct pci_dev *pdev) return; if (pci_enable_device(pdev) < 0) { - dev_warn(&pdev->dev, "Can't enable PCI device, " - "BIOS handoff failed.\n"); + dev_warn(&pdev->dev, + "Can't enable PCI device, BIOS handoff failed.\n"); return; } if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI) diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index c4bcfae..bdc82fe 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -2141,7 +2141,8 @@ static void r8a66597_hub_descriptor(struct r8a66597 *r8a66597, desc->bNbrPorts = r8a66597->max_root_hub; desc->bDescLength = 9; desc->bPwrOn2PwrGood = 0; - desc->wHubCharacteristics = cpu_to_le16(0x0011); + desc->wHubCharacteristics = + cpu_to_le16(HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_NO_OCPM); desc->u.hs.DeviceRemovable[0] = ((1 << r8a66597->max_root_hub) - 1) << 1; desc->u.hs.DeviceRemovable[1] = ~0; @@ -2483,9 +2484,8 @@ static int r8a66597_probe(struct platform_device *pdev) r8a66597->max_root_hub = 2; spin_lock_init(&r8a66597->lock); - init_timer(&r8a66597->rh_timer); - r8a66597->rh_timer.function = r8a66597_timer; - r8a66597->rh_timer.data = (unsigned long)r8a66597; + setup_timer(&r8a66597->rh_timer, r8a66597_timer, + (unsigned long)r8a66597); r8a66597->reg = reg; /* make sure no interrupts are pending */ @@ -2496,9 +2496,8 @@ static int r8a66597_probe(struct platform_device *pdev) for (i = 0; i < R8A66597_MAX_NUM_PIPE; i++) { INIT_LIST_HEAD(&r8a66597->pipe_queue[i]); - init_timer(&r8a66597->td_timer[i]); - r8a66597->td_timer[i].function = r8a66597_td_timer; - r8a66597->td_timer[i].data = (unsigned long)r8a66597; + setup_timer(&r8a66597->td_timer[i], r8a66597_td_timer, + (unsigned long)r8a66597); setup_timer(&r8a66597->interval_timer[i], r8a66597_interval_timer, (unsigned long)r8a66597); diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 25fb1da..4f4ba1e 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -1103,12 +1103,12 @@ sl811h_hub_descriptor ( desc->bPwrOn2PwrGood = sl811->board->potpg; if (!desc->bPwrOn2PwrGood) desc->bPwrOn2PwrGood = 10; - temp = 0x0001; + temp = HUB_CHAR_INDV_PORT_LPSM; } else - temp = 0x0002; + temp = HUB_CHAR_NO_LPSM; /* no overcurrent errors detection/handling */ - temp |= 0x0010; + temp |= HUB_CHAR_NO_OCPM; desc->wHubCharacteristics = cpu_to_le16(temp); @@ -1691,9 +1691,7 @@ sl811h_probe(struct platform_device *dev) spin_lock_init(&sl811->lock); INIT_LIST_HEAD(&sl811->async); sl811->board = dev_get_platdata(&dev->dev); - init_timer(&sl811->timer); - sl811->timer.function = sl811h_timer; - sl811->timer.data = (unsigned long) sl811; + setup_timer(&sl811->timer, sl811h_timer, (unsigned long)sl811); sl811->addr_reg = addr_reg; sl811->data_reg = data_reg; diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 2894e54..ad97e8a 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -2590,15 +2590,15 @@ static int u132_roothub_descriptor(struct u132 *u132, desc->bNbrPorts = u132->num_ports; temp = 1 + (u132->num_ports / 8); desc->bDescLength = 7 + 2 * temp; - temp = 0; + temp = HUB_CHAR_COMMON_LPSM | HUB_CHAR_COMMON_OCPM; if (rh_a & RH_A_NPS) - temp |= 0x0002; + temp |= HUB_CHAR_NO_LPSM; if (rh_a & RH_A_PSM) - temp |= 0x0001; + temp |= HUB_CHAR_INDV_PORT_LPSM; if (rh_a & RH_A_NOCP) - temp |= 0x0010; + temp |= HUB_CHAR_NO_OCPM; else if (rh_a & RH_A_OCPM) - temp |= 0x0008; + temp |= HUB_CHAR_INDV_PORT_OCPM; desc->wHubCharacteristics = cpu_to_le16(temp); retval = u132_read_pcimem(u132, roothub.b, &rh_b); if (retval) diff --git a/drivers/usb/host/uhci-grlib.c b/drivers/usb/host/uhci-grlib.c index 05f57ff..0342991 100644 --- a/drivers/usb/host/uhci-grlib.c +++ b/drivers/usb/host/uhci-grlib.c @@ -188,7 +188,6 @@ static struct platform_driver uhci_grlib_driver = { .shutdown = uhci_hcd_grlib_shutdown, .driver = { .name = "grlib-uhci", - .owner = THIS_MODULE, .of_match_table = uhci_hcd_grlib_of_match, }, }; diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index 93e17b1..19ba5ea 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c @@ -17,8 +17,9 @@ static const __u8 root_hub_hub_des[] = 0x09, /* __u8 bLength; */ 0x29, /* __u8 bDescriptorType; Hub-descriptor */ 0x02, /* __u8 bNbrPorts; */ - 0x0a, /* __u16 wHubCharacteristics; */ - 0x00, /* (per-port OC, no power switching) */ + HUB_CHAR_NO_LPSM | /* __u16 wHubCharacteristics; */ + HUB_CHAR_INDV_PORT_OCPM, /* (per-port OC, no power switching) */ + 0x00, 0x01, /* __u8 bPwrOn2pwrGood; 2ms */ 0x00, /* __u8 bHubContrCurrent; 0 mA */ 0x00, /* __u8 DeviceRemovable; *** 7 Ports max */ diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c index cf8f460..3a3e3ee 100644 --- a/drivers/usb/host/uhci-platform.c +++ b/drivers/usb/host/uhci-platform.c @@ -147,7 +147,6 @@ static struct platform_driver uhci_platform_driver = { .shutdown = uhci_hcd_platform_shutdown, .driver = { .name = "platform-uhci", - .owner = THIS_MODULE, .of_match_table = platform_uhci_ids, }, }; diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c index bb89175..745717e 100644 --- a/drivers/usb/host/xhci-dbg.c +++ b/drivers/usb/host/xhci-dbg.c @@ -552,7 +552,7 @@ void xhci_dbg_ctx(struct xhci_hcd *xhci, if (ctx->type == XHCI_CTX_TYPE_INPUT) { struct xhci_input_control_ctx *ctrl_ctx = - xhci_get_input_control_ctx(xhci, ctx); + xhci_get_input_control_ctx(ctx); if (!ctrl_ctx) { xhci_warn(xhci, "Could not get input context, bad type.\n"); return; diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 5cb3d7a..f833640 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -535,7 +535,7 @@ static void xhci_free_container_ctx(struct xhci_hcd *xhci, kfree(ctx); } -struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci, +struct xhci_input_control_ctx *xhci_get_input_control_ctx( struct xhci_container_ctx *ctx) { if (ctx->type != XHCI_CTX_TYPE_INPUT) @@ -784,8 +784,7 @@ void xhci_setup_streams_ep_input_ctx(struct xhci_hcd *xhci, * Reinstalls the "normal" endpoint ring (at its previous dequeue mark, * not at the beginning of the ring). */ -void xhci_setup_no_streams_ep_input_ctx(struct xhci_hcd *xhci, - struct xhci_ep_ctx *ep_ctx, +void xhci_setup_no_streams_ep_input_ctx(struct xhci_ep_ctx *ep_ctx, struct xhci_virt_ep *ep) { dma_addr_t addr; @@ -833,9 +832,8 @@ void xhci_free_stream_info(struct xhci_hcd *xhci, static void xhci_init_endpoint_timer(struct xhci_hcd *xhci, struct xhci_virt_ep *ep) { - init_timer(&ep->stop_cmd_timer); - ep->stop_cmd_timer.data = (unsigned long) ep; - ep->stop_cmd_timer.function = xhci_stop_endpoint_command_watchdog; + setup_timer(&ep->stop_cmd_timer, xhci_stop_endpoint_command_watchdog, + (unsigned long)ep); ep->xhci = xhci; } @@ -1342,8 +1340,7 @@ static u32 xhci_get_endpoint_mult(struct usb_device *udev, return ep->ss_ep_comp.bmAttributes; } -static u32 xhci_get_endpoint_type(struct usb_device *udev, - struct usb_host_endpoint *ep) +static u32 xhci_get_endpoint_type(struct usb_host_endpoint *ep) { int in; u32 type; @@ -1376,8 +1373,7 @@ static u32 xhci_get_endpoint_type(struct usb_device *udev, * Basically, this is the maxpacket size, multiplied by the burst size * and mult size. */ -static u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci, - struct usb_device *udev, +static u32 xhci_get_max_esit_payload(struct usb_device *udev, struct usb_host_endpoint *ep) { int max_burst; @@ -1418,7 +1414,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, ep_index = xhci_get_endpoint_index(&ep->desc); ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); - endpoint_type = xhci_get_endpoint_type(udev, ep); + endpoint_type = xhci_get_endpoint_type(ep); if (!endpoint_type) return -EINVAL; ep_ctx->ep_info2 = cpu_to_le32(endpoint_type); @@ -1484,7 +1480,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, } ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet) | MAX_BURST(max_burst)); - max_esit_payload = xhci_get_max_esit_payload(xhci, udev, ep); + max_esit_payload = xhci_get_max_esit_payload(udev, ep); ep_ctx->tx_info = cpu_to_le32(MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload)); /* @@ -1773,7 +1769,7 @@ struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, return command; } -void xhci_urb_free_priv(struct xhci_hcd *xhci, struct urb_priv *urb_priv) +void xhci_urb_free_priv(struct urb_priv *urb_priv) { if (urb_priv) { kfree(urb_priv->td[0]); @@ -1926,7 +1922,7 @@ static int xhci_test_trb_in_td(struct xhci_hcd *xhci, } /* TRB math checks for xhci_trb_in_td(), using the command and event rings. */ -static int xhci_check_trb_in_td_math(struct xhci_hcd *xhci, gfp_t mem_flags) +static int xhci_check_trb_in_td_math(struct xhci_hcd *xhci) { struct { dma_addr_t input_dma; @@ -2452,7 +2448,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) flags); if (!xhci->event_ring) goto fail; - if (xhci_check_trb_in_td_math(xhci, flags) < 0) + if (xhci_check_trb_in_td_math(xhci) < 0) goto fail; xhci->erst.entries = dma_alloc_coherent(dev, @@ -2509,9 +2505,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) xhci_print_ir_set(xhci, 0); /* init command timeout timer */ - init_timer(&xhci->cmd_timer); - xhci->cmd_timer.data = (unsigned long) xhci; - xhci->cmd_timer.function = xhci_handle_command_timeout; + setup_timer(&xhci->cmd_timer, xhci_handle_command_timeout, + (unsigned long)xhci); /* * XXX: Might need to set the Interrupter Moderation Register to diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index e692e76..88da8d6 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -299,7 +299,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci) * seconds), then it should assume that the there are * larger problems with the xHC and assert HCRST. */ - ret = xhci_handshake(xhci, &xhci->op_regs->cmd_ring, + ret = xhci_handshake(&xhci->op_regs->cmd_ring, CMD_RING_RUNNING, 0, 5 * 1000 * 1000); if (ret < 0) { xhci_err(xhci, "Stopped the command ring failed, " @@ -609,7 +609,7 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci, spin_unlock(&xhci->lock); usb_hcd_giveback_urb(hcd, urb, status); - xhci_urb_free_priv(xhci, urb_priv); + xhci_urb_free_priv(urb_priv); spin_lock(&xhci->lock); } } @@ -1110,7 +1110,7 @@ static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id, * is not waiting on the configure endpoint command. */ virt_dev = xhci->devs[slot_id]; - ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); + ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx); if (!ctrl_ctx) { xhci_warn(xhci, "Could not get input context, bad type.\n"); return; @@ -2354,8 +2354,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, status = 0; break; } - xhci_warn(xhci, "ERROR Unknown event condition, HC probably " - "busted\n"); + xhci_warn(xhci, "ERROR Unknown event condition %u, HC probably busted\n", + trb_comp_code); goto cleanup; } @@ -2497,7 +2497,7 @@ cleanup: urb = td->urb; urb_priv = urb->hcpriv; - xhci_urb_free_priv(xhci, urb_priv); + xhci_urb_free_priv(urb_priv); usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); if ((urb->actual_length != urb->transfer_buffer_length && diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index c50d8d2..ec8ac16 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -60,8 +60,7 @@ MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default"); * handshake done). There are two failure modes: "usec" have passed (major * hardware flakeout), or the register reads as all-ones (hardware removed). */ -int xhci_handshake(struct xhci_hcd *xhci, void __iomem *ptr, - u32 mask, u32 done, int usec) +int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec) { u32 result; @@ -111,7 +110,7 @@ int xhci_halt(struct xhci_hcd *xhci) xhci_dbg_trace(xhci, trace_xhci_dbg_init, "// Halt the HC"); xhci_quiesce(xhci); - ret = xhci_handshake(xhci, &xhci->op_regs->status, + ret = xhci_handshake(&xhci->op_regs->status, STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); if (!ret) { xhci->xhc_state |= XHCI_STATE_HALTED; @@ -140,7 +139,7 @@ static int xhci_start(struct xhci_hcd *xhci) * Wait for the HCHalted Status bit to be 0 to indicate the host is * running. */ - ret = xhci_handshake(xhci, &xhci->op_regs->status, + ret = xhci_handshake(&xhci->op_regs->status, STS_HALT, 0, XHCI_MAX_HALT_USEC); if (ret == -ETIMEDOUT) xhci_err(xhci, "Host took too long to start, " @@ -175,7 +174,7 @@ int xhci_reset(struct xhci_hcd *xhci) command |= CMD_RESET; writel(command, &xhci->op_regs->command); - ret = xhci_handshake(xhci, &xhci->op_regs->command, + ret = xhci_handshake(&xhci->op_regs->command, CMD_RESET, 0, 10 * 1000 * 1000); if (ret) return ret; @@ -186,7 +185,7 @@ int xhci_reset(struct xhci_hcd *xhci) * xHCI cannot write to any doorbells or operational registers other * than status until the "Controller Not Ready" flag is cleared. */ - ret = xhci_handshake(xhci, &xhci->op_regs->status, + ret = xhci_handshake(&xhci->op_regs->status, STS_CNR, 0, 10 * 1000 * 1000); for (i = 0; i < 2; ++i) { @@ -473,10 +472,8 @@ static void compliance_mode_recovery(unsigned long arg) static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci) { xhci->port_status_u0 = 0; - init_timer(&xhci->comp_mode_recovery_timer); - - xhci->comp_mode_recovery_timer.data = (unsigned long) xhci; - xhci->comp_mode_recovery_timer.function = compliance_mode_recovery; + setup_timer(&xhci->comp_mode_recovery_timer, + compliance_mode_recovery, (unsigned long)xhci); xhci->comp_mode_recovery_timer.expires = jiffies + msecs_to_jiffies(COMP_MODE_RCVRY_MSECS); @@ -929,7 +926,7 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) /* Some chips from Fresco Logic need an extraordinary delay */ delay *= (xhci->quirks & XHCI_SLOW_SUSPEND) ? 10 : 1; - if (xhci_handshake(xhci, &xhci->op_regs->status, + if (xhci_handshake(&xhci->op_regs->status, STS_HALT, STS_HALT, delay)) { xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n"); spin_unlock_irq(&xhci->lock); @@ -944,7 +941,7 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) command = readl(&xhci->op_regs->command); command |= CMD_CSS; writel(command, &xhci->op_regs->command); - if (xhci_handshake(xhci, &xhci->op_regs->status, + if (xhci_handshake(&xhci->op_regs->status, STS_SAVE, 0, 10 * 1000)) { xhci_warn(xhci, "WARN: xHC save state timeout\n"); spin_unlock_irq(&xhci->lock); @@ -1011,7 +1008,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) command = readl(&xhci->op_regs->command); command |= CMD_CRS; writel(command, &xhci->op_regs->command); - if (xhci_handshake(xhci, &xhci->op_regs->status, + if (xhci_handshake(&xhci->op_regs->status, STS_RESTORE, 0, 10 * 1000)) { xhci_warn(xhci, "WARN: xHC restore state timeout\n"); spin_unlock_irq(&xhci->lock); @@ -1082,7 +1079,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) command = readl(&xhci->op_regs->command); command |= CMD_RUN; writel(command, &xhci->op_regs->command); - xhci_handshake(xhci, &xhci->op_regs->status, STS_HALT, + xhci_handshake(&xhci->op_regs->status, STS_HALT, 0, 250 * 1000); /* step 5: walk topology and initialize portsc, @@ -1276,7 +1273,7 @@ static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id, return -ENOMEM; command->in_ctx = xhci->devs[slot_id]->in_ctx; - ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); + ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); if (!ctrl_ctx) { xhci_warn(xhci, "%s: Could not get input context, bad type.\n", __func__); @@ -1374,7 +1371,7 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) ret = xhci_check_maxpacket(xhci, slot_id, ep_index, urb); if (ret < 0) { - xhci_urb_free_priv(xhci, urb_priv); + xhci_urb_free_priv(urb_priv); urb->hcpriv = NULL; return ret; } @@ -1440,7 +1437,7 @@ dying: urb->ep->desc.bEndpointAddress, urb); ret = -ESHUTDOWN; free_priv: - xhci_urb_free_priv(xhci, urb_priv); + xhci_urb_free_priv(urb_priv); urb->hcpriv = NULL; spin_unlock_irqrestore(&xhci->lock, flags); return ret; @@ -1553,7 +1550,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) usb_hcd_unlink_urb_from_ep(hcd, urb); spin_unlock_irqrestore(&xhci->lock, flags); usb_hcd_giveback_urb(hcd, urb, -ESHUTDOWN); - xhci_urb_free_priv(xhci, urb_priv); + xhci_urb_free_priv(urb_priv); return ret; } if ((xhci->xhc_state & XHCI_STATE_DYING) || @@ -1660,7 +1657,7 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, in_ctx = xhci->devs[udev->slot_id]->in_ctx; out_ctx = xhci->devs[udev->slot_id]->out_ctx; - ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); + ctrl_ctx = xhci_get_input_control_ctx(in_ctx); if (!ctrl_ctx) { xhci_warn(xhci, "%s: Could not get input context, bad type.\n", __func__); @@ -1676,8 +1673,10 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, cpu_to_le32(EP_STATE_DISABLED)) || le32_to_cpu(ctrl_ctx->drop_flags) & xhci_get_endpoint_flag(&ep->desc)) { - xhci_warn(xhci, "xHCI %s called with disabled ep %p\n", - __func__, ep); + /* Do not warn when called after a usb_device_reset */ + if (xhci->devs[udev->slot_id]->eps[ep_index].ring != NULL) + xhci_warn(xhci, "xHCI %s called with disabled ep %p\n", + __func__, ep); return 0; } @@ -1714,7 +1713,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep) { struct xhci_hcd *xhci; - struct xhci_container_ctx *in_ctx, *out_ctx; + struct xhci_container_ctx *in_ctx; unsigned int ep_index; struct xhci_input_control_ctx *ctrl_ctx; u32 added_ctxs; @@ -1745,8 +1744,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, virt_dev = xhci->devs[udev->slot_id]; in_ctx = virt_dev->in_ctx; - out_ctx = virt_dev->out_ctx; - ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); + ctrl_ctx = xhci_get_input_control_ctx(in_ctx); if (!ctrl_ctx) { xhci_warn(xhci, "%s: Could not get input context, bad type.\n", __func__); @@ -1758,8 +1756,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, * to add it again without dropping it, reject the addition. */ if (virt_dev->eps[ep_index].ring && - !(le32_to_cpu(ctrl_ctx->drop_flags) & - xhci_get_endpoint_flag(&ep->desc))) { + !(le32_to_cpu(ctrl_ctx->drop_flags) & added_ctxs)) { xhci_warn(xhci, "Trying to add endpoint 0x%x " "without dropping it.\n", (unsigned int) ep->desc.bEndpointAddress); @@ -1769,8 +1766,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, /* If the HCD has already noted the endpoint is enabled, * ignore this request. */ - if (le32_to_cpu(ctrl_ctx->add_flags) & - xhci_get_endpoint_flag(&ep->desc)) { + if (le32_to_cpu(ctrl_ctx->add_flags) & added_ctxs) { xhci_warn(xhci, "xHCI %s called with enabled ep %p\n", __func__, ep); return 0; @@ -1816,7 +1812,7 @@ static void xhci_zero_in_ctx(struct xhci_hcd *xhci, struct xhci_virt_device *vir struct xhci_slot_ctx *slot_ctx; int i; - ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); + ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx); if (!ctrl_ctx) { xhci_warn(xhci, "%s: Could not get input context, bad type.\n", __func__); @@ -2542,7 +2538,7 @@ static int xhci_reserve_bandwidth(struct xhci_hcd *xhci, if (virt_dev->tt_info) old_active_eps = virt_dev->tt_info->active_eps; - ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); + ctrl_ctx = xhci_get_input_control_ctx(in_ctx); if (!ctrl_ctx) { xhci_warn(xhci, "%s: Could not get input context, bad type.\n", __func__); @@ -2639,7 +2635,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, spin_lock_irqsave(&xhci->lock, flags); virt_dev = xhci->devs[udev->slot_id]; - ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); + ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); if (!ctrl_ctx) { spin_unlock_irqrestore(&xhci->lock, flags); xhci_warn(xhci, "%s: Could not get input context, bad type.\n", @@ -2758,7 +2754,7 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) command->in_ctx = virt_dev->in_ctx; /* See section 4.6.6 - A0 = 1; A1 = D0 = D1 = 0 */ - ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); + ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); if (!ctrl_ctx) { xhci_warn(xhci, "%s: Could not get input context, bad type.\n", __func__); @@ -2883,7 +2879,7 @@ static void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci, dma_addr_t addr; in_ctx = xhci->devs[slot_id]->in_ctx; - ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); + ctrl_ctx = xhci_get_input_control_ctx(in_ctx); if (!ctrl_ctx) { xhci_warn(xhci, "%s: Could not get input context, bad type.\n", __func__); @@ -3173,7 +3169,7 @@ int xhci_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev, xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); return -ENOMEM; } - ctrl_ctx = xhci_get_input_control_ctx(xhci, config_cmd->in_ctx); + ctrl_ctx = xhci_get_input_control_ctx(config_cmd->in_ctx); if (!ctrl_ctx) { xhci_warn(xhci, "%s: Could not get input context, bad type.\n", __func__); @@ -3328,7 +3324,7 @@ int xhci_free_streams(struct usb_hcd *hcd, struct usb_device *udev, */ ep_index = xhci_get_endpoint_index(&eps[0]->desc); command = vdev->eps[ep_index].stream_info->free_streams_command; - ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); + ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); if (!ctrl_ctx) { spin_unlock_irqrestore(&xhci->lock, flags); xhci_warn(xhci, "%s: Could not get input context, bad type.\n", @@ -3346,7 +3342,7 @@ int xhci_free_streams(struct usb_hcd *hcd, struct usb_device *udev, xhci_endpoint_copy(xhci, command->in_ctx, vdev->out_ctx, ep_index); - xhci_setup_no_streams_ep_input_ctx(xhci, ep_ctx, + xhci_setup_no_streams_ep_input_ctx(ep_ctx, &vdev->eps[ep_index]); } xhci_setup_input_ctx_for_config_ep(xhci, command->in_ctx, @@ -3820,7 +3816,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, command->completion = &xhci->addr_dev; slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); - ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); + ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx); if (!ctrl_ctx) { xhci_warn(xhci, "%s: Could not get input context, bad type.\n", __func__); @@ -4003,7 +3999,7 @@ static int __maybe_unused xhci_change_max_exit_latency(struct xhci_hcd *xhci, /* Attempt to issue an Evaluate Context command to change the MEL. */ command = xhci->lpm_command; - ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); + ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); if (!ctrl_ctx) { spin_unlock_irqrestore(&xhci->lock, flags); xhci_warn(xhci, "%s: Could not get input context, bad type.\n", @@ -4741,7 +4737,7 @@ int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); return -ENOMEM; } - ctrl_ctx = xhci_get_input_control_ctx(xhci, config_cmd->in_ctx); + ctrl_ctx = xhci_get_input_control_ctx(config_cmd->in_ctx); if (!ctrl_ctx) { xhci_warn(xhci, "%s: Could not get input context, bad type.\n", __func__); @@ -4910,6 +4906,10 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) if (retval) goto error; xhci_dbg(xhci, "Called HCD init\n"); + + xhci_info(xhci, "hcc params 0x%08x hci version 0x%x quirks 0x%08x\n", + xhci->hcc_params, xhci->hci_version, xhci->quirks); + return 0; error: kfree(xhci); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index cc7c5bb..9745147 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1605,6 +1605,8 @@ static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci) dev_warn(xhci_to_hcd(xhci)->self.controller , fmt , ## args) #define xhci_warn_ratelimited(xhci, fmt, args...) \ dev_warn_ratelimited(xhci_to_hcd(xhci)->self.controller , fmt , ## args) +#define xhci_info(xhci, fmt, args...) \ + dev_info(xhci_to_hcd(xhci)->self.controller , fmt , ## args) /* * Registers should always be accessed with double word or quad word accesses. @@ -1712,8 +1714,7 @@ void xhci_free_stream_info(struct xhci_hcd *xhci, void xhci_setup_streams_ep_input_ctx(struct xhci_hcd *xhci, struct xhci_ep_ctx *ep_ctx, struct xhci_stream_info *stream_info); -void xhci_setup_no_streams_ep_input_ctx(struct xhci_hcd *xhci, - struct xhci_ep_ctx *ep_ctx, +void xhci_setup_no_streams_ep_input_ctx(struct xhci_ep_ctx *ep_ctx, struct xhci_virt_ep *ep); void xhci_free_device_endpoint_resources(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, bool drop_control_ep); @@ -1727,14 +1728,13 @@ struct xhci_ring *xhci_stream_id_to_ring( struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, bool allocate_in_ctx, bool allocate_completion, gfp_t mem_flags); -void xhci_urb_free_priv(struct xhci_hcd *xhci, struct urb_priv *urb_priv); +void xhci_urb_free_priv(struct urb_priv *urb_priv); void xhci_free_command(struct xhci_hcd *xhci, struct xhci_command *command); /* xHCI host controller glue */ typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *); -int xhci_handshake(struct xhci_hcd *xhci, void __iomem *ptr, - u32 mask, u32 done, int usec); +int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec); void xhci_quiesce(struct xhci_hcd *xhci); int xhci_halt(struct xhci_hcd *xhci); int xhci_reset(struct xhci_hcd *xhci); @@ -1864,7 +1864,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, void xhci_ring_device(struct xhci_hcd *xhci, int slot_id); /* xHCI contexts */ -struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); +struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_container_ctx *ctx); struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index); diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 37b44b0..6431d08 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c @@ -299,9 +299,7 @@ static inline void mts_show_command(struct scsi_cmnd *srb) MTS_DEBUG( "Command %s (%d bytes)\n", what, srb->cmd_len); out: - MTS_DEBUG( " %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", - srb->cmnd[0], srb->cmnd[1], srb->cmnd[2], srb->cmnd[3], srb->cmnd[4], srb->cmnd[5], - srb->cmnd[6], srb->cmnd[7], srb->cmnd[8], srb->cmnd[9]); + MTS_DEBUG( " %10ph\n", srb->cmnd); } #else diff --git a/drivers/usb/isp1760/isp1760-hcd.c b/drivers/usb/isp1760/isp1760-hcd.c index 996b2c1..eba9b82 100644 --- a/drivers/usb/isp1760/isp1760-hcd.c +++ b/drivers/usb/isp1760/isp1760-hcd.c @@ -1335,9 +1335,7 @@ static int isp1760_run(struct usb_hcd *hcd) if (retval) return retval; - init_timer(&errata2_timer); - errata2_timer.function = errata2_function; - errata2_timer.data = (unsigned long) hcd; + setup_timer(&errata2_timer, errata2_function, (unsigned long)hcd); errata2_timer.expires = jiffies + SLOT_CHECK_PERIOD * HZ / 1000; add_timer(&errata2_timer); @@ -1774,13 +1772,13 @@ static void isp1760_hub_descriptor(struct isp1760_hcd *priv, memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); /* per-port overcurrent reporting */ - temp = 0x0008; + temp = HUB_CHAR_INDV_PORT_OCPM; if (HCS_PPC(priv->hcs_params)) /* per-port power control */ - temp |= 0x0001; + temp |= HUB_CHAR_INDV_PORT_LPSM; else /* no power switching */ - temp |= 0x0002; + temp |= HUB_CHAR_NO_LPSM; desc->wHubCharacteristics = cpu_to_le16(temp); } @@ -2211,6 +2209,9 @@ int isp1760_hcd_register(struct isp1760_hcd *priv, void __iomem *regs, hcd->rsrc_start = mem->start; hcd->rsrc_len = resource_size(mem); + /* This driver doesn't support wakeup requests */ + hcd->cant_recv_wakeups = 1; + ret = usb_add_hcd(hcd, irq, irqflags); if (ret) goto error; diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 40ef40a..588d62a 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c @@ -124,12 +124,8 @@ static void async_complete(struct urb *urb) } else if (rq->dr->bRequest == 3) { memcpy(priv->reg, rq->reg, sizeof(priv->reg)); #if 0 - dev_dbg(&priv->usbdev->dev, - "async_complete regs %02x %02x %02x %02x %02x %02x %02x\n", - (unsigned int)priv->reg[0], (unsigned int)priv->reg[1], - (unsigned int)priv->reg[2], (unsigned int)priv->reg[3], - (unsigned int)priv->reg[4], (unsigned int)priv->reg[5], - (unsigned int)priv->reg[6]); + dev_dbg(&priv->usbdev->dev, "async_complete regs %7ph\n", + priv->reg); #endif /* if nAck interrupts are enabled and we have an interrupt, call the interrupt procedure */ if (rq->reg[2] & rq->reg[1] & 0x10 && pp) @@ -742,9 +738,7 @@ static int uss720_probe(struct usb_interface *intf, set_1284_register(pp, 2, 0x0c, GFP_KERNEL); /* debugging */ get_1284_register(pp, 0, ®, GFP_KERNEL); - dev_dbg(&intf->dev, "reg: %02x %02x %02x %02x %02x %02x %02x\n", - priv->reg[0], priv->reg[1], priv->reg[2], priv->reg[3], - priv->reg[4], priv->reg[5], priv->reg[6]); + dev_dbg(&intf->dev, "reg: %7ph\n", priv->reg); endpoint = &interface->endpoint[2]; dev_dbg(&intf->dev, "epaddr %d interval %d\n", diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index ccfdfb2..2f9735b 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c @@ -34,7 +34,7 @@ static struct usb_phy *__usb_find_phy(struct list_head *list, return phy; } - return ERR_PTR(-EPROBE_DEFER); + return ERR_PTR(-ENODEV); } static struct usb_phy *__usb_find_phy_dev(struct device *dev, diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index f4c56fc..f40c856 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -56,6 +56,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x0846, 0x1100) }, /* NetGear Managed Switch M4100 series, M5300 series, M7100 series */ { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */ + { USB_DEVICE(0x0908, 0x01FF) }, /* Siemens RUGGEDCOM USB Serial Console */ { USB_DEVICE(0x0BED, 0x1100) }, /* MEI (TM) Cashflow-SC Bill/Voucher Acceptor */ { USB_DEVICE(0x0BED, 0x1101) }, /* MEI series 2000 Combo Acceptor */ { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 220b4be..e4473a91 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -1309,35 +1309,6 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *current_position = data; unsigned char *data1; -#ifdef NOTMOS7840 - Data = 0x00; - status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data); - mos7840_port->shadowLCR = Data; - dev_dbg(&port->dev, "%s: LINE_CONTROL_REGISTER is %x\n", __func__, Data); - dev_dbg(&port->dev, "%s: mos7840_port->shadowLCR is %x\n", __func__, mos7840_port->shadowLCR); - - /* Data = 0x03; */ - /* status = mos7840_set_uart_reg(port,LINE_CONTROL_REGISTER,Data); */ - /* mos7840_port->shadowLCR=Data;//Need to add later */ - - Data |= SERIAL_LCR_DLAB; /* data latch enable in LCR 0x80 */ - status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data); - - /* Data = 0x0c; */ - /* status = mos7840_set_uart_reg(port,DIVISOR_LATCH_LSB,Data); */ - Data = 0x00; - status = mos7840_get_uart_reg(port, DIVISOR_LATCH_LSB, &Data); - dev_dbg(&port->dev, "%s: DLL value is %x\n", __func__, Data); - - Data = 0x0; - status = mos7840_get_uart_reg(port, DIVISOR_LATCH_MSB, &Data); - dev_dbg(&port->dev, "%s: DLM value is %x\n", __func__, Data); - - Data = Data & ~SERIAL_LCR_DLAB; - dev_dbg(&port->dev, "%s: mos7840_port->shadowLCR is %x\n", __func__, mos7840_port->shadowLCR); - status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data); -#endif - if (mos7840_port_paranoia_check(port, __func__)) return -1; @@ -1614,37 +1585,6 @@ static int mos7840_calc_baud_rate_divisor(struct usb_serial_port *port, *clk_sel_val = 0x70; } return 0; - -#ifdef NOTMCS7840 - - for (i = 0; i < ARRAY_SIZE(mos7840_divisor_table); i++) { - if (mos7840_divisor_table[i].BaudRate == baudrate) { - *divisor = mos7840_divisor_table[i].Divisor; - return 0; - } - } - - /* After trying for all the standard baud rates * - * Try calculating the divisor for this baud rate */ - - if (baudrate > 75 && baudrate < 230400) { - /* get the divisor */ - custom = (__u16) (230400L / baudrate); - - /* Check for round off */ - round1 = (__u16) (2304000L / baudrate); - round = (__u16) (round1 - (custom * 10)); - if (round > 4) - custom++; - *divisor = custom; - - dev_dbg(&port->dev, " Baud %d = %d\n", baudrate, custom); - return 0; - } - - dev_dbg(&port->dev, "%s", " Baud calculation Failed...\n"); - return -1; -#endif } /***************************************************************************** diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index efdcee1..f0c0c53 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -507,18 +507,10 @@ static void option_instat_callback(struct urb *urb); #define VIATELECOM_VENDOR_ID 0x15eb #define VIATELECOM_PRODUCT_CDS7 0x0001 -/* some devices interfaces need special handling due to a number of reasons */ -enum option_blacklist_reason { - OPTION_BLACKLIST_NONE = 0, - OPTION_BLACKLIST_SENDSETUP = 1, - OPTION_BLACKLIST_RESERVED_IF = 2 -}; - -#define MAX_BL_NUM 11 struct option_blacklist_info { - /* bitfield of interface numbers for OPTION_BLACKLIST_SENDSETUP */ + /* bitmask of interface numbers blacklisted for send_setup */ const unsigned long sendsetup; - /* bitfield of interface numbers for OPTION_BLACKLIST_RESERVED_IF */ + /* bitmask of interface numbers that are reserved */ const unsigned long reserved; }; @@ -1822,36 +1814,13 @@ struct option_private { module_usb_serial_driver(serial_drivers, option_ids); -static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason, - const struct option_blacklist_info *blacklist) -{ - unsigned long num; - const unsigned long *intf_list; - - if (blacklist) { - if (reason == OPTION_BLACKLIST_SENDSETUP) - intf_list = &blacklist->sendsetup; - else if (reason == OPTION_BLACKLIST_RESERVED_IF) - intf_list = &blacklist->reserved; - else { - BUG_ON(reason); - return false; - } - - for_each_set_bit(num, intf_list, MAX_BL_NUM + 1) { - if (num == ifnum) - return true; - } - } - return false; -} - static int option_probe(struct usb_serial *serial, const struct usb_device_id *id) { struct usb_interface_descriptor *iface_desc = &serial->interface->cur_altsetting->desc; struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; + const struct option_blacklist_info *blacklist; /* Never bind to the CD-Rom emulation interface */ if (iface_desc->bInterfaceClass == 0x08) @@ -1862,10 +1831,9 @@ static int option_probe(struct usb_serial *serial, * the same class/subclass/protocol as the serial interfaces. Look at * the Windows driver .INF files for reserved interface numbers. */ - if (is_blacklisted( - iface_desc->bInterfaceNumber, - OPTION_BLACKLIST_RESERVED_IF, - (const struct option_blacklist_info *) id->driver_info)) + blacklist = (void *)id->driver_info; + if (blacklist && test_bit(iface_desc->bInterfaceNumber, + &blacklist->reserved)) return -ENODEV; /* * Don't bind network interface on Samsung GT-B3730, it is handled by @@ -1876,8 +1844,8 @@ static int option_probe(struct usb_serial *serial, iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) return -ENODEV; - /* Store device id so we can use it during attach. */ - usb_set_serial_data(serial, (void *)id); + /* Store the blacklist info so we can use it during attach. */ + usb_set_serial_data(serial, (void *)blacklist); return 0; } @@ -1885,7 +1853,7 @@ static int option_probe(struct usb_serial *serial, static int option_attach(struct usb_serial *serial) { struct usb_interface_descriptor *iface_desc; - const struct usb_device_id *id; + const struct option_blacklist_info *blacklist; struct usb_wwan_intf_private *data; struct option_private *priv; @@ -1899,16 +1867,16 @@ static int option_attach(struct usb_serial *serial) return -ENOMEM; } - /* Retrieve device id stored at probe. */ - id = usb_get_serial_data(serial); + /* Retrieve blacklist info stored at probe. */ + blacklist = usb_get_serial_data(serial); + iface_desc = &serial->interface->cur_altsetting->desc; priv->bInterfaceNumber = iface_desc->bInterfaceNumber; data->private = priv; - if (!is_blacklisted(iface_desc->bInterfaceNumber, - OPTION_BLACKLIST_SENDSETUP, - (struct option_blacklist_info *)id->driver_info)) { + if (!blacklist || !test_bit(iface_desc->bInterfaceNumber, + &blacklist->sendsetup)) { data->send_setup = option_send_setup; } spin_lock_init(&data->susp_lock); diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 11c7a96..d684b4b 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -507,7 +507,7 @@ UNUSUAL_DEV( 0x04e6, 0x000c, 0x0100, 0x0100, UNUSUAL_DEV( 0x04e6, 0x000f, 0x0000, 0x9999, "SCM Microsystems", "eUSB SCSI Adapter (Bus Powered)", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_euscsi_init, + USB_SC_SCSI, USB_PR_BULK, usb_stor_euscsi_init, US_FL_SCM_MULT_TARG ), UNUSUAL_DEV( 0x04e6, 0x0101, 0x0200, 0x0200, @@ -1995,6 +1995,13 @@ UNUSUAL_DEV( 0x152d, 0x2329, 0x0100, 0x0100, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE | US_FL_SANE_SENSE ), +/* Reported by Dmitry Nezhevenko <dion@dion.org.ua> */ +UNUSUAL_DEV( 0x152d, 0x2566, 0x0114, 0x0114, + "JMicron", + "USB to ATA/ATAPI Bridge", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_BROKEN_FUA ), + /* Entrega Technologies U1-SC25 (later Xircom PortGear PGSCSI) * and Mac USB Dock USB-SCSI */ UNUSUAL_DEV( 0x1645, 0x0007, 0x0100, 0x0133, diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index 6df4357..dbc00e5 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h @@ -140,3 +140,10 @@ UNUSUAL_DEV(0x4971, 0x1012, 0x0000, 0x9999, "External HDD", USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_IGNORE_UAS), + +/* Reported-by: Richard Henderson <rth@redhat.com> */ +UNUSUAL_DEV(0x4971, 0x8017, 0x0000, 0x9999, + "SimpleTech", + "External HDD", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_REPORT_OPCODES), diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 1ae9d40..11f6f61 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -218,7 +218,8 @@ static inline void hub_descriptor(struct usb_hub_descriptor *desc) memset(desc, 0, sizeof(*desc)); desc->bDescriptorType = 0x29; desc->bDescLength = 9; - desc->wHubCharacteristics = (__constant_cpu_to_le16(0x0001)); + desc->wHubCharacteristics = __constant_cpu_to_le16( + HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_COMMON_OCPM); desc->bNbrPorts = VHCI_NPORTS; desc->u.hs.DeviceRemovable[0] = 0xff; desc->u.hs.DeviceRemovable[1] = 0xff; diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c index fe8bc77..aa5af81 100644 --- a/drivers/usb/wusbcore/rh.c +++ b/drivers/usb/wusbcore/rh.c @@ -185,9 +185,9 @@ static int wusbhc_rh_get_hub_descr(struct wusbhc *wusbhc, u16 wValue, descr->bDescriptorType = 0x29; /* HUB type */ descr->bNbrPorts = wusbhc->ports_max; descr->wHubCharacteristics = cpu_to_le16( - 0x00 /* All ports power at once */ + HUB_CHAR_COMMON_LPSM /* All ports power at once */ | 0x00 /* not part of compound device */ - | 0x10 /* No overcurrent protection */ + | HUB_CHAR_NO_OCPM /* No overcurrent protection */ | 0x00 /* 8 FS think time FIXME ?? */ | 0x00); /* No port indicators */ descr->bPwrOn2PwrGood = 0; |