USB fixes for 3.9-rc4

Here are some USB fixes to resolve issues reported recently, as well as a new
 device id for the ftdi_sio driver.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.19 (GNU/Linux)
 
 iEYEABECAAYFAlFUaA0ACgkQMUfUDdst+yk0AACfe9iitBiGERSO4NsyIvypoJ1q
 vOgAoKek8fiPmTKrZl18n79oX28qU9x2
 =Oee3
 -----END PGP SIGNATURE-----

Merge tag 'usb-3.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB fixes from Greg Kroah-Hartman:
 "Here are some USB fixes to resolve issues reported recently, as well
  as a new device id for the ftdi_sio driver."

* tag 'usb-3.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  usb: ftdi_sio: Add support for Mitsubishi FX-USB-AW/-BD
  usb: Fix compile error by selecting USB_OTG_UTILS
  USB: serial: fix hang when opening port
  USB: EHCI: fix bug in iTD/siTD DMA pool allocation
  xhci: Don't warn on empty ring for suspended devices.
  usb: xhci: Fix TRB transfer length macro used for Event TRB.
  usb/acpi: binding xhci root hub usb port with ACPI
  usb: add find_raw_port_number callback to struct hc_driver()
  usb: xhci: fix build warning
This commit is contained in:
Linus Torvalds 2013-03-28 15:54:25 -07:00
commit 0776ce03b1
14 changed files with 101 additions and 55 deletions

View File

