aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/Makefile2
-rw-r--r--drivers/usb/class/cdc-acm.c4
-rw-r--r--drivers/usb/class/cdc-wdm.c27
-rw-r--r--drivers/usb/core/buffer.c2
-rw-r--r--drivers/usb/core/devio.c2
-rw-r--r--drivers/usb/core/hcd.c26
-rw-r--r--drivers/usb/core/hcd.h14
-rw-r--r--drivers/usb/core/message.c58
-rw-r--r--drivers/usb/core/usb.c2
-rw-r--r--drivers/usb/gadget/ci13xxx_udc.c5
-rw-r--r--drivers/usb/gadget/file_storage.c20
-rw-r--r--drivers/usb/gadget/omap_udc.c3
-rw-r--r--drivers/usb/gadget/u_ether.c8
-rw-r--r--drivers/usb/gadget/usbstring.c6
-rw-r--r--drivers/usb/host/ehci-sched.c2
-rw-r--r--drivers/usb/host/whci/asl.c15
-rw-r--r--drivers/usb/host/whci/hcd.c23
-rw-r--r--drivers/usb/host/whci/pzl.c16
-rw-r--r--drivers/usb/host/whci/qset.c24
-rw-r--r--drivers/usb/host/whci/whcd.h1
-rw-r--r--drivers/usb/host/whci/whci-hc.h1
-rw-r--r--drivers/usb/musb/cppi_dma.c23
-rw-r--r--drivers/usb/musb/musb_core.c14
-rw-r--r--drivers/usb/musb/musb_gadget.c33
-rw-r--r--drivers/usb/musb/musb_host.c406
-rw-r--r--drivers/usb/musb/musbhsdma.c66
-rw-r--r--drivers/usb/musb/omap2430.c1
-rw-r--r--drivers/usb/musb/tusb6010.c1
-rw-r--r--drivers/usb/musb/tusb6010.h1
-rw-r--r--drivers/usb/otg/nop-usb-xceiv.c4
-rw-r--r--drivers/usb/otg/otg.c3
-rw-r--r--drivers/usb/serial/cyberjack.c7
-rw-r--r--drivers/usb/serial/cypress_m8.c4
-rw-r--r--drivers/usb/serial/empeg.c6
-rw-r--r--drivers/usb/serial/ftdi_sio.c21
-rw-r--r--drivers/usb/serial/ftdi_sio.h13
-rw-r--r--drivers/usb/serial/garmin_gps.c8
-rw-r--r--drivers/usb/serial/generic.c6
-rw-r--r--drivers/usb/serial/io_edgeport.c8
-rw-r--r--drivers/usb/serial/io_ti.c8
-rw-r--r--drivers/usb/serial/ipaq.c6
-rw-r--r--drivers/usb/serial/ipw.c3
-rw-r--r--drivers/usb/serial/iuu_phoenix.c1
-rw-r--r--drivers/usb/serial/kobil_sct.c6
-rw-r--r--drivers/usb/serial/mos7720.c7
-rw-r--r--drivers/usb/serial/mos7840.c43
-rw-r--r--drivers/usb/serial/moto_modem.c1
-rw-r--r--drivers/usb/serial/opticon.c8
-rw-r--r--drivers/usb/serial/option.c8
-rw-r--r--drivers/usb/serial/qcserial.c21
-rw-r--r--drivers/usb/serial/sierra.c24
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c40
-rw-r--r--drivers/usb/serial/usb-serial.c104
-rw-r--r--drivers/usb/serial/visor.c8
-rw-r--r--drivers/usb/storage/Makefile3
-rw-r--r--drivers/usb/storage/transport.c4
-rw-r--r--drivers/usb/storage/unusual_devs.h25
-rw-r--r--drivers/usb/wusbcore/devconnect.c21
-rw-r--r--drivers/usb/wusbcore/wusbhc.c32
59 files changed, 716 insertions, 543 deletions
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index 89299a5ce16..0716cdb44cd 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -27,6 +27,8 @@ obj-$(CONFIG_USB_WUSB) += wusbcore/
obj-$(CONFIG_USB_ACM) += class/
obj-$(CONFIG_USB_PRINTER) += class/
+obj-$(CONFIG_USB_WDM) += class/
+obj-$(CONFIG_USB_TMC) += class/
obj-$(CONFIG_USB_STORAGE) += storage/
obj-$(CONFIG_USB) += storage/
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 869d47cb6db..0a69c0977e3 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -546,10 +546,6 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
tty->driver_data = acm;
acm->tty = tty;
- /* force low_latency on so that our tty_push actually forces the data through,
- otherwise it is scheduled, and with high data rates data can get lost. */
- tty->low_latency = 1;
-
if (usb_autopm_get_interface(acm->control) < 0)
goto early_bail;
else
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 3771d6e6d0c..0fe434505ac 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -3,7 +3,7 @@
*
* This driver supports USB CDC WCM Device Management.
*
- * Copyright (c) 2007-2008 Oliver Neukum
+ * Copyright (c) 2007-2009 Oliver Neukum
*
* Some code taken from cdc-acm.c
*
@@ -610,7 +610,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
if (!buffer)
goto out;
- while (buflen > 0) {
+ while (buflen > 2) {
if (buffer [1] != USB_DT_CS_INTERFACE) {
dev_err(&intf->dev, "skipping garbage\n");
goto next_desc;
@@ -646,16 +646,18 @@ next_desc:
spin_lock_init(&desc->iuspin);
init_waitqueue_head(&desc->wait);
desc->wMaxCommand = maxcom;
+ /* this will be expanded and needed in hardware endianness */
desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber);
desc->intf = intf;
INIT_WORK(&desc->rxwork, wdm_rxwork);
- iface = &intf->altsetting[0];
+ rv = -EINVAL;
+ iface = intf->cur_altsetting;
+ if (iface->desc.bNumEndpoints != 1)
+ goto err;
ep = &iface->endpoint[0].desc;
- if (!usb_endpoint_is_int_in(ep)) {
- rv = -EINVAL;
+ if (!ep || !usb_endpoint_is_int_in(ep))
goto err;
- }
desc->wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize);
desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0;
@@ -711,12 +713,19 @@ next_desc:
usb_set_intfdata(intf, desc);
rv = usb_register_dev(intf, &wdm_class);
- dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n",
- intf->minor - WDM_MINOR_BASE);
if (rv < 0)
- goto err;
+ goto err3;
+ else
+ dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n",
+ intf->minor - WDM_MINOR_BASE);
out:
return rv;
+err3:
+ usb_set_intfdata(intf, NULL);
+ usb_buffer_free(interface_to_usbdev(desc->intf),
+ desc->bMaxPacketSize0,
+ desc->inbuf,
+ desc->response->transfer_dma);
err2:
usb_buffer_free(interface_to_usbdev(desc->intf),
desc->wMaxPacketSize,
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
index cadb2dc1d28..3ba2fff7149 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -119,7 +119,7 @@ void *hcd_buffer_alloc(
if (size <= pool_max [i])
return dma_pool_alloc(hcd->pool [i], mem_flags, dma);
}
- return dma_alloc_coherent(hcd->self.controller, size, dma, 0);
+ return dma_alloc_coherent(hcd->self.controller, size, dma, mem_flags);
}
void hcd_buffer_free(
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index df3c539f652..308609039c7 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -841,7 +841,7 @@ static int proc_resetep(struct dev_state *ps, void __user *arg)
ret = checkintf(ps, ret);
if (ret)
return ret;
- usb_settoggle(ps->dev, ep & 0xf, !(ep & USB_DIR_IN), 0);
+ usb_reset_endpoint(ps->dev, ep);
return 0;
}
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 81fa8506825..42b93da1085 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1539,6 +1539,32 @@ void usb_hcd_disable_endpoint(struct usb_device *udev,
hcd->driver->endpoint_disable(hcd, ep);
}
+/**
+ * usb_hcd_reset_endpoint - reset host endpoint state
+ * @udev: USB device.
+ * @ep: the endpoint to reset.
+ *
+ * Resets any host endpoint state such as the toggle bit, sequence
+ * number and current window.
+ */
+void usb_hcd_reset_endpoint(struct usb_device *udev,
+ struct usb_host_endpoint *ep)
+{
+ struct usb_hcd *hcd = bus_to_hcd(udev->bus);
+
+ if (hcd->driver->endpoint_reset)
+ hcd->driver->endpoint_reset(hcd, ep);
+ else {
+ int epnum = usb_endpoint_num(&ep->desc);
+ int is_out = usb_endpoint_dir_out(&ep->desc);
+ int is_control = usb_endpoint_xfer_control(&ep->desc);
+
+ usb_settoggle(udev, epnum, is_out, 0);
+ if (is_control)
+ usb_settoggle(udev, epnum, !is_out, 0);
+ }
+}
+
/* Protect against drivers that try to unlink URBs after the device
* is gone, by waiting until all unlinks for @udev are finished.
* Since we don't currently track URBs by device, simply wait until
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index f750eb1ab59..e7d4479de41 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -206,6 +206,11 @@ struct hc_driver {
void (*endpoint_disable)(struct usb_hcd *hcd,
struct usb_host_endpoint *ep);
+ /* (optional) reset any endpoint state such as sequence number
+ and current window */
+ void (*endpoint_reset)(struct usb_hcd *hcd,
+ struct usb_host_endpoint *ep);
+
/* root hub support */
int (*hub_status_data) (struct usb_hcd *hcd, char *buf);
int (*hub_control) (struct usb_hcd *hcd,
@@ -234,6 +239,8 @@ extern void usb_hcd_flush_endpoint(struct usb_device *udev,
struct usb_host_endpoint *ep);
extern void usb_hcd_disable_endpoint(struct usb_device *udev,
struct usb_host_endpoint *ep);
+extern void usb_hcd_reset_endpoint(struct usb_device *udev,
+ struct usb_host_endpoint *ep);
extern void usb_hcd_synchronize_unlinks(struct usb_device *udev);
extern int usb_hcd_get_frame_number(struct usb_device *udev);
@@ -279,6 +286,13 @@ extern irqreturn_t usb_hcd_irq(int irq, void *__hcd);
extern void usb_hc_died(struct usb_hcd *hcd);
extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd);
+/* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */
+#define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1)
+#define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep)))
+#define usb_settoggle(dev, ep, out, bit) \
+ ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | \
+ ((bit) << (ep)))
+
/* -------------------------------------------------------------------------- */
/* Enumeration is only for the hub driver, or HCD virtual root hubs */
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 30a0690f368..b6262837765 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1002,8 +1002,7 @@ int usb_clear_halt(struct usb_device *dev, int pipe)
* the copy in usb-storage, for as long as we need two copies.
*/
- /* toggle was reset by the clear */
- usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0);
+ usb_reset_endpoint(dev, endp);
return 0;
}
@@ -1076,6 +1075,30 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr,
}
/**
+ * usb_reset_endpoint - Reset an endpoint's state.
+ * @dev: the device whose endpoint is to be reset
+ * @epaddr: the endpoint's address. Endpoint number for output,
+ * endpoint number + USB_DIR_IN for input
+ *
+ * Resets any host-side endpoint state such as the toggle bit,
+ * sequence number or current window.
+ */
+void usb_reset_endpoint(struct usb_device *dev, unsigned int epaddr)
+{
+ unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
+ struct usb_host_endpoint *ep;
+
+ if (usb_endpoint_out(epaddr))
+ ep = dev->ep_out[epnum];
+ else
+ ep = dev->ep_in[epnum];
+ if (ep)
+ usb_hcd_reset_endpoint(dev, ep);
+}
+EXPORT_SYMBOL_GPL(usb_reset_endpoint);
+
+
+/**
* usb_disable_interface -- Disable all endpoints for an interface
* @dev: the device whose interface is being disabled
* @intf: pointer to the interface descriptor
@@ -1117,7 +1140,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
usb_disable_endpoint(dev, i, true);
usb_disable_endpoint(dev, i + USB_DIR_IN, true);
}
- dev->toggle[0] = dev->toggle[1] = 0;
/* getting rid of interfaces will disconnect
* any drivers bound to them (a key side effect)
@@ -1154,28 +1176,24 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
* usb_enable_endpoint - Enable an endpoint for USB communications
* @dev: the device whose interface is being enabled
* @ep: the endpoint
- * @reset_toggle: flag to set the endpoint's toggle back to 0
+ * @reset_ep: flag to reset the endpoint state
*
- * Resets the endpoint toggle if asked, and sets dev->ep_{in,out} pointers.
+ * Resets the endpoint state if asked, and sets dev->ep_{in,out} pointers.
* For control endpoints, both the input and output sides are handled.
*/
void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep,
- bool reset_toggle)
+ bool reset_ep)
{
int epnum = usb_endpoint_num(&ep->desc);
int is_out = usb_endpoint_dir_out(&ep->desc);
int is_control = usb_endpoint_xfer_control(&ep->desc);
- if (is_out || is_control) {
- if (reset_toggle)
- usb_settoggle(dev, epnum, 1, 0);
+ if (reset_ep)
+ usb_hcd_reset_endpoint(dev, ep);
+ if (is_out || is_control)
dev->ep_out[epnum] = ep;
- }
- if (!is_out || is_control) {
- if (reset_toggle)
- usb_settoggle(dev, epnum, 0, 0);
+ if (!is_out || is_control)
dev->ep_in[epnum] = ep;
- }
ep->enabled = 1;
}
@@ -1183,18 +1201,18 @@ void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep,
* usb_enable_interface - Enable all the endpoints for an interface
* @dev: the device whose interface is being enabled
* @intf: pointer to the interface descriptor
- * @reset_toggles: flag to set the endpoints' toggles back to 0
+ * @reset_eps: flag to reset the endpoints' state
*
* Enables all the endpoints for the interface's current altsetting.
*/
void usb_enable_interface(struct usb_device *dev,
- struct usb_interface *intf, bool reset_toggles)
+ struct usb_interface *intf, bool reset_eps)
{
struct usb_host_interface *alt = intf->cur_altsetting;
int i;
for (i = 0; i < alt->desc.bNumEndpoints; ++i)
- usb_enable_endpoint(dev, &alt->endpoint[i], reset_toggles);
+ usb_enable_endpoint(dev, &alt->endpoint[i], reset_eps);
}
/**
@@ -1335,7 +1353,7 @@ EXPORT_SYMBOL_GPL(usb_set_interface);
* This issues a standard SET_CONFIGURATION request to the device using
* the current configuration. The effect is to reset most USB-related
* state in the device, including interface altsettings (reset to zero),
- * endpoint halts (cleared), and data toggle (only for bulk and interrupt
+ * endpoint halts (cleared), and endpoint state (only for bulk and interrupt
* endpoints). Other usbcore state is unchanged, including bindings of
* usb device drivers to interfaces.
*
@@ -1343,7 +1361,7 @@ EXPORT_SYMBOL_GPL(usb_set_interface);
* (multi-interface) devices. Instead, the driver for each interface may
* use usb_set_interface() on the interfaces it claims. Be careful though;
* some devices don't support the SET_INTERFACE request, and others won't
- * reset all the interface state (notably data toggles). Resetting the whole
+ * reset all the interface state (notably endpoint state). Resetting the whole
* configuration would affect other drivers' interfaces.
*
* The caller must own the device lock.
@@ -1376,8 +1394,6 @@ int usb_reset_configuration(struct usb_device *dev)
if (retval < 0)
return retval;
- dev->toggle[0] = dev->toggle[1] = 0;
-
/* re-init hc/hcd interface/endpoint state */
for (i = 0; i < config->desc.bNumInterfaces; i++) {
struct usb_interface *intf = config->interface[i];
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index dcfc072630c..7eee400d3e3 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -362,7 +362,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE;
dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT;
/* ep0 maxpacket comes later, from device descriptor */
- usb_enable_endpoint(dev, &dev->ep0, true);
+ usb_enable_endpoint(dev, &dev->ep0, false);
dev->can_submit = 1;
/* Save readable and stable topology id, distinguishing devices
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 22c65960c42..38e531ecae4 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -51,6 +51,7 @@
* - Gadget API (majority of optional features)
* - Suspend & Remote Wakeup
*/
+#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dmapool.h>
#include <linux/dma-mapping.h>
@@ -142,7 +143,7 @@ static struct {
#define CAP_DEVICEADDR (0x014UL)
#define CAP_ENDPTLISTADDR (0x018UL)
#define CAP_PORTSC (0x044UL)
-#define CAP_DEVLC (0x0B4UL)
+#define CAP_DEVLC (0x084UL)
#define CAP_USBMODE (hw_bank.lpm ? 0x0C8UL : 0x068UL)
#define CAP_ENDPTSETUPSTAT (hw_bank.lpm ? 0x0D8UL : 0x06CUL)
#define CAP_ENDPTPRIME (hw_bank.lpm ? 0x0DCUL : 0x070UL)
@@ -1986,6 +1987,8 @@ static int ep_enable(struct usb_ep *ep,
do {
dbg_event(_usb_addr(mEp), "ENABLE", 0);
+ mEp->qh[mEp->dir].ptr->cap = 0;
+
if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
mEp->qh[mEp->dir].ptr->cap |= QH_IOS;
else if (mEp->type == USB_ENDPOINT_XFER_ISOC)
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 5c030b080d4..381a53b3e11 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -738,7 +738,6 @@ static struct fsg_dev *the_fsg;
static struct usb_gadget_driver fsg_driver;
static void close_backing_file(struct lun *curlun);
-static void close_all_backing_files(struct fsg_dev *fsg);
/*-------------------------------------------------------------------------*/
@@ -3593,12 +3592,10 @@ static int fsg_main_thread(void *fsg_)
fsg->thread_task = NULL;
spin_unlock_irq(&fsg->lock);
- /* In case we are exiting because of a signal, unregister the
- * gadget driver and close the backing file. */
- if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags)) {
+ /* If we are exiting because of a signal, unregister the
+ * gadget driver. */
+ if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags))
usb_gadget_unregister_driver(&fsg_driver);
- close_all_backing_files(fsg);
- }
/* Let the unbind and cleanup routines know the thread has exited */
complete_and_exit(&fsg->thread_notifier, 0);
@@ -3703,14 +3700,6 @@ static void close_backing_file(struct lun *curlun)
}
}
-static void close_all_backing_files(struct fsg_dev *fsg)
-{
- int i;
-
- for (i = 0; i < fsg->nluns; ++i)
- close_backing_file(&fsg->luns[i]);
-}
-
static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char *buf)
{
@@ -3845,6 +3834,7 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
if (curlun->registered) {
device_remove_file(&curlun->dev, &dev_attr_ro);
device_remove_file(&curlun->dev, &dev_attr_file);
+ close_backing_file(curlun);
device_unregister(&curlun->dev);
curlun->registered = 0;
}
@@ -4190,7 +4180,6 @@ autoconf_fail:
out:
fsg->state = FSG_STATE_TERMINATED; // The thread is dead
fsg_unbind(gadget);
- close_all_backing_files(fsg);
complete(&fsg->thread_notifier);
return rc;
}
@@ -4284,7 +4273,6 @@ static void __exit fsg_cleanup(void)
/* Wait for the thread to finish up */
wait_for_completion(&fsg->thread_notifier);
- close_all_backing_files(fsg);
kref_put(&fsg->ref, fsg_release);
}
module_exit(fsg_cleanup);
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 57d9641c6bf..a2db0e174f2 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -3104,7 +3104,6 @@ static int omap_udc_resume(struct platform_device *dev)
/*-------------------------------------------------------------------------*/
static struct platform_driver udc_driver = {
- .probe = omap_udc_probe,
.remove = __exit_p(omap_udc_remove),
.suspend = omap_udc_suspend,
.resume = omap_udc_resume,
@@ -3122,7 +3121,7 @@ static int __init udc_init(void)
#endif
"%s\n", driver_desc,
use_dma ? " (dma)" : "");
- return platform_driver_register(&udc_driver);
+ return platform_driver_probe(&udc_driver, omap_udc_probe);
}
module_init(udc_init);
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index 96d65ca06ec..4007770f7ed 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -175,12 +175,6 @@ static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p)
strlcpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof p->bus_info);
}
-static u32 eth_get_link(struct net_device *net)
-{
- struct eth_dev *dev = netdev_priv(net);
- return dev->gadget->speed != USB_SPEED_UNKNOWN;
-}
-
/* REVISIT can also support:
* - WOL (by tracking suspends and issuing remote wakeup)
* - msglevel (implies updated messaging)
@@ -189,7 +183,7 @@ static u32 eth_get_link(struct net_device *net)
static struct ethtool_ops ops = {
.get_drvinfo = eth_get_drvinfo,
- .get_link = eth_get_link
+ .get_link = ethtool_op_get_link,
};
static void defer_kevent(struct eth_dev *dev, int flag)
diff --git a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c
index 4154be375c7..58c4d37d312 100644
--- a/drivers/usb/gadget/usbstring.c
+++ b/drivers/usb/gadget/usbstring.c
@@ -38,7 +38,7 @@ static int utf8_to_utf16le(const char *s, __le16 *cp, unsigned len)
uchar = (c & 0x1f) << 6;
c = (u8) *s++;
- if ((c & 0xc0) != 0xc0)
+ if ((c & 0xc0) != 0x80)
goto fail;
c &= 0x3f;
uchar |= c;
@@ -49,13 +49,13 @@ static int utf8_to_utf16le(const char *s, __le16 *cp, unsigned len)
uchar = (c & 0x0f) << 12;
c = (u8) *s++;
- if ((c & 0xc0) != 0xc0)
+ if ((c & 0xc0) != 0x80)
goto fail;
c &= 0x3f;
uchar |= c << 6;
c = (u8) *s++;
- if ((c & 0xc0) != 0xc0)
+ if ((c & 0xc0) != 0x80)
goto fail;
c &= 0x3f;
uchar |= c;
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index ada5d2ba297..556d0ec0c1f 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -323,7 +323,7 @@ static int tt_available (
* already scheduled transactions
*/
if (125 < usecs) {
- int ufs = (usecs / 125) - 1;
+ int ufs = (usecs / 125);
int i;
for (i = uframe; i < (uframe + ufs) && i < 8; i++)
if (0 < tt_usecs[i]) {
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c
index 958751ccea4..c2050785a81 100644
--- a/drivers/usb/host/whci/asl.c
+++ b/drivers/usb/host/whci/asl.c
@@ -122,7 +122,8 @@ static uint32_t process_qset(struct whc *whc, struct whc_qset *qset)
process_inactive_qtd(whc, qset, td);
}
- update |= qset_add_qtds(whc, qset);
+ if (!qset->remove)
+ update |= qset_add_qtds(whc, qset);
done:
/*
@@ -254,23 +255,29 @@ int asl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags)
spin_lock_irqsave(&whc->lock, flags);
+ err = usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
+ if (err < 0) {
+ spin_unlock_irqrestore(&whc->lock, flags);
+ return err;
+ }
+
qset = get_qset(whc, urb, GFP_ATOMIC);
if (qset == NULL)
err = -ENOMEM;
else
err = qset_add_urb(whc, qset, urb, GFP_ATOMIC);
if (!err) {
- usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
if (!qset->in_sw_list)
asl_qset_insert_begin(whc, qset);
- }
+ } else
+ usb_hcd_unlink_urb_from_ep(&whc->wusbhc.usb_hcd, urb);
spin_unlock_irqrestore(&whc->lock, flags);
if (!err)
queue_work(whc->workqueue, &whc->async_work);
- return 0;
+ return err;
}
/**
diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c
index 1569afd6245..e019a5058ab 100644
--- a/drivers/usb/host/whci/hcd.c
+++ b/drivers/usb/host/whci/hcd.c
@@ -186,6 +186,28 @@ static void whc_endpoint_disable(struct usb_hcd *usb_hcd,
}
}
+static void whc_endpoint_reset(struct usb_hcd *usb_hcd,
+ struct usb_host_endpoint *ep)
+{