From b41709f1263bb1ad37efc43fea0bb0b670c12e78 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 19 May 2010 22:13:17 +0200 Subject: [PATCH 01/15] USB: mos7840: fix null-pointer dereference Fix null-pointer dereference on error path. Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mos7840.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index f8424d1bfc1b..585b7e663740 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -730,7 +730,6 @@ static void mos7840_bulk_in_callback(struct urb *urb) mos7840_port = urb->context; if (!mos7840_port) { dbg("%s", "NULL mos7840_port pointer"); - mos7840_port->read_urb_busy = false; return; } From 0c8a32dff4f9ebed3e067e52e12842d7d7e047a0 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 21 May 2010 04:37:42 -0400 Subject: [PATCH 02/15] USB: isp1362: fix inw warning on Blackfin systems The Blackfin code is incorrectly casting the argument to inw() to a pointer. Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp1362.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/isp1362.h b/drivers/usb/host/isp1362.h index 5151516ea1de..d995351f9bed 100644 --- a/drivers/usb/host/isp1362.h +++ b/drivers/usb/host/isp1362.h @@ -65,7 +65,7 @@ static inline void delayed_insw(unsigned int addr, void *buf, int len) unsigned short *bp = (unsigned short *)buf; while (len--) { DUMMY_DELAY_ACCESS; - *bp++ = inw((void *)addr); + *bp++ = inw(addr); } } From 2d62f3eea98354d61f90d6b115eecf9be5f4bdfe Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Mon, 24 May 2010 13:25:15 -0700 Subject: [PATCH 03/15] USB: xhci: Wait for controller to be ready after reset. After software resets an xHCI host controller, it must wait for the "Controller Not Ready" (CNR) bit in the status register to be cleared. Software is not supposed to ring any doorbells or write to any registers except the status register until this bit is cleared. Signed-off-by: Sarah Sharp Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 40e0a0c221b8..79ccfe5f8ad0 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -116,6 +116,7 @@ int xhci_reset(struct xhci_hcd *xhci) { u32 command; u32 state; + int ret; state = xhci_readl(xhci, &xhci->op_regs->status); if ((state & STS_HALT) == 0) { @@ -130,7 +131,17 @@ int xhci_reset(struct xhci_hcd *xhci) /* 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); + ret = handshake(xhci, &xhci->op_regs->command, + CMD_RESET, 0, 250 * 1000); + if (ret) + return ret; + + xhci_dbg(xhci, "Wait for controller to be ready for doorbell rings\n"); + /* + * xHCI cannot write to any doorbells or operational registers other + * than status until the "Controller Not Ready" flag is cleared. + */ + return handshake(xhci, &xhci->op_regs->status, STS_CNR, 0, 250 * 1000); } From ed07453fd356025cc25272629e982f5e4607632c Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Mon, 24 May 2010 13:25:21 -0700 Subject: [PATCH 04/15] USB: xhci: Wait for host to start running. When the run bit is set in the xHCI command register, it may take a few microseconds for the host to start running. We cannot ring any doorbells until the host is actually running, so wait until the status register says the host is running. Signed-off-by: Sarah Sharp Reported-by: Shinya Saito Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 79ccfe5f8ad0..8a49c6716b69 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -105,6 +105,33 @@ int xhci_halt(struct xhci_hcd *xhci) STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); } +/* + * Set the run bit and wait for the host to be running. + */ +int xhci_start(struct xhci_hcd *xhci) +{ + u32 temp; + int ret; + + 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); + + /* + * Wait for the HCHalted Status bit to be 0 to indicate the host is + * running. + */ + ret = handshake(xhci, &xhci->op_regs->status, + STS_HALT, 0, XHCI_MAX_HALT_USEC); + if (ret == -ETIMEDOUT) + xhci_err(xhci, "Host took too long to start, " + "waited %u microseconds.\n", + XHCI_MAX_HALT_USEC); + return ret; +} + /* * Reset a halted HC, and set the internal HC state to HC_STATE_HALT. * @@ -460,13 +487,11 @@ int xhci_run(struct usb_hcd *hcd) 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); + if (xhci_start(xhci)) { + xhci_halt(xhci); + return -ENODEV; + } + xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp); if (doorbell) (*doorbell)(xhci); From 0238634d02dd10b678ebe9ea5d8803483277ee93 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Mon, 24 May 2010 13:25:28 -0700 Subject: [PATCH 05/15] USB: xhci: Print NEC firmware version. The NEC xHCI host controller firmware version can be found by putting a vendor-specific command on the command ring and extracting the BCD encoded-version out of the vendor-specific event TRB. The firmware version debug line in dmesg will look like: xhci_hcd 0000:05:00.0: NEC firmware version 30.21 (NEC merged with Renesas Technologies and became Renesas Electronics on April 1, 2010. I have their OK to merge this vendor-specific code.) Signed-off-by: Sarah Sharp Cc: Satoshi Otani Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 2 ++ drivers/usb/host/xhci-ring.c | 31 ++++++++++++++++++++++++++++++- drivers/usb/host/xhci.c | 5 +++++ drivers/usb/host/xhci.h | 12 ++++++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index edffd81fc253..11482b6b9381 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -78,6 +78,8 @@ static int xhci_pci_setup(struct usb_hcd *hcd) xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure" " endpoint cmd after reset endpoint\n"); } + if (pdev->vendor == PCI_VENDOR_ID_NEC) + xhci->quirks |= XHCI_NEC_HOST; /* Make sure the HC is halted. */ retval = xhci_halt(xhci); diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 36c858e5b529..9012098add6b 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1071,6 +1071,15 @@ bandwidth_change: xhci_warn(xhci, "Reset device command completion " "for disabled slot %u\n", slot_id); break; + case TRB_TYPE(TRB_NEC_GET_FW): + if (!(xhci->quirks & XHCI_NEC_HOST)) { + xhci->error_bitmask |= 1 << 6; + break; + } + xhci_dbg(xhci, "NEC firmware version %2x.%02x\n", + NEC_FW_MAJOR(event->status), + NEC_FW_MINOR(event->status)); + break; default: /* Skip over unknown commands on the event ring */ xhci->error_bitmask |= 1 << 6; @@ -1079,6 +1088,17 @@ bandwidth_change: inc_deq(xhci, xhci->cmd_ring, false); } +static void handle_vendor_event(struct xhci_hcd *xhci, + union xhci_trb *event) +{ + u32 trb_type; + + trb_type = TRB_FIELD_TO_TYPE(event->generic.field[3]); + xhci_dbg(xhci, "Vendor specific event TRB type = %u\n", trb_type); + if (trb_type == TRB_NEC_CMD_COMP && (xhci->quirks & XHCI_NEC_HOST)) + handle_cmd_completion(xhci, &event->event_cmd); +} + static void handle_port_status(struct xhci_hcd *xhci, union xhci_trb *event) { @@ -1659,7 +1679,10 @@ void xhci_handle_event(struct xhci_hcd *xhci) update_ptrs = 0; break; default: - xhci->error_bitmask |= 1 << 3; + if ((event->event_cmd.flags & TRB_TYPE_BITMASK) >= TRB_TYPE(48)) + handle_vendor_event(xhci, event); + else + xhci->error_bitmask |= 1 << 3; } /* Any of the above functions may drop and re-acquire the lock, so check * to make sure a watchdog timer didn't mark the host as non-responsive. @@ -2378,6 +2401,12 @@ int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, false); } +int xhci_queue_vendor_command(struct xhci_hcd *xhci, + u32 field1, u32 field2, u32 field3, u32 field4) +{ + return queue_command(xhci, field1, field2, field3, field4, false); +} + /* Queue a reset device command TRB */ int xhci_queue_reset_device(struct xhci_hcd *xhci, u32 slot_id) { diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 8a49c6716b69..27345cd04da0 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -486,6 +486,9 @@ int xhci_run(struct usb_hcd *hcd) if (NUM_TEST_NOOPS > 0) doorbell = xhci_setup_one_noop(xhci); + if (xhci->quirks & XHCI_NEC_HOST) + xhci_queue_vendor_command(xhci, 0, 0, 0, + TRB_TYPE(TRB_NEC_GET_FW)); if (xhci_start(xhci)) { xhci_halt(xhci); @@ -495,6 +498,8 @@ int xhci_run(struct usb_hcd *hcd) xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp); if (doorbell) (*doorbell)(xhci); + if (xhci->quirks & XHCI_NEC_HOST) + xhci_ring_cmd_db(xhci); xhci_dbg(xhci, "Finished xhci_run\n"); return 0; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index dada2fb59261..8b4b7d39f79c 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -925,6 +925,7 @@ union xhci_trb { /* TRB bit mask */ #define TRB_TYPE_BITMASK (0xfc00) #define TRB_TYPE(p) ((p) << 10) +#define TRB_FIELD_TO_TYPE(p) (((p) & TRB_TYPE_BITMASK) >> 10) /* TRB type IDs */ /* bulk, interrupt, isoc scatter/gather, and control data stage */ #define TRB_NORMAL 1 @@ -992,6 +993,14 @@ union xhci_trb { #define TRB_MFINDEX_WRAP 39 /* TRB IDs 40-47 reserved, 48-63 is vendor-defined */ +/* Nec vendor-specific command completion event. */ +#define TRB_NEC_CMD_COMP 48 +/* Get NEC firmware revision. */ +#define TRB_NEC_GET_FW 49 + +#define NEC_FW_MINOR(p) (((p) >> 0) & 0xff) +#define NEC_FW_MAJOR(p) (((p) >> 8) & 0xff) + /* * TRBS_PER_SEGMENT must be a multiple of 4, * since the command ring is 64-byte aligned. @@ -1172,6 +1181,7 @@ struct xhci_hcd { unsigned int quirks; #define XHCI_LINK_TRB_QUIRK (1 << 0) #define XHCI_RESET_EP_QUIRK (1 << 1) +#define XHCI_NEC_HOST (1 << 2) }; /* For testing purposes */ @@ -1379,6 +1389,8 @@ void xhci_set_hc_event_deq(struct xhci_hcd *xhci); int xhci_queue_slot_control(struct xhci_hcd *xhci, u32 trb_type, u32 slot_id); int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, u32 slot_id); +int xhci_queue_vendor_command(struct xhci_hcd *xhci, + u32 field1, u32 field2, u32 field3, u32 field4); int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id, unsigned int ep_index); int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, From 390b166138e95a47bdfde6582a1935f65e5c6547 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 24 May 2010 17:48:56 +0900 Subject: [PATCH 06/15] USB: s3c: Enable soft disconnect during initialization Enable soft disconnect bit the OTG core during initialization. Without this, the host sees that a gadget is connected and tries to enumerate. The soft disconnect should be enabled until the USB gadget driver is registered with this otg driver. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/s3c-hsotg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 1f73b485732d..a6d725dd7335 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -2730,6 +2730,9 @@ static void s3c_hsotg_init(struct s3c_hsotg *hsotg) writel(0, hsotg->regs + S3C_DAINTMSK); + /* Be in disconnected state until gadget is registered */ + __orr32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon); + if (0) { /* post global nak until we're ready */ writel(S3C_DCTL_SGNPInNAK | S3C_DCTL_SGOUTNak, From 0287e43dda1a425da662f879dd27352021b0ca63 Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Tue, 25 May 2010 05:36:49 +0100 Subject: [PATCH 07/15] USB: s3c_hsotg: define USB_GADGET_DUALSPEED in Kconfig The s3c_hsotg driver sets usb_gadget->is_dualspeed to 1, yet it doesn't define USB_GADGET_DUALSPEED in Kconfig. This triggers a NULL pointer dereference in the composite driver (which is fixed in another patch). Signed-off-by: Maurus Cuelenaere Signed-off-by: Ben Dooks Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 649c0c5f7158..591ae9fde199 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -295,6 +295,7 @@ config USB_GADGET_S3C_HSOTG boolean "S3C HS/OtG USB Device controller" depends on S3C_DEV_USB_HSOTG select USB_GADGET_S3C_HSOTG_PIO + select USB_GADGET_DUALSPEED help The Samsung S3C64XX USB2.0 high-speed gadget controller integrated into the S3C64XX series SoC. From 0f002d200598918f5058dfcfda3da46f29019765 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 25 May 2010 05:36:50 +0100 Subject: [PATCH 08/15] USB: s3c-hsotg: Ensure TX FIFO addresses setup when initialising FIFOs Some versions of the S3C HS OtG block startup with overlapping TX FIFO information, so change the fifo_init code to ensure that known values are set into the FIFO registers at initialisation/reset time. This also ensures that the FIFO RAM pointers are in a known state before use. Signed-off-by: Ben Dooks Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/s3c-hsotg.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index a6d725dd7335..9abf96c5715d 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -297,6 +297,11 @@ static void s3c_hsotg_ctrl_epint(struct s3c_hsotg *hsotg, */ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg) { + unsigned int ep; + unsigned int addr; + unsigned int size; + u32 val; + /* the ryu 2.6.24 release ahs writel(0x1C0, hsotg->regs + S3C_GRXFSIZ); writel(S3C_GNPTXFSIZ_NPTxFStAddr(0x200) | @@ -310,6 +315,26 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg) writel(S3C_GNPTXFSIZ_NPTxFStAddr(2048) | S3C_GNPTXFSIZ_NPTxFDep(0x1C0), hsotg->regs + S3C_GNPTXFSIZ); + + /* arange all the rest of the TX FIFOs, as some versions of this + * block have overlapping default addresses. This also ensures + * that if the settings have been changed, then they are set to + * known values. */ + + /* start at the end of the GNPTXFSIZ, rounded up */ + addr = 2048 + 1024; + size = 768; + + /* currently we allocate TX FIFOs for all possible endpoints, + * and assume that they are all the same size. */ + + for (ep = 0; ep <= 15; ep++) { + val = addr; + val |= size << S3C_DPTXFSIZn_DPTxFSize_SHIFT; + addr += size; + + writel(val, hsotg->regs + S3C_DPTXFSIZn(ep)); + } } /** From 2e0e0777ec2ea1cb5461bded2c09573a9d778622 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 25 May 2010 05:36:51 +0100 Subject: [PATCH 09/15] USB: s3c-hsotg: SoftDisconnect minimum 3ms The shortest period SoftDisconnect can be asserted for is 3 milliseconds according to the V210 datasheet, so ensure that we add an msleep() to the registration code to enforce this. Signed-off-by: Ben Dooks Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/s3c-hsotg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 9abf96c5715d..31d19e1f261d 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -2599,6 +2599,9 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) writel(S3C_DCTL_CGOUTNak | S3C_DCTL_CGNPInNAK, hsotg->regs + S3C_DCTL); + /* must be at-least 3ms to allow bus to see disconnect */ + msleep(3); + /* remove the soft-disconnect and let's go */ __bic32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon); From 1703a6d3c38944731ba23594843a704d828266f3 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 25 May 2010 05:36:52 +0100 Subject: [PATCH 10/15] USB: s3c-hsotg: Ensure FIFOs are fully flushed after layout According to the design guide, if the FIFO layout is changed, then the FIFOs must be flushed to ensure all FIFO pointers are correct. Signed-off-by: Ben Dooks Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/s3c-hsotg.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 31d19e1f261d..26193eceb323 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -300,6 +300,7 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg) unsigned int ep; unsigned int addr; unsigned int size; + int timeout; u32 val; /* the ryu 2.6.24 release ahs @@ -335,6 +336,31 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg) writel(val, hsotg->regs + S3C_DPTXFSIZn(ep)); } + + /* according to p428 of the design guide, we need to ensure that + * all fifos are flushed before continuing */ + + writel(S3C_GRSTCTL_TxFNum(0x10) | S3C_GRSTCTL_TxFFlsh | + S3C_GRSTCTL_RxFFlsh, hsotg->regs + S3C_GRSTCTL); + + /* wait until the fifos are both flushed */ + timeout = 100; + while (1) { + val = readl(hsotg->regs + S3C_GRSTCTL); + + if ((val & (S3C_GRSTCTL_TxFFlsh | S3C_GRSTCTL_RxFFlsh)) == 0) + break; + + if (--timeout == 0) { + dev_err(hsotg->dev, + "%s: timeout flushing fifos (GRSTCTL=%08x)\n", + __func__, val); + } + + udelay(1); + } + + dev_dbg(hsotg->dev, "FIFOs reset, timeout at %d\n", timeout); } /** From 6a1a82df91fa0eb1cc76069a9efe5714d087eccd Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 3 Jun 2010 13:55:02 +0200 Subject: [PATCH 11/15] USB: ftdi_sio: fix DTR/RTS line modes Call set_mctrl() and clear_mctrl() according to the flow control mode selected. This makes serial communication for FT232 connected devices work when CRTSCTS is not set. This fixes a regression introduced by 4175f3e31 ("tty_port: If we are opened non blocking we still need to raise the carrier"). This patch calls the low-level driver's dtr_rts() function which consequently sets TIOCM_DTR | TIOCM_RTS. A later call to set_termios() without CRTSCTS in cflags, however, does not reset these bits, and so data is not actually sent out on the serial wire. Signed-off-by: Daniel Mack Cc: Johan Hovold Cc: Alan Cox Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 050211afc07e..79dd1ae195e5 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -2005,6 +2005,8 @@ static void ftdi_set_termios(struct tty_struct *tty, "urb failed to set to rts/cts flow control\n"); } + /* raise DTR/RTS */ + set_mctrl(port, TIOCM_DTR | TIOCM_RTS); } else { /* * Xon/Xoff code @@ -2052,6 +2054,8 @@ static void ftdi_set_termios(struct tty_struct *tty, } } + /* lower DTR/RTS */ + clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); } return; } From c2572b78aa0447244a38e555ebb1b3b48a0088a5 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 31 May 2010 08:04:47 +0800 Subject: [PATCH 12/15] USB: cdc-acm: fix resource reclaim in error path of acm_probe This patch fixes resource reclaim in error path of acm_probe: 1. In the case of "out of memory (read urbs usb_alloc_urb)\n")", there is no need to call acm_read_buffers_free(acm) here. Fix it by goto alloc_fail6 instead of alloc_fail7. 2. In the case of "out of memory (write urbs usb_alloc_urb)", usb_alloc_urb may fail in any iteration of the for loop. Current implementation does not properly free allocated snd->urb. Fix it by goto alloc_fail8 instead of alloc_fail7. 3. In the case of device_create_file(&intf->dev,&dev_attr_iCountryCodeRelDate) fail, acm->country_codes is kfreed. As a result, device_remove_file for dev_attr_wCountryCodes will not be executed in acm_disconnect. Fix it by calling device_remove_file for dev_attr_wCountryCodes before goto skip_countries. Signed-off-by: Axel Lin Acked-by: Oliver Neukum Cc: stable Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 0c2f14ff9696..61d75507d5d0 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1201,7 +1201,7 @@ made_compressed_probe: if (rcv->urb == NULL) { dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n"); - goto alloc_fail7; + goto alloc_fail6; } rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; @@ -1225,7 +1225,7 @@ made_compressed_probe: if (snd->urb == NULL) { dev_dbg(&intf->dev, "out of memory (write urbs usb_alloc_urb)"); - goto alloc_fail7; + goto alloc_fail8; } if (usb_endpoint_xfer_int(epwrite)) @@ -1264,6 +1264,7 @@ made_compressed_probe: i = device_create_file(&intf->dev, &dev_attr_iCountryCodeRelDate); if (i < 0) { + device_remove_file(&intf->dev, &dev_attr_wCountryCodes); kfree(acm->country_codes); goto skip_countries; } @@ -1300,6 +1301,7 @@ alloc_fail8: usb_free_urb(acm->wb[i].urb); alloc_fail7: acm_read_buffers_free(acm); +alloc_fail6: for (i = 0; i < num_rx_buf; i++) usb_free_urb(acm->ru[i].urb); usb_free_urb(acm->ctrlurb); From 1f23b2d98c11fed43c552a5dbd00c793f81a8736 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 2 Jun 2010 13:53:17 -0600 Subject: [PATCH 13/15] usb: fix ehci_hcd build failure when both generic-OF and xilinx is selected This patch fixes the driver to allow both CONFIG_USB_EHCI_HCD_PPC_OF and CONFIG_USB_ECHI_HCD_XILINX to be selected. Signed-off-by: Grant Likely CC: John Linn CC: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index ef3e88f0b3c3..a3ef2a9d9dc2 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1135,7 +1135,7 @@ MODULE_LICENSE ("GPL"); #ifdef CONFIG_XPS_USB_HCD_XILINX #include "ehci-xilinx-of.c" -#define OF_PLATFORM_DRIVER ehci_hcd_xilinx_of_driver +#define XILINX_OF_PLATFORM_DRIVER ehci_hcd_xilinx_of_driver #endif #ifdef CONFIG_PLAT_ORION @@ -1159,7 +1159,8 @@ MODULE_LICENSE ("GPL"); #endif #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ - !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) + !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ + !defined(XILINX_OF_PLATFORM_DRIVER) #error "missing bus glue for ehci-hcd" #endif @@ -1213,10 +1214,20 @@ static int __init ehci_hcd_init(void) if (retval < 0) goto clean3; #endif + +#ifdef XILINX_OF_PLATFORM_DRIVER + retval = of_register_platform_driver(&XILINX_OF_PLATFORM_DRIVER); + if (retval < 0) + goto clean4; +#endif return retval; +#ifdef XILINX_OF_PLATFORM_DRIVER + /* of_unregister_platform_driver(&XILINX_OF_PLATFORM_DRIVER); */ +clean4: +#endif #ifdef OF_PLATFORM_DRIVER - /* of_unregister_platform_driver(&OF_PLATFORM_DRIVER); */ + of_unregister_platform_driver(&OF_PLATFORM_DRIVER); clean3: #endif #ifdef PS3_SYSTEM_BUS_DRIVER @@ -1243,6 +1254,9 @@ module_init(ehci_hcd_init); static void __exit ehci_hcd_cleanup(void) { +#ifdef XILINX_OF_PLATFORM_DRIVER + of_unregister_platform_driver(&XILINX_OF_PLATFORM_DRIVER); +#endif #ifdef OF_PLATFORM_DRIVER of_unregister_platform_driver(&OF_PLATFORM_DRIVER); #endif From 109f34e71b9049a57f6cdf3f1da6bee2b722b259 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 27 May 2010 14:32:09 +0200 Subject: [PATCH 14/15] USB: serial: digi_acceleport: Eliminate a NULL pointer dereference If port is NULL, then the call to dev_err will dereference a value that is a small offset from NULL. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r exists@ expression E,E1; identifier f; statement S1,S2,S3; @@ if ((E == NULL && ...) || ...) { ... when != if (...) S1 else S2 when != E = E1 * E->f ... when any return ...; } else S3 // Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/digi_acceleport.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 3edda3ed822a..fd35f73b5721 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -1239,8 +1239,7 @@ static void digi_write_bulk_callback(struct urb *urb) /* port and serial sanity check */ if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) { - dev_err(&port->dev, - "%s: port or port->private is NULL, status=%d\n", + pr_err("%s: port or port->private is NULL, status=%d\n", __func__, status); return; } From c043f1245654a726925529007210e9f786426448 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 4 Jun 2010 14:02:42 -0400 Subject: [PATCH 15/15] USB: unbind all interfaces before rebinding them MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch (as1387) fixes a bug introduced during the changeover to the runtime PM framework. When a driver doesn't support resume or reset-resume, and consequently its interfaces need to be unbound and rebound, we have to unbind all the interfaces before trying to rebind any of them. Otherwise the driver's probe method for one interface could try to claim a different interface and fail, because that other interface hasn't been unbound yet. This fixes Bugzilla #15788. The symptom is that some USB sound cards don't work after hibernation. Signed-off-by: Alan Stern Tested-by: François Valenduc Cc: stable [.34] Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index ded550eda5d9..de98a94d1853 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1328,6 +1328,7 @@ int usb_resume(struct device *dev, pm_message_t msg) /* For all other calls, take the device back to full power and * tell the PM core in case it was autosuspended previously. + * Unbind the interfaces that will need rebinding later. */ } else { status = usb_resume_both(udev, msg); @@ -1336,6 +1337,7 @@ int usb_resume(struct device *dev, pm_message_t msg) pm_runtime_set_active(dev); pm_runtime_enable(dev); udev->last_busy = jiffies; + do_unbind_rebind(udev, DO_REBIND); } }