@ -2412,6 +2412,14 @@ int usb_hcd_is_primary_hcd(struct usb_hcd *hcd)
} }
EXPORT_SYMBOL_GPL(usb_hcd_is_primary_hcd); EXPORT_SYMBOL_GPL(usb_hcd_is_primary_hcd);
int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1)
{
if (!hcd->driver->find_raw_port_number)
return port1;
return hcd->driver->find_raw_port_number(hcd, port1);
}
static int usb_hcd_request_irqs(struct usb_hcd *hcd, static int usb_hcd_request_irqs(struct usb_hcd *hcd,
unsigned int irqnum, unsigned long irqflags) unsigned int irqnum, unsigned long irqflags)
{ {

View File

@ -15,6 +15,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/usb/hcd.h>
#include <acpi/acpi_bus.h> #include <acpi/acpi_bus.h>
#include "usb.h" #include "usb.h"
@ -188,8 +189,13 @@ static int usb_acpi_find_device(struct device *dev, acpi_handle *handle)
* connected to. * connected to.
*/ */
if (!udev->parent) { if (!udev->parent) {
*handle = acpi_get_child(DEVICE_ACPI_HANDLE(&udev->dev), struct usb_hcd *hcd = bus_to_hcd(udev->bus);
int raw_port_num;
raw_port_num = usb_hcd_find_raw_port_number(hcd,
port_num); port_num);
*handle = acpi_get_child(DEVICE_ACPI_HANDLE(&udev->dev),
raw_port_num);
if (!*handle) if (!*handle)
return -ENODEV; return -ENODEV;
} else { } else {

View File

@ -145,6 +145,7 @@ config USB_LPC32XX
tristate "LPC32XX USB Peripheral Controller" tristate "LPC32XX USB Peripheral Controller"
depends on ARCH_LPC32XX depends on ARCH_LPC32XX
select USB_ISP1301 select USB_ISP1301
select USB_OTG_UTILS
help help
This option selects the USB device controller in the LPC32xx SoC. This option selects the USB device controller in the LPC32xx SoC.

View File

@ -1214,6 +1214,7 @@ itd_urb_transaction (
memset (itd, 0, sizeof *itd); memset (itd, 0, sizeof *itd);
itd->itd_dma = itd_dma; itd->itd_dma = itd_dma;
itd->frame = 9999; /* an invalid value */
list_add (&itd->itd_list, &sched->td_list); list_add (&itd->itd_list, &sched->td_list);
} }
spin_unlock_irqrestore (&ehci->lock, flags); spin_unlock_irqrestore (&ehci->lock, flags);
@ -1915,6 +1916,7 @@ sitd_urb_transaction (
memset (sitd, 0, sizeof *sitd); memset (sitd, 0, sizeof *sitd);
sitd->sitd_dma = sitd_dma; sitd->sitd_dma = sitd_dma;
sitd->frame = 9999; /* an invalid value */
list_add (&sitd->sitd_list, &iso_sched->td_list); list_add (&sitd->sitd_list, &iso_sched->td_list);
} }

View File

@ -1022,44 +1022,24 @@ void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci,
* is attached to (or the roothub port its ancestor hub is attached to). All we * is attached to (or the roothub port its ancestor hub is attached to). All we
* know is the index of that port under either the USB 2.0 or the USB 3.0 * know is the index of that port under either the USB 2.0 or the USB 3.0
* roothub, but that doesn't give us the real index into the HW port status * roothub, but that doesn't give us the real index into the HW port status
* registers. Scan through the xHCI roothub port array, looking for the Nth * registers. Call xhci_find_raw_port_number() to get real index.
* entry of the correct port speed. Return the port number of that entry.
*/ */
static u32 xhci_find_real_port_number(struct xhci_hcd *xhci, static u32 xhci_find_real_port_number(struct xhci_hcd *xhci,
struct usb_device *udev) struct usb_device *udev)
{ {
struct usb_device *top_dev; struct usb_device *top_dev;
unsigned int num_similar_speed_ports; struct usb_hcd *hcd;
unsigned int faked_port_num;
int i; if (udev->speed == USB_SPEED_SUPER)
hcd = xhci->shared_hcd;
else
hcd = xhci->main_hcd;
for (top_dev = udev; top_dev->parent && top_dev->parent->parent; for (top_dev = udev; top_dev->parent && top_dev->parent->parent;
top_dev = top_dev->parent) top_dev = top_dev->parent)
/* Found device below root hub */; /* Found device below root hub */;
faked_port_num = top_dev->portnum;
for (i = 0, num_similar_speed_ports = 0;
i < HCS_MAX_PORTS(xhci->hcs_params1); i++) {
u8 port_speed = xhci->port_array[i];
/* return xhci_find_raw_port_number(hcd, top_dev->portnum);
* Skip ports that don't have known speeds, or have duplicate
* Extended Capabilities port speed entries.
*/
if (port_speed == 0 || port_speed == DUPLICATE_ENTRY)
continue;
/*
* USB 3.0 ports are always under a USB 3.0 hub. USB 2.0 and
* 1.1 ports are under the USB 2.0 hub. If the port speed
* matches the device speed, it's a similar speed port.
*/
if ((port_speed == 0x03) == (udev->speed == USB_SPEED_SUPER))
num_similar_speed_ports++;
if (num_similar_speed_ports == faked_port_num)
/* Roothub ports are numbered from 1 to N */
return i+1;
}
return 0;
} }
/* Setup an xHCI virtual device for a Set Address command */ /* Setup an xHCI virtual device for a Set Address command */

View File

@ -313,6 +313,7 @@ static const struct hc_driver xhci_pci_hc_driver = {
.set_usb2_hw_lpm = xhci_set_usb2_hardware_lpm, .set_usb2_hw_lpm = xhci_set_usb2_hardware_lpm,
.enable_usb3_lpm_timeout = xhci_enable_usb3_lpm_timeout, .enable_usb3_lpm_timeout = xhci_enable_usb3_lpm_timeout,
.disable_usb3_lpm_timeout = xhci_disable_usb3_lpm_timeout, .disable_usb3_lpm_timeout = xhci_disable_usb3_lpm_timeout,
.find_raw_port_number = xhci_find_raw_port_number,
}; };
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/

View File

@ -1599,14 +1599,20 @@ static void handle_port_status(struct xhci_hcd *xhci,
max_ports = HCS_MAX_PORTS(xhci->hcs_params1); max_ports = HCS_MAX_PORTS(xhci->hcs_params1);
if ((port_id <= 0) || (port_id > max_ports)) { if ((port_id <= 0) || (port_id > max_ports)) {
xhci_warn(xhci, "Invalid port id %d\n", port_id); xhci_warn(xhci, "Invalid port id %d\n", port_id);
bogus_port_status = true; inc_deq(xhci, xhci->event_ring);
goto cleanup; return;
} }
/* Figure out which usb_hcd this port is attached to: /* Figure out which usb_hcd this port is attached to:
* is it a USB 3.0 port or a USB 2.0/1.1 port? * is it a USB 3.0 port or a USB 2.0/1.1 port?
*/ */
major_revision = xhci->port_array[port_id - 1]; major_revision = xhci->port_array[port_id - 1];
/* Find the right roothub. */
hcd = xhci_to_hcd(xhci);
if ((major_revision == 0x03) != (hcd->speed == HCD_USB3))
hcd = xhci->shared_hcd;
if (major_revision == 0) { if (major_revision == 0) {
xhci_warn(xhci, "Event for port %u not in " xhci_warn(xhci, "Event for port %u not in "
"Extended Capabilities, ignoring.\n", "Extended Capabilities, ignoring.\n",
@ -1629,10 +1635,6 @@ static void handle_port_status(struct xhci_hcd *xhci,
* into the index into the ports on the correct split roothub, and the * into the index into the ports on the correct split roothub, and the
* correct bus_state structure. * correct bus_state structure.
*/ */
/* Find the right roothub. */
hcd = xhci_to_hcd(xhci);
if ((major_revision == 0x03) != (hcd->speed == HCD_USB3))
hcd = xhci->shared_hcd;
bus_state = &xhci->bus_state[hcd_index(hcd)]; bus_state = &xhci->bus_state[hcd_index(hcd)];
if (hcd->speed == HCD_USB3) if (hcd->speed == HCD_USB3)
port_array = xhci->usb3_ports; port_array = xhci->usb3_ports;
@ -2027,8 +2029,8 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
if (event_trb != ep_ring->dequeue && if (event_trb != ep_ring->dequeue &&
event_trb != td->last_trb) event_trb != td->last_trb)
td->urb->actual_length = td->urb->actual_length =
td->urb->transfer_buffer_length td->urb->transfer_buffer_length -
- TRB_LEN(le32_to_cpu(event->transfer_len)); EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
else else
td->urb->actual_length = 0; td->urb->actual_length = 0;
@ -2060,7 +2062,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
/* Maybe the event was for the data stage? */ /* Maybe the event was for the data stage? */
td->urb->actual_length = td->urb->actual_length =
td->urb->transfer_buffer_length - td->urb->transfer_buffer_length -
TRB_LEN(le32_to_cpu(event->transfer_len)); EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
xhci_dbg(xhci, "Waiting for status " xhci_dbg(xhci, "Waiting for status "
"stage event\n"); "stage event\n");
return 0; return 0;
@ -2096,7 +2098,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
/* handle completion code */ /* handle completion code */
switch (trb_comp_code) { switch (trb_comp_code) {
case COMP_SUCCESS: case COMP_SUCCESS:
if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) { if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) {
frame->status = 0; frame->status = 0;
break; break;
} }
@ -2141,7 +2143,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
len += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])); len += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2]));
} }
len += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) - len += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) -
TRB_LEN(le32_to_cpu(event->transfer_len)); EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
if (trb_comp_code != COMP_STOP_INVAL) { if (trb_comp_code != COMP_STOP_INVAL) {
frame->actual_length = len; frame->actual_length = len;
@ -2199,7 +2201,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
case COMP_SUCCESS: case COMP_SUCCESS:
/* Double check that the HW transferred everything. */ /* Double check that the HW transferred everything. */
if (event_trb != td->last_trb || if (event_trb != td->last_trb ||
TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
xhci_warn(xhci, "WARN Successful completion " xhci_warn(xhci, "WARN Successful completion "
"on short TX\n"); "on short TX\n");
if (td->urb->transfer_flags & URB_SHORT_NOT_OK) if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
@ -2227,18 +2229,18 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
"%d bytes untransferred\n", "%d bytes untransferred\n",
td->urb->ep->desc.bEndpointAddress, td->urb->ep->desc.bEndpointAddress,
td->urb->transfer_buffer_length, td->urb->transfer_buffer_length,
TRB_LEN(le32_to_cpu(event->transfer_len))); EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)));
/* Fast path - was this the last TRB in the TD for this URB? */ /* Fast path - was this the last TRB in the TD for this URB? */
if (event_trb == td->last_trb) { if (event_trb == td->last_trb) {
if (TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
td->urb->actual_length = td->urb->actual_length =
td->urb->transfer_buffer_length - td->urb->transfer_buffer_length -
TRB_LEN(le32_to_cpu(event->transfer_len)); EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
if (td->urb->transfer_buffer_length < if (td->urb->transfer_buffer_length <
td->urb->actual_length) { td->urb->actual_length) {
xhci_warn(xhci, "HC gave bad length " xhci_warn(xhci, "HC gave bad length "
"of %d bytes left\n", "of %d bytes left\n",
TRB_LEN(le32_to_cpu(event->transfer_len))); EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)));
td->urb->actual_length = 0; td->urb->actual_length = 0;
if (td->urb->transfer_flags & URB_SHORT_NOT_OK) if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
*status = -EREMOTEIO; *status = -EREMOTEIO;
@ -2280,7 +2282,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
if (trb_comp_code != COMP_STOP_INVAL) if (trb_comp_code != COMP_STOP_INVAL)
td->urb->actual_length += td->urb->actual_length +=
TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) - TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) -
TRB_LEN(le32_to_cpu(event->transfer_len)); EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
} }
return finish_td(xhci, td, event_trb, event, ep, status, false); return finish_td(xhci, td, event_trb, event, ep, status, false);
@ -2368,7 +2370,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
* transfer type * transfer type
*/ */
case COMP_SUCCESS: case COMP_SUCCESS:
if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0)
break; break;
if (xhci->quirks & XHCI_TRUST_TX_LENGTH) if (xhci->quirks & XHCI_TRUST_TX_LENGTH)
trb_comp_code = COMP_SHORT_TX; trb_comp_code = COMP_SHORT_TX;
@ -2461,14 +2463,21 @@ static int handle_tx_event(struct xhci_hcd *xhci,
* TD list. * TD list.
*/ */
if (list_empty(&ep_ring->td_list)) { if (list_empty(&ep_ring->td_list)) {
xhci_warn(xhci, "WARN Event TRB for slot %d ep %d " /*
"with no TDs queued?\n", * A stopped endpoint may generate an extra completion
TRB_TO_SLOT_ID(le32_to_cpu(event->flags)), * event if the device was suspended. Don't print
ep_index); * warnings.
xhci_dbg(xhci, "Event TRB with TRB type ID %u\n", */
(le32_to_cpu(event->flags) & if (!(trb_comp_code == COMP_STOP ||
TRB_TYPE_BITMASK)>>10); trb_comp_code == COMP_STOP_INVAL)) {
xhci_print_trb_offsets(xhci, (union xhci_trb *) event); xhci_warn(xhci, "WARN Event TRB for slot %d ep %d with no TDs queued?\n",
TRB_TO_SLOT_ID(le32_to_cpu(event->flags)),
ep_index);
xhci_dbg(xhci, "Event TRB with TRB type ID %u\n",
(le32_to_cpu(event->flags) &
TRB_TYPE_BITMASK)>>10);
xhci_print_trb_offsets(xhci, (union xhci_trb *) event);
}
if (ep->skip) { if (ep->skip) {
ep->skip = false; ep->skip = false;
xhci_dbg(xhci, "td_list is empty while skip " xhci_dbg(xhci, "td_list is empty while skip "

View File

@ -3779,6 +3779,28 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
return 0; return 0;
} }
/*
* Transfer the port index into real index in the HW port status
* registers. Caculate offset between the port's PORTSC register
* and port status base. Divide the number of per port register
* to get the real index. The raw port number bases 1.
*/
int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
__le32 __iomem *base_addr = &xhci->op_regs->port_status_base;
__le32 __iomem *addr;
int raw_port;
if (hcd->speed != HCD_USB3)
addr = xhci->usb2_ports[port1 - 1];
else
addr = xhci->usb3_ports[port1 - 1];
raw_port = (addr - base_addr)/NUM_PORT_REGS + 1;
return raw_port;
}
#ifdef CONFIG_USB_SUSPEND #ifdef CONFIG_USB_SUSPEND
/* BESL to HIRD Encoding array for USB2 LPM */ /* BESL to HIRD Encoding array for USB2 LPM */

View File

@ -972,6 +972,10 @@ struct xhci_transfer_event {
__le32 flags; __le32 flags;
}; };
/* Transfer event TRB length bit mask */
/* bits 0:23 */
#define EVENT_TRB_LEN(p) ((p) & 0xffffff)
/** Transfer Event bit fields **/ /** Transfer Event bit fields **/
#define TRB_TO_EP_ID(p) (((p) >> 16) & 0x1f) #define TRB_TO_EP_ID(p) (((p) >> 16) & 0x1f)
@ -1829,6 +1833,7 @@ void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 __iomem **port_array,
int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex,
char *buf, u16 wLength); char *buf, u16 wLength);
int xhci_hub_status_data(struct usb_hcd *hcd, char *buf); int xhci_hub_status_data(struct usb_hcd *hcd, char *buf);
int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1);
#ifdef CONFIG_PM #ifdef CONFIG_PM
int xhci_bus_suspend(struct usb_hcd *hcd); int xhci_bus_suspend(struct usb_hcd *hcd);

View File

@ -38,6 +38,7 @@ config USB_ISP1301
tristate "NXP ISP1301 USB transceiver support" tristate "NXP ISP1301 USB transceiver support"
depends on USB || USB_GADGET depends on USB || USB_GADGET
depends on I2C depends on I2C
select USB_OTG_UTILS
help help
Say Y here to add support for the NXP ISP1301 USB transceiver driver. Say Y here to add support for the NXP ISP1301 USB transceiver driver.
This chip is typically used as USB transceiver for USB host, gadget This chip is typically used as USB transceiver for USB host, gadget

View File

@ -640,6 +640,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) },
{ USB_DEVICE(ACTON_VID, ACTON_SPECTRAPRO_PID) }, { USB_DEVICE(ACTON_VID, ACTON_SPECTRAPRO_PID) },
{ USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) },
{ USB_DEVICE(MITSUBISHI_VID, MITSUBISHI_FXUSB_PID) },
{ USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
{ USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) },
{ USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) },

View File

@ -583,6 +583,13 @@
#define CONTEC_VID 0x06CE /* Vendor ID */ #define CONTEC_VID 0x06CE /* Vendor ID */
#define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ #define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */
/*
* Mitsubishi Electric Corp. (http://www.meau.com)
* Submitted by Konstantin Holoborodko
*/
#define MITSUBISHI_VID 0x06D3
#define MITSUBISHI_FXUSB_PID 0x0284 /* USB/RS422 converters: FX-USB-AW/-BD */
/* /*
* Definitions for B&B Electronics products. * Definitions for B&B Electronics products.
*/ */

