Commit 435a5aeb authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6

* 'usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6:
  USB: fix autosuspend bug in usb-serial
  USB: ehci: disable LPM and PPCD for nVidia MCP89 chips
  USB: serial: ftdi_sio: Vardaan USB RS422/485 converter PID added
  USB: yurex: add .llseek fop to file_operations
  USB: ftdi_sio: Add ID for RT Systems USB-29B radio cable
  usb: musb: do not use dma for control transfers
  usb: musb: gadget: fix compilation warning
  usb: musb: clear RXCSR_AUTOCLEAR before PIO read
  usb: musb: unmap dma buffer when switching to PIO
  xhci: Don't let the USB core disable SuperSpeed ports.
  xhci: Setup array of USB 2.0 and USB 3.0 ports.
  xhci: Fix reset-device and configure-endpoint commands
parents 2e5c26de b7a5100b
...@@ -1330,6 +1330,8 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, ...@@ -1330,6 +1330,8 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
*/ */
if (usb_endpoint_xfer_control(&urb->ep->desc)) { if (usb_endpoint_xfer_control(&urb->ep->desc)) {
if (hcd->self.uses_pio_for_control)
return ret;
if (hcd->self.uses_dma) { if (hcd->self.uses_dma) {
urb->setup_dma = dma_map_single( urb->setup_dma = dma_map_single(
hcd->self.controller, hcd->self.controller,
......
...@@ -161,6 +161,18 @@ static int ehci_pci_setup(struct usb_hcd *hcd) ...@@ -161,6 +161,18 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
if (pdev->revision < 0xa4) if (pdev->revision < 0xa4)
ehci->no_selective_suspend = 1; ehci->no_selective_suspend = 1;
break; break;
/* MCP89 chips on the MacBookAir3,1 give EPROTO when
* fetching device descriptors unless LPM is disabled.
* There are also intermittent problems enumerating
* devices with PPCD enabled.
*/
case 0x0d9d:
ehci_info(ehci, "disable lpm/ppcd for nvidia mcp89");
ehci->has_lpm = 0;
ehci->has_ppcd = 0;
ehci->command &= ~CMD_PPCEE;
break;
} }
break; break;
case PCI_VENDOR_ID_VIA: case PCI_VENDOR_ID_VIA:
......
...@@ -229,6 +229,13 @@ void xhci_ring_device(struct xhci_hcd *xhci, int slot_id) ...@@ -229,6 +229,13 @@ void xhci_ring_device(struct xhci_hcd *xhci, int slot_id)
static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex, static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex,
u32 __iomem *addr, u32 port_status) u32 __iomem *addr, u32 port_status)
{ {
/* Don't allow the USB core to disable SuperSpeed ports. */
if (xhci->port_array[wIndex] == 0x03) {
xhci_dbg(xhci, "Ignoring request to disable "
"SuperSpeed port.\n");
return;
}
/* Write 1 to disable the port */ /* Write 1 to disable the port */
xhci_writel(xhci, port_status | PORT_PE, addr); xhci_writel(xhci, port_status | PORT_PE, addr);
port_status = xhci_readl(xhci, addr); port_status = xhci_readl(xhci, addr);
......
...@@ -1443,6 +1443,13 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) ...@@ -1443,6 +1443,13 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
xhci->dcbaa = NULL; xhci->dcbaa = NULL;
scratchpad_free(xhci); scratchpad_free(xhci);
xhci->num_usb2_ports = 0;
xhci->num_usb3_ports = 0;
kfree(xhci->usb2_ports);
kfree(xhci->usb3_ports);
kfree(xhci->port_array);
xhci->page_size = 0; xhci->page_size = 0;
xhci->page_shift = 0; xhci->page_shift = 0;
xhci->bus_suspended = 0; xhci->bus_suspended = 0;
...@@ -1627,6 +1634,161 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci) ...@@ -1627,6 +1634,161 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci)
&xhci->ir_set->erst_dequeue); &xhci->ir_set->erst_dequeue);
} }
static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
u32 __iomem *addr, u8 major_revision)
{
u32 temp, port_offset, port_count;
int i;
if (major_revision > 0x03) {
xhci_warn(xhci, "Ignoring unknown port speed, "
"Ext Cap %p, revision = 0x%x\n",
addr, major_revision);
/* Ignoring port protocol we can't understand. FIXME */
return;
}
/* Port offset and count in the third dword, see section 7.2 */
temp = xhci_readl(xhci, addr + 2);
port_offset = XHCI_EXT_PORT_OFF(temp);
port_count = XHCI_EXT_PORT_COUNT(temp);
xhci_dbg(xhci, "Ext Cap %p, port offset = %u, "
"count = %u, revision = 0x%x\n",
addr, port_offset, port_count, major_revision);
/* Port count includes the current port offset */
if (port_offset == 0 || (port_offset + port_count - 1) > num_ports)
/* WTF? "Valid values are ‘1’ to MaxPorts" */
return;
port_offset--;
for (i = port_offset; i < (port_offset + port_count); i++) {
/* Duplicate entry. Ignore the port if the revisions differ. */
if (xhci->port_array[i] != 0) {
xhci_warn(xhci, "Duplicate port entry, Ext Cap %p,"
" port %u\n", addr, i);
xhci_warn(xhci, "Port was marked as USB %u, "
"duplicated as USB %u\n",
xhci->port_array[i], major_revision);
/* Only adjust the roothub port counts if we haven't
* found a similar duplicate.
*/
if (xhci->port_array[i] != major_revision &&
xhci->port_array[i] != (u8) -1) {
if (xhci->port_array[i] == 0x03)
xhci->num_usb3_ports--;
else
xhci->num_usb2_ports--;
xhci->port_array[i] = (u8) -1;
}
/* FIXME: Should we disable the port? */
}
xhci->port_array[i] = major_revision;
if (major_revision == 0x03)
xhci->num_usb3_ports++;
else
xhci->num_usb2_ports++;
}
/* FIXME: Should we disable ports not in the Extended Capabilities? */
}
/*
* Scan the Extended Capabilities for the "Supported Protocol Capabilities" that
* specify what speeds each port is supposed to be. We can't count on the port
* speed bits in the PORTSC register being correct until a device is connected,
* but we need to set up the two fake roothubs with the correct number of USB
* 3.0 and USB 2.0 ports at host controller initialization time.
*/
static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
{
u32 __iomem *addr;
u32 offset;
unsigned int num_ports;
int i, port_index;
addr = &xhci->cap_regs->hcc_params;
offset = XHCI_HCC_EXT_CAPS(xhci_readl(xhci, addr));
if (offset == 0) {
xhci_err(xhci, "No Extended Capability registers, "
"unable to set up roothub.\n");
return -ENODEV;
}
num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
xhci->port_array = kzalloc(sizeof(*xhci->port_array)*num_ports, flags);
if (!xhci->port_array)
return -ENOMEM;
/*
* For whatever reason, the first capability offset is from the
* capability register base, not from the HCCPARAMS register.
* See section 5.3.6 for offset calculation.
*/
addr = &xhci->cap_regs->hc_capbase + offset;
while (1) {
u32 cap_id;
cap_id = xhci_readl(xhci, addr);
if (XHCI_EXT_CAPS_ID(cap_id) == XHCI_EXT_CAPS_PROTOCOL)
xhci_add_in_port(xhci, num_ports, addr,
(u8) XHCI_EXT_PORT_MAJOR(cap_id));
offset = XHCI_EXT_CAPS_NEXT(cap_id);
if (!offset || (xhci->num_usb2_ports + xhci->num_usb3_ports)
== num_ports)
break;
/*
* Once you're into the Extended Capabilities, the offset is
* always relative to the register holding the offset.
*/
addr += offset;
}
if (xhci->num_usb2_ports == 0 && xhci->num_usb3_ports == 0) {
xhci_warn(xhci, "No ports on the roothubs?\n");
return -ENODEV;
}
xhci_dbg(xhci, "Found %u USB 2.0 ports and %u USB 3.0 ports.\n",
xhci->num_usb2_ports, xhci->num_usb3_ports);
/*
* Note we could have all USB 3.0 ports, or all USB 2.0 ports.
* Not sure how the USB core will handle a hub with no ports...
*/
if (xhci->num_usb2_ports) {
xhci->usb2_ports = kmalloc(sizeof(*xhci->usb2_ports)*
xhci->num_usb2_ports, flags);
if (!xhci->usb2_ports)
return -ENOMEM;
port_index = 0;
for (i = 0; i < num_ports; i++)
if (xhci->port_array[i] != 0x03) {
xhci->usb2_ports[port_index] =
&xhci->op_regs->port_status_base +
NUM_PORT_REGS*i;
xhci_dbg(xhci, "USB 2.0 port at index %u, "
"addr = %p\n", i,
xhci->usb2_ports[port_index]);
port_index++;
}
}
if (xhci->num_usb3_ports) {
xhci->usb3_ports = kmalloc(sizeof(*xhci->usb3_ports)*
xhci->num_usb3_ports, flags);
if (!xhci->usb3_ports)
return -ENOMEM;
port_index = 0;
for (i = 0; i < num_ports; i++)
if (xhci->port_array[i] == 0x03) {
xhci->usb3_ports[port_index] =
&xhci->op_regs->port_status_base +
NUM_PORT_REGS*i;
xhci_dbg(xhci, "USB 3.0 port at index %u, "
"addr = %p\n", i,
xhci->usb3_ports[port_index]);
port_index++;
}
}
return 0;
}
int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
{ {
...@@ -1809,6 +1971,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) ...@@ -1809,6 +1971,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
if (scratchpad_alloc(xhci, flags)) if (scratchpad_alloc(xhci, flags))
goto fail; goto fail;
if (xhci_setup_port_arrays(xhci, flags))
goto fail;
return 0; return 0;
......
...@@ -1549,6 +1549,15 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, ...@@ -1549,6 +1549,15 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
cmd_completion = command->completion; cmd_completion = command->completion;
cmd_status = &command->status; cmd_status = &command->status;
command->command_trb = xhci->cmd_ring->enqueue; command->command_trb = xhci->cmd_ring->enqueue;
/* Enqueue pointer can be left pointing to the link TRB,
* we must handle that
*/
if ((command->command_trb->link.control & TRB_TYPE_BITMASK)
== TRB_TYPE(TRB_LINK))
command->command_trb =
xhci->cmd_ring->enq_seg->next->trbs;
list_add_tail(&command->cmd_list, &virt_dev->cmd_list); list_add_tail(&command->cmd_list, &virt_dev->cmd_list);
} else { } else {
in_ctx = virt_dev->in_ctx; in_ctx = virt_dev->in_ctx;
...@@ -2272,6 +2281,15 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) ...@@ -2272,6 +2281,15 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
/* Attempt to submit the Reset Device command to the command ring */ /* Attempt to submit the Reset Device command to the command ring */
spin_lock_irqsave(&xhci->lock, flags); spin_lock_irqsave(&xhci->lock, flags);
reset_device_cmd->command_trb = xhci->cmd_ring->enqueue; reset_device_cmd->command_trb = xhci->cmd_ring->enqueue;
/* Enqueue pointer can be left pointing to the link TRB,
* we must handle that
*/
if ((reset_device_cmd->command_trb->link.control & TRB_TYPE_BITMASK)
== TRB_TYPE(TRB_LINK))
reset_device_cmd->command_trb =
xhci->cmd_ring->enq_seg->next->trbs;
list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list); list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list);
ret = xhci_queue_reset_device(xhci, slot_id); ret = xhci_queue_reset_device(xhci, slot_id);
if (ret) { if (ret) {
......
...@@ -453,6 +453,24 @@ struct xhci_doorbell_array { ...@@ -453,6 +453,24 @@ struct xhci_doorbell_array {
#define STREAM_ID_TO_DB(p) (((p) & 0xffff) << 16) #define STREAM_ID_TO_DB(p) (((p) & 0xffff) << 16)
/**
* struct xhci_protocol_caps
* @revision: major revision, minor revision, capability ID,
* and next capability pointer.
* @name_string: Four ASCII characters to say which spec this xHC
* follows, typically "USB ".
* @port_info: Port offset, count, and protocol-defined information.
*/
struct xhci_protocol_caps {
u32 revision;
u32 name_string;
u32 port_info;
};
#define XHCI_EXT_PORT_MAJOR(x) (((x) >> 24) & 0xff)
#define XHCI_EXT_PORT_OFF(x) ((x) & 0xff)
#define XHCI_EXT_PORT_COUNT(x) (((x) >> 8) & 0xff)
/** /**
* struct xhci_container_ctx * struct xhci_container_ctx
* @type: Type of context. Used to calculated offsets to contained contexts. * @type: Type of context. Used to calculated offsets to contained contexts.
...@@ -1240,6 +1258,14 @@ struct xhci_hcd { ...@@ -1240,6 +1258,14 @@ struct xhci_hcd {
u32 suspended_ports[8]; /* which ports are u32 suspended_ports[8]; /* which ports are
suspended */ suspended */
unsigned long resume_done[MAX_HC_PORTS]; unsigned long resume_done[MAX_HC_PORTS];
/* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */
u8 *port_array;
/* Array of pointers to USB 3.0 PORTSC registers */
u32 __iomem **usb3_ports;
unsigned int num_usb3_ports;
/* Array of pointers to USB 2.0 PORTSC registers */
u32 __iomem **usb2_ports;
unsigned int num_usb2_ports;
}; };
/* For testing purposes */ /* For testing purposes */
......
...@@ -536,6 +536,7 @@ static const struct file_operations yurex_fops = { ...@@ -536,6 +536,7 @@ static const struct file_operations yurex_fops = {
.open = yurex_open, .open = yurex_open,
.release = yurex_release, .release = yurex_release,
.fasync = yurex_fasync, .fasync = yurex_fasync,
.llseek = default_llseek,
}; };
......
...@@ -2116,12 +2116,15 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) ...@@ -2116,12 +2116,15 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
* Otherwise, wait till the gadget driver hooks up. * Otherwise, wait till the gadget driver hooks up.
*/ */
if (!is_otg_enabled(musb) && is_host_enabled(musb)) { if (!is_otg_enabled(musb) && is_host_enabled(musb)) {
struct usb_hcd *hcd = musb_to_hcd(musb);
MUSB_HST_MODE(musb); MUSB_HST_MODE(musb);
musb->xceiv->default_a = 1; musb->xceiv->default_a = 1;
musb->xceiv->state = OTG_STATE_A_IDLE; musb->xceiv->state = OTG_STATE_A_IDLE;
status = usb_add_hcd(musb_to_hcd(musb), -1, 0); status = usb_add_hcd(musb_to_hcd(musb), -1, 0);
hcd->self.uses_pio_for_control = 1;
DBG(1, "%s mode, status %d, devctl %02x %c\n", DBG(1, "%s mode, status %d, devctl %02x %c\n",
"HOST", status, "HOST", status,
musb_readb(musb->mregs, MUSB_DEVCTL), musb_readb(musb->mregs, MUSB_DEVCTL),
......
...@@ -92,6 +92,59 @@ ...@@ -92,6 +92,59 @@
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
/* Maps the buffer to dma */
static inline void map_dma_buffer(struct musb_request *request,
struct musb *musb)
{
if (request->request.dma == DMA_ADDR_INVALID) {
request->request.dma = dma_map_single(
musb->controller,
request->request.buf,
request->request.length,
request->tx
? DMA_TO_DEVICE
: DMA_FROM_DEVICE);
request->mapped = 1;
} else {
dma_sync_single_for_device(musb->controller,
request->request.dma,
request->request.length,
request->tx
? DMA_TO_DEVICE
: DMA_FROM_DEVICE);
request->mapped = 0;
}
}
/* Unmap the buffer from dma and maps it back to cpu */
static inline void unmap_dma_buffer(struct musb_request *request,
struct musb *musb)
{
if (request->request.dma == DMA_ADDR_INVALID) {
DBG(20, "not unmapping a never mapped buffer\n");
return;
}
if (request->mapped) {
dma_unmap_single(musb->controller,
request->request.dma,
request->request.length,
request->tx
? DMA_TO_DEVICE
: DMA_FROM_DEVICE);
request->request.dma = DMA_ADDR_INVALID;
request->mapped = 0;
} else {
dma_sync_single_for_cpu(musb->controller,
request->request.dma,
request->request.length,
request->tx
? DMA_TO_DEVICE
: DMA_FROM_DEVICE);
}
}
/* /*
* Immediately complete a request. * Immediately complete a request.
* *
...@@ -119,24 +172,8 @@ __acquires(ep->musb->lock) ...@@ -119,24 +172,8 @@ __acquires(ep->musb->lock)
ep->busy = 1; ep->busy = 1;
spin_unlock(&musb->lock); spin_unlock(&musb->lock);
if (is_dma_capable()) { if (is_dma_capable() && ep->dma)
if (req->mapped) { unmap_dma_buffer(req, musb);
dma_unmap_single(musb->controller,
req->request.dma,
req->request.length,
req->tx
? DMA_TO_DEVICE
: DMA_FROM_DEVICE);
req->request.dma = DMA_ADDR_INVALID;
req->mapped = 0;
} else if (req->request.dma != DMA_ADDR_INVALID)
dma_sync_single_for_cpu(musb->controller,
req->request.dma,
req->request.length,
req->tx
? DMA_TO_DEVICE
: DMA_FROM_DEVICE);
}
if (request->status == 0) if (request->status == 0)
DBG(5, "%s done request %p, %d/%d\n", DBG(5, "%s done request %p, %d/%d\n",
ep->end_point.name, request, ep->end_point.name, request,
...@@ -395,6 +432,13 @@ static void txstate(struct musb *musb, struct musb_request *req) ...@@ -395,6 +432,13 @@ static void txstate(struct musb *musb, struct musb_request *req)
#endif #endif
if (!use_dma) { if (!use_dma) {
/*
* Unmap the dma buffer back to cpu if dma channel
* programming fails
*/
if (is_dma_capable() && musb_ep->dma)
unmap_dma_buffer(req, musb);
musb_write_fifo(musb_ep->hw_ep, fifo_count, musb_write_fifo(musb_ep->hw_ep, fifo_count,
(u8 *) (request->buf + request->actual)); (u8 *) (request->buf + request->actual));
request->actual += fifo_count; request->actual += fifo_count;
...@@ -713,6 +757,21 @@ static void rxstate(struct musb *musb, struct musb_request *req) ...@@ -713,6 +757,21 @@ static void rxstate(struct musb *musb, struct musb_request *req)
return; return;
} }
#endif #endif
/*
* Unmap the dma buffer back to cpu if dma channel
* programming fails. This buffer is mapped if the
* channel allocation is successful
*/
if (is_dma_capable() && musb_ep->dma) {
unmap_dma_buffer(req, musb);
/*
* Clear DMAENAB and AUTOCLEAR for the
* PIO mode transfer
*/
csr &= ~(MUSB_RXCSR_DMAENAB | MUSB_RXCSR_AUTOCLEAR);
musb_writew(epio, MUSB_RXCSR, csr);
}
musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *) musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *)
(request->buf + request->actual)); (request->buf + request->actual));
...@@ -837,7 +896,9 @@ void musb_g_rx(struct musb *musb, u8 epnum) ...@@ -837,7 +896,9 @@ void musb_g_rx(struct musb *musb, u8 epnum)
if (!request) if (!request)
return; return;
} }
#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA)
exit: exit:
#endif
/* Analyze request */ /* Analyze request */
rxstate(musb, to_musb_request(request)); rxstate(musb, to_musb_request(request));
} }
...@@ -1150,26 +1211,9 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req, ...@@ -1150,26 +1211,9 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
request->epnum = musb_ep->current_epnum; request->epnum = musb_ep->current_epnum;
request->tx = musb_ep->is_in; request->tx = musb_ep->is_in;
if (is_dma_capable() && musb_ep->dma) { if (is_dma_capable() && musb_ep->dma)
if (request->request.dma == DMA_ADDR_INVALID) { map_dma_buffer(request, musb);
request->request.dma = dma_map_single( else
musb->controller,
request->request.buf,
request->request.length,
request->tx
? DMA_TO_DEVICE
: DMA_FROM_DEVICE);
request->mapped = 1;
} else {
dma_sync_single_for_device(musb->controller,
request->request.dma,
request->request.length,
request->tx
? DMA_TO_DEVICE
: DMA_FROM_DEVICE);
request->mapped = 0;
}
} else
request->mapped = 0; request->mapped = 0;
spin_lock_irqsave(&musb->lock, lockflags); spin_lock_irqsave(&musb->lock, lockflags);
...@@ -1789,6 +1833,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, ...@@ -1789,6 +1833,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
spin_unlock_irqrestore(&musb->lock, flags); spin_unlock_irqrestore(&musb->lock, flags);
if (is_otg_enabled(musb)) { if (is_otg_enabled(musb)) {
struct usb_hcd *hcd = musb_to_hcd(musb);
DBG(3, "OTG startup...\n"); DBG(3, "OTG startup...\n");
/* REVISIT: funcall to other code, which also /* REVISIT: funcall to other code, which also
...@@ -1803,6 +1849,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, ...@@ -1803,6 +1849,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
musb->gadget_driver = NULL; musb->gadget_driver = NULL;
musb->g.dev.driver = NULL; musb->g.dev.driver = NULL;
spin_unlock_irqrestore(&musb->lock, flags); spin_unlock_irqrestore(&musb->lock, flags);
} else {
hcd->self.uses_pio_for_control = 1;
} }
} }
} }
......
...@@ -201,6 +201,7 @@ static struct usb_device_id id_table_combined [] = { ...@@ -201,6 +201,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) }, { USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) },
{ USB_DEVICE(FTDI_VID, FTDI_VARDAAN_PID) },
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) }, { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) },
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) }, { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) },
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) }, { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) },
...@@ -696,6 +697,7 @@ static struct usb_device_id id_table_combined [] = { ...@@ -696,6 +697,7 @@ static struct usb_device_id id_table_combined [] = {
.driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
{ USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
{ USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_SERIAL_VX7_PID) }, { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_SERIAL_VX7_PID) },
{ USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_CT29B_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) },
{ USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
......
...@@ -114,6 +114,9 @@ ...@@ -114,6 +114,9 @@
/* Lenz LI-USB Computer Interface. */ /* Lenz LI-USB Computer Interface. */
#define FTDI_LENZ_LIUSB_PID 0xD780 #define FTDI_LENZ_LIUSB_PID 0xD780
/* Vardaan Enterprises Serial Interface VEUSB422R3 */
#define FTDI_VARDAAN_PID 0xF070
/* /*
* Xsens Technologies BV products (http://www.xsens.com). * Xsens Technologies BV products (http://www.xsens.com).
*/ */
...@@ -721,6 +724,7 @@ ...@@ -721,6 +724,7 @@
*/ */
#define RTSYSTEMS_VID 0x2100 /* Vendor ID */ #define RTSYSTEMS_VID 0x2100 /* Vendor ID */
#define RTSYSTEMS_SERIAL_VX7_PID 0x9e52 /* Serial converter for VX-7 Radios using FT232RL */ #define RTSYSTEMS_SERIAL_VX7_PID 0x9e52 /* Serial converter for VX-7 Radios using FT232RL */
#define RTSYSTEMS_CT29B_PID 0x9e54 /* CT29B Radio Cable */
/* /*
* Bayer Ascensia Contour blood glucose meter USB-converter cable. * Bayer Ascensia Contour blood glucose meter USB-converter cable.
......
...@@ -51,6 +51,7 @@ static struct usb_driver usb_serial_driver = { ...@@ -51,6 +51,7 @@ static struct usb_driver usb_serial_driver = {
.suspend = usb_serial_suspend, .suspend = usb_serial_suspend,
.resume = usb_serial_resume, .resume = usb_serial_resume,
.no_dynamic_id = 1, .no_dynamic_id = 1,
.supports_autosuspend = 1,
}; };
/* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead /* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead
...@@ -1343,6 +1344,8 @@ int usb_serial_register(struct usb_serial_driver *driver) ...@@ -1343,6 +1344,8 @@ int usb_serial_register(struct usb_serial_driver *driver)
return -ENODEV; return -ENODEV;
fixup_generic(driver); fixup_generic(driver);
if (driver->usb_driver)
driver->usb_driver->supports_autosuspend = 1;
if (!driver->description) if (!driver->description)
driver->description = driver->driver.name; driver->description = driver->driver.name;
......
...@@ -313,6 +313,10 @@ struct usb_bus { ...@@ -313,6 +313,10 @@ struct usb_bus {
int busnum; /* Bus number (in order of reg) */ int busnum; /* Bus number (in order of reg) */
const char *bus_name; /* stable id (PCI slot_name etc) */ const char *bus_name; /* stable id (PCI slot_name etc) */
u8 uses_dma; /* Does the host controller use DMA? */ u8 uses_dma; /* Does the host controller use DMA? */
u8 uses_pio_for_control; /*
* Does the host controller use PIO
* for control transfers?
*/
u8 otg_port; /* 0, or number of OTG/HNP port */ u8 otg_port; /* 0, or number of OTG/HNP port */
unsigned is_b_host:1; /* true during some HNP roleswitches */ unsigned is_b_host:1; /* true during some HNP roleswitches */
unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */ unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment