Commit 895213cb authored by Stephen Rothwell's avatar Stephen Rothwell

Merge branch 'quilt/usb.current'

parents d1ff24dd 639f2a74
...@@ -59,6 +59,7 @@ ...@@ -59,6 +59,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/serial.h>
#include <linux/tty_driver.h> #include <linux/tty_driver.h>
#include <linux/tty_flip.h> #include <linux/tty_flip.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -609,6 +610,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) ...@@ -609,6 +610,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
acm->throttle = 0; acm->throttle = 0;
tasklet_schedule(&acm->urb_task); tasklet_schedule(&acm->urb_task);
set_bit(ASYNCB_INITIALIZED, &acm->port.flags);
rv = tty_port_block_til_ready(&acm->port, tty, filp); rv = tty_port_block_til_ready(&acm->port, tty, filp);
done: done:
mutex_unlock(&acm->mutex); mutex_unlock(&acm->mutex);
......
...@@ -313,8 +313,13 @@ static ssize_t wdm_write ...@@ -313,8 +313,13 @@ static ssize_t wdm_write
r = usb_autopm_get_interface(desc->intf); r = usb_autopm_get_interface(desc->intf);
if (r < 0) if (r < 0)
goto outnp; goto outnp;
if (!file->f_flags && O_NONBLOCK)
r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE, r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE,
&desc->flags)); &desc->flags));
else
if (test_bit(WDM_IN_USE, &desc->flags))
r = -EAGAIN;
if (r < 0) if (r < 0)
goto out; goto out;
...@@ -377,7 +382,7 @@ outnl: ...@@ -377,7 +382,7 @@ outnl:
static ssize_t wdm_read static ssize_t wdm_read
(struct file *file, char __user *buffer, size_t count, loff_t *ppos) (struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{ {
int rv, cntr; int rv, cntr = 0;
int i = 0; int i = 0;
struct wdm_device *desc = file->private_data; struct wdm_device *desc = file->private_data;
...@@ -389,10 +394,23 @@ static ssize_t wdm_read ...@@ -389,10 +394,23 @@ static ssize_t wdm_read
if (desc->length == 0) { if (desc->length == 0) {
desc->read = 0; desc->read = 0;
retry: retry:
if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
rv = -ENODEV;
goto err;
}
i++; i++;
if (file->f_flags & O_NONBLOCK) {
if (!test_bit(WDM_READ, &desc->flags)) {
rv = cntr ? cntr : -EAGAIN;
goto err;
}
rv = 0;
} else {
rv = wait_event_interruptible(desc->wait, rv = wait_event_interruptible(desc->wait,
test_bit(WDM_READ, &desc->flags)); test_bit(WDM_READ, &desc->flags));
}
/* may have happened while we slept */
if (test_bit(WDM_DISCONNECTING, &desc->flags)) { if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
rv = -ENODEV; rv = -ENODEV;
goto err; goto err;
...@@ -448,7 +466,7 @@ retry: ...@@ -448,7 +466,7 @@ retry:
err: err:
mutex_unlock(&desc->rlock); mutex_unlock(&desc->rlock);
if (rv < 0) if (rv < 0 && rv != -EAGAIN)
dev_err(&desc->intf->dev, "wdm_read: exit error\n"); dev_err(&desc->intf->dev, "wdm_read: exit error\n");
return rv; return rv;
} }
......
...@@ -105,7 +105,7 @@ static int usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, ...@@ -105,7 +105,7 @@ static int usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
ep->ss_ep_comp->extralen = i; ep->ss_ep_comp->extralen = i;
buffer += i; buffer += i;
size -= i; size -= i;
retval = buffer - buffer_start + i; retval = buffer - buffer_start;
if (num_skipped > 0) if (num_skipped > 0)
dev_dbg(ddev, "skipped %d descriptor%s after %s\n", dev_dbg(ddev, "skipped %d descriptor%s after %s\n",
num_skipped, plural(num_skipped), num_skipped, plural(num_skipped),
......
...@@ -719,8 +719,12 @@ retry: ...@@ -719,8 +719,12 @@ retry:
/* port status seems weird until after reset, so /* port status seems weird until after reset, so
* force the reset and make khubd clean up later. * force the reset and make khubd clean up later.
*/ */
sl811->port1 |= (1 << USB_PORT_FEAT_C_CONNECTION) if (sl811->stat_insrmv & 1)
| (1 << USB_PORT_FEAT_CONNECTION); sl811->port1 |= 1 << USB_PORT_FEAT_CONNECTION;
else
sl811->port1 &= ~(1 << USB_PORT_FEAT_CONNECTION);
sl811->port1 |= 1 << USB_PORT_FEAT_C_CONNECTION;
} else if (irqstat & SL11H_INTMASK_RD) { } else if (irqstat & SL11H_INTMASK_RD) {
if (sl811->port1 & (1 << USB_PORT_FEAT_SUSPEND)) { if (sl811->port1 & (1 << USB_PORT_FEAT_SUSPEND)) {
......
...@@ -413,7 +413,8 @@ void xhci_dbg_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx) ...@@ -413,7 +413,8 @@ void xhci_dbg_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx)
int i; int i;
struct xhci_slot_ctx *slot_ctx = xhci_get_slot_ctx(xhci, ctx); struct xhci_slot_ctx *slot_ctx = xhci_get_slot_ctx(xhci, ctx);
dma_addr_t dma = ctx->dma + ((unsigned long)slot_ctx - (unsigned long)ctx); dma_addr_t dma = ctx->dma +
((unsigned long)slot_ctx - (unsigned long)ctx->bytes);
int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params); int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params);
xhci_dbg(xhci, "Slot Context:\n"); xhci_dbg(xhci, "Slot Context:\n");
...@@ -459,7 +460,7 @@ void xhci_dbg_ep_ctx(struct xhci_hcd *xhci, ...@@ -459,7 +460,7 @@ void xhci_dbg_ep_ctx(struct xhci_hcd *xhci,
for (i = 0; i < last_ep_ctx; ++i) { for (i = 0; i < last_ep_ctx; ++i) {
struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci, ctx, i); struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci, ctx, i);
dma_addr_t dma = ctx->dma + dma_addr_t dma = ctx->dma +
((unsigned long)ep_ctx - (unsigned long)ctx); ((unsigned long)ep_ctx - (unsigned long)ctx->bytes);
xhci_dbg(xhci, "Endpoint %02d Context:\n", i); xhci_dbg(xhci, "Endpoint %02d Context:\n", i);
xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info\n", xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info\n",
......
This diff is collapsed.
...@@ -94,6 +94,9 @@ static void xhci_link_segments(struct xhci_hcd *xhci, struct xhci_segment *prev, ...@@ -94,6 +94,9 @@ static void xhci_link_segments(struct xhci_hcd *xhci, struct xhci_segment *prev,
val = prev->trbs[TRBS_PER_SEGMENT-1].link.control; val = prev->trbs[TRBS_PER_SEGMENT-1].link.control;
val &= ~TRB_TYPE_BITMASK; val &= ~TRB_TYPE_BITMASK;
val |= TRB_TYPE(TRB_LINK); val |= TRB_TYPE(TRB_LINK);
/* Always set the chain bit with 0.95 hardware */
if (xhci_link_trb_quirk(xhci))
val |= TRB_CHAIN;
prev->trbs[TRBS_PER_SEGMENT-1].link.control = val; prev->trbs[TRBS_PER_SEGMENT-1].link.control = val;
} }
xhci_dbg(xhci, "Linking segment 0x%llx to segment 0x%llx (DMA)\n", xhci_dbg(xhci, "Linking segment 0x%llx to segment 0x%llx (DMA)\n",
...@@ -398,15 +401,28 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud ...@@ -398,15 +401,28 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
/* Step 5 */ /* Step 5 */
ep0_ctx->ep_info2 = EP_TYPE(CTRL_EP); ep0_ctx->ep_info2 = EP_TYPE(CTRL_EP);
/* /*
* See section 4.3 bullet 6:
* The default Max Packet size for ep0 is "8 bytes for a USB2
* LS/FS/HS device or 512 bytes for a USB3 SS device"
* XXX: Not sure about wireless USB devices. * XXX: Not sure about wireless USB devices.
*/ */
if (udev->speed == USB_SPEED_SUPER) switch (udev->speed) {
case USB_SPEED_SUPER:
ep0_ctx->ep_info2 |= MAX_PACKET(512); ep0_ctx->ep_info2 |= MAX_PACKET(512);
else break;
case USB_SPEED_HIGH:
/* USB core guesses at a 64-byte max packet first for FS devices */
case USB_SPEED_FULL:
ep0_ctx->ep_info2 |= MAX_PACKET(64);
break;
case USB_SPEED_LOW:
ep0_ctx->ep_info2 |= MAX_PACKET(8); ep0_ctx->ep_info2 |= MAX_PACKET(8);
break;
case USB_SPEED_VARIABLE:
xhci_dbg(xhci, "FIXME xHCI doesn't support wireless speeds\n");
return -EINVAL;
break;
default:
/* New speed? */
BUG();
}
/* EP 0 can handle "burst" sizes of 1, so Max Burst Size field is 0 */ /* EP 0 can handle "burst" sizes of 1, so Max Burst Size field is 0 */
ep0_ctx->ep_info2 |= MAX_BURST(0); ep0_ctx->ep_info2 |= MAX_BURST(0);
ep0_ctx->ep_info2 |= ERROR_COUNT(3); ep0_ctx->ep_info2 |= ERROR_COUNT(3);
...@@ -598,6 +614,44 @@ void xhci_endpoint_zero(struct xhci_hcd *xhci, ...@@ -598,6 +614,44 @@ void xhci_endpoint_zero(struct xhci_hcd *xhci,
*/ */
} }
/* Copy output xhci_ep_ctx to the input xhci_ep_ctx copy.
* Useful when you want to change one particular aspect of the endpoint and then
* issue a configure endpoint command.
*/
void xhci_endpoint_copy(struct xhci_hcd *xhci,
struct xhci_virt_device *vdev, unsigned int ep_index)
{
struct xhci_ep_ctx *out_ep_ctx;
struct xhci_ep_ctx *in_ep_ctx;
out_ep_ctx = xhci_get_ep_ctx(xhci, vdev->out_ctx, ep_index);
in_ep_ctx = xhci_get_ep_ctx(xhci, vdev->in_ctx, ep_index);
in_ep_ctx->ep_info = out_ep_ctx->ep_info;
in_ep_ctx->ep_info2 = out_ep_ctx->ep_info2;
in_ep_ctx->deq = out_ep_ctx->deq;
in_ep_ctx->tx_info = out_ep_ctx->tx_info;
}
/* Copy output xhci_slot_ctx to the input xhci_slot_ctx.
* Useful when you want to change one particular aspect of the endpoint and then
* issue a configure endpoint command. Only the context entries field matters,
* but we'll copy the whole thing anyway.
*/
void xhci_slot_copy(struct xhci_hcd *xhci, struct xhci_virt_device *vdev)
{
struct xhci_slot_ctx *in_slot_ctx;
struct xhci_slot_ctx *out_slot_ctx;
in_slot_ctx = xhci_get_slot_ctx(xhci, vdev->in_ctx);
out_slot_ctx = xhci_get_slot_ctx(xhci, vdev->out_ctx);
in_slot_ctx->dev_info = out_slot_ctx->dev_info;
in_slot_ctx->dev_info2 = out_slot_ctx->dev_info2;
in_slot_ctx->tt_info = out_slot_ctx->tt_info;
in_slot_ctx->dev_state = out_slot_ctx->dev_state;
}
/* Set up the scratchpad buffer array and scratchpad buffers, if needed. */ /* Set up the scratchpad buffer array and scratchpad buffers, if needed. */
static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags) static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags)
{ {
......
...@@ -24,6 +24,10 @@ ...@@ -24,6 +24,10 @@
#include "xhci.h" #include "xhci.h"
/* Device for a quirk */
#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73
#define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000
static const char hcd_name[] = "xhci_hcd"; static const char hcd_name[] = "xhci_hcd";
/* called after powerup, by probe or system-pm "wakeup" */ /* called after powerup, by probe or system-pm "wakeup" */
...@@ -62,6 +66,15 @@ static int xhci_pci_setup(struct usb_hcd *hcd) ...@@ -62,6 +66,15 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
xhci->hcc_params = xhci_readl(xhci, &xhci->cap_regs->hcc_params); xhci->hcc_params = xhci_readl(xhci, &xhci->cap_regs->hcc_params);
xhci_print_registers(xhci); xhci_print_registers(xhci);
/* Look for vendor-specific quirks */
if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK &&
pdev->revision == 0x0) {
xhci->quirks |= XHCI_RESET_EP_QUIRK;
xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure"
" endpoint cmd after reset endpoint\n");
}
/* Make sure the HC is halted. */ /* Make sure the HC is halted. */
retval = xhci_halt(xhci); retval = xhci_halt(xhci);
if (retval) if (retval)
......
This diff is collapsed.
...@@ -581,6 +581,7 @@ struct xhci_ep_ctx { ...@@ -581,6 +581,7 @@ struct xhci_ep_ctx {
/* bit 15 is Linear Stream Array */ /* bit 15 is Linear Stream Array */
/* Interval - period between requests to an endpoint - 125u increments. */ /* Interval - period between requests to an endpoint - 125u increments. */
#define EP_INTERVAL(p) ((p & 0xff) << 16) #define EP_INTERVAL(p) ((p & 0xff) << 16)
#define EP_INTERVAL_TO_UFRAMES(p) (1 << (((p) >> 16) & 0xff))
/* ep_info2 bitmasks */ /* ep_info2 bitmasks */
/* /*
...@@ -589,6 +590,7 @@ struct xhci_ep_ctx { ...@@ -589,6 +590,7 @@ struct xhci_ep_ctx {
*/ */
#define FORCE_EVENT (0x1) #define FORCE_EVENT (0x1)
#define ERROR_COUNT(p) (((p) & 0x3) << 1) #define ERROR_COUNT(p) (((p) & 0x3) << 1)
#define CTX_TO_EP_TYPE(p) (((p) >> 3) & 0x7)
#define EP_TYPE(p) ((p) << 3) #define EP_TYPE(p) ((p) << 3)
#define ISOC_OUT_EP 1 #define ISOC_OUT_EP 1
#define BULK_OUT_EP 2 #define BULK_OUT_EP 2
...@@ -601,6 +603,8 @@ struct xhci_ep_ctx { ...@@ -601,6 +603,8 @@ struct xhci_ep_ctx {
/* bit 7 is Host Initiate Disable - for disabling stream selection */ /* bit 7 is Host Initiate Disable - for disabling stream selection */
#define MAX_BURST(p) (((p)&0xff) << 8) #define MAX_BURST(p) (((p)&0xff) << 8)
#define MAX_PACKET(p) (((p)&0xffff) << 16) #define MAX_PACKET(p) (((p)&0xffff) << 16)
#define MAX_PACKET_MASK (0xffff << 16)
#define MAX_PACKET_DECODED(p) (((p) >> 16) & 0xffff)
/** /**
...@@ -926,6 +930,12 @@ struct xhci_td { ...@@ -926,6 +930,12 @@ struct xhci_td {
union xhci_trb *last_trb; union xhci_trb *last_trb;
}; };
struct xhci_dequeue_state {
struct xhci_segment *new_deq_seg;
union xhci_trb *new_deq_ptr;
int new_cycle_state;
};
struct xhci_ring { struct xhci_ring {
struct xhci_segment *first_seg; struct xhci_segment *first_seg;
union xhci_trb *enqueue; union xhci_trb *enqueue;
...@@ -952,12 +962,6 @@ struct xhci_ring { ...@@ -952,12 +962,6 @@ struct xhci_ring {
u32 cycle_state; u32 cycle_state;
}; };
struct xhci_dequeue_state {
struct xhci_segment *new_deq_seg;
union xhci_trb *new_deq_ptr;
int new_cycle_state;
};
struct xhci_erst_entry { struct xhci_erst_entry {
/* 64-bit event ring segment address */ /* 64-bit event ring segment address */
u64 seg_addr; u64 seg_addr;
...@@ -1058,6 +1062,9 @@ struct xhci_hcd { ...@@ -1058,6 +1062,9 @@ struct xhci_hcd {
int noops_submitted; int noops_submitted;
int noops_handled; int noops_handled;
int error_bitmask; int error_bitmask;
unsigned int quirks;
#define XHCI_LINK_TRB_QUIRK (1 << 0)
#define XHCI_RESET_EP_QUIRK (1 << 1)
}; };
/* For testing purposes */ /* For testing purposes */
...@@ -1136,6 +1143,13 @@ static inline void xhci_write_64(struct xhci_hcd *xhci, ...@@ -1136,6 +1143,13 @@ static inline void xhci_write_64(struct xhci_hcd *xhci,
writel(val_hi, ptr + 1); writel(val_hi, ptr + 1);
} }
static inline int xhci_link_trb_quirk(struct xhci_hcd *xhci)
{
u32 temp = xhci_readl(xhci, &xhci->cap_regs->hc_capbase);
return ((HC_VERSION(temp) == 0x95) &&
(xhci->quirks & XHCI_LINK_TRB_QUIRK));
}
/* xHCI debugging */ /* xHCI debugging */
void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int set_num); void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int set_num);
void xhci_print_registers(struct xhci_hcd *xhci); void xhci_print_registers(struct xhci_hcd *xhci);
...@@ -1158,7 +1172,12 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, struct usb_device ...@@ -1158,7 +1172,12 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, struct usb_device
int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev); int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev);
unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc); unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc);
unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc); unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc);
unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index);
unsigned int xhci_last_valid_endpoint(u32 added_ctxs);
void xhci_endpoint_zero(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, struct usb_host_endpoint *ep); void xhci_endpoint_zero(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, struct usb_host_endpoint *ep);
void xhci_endpoint_copy(struct xhci_hcd *xhci,
struct xhci_virt_device *vdev, unsigned int ep_index);
void xhci_slot_copy(struct xhci_hcd *xhci, struct xhci_virt_device *vdev);
int xhci_endpoint_init(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, int xhci_endpoint_init(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev,
struct usb_device *udev, struct usb_host_endpoint *ep, struct usb_device *udev, struct usb_host_endpoint *ep,
gfp_t mem_flags); gfp_t mem_flags);
...@@ -1205,8 +1224,12 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, ...@@ -1205,8 +1224,12 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb,
int slot_id, unsigned int ep_index); int slot_id, unsigned int ep_index);
int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb,
int slot_id, unsigned int ep_index); int slot_id, unsigned int ep_index);
int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb,
int slot_id, unsigned int ep_index);
int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
u32 slot_id); u32 slot_id);
int xhci_queue_evaluate_context(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
u32 slot_id);
int xhci_queue_reset_ep(struct xhci_hcd *xhci, int slot_id, int xhci_queue_reset_ep(struct xhci_hcd *xhci, int slot_id,
unsigned int ep_index); unsigned int ep_index);
void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
...@@ -1215,6 +1238,12 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, ...@@ -1215,6 +1238,12 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci, void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
struct xhci_ring *ep_ring, unsigned int slot_id, struct xhci_ring *ep_ring, unsigned int slot_id,
unsigned int ep_index, struct xhci_dequeue_state *deq_state); unsigned int ep_index, struct xhci_dequeue_state *deq_state);
void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
struct usb_device *udev,
unsigned int ep_index, struct xhci_ring *ep_ring);
void xhci_queue_config_ep_quirk(struct xhci_hcd *xhci,
unsigned int slot_id, unsigned int ep_index,
struct xhci_dequeue_state *deq_state);
/* xHCI roothub code */ /* xHCI roothub code */
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,
......
...@@ -175,6 +175,7 @@ static int usb_console_setup(struct console *co, char *options) ...@@ -175,6 +175,7 @@ static int usb_console_setup(struct console *co, char *options)
/* The console is special in terms of closing the device so /* The console is special in terms of closing the device so
* indicate this port is now acting as a system console. */ * indicate this port is now acting as a system console. */
port->console = 1; port->console = 1;
port->console_init_baud = baud;
retval = 0; retval = 0;
out: out:
......
...@@ -176,6 +176,9 @@ static struct usb_device_id id_table_combined [] = { ...@@ -176,6 +176,9 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) }, { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_OPENDCC_SNIFFER_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_OPENDCC_THROTTLE_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GATEWAY_PID) },
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_SPROG_II) }, { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) },
...@@ -702,6 +705,8 @@ static struct usb_device_id id_table_combined [] = { ...@@ -702,6 +705,8 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) },
{ USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID),
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) },
{ USB_DEVICE(FTDI_VID, HAMEG_HO870_PID) },
{ }, /* Optional parameter entry */ { }, /* Optional parameter entry */
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
......
...@@ -81,6 +81,9 @@ ...@@ -81,6 +81,9 @@
/* OpenDCC (www.opendcc.de) product id */ /* OpenDCC (www.opendcc.de) product id */
#define FTDI_OPENDCC_PID 0xBFD8 #define FTDI_OPENDCC_PID 0xBFD8
#define FTDI_OPENDCC_SNIFFER_PID 0xBFD9
#define FTDI_OPENDCC_THROTTLE_PID 0xBFDA
#define FTDI_OPENDCC_GATEWAY_PID 0xBFDB
/* Sprog II (Andrew Crosland's SprogII DCC interface) */ /* Sprog II (Andrew Crosland's SprogII DCC interface) */
#define FTDI_SPROG_II 0xF0C8 #define FTDI_SPROG_II 0xF0C8
...@@ -967,6 +970,12 @@ ...@@ -967,6 +970,12 @@
*/ */
#define MARVELL_OPENRD_PID 0x9e90 #define MARVELL_OPENRD_PID 0x9e90
/*
* Hameg HO820 and HO870 interface (using VID 0x0403)
*/
#define HAMEG_HO820_PID 0xed74
#define HAMEG_HO870_PID 0xed71
/* /*
* BmRequestType: 1100 0000b * BmRequestType: 1100 0000b
* bRequest: FTDI_E2_READ * bRequest: FTDI_E2_READ
......
...@@ -292,6 +292,7 @@ static int option_resume(struct usb_serial *serial); ...@@ -292,6 +292,7 @@ static int option_resume(struct usb_serial *serial);
#define TELIT_VENDOR_ID 0x1bc7 #define TELIT_VENDOR_ID 0x1bc7
#define TELIT_PRODUCT_UC864E 0x1003 #define TELIT_PRODUCT_UC864E 0x1003
#define TELIT_PRODUCT_UC864G 0x1004
/* ZTE PRODUCTS */ /* ZTE PRODUCTS */
#define ZTE_VENDOR_ID 0x19d2 #define ZTE_VENDOR_ID 0x19d2
...@@ -300,6 +301,7 @@ static int option_resume(struct usb_serial *serial); ...@@ -300,6 +301,7 @@ static int option_resume(struct usb_serial *serial);
#define ZTE_PRODUCT_MF626 0x0031 #define ZTE_PRODUCT_MF626 0x0031
#define ZTE_PRODUCT_CDMA_TECH 0xfffe #define ZTE_PRODUCT_CDMA_TECH 0xfffe
#define ZTE_PRODUCT_AC8710 0xfff1 #define ZTE_PRODUCT_AC8710 0xfff1
#define ZTE_PRODUCT_AC2726 0xfff5
#define BENQ_VENDOR_ID 0x04a5 #define BENQ_VENDOR_ID 0x04a5
#define BENQ_PRODUCT_H10 0x4068 #define BENQ_PRODUCT_H10 0x4068
...@@ -503,6 +505,7 @@ static struct usb_device_id option_ids[] = { ...@@ -503,6 +505,7 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
{ USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, { 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 */ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0003, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0003, 0xff, 0xff, 0xff) },
...@@ -572,6 +575,7 @@ static struct usb_device_id option_ids[] = { ...@@ -572,6 +575,7 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
{ USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
{ USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },
{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) },
......
...@@ -96,6 +96,7 @@ static struct usb_device_id id_table [] = { ...@@ -96,6 +96,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },
{ USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
{ USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
......
...@@ -130,3 +130,7 @@ ...@@ -130,3 +130,7 @@
/* Sony, USB data cable for CMD-Jxx mobile phones */ /* Sony, USB data cable for CMD-Jxx mobile phones */
#define SONY_VENDOR_ID 0x054c #define SONY_VENDOR_ID 0x054c
#define SONY_QN3USB_PRODUCT_ID 0x0437 #define SONY_QN3USB_PRODUCT_ID 0x0437
/* Sanwa KB-USB2 multimeter cable (ID: 11ad:0001) */
#define SANWA_VENDOR_ID 0x11ad
#define SANWA_PRODUCT_ID 0x0001
...@@ -223,8 +223,7 @@ static int serial_open (struct tty_struct *tty, struct file *filp) ...@@ -223,8 +223,7 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
tty->driver_data = port; tty->driver_data = port;
tty_port_tty_set(&port->port, tty); tty_port_tty_set(&port->port, tty);
/* If the console is attached, the device is already open */ if (port->port.count == 1) {
if (port->port.count == 1 && !port->console) {
first = 1; first = 1;
/* lock this module before we call it /* lock this module before we call it
* this may fail, which means we must bail out, * this may fail, which means we must bail out,
...@@ -242,11 +241,17 @@ static int serial_open (struct tty_struct *tty, struct file *filp) ...@@ -242,11 +241,17 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
if (retval) if (retval)
goto bailout_module_put; goto bailout_module_put;
/* only call the device specific open if this /* only call the device specific open if this is the
* is the first time the port is opened */ * first time the port is opened and it is not a
* console port where the HW has already been
* initialized */
if (port->console) {
tty_encode_baud_rate(tty, port->console_init_baud, port->console_init_baud);
} else {
retval = serial->type->open(tty, port, filp); retval = serial->type->open(tty, port, filp);
if (retval) if (retval)
goto bailout_interface_put; goto bailout_interface_put;
}
mutex_unlock(&serial->disc_mutex); mutex_unlock(&serial->disc_mutex);
set_bit(ASYNCB_INITIALIZED, &port->port.flags); set_bit(ASYNCB_INITIALIZED, &port->port.flags);
} }
......
...@@ -163,7 +163,7 @@ static void usb_onetouch_pm_hook(struct us_data *us, int action) ...@@ -163,7 +163,7 @@ static void usb_onetouch_pm_hook(struct us_data *us, int action)
usb_kill_urb(onetouch->irq); usb_kill_urb(onetouch->irq);
break; break;
case US_RESUME: case US_RESUME:
if (usb_submit_urb(onetouch->irq, GFP_KERNEL) != 0) if (usb_submit_urb(onetouch->irq, GFP_NOIO) != 0)
dev_err(&onetouch->irq->dev->dev, dev_err(&onetouch->irq->dev->dev,
"usb_submit_urb failed\n"); "usb_submit_urb failed\n");
break; break;
......
...@@ -107,6 +107,7 @@ struct usb_serial_port { ...@@ -107,6 +107,7 @@ struct usb_serial_port {
char throttled; char throttled;
char throttle_req; char throttle_req;
char console; char console;
int console_init_baud;
unsigned long sysrq; /* sysrq timeout */ unsigned long sysrq; /* sysrq timeout */
struct device dev; struct device dev;
enum port_dev_state dev_state; enum port_dev_state dev_state;
......
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