View File

@ -903,6 +903,7 @@ static int usb_serial_probe(struct usb_interface *interface,
port->port.ops = &serial_port_ops; port->port.ops = &serial_port_ops;
port->serial = serial; port->serial = serial;
spin_lock_init(&port->lock); spin_lock_init(&port->lock);
init_waitqueue_head(&port->delta_msr_wait);
/* Keep this for private driver use for the moment but /* Keep this for private driver use for the moment but
should probably go away */ should probably go away */
INIT_WORK(&port->work, usb_serial_port_work); INIT_WORK(&port->work, usb_serial_port_work);

View File

@ -357,6 +357,7 @@ struct hc_driver {
*/ */
int (*disable_usb3_lpm_timeout)(struct usb_hcd *, int (*disable_usb3_lpm_timeout)(struct usb_hcd *,
struct usb_device *, enum usb3_link_state state); struct usb_device *, enum usb3_link_state state);
int (*find_raw_port_number)(struct usb_hcd *, int);
}; };
extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
@ -396,6 +397,7 @@ extern int usb_hcd_is_primary_hcd(struct usb_hcd *hcd);
extern int usb_add_hcd(struct usb_hcd *hcd, extern int usb_add_hcd(struct usb_hcd *hcd,
unsigned int irqnum, unsigned long irqflags); unsigned int irqnum, unsigned long irqflags);
extern void usb_remove_hcd(struct usb_hcd *hcd); extern void usb_remove_hcd(struct usb_hcd *hcd);
extern int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1);
struct platform_device; struct platform_device;
extern void usb_hcd_platform_shutdown(struct platform_device *dev); extern void usb_hcd_platform_shutdown(struct platform_device *dev);