Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
Browse files Browse the repository at this point in the history
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6:
  USB: Add support for Mobilcom Debitel USB UMTS Surf-Stick to option driver
  USB: work around for EHCI with quirky periodic schedules
  USB: musb: Fix CPPI IRQs not being signaled
  USB: musb: respect usb_request->zero in control requests
  USB: musb: fix ISOC Tx programming for CPPI DMAs
  USB: musb: Remove unwanted message in boot log
  usb: amd5536udc: fixed shared interrupt bug and warning oops
  USB: ftdi_sio: Keep going when write errors are encountered.
  USB: musb_gadget: fix STALL handling
  USB: EHCI: don't send Clear-TT-Buffer following a STALL
  • Loading branch information
torvalds committed Dec 1, 2009
2 parents e8ed34c + 0ec8648 commit e272a18
Show file tree
Hide file tree
Showing 14 changed files with 118 additions and 78 deletions.
2 changes: 1 addition & 1 deletion drivers/usb/core/hub.c
Expand Up @@ -444,7 +444,7 @@ static void hub_irq(struct urb *urb)
static inline int
hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt)
{
return usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
HUB_CLEAR_TT_BUFFER, USB_RT_PORT, devinfo,
tt, NULL, 0, 1000);
}
Expand Down
49 changes: 30 additions & 19 deletions drivers/usb/gadget/amd5536udc.c
Expand Up @@ -1213,7 +1213,12 @@ udc_queue(struct usb_ep *usbep, struct usb_request *usbreq, gfp_t gfp)
tmp &= AMD_UNMASK_BIT(ep->num);
writel(tmp, &dev->regs->ep_irqmsk);
}
}
} else if (ep->in) {
/* enable ep irq */
tmp = readl(&dev->regs->ep_irqmsk);
tmp &= AMD_UNMASK_BIT(ep->num);
writel(tmp, &dev->regs->ep_irqmsk);
}

} else if (ep->dma) {

Expand Down Expand Up @@ -2005,18 +2010,17 @@ __acquires(dev->lock)
{
int tmp;

/* empty queues and init hardware */
udc_basic_init(dev);
for (tmp = 0; tmp < UDC_EP_NUM; tmp++) {
empty_req_queue(&dev->ep[tmp]);
}

if (dev->gadget.speed != USB_SPEED_UNKNOWN) {
spin_unlock(&dev->lock);
driver->disconnect(&dev->gadget);
spin_lock(&dev->lock);
}
/* init */

/* empty queues and init hardware */
udc_basic_init(dev);
for (tmp = 0; tmp < UDC_EP_NUM; tmp++)
empty_req_queue(&dev->ep[tmp]);

udc_setup_endpoints(dev);
}

Expand Down Expand Up @@ -2472,6 +2476,13 @@ static irqreturn_t udc_data_in_isr(struct udc *dev, int ep_ix)
}
}

} else if (!use_dma && ep->in) {
/* disable interrupt */
tmp = readl(
&dev->regs->ep_irqmsk);
tmp |= AMD_BIT(ep->num);
writel(tmp,
&dev->regs->ep_irqmsk);
}
}
/* clear status bits */
Expand Down Expand Up @@ -3279,6 +3290,17 @@ static int udc_pci_probe(
goto finished;
}

spin_lock_init(&dev->lock);
/* udc csr registers base */
dev->csr = dev->virt_addr + UDC_CSR_ADDR;
/* dev registers base */
dev->regs = dev->virt_addr + UDC_DEVCFG_ADDR;
/* ep registers base */
dev->ep_regs = dev->virt_addr + UDC_EPREGS_ADDR;
/* fifo's base */
dev->rxfifo = (u32 __iomem *)(dev->virt_addr + UDC_RXFIFO_ADDR);
dev->txfifo = (u32 __iomem *)(dev->virt_addr + UDC_TXFIFO_ADDR);

if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) {
dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq);
kfree(dev);
Expand Down Expand Up @@ -3331,7 +3353,6 @@ static int udc_probe(struct udc *dev)
udc_pollstall_timer.data = 0;

/* device struct setup */
spin_lock_init(&dev->lock);
dev->gadget.ops = &udc_ops;

dev_set_name(&dev->gadget.dev, "gadget");
Expand All @@ -3340,16 +3361,6 @@ static int udc_probe(struct udc *dev)
dev->gadget.name = name;
dev->gadget.is_dualspeed = 1;

/* udc csr registers base */
dev->csr = dev->virt_addr + UDC_CSR_ADDR;
/* dev registers base */
dev->regs = dev->virt_addr + UDC_DEVCFG_ADDR;
/* ep registers base */
dev->ep_regs = dev->virt_addr + UDC_EPREGS_ADDR;
/* fifo's base */
dev->rxfifo = (u32 __iomem *)(dev->virt_addr + UDC_RXFIFO_ADDR);
dev->txfifo = (u32 __iomem *)(dev->virt_addr + UDC_TXFIFO_ADDR);

/* init registers, interrupts, ... */
startup_registers(dev);

Expand Down
2 changes: 2 additions & 0 deletions drivers/usb/host/ehci-hcd.c
Expand Up @@ -28,6 +28,7 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/ktime.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/usb.h>
Expand Down Expand Up @@ -676,6 +677,7 @@ static int ehci_run (struct usb_hcd *hcd)
ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
msleep(5);
up_write(&ehci_cf_port_reset_rwsem);
ehci->last_periodic_enable = ktime_get_real();

temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
ehci_info (ehci,
Expand Down
4 changes: 4 additions & 0 deletions drivers/usb/host/ehci-pci.c
Expand Up @@ -111,6 +111,10 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
switch (pdev->vendor) {
case PCI_VENDOR_ID_INTEL:
ehci->need_io_watchdog = 0;
if (pdev->device == 0x27cc) {
ehci->broken_periodic = 1;
ehci_info(ehci, "using broken periodic workaround\n");
}
break;
case PCI_VENDOR_ID_TDI:
if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
Expand Down
16 changes: 14 additions & 2 deletions drivers/usb/host/ehci-q.c
Expand Up @@ -487,8 +487,20 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
* we must clear the TT buffer (11.17.5).
*/
if (unlikely(last_status != -EINPROGRESS &&
last_status != -EREMOTEIO))
ehci_clear_tt_buffer(ehci, qh, urb, token);
last_status != -EREMOTEIO)) {
/* The TT's in some hubs malfunction when they
* receive this request following a STALL (they
* stop sending isochronous packets). Since a
* STALL can't leave the TT buffer in a busy
* state (if you believe Figures 11-48 - 11-51
* in the USB 2.0 spec), we won't clear the TT
* buffer in this case. Strictly speaking this
* is a violation of the spec.
*/
if (last_status != -EPIPE)
ehci_clear_tt_buffer(ehci, qh, urb,
token);
}
}

/* if we're removing something not at the queue head,
Expand Down
12 changes: 12 additions & 0 deletions drivers/usb/host/ehci-sched.c
Expand Up @@ -475,6 +475,8 @@ static int enable_periodic (struct ehci_hcd *ehci)
/* make sure ehci_work scans these */
ehci->next_uframe = ehci_readl(ehci, &ehci->regs->frame_index)
% (ehci->periodic_size << 3);
if (unlikely(ehci->broken_periodic))
ehci->last_periodic_enable = ktime_get_real();
return 0;
}

Expand All @@ -486,6 +488,16 @@ static int disable_periodic (struct ehci_hcd *ehci)
if (--ehci->periodic_sched)
return 0;

if (unlikely(ehci->broken_periodic)) {
/* delay experimentally determined */
ktime_t safe = ktime_add_us(ehci->last_periodic_enable, 1000);
ktime_t now = ktime_get_real();
s64 delay = ktime_us_delta(safe, now);

if (unlikely(delay > 0))
udelay(delay);
}

/* did setting PSE not take effect yet?
* takes effect only at frame boundaries...
*/
Expand Down
2 changes: 2 additions & 0 deletions drivers/usb/host/ehci.h
Expand Up @@ -118,6 +118,7 @@ struct ehci_hcd { /* one per controller */
unsigned stamp;
unsigned random_frame;
unsigned long next_statechange;
ktime_t last_periodic_enable;
u32 command;

/* SILICON QUIRKS */
Expand All @@ -127,6 +128,7 @@ struct ehci_hcd { /* one per controller */
unsigned big_endian_desc:1;
unsigned has_amcc_usb23:1;
unsigned need_io_watchdog:1;
unsigned broken_periodic:1;

/* required for usb32 quirk */
#define OHCI_CTRL_HCFS (3 << 6)
Expand Down
10 changes: 5 additions & 5 deletions drivers/usb/musb/cppi_dma.c
Expand Up @@ -1442,11 +1442,6 @@ static int cppi_channel_abort(struct dma_channel *channel)
musb_writew(regs, MUSB_TXCSR, value);
musb_writew(regs, MUSB_TXCSR, value);

/* re-enable interrupt */
if (enabled)
musb_writel(tibase, DAVINCI_TXCPPI_INTENAB_REG,
(1 << cppi_ch->index));

/* While we scrub the TX state RAM, ensure that we clean
* up any interrupt that's currently asserted:
* 1. Write to completion Ptr value 0x1(bit 0 set)
Expand All @@ -1459,6 +1454,11 @@ static int cppi_channel_abort(struct dma_channel *channel)
cppi_reset_tx(tx_ram, 1);
musb_writel(&tx_ram->tx_complete, 0, 0);

/* re-enable interrupt */
if (enabled)
musb_writel(tibase, DAVINCI_TXCPPI_INTENAB_REG,
(1 << cppi_ch->index));

cppi_dump_tx(5, cppi_ch, " (done teardown)");

/* REVISIT tx side _should_ clean up the same way
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/musb/musb_core.c
Expand Up @@ -1450,7 +1450,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
#endif

if (hw_ep->max_packet_sz_tx) {
printk(KERN_DEBUG
DBG(1,
"%s: hw_ep %d%s, %smax %d\n",
musb_driver_name, i,
hw_ep->is_shared_fifo ? "shared" : "tx",
Expand All @@ -1459,7 +1459,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
hw_ep->max_packet_sz_tx);
}
if (hw_ep->max_packet_sz_rx && !hw_ep->is_shared_fifo) {
printk(KERN_DEBUG
DBG(1,
"%s: hw_ep %d%s, %smax %d\n",
musb_driver_name, i,
"rx",
Expand Down

0 comments on commit e272a18

Please sign in to comment.