From a19a6ee6cad2b20292a774c2f56ba8039b0fac9c Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Wed, 17 Feb 2010 16:39:44 -0500 Subject: backlight: Allow properties to be passed at registration Values such as max_brightness should be set before backlights are registered, but the current API doesn't allow that. Add a parameter to backlight_device_register and update drivers to ensure that they set this correctly. Signed-off-by: Matthew Garrett Signed-off-by: Richard Purdie --- drivers/usb/misc/appledisplay.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index 4d2952f1fb13..3adab041355a 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c @@ -202,6 +202,7 @@ static void appledisplay_work(struct work_struct *work) static int appledisplay_probe(struct usb_interface *iface, const struct usb_device_id *id) { + struct backlight_properties props; struct appledisplay *pdata; struct usb_device *udev = interface_to_usbdev(iface); struct usb_host_interface *iface_desc; @@ -279,16 +280,16 @@ static int appledisplay_probe(struct usb_interface *iface, /* Register backlight device */ snprintf(bl_name, sizeof(bl_name), "appledisplay%d", atomic_inc_return(&count_displays) - 1); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 0xff; pdata->bd = backlight_device_register(bl_name, NULL, pdata, - &appledisplay_bl_data); + &appledisplay_bl_data, &props); if (IS_ERR(pdata->bd)) { dev_err(&iface->dev, "Backlight registration failed\n"); retval = PTR_ERR(pdata->bd); goto error; } - pdata->bd->props.max_brightness = 0xff; - /* Try to get brightness */ brightness = appledisplay_bl_get_brightness(pdata->bd); -- cgit v1.2.2 From 336cee42dd52824e360ab419eab4e8888eb054ec Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Mon, 8 Mar 2010 21:50:11 -0600 Subject: tty_port,usb-console: Fix usb serial console open/close regression Commit e1108a63e10d344284011cccc06328b2cd3e5da3 ("usb_serial: Use the shutdown() operation") breaks the ability to use a usb console starting in 2.6.33. This was observed when using console=ttyUSB0,115200 as a boot argument with an FTDI device. The error is: ftdi_sio ttyUSB0: ftdi_submit_read_urb - failed submitting read urb, error -22 The handling of the ASYNCB_INITIALIZED changed in 2.6.32 such that in tty_port_shutdown() it always clears the flag if it is set. The fix is to add a variable to the tty_port struct to indicate when the tty port is a console. CC: Alan Cox CC: Alan Stern CC: Oliver Neukum CC: Andrew Morton Signed-off-by: Jason Wessel Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/console.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index b22ac3258523..f347da2ef00a 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c @@ -181,6 +181,7 @@ static int usb_console_setup(struct console *co, char *options) /* The console is special in terms of closing the device so * indicate this port is now acting as a system console. */ port->console = 1; + port->port.console = 1; mutex_unlock(&serial->disc_mutex); return retval; -- cgit v1.2.2 From 7152b592593b9d48b33f8997b1dfd6df9143f7ec Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Sat, 6 Mar 2010 15:04:03 -0500 Subject: USB: fix usbfs regression This patch (as1352) fixes a bug in the way isochronous input data is returned to userspace for usbfs transfers. The entire buffer must be copied, not just the first actual_length bytes, because the individual packets will be discontiguous if any of them are short. Reported-by: Markus Rechberger Signed-off-by: Alan Stern CC: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index e909ff7b9094..3466fdc5bb11 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1207,6 +1207,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, free_async(as); return -ENOMEM; } + /* Isochronous input data may end up being discontiguous + * if some of the packets are short. Clear the buffer so + * that the gaps don't leak kernel data to userspace. + */ + if (is_in && uurb->type == USBDEVFS_URB_TYPE_ISO) + memset(as->urb->transfer_buffer, 0, + uurb->buffer_length); } as->urb->dev = ps->dev; as->urb->pipe = (uurb->type << 30) | @@ -1345,10 +1352,14 @@ static int processcompl(struct async *as, void __user * __user *arg) void __user *addr = as->userurb; unsigned int i; - if (as->userbuffer && urb->actual_length) - if (copy_to_user(as->userbuffer, urb->transfer_buffer, - urb->actual_length)) + if (as->userbuffer && urb->actual_length) { + if (urb->number_of_packets > 0) /* Isochronous */ + i = urb->transfer_buffer_length; + else /* Non-Isoc */ + i = urb->actual_length; + if (copy_to_user(as->userbuffer, urb->transfer_buffer, i)) goto err_out; + } if (put_user(as->status, &userurb->status)) goto err_out; if (put_user(urb->actual_length, &userurb->actual_length)) -- cgit v1.2.2 From 0ae1474367a15e1b65a9deed3a73a14475a419fc Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sat, 27 Feb 2010 14:05:46 +0100 Subject: USB: serial: fix error message on close in generic driver Resubmitting read urb fails with -EPERM if completion handler runs while urb is being killed on close. This should not be reported as an error. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/generic.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 89fac36684c5..e560d1d7f628 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -415,11 +415,13 @@ void usb_serial_generic_resubmit_read_urb(struct usb_serial_port *port, ((serial->type->read_bulk_callback) ? serial->type->read_bulk_callback : usb_serial_generic_read_bulk_callback), port); + result = usb_submit_urb(urb, mem_flags); - if (result) + if (result && result != -EPERM) { dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result); + } } EXPORT_SYMBOL_GPL(usb_serial_generic_resubmit_read_urb); -- cgit v1.2.2 From 6313620228624ff4dcb78b1dbd459d0c208df126 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sat, 27 Feb 2010 14:06:07 +0100 Subject: USB: serial: fix softint not being called on errors Make sure usb_serial_port_softint is called on errors also when using multi urb writes. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/generic.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index e560d1d7f628..214bf25bc3b5 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -500,23 +500,18 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb) if (port->urbs_in_flight < 0) port->urbs_in_flight = 0; spin_unlock_irqrestore(&port->lock, flags); - - if (status) { - dbg("%s - nonzero multi-urb write bulk status " - "received: %d", __func__, status); - return; - } } else { port->write_urb_busy = 0; - if (status) { - dbg("%s - nonzero multi-urb write bulk status " - "received: %d", __func__, status); + if (status) kfifo_reset_out(&port->write_fifo); - } else + else usb_serial_generic_write_start(port); } + if (status) + dbg("%s - non-zero urb status: %d", __func__, status); + usb_serial_port_softint(port); } EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); -- cgit v1.2.2 From eb8878a881c306ff3eab6e741ab8fc94096f4e1a Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sat, 27 Feb 2010 16:24:49 +0100 Subject: USB: serial: use port endpoint size to determine if ep is available It is possible to have a multi-port device with a port lacking an in or out bulk endpoint. Only checking for num_bulk_in or num_bulk_out is thus not sufficient to determine whether a specific port has an in or out bulk endpoint. This fixes potential null pointer dereferences in the generic open and write routines, as well as access to uninitialised fifo in write_room and chars_in_buffer. Also let write fail with ENODEV (instead of 0) on missing out endpoint (also on zero-length writes). Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/generic.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 214bf25bc3b5..f804acb138ec 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -130,7 +130,7 @@ int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port spin_unlock_irqrestore(&port->lock, flags); /* if we have a bulk endpoint, start reading from it */ - if (serial->num_bulk_in) { + if (port->bulk_in_size) { /* Start reading from the device */ usb_fill_bulk_urb(port->read_urb, serial->dev, usb_rcvbulkpipe(serial->dev, @@ -159,10 +159,10 @@ static void generic_cleanup(struct usb_serial_port *port) dbg("%s - port %d", __func__, port->number); if (serial->dev) { - /* shutdown any bulk reads that might be going on */ - if (serial->num_bulk_out) + /* shutdown any bulk transfers that might be going on */ + if (port->bulk_out_size) usb_kill_urb(port->write_urb); - if (serial->num_bulk_in) + if (port->bulk_in_size) usb_kill_urb(port->read_urb); } } @@ -333,15 +333,15 @@ int usb_serial_generic_write(struct tty_struct *tty, dbg("%s - port %d", __func__, port->number); + /* only do something if we have a bulk out endpoint */ + if (!port->bulk_out_size) + return -ENODEV; + if (count == 0) { dbg("%s - write request of 0 bytes", __func__); return 0; } - /* only do something if we have a bulk out endpoint */ - if (!serial->num_bulk_out) - return 0; - if (serial->type->max_in_flight_urbs) return usb_serial_multi_urb_write(tty, port, buf, count); @@ -364,14 +364,19 @@ int usb_serial_generic_write_room(struct tty_struct *tty) int room = 0; dbg("%s - port %d", __func__, port->number); + + if (!port->bulk_out_size) + return 0; + spin_lock_irqsave(&port->lock, flags); if (serial->type->max_in_flight_urbs) { if (port->urbs_in_flight < serial->type->max_in_flight_urbs) room = port->bulk_out_size * (serial->type->max_in_flight_urbs - port->urbs_in_flight); - } else if (serial->num_bulk_out) + } else { room = kfifo_avail(&port->write_fifo); + } spin_unlock_irqrestore(&port->lock, flags); dbg("%s - returns %d", __func__, room); @@ -382,15 +387,18 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct usb_serial *serial = port->serial; - int chars = 0; unsigned long flags; + int chars; dbg("%s - port %d", __func__, port->number); + if (!port->bulk_out_size) + return 0; + spin_lock_irqsave(&port->lock, flags); if (serial->type->max_in_flight_urbs) chars = port->tx_bytes_flight; - else if (serial->num_bulk_out) + else chars = kfifo_len(&port->write_fifo); spin_unlock_irqrestore(&port->lock, flags); -- cgit v1.2.2 From cd0e8aa1f4d36ece677b8ecf270ba921843dc6ca Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Sat, 27 Feb 2010 22:56:28 +0100 Subject: USB: unusual_devs.h: Fix capacity for SL11R-IDE 2.6c SL11R-IDE 2.6c (at least) reports wrong capacity (one sector more). Reading that last sector causes the device not to work anymore (and looks like HAL or something does that automatically after plugging in): sd 5:0:0:0: [sdc] Device not ready sd 5:0:0:0: [sdc] Result: hostbyte=0x00 driverbyte=0x08 sd 5:0:0:0: [sdc] Sense Key : 0x2 [current] sd 5:0:0:0: [sdc] ASC=0x0 ASCQ=0x0 sd 5:0:0:0: [sdc] CDB: cdb[0]=0x28: 28 00 04 a8 b5 70 00 00 01 00 Add unusual_devs entry to fix the capacity. Signed-off-by: Ondrej Zary Signed-off-by: Phil Dibowitz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 98b549b1cab2..61c8b9df96e6 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -374,6 +374,15 @@ UNUSUAL_DEV( 0x04ce, 0x0002, 0x0074, 0x0074, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY), +/* Reported by Ondrej Zary + * The device reports one sector more and breaks when that sector is accessed + */ +UNUSUAL_DEV( 0x04ce, 0x0002, 0x026c, 0x026c, + "ScanLogic", + "SL11R-IDE", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY), + /* Reported by Kriston Fincher * Patch submitted by Sean Millichamp * This is to support the Panasonic PalmCam PV-SD4090 -- cgit v1.2.2 From bf162019b7f5bda9eb3241ae22de831df2126132 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Sun, 28 Feb 2010 13:51:29 +0800 Subject: USB: Option: Add support for a variant of DLink DWM 652 U5 I found a DLink DWM 652 U5 USB 3G modem has product ID 0xce1e instead of orignal 0xce16. The new ID is added. And I found there are two entries for 0xce16, one has raw number, the other has symbol DLINK_PRODUCT_DWM_652_U5. This is fixed too. Signed-off-by: Huang Ying Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 847b805d63a3..3ab1a0440d81 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -309,6 +309,7 @@ static int option_resume(struct usb_serial *serial); #define DLINK_VENDOR_ID 0x1186 #define DLINK_PRODUCT_DWM_652 0x3e04 #define DLINK_PRODUCT_DWM_652_U5 0xce16 +#define DLINK_PRODUCT_DWM_652_U5A 0xce1e #define QISDA_VENDOR_ID 0x1da5 #define QISDA_PRODUCT_H21_4512 0x4512 @@ -659,6 +660,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ + { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5A) }, { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, @@ -666,7 +668,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) }, { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, - { USB_DEVICE(ALINK_VENDOR_ID, 0xce16) }, { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) }, { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, -- cgit v1.2.2 From 92bc3648e6027384479852b770a542722fadee7c Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 1 Mar 2010 09:12:50 +0100 Subject: USB: EHCI: fix ITD list order When isochronous URBs are shorter than one frame and when more than one ITD in a frame has been completed before the interrupt can be handled, scan_periodic() completes the URBs in the order in which they are found in the descriptor list. Therefore, the descriptor list must contain the ITDs in the correct order, i.e., a new ITD must be linked in after any previous ITDs of the same endpoint. This should fix garbled capture data in the USB audio drivers. Signed-off-by: Clemens Ladisch Reported-by: Colin Fletcher Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-sched.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 39340ae00ac4..cd1e8bf5327e 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1565,13 +1565,27 @@ itd_patch( static inline void itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) { - /* always prepend ITD/SITD ... only QH tree is order-sensitive */ - itd->itd_next = ehci->pshadow [frame]; - itd->hw_next = ehci->periodic [frame]; - ehci->pshadow [frame].itd = itd; + union ehci_shadow *prev = &ehci->pshadow[frame]; + __hc32 *hw_p = &ehci->periodic[frame]; + union ehci_shadow here = *prev; + __hc32 type = 0; + + /* skip any iso nodes which might belong to previous microframes */ + while (here.ptr) { + type = Q_NEXT_TYPE(ehci, *hw_p); + if (type == cpu_to_hc32(ehci, Q_TYPE_QH)) + break; + prev = periodic_next_shadow(ehci, prev, type); + hw_p = shadow_next_periodic(ehci, &here, type); + here = *prev; + } + + itd->itd_next = here; + itd->hw_next = *hw_p; + prev->itd = itd; itd->frame = frame; wmb (); - ehci->periodic[frame] = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); + *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); } /* fit urb's itds into the selected schedule slot; activate as needed */ -- cgit v1.2.2 From 1082f57abfa26590b60c43f503afb24102a37016 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 1 Mar 2010 17:18:56 +0100 Subject: USB: EHCI: adjust ehci_iso_stream for changes in ehci_qh The EHCI driver stores in usb_host_endpoint.hcpriv a pointer to either an ehci_qh or an ehci_iso_stream structure, and uses the contents of the hw_info1 field to distinguish the two cases. After ehci_qh was split into hw and sw parts, ehci_iso_stream must also be adjusted so that it again looks like an ehci_qh structure. This fixes a NULL pointer access in ehci_endpoint_disable() when it tries to access qh->hw->hw_info1. Signed-off-by: Clemens Ladisch Reported-by: Colin Fletcher Cc: stable Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 2 +- drivers/usb/host/ehci-sched.c | 4 ++-- drivers/usb/host/ehci.h | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index d8d6d3461d32..dc55a62859c6 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -995,7 +995,7 @@ rescan: /* endpoints can be iso streams. for now, we don't * accelerate iso completions ... so spin a while. */ - if (qh->hw->hw_info1 == 0) { + if (qh->hw == NULL) { ehci_vdbg (ehci, "iso delay\n"); goto idle_timeout; } diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index cd1e8bf5327e..a0aaaaff2560 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1123,8 +1123,8 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb) urb->interval); } - /* if dev->ep [epnum] is a QH, info1.maxpacket is nonzero */ - } else if (unlikely (stream->hw_info1 != 0)) { + /* if dev->ep [epnum] is a QH, hw is set */ + } else if (unlikely (stream->hw != NULL)) { ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n", urb->dev->devpath, epnum, usb_pipein(urb->pipe) ? "in" : "out"); diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 2d85e21ff282..b1dce96dd621 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -394,9 +394,8 @@ struct ehci_iso_sched { * acts like a qh would, if EHCI had them for ISO. */ struct ehci_iso_stream { - /* first two fields match QH, but info1 == 0 */ - __hc32 hw_next; - __hc32 hw_info1; + /* first field matches ehci_hq, but is NULL */ + struct ehci_qh_hw *hw; u32 refcount; u8 bEndpointAddress; -- cgit v1.2.2 From f0730924e9e32bb8935c60040a26d94179355088 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Wed, 3 Mar 2010 00:37:56 +0100 Subject: USB: cdc-acm: Fix stupid NULL pointer in resume() Stupid logic bug passing a just nulled pointer Signed-off-by: Oliver Neukum Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 975d556b4787..be6331e2c276 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1441,7 +1441,7 @@ static int acm_resume(struct usb_interface *intf) wb = acm->delayed_wb; acm->delayed_wb = NULL; spin_unlock_irq(&acm->write_lock); - acm_start_wb(acm, acm->delayed_wb); + acm_start_wb(acm, wb); } else { spin_unlock_irq(&acm->write_lock); } -- cgit v1.2.2 From 0725e95ea56698774e893edb7e7276b1d6890954 Mon Sep 17 00:00:00 2001 From: Bernhard Rosenkraenzer Date: Wed, 10 Mar 2010 12:36:43 +0100 Subject: USB: qcserial: add new device ids This patch adds various USB device IDs for Gobi 2000 devices, as found in the drivers available at https://www.codeaurora.org/wiki/GOBI_Releases Signed-off-by: Bernhard Rosenkraenzer Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/qcserial.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 310ff6ec6567..53a2d5a935a2 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -47,6 +47,35 @@ static const struct usb_device_id id_table[] = { {USB_DEVICE(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ {USB_DEVICE(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ {USB_DEVICE(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */ + {USB_DEVICE(0x413c, 0x8185)}, /* Dell Gobi 2000 QDL device (N0218, VU936) */ + {USB_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ + {USB_DEVICE(0x05c6, 0x9224)}, /* Sony Gobi 2000 QDL device (N0279, VU730) */ + {USB_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ + {USB_DEVICE(0x05c6, 0x9244)}, /* Samsung Gobi 2000 QDL device (VL176) */ + {USB_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */ + {USB_DEVICE(0x03f0, 0x241d)}, /* HP Gobi 2000 QDL device (VP412) */ + {USB_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */ + {USB_DEVICE(0x05c6, 0x9214)}, /* Acer Gobi 2000 QDL device (VP413) */ + {USB_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */ + {USB_DEVICE(0x05c6, 0x9264)}, /* Asus Gobi 2000 QDL device (VR305) */ + {USB_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */ + {USB_DEVICE(0x05c6, 0x9234)}, /* Top Global Gobi 2000 QDL device (VR306) */ + {USB_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */ + {USB_DEVICE(0x05c6, 0x9274)}, /* iRex Technologies Gobi 2000 QDL device (VR307) */ + {USB_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */ + {USB_DEVICE(0x1199, 0x9000)}, /* Sierra Wireless Gobi 2000 QDL device (VT773) */ + {USB_DEVICE(0x1199, 0x9001)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9002)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9003)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9004)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9005)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9006)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9007)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9008)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9009)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x16d8, 0x8001)}, /* CMDTech Gobi 2000 QDL device (VU922) */ + {USB_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, id_table); -- cgit v1.2.2 From ae926976ac362efc9db2365a07891cc52414f2ec Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Mon, 8 Mar 2010 11:26:01 -0500 Subject: USB: musb: fix build error introduced by isoc change The recent commit "usb: musb: Fix for isochronous IN transfer" (f82a689fa) seems to have been against an older kernel version. It uses the old style naming of variables. Unfortunately, this breaks building for most MUSB users out there since "bDesiredMode" has been renamed to "desired_mode". Signed-off-by: Sonic Zhang Signed-off-by: Mike Frysinger Acked-by: Felipe Balbi Acked-by: Anand Gadiyar Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 3421cf9858b5..dec896e888db 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -1689,7 +1689,7 @@ void musb_host_rx(struct musb *musb, u8 epnum) dma->desired_mode = 1; if (rx_count < hw_ep->max_packet_sz_rx) { length = rx_count; - dma->bDesiredMode = 0; + dma->desired_mode = 0; } else { length = urb->transfer_buffer_length; } -- cgit v1.2.2 From bc75fa3825cdbbdeee3a65d91cc5583bdfe41edf Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Tue, 16 Mar 2010 14:48:45 -0600 Subject: USB: xhci: rename driver to xhci_hcd Naming consistency with other USB HCDs. Signed-off-by: Alex Chiang Cc: Sarah Sharp Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Makefile | 4 +- drivers/usb/host/xhci-hcd.c | 1916 ------------------------------------------- drivers/usb/host/xhci.c | 1916 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1918 insertions(+), 1918 deletions(-) delete mode 100644 drivers/usb/host/xhci-hcd.c create mode 100644 drivers/usb/host/xhci.c (limited to 'drivers/usb') diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 4e0c67f1f51b..b6315aa47f7a 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -12,7 +12,7 @@ fhci-objs := fhci-hcd.o fhci-hub.o fhci-q.o fhci-mem.o \ ifeq ($(CONFIG_FHCI_DEBUG),y) fhci-objs += fhci-dbg.o endif -xhci-objs := xhci-hcd.o xhci-mem.o xhci-pci.o xhci-ring.o xhci-hub.o xhci-dbg.o +xhci-hcd-objs := xhci.o xhci-mem.o xhci-pci.o xhci-ring.o xhci-hub.o xhci-dbg.o obj-$(CONFIG_USB_WHCI_HCD) += whci/ @@ -25,7 +25,7 @@ obj-$(CONFIG_USB_ISP1362_HCD) += isp1362-hcd.o obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o obj-$(CONFIG_USB_FHCI_HCD) += fhci.o -obj-$(CONFIG_USB_XHCI_HCD) += xhci.o +obj-$(CONFIG_USB_XHCI_HCD) += xhci-hcd.o obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c deleted file mode 100644 index 4cb69e0af834..000000000000 --- a/drivers/usb/host/xhci-hcd.c +++ /dev/null @@ -1,1916 +0,0 @@ -/* - * xHCI host controller driver - * - * Copyright (C) 2008 Intel Corp. - * - * Author: Sarah Sharp - * Some code borrowed from the Linux EHCI driver. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include - -#include "xhci.h" - -#define DRIVER_AUTHOR "Sarah Sharp" -#define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver" - -/* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */ -static int link_quirk; -module_param(link_quirk, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB"); - -/* TODO: copied from ehci-hcd.c - can this be refactored? */ -/* - * handshake - spin reading hc until handshake completes or fails - * @ptr: address of hc register to be read - * @mask: bits to look at in result of read - * @done: value of those bits when handshake succeeds - * @usec: timeout in microseconds - * - * Returns negative errno, or zero on success - * - * Success happens when the "mask" bits have the specified value (hardware - * handshake done). There are two failure modes: "usec" have passed (major - * hardware flakeout), or the register reads as all-ones (hardware removed). - */ -static int handshake(struct xhci_hcd *xhci, void __iomem *ptr, - u32 mask, u32 done, int usec) -{ - u32 result; - - do { - result = xhci_readl(xhci, ptr); - if (result == ~(u32)0) /* card removed */ - return -ENODEV; - result &= mask; - if (result == done) - return 0; - udelay(1); - usec--; - } while (usec > 0); - return -ETIMEDOUT; -} - -/* - * Disable interrupts and begin the xHCI halting process. - */ -void xhci_quiesce(struct xhci_hcd *xhci) -{ - u32 halted; - u32 cmd; - u32 mask; - - mask = ~(XHCI_IRQS); - halted = xhci_readl(xhci, &xhci->op_regs->status) & STS_HALT; - if (!halted) - mask &= ~CMD_RUN; - - cmd = xhci_readl(xhci, &xhci->op_regs->command); - cmd &= mask; - xhci_writel(xhci, cmd, &xhci->op_regs->command); -} - -/* - * Force HC into halt state. - * - * Disable any IRQs and clear the run/stop bit. - * HC will complete any current and actively pipelined transactions, and - * should halt within 16 microframes of the run/stop bit being cleared. - * Read HC Halted bit in the status register to see when the HC is finished. - * XXX: shouldn't we set HC_STATE_HALT here somewhere? - */ -int xhci_halt(struct xhci_hcd *xhci) -{ - xhci_dbg(xhci, "// Halt the HC\n"); - xhci_quiesce(xhci); - - return handshake(xhci, &xhci->op_regs->status, - STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); -} - -/* - * Reset a halted HC, and set the internal HC state to HC_STATE_HALT. - * - * This resets pipelines, timers, counters, state machines, etc. - * Transactions will be terminated immediately, and operational registers - * will be set to their defaults. - */ -int xhci_reset(struct xhci_hcd *xhci) -{ - u32 command; - u32 state; - - state = xhci_readl(xhci, &xhci->op_regs->status); - if ((state & STS_HALT) == 0) { - xhci_warn(xhci, "Host controller not halted, aborting reset.\n"); - return 0; - } - - xhci_dbg(xhci, "// Reset the HC\n"); - command = xhci_readl(xhci, &xhci->op_regs->command); - command |= CMD_RESET; - xhci_writel(xhci, command, &xhci->op_regs->command); - /* XXX: Why does EHCI set this here? Shouldn't other code do this? */ - xhci_to_hcd(xhci)->state = HC_STATE_HALT; - - return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000); -} - - -#if 0 -/* Set up MSI-X table for entry 0 (may claim other entries later) */ -static int xhci_setup_msix(struct xhci_hcd *xhci) -{ - int ret; - struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); - - xhci->msix_count = 0; - /* XXX: did I do this right? ixgbe does kcalloc for more than one */ - xhci->msix_entries = kmalloc(sizeof(struct msix_entry), GFP_KERNEL); - if (!xhci->msix_entries) { - xhci_err(xhci, "Failed to allocate MSI-X entries\n"); - return -ENOMEM; - } - xhci->msix_entries[0].entry = 0; - - ret = pci_enable_msix(pdev, xhci->msix_entries, xhci->msix_count); - if (ret) { - xhci_err(xhci, "Failed to enable MSI-X\n"); - goto free_entries; - } - - /* - * Pass the xhci pointer value as the request_irq "cookie". - * If more irqs are added, this will need to be unique for each one. - */ - ret = request_irq(xhci->msix_entries[0].vector, &xhci_irq, 0, - "xHCI", xhci_to_hcd(xhci)); - if (ret) { - xhci_err(xhci, "Failed to allocate MSI-X interrupt\n"); - goto disable_msix; - } - xhci_dbg(xhci, "Finished setting up MSI-X\n"); - return 0; - -disable_msix: - pci_disable_msix(pdev); -free_entries: - kfree(xhci->msix_entries); - xhci->msix_entries = NULL; - return ret; -} - -/* XXX: code duplication; can xhci_setup_msix call this? */ -/* Free any IRQs and disable MSI-X */ -static void xhci_cleanup_msix(struct xhci_hcd *xhci) -{ - struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); - if (!xhci->msix_entries) - return; - - free_irq(xhci->msix_entries[0].vector, xhci); - pci_disable_msix(pdev); - kfree(xhci->msix_entries); - xhci->msix_entries = NULL; - xhci_dbg(xhci, "Finished cleaning up MSI-X\n"); -} -#endif - -/* - * Initialize memory for HCD and xHC (one-time init). - * - * Program the PAGESIZE register, initialize the device context array, create - * device contexts (?), set up a command ring segment (or two?), create event - * ring (one for now). - */ -int xhci_init(struct usb_hcd *hcd) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - int retval = 0; - - xhci_dbg(xhci, "xhci_init\n"); - spin_lock_init(&xhci->lock); - if (link_quirk) { - xhci_dbg(xhci, "QUIRK: Not clearing Link TRB chain bits.\n"); - xhci->quirks |= XHCI_LINK_TRB_QUIRK; - } else { - xhci_dbg(xhci, "xHCI doesn't need link TRB QUIRK\n"); - } - retval = xhci_mem_init(xhci, GFP_KERNEL); - xhci_dbg(xhci, "Finished xhci_init\n"); - - return retval; -} - -/* - * Called in interrupt context when there might be work - * queued on the event ring - * - * xhci->lock must be held by caller. - */ -static void xhci_work(struct xhci_hcd *xhci) -{ - u32 temp; - u64 temp_64; - - /* - * Clear the op reg interrupt status first, - * so we can receive interrupts from other MSI-X interrupters. - * Write 1 to clear the interrupt status. - */ - temp = xhci_readl(xhci, &xhci->op_regs->status); - temp |= STS_EINT; - xhci_writel(xhci, temp, &xhci->op_regs->status); - /* FIXME when MSI-X is supported and there are multiple vectors */ - /* Clear the MSI-X event interrupt status */ - - /* Acknowledge the interrupt */ - temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); - temp |= 0x3; - xhci_writel(xhci, temp, &xhci->ir_set->irq_pending); - /* Flush posted writes */ - xhci_readl(xhci, &xhci->ir_set->irq_pending); - - if (xhci->xhc_state & XHCI_STATE_DYING) - xhci_dbg(xhci, "xHCI dying, ignoring interrupt. " - "Shouldn't IRQs be disabled?\n"); - else - /* FIXME this should be a delayed service routine - * that clears the EHB. - */ - xhci_handle_event(xhci); - - /* Clear the event handler busy flag (RW1C); the event ring should be empty. */ - temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); - xhci_write_64(xhci, temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue); - /* Flush posted writes -- FIXME is this necessary? */ - xhci_readl(xhci, &xhci->ir_set->irq_pending); -} - -/*-------------------------------------------------------------------------*/ - -/* - * xHCI spec says we can get an interrupt, and if the HC has an error condition, - * we might get bad data out of the event ring. Section 4.10.2.7 has a list of - * indicators of an event TRB error, but we check the status *first* to be safe. - */ -irqreturn_t xhci_irq(struct usb_hcd *hcd) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - u32 temp, temp2; - union xhci_trb *trb; - - spin_lock(&xhci->lock); - trb = xhci->event_ring->dequeue; - /* Check if the xHC generated the interrupt, or the irq is shared */ - temp = xhci_readl(xhci, &xhci->op_regs->status); - temp2 = xhci_readl(xhci, &xhci->ir_set->irq_pending); - if (temp == 0xffffffff && temp2 == 0xffffffff) - goto hw_died; - - if (!(temp & STS_EINT) && !ER_IRQ_PENDING(temp2)) { - spin_unlock(&xhci->lock); - return IRQ_NONE; - } - xhci_dbg(xhci, "op reg status = %08x\n", temp); - xhci_dbg(xhci, "ir set irq_pending = %08x\n", temp2); - xhci_dbg(xhci, "Event ring dequeue ptr:\n"); - xhci_dbg(xhci, "@%llx %08x %08x %08x %08x\n", - (unsigned long long)xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, trb), - lower_32_bits(trb->link.segment_ptr), - upper_32_bits(trb->link.segment_ptr), - (unsigned int) trb->link.intr_target, - (unsigned int) trb->link.control); - - if (temp & STS_FATAL) { - xhci_warn(xhci, "WARNING: Host System Error\n"); - xhci_halt(xhci); -hw_died: - xhci_to_hcd(xhci)->state = HC_STATE_HALT; - spin_unlock(&xhci->lock); - return -ESHUTDOWN; - } - - xhci_work(xhci); - spin_unlock(&xhci->lock); - - return IRQ_HANDLED; -} - -#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING -void xhci_event_ring_work(unsigned long arg) -{ - unsigned long flags; - int temp; - u64 temp_64; - struct xhci_hcd *xhci = (struct xhci_hcd *) arg; - int i, j; - - xhci_dbg(xhci, "Poll event ring: %lu\n", jiffies); - - spin_lock_irqsave(&xhci->lock, flags); - temp = xhci_readl(xhci, &xhci->op_regs->status); - xhci_dbg(xhci, "op reg status = 0x%x\n", temp); - if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) { - xhci_dbg(xhci, "HW died, polling stopped.\n"); - spin_unlock_irqrestore(&xhci->lock, flags); - return; - } - - temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); - xhci_dbg(xhci, "ir_set 0 pending = 0x%x\n", temp); - xhci_dbg(xhci, "No-op commands handled = %d\n", xhci->noops_handled); - xhci_dbg(xhci, "HC error bitmask = 0x%x\n", xhci->error_bitmask); - xhci->error_bitmask = 0; - xhci_dbg(xhci, "Event ring:\n"); - xhci_debug_segment(xhci, xhci->event_ring->deq_seg); - xhci_dbg_ring_ptrs(xhci, xhci->event_ring); - temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); - temp_64 &= ~ERST_PTR_MASK; - xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64); - xhci_dbg(xhci, "Command ring:\n"); - xhci_debug_segment(xhci, xhci->cmd_ring->deq_seg); - xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); - xhci_dbg_cmd_ptrs(xhci); - for (i = 0; i < MAX_HC_SLOTS; ++i) { - if (!xhci->devs[i]) - continue; - for (j = 0; j < 31; ++j) { - struct xhci_ring *ring = xhci->devs[i]->eps[j].ring; - if (!ring) - continue; - xhci_dbg(xhci, "Dev %d endpoint ring %d:\n", i, j); - xhci_debug_segment(xhci, ring->deq_seg); - } - } - - if (xhci->noops_submitted != NUM_TEST_NOOPS) - if (xhci_setup_one_noop(xhci)) - xhci_ring_cmd_db(xhci); - spin_unlock_irqrestore(&xhci->lock, flags); - - if (!xhci->zombie) - mod_timer(&xhci->event_ring_timer, jiffies + POLL_TIMEOUT * HZ); - else - xhci_dbg(xhci, "Quit polling the event ring.\n"); -} -#endif - -/* - * Start the HC after it was halted. - * - * This function is called by the USB core when the HC driver is added. - * Its opposite is xhci_stop(). - * - * xhci_init() must be called once before this function can be called. - * Reset the HC, enable device slot contexts, program DCBAAP, and - * set command ring pointer and event ring pointer. - * - * Setup MSI-X vectors and enable interrupts. - */ -int xhci_run(struct usb_hcd *hcd) -{ - u32 temp; - u64 temp_64; - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - void (*doorbell)(struct xhci_hcd *) = NULL; - - hcd->uses_new_polling = 1; - hcd->poll_rh = 0; - - xhci_dbg(xhci, "xhci_run\n"); -#if 0 /* FIXME: MSI not setup yet */ - /* Do this at the very last minute */ - ret = xhci_setup_msix(xhci); - if (!ret) - return ret; - - return -ENOSYS; -#endif -#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING - init_timer(&xhci->event_ring_timer); - xhci->event_ring_timer.data = (unsigned long) xhci; - xhci->event_ring_timer.function = xhci_event_ring_work; - /* Poll the event ring */ - xhci->event_ring_timer.expires = jiffies + POLL_TIMEOUT * HZ; - xhci->zombie = 0; - xhci_dbg(xhci, "Setting event ring polling timer\n"); - add_timer(&xhci->event_ring_timer); -#endif - - xhci_dbg(xhci, "Command ring memory map follows:\n"); - xhci_debug_ring(xhci, xhci->cmd_ring); - xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); - xhci_dbg_cmd_ptrs(xhci); - - xhci_dbg(xhci, "ERST memory map follows:\n"); - xhci_dbg_erst(xhci, &xhci->erst); - xhci_dbg(xhci, "Event ring:\n"); - xhci_debug_ring(xhci, xhci->event_ring); - xhci_dbg_ring_ptrs(xhci, xhci->event_ring); - temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); - temp_64 &= ~ERST_PTR_MASK; - xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64); - - xhci_dbg(xhci, "// Set the interrupt modulation register\n"); - temp = xhci_readl(xhci, &xhci->ir_set->irq_control); - temp &= ~ER_IRQ_INTERVAL_MASK; - temp |= (u32) 160; - xhci_writel(xhci, temp, &xhci->ir_set->irq_control); - - /* Set the HCD state before we enable the irqs */ - hcd->state = HC_STATE_RUNNING; - temp = xhci_readl(xhci, &xhci->op_regs->command); - temp |= (CMD_EIE); - xhci_dbg(xhci, "// Enable interrupts, cmd = 0x%x.\n", - temp); - xhci_writel(xhci, temp, &xhci->op_regs->command); - - temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); - xhci_dbg(xhci, "// Enabling event ring interrupter %p by writing 0x%x to irq_pending\n", - xhci->ir_set, (unsigned int) ER_IRQ_ENABLE(temp)); - xhci_writel(xhci, ER_IRQ_ENABLE(temp), - &xhci->ir_set->irq_pending); - xhci_print_ir_set(xhci, xhci->ir_set, 0); - - if (NUM_TEST_NOOPS > 0) - doorbell = xhci_setup_one_noop(xhci); - - temp = xhci_readl(xhci, &xhci->op_regs->command); - temp |= (CMD_RUN); - xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n", - temp); - xhci_writel(xhci, temp, &xhci->op_regs->command); - /* Flush PCI posted writes */ - temp = xhci_readl(xhci, &xhci->op_regs->command); - xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp); - if (doorbell) - (*doorbell)(xhci); - - xhci_dbg(xhci, "Finished xhci_run\n"); - return 0; -} - -/* - * Stop xHCI driver. - * - * This function is called by the USB core when the HC driver is removed. - * Its opposite is xhci_run(). - * - * Disable device contexts, disable IRQs, and quiesce the HC. - * Reset the HC, finish any completed transactions, and cleanup memory. - */ -void xhci_stop(struct usb_hcd *hcd) -{ - u32 temp; - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - - spin_lock_irq(&xhci->lock); - xhci_halt(xhci); - xhci_reset(xhci); - spin_unlock_irq(&xhci->lock); - -#if 0 /* No MSI yet */ - xhci_cleanup_msix(xhci); -#endif -#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING - /* Tell the event ring poll function not to reschedule */ - xhci->zombie = 1; - del_timer_sync(&xhci->event_ring_timer); -#endif - - xhci_dbg(xhci, "// Disabling event ring interrupts\n"); - temp = xhci_readl(xhci, &xhci->op_regs->status); - xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status); - temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); - xhci_writel(xhci, ER_IRQ_DISABLE(temp), - &xhci->ir_set->irq_pending); - xhci_print_ir_set(xhci, xhci->ir_set, 0); - - xhci_dbg(xhci, "cleaning up memory\n"); - xhci_mem_cleanup(xhci); - xhci_dbg(xhci, "xhci_stop completed - status = %x\n", - xhci_readl(xhci, &xhci->op_regs->status)); -} - -/* - * Shutdown HC (not bus-specific) - * - * This is called when the machine is rebooting or halting. We assume that the - * machine will be powered off, and the HC's internal state will be reset. - * Don't bother to free memory. - */ -void xhci_shutdown(struct usb_hcd *hcd) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - - spin_lock_irq(&xhci->lock); - xhci_halt(xhci); - spin_unlock_irq(&xhci->lock); - -#if 0 - xhci_cleanup_msix(xhci); -#endif - - xhci_dbg(xhci, "xhci_shutdown completed - status = %x\n", - xhci_readl(xhci, &xhci->op_regs->status)); -} - -/*-------------------------------------------------------------------------*/ - -/** - * xhci_get_endpoint_index - Used for passing endpoint bitmasks between the core and - * HCDs. Find the index for an endpoint given its descriptor. Use the return - * value to right shift 1 for the bitmask. - * - * Index = (epnum * 2) + direction - 1, - * where direction = 0 for OUT, 1 for IN. - * For control endpoints, the IN index is used (OUT index is unused), so - * index = (epnum * 2) + direction - 1 = (epnum * 2) + 1 - 1 = (epnum * 2) - */ -unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc) -{ - unsigned int index; - if (usb_endpoint_xfer_control(desc)) - index = (unsigned int) (usb_endpoint_num(desc)*2); - else - index = (unsigned int) (usb_endpoint_num(desc)*2) + - (usb_endpoint_dir_in(desc) ? 1 : 0) - 1; - return index; -} - -/* Find the flag for this endpoint (for use in the control context). Use the - * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is - * bit 1, etc. - */ -unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc) -{ - return 1 << (xhci_get_endpoint_index(desc) + 1); -} - -/* Find the flag for this endpoint (for use in the control context). Use the - * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is - * bit 1, etc. - */ -unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index) -{ - return 1 << (ep_index + 1); -} - -/* Compute the last valid endpoint context index. Basically, this is the - * endpoint index plus one. For slot contexts with more than valid endpoint, - * we find the most significant bit set in the added contexts flags. - * e.g. ep 1 IN (with epnum 0x81) => added_ctxs = 0b1000 - * fls(0b1000) = 4, but the endpoint context index is 3, so subtract one. - */ -unsigned int xhci_last_valid_endpoint(u32 added_ctxs) -{ - return fls(added_ctxs) - 1; -} - -/* Returns 1 if the arguments are OK; - * returns 0 this is a root hub; returns -EINVAL for NULL pointers. - */ -int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, - struct usb_host_endpoint *ep, int check_ep, const char *func) { - if (!hcd || (check_ep && !ep) || !udev) { - printk(KERN_DEBUG "xHCI %s called with invalid args\n", - func); - return -EINVAL; - } - if (!udev->parent) { - printk(KERN_DEBUG "xHCI %s called for root hub\n", - func); - return 0; - } - if (!udev->slot_id) { - printk(KERN_DEBUG "xHCI %s called with unaddressed device\n", - func); - return -EINVAL; - } - return 1; -} - -static int xhci_configure_endpoint(struct xhci_hcd *xhci, - struct usb_device *udev, struct xhci_command *command, - bool ctx_change, bool must_succeed); - -/* - * Full speed devices may have a max packet size greater than 8 bytes, but the - * USB core doesn't know that until it reads the first 8 bytes of the - * descriptor. If the usb_device's max packet size changes after that point, - * we need to issue an evaluate context command and wait on it. - */ -static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id, - unsigned int ep_index, struct urb *urb) -{ - struct xhci_container_ctx *in_ctx; - struct xhci_container_ctx *out_ctx; - struct xhci_input_control_ctx *ctrl_ctx; - struct xhci_ep_ctx *ep_ctx; - int max_packet_size; - int hw_max_packet_size; - int ret = 0; - - out_ctx = xhci->devs[slot_id]->out_ctx; - ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); - hw_max_packet_size = MAX_PACKET_DECODED(ep_ctx->ep_info2); - max_packet_size = urb->dev->ep0.desc.wMaxPacketSize; - if (hw_max_packet_size != max_packet_size) { - xhci_dbg(xhci, "Max Packet Size for ep 0 changed.\n"); - xhci_dbg(xhci, "Max packet size in usb_device = %d\n", - max_packet_size); - xhci_dbg(xhci, "Max packet size in xHCI HW = %d\n", - hw_max_packet_size); - xhci_dbg(xhci, "Issuing evaluate context command.\n"); - - /* Set up the modified control endpoint 0 */ - xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx, - xhci->devs[slot_id]->out_ctx, ep_index); - in_ctx = xhci->devs[slot_id]->in_ctx; - ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index); - ep_ctx->ep_info2 &= ~MAX_PACKET_MASK; - ep_ctx->ep_info2 |= MAX_PACKET(max_packet_size); - - /* Set up the input context flags for the command */ - /* FIXME: This won't work if a non-default control endpoint - * changes max packet sizes. - */ - ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); - ctrl_ctx->add_flags = EP0_FLAG; - ctrl_ctx->drop_flags = 0; - - xhci_dbg(xhci, "Slot %d input context\n", slot_id); - xhci_dbg_ctx(xhci, in_ctx, ep_index); - xhci_dbg(xhci, "Slot %d output context\n", slot_id); - xhci_dbg_ctx(xhci, out_ctx, ep_index); - - ret = xhci_configure_endpoint(xhci, urb->dev, NULL, - true, false); - - /* Clean up the input context for later use by bandwidth - * functions. - */ - ctrl_ctx->add_flags = SLOT_FLAG; - } - return ret; -} - -/* - * non-error returns are a promise to giveback() the urb later - * we drop ownership so next owner (or urb unlink) can get it - */ -int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - unsigned long flags; - int ret = 0; - unsigned int slot_id, ep_index; - - - if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0) - return -EINVAL; - - slot_id = urb->dev->slot_id; - ep_index = xhci_get_endpoint_index(&urb->ep->desc); - - if (!xhci->devs || !xhci->devs[slot_id]) { - if (!in_interrupt()) - dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n"); - ret = -EINVAL; - goto exit; - } - if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { - if (!in_interrupt()) - xhci_dbg(xhci, "urb submitted during PCI suspend\n"); - ret = -ESHUTDOWN; - goto exit; - } - if (usb_endpoint_xfer_control(&urb->ep->desc)) { - /* Check to see if the max packet size for the default control - * endpoint changed during FS device enumeration - */ - if (urb->dev->speed == USB_SPEED_FULL) { - ret = xhci_check_maxpacket(xhci, slot_id, - ep_index, urb); - if (ret < 0) - return ret; - } - - /* We have a spinlock and interrupts disabled, so we must pass - * atomic context to this function, which may allocate memory. - */ - spin_lock_irqsave(&xhci->lock, flags); - if (xhci->xhc_state & XHCI_STATE_DYING) - goto dying; - ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb, - slot_id, ep_index); - spin_unlock_irqrestore(&xhci->lock, flags); - } else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) { - spin_lock_irqsave(&xhci->lock, flags); - if (xhci->xhc_state & XHCI_STATE_DYING) - goto dying; - ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, - slot_id, ep_index); - spin_unlock_irqrestore(&xhci->lock, flags); - } else if (usb_endpoint_xfer_int(&urb->ep->desc)) { - spin_lock_irqsave(&xhci->lock, flags); - if (xhci->xhc_state & XHCI_STATE_DYING) - goto dying; - ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb, - slot_id, ep_index); - spin_unlock_irqrestore(&xhci->lock, flags); - } else { - ret = -EINVAL; - } -exit: - return ret; -dying: - xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for " - "non-responsive xHCI host.\n", - urb->ep->desc.bEndpointAddress, urb); - spin_unlock_irqrestore(&xhci->lock, flags); - return -ESHUTDOWN; -} - -/* - * Remove the URB's TD from the endpoint ring. This may cause the HC to stop - * USB transfers, potentially stopping in the middle of a TRB buffer. The HC - * should pick up where it left off in the TD, unless a Set Transfer Ring - * Dequeue Pointer is issued. - * - * The TRBs that make up the buffers for the canceled URB will be "removed" from - * the ring. Since the ring is a contiguous structure, they can't be physically - * removed. Instead, there are two options: - * - * 1) If the HC is in the middle of processing the URB to be canceled, we - * simply move the ring's dequeue pointer past those TRBs using the Set - * Transfer Ring Dequeue Pointer command. This will be the common case, - * when drivers timeout on the last submitted URB and attempt to cancel. - * - * 2) If the HC is in the middle of a different TD, we turn the TRBs into a - * series of 1-TRB transfer no-op TDs. (No-ops shouldn't be chained.) The - * HC will need to invalidate the any TRBs it has cached after the stop - * endpoint command, as noted in the xHCI 0.95 errata. - * - * 3) The TD may have completed by the time the Stop Endpoint Command - * completes, so software needs to handle that case too. - * - * This function should protect against the TD enqueueing code ringing the - * doorbell while this code is waiting for a Stop Endpoint command to complete. - * It also needs to account for multiple cancellations on happening at the same - * time for the same endpoint. - * - * Note that this function can be called in any context, or so says - * usb_hcd_unlink_urb() - */ -int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) -{ - unsigned long flags; - int ret; - u32 temp; - struct xhci_hcd *xhci; - struct xhci_td *td; - unsigned int ep_index; - struct xhci_ring *ep_ring; - struct xhci_virt_ep *ep; - - xhci = hcd_to_xhci(hcd); - spin_lock_irqsave(&xhci->lock, flags); - /* Make sure the URB hasn't completed or been unlinked already */ - ret = usb_hcd_check_unlink_urb(hcd, urb, status); - if (ret || !urb->hcpriv) - goto done; - temp = xhci_readl(xhci, &xhci->op_regs->status); - if (temp == 0xffffffff) { - xhci_dbg(xhci, "HW died, freeing TD.\n"); - td = (struct xhci_td *) urb->hcpriv; - - usb_hcd_unlink_urb_from_ep(hcd, urb); - spin_unlock_irqrestore(&xhci->lock, flags); - usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, -ESHUTDOWN); - kfree(td); - return ret; - } - if (xhci->xhc_state & XHCI_STATE_DYING) { - xhci_dbg(xhci, "Ep 0x%x: URB %p to be canceled on " - "non-responsive xHCI host.\n", - urb->ep->desc.bEndpointAddress, urb); - /* Let the stop endpoint command watchdog timer (which set this - * state) finish cleaning up the endpoint TD lists. We must - * have caught it in the middle of dropping a lock and giving - * back an URB. - */ - goto done; - } - - xhci_dbg(xhci, "Cancel URB %p\n", urb); - xhci_dbg(xhci, "Event ring:\n"); - xhci_debug_ring(xhci, xhci->event_ring); - ep_index = xhci_get_endpoint_index(&urb->ep->desc); - ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index]; - ep_ring = ep->ring; - xhci_dbg(xhci, "Endpoint ring:\n"); - xhci_debug_ring(xhci, ep_ring); - td = (struct xhci_td *) urb->hcpriv; - - list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list); - /* Queue a stop endpoint command, but only if this is - * the first cancellation to be handled. - */ - if (!(ep->ep_state & EP_HALT_PENDING)) { - ep->ep_state |= EP_HALT_PENDING; - ep->stop_cmds_pending++; - ep->stop_cmd_timer.expires = jiffies + - XHCI_STOP_EP_CMD_TIMEOUT * HZ; - add_timer(&ep->stop_cmd_timer); - xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index); - xhci_ring_cmd_db(xhci); - } -done: - spin_unlock_irqrestore(&xhci->lock, flags); - return ret; -} - -/* Drop an endpoint from a new bandwidth configuration for this device. - * Only one call to this function is allowed per endpoint before - * check_bandwidth() or reset_bandwidth() must be called. - * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will - * add the endpoint to the schedule with possibly new parameters denoted by a - * different endpoint descriptor in usb_host_endpoint. - * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is - * not allowed. - * - * The USB core will not allow URBs to be queued to an endpoint that is being - * disabled, so there's no need for mutual exclusion to protect - * the xhci->devs[slot_id] structure. - */ -int xhci_drop_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_input_control_ctx *ctrl_ctx; - struct xhci_slot_ctx *slot_ctx; - unsigned int last_ctx; - unsigned int ep_index; - struct xhci_ep_ctx *ep_ctx; - u32 drop_flag; - u32 new_add_flags, new_drop_flags, new_slot_info; - int ret; - - ret = xhci_check_args(hcd, udev, ep, 1, __func__); - if (ret <= 0) - return ret; - xhci = hcd_to_xhci(hcd); - xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); - - drop_flag = xhci_get_endpoint_flag(&ep->desc); - if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) { - xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n", - __func__, drop_flag); - return 0; - } - - if (!xhci->devs || !xhci->devs[udev->slot_id]) { - xhci_warn(xhci, "xHCI %s called with unaddressed device\n", - __func__); - return -EINVAL; - } - - 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); - ep_index = xhci_get_endpoint_index(&ep->desc); - ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); - /* If the HC already knows the endpoint is disabled, - * or the HCD has noted it is disabled, ignore this request - */ - if ((ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED || - ctrl_ctx->drop_flags & xhci_get_endpoint_flag(&ep->desc)) { - xhci_warn(xhci, "xHCI %s called with disabled ep %p\n", - __func__, ep); - return 0; - } - - ctrl_ctx->drop_flags |= drop_flag; - new_drop_flags = ctrl_ctx->drop_flags; - - ctrl_ctx->add_flags &= ~drop_flag; - new_add_flags = ctrl_ctx->add_flags; - - last_ctx = xhci_last_valid_endpoint(ctrl_ctx->add_flags); - slot_ctx = xhci_get_slot_ctx(xhci, in_ctx); - /* Update the last valid endpoint context, if we deleted the last one */ - if ((slot_ctx->dev_info & LAST_CTX_MASK) > LAST_CTX(last_ctx)) { - slot_ctx->dev_info &= ~LAST_CTX_MASK; - slot_ctx->dev_info |= LAST_CTX(last_ctx); - } - new_slot_info = slot_ctx->dev_info; - - xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep); - - xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n", - (unsigned int) ep->desc.bEndpointAddress, - udev->slot_id, - (unsigned int) new_drop_flags, - (unsigned int) new_add_flags, - (unsigned int) new_slot_info); - return 0; -} - -/* Add an endpoint to a new possible bandwidth configuration for this device. - * Only one call to this function is allowed per endpoint before - * check_bandwidth() or reset_bandwidth() must be called. - * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will - * add the endpoint to the schedule with possibly new parameters denoted by a - * different endpoint descriptor in usb_host_endpoint. - * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is - * not allowed. - * - * The USB core will not allow URBs to be queued to an endpoint until the - * configuration or alt setting is installed in the device, so there's no need - * for mutual exclusion to protect the xhci->devs[slot_id] structure. - */ -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; - unsigned int ep_index; - struct xhci_ep_ctx *ep_ctx; - struct xhci_slot_ctx *slot_ctx; - struct xhci_input_control_ctx *ctrl_ctx; - u32 added_ctxs; - unsigned int last_ctx; - u32 new_add_flags, new_drop_flags, new_slot_info; - int ret = 0; - - ret = xhci_check_args(hcd, udev, ep, 1, __func__); - if (ret <= 0) { - /* So we won't queue a reset ep command for a root hub */ - ep->hcpriv = NULL; - return ret; - } - xhci = hcd_to_xhci(hcd); - - added_ctxs = xhci_get_endpoint_flag(&ep->desc); - last_ctx = xhci_last_valid_endpoint(added_ctxs); - if (added_ctxs == SLOT_FLAG || added_ctxs == EP0_FLAG) { - /* FIXME when we have to issue an evaluate endpoint command to - * deal with ep0 max packet size changing once we get the - * descriptors - */ - xhci_dbg(xhci, "xHCI %s - can't add slot or ep 0 %#x\n", - __func__, added_ctxs); - return 0; - } - - if (!xhci->devs || !xhci->devs[udev->slot_id]) { - xhci_warn(xhci, "xHCI %s called with unaddressed device\n", - __func__); - return -EINVAL; - } - - 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); - ep_index = xhci_get_endpoint_index(&ep->desc); - ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); - /* If the HCD has already noted the endpoint is enabled, - * ignore this request. - */ - if (ctrl_ctx->add_flags & xhci_get_endpoint_flag(&ep->desc)) { - xhci_warn(xhci, "xHCI %s called with enabled ep %p\n", - __func__, ep); - return 0; - } - - /* - * Configuration and alternate setting changes must be done in - * process context, not interrupt context (or so documenation - * for usb_set_interface() and usb_set_configuration() claim). - */ - if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id], - udev, ep, GFP_NOIO) < 0) { - dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n", - __func__, ep->desc.bEndpointAddress); - return -ENOMEM; - } - - ctrl_ctx->add_flags |= added_ctxs; - new_add_flags = ctrl_ctx->add_flags; - - /* If xhci_endpoint_disable() was called for this endpoint, but the - * xHC hasn't been notified yet through the check_bandwidth() call, - * this re-adds a new state for the endpoint from the new endpoint - * descriptors. We must drop and re-add this endpoint, so we leave the - * drop flags alone. - */ - new_drop_flags = ctrl_ctx->drop_flags; - - slot_ctx = xhci_get_slot_ctx(xhci, in_ctx); - /* Update the last valid endpoint context, if we just added one past */ - if ((slot_ctx->dev_info & LAST_CTX_MASK) < LAST_CTX(last_ctx)) { - slot_ctx->dev_info &= ~LAST_CTX_MASK; - slot_ctx->dev_info |= LAST_CTX(last_ctx); - } - new_slot_info = slot_ctx->dev_info; - - /* Store the usb_device pointer for later use */ - ep->hcpriv = udev; - - xhci_dbg(xhci, "add ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n", - (unsigned int) ep->desc.bEndpointAddress, - udev->slot_id, - (unsigned int) new_drop_flags, - (unsigned int) new_add_flags, - (unsigned int) new_slot_info); - return 0; -} - -static void xhci_zero_in_ctx(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev) -{ - struct xhci_input_control_ctx *ctrl_ctx; - struct xhci_ep_ctx *ep_ctx; - struct xhci_slot_ctx *slot_ctx; - int i; - - /* When a device's add flag and drop flag are zero, any subsequent - * configure endpoint command will leave that endpoint's state - * untouched. Make sure we don't leave any old state in the input - * endpoint contexts. - */ - ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); - ctrl_ctx->drop_flags = 0; - ctrl_ctx->add_flags = 0; - slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); - slot_ctx->dev_info &= ~LAST_CTX_MASK; - /* Endpoint 0 is always valid */ - slot_ctx->dev_info |= LAST_CTX(1); - for (i = 1; i < 31; ++i) { - ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, i); - ep_ctx->ep_info = 0; - ep_ctx->ep_info2 = 0; - ep_ctx->deq = 0; - ep_ctx->tx_info = 0; - } -} - -static int xhci_configure_endpoint_result(struct xhci_hcd *xhci, - struct usb_device *udev, int *cmd_status) -{ - int ret; - - switch (*cmd_status) { - case COMP_ENOMEM: - dev_warn(&udev->dev, "Not enough host controller resources " - "for new device state.\n"); - ret = -ENOMEM; - /* FIXME: can we allocate more resources for the HC? */ - break; - case COMP_BW_ERR: - dev_warn(&udev->dev, "Not enough bandwidth " - "for new device state.\n"); - ret = -ENOSPC; - /* FIXME: can we go back to the old state? */ - break; - case COMP_TRB_ERR: - /* the HCD set up something wrong */ - dev_warn(&udev->dev, "ERROR: Endpoint drop flag = 0, " - "add flag = 1, " - "and endpoint is not disabled.\n"); - ret = -EINVAL; - break; - case COMP_SUCCESS: - dev_dbg(&udev->dev, "Successful Endpoint Configure command\n"); - ret = 0; - break; - default: - xhci_err(xhci, "ERROR: unexpected command completion " - "code 0x%x.\n", *cmd_status); - ret = -EINVAL; - break; - } - return ret; -} - -static int xhci_evaluate_context_result(struct xhci_hcd *xhci, - struct usb_device *udev, int *cmd_status) -{ - int ret; - struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id]; - - switch (*cmd_status) { - case COMP_EINVAL: - dev_warn(&udev->dev, "WARN: xHCI driver setup invalid evaluate " - "context command.\n"); - ret = -EINVAL; - break; - case COMP_EBADSLT: - dev_warn(&udev->dev, "WARN: slot not enabled for" - "evaluate context command.\n"); - case COMP_CTX_STATE: - dev_warn(&udev->dev, "WARN: invalid context state for " - "evaluate context command.\n"); - xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1); - ret = -EINVAL; - break; - case COMP_SUCCESS: - dev_dbg(&udev->dev, "Successful evaluate context command\n"); - ret = 0; - break; - default: - xhci_err(xhci, "ERROR: unexpected command completion " - "code 0x%x.\n", *cmd_status); - ret = -EINVAL; - break; - } - return ret; -} - -/* Issue a configure endpoint command or evaluate context command - * and wait for it to finish. - */ -static int xhci_configure_endpoint(struct xhci_hcd *xhci, - struct usb_device *udev, - struct xhci_command *command, - bool ctx_change, bool must_succeed) -{ - int ret; - int timeleft; - unsigned long flags; - struct xhci_container_ctx *in_ctx; - struct completion *cmd_completion; - int *cmd_status; - struct xhci_virt_device *virt_dev; - - spin_lock_irqsave(&xhci->lock, flags); - virt_dev = xhci->devs[udev->slot_id]; - if (command) { - in_ctx = command->in_ctx; - cmd_completion = command->completion; - cmd_status = &command->status; - command->command_trb = xhci->cmd_ring->enqueue; - list_add_tail(&command->cmd_list, &virt_dev->cmd_list); - } else { - in_ctx = virt_dev->in_ctx; - cmd_completion = &virt_dev->cmd_completion; - cmd_status = &virt_dev->cmd_status; - } - - if (!ctx_change) - ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, - udev->slot_id, must_succeed); - else - ret = xhci_queue_evaluate_context(xhci, in_ctx->dma, - udev->slot_id); - if (ret < 0) { - if (command) - list_del(&command->cmd_list); - spin_unlock_irqrestore(&xhci->lock, flags); - xhci_dbg(xhci, "FIXME allocate a new ring segment\n"); - return -ENOMEM; - } - xhci_ring_cmd_db(xhci); - spin_unlock_irqrestore(&xhci->lock, flags); - - /* Wait for the configure endpoint command to complete */ - timeleft = wait_for_completion_interruptible_timeout( - cmd_completion, - USB_CTRL_SET_TIMEOUT); - if (timeleft <= 0) { - xhci_warn(xhci, "%s while waiting for %s command\n", - timeleft == 0 ? "Timeout" : "Signal", - ctx_change == 0 ? - "configure endpoint" : - "evaluate context"); - /* FIXME cancel the configure endpoint command */ - return -ETIME; - } - - if (!ctx_change) - return xhci_configure_endpoint_result(xhci, udev, cmd_status); - return xhci_evaluate_context_result(xhci, udev, cmd_status); -} - -/* Called after one or more calls to xhci_add_endpoint() or - * xhci_drop_endpoint(). If this call fails, the USB core is expected - * to call xhci_reset_bandwidth(). - * - * Since we are in the middle of changing either configuration or - * installing a new alt setting, the USB core won't allow URBs to be - * enqueued for any endpoint on the old config or interface. Nothing - * else should be touching the xhci->devs[slot_id] structure, so we - * don't need to take the xhci->lock for manipulating that. - */ -int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) -{ - int i; - int ret = 0; - struct xhci_hcd *xhci; - struct xhci_virt_device *virt_dev; - struct xhci_input_control_ctx *ctrl_ctx; - struct xhci_slot_ctx *slot_ctx; - - ret = xhci_check_args(hcd, udev, NULL, 0, __func__); - if (ret <= 0) - return ret; - xhci = hcd_to_xhci(hcd); - - if (!udev->slot_id || !xhci->devs || !xhci->devs[udev->slot_id]) { - xhci_warn(xhci, "xHCI %s called with unaddressed device\n", - __func__); - return -EINVAL; - } - xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); - virt_dev = xhci->devs[udev->slot_id]; - - /* See section 4.6.6 - A0 = 1; A1 = D0 = D1 = 0 */ - ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); - ctrl_ctx->add_flags |= SLOT_FLAG; - ctrl_ctx->add_flags &= ~EP0_FLAG; - ctrl_ctx->drop_flags &= ~SLOT_FLAG; - ctrl_ctx->drop_flags &= ~EP0_FLAG; - xhci_dbg(xhci, "New Input Control Context:\n"); - slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); - xhci_dbg_ctx(xhci, virt_dev->in_ctx, - LAST_CTX_TO_EP_NUM(slot_ctx->dev_info)); - - ret = xhci_configure_endpoint(xhci, udev, NULL, - false, false); - if (ret) { - /* Callee should call reset_bandwidth() */ - return ret; - } - - xhci_dbg(xhci, "Output context after successful config ep cmd:\n"); - xhci_dbg_ctx(xhci, virt_dev->out_ctx, - LAST_CTX_TO_EP_NUM(slot_ctx->dev_info)); - - xhci_zero_in_ctx(xhci, virt_dev); - /* Install new rings and free or cache any old rings */ - for (i = 1; i < 31; ++i) { - if (!virt_dev->eps[i].new_ring) - continue; - /* Only cache or free the old ring if it exists. - * It may not if this is the first add of an endpoint. - */ - if (virt_dev->eps[i].ring) { - xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); - } - virt_dev->eps[i].ring = virt_dev->eps[i].new_ring; - virt_dev->eps[i].new_ring = NULL; - } - - return ret; -} - -void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) -{ - struct xhci_hcd *xhci; - struct xhci_virt_device *virt_dev; - int i, ret; - - ret = xhci_check_args(hcd, udev, NULL, 0, __func__); - if (ret <= 0) - return; - xhci = hcd_to_xhci(hcd); - - if (!xhci->devs || !xhci->devs[udev->slot_id]) { - xhci_warn(xhci, "xHCI %s called with unaddressed device\n", - __func__); - return; - } - xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); - virt_dev = xhci->devs[udev->slot_id]; - /* Free any rings allocated for added endpoints */ - for (i = 0; i < 31; ++i) { - if (virt_dev->eps[i].new_ring) { - xhci_ring_free(xhci, virt_dev->eps[i].new_ring); - virt_dev->eps[i].new_ring = NULL; - } - } - xhci_zero_in_ctx(xhci, virt_dev); -} - -static void xhci_setup_input_ctx_for_config_ep(struct xhci_hcd *xhci, - struct xhci_container_ctx *in_ctx, - struct xhci_container_ctx *out_ctx, - u32 add_flags, u32 drop_flags) -{ - struct xhci_input_control_ctx *ctrl_ctx; - ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); - ctrl_ctx->add_flags = add_flags; - ctrl_ctx->drop_flags = drop_flags; - xhci_slot_copy(xhci, in_ctx, out_ctx); - ctrl_ctx->add_flags |= SLOT_FLAG; - - xhci_dbg(xhci, "Input Context:\n"); - xhci_dbg_ctx(xhci, in_ctx, xhci_last_valid_endpoint(add_flags)); -} - -void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci, - unsigned int slot_id, unsigned int ep_index, - struct xhci_dequeue_state *deq_state) -{ - struct xhci_container_ctx *in_ctx; - struct xhci_ep_ctx *ep_ctx; - u32 added_ctxs; - dma_addr_t addr; - - xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx, - xhci->devs[slot_id]->out_ctx, ep_index); - in_ctx = xhci->devs[slot_id]->in_ctx; - ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index); - addr = xhci_trb_virt_to_dma(deq_state->new_deq_seg, - deq_state->new_deq_ptr); - if (addr == 0) { - xhci_warn(xhci, "WARN Cannot submit config ep after " - "reset ep command\n"); - xhci_warn(xhci, "WARN deq seg = %p, deq ptr = %p\n", - deq_state->new_deq_seg, - deq_state->new_deq_ptr); - return; - } - ep_ctx->deq = addr | deq_state->new_cycle_state; - - added_ctxs = xhci_get_endpoint_flag_from_index(ep_index); - xhci_setup_input_ctx_for_config_ep(xhci, xhci->devs[slot_id]->in_ctx, - xhci->devs[slot_id]->out_ctx, added_ctxs, added_ctxs); -} - -void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, - struct usb_device *udev, unsigned int ep_index) -{ - struct xhci_dequeue_state deq_state; - struct xhci_virt_ep *ep; - - xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n"); - ep = &xhci->devs[udev->slot_id]->eps[ep_index]; - /* We need to move the HW's dequeue pointer past this TD, - * or it will attempt to resend it on the next doorbell ring. - */ - xhci_find_new_dequeue_state(xhci, udev->slot_id, - ep_index, ep->stopped_td, - &deq_state); - - /* HW with the reset endpoint quirk will use the saved dequeue state to - * issue a configure endpoint command later. - */ - if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) { - xhci_dbg(xhci, "Queueing new dequeue state\n"); - xhci_queue_new_dequeue_state(xhci, udev->slot_id, - ep_index, &deq_state); - } else { - /* Better hope no one uses the input context between now and the - * reset endpoint completion! - */ - xhci_dbg(xhci, "Setting up input context for " - "configure endpoint command\n"); - xhci_setup_input_ctx_for_quirk(xhci, udev->slot_id, - ep_index, &deq_state); - } -} - -/* Deal with stalled endpoints. The core should have sent the control message - * to clear the halt condition. However, we need to make the xHCI hardware - * reset its sequence number, since a device will expect a sequence number of - * zero after the halt condition is cleared. - * Context: in_interrupt - */ -void xhci_endpoint_reset(struct usb_hcd *hcd, - struct usb_host_endpoint *ep) -{ - struct xhci_hcd *xhci; - struct usb_device *udev; - unsigned int ep_index; - unsigned long flags; - int ret; - struct xhci_virt_ep *virt_ep; - - xhci = hcd_to_xhci(hcd); - udev = (struct usb_device *) ep->hcpriv; - /* Called with a root hub endpoint (or an endpoint that wasn't added - * with xhci_add_endpoint() - */ - if (!ep->hcpriv) - return; - ep_index = xhci_get_endpoint_index(&ep->desc); - virt_ep = &xhci->devs[udev->slot_id]->eps[ep_index]; - if (!virt_ep->stopped_td) { - xhci_dbg(xhci, "Endpoint 0x%x not halted, refusing to reset.\n", - ep->desc.bEndpointAddress); - return; - } - if (usb_endpoint_xfer_control(&ep->desc)) { - xhci_dbg(xhci, "Control endpoint stall already handled.\n"); - return; - } - - xhci_dbg(xhci, "Queueing reset endpoint command\n"); - spin_lock_irqsave(&xhci->lock, flags); - ret = xhci_queue_reset_ep(xhci, udev->slot_id, ep_index); - /* - * Can't change the ring dequeue pointer until it's transitioned to the - * stopped state, which is only upon a successful reset endpoint - * command. Better hope that last command worked! - */ - if (!ret) { - xhci_cleanup_stalled_ring(xhci, udev, ep_index); - kfree(virt_ep->stopped_td); - xhci_ring_cmd_db(xhci); - } - spin_unlock_irqrestore(&xhci->lock, flags); - - if (ret) - xhci_warn(xhci, "FIXME allocate a new ring segment\n"); -} - -/* - * This submits a Reset Device Command, which will set the device state to 0, - * set the device address to 0, and disable all the endpoints except the default - * control endpoint. The USB core should come back and call - * xhci_address_device(), and then re-set up the configuration. If this is - * called because of a usb_reset_and_verify_device(), then the old alternate - * settings will be re-installed through the normal bandwidth allocation - * functions. - * - * Wait for the Reset Device command to finish. Remove all structures - * associated with the endpoints that were disabled. Clear the input device - * structure? Cache the rings? Reset the control endpoint 0 max packet size? - */ -int xhci_reset_device(struct usb_hcd *hcd, struct usb_device *udev) -{ - int ret, i; - unsigned long flags; - struct xhci_hcd *xhci; - unsigned int slot_id; - struct xhci_virt_device *virt_dev; - struct xhci_command *reset_device_cmd; - int timeleft; - int last_freed_endpoint; - - ret = xhci_check_args(hcd, udev, NULL, 0, __func__); - if (ret <= 0) - return ret; - xhci = hcd_to_xhci(hcd); - slot_id = udev->slot_id; - virt_dev = xhci->devs[slot_id]; - if (!virt_dev) { - xhci_dbg(xhci, "%s called with invalid slot ID %u\n", - __func__, slot_id); - return -EINVAL; - } - - xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id); - /* Allocate the command structure that holds the struct completion. - * Assume we're in process context, since the normal device reset - * process has to wait for the device anyway. Storage devices are - * reset as part of error handling, so use GFP_NOIO instead of - * GFP_KERNEL. - */ - reset_device_cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO); - if (!reset_device_cmd) { - xhci_dbg(xhci, "Couldn't allocate command structure.\n"); - return -ENOMEM; - } - - /* Attempt to submit the Reset Device command to the command ring */ - spin_lock_irqsave(&xhci->lock, flags); - reset_device_cmd->command_trb = xhci->cmd_ring->enqueue; - list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list); - ret = xhci_queue_reset_device(xhci, slot_id); - if (ret) { - xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); - list_del(&reset_device_cmd->cmd_list); - spin_unlock_irqrestore(&xhci->lock, flags); - goto command_cleanup; - } - xhci_ring_cmd_db(xhci); - spin_unlock_irqrestore(&xhci->lock, flags); - - /* Wait for the Reset Device command to finish */ - timeleft = wait_for_completion_interruptible_timeout( - reset_device_cmd->completion, - USB_CTRL_SET_TIMEOUT); - if (timeleft <= 0) { - xhci_warn(xhci, "%s while waiting for reset device command\n", - timeleft == 0 ? "Timeout" : "Signal"); - spin_lock_irqsave(&xhci->lock, flags); - /* The timeout might have raced with the event ring handler, so - * only delete from the list if the item isn't poisoned. - */ - if (reset_device_cmd->cmd_list.next != LIST_POISON1) - list_del(&reset_device_cmd->cmd_list); - spin_unlock_irqrestore(&xhci->lock, flags); - ret = -ETIME; - goto command_cleanup; - } - - /* The Reset Device command can't fail, according to the 0.95/0.96 spec, - * unless we tried to reset a slot ID that wasn't enabled, - * or the device wasn't in the addressed or configured state. - */ - ret = reset_device_cmd->status; - switch (ret) { - case COMP_EBADSLT: /* 0.95 completion code for bad slot ID */ - case COMP_CTX_STATE: /* 0.96 completion code for same thing */ - xhci_info(xhci, "Can't reset device (slot ID %u) in %s state\n", - slot_id, - xhci_get_slot_state(xhci, virt_dev->out_ctx)); - xhci_info(xhci, "Not freeing device rings.\n"); - /* Don't treat this as an error. May change my mind later. */ - ret = 0; - goto command_cleanup; - case COMP_SUCCESS: - xhci_dbg(xhci, "Successful reset device command.\n"); - break; - default: - if (xhci_is_vendor_info_code(xhci, ret)) - break; - xhci_warn(xhci, "Unknown completion code %u for " - "reset device command.\n", ret); - ret = -EINVAL; - goto command_cleanup; - } - - /* Everything but endpoint 0 is disabled, so free or cache the rings. */ - last_freed_endpoint = 1; - for (i = 1; i < 31; ++i) { - if (!virt_dev->eps[i].ring) - continue; - xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); - last_freed_endpoint = i; - } - xhci_dbg(xhci, "Output context after successful reset device cmd:\n"); - xhci_dbg_ctx(xhci, virt_dev->out_ctx, last_freed_endpoint); - ret = 0; - -command_cleanup: - xhci_free_command(xhci, reset_device_cmd); - return ret; -} - -/* - * At this point, the struct usb_device is about to go away, the device has - * disconnected, and all traffic has been stopped and the endpoints have been - * disabled. Free any HC data structures associated with that device. - */ -void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - struct xhci_virt_device *virt_dev; - unsigned long flags; - u32 state; - int i; - - if (udev->slot_id == 0) - return; - virt_dev = xhci->devs[udev->slot_id]; - if (!virt_dev) - return; - - /* Stop any wayward timer functions (which may grab the lock) */ - for (i = 0; i < 31; ++i) { - virt_dev->eps[i].ep_state &= ~EP_HALT_PENDING; - del_timer_sync(&virt_dev->eps[i].stop_cmd_timer); - } - - spin_lock_irqsave(&xhci->lock, flags); - /* Don't disable the slot if the host controller is dead. */ - state = xhci_readl(xhci, &xhci->op_regs->status); - if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) { - xhci_free_virt_device(xhci, udev->slot_id); - spin_unlock_irqrestore(&xhci->lock, flags); - return; - } - - if (xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) { - spin_unlock_irqrestore(&xhci->lock, flags); - xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); - return; - } - xhci_ring_cmd_db(xhci); - spin_unlock_irqrestore(&xhci->lock, flags); - /* - * Event command completion handler will free any data structures - * associated with the slot. XXX Can free sleep? - */ -} - -/* - * Returns 0 if the xHC ran out of device slots, the Enable Slot command - * timed out, or allocating memory failed. Returns 1 on success. - */ -int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - unsigned long flags; - int timeleft; - int ret; - - spin_lock_irqsave(&xhci->lock, flags); - ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0); - if (ret) { - spin_unlock_irqrestore(&xhci->lock, flags); - xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); - return 0; - } - xhci_ring_cmd_db(xhci); - spin_unlock_irqrestore(&xhci->lock, flags); - - /* XXX: how much time for xHC slot assignment? */ - timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, - USB_CTRL_SET_TIMEOUT); - if (timeleft <= 0) { - xhci_warn(xhci, "%s while waiting for a slot\n", - timeleft == 0 ? "Timeout" : "Signal"); - /* FIXME cancel the enable slot request */ - return 0; - } - - if (!xhci->slot_id) { - xhci_err(xhci, "Error while assigning device slot ID\n"); - return 0; - } - /* xhci_alloc_virt_device() does not touch rings; no need to lock */ - if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_KERNEL)) { - /* Disable slot, if we can do it without mem alloc */ - xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n"); - spin_lock_irqsave(&xhci->lock, flags); - if (!xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) - xhci_ring_cmd_db(xhci); - spin_unlock_irqrestore(&xhci->lock, flags); - return 0; - } - udev->slot_id = xhci->slot_id; - /* Is this a LS or FS device under a HS hub? */ - /* Hub or peripherial? */ - return 1; -} - -/* - * Issue an Address Device command (which will issue a SetAddress request to - * the device). - * We should be protected by the usb_address0_mutex in khubd's hub_port_init, so - * we should only issue and wait on one address command at the same time. - * - * We add one to the device address issued by the hardware because the USB core - * uses address 1 for the root hubs (even though they're not really devices). - */ -int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) -{ - unsigned long flags; - int timeleft; - struct xhci_virt_device *virt_dev; - int ret = 0; - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - struct xhci_slot_ctx *slot_ctx; - struct xhci_input_control_ctx *ctrl_ctx; - u64 temp_64; - - if (!udev->slot_id) { - xhci_dbg(xhci, "Bad Slot ID %d\n", udev->slot_id); - return -EINVAL; - } - - virt_dev = xhci->devs[udev->slot_id]; - - /* If this is a Set Address to an unconfigured device, setup ep 0 */ - if (!udev->config) - xhci_setup_addressable_virt_dev(xhci, udev); - /* Otherwise, assume the core has the device configured how it wants */ - xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); - xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); - - spin_lock_irqsave(&xhci->lock, flags); - ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, - udev->slot_id); - if (ret) { - spin_unlock_irqrestore(&xhci->lock, flags); - xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); - return ret; - } - xhci_ring_cmd_db(xhci); - spin_unlock_irqrestore(&xhci->lock, flags); - - /* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */ - timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, - USB_CTRL_SET_TIMEOUT); - /* FIXME: From section 4.3.4: "Software shall be responsible for timing - * the SetAddress() "recovery interval" required by USB and aborting the - * command on a timeout. - */ - if (timeleft <= 0) { - xhci_warn(xhci, "%s while waiting for a slot\n", - timeleft == 0 ? "Timeout" : "Signal"); - /* FIXME cancel the address device command */ - return -ETIME; - } - - switch (virt_dev->cmd_status) { - case COMP_CTX_STATE: - case COMP_EBADSLT: - xhci_err(xhci, "Setup ERROR: address device command for slot %d.\n", - udev->slot_id); - ret = -EINVAL; - break; - case COMP_TX_ERR: - dev_warn(&udev->dev, "Device not responding to set address.\n"); - ret = -EPROTO; - break; - case COMP_SUCCESS: - xhci_dbg(xhci, "Successful Address Device command\n"); - break; - default: - xhci_err(xhci, "ERROR: unexpected command completion " - "code 0x%x.\n", virt_dev->cmd_status); - xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id); - xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2); - ret = -EINVAL; - break; - } - if (ret) { - return ret; - } - temp_64 = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); - xhci_dbg(xhci, "Op regs DCBAA ptr = %#016llx\n", temp_64); - xhci_dbg(xhci, "Slot ID %d dcbaa entry @%p = %#016llx\n", - udev->slot_id, - &xhci->dcbaa->dev_context_ptrs[udev->slot_id], - (unsigned long long) - xhci->dcbaa->dev_context_ptrs[udev->slot_id]); - xhci_dbg(xhci, "Output Context DMA address = %#08llx\n", - (unsigned long long)virt_dev->out_ctx->dma); - xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); - xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); - xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id); - xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2); - /* - * USB core uses address 1 for the roothubs, so we add one to the - * address given back to us by the HC. - */ - slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); - udev->devnum = (slot_ctx->dev_state & DEV_ADDR_MASK) + 1; - /* Zero the input context control for later use */ - ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); - ctrl_ctx->add_flags = 0; - ctrl_ctx->drop_flags = 0; - - xhci_dbg(xhci, "Device address = %d\n", udev->devnum); - /* XXX Meh, not sure if anyone else but choose_address uses this. */ - set_bit(udev->devnum, udev->bus->devmap.devicemap); - - return 0; -} - -/* Once a hub descriptor is fetched for a device, we need to update the xHC's - * internal data structures for the device. - */ -int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, - struct usb_tt *tt, gfp_t mem_flags) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - struct xhci_virt_device *vdev; - struct xhci_command *config_cmd; - struct xhci_input_control_ctx *ctrl_ctx; - struct xhci_slot_ctx *slot_ctx; - unsigned long flags; - unsigned think_time; - int ret; - - /* Ignore root hubs */ - if (!hdev->parent) - return 0; - - vdev = xhci->devs[hdev->slot_id]; - if (!vdev) { - xhci_warn(xhci, "Cannot update hub desc for unknown device.\n"); - return -EINVAL; - } - config_cmd = xhci_alloc_command(xhci, true, true, mem_flags); - if (!config_cmd) { - xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); - return -ENOMEM; - } - - spin_lock_irqsave(&xhci->lock, flags); - xhci_slot_copy(xhci, config_cmd->in_ctx, vdev->out_ctx); - ctrl_ctx = xhci_get_input_control_ctx(xhci, config_cmd->in_ctx); - ctrl_ctx->add_flags |= SLOT_FLAG; - slot_ctx = xhci_get_slot_ctx(xhci, config_cmd->in_ctx); - slot_ctx->dev_info |= DEV_HUB; - if (tt->multi) - slot_ctx->dev_info |= DEV_MTT; - if (xhci->hci_version > 0x95) { - xhci_dbg(xhci, "xHCI version %x needs hub " - "TT think time and number of ports\n", - (unsigned int) xhci->hci_version); - slot_ctx->dev_info2 |= XHCI_MAX_PORTS(hdev->maxchild); - /* Set TT think time - convert from ns to FS bit times. - * 0 = 8 FS bit times, 1 = 16 FS bit times, - * 2 = 24 FS bit times, 3 = 32 FS bit times. - */ - think_time = tt->think_time; - if (think_time != 0) - think_time = (think_time / 666) - 1; - slot_ctx->tt_info |= TT_THINK_TIME(think_time); - } else { - xhci_dbg(xhci, "xHCI version %x doesn't need hub " - "TT think time or number of ports\n", - (unsigned int) xhci->hci_version); - } - slot_ctx->dev_state = 0; - spin_unlock_irqrestore(&xhci->lock, flags); - - xhci_dbg(xhci, "Set up %s for hub device.\n", - (xhci->hci_version > 0x95) ? - "configure endpoint" : "evaluate context"); - xhci_dbg(xhci, "Slot %u Input Context:\n", hdev->slot_id); - xhci_dbg_ctx(xhci, config_cmd->in_ctx, 0); - - /* Issue and wait for the configure endpoint or - * evaluate context command. - */ - if (xhci->hci_version > 0x95) - ret = xhci_configure_endpoint(xhci, hdev, config_cmd, - false, false); - else - ret = xhci_configure_endpoint(xhci, hdev, config_cmd, - true, false); - - xhci_dbg(xhci, "Slot %u Output Context:\n", hdev->slot_id); - xhci_dbg_ctx(xhci, vdev->out_ctx, 0); - - xhci_free_command(xhci, config_cmd); - return ret; -} - -int xhci_get_frame(struct usb_hcd *hcd) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - /* EHCI mods by the periodic size. Why? */ - return xhci_readl(xhci, &xhci->run_regs->microframe_index) >> 3; -} - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_LICENSE("GPL"); - -static int __init xhci_hcd_init(void) -{ -#ifdef CONFIG_PCI - int retval = 0; - - retval = xhci_register_pci(); - - if (retval < 0) { - printk(KERN_DEBUG "Problem registering PCI driver."); - return retval; - } -#endif - /* - * Check the compiler generated sizes of structures that must be laid - * out in specific ways for hardware access. - */ - BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8); - BUILD_BUG_ON(sizeof(struct xhci_slot_ctx) != 8*32/8); - BUILD_BUG_ON(sizeof(struct xhci_ep_ctx) != 8*32/8); - /* xhci_device_control has eight fields, and also - * embeds one xhci_slot_ctx and 31 xhci_ep_ctx - */ - BUILD_BUG_ON(sizeof(struct xhci_stream_ctx) != 4*32/8); - BUILD_BUG_ON(sizeof(union xhci_trb) != 4*32/8); - BUILD_BUG_ON(sizeof(struct xhci_erst_entry) != 4*32/8); - BUILD_BUG_ON(sizeof(struct xhci_cap_regs) != 7*32/8); - BUILD_BUG_ON(sizeof(struct xhci_intr_reg) != 8*32/8); - /* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */ - BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8); - BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8); - return 0; -} -module_init(xhci_hcd_init); - -static void __exit xhci_hcd_cleanup(void) -{ -#ifdef CONFIG_PCI - xhci_unregister_pci(); -#endif -} -module_exit(xhci_hcd_cleanup); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c new file mode 100644 index 000000000000..4cb69e0af834 --- /dev/null +++ b/drivers/usb/host/xhci.c @@ -0,0 +1,1916 @@ +/* + * xHCI host controller driver + * + * Copyright (C) 2008 Intel Corp. + * + * Author: Sarah Sharp + * Some code borrowed from the Linux EHCI driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +#include "xhci.h" + +#define DRIVER_AUTHOR "Sarah Sharp" +#define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver" + +/* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */ +static int link_quirk; +module_param(link_quirk, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB"); + +/* TODO: copied from ehci-hcd.c - can this be refactored? */ +/* + * handshake - spin reading hc until handshake completes or fails + * @ptr: address of hc register to be read + * @mask: bits to look at in result of read + * @done: value of those bits when handshake succeeds + * @usec: timeout in microseconds + * + * Returns negative errno, or zero on success + * + * Success happens when the "mask" bits have the specified value (hardware + * handshake done). There are two failure modes: "usec" have passed (major + * hardware flakeout), or the register reads as all-ones (hardware removed). + */ +static int handshake(struct xhci_hcd *xhci, void __iomem *ptr, + u32 mask, u32 done, int usec) +{ + u32 result; + + do { + result = xhci_readl(xhci, ptr); + if (result == ~(u32)0) /* card removed */ + return -ENODEV; + result &= mask; + if (result == done) + return 0; + udelay(1); + usec--; + } while (usec > 0); + return -ETIMEDOUT; +} + +/* + * Disable interrupts and begin the xHCI halting process. + */ +void xhci_quiesce(struct xhci_hcd *xhci) +{ + u32 halted; + u32 cmd; + u32 mask; + + mask = ~(XHCI_IRQS); + halted = xhci_readl(xhci, &xhci->op_regs->status) & STS_HALT; + if (!halted) + mask &= ~CMD_RUN; + + cmd = xhci_readl(xhci, &xhci->op_regs->command); + cmd &= mask; + xhci_writel(xhci, cmd, &xhci->op_regs->command); +} + +/* + * Force HC into halt state. + * + * Disable any IRQs and clear the run/stop bit. + * HC will complete any current and actively pipelined transactions, and + * should halt within 16 microframes of the run/stop bit being cleared. + * Read HC Halted bit in the status register to see when the HC is finished. + * XXX: shouldn't we set HC_STATE_HALT here somewhere? + */ +int xhci_halt(struct xhci_hcd *xhci) +{ + xhci_dbg(xhci, "// Halt the HC\n"); + xhci_quiesce(xhci); + + return handshake(xhci, &xhci->op_regs->status, + STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); +} + +/* + * Reset a halted HC, and set the internal HC state to HC_STATE_HALT. + * + * This resets pipelines, timers, counters, state machines, etc. + * Transactions will be terminated immediately, and operational registers + * will be set to their defaults. + */ +int xhci_reset(struct xhci_hcd *xhci) +{ + u32 command; + u32 state; + + state = xhci_readl(xhci, &xhci->op_regs->status); + if ((state & STS_HALT) == 0) { + xhci_warn(xhci, "Host controller not halted, aborting reset.\n"); + return 0; + } + + xhci_dbg(xhci, "// Reset the HC\n"); + command = xhci_readl(xhci, &xhci->op_regs->command); + command |= CMD_RESET; + xhci_writel(xhci, command, &xhci->op_regs->command); + /* XXX: Why does EHCI set this here? Shouldn't other code do this? */ + xhci_to_hcd(xhci)->state = HC_STATE_HALT; + + return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000); +} + + +#if 0 +/* Set up MSI-X table for entry 0 (may claim other entries later) */ +static int xhci_setup_msix(struct xhci_hcd *xhci) +{ + int ret; + struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); + + xhci->msix_count = 0; + /* XXX: did I do this right? ixgbe does kcalloc for more than one */ + xhci->msix_entries = kmalloc(sizeof(struct msix_entry), GFP_KERNEL); + if (!xhci->msix_entries) { + xhci_err(xhci, "Failed to allocate MSI-X entries\n"); + return -ENOMEM; + } + xhci->msix_entries[0].entry = 0; + + ret = pci_enable_msix(pdev, xhci->msix_entries, xhci->msix_count); + if (ret) { + xhci_err(xhci, "Failed to enable MSI-X\n"); + goto free_entries; + } + + /* + * Pass the xhci pointer value as the request_irq "cookie". + * If more irqs are added, this will need to be unique for each one. + */ + ret = request_irq(xhci->msix_entries[0].vector, &xhci_irq, 0, + "xHCI", xhci_to_hcd(xhci)); + if (ret) { + xhci_err(xhci, "Failed to allocate MSI-X interrupt\n"); + goto disable_msix; + } + xhci_dbg(xhci, "Finished setting up MSI-X\n"); + return 0; + +disable_msix: + pci_disable_msix(pdev); +free_entries: + kfree(xhci->msix_entries); + xhci->msix_entries = NULL; + return ret; +} + +/* XXX: code duplication; can xhci_setup_msix call this? */ +/* Free any IRQs and disable MSI-X */ +static void xhci_cleanup_msix(struct xhci_hcd *xhci) +{ + struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); + if (!xhci->msix_entries) + return; + + free_irq(xhci->msix_entries[0].vector, xhci); + pci_disable_msix(pdev); + kfree(xhci->msix_entries); + xhci->msix_entries = NULL; + xhci_dbg(xhci, "Finished cleaning up MSI-X\n"); +} +#endif + +/* + * Initialize memory for HCD and xHC (one-time init). + * + * Program the PAGESIZE register, initialize the device context array, create + * device contexts (?), set up a command ring segment (or two?), create event + * ring (one for now). + */ +int xhci_init(struct usb_hcd *hcd) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + int retval = 0; + + xhci_dbg(xhci, "xhci_init\n"); + spin_lock_init(&xhci->lock); + if (link_quirk) { + xhci_dbg(xhci, "QUIRK: Not clearing Link TRB chain bits.\n"); + xhci->quirks |= XHCI_LINK_TRB_QUIRK; + } else { + xhci_dbg(xhci, "xHCI doesn't need link TRB QUIRK\n"); + } + retval = xhci_mem_init(xhci, GFP_KERNEL); + xhci_dbg(xhci, "Finished xhci_init\n"); + + return retval; +} + +/* + * Called in interrupt context when there might be work + * queued on the event ring + * + * xhci->lock must be held by caller. + */ +static void xhci_work(struct xhci_hcd *xhci) +{ + u32 temp; + u64 temp_64; + + /* + * Clear the op reg interrupt status first, + * so we can receive interrupts from other MSI-X interrupters. + * Write 1 to clear the interrupt status. + */ + temp = xhci_readl(xhci, &xhci->op_regs->status); + temp |= STS_EINT; + xhci_writel(xhci, temp, &xhci->op_regs->status); + /* FIXME when MSI-X is supported and there are multiple vectors */ + /* Clear the MSI-X event interrupt status */ + + /* Acknowledge the interrupt */ + temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); + temp |= 0x3; + xhci_writel(xhci, temp, &xhci->ir_set->irq_pending); + /* Flush posted writes */ + xhci_readl(xhci, &xhci->ir_set->irq_pending); + + if (xhci->xhc_state & XHCI_STATE_DYING) + xhci_dbg(xhci, "xHCI dying, ignoring interrupt. " + "Shouldn't IRQs be disabled?\n"); + else + /* FIXME this should be a delayed service routine + * that clears the EHB. + */ + xhci_handle_event(xhci); + + /* Clear the event handler busy flag (RW1C); the event ring should be empty. */ + temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); + xhci_write_64(xhci, temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue); + /* Flush posted writes -- FIXME is this necessary? */ + xhci_readl(xhci, &xhci->ir_set->irq_pending); +} + +/*-------------------------------------------------------------------------*/ + +/* + * xHCI spec says we can get an interrupt, and if the HC has an error condition, + * we might get bad data out of the event ring. Section 4.10.2.7 has a list of + * indicators of an event TRB error, but we check the status *first* to be safe. + */ +irqreturn_t xhci_irq(struct usb_hcd *hcd) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + u32 temp, temp2; + union xhci_trb *trb; + + spin_lock(&xhci->lock); + trb = xhci->event_ring->dequeue; + /* Check if the xHC generated the interrupt, or the irq is shared */ + temp = xhci_readl(xhci, &xhci->op_regs->status); + temp2 = xhci_readl(xhci, &xhci->ir_set->irq_pending); + if (temp == 0xffffffff && temp2 == 0xffffffff) + goto hw_died; + + if (!(temp & STS_EINT) && !ER_IRQ_PENDING(temp2)) { + spin_unlock(&xhci->lock); + return IRQ_NONE; + } + xhci_dbg(xhci, "op reg status = %08x\n", temp); + xhci_dbg(xhci, "ir set irq_pending = %08x\n", temp2); + xhci_dbg(xhci, "Event ring dequeue ptr:\n"); + xhci_dbg(xhci, "@%llx %08x %08x %08x %08x\n", + (unsigned long long)xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, trb), + lower_32_bits(trb->link.segment_ptr), + upper_32_bits(trb->link.segment_ptr), + (unsigned int) trb->link.intr_target, + (unsigned int) trb->link.control); + + if (temp & STS_FATAL) { + xhci_warn(xhci, "WARNING: Host System Error\n"); + xhci_halt(xhci); +hw_died: + xhci_to_hcd(xhci)->state = HC_STATE_HALT; + spin_unlock(&xhci->lock); + return -ESHUTDOWN; + } + + xhci_work(xhci); + spin_unlock(&xhci->lock); + + return IRQ_HANDLED; +} + +#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING +void xhci_event_ring_work(unsigned long arg) +{ + unsigned long flags; + int temp; + u64 temp_64; + struct xhci_hcd *xhci = (struct xhci_hcd *) arg; + int i, j; + + xhci_dbg(xhci, "Poll event ring: %lu\n", jiffies); + + spin_lock_irqsave(&xhci->lock, flags); + temp = xhci_readl(xhci, &xhci->op_regs->status); + xhci_dbg(xhci, "op reg status = 0x%x\n", temp); + if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) { + xhci_dbg(xhci, "HW died, polling stopped.\n"); + spin_unlock_irqrestore(&xhci->lock, flags); + return; + } + + temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); + xhci_dbg(xhci, "ir_set 0 pending = 0x%x\n", temp); + xhci_dbg(xhci, "No-op commands handled = %d\n", xhci->noops_handled); + xhci_dbg(xhci, "HC error bitmask = 0x%x\n", xhci->error_bitmask); + xhci->error_bitmask = 0; + xhci_dbg(xhci, "Event ring:\n"); + xhci_debug_segment(xhci, xhci->event_ring->deq_seg); + xhci_dbg_ring_ptrs(xhci, xhci->event_ring); + temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); + temp_64 &= ~ERST_PTR_MASK; + xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64); + xhci_dbg(xhci, "Command ring:\n"); + xhci_debug_segment(xhci, xhci->cmd_ring->deq_seg); + xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); + xhci_dbg_cmd_ptrs(xhci); + for (i = 0; i < MAX_HC_SLOTS; ++i) { + if (!xhci->devs[i]) + continue; + for (j = 0; j < 31; ++j) { + struct xhci_ring *ring = xhci->devs[i]->eps[j].ring; + if (!ring) + continue; + xhci_dbg(xhci, "Dev %d endpoint ring %d:\n", i, j); + xhci_debug_segment(xhci, ring->deq_seg); + } + } + + if (xhci->noops_submitted != NUM_TEST_NOOPS) + if (xhci_setup_one_noop(xhci)) + xhci_ring_cmd_db(xhci); + spin_unlock_irqrestore(&xhci->lock, flags); + + if (!xhci->zombie) + mod_timer(&xhci->event_ring_timer, jiffies + POLL_TIMEOUT * HZ); + else + xhci_dbg(xhci, "Quit polling the event ring.\n"); +} +#endif + +/* + * Start the HC after it was halted. + * + * This function is called by the USB core when the HC driver is added. + * Its opposite is xhci_stop(). + * + * xhci_init() must be called once before this function can be called. + * Reset the HC, enable device slot contexts, program DCBAAP, and + * set command ring pointer and event ring pointer. + * + * Setup MSI-X vectors and enable interrupts. + */ +int xhci_run(struct usb_hcd *hcd) +{ + u32 temp; + u64 temp_64; + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + void (*doorbell)(struct xhci_hcd *) = NULL; + + hcd->uses_new_polling = 1; + hcd->poll_rh = 0; + + xhci_dbg(xhci, "xhci_run\n"); +#if 0 /* FIXME: MSI not setup yet */ + /* Do this at the very last minute */ + ret = xhci_setup_msix(xhci); + if (!ret) + return ret; + + return -ENOSYS; +#endif +#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING + init_timer(&xhci->event_ring_timer); + xhci->event_ring_timer.data = (unsigned long) xhci; + xhci->event_ring_timer.function = xhci_event_ring_work; + /* Poll the event ring */ + xhci->event_ring_timer.expires = jiffies + POLL_TIMEOUT * HZ; + xhci->zombie = 0; + xhci_dbg(xhci, "Setting event ring polling timer\n"); + add_timer(&xhci->event_ring_timer); +#endif + + xhci_dbg(xhci, "Command ring memory map follows:\n"); + xhci_debug_ring(xhci, xhci->cmd_ring); + xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); + xhci_dbg_cmd_ptrs(xhci); + + xhci_dbg(xhci, "ERST memory map follows:\n"); + xhci_dbg_erst(xhci, &xhci->erst); + xhci_dbg(xhci, "Event ring:\n"); + xhci_debug_ring(xhci, xhci->event_ring); + xhci_dbg_ring_ptrs(xhci, xhci->event_ring); + temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); + temp_64 &= ~ERST_PTR_MASK; + xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64); + + xhci_dbg(xhci, "// Set the interrupt modulation register\n"); + temp = xhci_readl(xhci, &xhci->ir_set->irq_control); + temp &= ~ER_IRQ_INTERVAL_MASK; + temp |= (u32) 160; + xhci_writel(xhci, temp, &xhci->ir_set->irq_control); + + /* Set the HCD state before we enable the irqs */ + hcd->state = HC_STATE_RUNNING; + temp = xhci_readl(xhci, &xhci->op_regs->command); + temp |= (CMD_EIE); + xhci_dbg(xhci, "// Enable interrupts, cmd = 0x%x.\n", + temp); + xhci_writel(xhci, temp, &xhci->op_regs->command); + + temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); + xhci_dbg(xhci, "// Enabling event ring interrupter %p by writing 0x%x to irq_pending\n", + xhci->ir_set, (unsigned int) ER_IRQ_ENABLE(temp)); + xhci_writel(xhci, ER_IRQ_ENABLE(temp), + &xhci->ir_set->irq_pending); + xhci_print_ir_set(xhci, xhci->ir_set, 0); + + if (NUM_TEST_NOOPS > 0) + doorbell = xhci_setup_one_noop(xhci); + + temp = xhci_readl(xhci, &xhci->op_regs->command); + temp |= (CMD_RUN); + xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n", + temp); + xhci_writel(xhci, temp, &xhci->op_regs->command); + /* Flush PCI posted writes */ + temp = xhci_readl(xhci, &xhci->op_regs->command); + xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp); + if (doorbell) + (*doorbell)(xhci); + + xhci_dbg(xhci, "Finished xhci_run\n"); + return 0; +} + +/* + * Stop xHCI driver. + * + * This function is called by the USB core when the HC driver is removed. + * Its opposite is xhci_run(). + * + * Disable device contexts, disable IRQs, and quiesce the HC. + * Reset the HC, finish any completed transactions, and cleanup memory. + */ +void xhci_stop(struct usb_hcd *hcd) +{ + u32 temp; + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + + spin_lock_irq(&xhci->lock); + xhci_halt(xhci); + xhci_reset(xhci); + spin_unlock_irq(&xhci->lock); + +#if 0 /* No MSI yet */ + xhci_cleanup_msix(xhci); +#endif +#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING + /* Tell the event ring poll function not to reschedule */ + xhci->zombie = 1; + del_timer_sync(&xhci->event_ring_timer); +#endif + + xhci_dbg(xhci, "// Disabling event ring interrupts\n"); + temp = xhci_readl(xhci, &xhci->op_regs->status); + xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status); + temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); + xhci_writel(xhci, ER_IRQ_DISABLE(temp), + &xhci->ir_set->irq_pending); + xhci_print_ir_set(xhci, xhci->ir_set, 0); + + xhci_dbg(xhci, "cleaning up memory\n"); + xhci_mem_cleanup(xhci); + xhci_dbg(xhci, "xhci_stop completed - status = %x\n", + xhci_readl(xhci, &xhci->op_regs->status)); +} + +/* + * Shutdown HC (not bus-specific) + * + * This is called when the machine is rebooting or halting. We assume that the + * machine will be powered off, and the HC's internal state will be reset. + * Don't bother to free memory. + */ +void xhci_shutdown(struct usb_hcd *hcd) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + + spin_lock_irq(&xhci->lock); + xhci_halt(xhci); + spin_unlock_irq(&xhci->lock); + +#if 0 + xhci_cleanup_msix(xhci); +#endif + + xhci_dbg(xhci, "xhci_shutdown completed - status = %x\n", + xhci_readl(xhci, &xhci->op_regs->status)); +} + +/*-------------------------------------------------------------------------*/ + +/** + * xhci_get_endpoint_index - Used for passing endpoint bitmasks between the core and + * HCDs. Find the index for an endpoint given its descriptor. Use the return + * value to right shift 1 for the bitmask. + * + * Index = (epnum * 2) + direction - 1, + * where direction = 0 for OUT, 1 for IN. + * For control endpoints, the IN index is used (OUT index is unused), so + * index = (epnum * 2) + direction - 1 = (epnum * 2) + 1 - 1 = (epnum * 2) + */ +unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc) +{ + unsigned int index; + if (usb_endpoint_xfer_control(desc)) + index = (unsigned int) (usb_endpoint_num(desc)*2); + else + index = (unsigned int) (usb_endpoint_num(desc)*2) + + (usb_endpoint_dir_in(desc) ? 1 : 0) - 1; + return index; +} + +/* Find the flag for this endpoint (for use in the control context). Use the + * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is + * bit 1, etc. + */ +unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc) +{ + return 1 << (xhci_get_endpoint_index(desc) + 1); +} + +/* Find the flag for this endpoint (for use in the control context). Use the + * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is + * bit 1, etc. + */ +unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index) +{ + return 1 << (ep_index + 1); +} + +/* Compute the last valid endpoint context index. Basically, this is the + * endpoint index plus one. For slot contexts with more than valid endpoint, + * we find the most significant bit set in the added contexts flags. + * e.g. ep 1 IN (with epnum 0x81) => added_ctxs = 0b1000 + * fls(0b1000) = 4, but the endpoint context index is 3, so subtract one. + */ +unsigned int xhci_last_valid_endpoint(u32 added_ctxs) +{ + return fls(added_ctxs) - 1; +} + +/* Returns 1 if the arguments are OK; + * returns 0 this is a root hub; returns -EINVAL for NULL pointers. + */ +int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, + struct usb_host_endpoint *ep, int check_ep, const char *func) { + if (!hcd || (check_ep && !ep) || !udev) { + printk(KERN_DEBUG "xHCI %s called with invalid args\n", + func); + return -EINVAL; + } + if (!udev->parent) { + printk(KERN_DEBUG "xHCI %s called for root hub\n", + func); + return 0; + } + if (!udev->slot_id) { + printk(KERN_DEBUG "xHCI %s called with unaddressed device\n", + func); + return -EINVAL; + } + return 1; +} + +static int xhci_configure_endpoint(struct xhci_hcd *xhci, + struct usb_device *udev, struct xhci_command *command, + bool ctx_change, bool must_succeed); + +/* + * Full speed devices may have a max packet size greater than 8 bytes, but the + * USB core doesn't know that until it reads the first 8 bytes of the + * descriptor. If the usb_device's max packet size changes after that point, + * we need to issue an evaluate context command and wait on it. + */ +static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id, + unsigned int ep_index, struct urb *urb) +{ + struct xhci_container_ctx *in_ctx; + struct xhci_container_ctx *out_ctx; + struct xhci_input_control_ctx *ctrl_ctx; + struct xhci_ep_ctx *ep_ctx; + int max_packet_size; + int hw_max_packet_size; + int ret = 0; + + out_ctx = xhci->devs[slot_id]->out_ctx; + ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); + hw_max_packet_size = MAX_PACKET_DECODED(ep_ctx->ep_info2); + max_packet_size = urb->dev->ep0.desc.wMaxPacketSize; + if (hw_max_packet_size != max_packet_size) { + xhci_dbg(xhci, "Max Packet Size for ep 0 changed.\n"); + xhci_dbg(xhci, "Max packet size in usb_device = %d\n", + max_packet_size); + xhci_dbg(xhci, "Max packet size in xHCI HW = %d\n", + hw_max_packet_size); + xhci_dbg(xhci, "Issuing evaluate context command.\n"); + + /* Set up the modified control endpoint 0 */ + xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx, + xhci->devs[slot_id]->out_ctx, ep_index); + in_ctx = xhci->devs[slot_id]->in_ctx; + ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index); + ep_ctx->ep_info2 &= ~MAX_PACKET_MASK; + ep_ctx->ep_info2 |= MAX_PACKET(max_packet_size); + + /* Set up the input context flags for the command */ + /* FIXME: This won't work if a non-default control endpoint + * changes max packet sizes. + */ + ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); + ctrl_ctx->add_flags = EP0_FLAG; + ctrl_ctx->drop_flags = 0; + + xhci_dbg(xhci, "Slot %d input context\n", slot_id); + xhci_dbg_ctx(xhci, in_ctx, ep_index); + xhci_dbg(xhci, "Slot %d output context\n", slot_id); + xhci_dbg_ctx(xhci, out_ctx, ep_index); + + ret = xhci_configure_endpoint(xhci, urb->dev, NULL, + true, false); + + /* Clean up the input context for later use by bandwidth + * functions. + */ + ctrl_ctx->add_flags = SLOT_FLAG; + } + return ret; +} + +/* + * non-error returns are a promise to giveback() the urb later + * we drop ownership so next owner (or urb unlink) can get it + */ +int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + unsigned long flags; + int ret = 0; + unsigned int slot_id, ep_index; + + + if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0) + return -EINVAL; + + slot_id = urb->dev->slot_id; + ep_index = xhci_get_endpoint_index(&urb->ep->desc); + + if (!xhci->devs || !xhci->devs[slot_id]) { + if (!in_interrupt()) + dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n"); + ret = -EINVAL; + goto exit; + } + if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { + if (!in_interrupt()) + xhci_dbg(xhci, "urb submitted during PCI suspend\n"); + ret = -ESHUTDOWN; + goto exit; + } + if (usb_endpoint_xfer_control(&urb->ep->desc)) { + /* Check to see if the max packet size for the default control + * endpoint changed during FS device enumeration + */ + if (urb->dev->speed == USB_SPEED_FULL) { + ret = xhci_check_maxpacket(xhci, slot_id, + ep_index, urb); + if (ret < 0) + return ret; + } + + /* We have a spinlock and interrupts disabled, so we must pass + * atomic context to this function, which may allocate memory. + */ + spin_lock_irqsave(&xhci->lock, flags); + if (xhci->xhc_state & XHCI_STATE_DYING) + goto dying; + ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb, + slot_id, ep_index); + spin_unlock_irqrestore(&xhci->lock, flags); + } else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) { + spin_lock_irqsave(&xhci->lock, flags); + if (xhci->xhc_state & XHCI_STATE_DYING) + goto dying; + ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, + slot_id, ep_index); + spin_unlock_irqrestore(&xhci->lock, flags); + } else if (usb_endpoint_xfer_int(&urb->ep->desc)) { + spin_lock_irqsave(&xhci->lock, flags); + if (xhci->xhc_state & XHCI_STATE_DYING) + goto dying; + ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb, + slot_id, ep_index); + spin_unlock_irqrestore(&xhci->lock, flags); + } else { + ret = -EINVAL; + } +exit: + return ret; +dying: + xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for " + "non-responsive xHCI host.\n", + urb->ep->desc.bEndpointAddress, urb); + spin_unlock_irqrestore(&xhci->lock, flags); + return -ESHUTDOWN; +} + +/* + * Remove the URB's TD from the endpoint ring. This may cause the HC to stop + * USB transfers, potentially stopping in the middle of a TRB buffer. The HC + * should pick up where it left off in the TD, unless a Set Transfer Ring + * Dequeue Pointer is issued. + * + * The TRBs that make up the buffers for the canceled URB will be "removed" from + * the ring. Since the ring is a contiguous structure, they can't be physically + * removed. Instead, there are two options: + * + * 1) If the HC is in the middle of processing the URB to be canceled, we + * simply move the ring's dequeue pointer past those TRBs using the Set + * Transfer Ring Dequeue Pointer command. This will be the common case, + * when drivers timeout on the last submitted URB and attempt to cancel. + * + * 2) If the HC is in the middle of a different TD, we turn the TRBs into a + * series of 1-TRB transfer no-op TDs. (No-ops shouldn't be chained.) The + * HC will need to invalidate the any TRBs it has cached after the stop + * endpoint command, as noted in the xHCI 0.95 errata. + * + * 3) The TD may have completed by the time the Stop Endpoint Command + * completes, so software needs to handle that case too. + * + * This function should protect against the TD enqueueing code ringing the + * doorbell while this code is waiting for a Stop Endpoint command to complete. + * It also needs to account for multiple cancellations on happening at the same + * time for the same endpoint. + * + * Note that this function can be called in any context, or so says + * usb_hcd_unlink_urb() + */ +int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) +{ + unsigned long flags; + int ret; + u32 temp; + struct xhci_hcd *xhci; + struct xhci_td *td; + unsigned int ep_index; + struct xhci_ring *ep_ring; + struct xhci_virt_ep *ep; + + xhci = hcd_to_xhci(hcd); + spin_lock_irqsave(&xhci->lock, flags); + /* Make sure the URB hasn't completed or been unlinked already */ + ret = usb_hcd_check_unlink_urb(hcd, urb, status); + if (ret || !urb->hcpriv) + goto done; + temp = xhci_readl(xhci, &xhci->op_regs->status); + if (temp == 0xffffffff) { + xhci_dbg(xhci, "HW died, freeing TD.\n"); + td = (struct xhci_td *) urb->hcpriv; + + usb_hcd_unlink_urb_from_ep(hcd, urb); + spin_unlock_irqrestore(&xhci->lock, flags); + usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, -ESHUTDOWN); + kfree(td); + return ret; + } + if (xhci->xhc_state & XHCI_STATE_DYING) { + xhci_dbg(xhci, "Ep 0x%x: URB %p to be canceled on " + "non-responsive xHCI host.\n", + urb->ep->desc.bEndpointAddress, urb); + /* Let the stop endpoint command watchdog timer (which set this + * state) finish cleaning up the endpoint TD lists. We must + * have caught it in the middle of dropping a lock and giving + * back an URB. + */ + goto done; + } + + xhci_dbg(xhci, "Cancel URB %p\n", urb); + xhci_dbg(xhci, "Event ring:\n"); + xhci_debug_ring(xhci, xhci->event_ring); + ep_index = xhci_get_endpoint_index(&urb->ep->desc); + ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index]; + ep_ring = ep->ring; + xhci_dbg(xhci, "Endpoint ring:\n"); + xhci_debug_ring(xhci, ep_ring); + td = (struct xhci_td *) urb->hcpriv; + + list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list); + /* Queue a stop endpoint command, but only if this is + * the first cancellation to be handled. + */ + if (!(ep->ep_state & EP_HALT_PENDING)) { + ep->ep_state |= EP_HALT_PENDING; + ep->stop_cmds_pending++; + ep->stop_cmd_timer.expires = jiffies + + XHCI_STOP_EP_CMD_TIMEOUT * HZ; + add_timer(&ep->stop_cmd_timer); + xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index); + xhci_ring_cmd_db(xhci); + } +done: + spin_unlock_irqrestore(&xhci->lock, flags); + return ret; +} + +/* Drop an endpoint from a new bandwidth configuration for this device. + * Only one call to this function is allowed per endpoint before + * check_bandwidth() or reset_bandwidth() must be called. + * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will + * add the endpoint to the schedule with possibly new parameters denoted by a + * different endpoint descriptor in usb_host_endpoint. + * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is + * not allowed. + * + * The USB core will not allow URBs to be queued to an endpoint that is being + * disabled, so there's no need for mutual exclusion to protect + * the xhci->devs[slot_id] structure. + */ +int xhci_drop_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_input_control_ctx *ctrl_ctx; + struct xhci_slot_ctx *slot_ctx; + unsigned int last_ctx; + unsigned int ep_index; + struct xhci_ep_ctx *ep_ctx; + u32 drop_flag; + u32 new_add_flags, new_drop_flags, new_slot_info; + int ret; + + ret = xhci_check_args(hcd, udev, ep, 1, __func__); + if (ret <= 0) + return ret; + xhci = hcd_to_xhci(hcd); + xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); + + drop_flag = xhci_get_endpoint_flag(&ep->desc); + if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) { + xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n", + __func__, drop_flag); + return 0; + } + + if (!xhci->devs || !xhci->devs[udev->slot_id]) { + xhci_warn(xhci, "xHCI %s called with unaddressed device\n", + __func__); + return -EINVAL; + } + + 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); + ep_index = xhci_get_endpoint_index(&ep->desc); + ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); + /* If the HC already knows the endpoint is disabled, + * or the HCD has noted it is disabled, ignore this request + */ + if ((ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED || + ctrl_ctx->drop_flags & xhci_get_endpoint_flag(&ep->desc)) { + xhci_warn(xhci, "xHCI %s called with disabled ep %p\n", + __func__, ep); + return 0; + } + + ctrl_ctx->drop_flags |= drop_flag; + new_drop_flags = ctrl_ctx->drop_flags; + + ctrl_ctx->add_flags &= ~drop_flag; + new_add_flags = ctrl_ctx->add_flags; + + last_ctx = xhci_last_valid_endpoint(ctrl_ctx->add_flags); + slot_ctx = xhci_get_slot_ctx(xhci, in_ctx); + /* Update the last valid endpoint context, if we deleted the last one */ + if ((slot_ctx->dev_info & LAST_CTX_MASK) > LAST_CTX(last_ctx)) { + slot_ctx->dev_info &= ~LAST_CTX_MASK; + slot_ctx->dev_info |= LAST_CTX(last_ctx); + } + new_slot_info = slot_ctx->dev_info; + + xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep); + + xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n", + (unsigned int) ep->desc.bEndpointAddress, + udev->slot_id, + (unsigned int) new_drop_flags, + (unsigned int) new_add_flags, + (unsigned int) new_slot_info); + return 0; +} + +/* Add an endpoint to a new possible bandwidth configuration for this device. + * Only one call to this function is allowed per endpoint before + * check_bandwidth() or reset_bandwidth() must be called. + * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will + * add the endpoint to the schedule with possibly new parameters denoted by a + * different endpoint descriptor in usb_host_endpoint. + * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is + * not allowed. + * + * The USB core will not allow URBs to be queued to an endpoint until the + * configuration or alt setting is installed in the device, so there's no need + * for mutual exclusion to protect the xhci->devs[slot_id] structure. + */ +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; + unsigned int ep_index; + struct xhci_ep_ctx *ep_ctx; + struct xhci_slot_ctx *slot_ctx; + struct xhci_input_control_ctx *ctrl_ctx; + u32 added_ctxs; + unsigned int last_ctx; + u32 new_add_flags, new_drop_flags, new_slot_info; + int ret = 0; + + ret = xhci_check_args(hcd, udev, ep, 1, __func__); + if (ret <= 0) { + /* So we won't queue a reset ep command for a root hub */ + ep->hcpriv = NULL; + return ret; + } + xhci = hcd_to_xhci(hcd); + + added_ctxs = xhci_get_endpoint_flag(&ep->desc); + last_ctx = xhci_last_valid_endpoint(added_ctxs); + if (added_ctxs == SLOT_FLAG || added_ctxs == EP0_FLAG) { + /* FIXME when we have to issue an evaluate endpoint command to + * deal with ep0 max packet size changing once we get the + * descriptors + */ + xhci_dbg(xhci, "xHCI %s - can't add slot or ep 0 %#x\n", + __func__, added_ctxs); + return 0; + } + + if (!xhci->devs || !xhci->devs[udev->slot_id]) { + xhci_warn(xhci, "xHCI %s called with unaddressed device\n", + __func__); + return -EINVAL; + } + + 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); + ep_index = xhci_get_endpoint_index(&ep->desc); + ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); + /* If the HCD has already noted the endpoint is enabled, + * ignore this request. + */ + if (ctrl_ctx->add_flags & xhci_get_endpoint_flag(&ep->desc)) { + xhci_warn(xhci, "xHCI %s called with enabled ep %p\n", + __func__, ep); + return 0; + } + + /* + * Configuration and alternate setting changes must be done in + * process context, not interrupt context (or so documenation + * for usb_set_interface() and usb_set_configuration() claim). + */ + if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id], + udev, ep, GFP_NOIO) < 0) { + dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n", + __func__, ep->desc.bEndpointAddress); + return -ENOMEM; + } + + ctrl_ctx->add_flags |= added_ctxs; + new_add_flags = ctrl_ctx->add_flags; + + /* If xhci_endpoint_disable() was called for this endpoint, but the + * xHC hasn't been notified yet through the check_bandwidth() call, + * this re-adds a new state for the endpoint from the new endpoint + * descriptors. We must drop and re-add this endpoint, so we leave the + * drop flags alone. + */ + new_drop_flags = ctrl_ctx->drop_flags; + + slot_ctx = xhci_get_slot_ctx(xhci, in_ctx); + /* Update the last valid endpoint context, if we just added one past */ + if ((slot_ctx->dev_info & LAST_CTX_MASK) < LAST_CTX(last_ctx)) { + slot_ctx->dev_info &= ~LAST_CTX_MASK; + slot_ctx->dev_info |= LAST_CTX(last_ctx); + } + new_slot_info = slot_ctx->dev_info; + + /* Store the usb_device pointer for later use */ + ep->hcpriv = udev; + + xhci_dbg(xhci, "add ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n", + (unsigned int) ep->desc.bEndpointAddress, + udev->slot_id, + (unsigned int) new_drop_flags, + (unsigned int) new_add_flags, + (unsigned int) new_slot_info); + return 0; +} + +static void xhci_zero_in_ctx(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev) +{ + struct xhci_input_control_ctx *ctrl_ctx; + struct xhci_ep_ctx *ep_ctx; + struct xhci_slot_ctx *slot_ctx; + int i; + + /* When a device's add flag and drop flag are zero, any subsequent + * configure endpoint command will leave that endpoint's state + * untouched. Make sure we don't leave any old state in the input + * endpoint contexts. + */ + ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); + ctrl_ctx->drop_flags = 0; + ctrl_ctx->add_flags = 0; + slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); + slot_ctx->dev_info &= ~LAST_CTX_MASK; + /* Endpoint 0 is always valid */ + slot_ctx->dev_info |= LAST_CTX(1); + for (i = 1; i < 31; ++i) { + ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, i); + ep_ctx->ep_info = 0; + ep_ctx->ep_info2 = 0; + ep_ctx->deq = 0; + ep_ctx->tx_info = 0; + } +} + +static int xhci_configure_endpoint_result(struct xhci_hcd *xhci, + struct usb_device *udev, int *cmd_status) +{ + int ret; + + switch (*cmd_status) { + case COMP_ENOMEM: + dev_warn(&udev->dev, "Not enough host controller resources " + "for new device state.\n"); + ret = -ENOMEM; + /* FIXME: can we allocate more resources for the HC? */ + break; + case COMP_BW_ERR: + dev_warn(&udev->dev, "Not enough bandwidth " + "for new device state.\n"); + ret = -ENOSPC; + /* FIXME: can we go back to the old state? */ + break; + case COMP_TRB_ERR: + /* the HCD set up something wrong */ + dev_warn(&udev->dev, "ERROR: Endpoint drop flag = 0, " + "add flag = 1, " + "and endpoint is not disabled.\n"); + ret = -EINVAL; + break; + case COMP_SUCCESS: + dev_dbg(&udev->dev, "Successful Endpoint Configure command\n"); + ret = 0; + break; + default: + xhci_err(xhci, "ERROR: unexpected command completion " + "code 0x%x.\n", *cmd_status); + ret = -EINVAL; + break; + } + return ret; +} + +static int xhci_evaluate_context_result(struct xhci_hcd *xhci, + struct usb_device *udev, int *cmd_status) +{ + int ret; + struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id]; + + switch (*cmd_status) { + case COMP_EINVAL: + dev_warn(&udev->dev, "WARN: xHCI driver setup invalid evaluate " + "context command.\n"); + ret = -EINVAL; + break; + case COMP_EBADSLT: + dev_warn(&udev->dev, "WARN: slot not enabled for" + "evaluate context command.\n"); + case COMP_CTX_STATE: + dev_warn(&udev->dev, "WARN: invalid context state for " + "evaluate context command.\n"); + xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1); + ret = -EINVAL; + break; + case COMP_SUCCESS: + dev_dbg(&udev->dev, "Successful evaluate context command\n"); + ret = 0; + break; + default: + xhci_err(xhci, "ERROR: unexpected command completion " + "code 0x%x.\n", *cmd_status); + ret = -EINVAL; + break; + } + return ret; +} + +/* Issue a configure endpoint command or evaluate context command + * and wait for it to finish. + */ +static int xhci_configure_endpoint(struct xhci_hcd *xhci, + struct usb_device *udev, + struct xhci_command *command, + bool ctx_change, bool must_succeed) +{ + int ret; + int timeleft; + unsigned long flags; + struct xhci_container_ctx *in_ctx; + struct completion *cmd_completion; + int *cmd_status; + struct xhci_virt_device *virt_dev; + + spin_lock_irqsave(&xhci->lock, flags); + virt_dev = xhci->devs[udev->slot_id]; + if (command) { + in_ctx = command->in_ctx; + cmd_completion = command->completion; + cmd_status = &command->status; + command->command_trb = xhci->cmd_ring->enqueue; + list_add_tail(&command->cmd_list, &virt_dev->cmd_list); + } else { + in_ctx = virt_dev->in_ctx; + cmd_completion = &virt_dev->cmd_completion; + cmd_status = &virt_dev->cmd_status; + } + + if (!ctx_change) + ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, + udev->slot_id, must_succeed); + else + ret = xhci_queue_evaluate_context(xhci, in_ctx->dma, + udev->slot_id); + if (ret < 0) { + if (command) + list_del(&command->cmd_list); + spin_unlock_irqrestore(&xhci->lock, flags); + xhci_dbg(xhci, "FIXME allocate a new ring segment\n"); + return -ENOMEM; + } + xhci_ring_cmd_db(xhci); + spin_unlock_irqrestore(&xhci->lock, flags); + + /* Wait for the configure endpoint command to complete */ + timeleft = wait_for_completion_interruptible_timeout( + cmd_completion, + USB_CTRL_SET_TIMEOUT); + if (timeleft <= 0) { + xhci_warn(xhci, "%s while waiting for %s command\n", + timeleft == 0 ? "Timeout" : "Signal", + ctx_change == 0 ? + "configure endpoint" : + "evaluate context"); + /* FIXME cancel the configure endpoint command */ + return -ETIME; + } + + if (!ctx_change) + return xhci_configure_endpoint_result(xhci, udev, cmd_status); + return xhci_evaluate_context_result(xhci, udev, cmd_status); +} + +/* Called after one or more calls to xhci_add_endpoint() or + * xhci_drop_endpoint(). If this call fails, the USB core is expected + * to call xhci_reset_bandwidth(). + * + * Since we are in the middle of changing either configuration or + * installing a new alt setting, the USB core won't allow URBs to be + * enqueued for any endpoint on the old config or interface. Nothing + * else should be touching the xhci->devs[slot_id] structure, so we + * don't need to take the xhci->lock for manipulating that. + */ +int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) +{ + int i; + int ret = 0; + struct xhci_hcd *xhci; + struct xhci_virt_device *virt_dev; + struct xhci_input_control_ctx *ctrl_ctx; + struct xhci_slot_ctx *slot_ctx; + + ret = xhci_check_args(hcd, udev, NULL, 0, __func__); + if (ret <= 0) + return ret; + xhci = hcd_to_xhci(hcd); + + if (!udev->slot_id || !xhci->devs || !xhci->devs[udev->slot_id]) { + xhci_warn(xhci, "xHCI %s called with unaddressed device\n", + __func__); + return -EINVAL; + } + xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); + virt_dev = xhci->devs[udev->slot_id]; + + /* See section 4.6.6 - A0 = 1; A1 = D0 = D1 = 0 */ + ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); + ctrl_ctx->add_flags |= SLOT_FLAG; + ctrl_ctx->add_flags &= ~EP0_FLAG; + ctrl_ctx->drop_flags &= ~SLOT_FLAG; + ctrl_ctx->drop_flags &= ~EP0_FLAG; + xhci_dbg(xhci, "New Input Control Context:\n"); + slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); + xhci_dbg_ctx(xhci, virt_dev->in_ctx, + LAST_CTX_TO_EP_NUM(slot_ctx->dev_info)); + + ret = xhci_configure_endpoint(xhci, udev, NULL, + false, false); + if (ret) { + /* Callee should call reset_bandwidth() */ + return ret; + } + + xhci_dbg(xhci, "Output context after successful config ep cmd:\n"); + xhci_dbg_ctx(xhci, virt_dev->out_ctx, + LAST_CTX_TO_EP_NUM(slot_ctx->dev_info)); + + xhci_zero_in_ctx(xhci, virt_dev); + /* Install new rings and free or cache any old rings */ + for (i = 1; i < 31; ++i) { + if (!virt_dev->eps[i].new_ring) + continue; + /* Only cache or free the old ring if it exists. + * It may not if this is the first add of an endpoint. + */ + if (virt_dev->eps[i].ring) { + xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); + } + virt_dev->eps[i].ring = virt_dev->eps[i].new_ring; + virt_dev->eps[i].new_ring = NULL; + } + + return ret; +} + +void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) +{ + struct xhci_hcd *xhci; + struct xhci_virt_device *virt_dev; + int i, ret; + + ret = xhci_check_args(hcd, udev, NULL, 0, __func__); + if (ret <= 0) + return; + xhci = hcd_to_xhci(hcd); + + if (!xhci->devs || !xhci->devs[udev->slot_id]) { + xhci_warn(xhci, "xHCI %s called with unaddressed device\n", + __func__); + return; + } + xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); + virt_dev = xhci->devs[udev->slot_id]; + /* Free any rings allocated for added endpoints */ + for (i = 0; i < 31; ++i) { + if (virt_dev->eps[i].new_ring) { + xhci_ring_free(xhci, virt_dev->eps[i].new_ring); + virt_dev->eps[i].new_ring = NULL; + } + } + xhci_zero_in_ctx(xhci, virt_dev); +} + +static void xhci_setup_input_ctx_for_config_ep(struct xhci_hcd *xhci, + struct xhci_container_ctx *in_ctx, + struct xhci_container_ctx *out_ctx, + u32 add_flags, u32 drop_flags) +{ + struct xhci_input_control_ctx *ctrl_ctx; + ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); + ctrl_ctx->add_flags = add_flags; + ctrl_ctx->drop_flags = drop_flags; + xhci_slot_copy(xhci, in_ctx, out_ctx); + ctrl_ctx->add_flags |= SLOT_FLAG; + + xhci_dbg(xhci, "Input Context:\n"); + xhci_dbg_ctx(xhci, in_ctx, xhci_last_valid_endpoint(add_flags)); +} + +void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci, + unsigned int slot_id, unsigned int ep_index, + struct xhci_dequeue_state *deq_state) +{ + struct xhci_container_ctx *in_ctx; + struct xhci_ep_ctx *ep_ctx; + u32 added_ctxs; + dma_addr_t addr; + + xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx, + xhci->devs[slot_id]->out_ctx, ep_index); + in_ctx = xhci->devs[slot_id]->in_ctx; + ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index); + addr = xhci_trb_virt_to_dma(deq_state->new_deq_seg, + deq_state->new_deq_ptr); + if (addr == 0) { + xhci_warn(xhci, "WARN Cannot submit config ep after " + "reset ep command\n"); + xhci_warn(xhci, "WARN deq seg = %p, deq ptr = %p\n", + deq_state->new_deq_seg, + deq_state->new_deq_ptr); + return; + } + ep_ctx->deq = addr | deq_state->new_cycle_state; + + added_ctxs = xhci_get_endpoint_flag_from_index(ep_index); + xhci_setup_input_ctx_for_config_ep(xhci, xhci->devs[slot_id]->in_ctx, + xhci->devs[slot_id]->out_ctx, added_ctxs, added_ctxs); +} + +void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, + struct usb_device *udev, unsigned int ep_index) +{ + struct xhci_dequeue_state deq_state; + struct xhci_virt_ep *ep; + + xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n"); + ep = &xhci->devs[udev->slot_id]->eps[ep_index]; + /* We need to move the HW's dequeue pointer past this TD, + * or it will attempt to resend it on the next doorbell ring. + */ + xhci_find_new_dequeue_state(xhci, udev->slot_id, + ep_index, ep->stopped_td, + &deq_state); + + /* HW with the reset endpoint quirk will use the saved dequeue state to + * issue a configure endpoint command later. + */ + if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) { + xhci_dbg(xhci, "Queueing new dequeue state\n"); + xhci_queue_new_dequeue_state(xhci, udev->slot_id, + ep_index, &deq_state); + } else { + /* Better hope no one uses the input context between now and the + * reset endpoint completion! + */ + xhci_dbg(xhci, "Setting up input context for " + "configure endpoint command\n"); + xhci_setup_input_ctx_for_quirk(xhci, udev->slot_id, + ep_index, &deq_state); + } +} + +/* Deal with stalled endpoints. The core should have sent the control message + * to clear the halt condition. However, we need to make the xHCI hardware + * reset its sequence number, since a device will expect a sequence number of + * zero after the halt condition is cleared. + * Context: in_interrupt + */ +void xhci_endpoint_reset(struct usb_hcd *hcd, + struct usb_host_endpoint *ep) +{ + struct xhci_hcd *xhci; + struct usb_device *udev; + unsigned int ep_index; + unsigned long flags; + int ret; + struct xhci_virt_ep *virt_ep; + + xhci = hcd_to_xhci(hcd); + udev = (struct usb_device *) ep->hcpriv; + /* Called with a root hub endpoint (or an endpoint that wasn't added + * with xhci_add_endpoint() + */ + if (!ep->hcpriv) + return; + ep_index = xhci_get_endpoint_index(&ep->desc); + virt_ep = &xhci->devs[udev->slot_id]->eps[ep_index]; + if (!virt_ep->stopped_td) { + xhci_dbg(xhci, "Endpoint 0x%x not halted, refusing to reset.\n", + ep->desc.bEndpointAddress); + return; + } + if (usb_endpoint_xfer_control(&ep->desc)) { + xhci_dbg(xhci, "Control endpoint stall already handled.\n"); + return; + } + + xhci_dbg(xhci, "Queueing reset endpoint command\n"); + spin_lock_irqsave(&xhci->lock, flags); + ret = xhci_queue_reset_ep(xhci, udev->slot_id, ep_index); + /* + * Can't change the ring dequeue pointer until it's transitioned to the + * stopped state, which is only upon a successful reset endpoint + * command. Better hope that last command worked! + */ + if (!ret) { + xhci_cleanup_stalled_ring(xhci, udev, ep_index); + kfree(virt_ep->stopped_td); + xhci_ring_cmd_db(xhci); + } + spin_unlock_irqrestore(&xhci->lock, flags); + + if (ret) + xhci_warn(xhci, "FIXME allocate a new ring segment\n"); +} + +/* + * This submits a Reset Device Command, which will set the device state to 0, + * set the device address to 0, and disable all the endpoints except the default + * control endpoint. The USB core should come back and call + * xhci_address_device(), and then re-set up the configuration. If this is + * called because of a usb_reset_and_verify_device(), then the old alternate + * settings will be re-installed through the normal bandwidth allocation + * functions. + * + * Wait for the Reset Device command to finish. Remove all structures + * associated with the endpoints that were disabled. Clear the input device + * structure? Cache the rings? Reset the control endpoint 0 max packet size? + */ +int xhci_reset_device(struct usb_hcd *hcd, struct usb_device *udev) +{ + int ret, i; + unsigned long flags; + struct xhci_hcd *xhci; + unsigned int slot_id; + struct xhci_virt_device *virt_dev; + struct xhci_command *reset_device_cmd; + int timeleft; + int last_freed_endpoint; + + ret = xhci_check_args(hcd, udev, NULL, 0, __func__); + if (ret <= 0) + return ret; + xhci = hcd_to_xhci(hcd); + slot_id = udev->slot_id; + virt_dev = xhci->devs[slot_id]; + if (!virt_dev) { + xhci_dbg(xhci, "%s called with invalid slot ID %u\n", + __func__, slot_id); + return -EINVAL; + } + + xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id); + /* Allocate the command structure that holds the struct completion. + * Assume we're in process context, since the normal device reset + * process has to wait for the device anyway. Storage devices are + * reset as part of error handling, so use GFP_NOIO instead of + * GFP_KERNEL. + */ + reset_device_cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO); + if (!reset_device_cmd) { + xhci_dbg(xhci, "Couldn't allocate command structure.\n"); + return -ENOMEM; + } + + /* Attempt to submit the Reset Device command to the command ring */ + spin_lock_irqsave(&xhci->lock, flags); + reset_device_cmd->command_trb = xhci->cmd_ring->enqueue; + list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list); + ret = xhci_queue_reset_device(xhci, slot_id); + if (ret) { + xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); + list_del(&reset_device_cmd->cmd_list); + spin_unlock_irqrestore(&xhci->lock, flags); + goto command_cleanup; + } + xhci_ring_cmd_db(xhci); + spin_unlock_irqrestore(&xhci->lock, flags); + + /* Wait for the Reset Device command to finish */ + timeleft = wait_for_completion_interruptible_timeout( + reset_device_cmd->completion, + USB_CTRL_SET_TIMEOUT); + if (timeleft <= 0) { + xhci_warn(xhci, "%s while waiting for reset device command\n", + timeleft == 0 ? "Timeout" : "Signal"); + spin_lock_irqsave(&xhci->lock, flags); + /* The timeout might have raced with the event ring handler, so + * only delete from the list if the item isn't poisoned. + */ + if (reset_device_cmd->cmd_list.next != LIST_POISON1) + list_del(&reset_device_cmd->cmd_list); + spin_unlock_irqrestore(&xhci->lock, flags); + ret = -ETIME; + goto command_cleanup; + } + + /* The Reset Device command can't fail, according to the 0.95/0.96 spec, + * unless we tried to reset a slot ID that wasn't enabled, + * or the device wasn't in the addressed or configured state. + */ + ret = reset_device_cmd->status; + switch (ret) { + case COMP_EBADSLT: /* 0.95 completion code for bad slot ID */ + case COMP_CTX_STATE: /* 0.96 completion code for same thing */ + xhci_info(xhci, "Can't reset device (slot ID %u) in %s state\n", + slot_id, + xhci_get_slot_state(xhci, virt_dev->out_ctx)); + xhci_info(xhci, "Not freeing device rings.\n"); + /* Don't treat this as an error. May change my mind later. */ + ret = 0; + goto command_cleanup; + case COMP_SUCCESS: + xhci_dbg(xhci, "Successful reset device command.\n"); + break; + default: + if (xhci_is_vendor_info_code(xhci, ret)) + break; + xhci_warn(xhci, "Unknown completion code %u for " + "reset device command.\n", ret); + ret = -EINVAL; + goto command_cleanup; + } + + /* Everything but endpoint 0 is disabled, so free or cache the rings. */ + last_freed_endpoint = 1; + for (i = 1; i < 31; ++i) { + if (!virt_dev->eps[i].ring) + continue; + xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); + last_freed_endpoint = i; + } + xhci_dbg(xhci, "Output context after successful reset device cmd:\n"); + xhci_dbg_ctx(xhci, virt_dev->out_ctx, last_freed_endpoint); + ret = 0; + +command_cleanup: + xhci_free_command(xhci, reset_device_cmd); + return ret; +} + +/* + * At this point, the struct usb_device is about to go away, the device has + * disconnected, and all traffic has been stopped and the endpoints have been + * disabled. Free any HC data structures associated with that device. + */ +void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct xhci_virt_device *virt_dev; + unsigned long flags; + u32 state; + int i; + + if (udev->slot_id == 0) + return; + virt_dev = xhci->devs[udev->slot_id]; + if (!virt_dev) + return; + + /* Stop any wayward timer functions (which may grab the lock) */ + for (i = 0; i < 31; ++i) { + virt_dev->eps[i].ep_state &= ~EP_HALT_PENDING; + del_timer_sync(&virt_dev->eps[i].stop_cmd_timer); + } + + spin_lock_irqsave(&xhci->lock, flags); + /* Don't disable the slot if the host controller is dead. */ + state = xhci_readl(xhci, &xhci->op_regs->status); + if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) { + xhci_free_virt_device(xhci, udev->slot_id); + spin_unlock_irqrestore(&xhci->lock, flags); + return; + } + + if (xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) { + spin_unlock_irqrestore(&xhci->lock, flags); + xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); + return; + } + xhci_ring_cmd_db(xhci); + spin_unlock_irqrestore(&xhci->lock, flags); + /* + * Event command completion handler will free any data structures + * associated with the slot. XXX Can free sleep? + */ +} + +/* + * Returns 0 if the xHC ran out of device slots, the Enable Slot command + * timed out, or allocating memory failed. Returns 1 on success. + */ +int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + unsigned long flags; + int timeleft; + int ret; + + spin_lock_irqsave(&xhci->lock, flags); + ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0); + if (ret) { + spin_unlock_irqrestore(&xhci->lock, flags); + xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); + return 0; + } + xhci_ring_cmd_db(xhci); + spin_unlock_irqrestore(&xhci->lock, flags); + + /* XXX: how much time for xHC slot assignment? */ + timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, + USB_CTRL_SET_TIMEOUT); + if (timeleft <= 0) { + xhci_warn(xhci, "%s while waiting for a slot\n", + timeleft == 0 ? "Timeout" : "Signal"); + /* FIXME cancel the enable slot request */ + return 0; + } + + if (!xhci->slot_id) { + xhci_err(xhci, "Error while assigning device slot ID\n"); + return 0; + } + /* xhci_alloc_virt_device() does not touch rings; no need to lock */ + if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_KERNEL)) { + /* Disable slot, if we can do it without mem alloc */ + xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n"); + spin_lock_irqsave(&xhci->lock, flags); + if (!xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) + xhci_ring_cmd_db(xhci); + spin_unlock_irqrestore(&xhci->lock, flags); + return 0; + } + udev->slot_id = xhci->slot_id; + /* Is this a LS or FS device under a HS hub? */ + /* Hub or peripherial? */ + return 1; +} + +/* + * Issue an Address Device command (which will issue a SetAddress request to + * the device). + * We should be protected by the usb_address0_mutex in khubd's hub_port_init, so + * we should only issue and wait on one address command at the same time. + * + * We add one to the device address issued by the hardware because the USB core + * uses address 1 for the root hubs (even though they're not really devices). + */ +int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) +{ + unsigned long flags; + int timeleft; + struct xhci_virt_device *virt_dev; + int ret = 0; + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct xhci_slot_ctx *slot_ctx; + struct xhci_input_control_ctx *ctrl_ctx; + u64 temp_64; + + if (!udev->slot_id) { + xhci_dbg(xhci, "Bad Slot ID %d\n", udev->slot_id); + return -EINVAL; + } + + virt_dev = xhci->devs[udev->slot_id]; + + /* If this is a Set Address to an unconfigured device, setup ep 0 */ + if (!udev->config) + xhci_setup_addressable_virt_dev(xhci, udev); + /* Otherwise, assume the core has the device configured how it wants */ + xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); + xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); + + spin_lock_irqsave(&xhci->lock, flags); + ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, + udev->slot_id); + if (ret) { + spin_unlock_irqrestore(&xhci->lock, flags); + xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); + return ret; + } + xhci_ring_cmd_db(xhci); + spin_unlock_irqrestore(&xhci->lock, flags); + + /* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */ + timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, + USB_CTRL_SET_TIMEOUT); + /* FIXME: From section 4.3.4: "Software shall be responsible for timing + * the SetAddress() "recovery interval" required by USB and aborting the + * command on a timeout. + */ + if (timeleft <= 0) { + xhci_warn(xhci, "%s while waiting for a slot\n", + timeleft == 0 ? "Timeout" : "Signal"); + /* FIXME cancel the address device command */ + return -ETIME; + } + + switch (virt_dev->cmd_status) { + case COMP_CTX_STATE: + case COMP_EBADSLT: + xhci_err(xhci, "Setup ERROR: address device command for slot %d.\n", + udev->slot_id); + ret = -EINVAL; + break; + case COMP_TX_ERR: + dev_warn(&udev->dev, "Device not responding to set address.\n"); + ret = -EPROTO; + break; + case COMP_SUCCESS: + xhci_dbg(xhci, "Successful Address Device command\n"); + break; + default: + xhci_err(xhci, "ERROR: unexpected command completion " + "code 0x%x.\n", virt_dev->cmd_status); + xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id); + xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2); + ret = -EINVAL; + break; + } + if (ret) { + return ret; + } + temp_64 = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); + xhci_dbg(xhci, "Op regs DCBAA ptr = %#016llx\n", temp_64); + xhci_dbg(xhci, "Slot ID %d dcbaa entry @%p = %#016llx\n", + udev->slot_id, + &xhci->dcbaa->dev_context_ptrs[udev->slot_id], + (unsigned long long) + xhci->dcbaa->dev_context_ptrs[udev->slot_id]); + xhci_dbg(xhci, "Output Context DMA address = %#08llx\n", + (unsigned long long)virt_dev->out_ctx->dma); + xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); + xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); + xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id); + xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2); + /* + * USB core uses address 1 for the roothubs, so we add one to the + * address given back to us by the HC. + */ + slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); + udev->devnum = (slot_ctx->dev_state & DEV_ADDR_MASK) + 1; + /* Zero the input context control for later use */ + ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); + ctrl_ctx->add_flags = 0; + ctrl_ctx->drop_flags = 0; + + xhci_dbg(xhci, "Device address = %d\n", udev->devnum); + /* XXX Meh, not sure if anyone else but choose_address uses this. */ + set_bit(udev->devnum, udev->bus->devmap.devicemap); + + return 0; +} + +/* Once a hub descriptor is fetched for a device, we need to update the xHC's + * internal data structures for the device. + */ +int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, + struct usb_tt *tt, gfp_t mem_flags) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct xhci_virt_device *vdev; + struct xhci_command *config_cmd; + struct xhci_input_control_ctx *ctrl_ctx; + struct xhci_slot_ctx *slot_ctx; + unsigned long flags; + unsigned think_time; + int ret; + + /* Ignore root hubs */ + if (!hdev->parent) + return 0; + + vdev = xhci->devs[hdev->slot_id]; + if (!vdev) { + xhci_warn(xhci, "Cannot update hub desc for unknown device.\n"); + return -EINVAL; + } + config_cmd = xhci_alloc_command(xhci, true, true, mem_flags); + if (!config_cmd) { + xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); + return -ENOMEM; + } + + spin_lock_irqsave(&xhci->lock, flags); + xhci_slot_copy(xhci, config_cmd->in_ctx, vdev->out_ctx); + ctrl_ctx = xhci_get_input_control_ctx(xhci, config_cmd->in_ctx); + ctrl_ctx->add_flags |= SLOT_FLAG; + slot_ctx = xhci_get_slot_ctx(xhci, config_cmd->in_ctx); + slot_ctx->dev_info |= DEV_HUB; + if (tt->multi) + slot_ctx->dev_info |= DEV_MTT; + if (xhci->hci_version > 0x95) { + xhci_dbg(xhci, "xHCI version %x needs hub " + "TT think time and number of ports\n", + (unsigned int) xhci->hci_version); + slot_ctx->dev_info2 |= XHCI_MAX_PORTS(hdev->maxchild); + /* Set TT think time - convert from ns to FS bit times. + * 0 = 8 FS bit times, 1 = 16 FS bit times, + * 2 = 24 FS bit times, 3 = 32 FS bit times. + */ + think_time = tt->think_time; + if (think_time != 0) + think_time = (think_time / 666) - 1; + slot_ctx->tt_info |= TT_THINK_TIME(think_time); + } else { + xhci_dbg(xhci, "xHCI version %x doesn't need hub " + "TT think time or number of ports\n", + (unsigned int) xhci->hci_version); + } + slot_ctx->dev_state = 0; + spin_unlock_irqrestore(&xhci->lock, flags); + + xhci_dbg(xhci, "Set up %s for hub device.\n", + (xhci->hci_version > 0x95) ? + "configure endpoint" : "evaluate context"); + xhci_dbg(xhci, "Slot %u Input Context:\n", hdev->slot_id); + xhci_dbg_ctx(xhci, config_cmd->in_ctx, 0); + + /* Issue and wait for the configure endpoint or + * evaluate context command. + */ + if (xhci->hci_version > 0x95) + ret = xhci_configure_endpoint(xhci, hdev, config_cmd, + false, false); + else + ret = xhci_configure_endpoint(xhci, hdev, config_cmd, + true, false); + + xhci_dbg(xhci, "Slot %u Output Context:\n", hdev->slot_id); + xhci_dbg_ctx(xhci, vdev->out_ctx, 0); + + xhci_free_command(xhci, config_cmd); + return ret; +} + +int xhci_get_frame(struct usb_hcd *hcd) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + /* EHCI mods by the periodic size. Why? */ + return xhci_readl(xhci, &xhci->run_regs->microframe_index) >> 3; +} + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_LICENSE("GPL"); + +static int __init xhci_hcd_init(void) +{ +#ifdef CONFIG_PCI + int retval = 0; + + retval = xhci_register_pci(); + + if (retval < 0) { + printk(KERN_DEBUG "Problem registering PCI driver."); + return retval; + } +#endif + /* + * Check the compiler generated sizes of structures that must be laid + * out in specific ways for hardware access. + */ + BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8); + BUILD_BUG_ON(sizeof(struct xhci_slot_ctx) != 8*32/8); + BUILD_BUG_ON(sizeof(struct xhci_ep_ctx) != 8*32/8); + /* xhci_device_control has eight fields, and also + * embeds one xhci_slot_ctx and 31 xhci_ep_ctx + */ + BUILD_BUG_ON(sizeof(struct xhci_stream_ctx) != 4*32/8); + BUILD_BUG_ON(sizeof(union xhci_trb) != 4*32/8); + BUILD_BUG_ON(sizeof(struct xhci_erst_entry) != 4*32/8); + BUILD_BUG_ON(sizeof(struct xhci_cap_regs) != 7*32/8); + BUILD_BUG_ON(sizeof(struct xhci_intr_reg) != 8*32/8); + /* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */ + BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8); + BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8); + return 0; +} +module_init(xhci_hcd_init); + +static void __exit xhci_hcd_cleanup(void) +{ +#ifdef CONFIG_PCI + xhci_unregister_pci(); +#endif +} +module_exit(xhci_hcd_cleanup); -- cgit v1.2.2 From 1d68064a7d80da4a7334cab0356162e36229c1a1 Mon Sep 17 00:00:00 2001 From: Andiry Xu Date: Fri, 12 Mar 2010 17:10:04 +0800 Subject: USB: xHCI: re-initialize cmd_completion When a signal interrupts a Configure Endpoint command, the cmd_completion used in xhci_configure_endpoint() is not re-initialized and the wait_for_completion_interruptible_timeout() will return failure. Initialize cmd_completion in xhci_configure_endpoint(). Signed-off-by: Andiry Xu Signed-off-by: Sarah Sharp Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/usb') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 4cb69e0af834..492a61c2c79d 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1173,6 +1173,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, cmd_completion = &virt_dev->cmd_completion; cmd_status = &virt_dev->cmd_status; } + init_completion(cmd_completion); if (!ctx_change) ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, -- cgit v1.2.2 From dee5658b482e9e2ac7d6205dc876fc11d4008138 Mon Sep 17 00:00:00 2001 From: Daniel Sangorrin Date: Thu, 11 Mar 2010 14:10:58 -0800 Subject: USB: serial: ftdi: add CONTEC vendor and product id This is a patch to ftdi_sio_ids.h and ftdi_sio.c that adds identifiers for CONTEC USB serial converter. I tested it with the device COM-1(USB)H [akpm@linux-foundation.org: keep the VIDs sorted a bit] Signed-off-by: Daniel Sangorrin Cc: Andreas Mohr Cc: Radek Liboska Cc: stable Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio_ids.h | 7 +++++++ 2 files changed, 8 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 6af0dfa5f5ac..6fc09dc3b53e 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -658,6 +658,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) }, { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) }, + { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 0727e198503e..75482cbc3998 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -500,6 +500,13 @@ #define CONTEC_VID 0x06CE /* Vendor ID */ #define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ +/* + * Contec products (http://www.contec.com) + * Submitted by Daniel Sangorrin + */ +#define CONTEC_VID 0x06CE /* Vendor ID */ +#define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ + /* * Definitions for B&B Electronics products. */ -- cgit v1.2.2 From eaff4cdc978f414cf7b5441a333de3070d80e9c7 Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Thu, 11 Mar 2010 13:09:24 -0500 Subject: USB: option: fix incorrect manufacturer name in usb/serial/option: MAXON->CMOTECH Signed-off-by: Nathaniel McCallum Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 3ab1a0440d81..f19fd3335cdb 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -288,7 +288,7 @@ static int option_resume(struct usb_serial *serial); #define QUALCOMM_VENDOR_ID 0x05C6 -#define MAXON_VENDOR_ID 0x16d8 +#define CMOTECH_VENDOR_ID 0x16d8 #define TELIT_VENDOR_ID 0x1bc7 #define TELIT_PRODUCT_UC864E 0x1003 @@ -548,7 +548,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ - { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ + { USB_DEVICE(CMOTECH_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ -- cgit v1.2.2 From bb73ed2a268a29ab1b7d8cc50b5f248578e7e188 Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Thu, 11 Mar 2010 13:01:17 -0500 Subject: USB: option: move hardcoded PID to a macro in usb/serial/option Signed-off-by: Nathaniel McCallum Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index f19fd3335cdb..132ad930e6b2 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -289,6 +289,7 @@ static int option_resume(struct usb_serial *serial); #define QUALCOMM_VENDOR_ID 0x05C6 #define CMOTECH_VENDOR_ID 0x16d8 +#define CMOTECH_PRODUCT_6280 0x6280 #define TELIT_VENDOR_ID 0x1bc7 #define TELIT_PRODUCT_UC864E 0x1003 @@ -548,7 +549,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ - { USB_DEVICE(CMOTECH_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ -- cgit v1.2.2 From 3b04872aa75006e2a4adaaec21e9c9ede8b8ad9d Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Thu, 11 Mar 2010 13:09:26 -0500 Subject: USB: option: add support for a new CMOTECH device to usb/serial/option Signed-off-by: Nathaniel McCallum Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 132ad930e6b2..3af1eb8aa635 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -289,6 +289,7 @@ static int option_resume(struct usb_serial *serial); #define QUALCOMM_VENDOR_ID 0x05C6 #define CMOTECH_VENDOR_ID 0x16d8 +#define CMOTECH_PRODUCT_6008 0x6008 #define CMOTECH_PRODUCT_6280 0x6280 #define TELIT_VENDOR_ID 0x1bc7 @@ -550,6 +551,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ -- cgit v1.2.2 From fa7bf3424ead0a496f5176abb3253b8176bb2935 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 11 Mar 2010 15:06:54 -0700 Subject: usb/gadget: fix compile error on r8a66597-udc.c C file uses IS_ERR and PTR_ERR, but doesn't include Signed-off-by: Grant Likely Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/r8a66597-udc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 8b45145b9136..5e13d23b5f0c 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.2 From 9957dd97ec5e98dd334f87ade1d9a0b24d1f86eb Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 12 Mar 2010 10:35:20 +0200 Subject: usb: musb: Fix compile error for omaps for musb_hdrc CONFIG_ARCH_OMAP34XX is now CONFIG_ARCH_OMAP3. But since drivers/usb/musb/omap2430.c use CONFIG_PM for these registers and functions, do the same for the header. Otherwise we get the following for most omap3 defconfigs: drivers/usb/musb/omap2430.c:261: error: expected identifier or '(' before 'do' drivers/usb/musb/omap2430.c:261: error: expected identifier or '(' before 'while' drivers/usb/musb/omap2430.c:268: error: expected identifier or '(' before 'do' drivers/usb/musb/omap2430.c:268: error: expected identifier or '(' before 'while' Signed-off-by: Tony Lindgren Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index d849fb81c131..cd9f4a9a06c6 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -469,7 +469,7 @@ struct musb_csr_regs { struct musb_context_registers { -#if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP2430) +#ifdef CONFIG_PM u32 otg_sysconfig, otg_forcestandby; #endif u8 power; @@ -483,7 +483,7 @@ struct musb_context_registers { struct musb_csr_regs index_regs[MUSB_C_NUM_EPS]; }; -#if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP2430) +#ifdef CONFIG_PM extern void musb_platform_save_context(struct musb *musb, struct musb_context_registers *musb_context); extern void musb_platform_restore_context(struct musb *musb, -- cgit v1.2.2 From adb3ee421d6d39fbfadadf7093a587461ac4597e Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 12 Mar 2010 10:27:21 +0200 Subject: usb: musb: abstract out ULPI_BUSCONTROL register reads/writes The USB PHY on current Blackfin processors is a UTMI+ level 2 PHY. However, it has no ULPI support - so there are no registers at all. That means accesses to ULPI_BUSCONTROL have to be abstracted away like other MUSB registers. This fixes building for Blackfin parts again. Signed-off-by: Mike Frysinger Acked-by: Anand Gadiyar Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 5 ++--- drivers/usb/musb/musb_regs.h | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index b4bbf8f2c238..e54e468c5672 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2007,7 +2007,6 @@ bad_config: /* host side needs more setup */ if (is_host_enabled(musb)) { struct usb_hcd *hcd = musb_to_hcd(musb); - u8 busctl; otg_set_host(musb->xceiv, &hcd->self); @@ -2018,9 +2017,9 @@ bad_config: /* program PHY to use external vBus if required */ if (plat->extvbus) { - busctl = musb_readb(musb->mregs, MUSB_ULPI_BUSCONTROL); + u8 busctl = musb_read_ulpi_buscontrol(musb->mregs); busctl |= MUSB_ULPI_USE_EXTVBUS; - musb_writeb(musb->mregs, MUSB_ULPI_BUSCONTROL, busctl); + musb_write_ulpi_buscontrol(musb->mregs, busctl); } } diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index 8d8062b10e2f..327d0edd210e 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h @@ -326,6 +326,11 @@ static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off) musb_writew(mbase, MUSB_RXFIFOADD, c_off); } +static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val) +{ + musb_writeb(mbase, MUSB_ULPI_BUSCONTROL, val); +} + static inline u8 musb_read_txfifosz(void __iomem *mbase) { return musb_readb(mbase, MUSB_TXFIFOSZ); @@ -346,6 +351,11 @@ static inline u16 musb_read_rxfifoadd(void __iomem *mbase) return musb_readw(mbase, MUSB_RXFIFOADD); } +static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase) +{ + return musb_readb(mbase, MUSB_ULPI_BUSCONTROL); +} + static inline u8 musb_read_configdata(void __iomem *mbase) { musb_writeb(mbase, MUSB_INDEX, 0); @@ -510,6 +520,10 @@ static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off) { } +static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val) +{ +} + static inline u8 musb_read_txfifosz(void __iomem *mbase) { } @@ -526,6 +540,11 @@ static inline u16 musb_read_rxfifoadd(void __iomem *mbase) { } +static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase) +{ + return 0; +} + static inline u8 musb_read_configdata(void __iomem *mbase) { return 0; -- cgit v1.2.2 From 7f4bca4049941ba8dac35775fe462d4ef9f0dce4 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 12 Mar 2010 10:27:23 +0200 Subject: USB: musb: fix warnings in Blackfin regs The recent commit "usb: musb: Add context save and restore support" added some stubs for the Blackfin code so things would compile, but it also added a bunch of warnings due to missing return statements. Signed-off-by: Mike Frysinger Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_regs.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index 327d0edd210e..fa55aacc385d 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h @@ -526,18 +526,22 @@ static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val) static inline u8 musb_read_txfifosz(void __iomem *mbase) { + return 0; } static inline u16 musb_read_txfifoadd(void __iomem *mbase) { + return 0; } static inline u8 musb_read_rxfifosz(void __iomem *mbase) { + return 0; } static inline u16 musb_read_rxfifoadd(void __iomem *mbase) { + return 0; } static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase) @@ -596,22 +600,27 @@ static inline void musb_write_txhubport(void __iomem *mbase, u8 epnum, static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum) { + return 0; } static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum) { + return 0; } static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum) { + return 0; } static inline u8 musb_read_txfunaddr(void __iomem *mbase, u8 epnum) { + return 0; } static inline u8 musb_read_txhubaddr(void __iomem *mbase, u8 epnum) { + return 0; } static inline void musb_read_txhubport(void __iomem *mbase, u8 epnum) -- cgit v1.2.2 From aa4714560b4ea359bb7830188ebd06bce71bcdea Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 12 Mar 2010 10:27:24 +0200 Subject: usb: musb: core: declare mbase only where it's used ... and avoid a compilation if we disable host side of musb. Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index e54e468c5672..0e8b8ab1d168 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -379,7 +379,6 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, u8 devctl, u8 power) { irqreturn_t handled = IRQ_NONE; - void __iomem *mbase = musb->mregs; DBG(3, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl, int_usb); @@ -394,6 +393,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, if (devctl & MUSB_DEVCTL_HM) { #ifdef CONFIG_USB_MUSB_HDRC_HCD + void __iomem *mbase = musb->mregs; + switch (musb->xceiv->state) { case OTG_STATE_A_SUSPEND: /* remote wakeup? later, GetPortStatus @@ -471,6 +472,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, #ifdef CONFIG_USB_MUSB_HDRC_HCD /* see manual for the order of the tests */ if (int_usb & MUSB_INTR_SESSREQ) { + void __iomem *mbase = musb->mregs; + DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb)); /* IRQ arrives from ID pin sense or (later, if VBUS power @@ -519,6 +522,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, case OTG_STATE_A_WAIT_BCON: case OTG_STATE_A_WAIT_VRISE: if (musb->vbuserr_retry) { + void __iomem *mbase = musb->mregs; + musb->vbuserr_retry--; ignore = 1; devctl |= MUSB_DEVCTL_SESSION; @@ -622,6 +627,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, if (int_usb & MUSB_INTR_CONNECT) { struct usb_hcd *hcd = musb_to_hcd(musb); + void __iomem *mbase = musb->mregs; handled = IRQ_HANDLED; musb->is_active = 1; -- cgit v1.2.2 From 860e41a71c1731e79e1920dc42676bafc925af5e Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sat, 27 Feb 2010 20:54:24 +0100 Subject: usb: cdc-wdm: Fix race between write and disconnect Unify mutexes to fix a race between write and disconnect and shift the test for disconnection to always report it. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 84 ++++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 39 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 18aafcb08fc8..cf1c5fb918dc 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -87,9 +87,7 @@ struct wdm_device { int count; dma_addr_t shandle; dma_addr_t ihandle; - struct mutex wlock; - struct mutex rlock; - struct mutex plock; + struct mutex lock; wait_queue_head_t wait; struct work_struct rxwork; int werr; @@ -305,14 +303,38 @@ static ssize_t wdm_write if (we < 0) return -EIO; - r = mutex_lock_interruptible(&desc->wlock); /* concurrent writes */ + desc->outbuf = buf = kmalloc(count, GFP_KERNEL); + if (!buf) { + rv = -ENOMEM; + goto outnl; + } + + r = copy_from_user(buf, buffer, count); + if (r > 0) { + kfree(buf); + rv = -EFAULT; + goto outnl; + } + + /* concurrent writes and disconnect */ + r = mutex_lock_interruptible(&desc->lock); rv = -ERESTARTSYS; - if (r) + if (r) { + kfree(buf); goto outnl; + } + + if (test_bit(WDM_DISCONNECTING, &desc->flags)) { + kfree(buf); + rv = -ENODEV; + goto outnp; + } r = usb_autopm_get_interface(desc->intf); - if (r < 0) + if (r < 0) { + kfree(buf); goto outnp; + } if (!file->f_flags && O_NONBLOCK) r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE, @@ -320,24 +342,8 @@ static ssize_t wdm_write else if (test_bit(WDM_IN_USE, &desc->flags)) r = -EAGAIN; - if (r < 0) - goto out; - - if (test_bit(WDM_DISCONNECTING, &desc->flags)) { - rv = -ENODEV; - goto out; - } - - desc->outbuf = buf = kmalloc(count, GFP_KERNEL); - if (!buf) { - rv = -ENOMEM; - goto out; - } - - r = copy_from_user(buf, buffer, count); - if (r > 0) { + if (r < 0) { kfree(buf); - rv = -EFAULT; goto out; } @@ -374,7 +380,7 @@ static ssize_t wdm_write out: usb_autopm_put_interface(desc->intf); outnp: - mutex_unlock(&desc->wlock); + mutex_unlock(&desc->lock); outnl: return rv < 0 ? rv : count; } @@ -387,7 +393,7 @@ static ssize_t wdm_read struct wdm_device *desc = file->private_data; - rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */ + rv = mutex_lock_interruptible(&desc->lock); /*concurrent reads */ if (rv < 0) return -ERESTARTSYS; @@ -465,7 +471,7 @@ retry: rv = cntr; err: - mutex_unlock(&desc->rlock); + mutex_unlock(&desc->lock); if (rv < 0 && rv != -EAGAIN) dev_err(&desc->intf->dev, "wdm_read: exit error\n"); return rv; @@ -533,7 +539,7 @@ static int wdm_open(struct inode *inode, struct file *file) } intf->needs_remote_wakeup = 1; - mutex_lock(&desc->plock); + mutex_lock(&desc->lock); if (!desc->count++) { rv = usb_submit_urb(desc->validity, GFP_KERNEL); if (rv < 0) { @@ -544,7 +550,7 @@ static int wdm_open(struct inode *inode, struct file *file) } else { rv = 0; } - mutex_unlock(&desc->plock); + mutex_unlock(&desc->lock); usb_autopm_put_interface(desc->intf); out: mutex_unlock(&wdm_mutex); @@ -556,9 +562,9 @@ static int wdm_release(struct inode *inode, struct file *file) struct wdm_device *desc = file->private_data; mutex_lock(&wdm_mutex); - mutex_lock(&desc->plock); + mutex_lock(&desc->lock); desc->count--; - mutex_unlock(&desc->plock); + mutex_unlock(&desc->lock); if (!desc->count) { dev_dbg(&desc->intf->dev, "wdm_release: cleanup"); @@ -655,9 +661,7 @@ next_desc: desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL); if (!desc) goto out; - mutex_init(&desc->wlock); - mutex_init(&desc->rlock); - mutex_init(&desc->plock); + mutex_init(&desc->lock); spin_lock_init(&desc->iuspin); init_waitqueue_head(&desc->wait); desc->wMaxCommand = maxcom; @@ -772,7 +776,9 @@ static void wdm_disconnect(struct usb_interface *intf) clear_bit(WDM_IN_USE, &desc->flags); spin_unlock_irqrestore(&desc->iuspin, flags); cancel_work_sync(&desc->rxwork); + mutex_lock(&desc->lock); kill_urbs(desc); + mutex_unlock(&desc->lock); wake_up_all(&desc->wait); if (!desc->count) cleanup(desc); @@ -786,7 +792,7 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); - mutex_lock(&desc->plock); + mutex_lock(&desc->lock); #ifdef CONFIG_PM if ((message.event & PM_EVENT_AUTO) && test_bit(WDM_IN_USE, &desc->flags)) { @@ -798,7 +804,7 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) #ifdef CONFIG_PM } #endif - mutex_unlock(&desc->plock); + mutex_unlock(&desc->lock); return rv; } @@ -821,9 +827,9 @@ static int wdm_resume(struct usb_interface *intf) int rv; dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); - mutex_lock(&desc->plock); + mutex_lock(&desc->lock); rv = recover_from_urb_loss(desc); - mutex_unlock(&desc->plock); + mutex_unlock(&desc->lock); return rv; } @@ -831,7 +837,7 @@ static int wdm_pre_reset(struct usb_interface *intf) { struct wdm_device *desc = usb_get_intfdata(intf); - mutex_lock(&desc->plock); + mutex_lock(&desc->lock); return 0; } @@ -841,7 +847,7 @@ static int wdm_post_reset(struct usb_interface *intf) int rv; rv = recover_from_urb_loss(desc); - mutex_unlock(&desc->plock); + mutex_unlock(&desc->lock); return 0; } -- cgit v1.2.2 From 922a5eadd5a3aa0b806be0c18694b618d41d0784 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sat, 27 Feb 2010 20:54:59 +0100 Subject: usb: cdc-wdm: Fix race between autosuspend and reading from the device While an available response is read the device must not be autosuspended. This requires a flag dedicated to that purpose. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index cf1c5fb918dc..940b17af162c 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -52,6 +52,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); #define WDM_READ 4 #define WDM_INT_STALL 5 #define WDM_POLL_RUNNING 6 +#define WDM_RESPONDING 7 #define WDM_MAX 16 @@ -115,21 +116,22 @@ static void wdm_in_callback(struct urb *urb) int status = urb->status; spin_lock(&desc->iuspin); + clear_bit(WDM_RESPONDING, &desc->flags); if (status) { switch (status) { case -ENOENT: dev_dbg(&desc->intf->dev, "nonzero urb status received: -ENOENT"); - break; + goto skip_error; case -ECONNRESET: dev_dbg(&desc->intf->dev, "nonzero urb status received: -ECONNRESET"); - break; + goto skip_error; case -ESHUTDOWN: dev_dbg(&desc->intf->dev, "nonzero urb status received: -ESHUTDOWN"); - break; + goto skip_error; case -EPIPE: dev_err(&desc->intf->dev, "nonzero urb status received: -EPIPE\n"); @@ -145,6 +147,7 @@ static void wdm_in_callback(struct urb *urb) desc->reslength = urb->actual_length; memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength); desc->length += desc->reslength; +skip_error: wake_up(&desc->wait); set_bit(WDM_READ, &desc->flags); @@ -227,6 +230,7 @@ static void wdm_int_callback(struct urb *urb) desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; spin_lock(&desc->iuspin); clear_bit(WDM_READ, &desc->flags); + set_bit(WDM_RESPONDING, &desc->flags); if (!test_bit(WDM_DISCONNECTING, &desc->flags)) { rv = usb_submit_urb(desc->response, GFP_ATOMIC); dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", @@ -234,6 +238,7 @@ static void wdm_int_callback(struct urb *urb) } spin_unlock(&desc->iuspin); if (rv < 0) { + clear_bit(WDM_RESPONDING, &desc->flags); if (rv == -EPERM) return; if (rv == -ENOMEM) { @@ -795,7 +800,8 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) mutex_lock(&desc->lock); #ifdef CONFIG_PM if ((message.event & PM_EVENT_AUTO) && - test_bit(WDM_IN_USE, &desc->flags)) { + (test_bit(WDM_IN_USE, &desc->flags) + || test_bit(WDM_RESPONDING, &desc->flags))) { rv = -EBUSY; } else { #endif -- cgit v1.2.2 From d855fe2e9c19edaa47baba0e7f95e17f7a24dba8 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sat, 27 Feb 2010 20:55:26 +0100 Subject: usb: cdc-wdm: Fix race between disconnect and debug messages dev_dbg() and dev_err() cannot be used to report failures that may have been caused by a device's removal Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 940b17af162c..72e2eb030459 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -435,11 +435,8 @@ retry: spin_lock_irq(&desc->iuspin); if (desc->rerr) { /* read completed, error happened */ - int t = desc->rerr; desc->rerr = 0; spin_unlock_irq(&desc->iuspin); - dev_err(&desc->intf->dev, - "reading had resulted in %d\n", t); rv = -EIO; goto err; } @@ -477,8 +474,6 @@ retry: err: mutex_unlock(&desc->lock); - if (rv < 0 && rv != -EAGAIN) - dev_err(&desc->intf->dev, "wdm_read: exit error\n"); return rv; } -- cgit v1.2.2 From beb1d35f1690fe27694472a010a8e4a9ae11cc50 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sat, 27 Feb 2010 20:55:52 +0100 Subject: usb: cdc-wdm: Fix submission of URB after suspension There's a window under which cdc-wdm may submit an URB to a device about to be suspended. This introduces a flag to prevent it. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 72e2eb030459..a6b5e9fd0714 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -53,7 +53,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); #define WDM_INT_STALL 5 #define WDM_POLL_RUNNING 6 #define WDM_RESPONDING 7 - +#define WDM_SUSPENDING 8 #define WDM_MAX 16 @@ -231,7 +231,8 @@ static void wdm_int_callback(struct urb *urb) spin_lock(&desc->iuspin); clear_bit(WDM_READ, &desc->flags); set_bit(WDM_RESPONDING, &desc->flags); - if (!test_bit(WDM_DISCONNECTING, &desc->flags)) { + if (!test_bit(WDM_DISCONNECTING, &desc->flags) + && !test_bit(WDM_SUSPENDING, &desc->flags)) { rv = usb_submit_urb(desc->response, GFP_ATOMIC); dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", __func__, rv); @@ -800,6 +801,7 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) rv = -EBUSY; } else { #endif + set_bit(WDM_SUSPENDING, &desc->flags); cancel_work_sync(&desc->rxwork); kill_urbs(desc); #ifdef CONFIG_PM @@ -830,6 +832,7 @@ static int wdm_resume(struct usb_interface *intf) dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); mutex_lock(&desc->lock); rv = recover_from_urb_loss(desc); + clear_bit(WDM_SUSPENDING, &desc->flags); mutex_unlock(&desc->lock); return rv; } -- cgit v1.2.2 From 62e6685470fb04fb7688ecef96c39160498721d5 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sat, 27 Feb 2010 20:56:22 +0100 Subject: usb: cdc-wdm:Fix loss of data due to autosuspend The guarding flag must be set and tested under spinlock and cleared before the URBs are resubmitted in resume. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index a6b5e9fd0714..07c12974fe14 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -794,14 +794,17 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); mutex_lock(&desc->lock); + spin_lock_irq(&desc->iuspin); #ifdef CONFIG_PM if ((message.event & PM_EVENT_AUTO) && (test_bit(WDM_IN_USE, &desc->flags) || test_bit(WDM_RESPONDING, &desc->flags))) { + spin_unlock_irq(&desc->iuspin); rv = -EBUSY; } else { #endif set_bit(WDM_SUSPENDING, &desc->flags); + spin_unlock_irq(&desc->iuspin); cancel_work_sync(&desc->rxwork); kill_urbs(desc); #ifdef CONFIG_PM @@ -831,8 +834,8 @@ static int wdm_resume(struct usb_interface *intf) dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); mutex_lock(&desc->lock); - rv = recover_from_urb_loss(desc); clear_bit(WDM_SUSPENDING, &desc->flags); + rv = recover_from_urb_loss(desc); mutex_unlock(&desc->lock); return rv; } -- cgit v1.2.2 From d93d16e9aa58887feadd999ea26b7b8139e98b56 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sat, 27 Feb 2010 20:56:47 +0100 Subject: usb: cdc-wdm: Fix order in disconnect and fix locking - as the callback can schedule work, URBs must be killed first - if the driver causes an autoresume, the caller must handle locking Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 07c12974fe14..b57490508860 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -776,9 +776,9 @@ static void wdm_disconnect(struct usb_interface *intf) /* to terminate pending flushes */ clear_bit(WDM_IN_USE, &desc->flags); spin_unlock_irqrestore(&desc->iuspin, flags); - cancel_work_sync(&desc->rxwork); mutex_lock(&desc->lock); kill_urbs(desc); + cancel_work_sync(&desc->rxwork); mutex_unlock(&desc->lock); wake_up_all(&desc->wait); if (!desc->count) @@ -786,6 +786,7 @@ static void wdm_disconnect(struct usb_interface *intf) mutex_unlock(&wdm_mutex); } +#ifdef CONFIG_PM static int wdm_suspend(struct usb_interface *intf, pm_message_t message) { struct wdm_device *desc = usb_get_intfdata(intf); @@ -793,27 +794,30 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); - mutex_lock(&desc->lock); + /* if this is an autosuspend the caller does the locking */ + if (!(message.event & PM_EVENT_AUTO)) + mutex_lock(&desc->lock); spin_lock_irq(&desc->iuspin); -#ifdef CONFIG_PM + if ((message.event & PM_EVENT_AUTO) && (test_bit(WDM_IN_USE, &desc->flags) || test_bit(WDM_RESPONDING, &desc->flags))) { spin_unlock_irq(&desc->iuspin); rv = -EBUSY; } else { -#endif + set_bit(WDM_SUSPENDING, &desc->flags); spin_unlock_irq(&desc->iuspin); - cancel_work_sync(&desc->rxwork); + /* callback submits work - order is essential */ kill_urbs(desc); -#ifdef CONFIG_PM + cancel_work_sync(&desc->rxwork); } -#endif - mutex_unlock(&desc->lock); + if (!(message.event & PM_EVENT_AUTO)) + mutex_unlock(&desc->lock); return rv; } +#endif static int recover_from_urb_loss(struct wdm_device *desc) { @@ -827,6 +831,8 @@ static int recover_from_urb_loss(struct wdm_device *desc) } return rv; } + +#ifdef CONFIG_PM static int wdm_resume(struct usb_interface *intf) { struct wdm_device *desc = usb_get_intfdata(intf); @@ -839,6 +845,7 @@ static int wdm_resume(struct usb_interface *intf) mutex_unlock(&desc->lock); return rv; } +#endif static int wdm_pre_reset(struct usb_interface *intf) { @@ -862,9 +869,11 @@ static struct usb_driver wdm_driver = { .name = "cdc_wdm", .probe = wdm_probe, .disconnect = wdm_disconnect, +#ifdef CONFIG_PM .suspend = wdm_suspend, .resume = wdm_resume, .reset_resume = wdm_resume, +#endif .pre_reset = wdm_pre_reset, .post_reset = wdm_post_reset, .id_table = wdm_ids, -- cgit v1.2.2 From 338124c1f18c2c737656ac58735f040d90b23d8c Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sat, 27 Feb 2010 20:57:12 +0100 Subject: usb: cdc-wdm: Fix deadlock between write and resume The new runtime PM scheme allows resume() to have no locks. This fixes the deadlock. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index b57490508860..189141ca4e05 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -839,10 +839,10 @@ static int wdm_resume(struct usb_interface *intf) int rv; dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); - mutex_lock(&desc->lock); + clear_bit(WDM_SUSPENDING, &desc->flags); rv = recover_from_urb_loss(desc); - mutex_unlock(&desc->lock); + return rv; } #endif -- cgit v1.2.2 From 510607db7e2ad5078c554911418a71b469886076 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Wed, 3 Mar 2010 19:37:12 +0100 Subject: USB: serial: Fix module name typo for qcaux Kconfig entry. The module is called qcaux and not moto_modem. Also use help instead of ---help-- to be in sync with the other Kconfig entries. Signed-off-by: Stefan Schmidt Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index c78b255e3f83..a0ecb42cb33a 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -474,14 +474,14 @@ config USB_SERIAL_OTI6858 config USB_SERIAL_QCAUX tristate "USB Qualcomm Auxiliary Serial Port Driver" - ---help--- + help Say Y here if you want to use the auxiliary serial ports provided by many modems based on Qualcomm chipsets. These ports often use a proprietary protocol called DM and cannot be used for AT- or PPP-based communication. To compile this driver as a module, choose M here: the - module will be called moto_modem. If unsure, choose N. + module will be called qcaux. If unsure, choose N. config USB_SERIAL_QUALCOMM tristate "USB Qualcomm Serial modem" -- cgit v1.2.2 From 33c387529b7931248c6637bf9720ac7504a0b28b Mon Sep 17 00:00:00 2001 From: spark Date: Fri, 5 Mar 2010 14:18:05 +0800 Subject: USB: option.c: Add Pirelli VID/PID and indicate Pirelli's modem interface is 0xff Signed-off-by: spark Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 3af1eb8aa635..950cb311ca94 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -335,6 +335,24 @@ static int option_resume(struct usb_serial *serial); #define ALCATEL_VENDOR_ID 0x1bbb #define ALCATEL_PRODUCT_X060S 0x0000 +#define PIRELLI_VENDOR_ID 0x1266 +#define PIRELLI_PRODUCT_C100_1 0x1002 +#define PIRELLI_PRODUCT_C100_2 0x1003 +#define PIRELLI_PRODUCT_1004 0x1004 +#define PIRELLI_PRODUCT_1005 0x1005 +#define PIRELLI_PRODUCT_1006 0x1006 +#define PIRELLI_PRODUCT_1007 0x1007 +#define PIRELLI_PRODUCT_1008 0x1008 +#define PIRELLI_PRODUCT_1009 0x1009 +#define PIRELLI_PRODUCT_100A 0x100a +#define PIRELLI_PRODUCT_100B 0x100b +#define PIRELLI_PRODUCT_100C 0x100c +#define PIRELLI_PRODUCT_100D 0x100d +#define PIRELLI_PRODUCT_100E 0x100e +#define PIRELLI_PRODUCT_100F 0x100f +#define PIRELLI_PRODUCT_1011 0x1011 +#define PIRELLI_PRODUCT_1012 0x1012 + /* Airplus products */ #define AIRPLUS_VENDOR_ID 0x1011 #define AIRPLUS_PRODUCT_MCD650 0x3198 @@ -679,6 +697,24 @@ static const struct usb_device_id option_ids[] = { .driver_info = (kernel_ulong_t)&four_g_w14_blacklist }, { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, + /* Pirelli */ + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_1)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_2)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1004)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1005)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1006)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1007)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1008)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1009)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100A)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100B) }, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100C) }, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100D) }, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100E) }, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) }, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, + { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); @@ -802,12 +838,19 @@ static int option_probe(struct usb_serial *serial, const struct usb_device_id *id) { struct option_intf_private *data; + /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8) return -ENODEV; + /* Bandrich modem and AT command interface is 0xff */ + if ((serial->dev->descriptor.idVendor == BANDRICH_VENDOR_ID || + serial->dev->descriptor.idVendor == PIRELLI_VENDOR_ID) && + serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff) + return -ENODEV; + data = serial->private = kzalloc(sizeof(struct option_intf_private), GFP_KERNEL); if (!data) return -ENOMEM; -- cgit v1.2.2 From 872f8b42544c58dfa241956d220ada115a8e93c7 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 6 Mar 2010 14:08:56 +0300 Subject: USB: goku_udc: remove potential null dereference "dev" is always null here. In the end it's only used to get the pci_name() of "pdev" which is redundant information and so I removed it. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/goku_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index e8edc640381e..1088d08c7ed8 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c @@ -1768,7 +1768,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) * usb_gadget_driver_{register,unregister}() must change. */ if (the_controller) { - WARNING(dev, "ignoring %s\n", pci_name(pdev)); + pr_warning("ignoring %s\n", pci_name(pdev)); return -EBUSY; } if (!pdev->irq) { -- cgit v1.2.2 From f2984a333fb5e325d478950c9d8af3693869e69c Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 9 Mar 2010 00:35:22 -0500 Subject: USB: gadget: fix Blackfin builds after gadget cleansing The recent change to clean out dead gadget drivers (90f7976880bbbf99) missed the call to gadget_is_musbhsfc() behind CONFIG_BLACKFIN. This causes Blackfin gadget builds to fail since the function no longer exists anywhere. Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/epautoconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 65a5f94cbc04..3568de210f79 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -266,7 +266,7 @@ struct usb_ep * __init usb_ep_autoconfig ( } #ifdef CONFIG_BLACKFIN - } else if (gadget_is_musbhsfc(gadget) || gadget_is_musbhdrc(gadget)) { + } else if (gadget_is_musbhdrc(gadget)) { if ((USB_ENDPOINT_XFER_BULK == type) || (USB_ENDPOINT_XFER_ISOC == type)) { if (USB_DIR_IN & desc->bEndpointAddress) -- cgit v1.2.2 From f88f6691b73a35b0c6dcabb9e587aa4c63d09010 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 7 Mar 2010 10:36:27 -0500 Subject: USB: g_mass_storage: fix section mismatch warnings The recent commit (0e530b45783f75) that moved usb_ep_autoconfig from the __devinit section to the __init section missed the mass storage device. Its fsg_bind() function uses the usb_ep_autoconfig() function from non __init context leading to: WARNING: drivers/usb/gadget/g_mass_storage.o(.text): Section mismatch in reference from the function _fsg_bind() to the function .init.text:_usb_ep_autoconfig() So move fsg_bind() into __init as well. Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/f_mass_storage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 5a3cdd08f1d0..db08de2af182 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2910,7 +2910,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) } -static int fsg_bind(struct usb_configuration *c, struct usb_function *f) +static int __init fsg_bind(struct usb_configuration *c, struct usb_function *f) { struct fsg_dev *fsg = fsg_from_func(f); struct usb_gadget *gadget = c->cdev->gadget; -- cgit v1.2.2 From f479d70b4f7674083c2e3c3e603b15811713fb18 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Fri, 12 Mar 2010 15:55:28 +0100 Subject: USB: gadget: f_mass_storage::fsg_bind(): fix error handling Contrary to the comment in fsg_add, fsg_bind calls fsg_unbind on errors, which decreases refcount and frees the fsg_dev structure, causing trouble when fsg_add does the same. Fix it by simply leaving up cleanup to fsg_add(). Signed-off-by: Peter Korsgaard Acked-by: Michal Nazarewicz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/f_mass_storage.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index db08de2af182..f4911c09022e 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2954,7 +2954,6 @@ static int __init fsg_bind(struct usb_configuration *c, struct usb_function *f) autoconf_fail: ERROR(fsg, "unable to autoconfigure all endpoints\n"); rc = -ENOTSUPP; - fsg_unbind(c, f); return rc; } -- cgit v1.2.2 From 11b10d999469dc0514447a15e88c7ef14ec0761d Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Mon, 15 Mar 2010 11:10:23 +0100 Subject: USB: g_mass_storage: fixed module name in Kconfig The Kconfig help message for Mass Storage Gadget claimed the module will be named "g_file_storage" whereas it should be "g_mass_storage". Signed-off-by: Michal Nazarewicz Cc: Kyungmin Park Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 7460cd797f45..11a3e0fa4331 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -747,7 +747,7 @@ config USB_MASS_STORAGE which may be used with composite framework. Say "y" to link the driver statically, or "m" to build - a dynamically linked module called "g_file_storage". If unsure, + a dynamically linked module called "g_mass_storage". If unsure, consider File-backed Storage Gadget. config USB_G_SERIAL -- cgit v1.2.2 From 9c67d28e4e7683b4f667fa4c7b6f9aee92b44b5c Mon Sep 17 00:00:00 2001 From: Alessio Igor Bogani Date: Sat, 13 Mar 2010 18:35:14 +0100 Subject: USB: ftdi_sio: Fix locking for change_speed() function The change_speed() function should be serialized against multiple calls. Use the cfg_lock mutex to do this. Signed-off-by: Alessio Igor Bogani Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 6fc09dc3b53e..1d7c4fac02e8 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -91,7 +91,7 @@ struct ftdi_private { unsigned long tx_outstanding_bytes; unsigned long tx_outstanding_urbs; unsigned short max_packet_size; - struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() */ + struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() and change_speed() */ }; /* struct ftdi_sio_quirk is used by devices requiring special attention. */ @@ -1273,8 +1273,8 @@ check_and_exit: (priv->flags & ASYNC_SPD_MASK)) || (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) && (old_priv.custom_divisor != priv->custom_divisor))) { - mutex_unlock(&priv->cfg_lock); change_speed(tty, port); + mutex_unlock(&priv->cfg_lock); } else mutex_unlock(&priv->cfg_lock); @@ -2265,9 +2265,11 @@ static void ftdi_set_termios(struct tty_struct *tty, clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); } else { /* set the baudrate determined before */ + mutex_lock(&priv->cfg_lock); if (change_speed(tty, port)) dev_err(&port->dev, "%s urb failed to set baudrate\n", __func__); + mutex_unlock(&priv->cfg_lock); /* Ensure RTS and DTR are raised when baudrate changed from 0 */ if (!old_termios || (old_termios->c_cflag & CBAUD) == B0) set_mctrl(port, TIOCM_DTR | TIOCM_RTS); -- cgit v1.2.2 From 83ba11d93434e6f0cc2e060336b0b19a3f687fa3 Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Mon, 8 Mar 2010 18:20:59 +0100 Subject: USB: gadget: add gadget controller number for s3c-hsotg driver This prevents some drivers from complaining that no bcdDevice id was set. Signed-off-by: Maurus Cuelenaere Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/gadget_chips.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index 1edbc12fff18..e511fec9f26d 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h @@ -136,6 +136,12 @@ #define gadget_is_r8a66597(g) 0 #endif +#ifdef CONFIG_USB_S3C_HSOTG +#define gadget_is_s3c_hsotg(g) (!strcmp("s3c-hsotg", (g)->name)) +#else +#define gadget_is_s3c_hsotg(g) 0 +#endif + /** * usb_gadget_controller_number - support bcdDevice id convention @@ -192,6 +198,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) return 0x24; else if (gadget_is_r8a66597(gadget)) return 0x25; + else if (gadget_is_s3c_hsotg(gadget)) + return 0x26; return -ENOENT; } -- cgit v1.2.2 From 7f56cfd253d929c06ce4ed5bfb99a8c6805075c9 Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Wed, 10 Mar 2010 12:33:11 +0100 Subject: USB: Remove last bit of CONFIG_USB_BERRY_CHARGE One last bit was missed while removing the USB_BERRY_CHARGE config option in a8d4211f33a9573f7b1bdcfd9c9c48631d1515ee which gets dropped by this patch. Signed-off-by: Christoph Egger Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 61c8b9df96e6..ccf1dbbb87ef 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1389,20 +1389,6 @@ UNUSUAL_DEV( 0x0f19, 0x0105, 0x0100, 0x0100, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE ), -/* Jeremy Katz : - * The Blackberry Pearl can run in two modes; a usb-storage only mode - * and a mode that allows access via mass storage and to its database. - * The berry_charge module will set the device to dual mode and thus we - * should ignore its native mode if that module is built - */ -#ifdef CONFIG_USB_BERRY_CHARGE -UNUSUAL_DEV( 0x0fca, 0x0006, 0x0001, 0x0001, - "RIM", - "Blackberry Pearl", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_IGNORE_DEVICE ), -#endif - /* Reported by Michael Stattmann */ UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, "Sony Ericsson", -- cgit v1.2.2 From e549a17f698e266373f6757bd068d1e98397b4c0 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Wed, 10 Mar 2010 23:26:37 +0100 Subject: USB: cp210x: Remove double usb_control_msg from cp210x_set_config This patch removes a double usb_control_msg that sets the cp210x configuration registers a second time when calling cp210x_set_config. For data sizes >2 the second write gets corrupted. The patch has been created against 2.6.34-rc1, but all cp210x driver revisions are affected. Signed-off-by: Michael Brunner Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 507382b0a9ed..ec9b0449ccf6 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -313,11 +313,6 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, return -EPROTO; } - /* Single data value */ - result = usb_control_msg(serial->dev, - usb_sndctrlpipe(serial->dev, 0), - request, REQTYPE_HOST_TO_DEVICE, data[0], - 0, NULL, 0, 300); return 0; } -- cgit v1.2.2 From f09a15e6e69884cedec4d1c022089a973aa01f1e Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 16 Mar 2010 12:55:44 -0700 Subject: USB: Fix usb_fill_int_urb for SuperSpeed devices USB 3 and Wireless USB specify a logarithmic encoding of the endpoint interval that matches the USB 2 specification. usb_fill_int_urb() didn't know that and was filling in the interval as if it was USB 1.1. Fix usb_fill_int_urb() for SuperSpeed devices, but leave the wireless case alone, because David Vrabel wants to keep the old encoding. Update the struct urb kernel doc to note that SuperSpeed URBs must have urb->interval specified in microframes. Add a missing break statement in the usb_submit_urb() interrupt URB checking, since wireless USB and SuperSpeed USB encode urb->interval differently. This allows xHCI roothubs to actually register with khubd. Signed-off-by: Matthew Wilcox Signed-off-by: Sarah Sharp Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/urb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/usb') diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 27080561a1c2..45a32dadb406 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -453,6 +453,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) if (urb->interval > (1 << 15)) return -EINVAL; max = 1 << 15; + break; case USB_SPEED_WIRELESS: if (urb->interval > 16) return -EINVAL; -- cgit v1.2.2 From 9ce669a8924c61b7321d6e2f27ed67bcd46c1fbb Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Tue, 16 Mar 2010 12:59:24 -0700 Subject: USB: xhci: Make endpoint interval debugging clearer. The xHCI hardware can only handle polling intervals that are a power of two. When we add a new endpoint during a bandwidth allocation, and the polling interval is rounded down to a power of two, print the original polling interval in the endpoint descriptor. Signed-off-by: Sarah Sharp Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mem.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 49f7d72f8b1b..bba9b19ed1b9 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -566,8 +566,13 @@ static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev, if (interval < 3) interval = 3; if ((1 << interval) != 8*ep->desc.bInterval) - dev_warn(&udev->dev, "ep %#x - rounding interval to %d microframes\n", - ep->desc.bEndpointAddress, 1 << interval); + dev_warn(&udev->dev, + "ep %#x - rounding interval" + " to %d microframes, " + "ep desc says %d microframes\n", + ep->desc.bEndpointAddress, + 1 << interval, + 8*ep->desc.bInterval); } break; default: -- cgit v1.2.2 From d835933436ac0d1e8f5b35fe809fd4e767e55d6e Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 16 Mar 2010 12:29:35 +0900 Subject: usb: r8a66597-hcd: fix removed from an attached hub fix the problem that when a USB hub is attached to the r8a66597-hcd and a device is removed from that hub, it's likely that a kernel panic follows. Reported-by: Markus Pietrek Signed-off-by: Yoshihiro Shimoda Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/r8a66597-hcd.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index bee558aed427..f71a73a93d0c 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -418,7 +418,7 @@ static u8 alloc_usb_address(struct r8a66597 *r8a66597, struct urb *urb) /* this function must be called with interrupt disabled */ static void free_usb_address(struct r8a66597 *r8a66597, - struct r8a66597_device *dev) + struct r8a66597_device *dev, int reset) { int port; @@ -430,7 +430,13 @@ static void free_usb_address(struct r8a66597 *r8a66597, dev->state = USB_STATE_DEFAULT; r8a66597->address_map &= ~(1 << dev->address); dev->address = 0; - dev_set_drvdata(&dev->udev->dev, NULL); + /* + * Only when resetting USB, it is necessary to erase drvdata. When + * a usb device with usb hub is disconnect, "dev->udev" is already + * freed on usb_desconnect(). So we cannot access the data. + */ + if (reset) + dev_set_drvdata(&dev->udev->dev, NULL); list_del(&dev->device_list); kfree(dev); @@ -1069,7 +1075,7 @@ static void r8a66597_usb_disconnect(struct r8a66597 *r8a66597, int port) struct r8a66597_device *dev = r8a66597->root_hub[port].dev; disable_r8a66597_pipe_all(r8a66597, dev); - free_usb_address(r8a66597, dev); + free_usb_address(r8a66597, dev, 0); start_root_hub_sampling(r8a66597, port, 0); } @@ -2085,7 +2091,7 @@ static void update_usb_address_map(struct r8a66597 *r8a66597, spin_lock_irqsave(&r8a66597->lock, flags); dev = get_r8a66597_device(r8a66597, addr); disable_r8a66597_pipe_all(r8a66597, dev); - free_usb_address(r8a66597, dev); + free_usb_address(r8a66597, dev, 0); put_child_connect_map(r8a66597, addr); spin_unlock_irqrestore(&r8a66597->lock, flags); } @@ -2228,7 +2234,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, rh->port |= (1 << USB_PORT_FEAT_RESET); disable_r8a66597_pipe_all(r8a66597, dev); - free_usb_address(r8a66597, dev); + free_usb_address(r8a66597, dev, 1); r8a66597_mdfy(r8a66597, USBRST, USBRST | UACT, get_dvstctr_reg(port)); -- cgit v1.2.2 From 4cb80cda51ff950614701fb30c9d4e583fe5a31f Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Fri, 12 Mar 2010 12:33:15 +0100 Subject: USB: gadget/multi: cdc_do_config: remove redundant check cdc_do_config() had a double ret check after fsg_add(). Signed-off-by: Peter Korsgaard Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/multi.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 76496f5d272c..a930d7fd7e7a 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -211,8 +211,6 @@ static int __init cdc_do_config(struct usb_configuration *c) ret = fsg_add(c->cdev, c, fsg_common); if (ret < 0) return ret; - if (ret < 0) - return ret; return 0; } -- cgit v1.2.2 From 72f878cc6f324ecc2ca00ff2f9c0dc2c168cd4cc Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Thu, 25 Mar 2010 18:22:40 +0100 Subject: USB gadget r8a66597-udc.c: duplicated include drivers/usb/gadget/r8a66597-udc.c: linux/err.h is included more than once. Signed-off-by: Andrea Gelmini Signed-off-by: Paul Mundt --- drivers/usb/gadget/r8a66597-udc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 5e13d23b5f0c..8b45145b9136 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.2 From c6c352371c1ce486a62f4eb92e545b05cfcef76b Mon Sep 17 00:00:00 2001 From: Harro Haan Date: Mon, 1 Mar 2010 17:38:37 +0100 Subject: ARM: 5965/1: Fix soft lockup in at91 udc driver Fix a potential soft lockup in the AT91 UDC driver by ensuring that the UDC clock is enabled inside the interrupt handler. If the UDC clock is not enabled then the UDC registers cannot be written to and the interrupt cannot be cleared or masked. Note that this patch (and other parts of the existing AT91 UDC driver) is potentially racy for preempt-rt kernels, but is okay for mainline. For more info see: http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20100203/09cdb3b4/attachment.el http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20100203/8443a1e4/attachment.el Signed-off-by: Ryan Mallon Acked-by: Harro Haan Tested-by: Remy Bohmer Acked-by: Andrew Victor Cc: David Brownell Signed-off-by: Russell King --- drivers/usb/gadget/at91_udc.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 12ac9cd32a07..df1bae9b048e 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -1370,6 +1370,12 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc) { struct at91_udc *udc = _udc; u32 rescans = 5; + int disable_clock = 0; + + if (!udc->clocked) { + clk_on(udc); + disable_clock = 1; + } while (rescans--) { u32 status; @@ -1458,6 +1464,9 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc) } } + if (disable_clock) + clk_off(udc); + return IRQ_HANDLED; } -- cgit v1.2.2 From 5a0e3ad6af8660be21ca98a971cd00f331318c05 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 24 Mar 2010 17:04:11 +0900 Subject: include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h percpu.h is included by sched.h and module.h and thus ends up being included when building most .c files. percpu.h includes slab.h which in turn includes gfp.h making everything defined by the two files universally available and complicating inclusion dependencies. percpu.h -> slab.h dependency is about to be removed. Prepare for this change by updating users of gfp and slab facilities include those headers directly instead of assuming availability. As this conversion needs to touch large number of source files, the following script is used as the basis of conversion. http://userweb.kernel.org/~tj/misc/slabh-sweep.py The script does the followings. * Scan files for gfp and slab usages and update includes such that only the necessary includes are there. ie. if only gfp is used, gfp.h, if slab is used, slab.h. * When the script inserts a new include, it looks at the include blocks and try to put the new include such that its order conforms to its surrounding. It's put in the include block which contains core kernel includes, in the same order that the rest are ordered - alphabetical, Christmas tree, rev-Xmas-tree or at the end if there doesn't seem to be any matching order. * If the script can't find a place to put a new include (mostly because the file doesn't have fitting include block), it prints out an error message indicating which .h file needs to be added to the file. The conversion was done in the following steps. 1. The initial automatic conversion of all .c files updated slightly over 4000 files, deleting around 700 includes and adding ~480 gfp.h and ~3000 slab.h inclusions. The script emitted errors for ~400 files. 2. Each error was manually checked. Some didn't need the inclusion, some needed manual addition while adding it to implementation .h or embedding .c file was more appropriate for others. This step added inclusions to around 150 files. 3. The script was run again and the output was compared to the edits from #2 to make sure no file was left behind. 4. Several build tests were done and a couple of problems were fixed. e.g. lib/decompress_*.c used malloc/free() wrappers around slab APIs requiring slab.h to be added manually. 5. The script was run on all .h files but without automatically editing them as sprinkling gfp.h and slab.h inclusions around .h files could easily lead to inclusion dependency hell. Most gfp.h inclusion directives were ignored as stuff from gfp.h was usually wildly available and often used in preprocessor macros. Each slab.h inclusion directive was examined and added manually as necessary. 6. percpu.h was updated not to include slab.h. 7. Build test were done on the following configurations and failures were fixed. CONFIG_GCOV_KERNEL was turned off for all tests (as my distributed build env didn't work with gcov compiles) and a few more options had to be turned off depending on archs to make things build (like ipr on powerpc/64 which failed due to missing writeq). * x86 and x86_64 UP and SMP allmodconfig and a custom test config. * powerpc and powerpc64 SMP allmodconfig * sparc and sparc64 SMP allmodconfig * ia64 SMP allmodconfig * s390 SMP allmodconfig * alpha SMP allmodconfig * um on x86_64 SMP allmodconfig 8. percpu.h modifications were reverted so that it could be applied as a separate patch and serve as bisection point. Given the fact that I had only a couple of failures from tests on step 6, I'm fairly confident about the coverage of this conversion patch. If there is a breakage, it's likely to be something in one of the arch headers which should be easily discoverable easily on most builds of the specific arch. Signed-off-by: Tejun Heo Guess-its-ok-by: Christoph Lameter Cc: Ingo Molnar Cc: Lee Schermerhorn --- drivers/usb/atm/speedtch.c | 1 - drivers/usb/atm/ueagle-atm.c | 1 + drivers/usb/c67x00/c67x00-drv.c | 1 + drivers/usb/c67x00/c67x00-sched.c | 1 + drivers/usb/class/usbtmc.c | 1 + drivers/usb/core/devices.c | 2 +- drivers/usb/core/driver.c | 1 + drivers/usb/core/endpoint.c | 1 + drivers/usb/core/file.c | 1 + drivers/usb/gadget/atmel_usba_udc.c | 1 + drivers/usb/gadget/ci13xxx_udc.c | 1 + drivers/usb/gadget/config.c | 1 + drivers/usb/gadget/f_acm.c | 1 + drivers/usb/gadget/f_audio.c | 1 + drivers/usb/gadget/f_ecm.c | 1 + drivers/usb/gadget/f_eem.c | 1 + drivers/usb/gadget/f_loopback.c | 1 + drivers/usb/gadget/f_obex.c | 1 + drivers/usb/gadget/f_phonet.c | 1 + drivers/usb/gadget/f_rndis.c | 1 + drivers/usb/gadget/f_serial.c | 1 + drivers/usb/gadget/f_sourcesink.c | 1 + drivers/usb/gadget/f_subset.c | 1 + drivers/usb/gadget/gmidi.c | 1 + drivers/usb/gadget/imx_udc.c | 1 + drivers/usb/gadget/lh7a40x_udc.c | 1 + drivers/usb/gadget/m66592-udc.c | 1 + drivers/usb/gadget/pxa27x_udc.c | 1 + drivers/usb/gadget/r8a66597-udc.c | 1 + drivers/usb/gadget/rndis.c | 1 + drivers/usb/gadget/s3c-hsotg.c | 1 + drivers/usb/gadget/u_audio.c | 1 + drivers/usb/gadget/u_ether.c | 1 + drivers/usb/gadget/u_serial.c | 1 + drivers/usb/gadget/zero.c | 1 + drivers/usb/host/ehci-hcd.c | 2 +- drivers/usb/host/ehci-mxc.c | 1 + drivers/usb/host/ehci-omap.c | 1 + drivers/usb/host/fhci-hcd.c | 1 + drivers/usb/host/fhci-mem.c | 1 + drivers/usb/host/fhci-q.c | 1 + drivers/usb/host/fhci-tds.c | 1 + drivers/usb/host/hwa-hc.c | 1 + drivers/usb/host/imx21-hcd.c | 1 + drivers/usb/host/isp116x-hcd.c | 1 + drivers/usb/host/ohci-q.c | 1 + drivers/usb/host/r8a66597-hcd.c | 1 + drivers/usb/host/uhci-debug.c | 1 + drivers/usb/host/whci/asl.c | 1 + drivers/usb/host/whci/debug.c | 1 + drivers/usb/host/whci/init.c | 1 + drivers/usb/host/whci/pzl.c | 1 + drivers/usb/host/whci/qset.c | 1 + drivers/usb/host/xhci-mem.c | 1 + drivers/usb/host/xhci-ring.c | 1 + drivers/usb/host/xhci.c | 1 + drivers/usb/misc/appledisplay.c | 1 + drivers/usb/misc/cypress_cy7c63.c | 1 + drivers/usb/misc/cytherm.c | 1 + drivers/usb/misc/isight_firmware.c | 1 + drivers/usb/misc/sisusbvga/sisusb_con.c | 1 - drivers/usb/misc/sisusbvga/sisusb_init.c | 1 - drivers/usb/misc/trancevibrator.c | 1 + drivers/usb/misc/uss720.c | 1 + drivers/usb/mon/mon_bin.c | 1 + drivers/usb/mon/mon_main.c | 1 + drivers/usb/mon/mon_stat.c | 1 + drivers/usb/mon/mon_text.c | 1 + drivers/usb/musb/blackfin.c | 1 - drivers/usb/musb/cppi_dma.c | 1 + drivers/usb/musb/davinci.c | 1 - drivers/usb/musb/musb_gadget.c | 1 + drivers/usb/musb/musb_virthub.c | 1 - drivers/usb/musb/musbhsdma.c | 1 + drivers/usb/musb/omap2430.c | 1 - drivers/usb/musb/tusb6010_omap.c | 1 + drivers/usb/otg/gpio_vbus.c | 1 + drivers/usb/otg/nop-usb-xceiv.c | 1 + drivers/usb/otg/twl4030-usb.c | 1 + drivers/usb/otg/ulpi.c | 1 + drivers/usb/serial/aircable.c | 1 + drivers/usb/serial/ark3116.c | 1 + drivers/usb/serial/bus.c | 1 + drivers/usb/serial/ch341.c | 1 + drivers/usb/serial/navman.c | 1 + drivers/usb/serial/opticon.c | 1 + drivers/usb/serial/option.c | 1 + drivers/usb/serial/safe_serial.c | 2 +- drivers/usb/serial/sierra.c | 1 + drivers/usb/serial/symbolserial.c | 1 + drivers/usb/serial/usb_debug.c | 1 + drivers/usb/storage/alauda.c | 1 + drivers/usb/storage/karma.c | 1 + drivers/usb/storage/option_ms.c | 1 + drivers/usb/storage/scsiglue.c | 1 - drivers/usb/storage/sierra_ms.c | 1 + drivers/usb/storage/transport.c | 2 +- drivers/usb/wusbcore/cbaf.c | 1 + drivers/usb/wusbcore/crypto.c | 1 + drivers/usb/wusbcore/devconnect.c | 1 + drivers/usb/wusbcore/mmc.c | 1 + drivers/usb/wusbcore/rh.c | 1 + drivers/usb/wusbcore/security.c | 1 + drivers/usb/wusbcore/wa-hc.c | 1 + drivers/usb/wusbcore/wa-nep.c | 1 + drivers/usb/wusbcore/wa-rpipe.c | 1 + drivers/usb/wusbcore/wa-xfer.c | 1 + 107 files changed, 99 insertions(+), 12 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 3e862401a638..1e9ba4bdffef 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index c5395246886d..25f01b536f67 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -66,6 +66,7 @@ #include #include #include +#include #include diff --git a/drivers/usb/c67x00/c67x00-drv.c b/drivers/usb/c67x00/c67x00-drv.c index 029ee4a8a1f3..b6d49234e521 100644 --- a/drivers/usb/c67x00/c67x00-drv.c +++ b/drivers/usb/c67x00/c67x00-drv.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/c67x00/c67x00-sched.c b/drivers/usb/c67x00/c67x00-sched.c index 85dfe2965661..f6b3c253f3fa 100644 --- a/drivers/usb/c67x00/c67x00-sched.c +++ b/drivers/usb/c67x00/c67x00-sched.c @@ -22,6 +22,7 @@ */ #include +#include #include "c67x00.h" #include "c67x00-hcd.h" diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 8588c0937a89..3e7c1b800ebb 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index d41811bfef2a..19bc03a9fecf 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c @@ -50,7 +50,7 @@ #include #include -#include +#include #include #include #include diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index f3c233806fa3..6a3b5cae3a6e 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -23,6 +23,7 @@ */ #include +#include #include #include #include diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c index d26b9ea981f9..4f84a41ee7a8 100644 --- a/drivers/usb/core/endpoint.c +++ b/drivers/usb/core/endpoint.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include "usb.h" diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index c3536f151f02..f06f5dbc8cdc 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index f79bdfe4bed9..75a256f3d45b 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index c7cb87a6fee2..699695128e33 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c index e1191b9a316a..47e8e722682c 100644 --- a/drivers/usb/gadget/config.c +++ b/drivers/usb/gadget/config.c @@ -19,6 +19,7 @@ */ #include +#include #include #include #include diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index e49c7325dce2..400e1ebe6976 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -14,6 +14,7 @@ /* #define VERBOSE_DEBUG */ +#include #include #include diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c index f1e3aad76c37..43bf44514c41 100644 --- a/drivers/usb/gadget/f_audio.c +++ b/drivers/usb/gadget/f_audio.c @@ -9,6 +9,7 @@ * Licensed under the GPL-2 or later. */ +#include #include #include #include diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c index 2fff530efc19..4e595324c614 100644 --- a/drivers/usb/gadget/f_ecm.c +++ b/drivers/usb/gadget/f_ecm.c @@ -21,6 +21,7 @@ /* #define VERBOSE_DEBUG */ +#include #include #include #include diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c index d4f0db58a8ad..38226e9a371d 100644 --- a/drivers/usb/gadget/f_eem.c +++ b/drivers/usb/gadget/f_eem.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "u_ether.h" diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c index 6cb29d3df575..e91d1b16d9be 100644 --- a/drivers/usb/gadget/f_loopback.c +++ b/drivers/usb/gadget/f_loopback.c @@ -21,6 +21,7 @@ /* #define VERBOSE_DEBUG */ +#include #include #include diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c index b4a3ba654ea5..8f8c64371475 100644 --- a/drivers/usb/gadget/f_obex.c +++ b/drivers/usb/gadget/f_obex.c @@ -23,6 +23,7 @@ /* #define VERBOSE_DEBUG */ +#include #include #include diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c index d2de10b9dc4b..3c6e1a058745 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/f_phonet.c @@ -20,6 +20,7 @@ * 02110-1301 USA */ +#include #include #include diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index a30e60c7f129..56b022150f22 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -24,6 +24,7 @@ /* #define VERBOSE_DEBUG */ +#include #include #include #include diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c index db0aa93606ef..490b00b01a7d 100644 --- a/drivers/usb/gadget/f_serial.c +++ b/drivers/usb/gadget/f_serial.c @@ -10,6 +10,7 @@ * either version 2 of that License or (at your option) any later version. */ +#include #include #include diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c index 09cba273d2db..6d3cc443d914 100644 --- a/drivers/usb/gadget/f_sourcesink.c +++ b/drivers/usb/gadget/f_sourcesink.c @@ -21,6 +21,7 @@ /* #define VERBOSE_DEBUG */ +#include #include #include diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c index a9c98fdb626d..8675ca415329 100644 --- a/drivers/usb/gadget/f_subset.c +++ b/drivers/usb/gadget/f_subset.c @@ -19,6 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include #include #include diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 04f6224b7e06..2b56ce621852 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c @@ -21,6 +21,7 @@ /* #define VERBOSE_DEBUG */ #include +#include #include #include diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c index 01ee0b9bc957..e743122fcd93 100644 --- a/drivers/usb/gadget/imx_udc.c +++ b/drivers/usb/gadget/imx_udc.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index 6cd3d54f5640..fded3fca793b 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c @@ -22,6 +22,7 @@ */ #include +#include #include "lh7a40x_udc.h" diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index a8c8543d1b08..166bf71fd348 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 05b892c3d686..85b0d8921eae 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 5e13d23b5f0c..e848ecb896fd 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 48267bc0b2e0..5c0d06c79a81 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index f742c8e7397c..124a8ccfdcda 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/gadget/u_audio.c b/drivers/usb/gadget/u_audio.c index 35e0930f5bbb..7a86d2c9109c 100644 --- a/drivers/usb/gadget/u_audio.c +++ b/drivers/usb/gadget/u_audio.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 84ca195c2d10..07f4178ad178 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c @@ -23,6 +23,7 @@ /* #define VERBOSE_DEBUG */ #include +#include #include #include #include diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index adf8260c3a6a..16bdf77f582a 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "u_serial.h" diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index fac81ee193dd..807280d069f9 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -50,6 +50,7 @@ /* #define VERBOSE_DEBUG */ #include +#include #include #include diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index dc55a62859c6..207e7a85aeb0 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -35,6 +34,7 @@ #include #include #include +#include #include "../core/hcd.h" diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index 23cd917088b4..ead59f42e69b 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -21,6 +21,7 @@ #include #include #include +#include #include diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index f0282d6bb7aa..a67a0030dd57 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -37,6 +37,7 @@ #include #include #include +#include #include /* diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 5dcfb3de9945..15379c636143 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include "../core/hcd.h" diff --git a/drivers/usb/host/fhci-mem.c b/drivers/usb/host/fhci-mem.c index 2c0736c99712..5591bfb499d1 100644 --- a/drivers/usb/host/fhci-mem.c +++ b/drivers/usb/host/fhci-mem.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include "../core/hcd.h" diff --git a/drivers/usb/host/fhci-q.c b/drivers/usb/host/fhci-q.c index b0a1446ba292..f73c92359beb 100644 --- a/drivers/usb/host/fhci-q.c +++ b/drivers/usb/host/fhci-q.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include "../core/hcd.h" diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c index e1232890c78b..57013479d7f7 100644 --- a/drivers/usb/host/fhci-tds.c +++ b/drivers/usb/host/fhci-tds.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c index 88b03214622b..35742f8c7cda 100644 --- a/drivers/usb/host/hwa-hc.c +++ b/drivers/usb/host/hwa-hc.c @@ -55,6 +55,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index 213e270e1c29..8a12f297645f 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include "../core/hcd.h" diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index a2b305477afe..92de71dc7729 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 35288bcae0db..83094d067e0f 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -8,6 +8,7 @@ */ #include +#include static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv) { diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index f71a73a93d0c..d478ffad59b4 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include "../core/hcd.h" diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index e52b954dda47..98cf0b26b968 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c @@ -9,6 +9,7 @@ * (C) Copyright 1999-2001 Johannes Erdfelt */ +#include #include #include #include diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c index 562eba108816..773249306031 100644 --- a/drivers/usb/host/whci/asl.c +++ b/drivers/usb/host/whci/asl.c @@ -16,6 +16,7 @@ * along with this program. If not, see . */ #include +#include #include #include #include diff --git a/drivers/usb/host/whci/debug.c b/drivers/usb/host/whci/debug.c index 8c1c610c9513..c5305b599ca0 100644 --- a/drivers/usb/host/whci/debug.c +++ b/drivers/usb/host/whci/debug.c @@ -15,6 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ +#include #include #include #include diff --git a/drivers/usb/host/whci/init.c b/drivers/usb/host/whci/init.c index 34a783cb0133..f7582e8e2169 100644 --- a/drivers/usb/host/whci/init.c +++ b/drivers/usb/host/whci/init.c @@ -16,6 +16,7 @@ * along with this program. If not, see . */ #include +#include #include #include diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c index 0db3fb2dc03a..33c5580b4d25 100644 --- a/drivers/usb/host/whci/pzl.c +++ b/drivers/usb/host/whci/pzl.c @@ -16,6 +16,7 @@ * along with this program. If not, see . */ #include +#include #include #include #include diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c index 7d4204db0f61..141d049beb3e 100644 --- a/drivers/usb/host/whci/qset.c +++ b/drivers/usb/host/whci/qset.c @@ -17,6 +17,7 @@ */ #include #include +#include #include #include diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index bba9b19ed1b9..c09539bad1ee 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -22,6 +22,7 @@ #include #include +#include #include #include "xhci.h" diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 6ba841bca4a2..85d7e8f2085e 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -65,6 +65,7 @@ */ #include +#include #include "xhci.h" /* diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 492a61c2c79d..7e4277273908 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "xhci.h" diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index 3adab041355a..094f91cbc578 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/misc/cypress_cy7c63.c b/drivers/usb/misc/cypress_cy7c63.c index 1547d8cac5fb..2f43c57743c9 100644 --- a/drivers/usb/misc/cypress_cy7c63.c +++ b/drivers/usb/misc/cypress_cy7c63.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #define DRIVER_AUTHOR "Oliver Bock (bock@tfh-berlin.de)" diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c index b9cbbbda8245..1d7251bc1b5f 100644 --- a/drivers/usb/misc/cytherm.c +++ b/drivers/usb/misc/cytherm.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/misc/isight_firmware.c b/drivers/usb/misc/isight_firmware.c index 06e990adc6cd..fe1d44319d0a 100644 --- a/drivers/usb/misc/isight_firmware.c +++ b/drivers/usb/misc/isight_firmware.c @@ -25,6 +25,7 @@ #include #include #include +#include static const struct usb_device_id id_table[] = { {USB_DEVICE(0x05ac, 0x8300)}, diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c index b624320df903..b271b0557a1f 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_con.c +++ b/drivers/usb/misc/sisusbvga/sisusb_con.c @@ -58,7 +58,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.c b/drivers/usb/misc/sisusbvga/sisusb_init.c index 0ab990744830..cb8a3d91f970 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_init.c +++ b/drivers/usb/misc/sisusbvga/sisusb_init.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include "sisusb.h" diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c index 5da28eaee314..d77aba46ae85 100644 --- a/drivers/usb/misc/trancevibrator.c +++ b/drivers/usb/misc/trancevibrator.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index f56fed53f2dd..796e2f68f749 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c @@ -49,6 +49,7 @@ #include #include #include +#include /* * Version Information diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index 6dd44bc1f5ff..ddf7f9a1b336 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c @@ -17,6 +17,7 @@ #include #include #include +#include #include diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index e0c2db3b767b..e4af18b93c7d 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/mon/mon_stat.c b/drivers/usb/mon/mon_stat.c index ac8b0d5ce7f8..1becdc3837e6 100644 --- a/drivers/usb/mon/mon_stat.c +++ b/drivers/usb/mon/mon_stat.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index 31c11888ec6a..4d0be130f49b 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index bcee1339d4fd..719a22d664ef 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index 3c69a76ec392..59dc3d351b60 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c @@ -7,6 +7,7 @@ */ #include +#include #include #include "musb_core.h" diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index a883f9dd3f8a..29bce5c0fd10 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index a9f288cd70ed..6fca870e957e 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "musb_core.h" diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index bfe5fe4ebfee..7775e1c0a215 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 2fa7d5c00f31..1008044a3bbc 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "musb_core.h" #include "musbhsdma.h" diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 3fe16867b5a8..490cdf15ccb6 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c index 1c868096bd6f..5afa070d7dc9 100644 --- a/drivers/usb/musb/tusb6010_omap.c +++ b/drivers/usb/musb/tusb6010_omap.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c index 1c26c94513e9..221c44444ec6 100644 --- a/drivers/usb/otg/gpio_vbus.c +++ b/drivers/usb/otg/gpio_vbus.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index af456b48985f..e70014ab0976 100644 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ b/drivers/usb/otg/nop-usb-xceiv.c @@ -30,6 +30,7 @@ #include #include #include +#include struct nop_usb_xceiv { struct otg_transceiver otg; diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 3e4e9f434d78..223cdf46ccb7 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c @@ -37,6 +37,7 @@ #include #include #include +#include /* Register defines */ diff --git a/drivers/usb/otg/ulpi.c b/drivers/usb/otg/ulpi.c index 896527456b7e..9010225e0d06 100644 --- a/drivers/usb/otg/ulpi.c +++ b/drivers/usb/otg/ulpi.c @@ -24,6 +24,7 @@ */ #include +#include #include #include #include diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c index 365db1097bfd..4fd7af98b1ae 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c @@ -43,6 +43,7 @@ */ #include +#include #include #include #include diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 547c9448c28c..9b66bf19f751 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index ba555c528cc6..7f547dc3a590 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 9f4fed1968b5..7e8e39818414 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c index 04a6cbbed2c0..a6b207c84917 100644 --- a/drivers/usb/serial/navman.c +++ b/drivers/usb/serial/navman.c @@ -12,6 +12,7 @@ * flags as the navman is rx only so cannot echo. */ +#include #include #include #include diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 701452ae9197..ed01f3b2de8c 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 950cb311ca94..ca9d866672aa 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 4b463cd140ef..43a0cadd5782 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c @@ -64,8 +64,8 @@ #include #include +#include #include -#include #include #include #include diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 34e6f894cba9..9202f94505e6 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c index ee190cc1757c..d9457bd4fe10 100644 --- a/drivers/usb/serial/symbolserial.c +++ b/drivers/usb/serial/symbolserial.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/serial/usb_debug.c b/drivers/usb/serial/usb_debug.c index 252cc2d993b2..28026b47344a 100644 --- a/drivers/usb/serial/usb_debug.c +++ b/drivers/usb/serial/usb_debug.c @@ -8,6 +8,7 @@ * 2 as published by the Free Software Foundation. */ +#include #include #include #include diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c index 67edc65acb8e..42d0eaed4a01 100644 --- a/drivers/usb/storage/alauda.c +++ b/drivers/usb/storage/alauda.c @@ -32,6 +32,7 @@ */ #include +#include #include #include diff --git a/drivers/usb/storage/karma.c b/drivers/usb/storage/karma.c index 7953d93a7739..ba1b78906880 100644 --- a/drivers/usb/storage/karma.c +++ b/drivers/usb/storage/karma.c @@ -19,6 +19,7 @@ */ #include +#include #include #include diff --git a/drivers/usb/storage/option_ms.c b/drivers/usb/storage/option_ms.c index 773a5cd38c5a..89460181d122 100644 --- a/drivers/usb/storage/option_ms.c +++ b/drivers/usb/storage/option_ms.c @@ -21,6 +21,7 @@ */ #include +#include #include "usb.h" #include "transport.h" diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 4cc035562cc2..d8d98cfecada 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -43,7 +43,6 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include #include diff --git a/drivers/usb/storage/sierra_ms.c b/drivers/usb/storage/sierra_ms.c index 4395c4100ec2..57fc2f532cab 100644 --- a/drivers/usb/storage/sierra_ms.c +++ b/drivers/usb/storage/sierra_ms.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "usb.h" #include "transport.h" diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 468038126e5e..f253edec3bb8 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -44,8 +44,8 @@ */ #include +#include #include -#include #include diff --git a/drivers/usb/wusbcore/cbaf.c b/drivers/usb/wusbcore/cbaf.c index 51a8e0d5789d..c0c5665e60a9 100644 --- a/drivers/usb/wusbcore/cbaf.c +++ b/drivers/usb/wusbcore/cbaf.c @@ -92,6 +92,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/wusbcore/crypto.c b/drivers/usb/wusbcore/crypto.c index 9579cf4c38bf..827c87f10cc5 100644 --- a/drivers/usb/wusbcore/crypto.c +++ b/drivers/usb/wusbcore/crypto.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c index 1c918286159c..46e79d349498 100644 --- a/drivers/usb/wusbcore/devconnect.c +++ b/drivers/usb/wusbcore/devconnect.c @@ -88,6 +88,7 @@ #include #include +#include #include #include "wusbhc.h" diff --git a/drivers/usb/wusbcore/mmc.c b/drivers/usb/wusbcore/mmc.c index 2d827397e30b..0a57ff0a0b0c 100644 --- a/drivers/usb/wusbcore/mmc.c +++ b/drivers/usb/wusbcore/mmc.c @@ -37,6 +37,7 @@ * - add timers that autoremove intervalled IEs? */ #include +#include #include "wusbhc.h" /* Initialize the MMCIEs handling mechanism */ diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c index 9fe4246cecb9..a68ad7aa0b59 100644 --- a/drivers/usb/wusbcore/rh.c +++ b/drivers/usb/wusbcore/rh.c @@ -69,6 +69,7 @@ * * wusbhc_rh_start_port_reset() ??? unimplemented */ +#include #include "wusbhc.h" /* diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c index edcd2d756037..b60799b811c1 100644 --- a/drivers/usb/wusbcore/security.c +++ b/drivers/usb/wusbcore/security.c @@ -23,6 +23,7 @@ * FIXME: docs */ #include +#include #include #include #include "wusbhc.h" diff --git a/drivers/usb/wusbcore/wa-hc.c b/drivers/usb/wusbcore/wa-hc.c index 9d04722415bb..59a748a0e5da 100644 --- a/drivers/usb/wusbcore/wa-hc.c +++ b/drivers/usb/wusbcore/wa-hc.c @@ -22,6 +22,7 @@ * * FIXME: docs */ +#include #include "wusbhc.h" #include "wa-hc.h" diff --git a/drivers/usb/wusbcore/wa-nep.c b/drivers/usb/wusbcore/wa-nep.c index 17d2626038be..f67f7f1e6df9 100644 --- a/drivers/usb/wusbcore/wa-nep.c +++ b/drivers/usb/wusbcore/wa-nep.c @@ -51,6 +51,7 @@ */ #include #include +#include #include "wa-hc.h" #include "wusbhc.h" diff --git a/drivers/usb/wusbcore/wa-rpipe.c b/drivers/usb/wusbcore/wa-rpipe.c index 7369655f69cd..c7b1d8108de9 100644 --- a/drivers/usb/wusbcore/wa-rpipe.c +++ b/drivers/usb/wusbcore/wa-rpipe.c @@ -60,6 +60,7 @@ #include #include #include +#include #include "wusbhc.h" #include "wa-hc.h" diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c index 489b47833e2c..112ef7e26f6b 100644 --- a/drivers/usb/wusbcore/wa-xfer.c +++ b/drivers/usb/wusbcore/wa-xfer.c @@ -81,6 +81,7 @@ */ #include #include +#include #include #include "wa-hc.h" -- cgit v1.2.2