Parent repository is bk://kernel.bkbits.net/gregkh/linux/usb-2.6 ======== ChangeSet 1.1580 ======== D 1.1580 04/02/17 21:33:37-08:00 akpm@mnm.(none) 36775 36774 0/0/1 P ChangeSet C Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6 C into mnm.(none):/usr/src/bk-usb ------------------------------------------------ diff -Nru a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c --- a/drivers/usb/class/usblp.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/class/usblp.c Tue Feb 17 21:35:00 2004 @@ -603,7 +603,7 @@ { DECLARE_WAITQUEUE(wait, current); struct usblp *usblp = file->private_data; - int timeout, err = 0; + int timeout, err = 0, transfer_length; size_t writecount = 0; while (writecount < count) { @@ -654,19 +654,13 @@ continue; } - writecount += usblp->writeurb->transfer_buffer_length; - usblp->writeurb->transfer_buffer_length = 0; + transfer_length=(count - writecount); + if (transfer_length > USBLP_BUF_SIZE) + transfer_length = USBLP_BUF_SIZE; - if (writecount == count) { - up (&usblp->sem); - break; - } + usblp->writeurb->transfer_buffer_length = transfer_length; - usblp->writeurb->transfer_buffer_length = (count - writecount) < USBLP_BUF_SIZE ? - (count - writecount) : USBLP_BUF_SIZE; - - if (copy_from_user(usblp->writeurb->transfer_buffer, buffer + writecount, - usblp->writeurb->transfer_buffer_length)) { + if (copy_from_user(usblp->writeurb->transfer_buffer, buffer + writecount, transfer_length)) { up(&usblp->sem); return writecount ? writecount : -EFAULT; } @@ -683,6 +677,8 @@ break; } up (&usblp->sem); + + writecount += transfer_length; } return count; diff -Nru a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c --- a/drivers/usb/core/buffer.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/core/buffer.c Tue Feb 17 21:35:00 2004 @@ -2,14 +2,19 @@ * DMA memory management for framework level HCD code (hc_driver) * * This implementation plugs in through generic "usb_bus" level methods, - * and works with real PCI, or when "pci device == null" makes sense. + * and should work with all USB controllers, regardles of bus type. */ #include #include #include #include -#include +#include +#include +#include +#include +#include +#include #ifdef CONFIG_USB_DEBUG @@ -62,7 +67,7 @@ if (!(size = pool_max [i])) continue; snprintf (name, sizeof name, "buffer-%d", size); - hcd->pool [i] = pci_pool_create (name, hcd->pdev, + hcd->pool [i] = dma_pool_create (name, hcd->self.controller, size, size, 0); if (!hcd->pool [i]) { hcd_buffer_destroy (hcd); @@ -86,9 +91,9 @@ int i; for (i = 0; i < HCD_BUFFER_POOLS; i++) { - struct pci_pool *pool = hcd->pool [i]; + struct dma_pool *pool = hcd->pool [i]; if (pool) { - pci_pool_destroy (pool); + dma_pool_destroy (pool); hcd->pool [i] = 0; } } @@ -112,9 +117,9 @@ for (i = 0; i < HCD_BUFFER_POOLS; i++) { if (size <= pool_max [i]) - return pci_pool_alloc (hcd->pool [i], mem_flags, dma); + return dma_pool_alloc (hcd->pool [i], mem_flags, dma); } - return pci_alloc_consistent (hcd->pdev, size, dma); + return dma_alloc_coherent (hcd->self.controller, size, dma, 0); } void hcd_buffer_free ( @@ -131,9 +136,9 @@ return; for (i = 0; i < HCD_BUFFER_POOLS; i++) { if (size <= pool_max [i]) { - pci_pool_free (hcd->pool [i], addr, dma); + dma_pool_free (hcd->pool [i], addr, dma); return; } } - pci_free_consistent (hcd->pdev, size, addr, dma); + dma_free_coherent (hcd->self.controller, size, addr, dma); } diff -Nru a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c --- a/drivers/usb/core/hcd-pci.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/core/hcd-pci.c Tue Feb 17 21:35:00 2004 @@ -146,12 +146,10 @@ pci_set_drvdata (dev, hcd); hcd->driver = driver; hcd->description = driver->description; - hcd->pdev = dev; hcd->self.bus_name = pci_name(dev); if (hcd->product_desc == NULL) hcd->product_desc = "USB Host Controller"; hcd->self.controller = &dev->dev; - hcd->controller = hcd->self.controller; if ((retval = hcd_buffer_create (hcd)) != 0) { clean_3: @@ -159,11 +157,11 @@ goto clean_2; } - dev_info (hcd->controller, "%s\n", hcd->product_desc); + dev_info (hcd->self.controller, "%s\n", hcd->product_desc); /* till now HC has been in an indeterminate state ... */ if (driver->reset && (retval = driver->reset (hcd)) < 0) { - dev_err (hcd->controller, "can't reset\n"); + dev_err (hcd->self.controller, "can't reset\n"); goto clean_3; } hcd->state = USB_STATE_HALT; @@ -177,13 +175,13 @@ retval = request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ, hcd->description, hcd); if (retval != 0) { - dev_err (hcd->controller, + dev_err (hcd->self.controller, "request interrupt %s failed\n", bufp); goto clean_3; } hcd->irq = dev->irq; - dev_info (hcd->controller, "irq %s, %s %p\n", bufp, + dev_info (hcd->self.controller, "irq %s, %s %p\n", bufp, (driver->flags & HCD_MEMORY) ? "pci mem" : "io base", base); @@ -226,7 +224,7 @@ hcd = pci_get_drvdata(dev); if (!hcd) return; - dev_info (hcd->controller, "remove, state %x\n", hcd->state); + dev_info (hcd->self.controller, "remove, state %x\n", hcd->state); if (in_interrupt ()) BUG (); @@ -235,7 +233,7 @@ if (HCD_IS_RUNNING (hcd->state)) hcd->state = USB_STATE_QUIESCING; - dev_dbg (hcd->controller, "roothub graceful disconnect\n"); + dev_dbg (hcd->self.controller, "roothub graceful disconnect\n"); usb_disconnect (&hub); hcd->driver->stop (hcd); @@ -273,15 +271,15 @@ int retval = 0; hcd = pci_get_drvdata(dev); - dev_dbg (hcd->controller, "suspend D%d --> D%d\n", + dev_dbg (hcd->self.controller, "suspend D%d --> D%d\n", dev->current_state, state); switch (hcd->state) { case USB_STATE_HALT: - dev_dbg (hcd->controller, "halted; hcd not suspended\n"); + dev_dbg (hcd->self.controller, "halted; hcd not suspended\n"); break; case USB_STATE_SUSPENDED: - dev_dbg (hcd->controller, "hcd already suspended\n"); + dev_dbg (hcd->self.controller, "hcd already suspended\n"); break; default: /* remote wakeup needs hub->suspend() cooperation */ @@ -293,7 +291,8 @@ hcd->state = USB_STATE_QUIESCING; retval = hcd->driver->suspend (hcd, state); if (retval) - dev_dbg (hcd->controller, "suspend fail, retval %d\n", + dev_dbg (hcd->self.controller, + "suspend fail, retval %d\n", retval); else hcd->state = USB_STATE_SUSPENDED; @@ -316,11 +315,12 @@ int retval; hcd = pci_get_drvdata(dev); - dev_dbg (hcd->controller, "resume from state D%d\n", + dev_dbg (hcd->self.controller, "resume from state D%d\n", dev->current_state); if (hcd->state != USB_STATE_SUSPENDED) { - dev_dbg (hcd->controller, "can't resume, not suspended!\n"); + dev_dbg (hcd->self.controller, + "can't resume, not suspended!\n"); return -EL3HLT; } hcd->state = USB_STATE_RESUMING; @@ -333,7 +333,8 @@ retval = hcd->driver->resume (hcd); if (!HCD_IS_RUNNING (hcd->state)) { - dev_dbg (hcd->controller, "resume fail, retval %d\n", retval); + dev_dbg (hcd->self.controller, + "resume fail, retval %d\n", retval); usb_hc_died (hcd); } diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c --- a/drivers/usb/core/hcd.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/core/hcd.c Tue Feb 17 21:35:00 2004 @@ -351,7 +351,7 @@ /* FALLTHROUGH */ case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: case DeviceOutRequest | USB_REQ_SET_FEATURE: - dev_dbg (hcd->controller, "no device features yet yet\n"); + dev_dbg (hcd->self.controller, "no device features yet yet\n"); break; case DeviceRequest | USB_REQ_GET_CONFIGURATION: ubuf [0] = 1; @@ -394,7 +394,7 @@ break; case DeviceOutRequest | USB_REQ_SET_ADDRESS: // wValue == urb->dev->devaddr - dev_dbg (hcd->controller, "root hub device address %d\n", + dev_dbg (hcd->self.controller, "root hub device address %d\n", wValue); break; @@ -409,7 +409,7 @@ /* FALLTHROUGH */ case EndpointOutRequest | USB_REQ_CLEAR_FEATURE: case EndpointOutRequest | USB_REQ_SET_FEATURE: - dev_dbg (hcd->controller, "no endpoint features yet\n"); + dev_dbg (hcd->self.controller, "no endpoint features yet\n"); break; /* CLASS REQUESTS (and errors) */ @@ -423,12 +423,12 @@ error: /* "protocol stall" on error */ urb->status = -EPIPE; - dev_dbg (hcd->controller, "unsupported hub control message (maxchild %d)\n", + dev_dbg (hcd->self.controller, "unsupported hub control message (maxchild %d)\n", urb->dev->maxchild); } if (urb->status) { urb->actual_length = 0; - dev_dbg (hcd->controller, "CTRL: TypeReq=0x%x val=0x%x idx=0x%x len=%d ==> %d\n", + dev_dbg (hcd->self.controller, "CTRL: TypeReq=0x%x val=0x%x idx=0x%x len=%d ==> %d\n", typeReq, wValue, wIndex, wLength, urb->status); } if (bufp) { @@ -464,7 +464,7 @@ || urb->status != -EINPROGRESS || urb->transfer_buffer_length < len || !HCD_IS_RUNNING (hcd->state)) { - dev_dbg (hcd->controller, + dev_dbg (hcd->self.controller, "not queuing rh status urb, stat %d\n", urb->status); return -EINVAL; @@ -1068,18 +1068,18 @@ /* lower level hcd code should use *_dma exclusively, * unless it uses pio or talks to another transport. */ - if (hcd->controller->dma_mask) { + if (hcd->self.controller->dma_mask) { if (usb_pipecontrol (urb->pipe) && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) urb->setup_dma = dma_map_single ( - hcd->controller, + hcd->self.controller, urb->setup_packet, sizeof (struct usb_ctrlrequest), DMA_TO_DEVICE); if (urb->transfer_buffer_length != 0 && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) urb->transfer_dma = dma_map_single ( - hcd->controller, + hcd->self.controller, urb->transfer_buffer, urb->transfer_buffer_length, usb_pipein (urb->pipe) @@ -1125,7 +1125,7 @@ /* failures "should" be harmless */ value = hcd->driver->urb_dequeue (hcd, urb); if (value != 0) - dev_dbg (hcd->controller, + dev_dbg (hcd->self.controller, "dequeue %p --> %d\n", urb, value); } @@ -1232,7 +1232,7 @@ * finish unlinking the initial failed usb_set_address(). */ if (!hcd->saw_irq) { - dev_warn (hcd->controller, "Unlink after no-IRQ? " + dev_warn (hcd->self.controller, "Unlink after no-IRQ? " "Different ACPI or APIC settings may help." "\n"); hcd->saw_irq = 1; @@ -1244,7 +1244,8 @@ */ if (!(urb->transfer_flags & URB_ASYNC_UNLINK)) { if (in_interrupt ()) { - dev_dbg (hcd->controller, "non-async unlink in_interrupt"); + dev_dbg (hcd->self.controller, + "non-async unlink in_interrupt"); retval = -EWOULDBLOCK; goto done; } @@ -1363,7 +1364,7 @@ if (tmp == -EINPROGRESS) { tmp = urb->pipe; unlink1 (hcd, urb); - dev_dbg (hcd->controller, + dev_dbg (hcd->self.controller, "shutdown urb %p pipe %08x ep%d%s%s\n", urb, tmp, usb_pipeendpoint (tmp), (tmp & USB_DIR_IN) ? "in" : "out", @@ -1417,7 +1418,7 @@ /* device driver problem with refcounts? */ if (!list_empty (&dev->urb_list)) { - dev_dbg (hcd->controller, "free busy dev, %s devnum %d (bug!)\n", + dev_dbg (hcd->self.controller, "free busy dev, %s devnum %d (bug!)\n", hcd->self.bus_name, udev->devnum); return -EINVAL; } @@ -1474,15 +1475,16 @@ // It would catch exit/unlink paths for all urbs. /* lower level hcd code should use *_dma exclusively */ - if (hcd->controller->dma_mask) { + if (hcd->self.controller->dma_mask) { if (usb_pipecontrol (urb->pipe) && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) - dma_unmap_single (hcd->controller, urb->setup_dma, + dma_unmap_single (hcd->self.controller, urb->setup_dma, sizeof (struct usb_ctrlrequest), DMA_TO_DEVICE); if (urb->transfer_buffer_length != 0 && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) - dma_unmap_single (hcd->controller, urb->transfer_dma, + dma_unmap_single (hcd->self.controller, + urb->transfer_dma, urb->transfer_buffer_length, usb_pipein (urb->pipe) ? DMA_FROM_DEVICE @@ -1551,7 +1553,7 @@ */ void usb_hc_died (struct usb_hcd *hcd) { - dev_err (hcd->controller, "HC died; cleaning up\n"); + dev_err (hcd->self.controller, "HC died; cleaning up\n"); /* clean up old urbs and devices; needs a task context */ INIT_WORK (&hcd->work, hcd_panic, hcd); diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h --- a/drivers/usb/core/hcd.h Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/core/hcd.h Tue Feb 17 21:35:00 2004 @@ -76,17 +76,14 @@ unsigned saw_irq : 1; int irq; /* irq allocated */ void *regs; /* device memory/io */ - struct device *controller; /* handle to hardware */ - /* a few non-PCI controllers exist, mostly for OHCI */ - struct pci_dev *pdev; /* pci is typical */ #ifdef CONFIG_PCI int region; /* pci region for regs */ u32 pci_state [16]; /* for PM state save */ #endif #define HCD_BUFFER_POOLS 4 - struct pci_pool *pool [HCD_BUFFER_POOLS]; + struct dma_pool *pool [HCD_BUFFER_POOLS]; int state; # define __ACTIVE 0x01 @@ -355,7 +352,7 @@ static inline int hcd_register_root (struct usb_hcd *hcd) { return usb_register_root_hub ( - hcd_to_bus (hcd)->root_hub, hcd->controller); + hcd_to_bus (hcd)->root_hub, hcd->self.controller); } /*-------------------------------------------------------------------------*/ diff -Nru a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c --- a/drivers/usb/host/ehci-dbg.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/host/ehci-dbg.c Tue Feb 17 21:35:00 2004 @@ -19,13 +19,13 @@ /* this file is part of ehci-hcd.c */ #define ehci_dbg(ehci, fmt, args...) \ - dev_dbg ((ehci)->hcd.controller , fmt , ## args ) + dev_dbg ((ehci)->hcd.self.controller , fmt , ## args ) #define ehci_err(ehci, fmt, args...) \ - dev_err ((ehci)->hcd.controller , fmt , ## args ) + dev_err ((ehci)->hcd.self.controller , fmt , ## args ) #define ehci_info(ehci, fmt, args...) \ - dev_info ((ehci)->hcd.controller , fmt , ## args ) + dev_info ((ehci)->hcd.self.controller , fmt , ## args ) #define ehci_warn(ehci, fmt, args...) \ - dev_warn ((ehci)->hcd.controller , fmt , ## args ) + dev_warn ((ehci)->hcd.self.controller , fmt , ## args ) #ifdef EHCI_VERBOSE_DEBUG # define vdbg dbg @@ -367,7 +367,7 @@ scratch, cpu_to_le32p (&qh->hw_info2), cpu_to_le32p (&qh->hw_token), mark, (__constant_cpu_to_le32 (QTD_TOGGLE) & qh->hw_token) - ? "data0" : "data1", + ? "data1" : "data0", (cpu_to_le32p (&qh->hw_alt_next) >> 1) & 0x0f); size -= temp; next += temp; @@ -625,7 +625,7 @@ i = HC_VERSION(readl (&ehci->caps->hc_capbase)); temp = snprintf (next, size, "PCI device %s\nEHCI %x.%02x, hcd state %d (driver " DRIVER_VERSION ")\n", - pci_name(hcd->pdev), + pci_name(to_pci_dev(hcd->self.controller)), i >> 8, i & 0x0ff, ehci->hcd.state); size -= temp; next += temp; diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c --- a/drivers/usb/host/ehci-hcd.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/host/ehci-hcd.c Tue Feb 17 21:35:00 2004 @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -67,6 +68,7 @@ * * HISTORY: * + * 2004-02-24 Replace pci_* with generic dma_* API calls (dsaxena@plexity.net) * 2003-12-29 Rewritten high speed iso transfer support (by Michal Sojka, * , updates by DB). * @@ -288,13 +290,13 @@ /* request handoff to OS */ cap &= 1 << 24; - pci_write_config_dword (ehci->hcd.pdev, where, cap); + pci_write_config_dword (to_pci_dev(ehci->hcd.self.controller), where, cap); /* and wait a while for it to happen */ do { wait_ms (10); msec -= 10; - pci_read_config_dword (ehci->hcd.pdev, where, &cap); + pci_read_config_dword (to_pci_dev(ehci->hcd.self.controller), where, &cap); } while ((cap & (1 << 16)) && msec); if (cap & (1 << 16)) { ehci_err (ehci, "BIOS handoff failed (%d, %04x)\n", @@ -339,7 +341,7 @@ while (temp) { u32 cap; - pci_read_config_dword (ehci->hcd.pdev, temp, &cap); + pci_read_config_dword (to_pci_dev(ehci->hcd.self.controller), temp, &cap); ehci_dbg (ehci, "capability %04x at %02x\n", cap, temp); switch (cap & 0xff) { case 1: /* BIOS/SMM/... handoff */ @@ -378,7 +380,7 @@ * periodic_size can shrink by USBCMD update if hcc_params allows. */ ehci->periodic_size = DEFAULT_I_TDPS; - if ((retval = ehci_mem_init (ehci, SLAB_KERNEL)) < 0) + if ((retval = ehci_mem_init (ehci, GFP_KERNEL)) < 0) return retval; /* controllers may cache some of the periodic schedule ... */ @@ -433,13 +435,13 @@ writel (0, &ehci->regs->segment); #if 0 // this is deeply broken on almost all architectures - if (!pci_set_dma_mask (ehci->hcd.pdev, 0xffffffffffffffffULL)) + if (!pci_set_dma_mask (to_pci_dev(ehci->hcd.self.controller), 0xffffffffffffffffULL)) ehci_info (ehci, "enabled 64bit PCI DMA\n"); #endif } /* help hc dma work well with cachelines */ - pci_set_mwi (ehci->hcd.pdev); + pci_set_mwi (to_pci_dev(ehci->hcd.self.controller)); /* clear interrupt enables, set irq latency */ temp = readl (&ehci->regs->command) & 0x0fff; @@ -493,7 +495,7 @@ readl (&ehci->regs->command); /* unblock posted write */ /* PCI Serial Bus Release Number is at 0x60 offset */ - pci_read_config_byte (hcd->pdev, 0x60, &tempbyte); + pci_read_config_byte(to_pci_dev(hcd->self.controller), 0x60, &tempbyte); temp = HC_VERSION(readl (&ehci->caps->hc_capbase)); ehci_info (ehci, "USB %x.%x enabled, EHCI %x.%02x, driver %s\n", @@ -758,7 +760,7 @@ * non-error returns are a promise to giveback() the urb later * we drop ownership so next owner (or urb unlink) can get it * - * urb + dev is in hcd_dev.urb_list + * urb + dev is in hcd.self.controller.urb_list * we're queueing TDs onto software and hardware lists * * hcd-specific init for hcpriv hasn't been done yet diff -Nru a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c --- a/drivers/usb/host/ehci-hub.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/host/ehci-hub.c Tue Feb 17 21:35:00 2004 @@ -113,7 +113,7 @@ u16 temp; desc->bDescriptorType = 0x29; - desc->bPwrOn2PwrGood = 10; /* FIXME: f(system power) */ + desc->bPwrOn2PwrGood = 10; /* ehci 1.0, 2.3.9 says 20ms max */ desc->bHubContrCurrent = 0; desc->bNbrPorts = ports; diff -Nru a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c --- a/drivers/usb/host/ehci-mem.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/host/ehci-mem.c Tue Feb 17 21:35:00 2004 @@ -24,7 +24,7 @@ * There's basically three types of memory: * - data used only by the HCD ... kmalloc is fine * - async and periodic schedules, shared by HC and HCD ... these - * need to use pci_pool or pci_alloc_consistent + * need to use dma_pool or dma_alloc_coherent * - driver buffers, read/written by HC ... single shot DMA mapped * * There's also PCI "register" data, which is memory mapped. @@ -74,7 +74,7 @@ struct ehci_qtd *qtd; dma_addr_t dma; - qtd = pci_pool_alloc (ehci->qtd_pool, flags, &dma); + qtd = dma_pool_alloc (ehci->qtd_pool, flags, &dma); if (qtd != 0) { ehci_qtd_init (qtd, dma); } @@ -83,7 +83,7 @@ static inline void ehci_qtd_free (struct ehci_hcd *ehci, struct ehci_qtd *qtd) { - pci_pool_free (ehci->qtd_pool, qtd, qtd->qtd_dma); + dma_pool_free (ehci->qtd_pool, qtd, qtd->qtd_dma); } @@ -93,7 +93,7 @@ dma_addr_t dma; qh = (struct ehci_qh *) - pci_pool_alloc (ehci->qh_pool, flags, &dma); + dma_pool_alloc (ehci->qh_pool, flags, &dma); if (!qh) return qh; @@ -107,7 +107,7 @@ qh->dummy = ehci_qtd_alloc (ehci, flags); if (qh->dummy == 0) { ehci_dbg (ehci, "no dummy td\n"); - pci_pool_free (ehci->qh_pool, qh, qh->qh_dma); + dma_pool_free (ehci->qh_pool, qh, qh->qh_dma); qh = 0; } return qh; @@ -132,7 +132,7 @@ if (qh->dummy) ehci_qtd_free (ehci, qh->dummy); usb_put_dev (qh->dev); - pci_pool_free (ehci->qh_pool, qh, qh->qh_dma); + dma_pool_free (ehci->qh_pool, qh, qh->qh_dma); } /*-------------------------------------------------------------------------*/ @@ -148,26 +148,26 @@ qh_put (ehci, ehci->async); ehci->async = 0; - /* PCI consistent memory and pools */ + /* DMA consistent memory and pools */ if (ehci->qtd_pool) - pci_pool_destroy (ehci->qtd_pool); + dma_pool_destroy (ehci->qtd_pool); ehci->qtd_pool = 0; if (ehci->qh_pool) { - pci_pool_destroy (ehci->qh_pool); + dma_pool_destroy (ehci->qh_pool); ehci->qh_pool = 0; } if (ehci->itd_pool) - pci_pool_destroy (ehci->itd_pool); + dma_pool_destroy (ehci->itd_pool); ehci->itd_pool = 0; if (ehci->sitd_pool) - pci_pool_destroy (ehci->sitd_pool); + dma_pool_destroy (ehci->sitd_pool); ehci->sitd_pool = 0; if (ehci->periodic) - pci_free_consistent (ehci->hcd.pdev, + dma_free_coherent (ehci->hcd.self.controller, ehci->periodic_size * sizeof (u32), ehci->periodic, ehci->periodic_dma); ehci->periodic = 0; @@ -184,7 +184,8 @@ int i; /* QTDs for control/bulk/intr transfers */ - ehci->qtd_pool = pci_pool_create ("ehci_qtd", ehci->hcd.pdev, + ehci->qtd_pool = dma_pool_create ("ehci_qtd", + ehci->hcd.self.controller, sizeof (struct ehci_qtd), 32 /* byte alignment (for hw parts) */, 4096 /* can't cross 4K */); @@ -193,7 +194,8 @@ } /* QHs for control/bulk/intr transfers */ - ehci->qh_pool = pci_pool_create ("ehci_qh", ehci->hcd.pdev, + ehci->qh_pool = dma_pool_create ("ehci_qh", + ehci->hcd.self.controller, sizeof (struct ehci_qh), 32 /* byte alignment (for hw parts) */, 4096 /* can't cross 4K */); @@ -206,7 +208,8 @@ } /* ITD for high speed ISO transfers */ - ehci->itd_pool = pci_pool_create ("ehci_itd", ehci->hcd.pdev, + ehci->itd_pool = dma_pool_create ("ehci_itd", + ehci->hcd.self.controller, sizeof (struct ehci_itd), 32 /* byte alignment (for hw parts) */, 4096 /* can't cross 4K */); @@ -215,7 +218,8 @@ } /* SITD for full/low speed split ISO transfers */ - ehci->sitd_pool = pci_pool_create ("ehci_sitd", ehci->hcd.pdev, + ehci->sitd_pool = dma_pool_create ("ehci_sitd", + ehci->hcd.self.controller, sizeof (struct ehci_sitd), 32 /* byte alignment (for hw parts) */, 4096 /* can't cross 4K */); @@ -225,9 +229,9 @@ /* Hardware periodic table */ ehci->periodic = (u32 *) - pci_alloc_consistent (ehci->hcd.pdev, + dma_alloc_coherent (ehci->hcd.self.controller, ehci->periodic_size * sizeof (u32), - &ehci->periodic_dma); + &ehci->periodic_dma, 0); if (ehci->periodic == 0) { goto fail; } diff -Nru a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c --- a/drivers/usb/host/ehci-q.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/host/ehci-q.c Tue Feb 17 21:35:00 2004 @@ -776,7 +776,7 @@ qh = (struct ehci_qh *) *ptr; if (unlikely (qh == 0)) { /* can't sleep here, we have ehci->lock... */ - qh = qh_make (ehci, urb, SLAB_ATOMIC); + qh = qh_make (ehci, urb, GFP_ATOMIC); *ptr = qh; } if (likely (qh != 0)) { diff -Nru a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c --- a/drivers/usb/host/ehci-sched.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/host/ehci-sched.c Tue Feb 17 21:35:00 2004 @@ -490,33 +490,6 @@ return status; } -static unsigned -intr_complete ( - struct ehci_hcd *ehci, - unsigned frame, - struct ehci_qh *qh, - struct pt_regs *regs -) { - unsigned count; - - /* nothing to report? */ - if (likely ((qh->hw_token & __constant_cpu_to_le32 (QTD_STS_ACTIVE)) - != 0)) - return 0; - if (unlikely (list_empty (&qh->qtd_list))) { - dbg ("intr qh %p no TDs?", qh); - return 0; - } - - /* handle any completions */ - count = qh_completions (ehci, qh, regs); - - if (unlikely (list_empty (&qh->qtd_list))) - intr_deschedule (ehci, qh, 0); - - return count; -} - /*-------------------------------------------------------------------------*/ static inline struct ehci_iso_stream * @@ -605,7 +578,7 @@ itd = list_entry (stream->free_itd_list.next, struct ehci_itd, itd_list); list_del (&itd->itd_list); - pci_pool_free (ehci->itd_pool, itd, itd->itd_dma); + dma_pool_free (ehci->itd_pool, itd, itd->itd_dma); } is_in = (stream->bEndpointAddress & USB_DIR_IN) ? 0x10 : 0; @@ -718,7 +691,8 @@ trans = EHCI_ISOC_ACTIVE; trans |= buf & 0x0fff; - if (unlikely ((i + 1) == urb->number_of_packets)) + if (unlikely (((i + 1) == urb->number_of_packets)) + && !(urb->transfer_flags & URB_NO_INTERRUPT)) trans |= EHCI_ITD_IOC; trans |= length << 16; uframe->transaction = cpu_to_le32 (trans); @@ -786,7 +760,7 @@ list_del (&itd->itd_list); itd_dma = itd->itd_dma; } else - itd = pci_pool_alloc (ehci->itd_pool, mem_flags, + itd = dma_pool_alloc (ehci->itd_pool, mem_flags, &itd_dma); if (unlikely (0 == itd)) { @@ -809,7 +783,10 @@ * periodic schedule slots. (Affected by TUNE_FLS, which defaults to * "as small as possible" to be cache-friendlier.) That limits the size * transfers you can stream reliably; avoid more than 64 msec per urb. - * Also avoid queue depths of less than the system's worst irq latency. + * Also avoid queue depths of less than ehci's worst irq latency (affected + * by the per-urb URB_NO_INTERRUPT hint, the log2_irq_thresh module parameter, + * and other factors); or more than about 230 msec total (for portability, + * given EHCI_TUNE_FLS and the slop). Or, write a smarter scheduler! */ #define SCHEDULE_SLOP 10 /* frames */ @@ -1233,7 +1210,7 @@ scan_periodic (struct ehci_hcd *ehci, struct pt_regs *regs) { unsigned frame, clock, now_uframe, mod; - unsigned count = 0; + unsigned modified; mod = ehci->periodic_size << 3; @@ -1244,47 +1221,50 @@ */ now_uframe = ehci->next_uframe; if (HCD_IS_RUNNING (ehci->hcd.state)) - clock = readl (&ehci->regs->frame_index) % mod; + clock = readl (&ehci->regs->frame_index); else clock = now_uframe + mod - 1; + clock %= mod; for (;;) { union ehci_shadow q, *q_p; u32 type, *hw_p; unsigned uframes; + /* don't scan past the live uframe */ frame = now_uframe >> 3; -restart: - /* scan schedule to _before_ current frame index */ - if ((frame == (clock >> 3)) - && HCD_IS_RUNNING (ehci->hcd.state)) + if (frame == (clock >> 3)) uframes = now_uframe & 0x07; - else + else { + /* safe to scan the whole frame at once */ + now_uframe |= 0x07; uframes = 8; + } +restart: + /* scan each element in frame's queue for completions */ q_p = &ehci->pshadow [frame]; hw_p = &ehci->periodic [frame]; q.ptr = q_p->ptr; type = Q_NEXT_TYPE (*hw_p); + modified = 0; - /* scan each element in frame's queue for completions */ while (q.ptr != 0) { - int last; unsigned uf; union ehci_shadow temp; switch (type) { case Q_TYPE_QH: - last = (q.qh->hw_next == EHCI_LIST_END); - temp = q.qh->qh_next; + /* handle any completions */ + temp.qh = qh_get (q.qh); type = Q_NEXT_TYPE (q.qh->hw_next); - count += intr_complete (ehci, frame, - qh_get (q.qh), regs); - qh_put (ehci, q.qh); - q = temp; + q = q.qh->qh_next; + modified = qh_completions (ehci, temp.qh, regs); + if (unlikely (list_empty (&temp.qh->qtd_list))) + intr_deschedule (ehci, temp.qh, 0); + qh_put (ehci, temp.qh); break; case Q_TYPE_FSTN: - last = (q.fstn->hw_next == EHCI_LIST_END); /* for "save place" FSTNs, look at QH entries * in the previous frame for completions. */ @@ -1295,8 +1275,6 @@ q = q.fstn->fstn_next; break; case Q_TYPE_ITD: - last = (q.itd->hw_next == EHCI_LIST_END); - /* skip itds for later in the frame */ rmb (); for (uf = uframes; uf < 8; uf++) { @@ -1317,31 +1295,24 @@ */ *q_p = q.itd->itd_next; *hw_p = q.itd->hw_next; + type = Q_NEXT_TYPE (q.itd->hw_next); wmb(); - - /* always rescan here; simpler */ - count += itd_complete (ehci, q.itd, regs); - goto restart; + modified = itd_complete (ehci, q.itd, regs); + q = *q_p; + break; #ifdef have_split_iso case Q_TYPE_SITD: - last = (q.sitd->hw_next == EHCI_LIST_END); - sitd_complete (ehci, q.sitd); - type = Q_NEXT_TYPE (q.sitd->hw_next); - - // FIXME unlink SITD after split completes - q = q.sitd->sitd_next; - break; + // nyet! #endif /* have_split_iso */ default: dbg ("corrupt type %d frame %d shadow %p", type, frame, q.ptr); // BUG (); - last = 1; q.ptr = 0; } - /* did completion remove an interior q entry? */ - if (unlikely (q.ptr == 0 && !last)) + /* assume completion callbacks modify the queue */ + if (unlikely (modified)) goto restart; } @@ -1368,9 +1339,6 @@ /* rescan the rest of this frame, then ... */ clock = now; } else { - /* FIXME sometimes we can scan the next frame - * right away, not always inching up on it ... - */ now_uframe++; now_uframe %= mod; } diff -Nru a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h --- a/drivers/usb/host/ehci.h Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/host/ehci.h Tue Feb 17 21:35:00 2004 @@ -74,11 +74,11 @@ struct ehci_regs *regs; u32 hcs_params; /* cached register copy */ - /* per-HC memory pools (could be per-PCI-bus, but ...) */ - struct pci_pool *qh_pool; /* qh per active urb */ - struct pci_pool *qtd_pool; /* one or more per qh */ - struct pci_pool *itd_pool; /* itd per iso urb */ - struct pci_pool *sitd_pool; /* sitd per split iso urb */ + /* per-HC memory pools (could be per-bus, but ...) */ + struct dma_pool *qh_pool; /* qh per active urb */ + struct dma_pool *qtd_pool; /* one or more per qh */ + struct dma_pool *itd_pool; /* itd per iso urb */ + struct dma_pool *sitd_pool; /* sitd per split iso urb */ struct timer_list watchdog; struct notifier_block reboot_notifier; diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c --- a/drivers/usb/host/ohci-hcd.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/host/ohci-hcd.c Tue Feb 17 21:35:00 2004 @@ -17,6 +17,7 @@ * * History: * + * 2004/02/04 use generic dma_* functions instead of pci_* (dsaxena@plexity.net) * 2003/02/24 show registers in sysfs (Kevin Brosius) * * 2002/09/03 get rid of ed hashtables, rework periodic scheduling and @@ -96,6 +97,8 @@ #include /* for in_interrupt () */ #include #include "../core/hcd.h" +#include +#include /* needed by ohci-mem.c when no PCI */ #include #include @@ -642,8 +645,9 @@ remove_debug_files (ohci); ohci_mem_cleanup (ohci); if (ohci->hcca) { - pci_free_consistent (ohci->hcd.pdev, sizeof *ohci->hcca, - ohci->hcca, ohci->hcca_dma); + dma_free_coherent (ohci->hcd.self.controller, + sizeof *ohci->hcca, + ohci->hcca, ohci->hcca_dma); ohci->hcca = NULL; ohci->hcca_dma = 0; } diff -Nru a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c --- a/drivers/usb/host/ohci-mem.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/host/ohci-mem.c Tue Feb 17 21:35:00 2004 @@ -13,7 +13,7 @@ * There's basically three types of memory: * - data used only by the HCD ... kmalloc is fine * - async and periodic schedules, shared by HC and HCD ... these - * need to use pci_pool or pci_alloc_consistent + * need to use dma_pool or dma_alloc_coherent * - driver buffers, read/written by HC ... the hcd glue or the * device driver provides us with dma addresses * @@ -45,18 +45,18 @@ static int ohci_mem_init (struct ohci_hcd *ohci) { - ohci->td_cache = pci_pool_create ("ohci_td", ohci->hcd.pdev, + ohci->td_cache = dma_pool_create ("ohci_td", ohci->hcd.self.controller, sizeof (struct td), 32 /* byte alignment */, 0 /* no page-crossing issues */); if (!ohci->td_cache) return -ENOMEM; - ohci->ed_cache = pci_pool_create ("ohci_ed", ohci->hcd.pdev, + ohci->ed_cache = dma_pool_create ("ohci_ed", ohci->hcd.self.controller, sizeof (struct ed), 16 /* byte alignment */, 0 /* no page-crossing issues */); if (!ohci->ed_cache) { - pci_pool_destroy (ohci->td_cache); + dma_pool_destroy (ohci->td_cache); return -ENOMEM; } return 0; @@ -65,11 +65,11 @@ static void ohci_mem_cleanup (struct ohci_hcd *ohci) { if (ohci->td_cache) { - pci_pool_destroy (ohci->td_cache); + dma_pool_destroy (ohci->td_cache); ohci->td_cache = 0; } if (ohci->ed_cache) { - pci_pool_destroy (ohci->ed_cache); + dma_pool_destroy (ohci->ed_cache); ohci->ed_cache = 0; } } @@ -96,7 +96,7 @@ dma_addr_t dma; struct td *td; - td = pci_pool_alloc (hc->td_cache, mem_flags, &dma); + td = dma_pool_alloc (hc->td_cache, mem_flags, &dma); if (td) { /* in case hc fetches it, make it look dead */ memset (td, 0, sizeof *td); @@ -118,7 +118,7 @@ *prev = td->td_hash; else if ((td->hwINFO & TD_DONE) != 0) ohci_dbg (hc, "no hash for td %p\n", td); - pci_pool_free (hc->td_cache, td, td->td_dma); + dma_pool_free (hc->td_cache, td, td->td_dma); } /*-------------------------------------------------------------------------*/ @@ -130,7 +130,7 @@ dma_addr_t dma; struct ed *ed; - ed = pci_pool_alloc (hc->ed_cache, mem_flags, &dma); + ed = dma_pool_alloc (hc->ed_cache, mem_flags, &dma); if (ed) { memset (ed, 0, sizeof (*ed)); INIT_LIST_HEAD (&ed->td_list); @@ -142,6 +142,6 @@ static void ed_free (struct ohci_hcd *hc, struct ed *ed) { - pci_pool_free (hc->ed_cache, ed, ed->dma); + dma_pool_free (hc->ed_cache, ed, ed->dma); } diff -Nru a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c --- a/drivers/usb/host/ohci-omap.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/host/ohci-omap.c Tue Feb 17 21:35:00 2004 @@ -388,9 +388,7 @@ hcd->description = driver->description; hcd->irq = dev->irq[0]; hcd->regs = dev->mapbase; - hcd->pdev = OMAP_FAKE_PCIDEV; hcd->self.controller = &dev->dev; - hcd->controller = hcd->self.controller; retval = hcd_buffer_create (hcd); if (retval != 0) { @@ -494,12 +492,10 @@ struct ohci_hcd *ohci = hcd_to_ohci (hcd); int ret; - if (hcd->pdev) { - ohci->hcca = pci_alloc_consistent (hcd->pdev, - sizeof *ohci->hcca, &ohci->hcca_dma); - if (!ohci->hcca) - return -ENOMEM; - } + ohci->hcca = dma_alloc_consistent (hcd->self.controller, + sizeof *ohci->hcca, &ohci->hcca_dma); + if (!ohci->hcca) + return -ENOMEM; memset (ohci->hcca, 0, sizeof (struct ohci_hcca)); if ((ret = ohci_mem_init (ohci)) < 0) { diff -Nru a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c --- a/drivers/usb/host/ohci-pci.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/host/ohci-pci.c Tue Feb 17 21:35:00 2004 @@ -45,17 +45,19 @@ struct ohci_hcd *ohci = hcd_to_ohci (hcd); int ret; - if (hcd->pdev) { - ohci->hcca = pci_alloc_consistent (hcd->pdev, - sizeof *ohci->hcca, &ohci->hcca_dma); - if (!ohci->hcca) - return -ENOMEM; + ohci->hcca = dma_alloc_coherent (hcd->self.controller, + sizeof *ohci->hcca, &ohci->hcca_dma, 0); + if (!ohci->hcca) + return -ENOMEM; + + if(hcd->self.controller && hcd->self.controller->bus == &pci_bus_type) { + struct pci_dev *pdev = to_pci_dev(hcd->self.controller); /* AMD 756, for most chips (early revs), corrupts register * values on read ... so enable the vendor workaround. */ - if (hcd->pdev->vendor == PCI_VENDOR_ID_AMD - && hcd->pdev->device == 0x740c) { + if (pdev->vendor == PCI_VENDOR_ID_AMD + && pdev->device == 0x740c) { ohci->flags = OHCI_QUIRK_AMD756; ohci_info (ohci, "AMD756 erratum 4 workaround\n"); } @@ -68,8 +70,8 @@ * for this chip. Evidently control and bulk lists * can get confused. (B&W G3 models, and ...) */ - else if (hcd->pdev->vendor == PCI_VENDOR_ID_OPTI - && hcd->pdev->device == 0xc861) { + else if (pdev->vendor == PCI_VENDOR_ID_OPTI + && pdev->device == 0xc861) { ohci_info (ohci, "WARNING: OPTi workarounds unavailable\n"); } @@ -78,12 +80,11 @@ * identify the USB (fn2). This quirk might apply to more or * even all NSC stuff. */ - else if (hcd->pdev->vendor == PCI_VENDOR_ID_NS) { - struct pci_dev *b, *hc; + else if (pdev->vendor == PCI_VENDOR_ID_NS) { + struct pci_dev *b; - hc = hcd->pdev; - b = pci_find_slot (hc->bus->number, - PCI_DEVFN (PCI_SLOT (hc->devfn), 1)); + b = pci_find_slot (pdev->bus->number, + PCI_DEVFN (PCI_SLOT (pdev->devfn), 1)); if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO && b->vendor == PCI_VENDOR_ID_NS) { ohci->flags |= OHCI_QUIRK_SUPERIO; @@ -145,7 +146,7 @@ #ifdef CONFIG_PMAC_PBOOK if (_machine == _MACH_Pmac) - disable_irq (hcd->pdev->irq); + disable_irq ((to_pci_dev(hcd->self.controller))->irq); /* else, 2.4 assumes shared irqs -- don't disable */ #endif @@ -179,15 +180,17 @@ * memory during sleep. We disable its bus master bit during * suspend */ - pci_read_config_word (hcd->pdev, PCI_COMMAND, &cmd); + pci_read_config_word (to_pci_dev(hcd->self.controller), PCI_COMMAND, + &cmd); cmd &= ~PCI_COMMAND_MASTER; - pci_write_config_word (hcd->pdev, PCI_COMMAND, cmd); + pci_write_config_word (to_pci_dev(hcd->self.controller), PCI_COMMAND, + cmd); #ifdef CONFIG_PMAC_PBOOK { struct device_node *of_node; /* Disable USB PAD & cell clock */ - of_node = pci_device_to_OF_node (hcd->pdev); + of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.controller)); if (of_node) pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0); } @@ -207,7 +210,7 @@ struct device_node *of_node; /* Re-enable USB PAD & cell clock */ - of_node = pci_device_to_OF_node (hcd->pdev); + of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.controller)); if (of_node) pmac_call_feature (PMAC_FTR_USB_ENABLE, of_node, 0, 1); } @@ -222,7 +225,7 @@ #endif /* Re-enable bus mastering */ - pci_set_master (ohci->hcd.pdev); + pci_set_master (to_pci_dev(ohci->hcd.self.controller)); switch (temp) { @@ -282,7 +285,7 @@ #ifdef CONFIG_PMAC_PBOOK if (_machine == _MACH_Pmac) - enable_irq (hcd->pdev->irq); + enable_irq (to_pci_dev(hcd->self.controller)->irq); #endif /* Check for a pending done list */ diff -Nru a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c --- a/drivers/usb/host/ohci-q.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/host/ohci-q.c Tue Feb 17 21:35:00 2004 @@ -375,7 +375,7 @@ if (!(ed = dev->ep [ep])) { struct td *td; - ed = ed_alloc (ohci, SLAB_ATOMIC); + ed = ed_alloc (ohci, GFP_ATOMIC); if (!ed) { /* out of memory */ goto done; @@ -383,7 +383,7 @@ dev->ep [ep] = ed; /* dummy td; end of td list for ed */ - td = td_alloc (ohci, SLAB_ATOMIC); + td = td_alloc (ohci, GFP_ATOMIC); if (!td) { /* out of memory */ ed_free (ohci, ed); diff -Nru a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c --- a/drivers/usb/host/ohci-sa1111.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/host/ohci-sa1111.c Tue Feb 17 21:35:00 2004 @@ -167,9 +167,7 @@ hcd->description = driver->description; hcd->irq = dev->irq[1]; hcd->regs = dev->mapbase; - hcd->pdev = SA1111_FAKE_PCIDEV; hcd->self.controller = &dev->dev; - hcd->controller = hcd->self.controller; retval = hcd_buffer_create (hcd); if (retval != 0) { @@ -270,14 +268,12 @@ struct ohci_hcd *ohci = hcd_to_ohci (hcd); int ret; - if (hcd->pdev) { - ohci->hcca = pci_alloc_consistent (hcd->pdev, - sizeof *ohci->hcca, &ohci->hcca_dma); - if (!ohci->hcca) - return -ENOMEM; - } - - memset (ohci->hcca, 0, sizeof (struct ohci_hcca)); + ohci->hcca = dma_alloc_coherent (hcd->self.controller, + sizeof *ohci->hcca, &ohci->hcca_dma, 0); + if (!ohci->hcca) + return -ENOMEM; + + memset (ohci->hcca, 0, sizeof (struct ohci_hcca)); if ((ret = ohci_mem_init (ohci)) < 0) { ohci_stop (hcd); return ret; diff -Nru a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h --- a/drivers/usb/host/ohci.h Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/host/ohci.h Tue Feb 17 21:35:00 2004 @@ -361,8 +361,8 @@ /* * memory management for queue data structures */ - struct pci_pool *td_cache; - struct pci_pool *ed_cache; + struct dma_pool *td_cache; + struct dma_pool *ed_cache; struct td *td_hash [TD_HASH_SIZE]; /* @@ -391,13 +391,13 @@ #endif /* DEBUG */ #define ohci_dbg(ohci, fmt, args...) \ - dev_dbg ((ohci)->hcd.controller , fmt , ## args ) + dev_dbg ((ohci)->hcd.self.controller , fmt , ## args ) #define ohci_err(ohci, fmt, args...) \ - dev_err ((ohci)->hcd.controller , fmt , ## args ) + dev_err ((ohci)->hcd.self.controller , fmt , ## args ) #define ohci_info(ohci, fmt, args...) \ - dev_info ((ohci)->hcd.controller , fmt , ## args ) + dev_info ((ohci)->hcd.self.controller , fmt , ## args ) #define ohci_warn(ohci, fmt, args...) \ - dev_warn ((ohci)->hcd.controller , fmt , ## args ) + dev_warn ((ohci)->hcd.self.controller , fmt , ## args ) #ifdef OHCI_VERBOSE_DEBUG # define ohci_vdbg ohci_dbg diff -Nru a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c --- a/drivers/usb/host/uhci-debug.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/host/uhci-debug.c Tue Feb 17 21:35:00 2004 @@ -321,8 +321,8 @@ out += sprintf(out, "%s", (urbp->fsbr ? "FSBR " : "")); out += sprintf(out, "%s", (urbp->fsbr_timeout ? "FSBR_TO " : "")); - if (urbp->status != -EINPROGRESS) - out += sprintf(out, "Status=%d ", urbp->status); + if (urbp->urb->status != -EINPROGRESS) + out += sprintf(out, "Status=%d ", urbp->urb->status); //out += sprintf(out, "Inserttime=%lx ",urbp->inserttime); //out += sprintf(out, "FSBRtime=%lx ",urbp->fsbrtime); @@ -402,7 +402,7 @@ head = &uhci->complete_list; tmp = head->next; while (tmp != head) { - struct urb_priv *urbp = list_entry(tmp, struct urb_priv, complete_list); + struct urb_priv *urbp = list_entry(tmp, struct urb_priv, urb_list); out += sprintf(out, " %d: ", ++count); out += uhci_show_urbp(uhci, urbp, out, len - (out - buf)); @@ -418,7 +418,7 @@ { unsigned long flags; char *out = buf; - int i; + int i, j; struct uhci_qh *qh; struct uhci_td *td; struct list_head *tmp, *head; @@ -473,10 +473,11 @@ continue; } + j = (i < 7) ? 7 : i+1; /* Next skeleton */ if (list_empty(&qh->list)) { if (i < UHCI_NUM_SKELQH - 1) { if (qh->link != - (cpu_to_le32(uhci->skelqh[i + 1]->dma_handle) | UHCI_PTR_QH)) { + (cpu_to_le32(uhci->skelqh[j]->dma_handle) | UHCI_PTR_QH)) { show_qh_name(); out += sprintf(out, " skeleton QH not linked to next skeleton QH!\n"); } @@ -500,7 +501,7 @@ if (i < UHCI_NUM_SKELQH - 1) { if (qh->link != - (cpu_to_le32(uhci->skelqh[i + 1]->dma_handle) | UHCI_PTR_QH)) + (cpu_to_le32(uhci->skelqh[j]->dma_handle) | UHCI_PTR_QH)) out += sprintf(out, " last QH not linked to next skeleton!\n"); } } diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c --- a/drivers/usb/host/uhci-hcd.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/host/uhci-hcd.c Tue Feb 17 21:35:00 2004 @@ -41,6 +41,8 @@ #include #include #include +#include +#include #ifdef CONFIG_USB_DEBUG #define DEBUG #else @@ -48,6 +50,7 @@ #endif #include +#include #include #include #include @@ -80,7 +83,7 @@ MODULE_PARM(debug, "i"); MODULE_PARM_DESC(debug, "Debug level"); static char *errbuf; -#define ERRBUF_LEN (PAGE_SIZE * 8) +#define ERRBUF_LEN (32 * 1024) #include "uhci-hub.c" #include "uhci-debug.c" @@ -121,21 +124,17 @@ static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci) { - unsigned long flags; - - spin_lock_irqsave(&uhci->frame_list_lock, flags); + spin_lock(&uhci->frame_list_lock); uhci->term_td->status &= ~cpu_to_le32(TD_CTRL_IOC); - spin_unlock_irqrestore(&uhci->frame_list_lock, flags); + spin_unlock(&uhci->frame_list_lock); } -static inline void uhci_add_complete(struct uhci_hcd *uhci, struct urb *urb) +static inline void uhci_moveto_complete(struct uhci_hcd *uhci, + struct urb_priv *urbp) { - struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; - unsigned long flags; - - spin_lock_irqsave(&uhci->complete_list_lock, flags); - list_add_tail(&urbp->complete_list, &uhci->complete_list); - spin_unlock_irqrestore(&uhci->complete_list_lock, flags); + spin_lock(&uhci->complete_list_lock); + list_move_tail(&urbp->urb_list, &uhci->complete_list); + spin_unlock(&uhci->complete_list_lock); } static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci, struct usb_device *dev) @@ -143,7 +142,7 @@ dma_addr_t dma_handle; struct uhci_td *td; - td = pci_pool_alloc(uhci->td_pool, GFP_ATOMIC, &dma_handle); + td = dma_pool_alloc(uhci->td_pool, GFP_ATOMIC, &dma_handle); if (!td) return NULL; @@ -295,7 +294,7 @@ if (td->dev) usb_put_dev(td->dev); - pci_pool_free(uhci->td_pool, td, td->dma_handle); + dma_pool_free(uhci->td_pool, td, td->dma_handle); } static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, struct usb_device *dev) @@ -303,7 +302,7 @@ dma_addr_t dma_handle; struct uhci_qh *qh; - qh = pci_pool_alloc(uhci->qh_pool, GFP_ATOMIC, &dma_handle); + qh = dma_pool_alloc(uhci->qh_pool, GFP_ATOMIC, &dma_handle); if (!qh) return NULL; @@ -333,7 +332,7 @@ if (qh->dev) usb_put_dev(qh->dev); - pci_pool_free(uhci->qh_pool, qh, qh->dma_handle); + dma_pool_free(uhci->qh_pool, qh, qh->dma_handle); } /* @@ -671,7 +670,6 @@ INIT_LIST_HEAD(&urbp->td_list); INIT_LIST_HEAD(&urbp->queue_list); - INIT_LIST_HEAD(&urbp->complete_list); INIT_LIST_HEAD(&urbp->urb_list); list_add_tail(&urbp->urb_list, &uhci->urb_list); @@ -722,9 +720,6 @@ if (!list_empty(&urbp->urb_list)) warn("uhci_destroy_urb_priv: urb %p still on uhci->urb_list or uhci->remove_list", urb); - if (!list_empty(&urbp->complete_list)) - warn("uhci_destroy_urb_priv: urb %p still on uhci->complete_list", urb); - spin_lock_irqsave(&uhci->td_remove_list_lock, flags); /* Check to see if the remove list is empty. Set the IOC bit */ @@ -913,7 +908,7 @@ uhci_insert_tds_in_qh(qh, urb, UHCI_PTR_BREADTH); - /* Low speed transfers get a different queue, and won't hog the bus */ + /* Low-speed transfers get a different queue, and won't hog the bus */ if (urb->dev->speed == USB_SPEED_LOW) skelqh = uhci->skel_ls_control_qh; else { @@ -971,7 +966,7 @@ /* One TD, who cares about Breadth first? */ uhci_insert_tds_in_qh(urbp->qh, urb, UHCI_PTR_DEPTH); - /* Low speed transfers get a different queue */ + /* Low-speed transfers get a different queue */ if (urb->dev->speed == USB_SPEED_LOW) uhci_insert_qh(uhci, uhci->skel_ls_control_qh, urb); else @@ -1255,7 +1250,7 @@ { int ret; - /* Can't have low speed bulk transfers */ + /* Can't have low-speed bulk transfers */ if (urb->dev->speed == USB_SPEED_LOW) return -EINVAL; @@ -1462,11 +1457,14 @@ spin_lock_irqsave(&uhci->urb_list_lock, flags); + if (urb->status != -EINPROGRESS) /* URB already unlinked! */ + goto out; + eurb = uhci_find_urb_ep(uhci, urb); if (!uhci_alloc_urb_priv(uhci, urb)) { - spin_unlock_irqrestore(&uhci->urb_list_lock, flags); - return -ENOMEM; + ret = -ENOMEM; + goto out; } switch (usb_pipetype(urb->pipe)) { @@ -1514,10 +1512,11 @@ return ret; } + ret = 0; +out: spin_unlock_irqrestore(&uhci->urb_list_lock, flags); - - return 0; + return ret; } /* @@ -1527,18 +1526,15 @@ */ static void uhci_transfer_result(struct uhci_hcd *uhci, struct urb *urb) { - int ret = -EINVAL; - unsigned long flags; + int ret = -EINPROGRESS; struct urb_priv *urbp; - spin_lock_irqsave(&urb->lock, flags); + spin_lock(&urb->lock); urbp = (struct urb_priv *)urb->hcpriv; - if (urb->status != -EINPROGRESS) { - info("uhci_transfer_result: called for URB %p not in flight?", urb); + if (urb->status != -EINPROGRESS) /* URB already dequeued */ goto out; - } switch (usb_pipetype(urb->pipe)) { case PIPE_CONTROL: @@ -1555,10 +1551,9 @@ break; } - urbp->status = ret; - if (ret == -EINPROGRESS) goto out; + urb->status = ret; switch (usb_pipetype(urb->pipe)) { case PIPE_CONTROL: @@ -1589,13 +1584,11 @@ usb_pipetype(urb->pipe), urb); } - /* Remove it from uhci->urb_list */ - list_del_init(&urbp->urb_list); - - uhci_add_complete(uhci, urb); + /* Move it from uhci->urb_list to uhci->complete_list */ + uhci_moveto_complete(uhci, urbp); out: - spin_unlock_irqrestore(&urb->lock, flags); + spin_unlock(&urb->lock); } /* @@ -1607,10 +1600,6 @@ struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; int prevactive = 1; - /* We can get called when urbp allocation fails, so check */ - if (!urbp) - return; - uhci_dec_fsbr(uhci, urb); /* Safe since it checks */ /* @@ -1660,13 +1649,6 @@ unsigned long flags; struct urb_priv *urbp = urb->hcpriv; - /* If this is an interrupt URB that is being killed in urb->complete, */ - /* then just set its status and return */ - if (!urbp) { - urb->status = -ECONNRESET; - return 0; - } - spin_lock_irqsave(&uhci->urb_list_lock, flags); list_del_init(&urbp->urb_list); @@ -1678,7 +1660,7 @@ /* If we're the first, set the next interrupt bit */ if (list_empty(&uhci->urb_remove_list)) uhci_set_next_interrupt(uhci); - list_add(&urbp->urb_list, &uhci->urb_remove_list); + list_add_tail(&urbp->urb_list, &uhci->urb_remove_list); spin_unlock(&uhci->urb_remove_list_lock); spin_unlock_irqrestore(&uhci->urb_list_lock, flags); @@ -1805,9 +1787,8 @@ static void uhci_free_pending_qhs(struct uhci_hcd *uhci) { struct list_head *tmp, *head; - unsigned long flags; - spin_lock_irqsave(&uhci->qh_remove_list_lock, flags); + spin_lock(&uhci->qh_remove_list_lock); head = &uhci->qh_remove_list; tmp = head->next; while (tmp != head) { @@ -1819,15 +1800,14 @@ uhci_free_qh(uhci, qh); } - spin_unlock_irqrestore(&uhci->qh_remove_list_lock, flags); + spin_unlock(&uhci->qh_remove_list_lock); } static void uhci_free_pending_tds(struct uhci_hcd *uhci) { struct list_head *tmp, *head; - unsigned long flags; - spin_lock_irqsave(&uhci->td_remove_list_lock, flags); + spin_lock(&uhci->td_remove_list_lock); head = &uhci->td_remove_list; tmp = head->next; while (tmp != head) { @@ -1839,23 +1819,16 @@ uhci_free_td(uhci, td); } - spin_unlock_irqrestore(&uhci->td_remove_list_lock, flags); + spin_unlock(&uhci->td_remove_list_lock); } static void uhci_finish_urb(struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs) { - struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; struct uhci_hcd *uhci = hcd_to_uhci(hcd); - int status; - unsigned long flags; - spin_lock_irqsave(&urb->lock, flags); - status = urbp->status; + spin_lock(&urb->lock); uhci_destroy_urb_priv(uhci, urb); - - if (urb->status != -ENOENT && urb->status != -ECONNRESET) - urb->status = status; - spin_unlock_irqrestore(&urb->lock, flags); + spin_unlock(&urb->lock); usb_hcd_giveback_urb(hcd, urb, regs); } @@ -1864,48 +1837,40 @@ { struct uhci_hcd *uhci = hcd_to_uhci(hcd); struct list_head *tmp, *head; - unsigned long flags; - spin_lock_irqsave(&uhci->complete_list_lock, flags); + spin_lock(&uhci->complete_list_lock); head = &uhci->complete_list; tmp = head->next; while (tmp != head) { - struct urb_priv *urbp = list_entry(tmp, struct urb_priv, complete_list); + struct urb_priv *urbp = list_entry(tmp, struct urb_priv, urb_list); struct urb *urb = urbp->urb; - list_del_init(&urbp->complete_list); - spin_unlock_irqrestore(&uhci->complete_list_lock, flags); + list_del_init(&urbp->urb_list); + spin_unlock(&uhci->complete_list_lock); uhci_finish_urb(hcd, urb, regs); - spin_lock_irqsave(&uhci->complete_list_lock, flags); + spin_lock(&uhci->complete_list_lock); head = &uhci->complete_list; tmp = head->next; } - spin_unlock_irqrestore(&uhci->complete_list_lock, flags); + spin_unlock(&uhci->complete_list_lock); } -static void uhci_remove_pending_qhs(struct uhci_hcd *uhci) +static void uhci_remove_pending_urbps(struct uhci_hcd *uhci) { struct list_head *tmp, *head; - unsigned long flags; - spin_lock_irqsave(&uhci->urb_remove_list_lock, flags); + spin_lock(&uhci->urb_remove_list_lock); head = &uhci->urb_remove_list; tmp = head->next; while (tmp != head) { struct urb_priv *urbp = list_entry(tmp, struct urb_priv, urb_list); - struct urb *urb = urbp->urb; tmp = tmp->next; - - list_del_init(&urbp->urb_list); - - urbp->status = urb->status = -ECONNRESET; - - uhci_add_complete(uhci, urb); + uhci_moveto_complete(uhci, urbp); } - spin_unlock_irqrestore(&uhci->urb_remove_list_lock, flags); + spin_unlock(&uhci->urb_remove_list_lock); } static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs) @@ -1917,10 +1882,11 @@ /* * Read the interrupt status, and write it back to clear the - * interrupt cause + * interrupt cause. Contrary to the UHCI specification, the + * "HC Halted" status bit is persistent: it is RO, not R/WC. */ status = inw(io_addr + USBSTS); - if (!status) /* shared interrupt, not mine */ + if (!(status & ~USBSTS_HCH)) /* shared interrupt, not mine */ return IRQ_NONE; outw(status, io_addr + USBSTS); /* Clear it */ @@ -1942,7 +1908,7 @@ uhci_free_pending_tds(uhci); - uhci_remove_pending_qhs(uhci); + uhci_remove_pending_urbps(uhci); uhci_clear_next_interrupt(uhci); @@ -2049,7 +2015,8 @@ unsigned int io_addr = uhci->io_addr; int i; - if (!uhci->hcd.pdev || uhci->hcd.pdev->vendor != PCI_VENDOR_ID_INTEL) + if (!uhci->hcd.self.controller || + to_pci_dev(uhci->hcd.self.controller)->vendor != PCI_VENDOR_ID_INTEL) return 1; /* Some of Intel's USB controllers have a bug that causes false @@ -2163,17 +2130,17 @@ } if (uhci->qh_pool) { - pci_pool_destroy(uhci->qh_pool); + dma_pool_destroy(uhci->qh_pool); uhci->qh_pool = NULL; } if (uhci->td_pool) { - pci_pool_destroy(uhci->td_pool); + dma_pool_destroy(uhci->td_pool); uhci->td_pool = NULL; } if (uhci->fl) { - pci_free_consistent(uhci->hcd.pdev, sizeof(*uhci->fl), uhci->fl, uhci->fl->dma_handle); + dma_free_coherent(uhci->hcd.self.controller, sizeof(*uhci->fl), uhci->fl, uhci->fl->dma_handle); uhci->fl = NULL; } @@ -2198,7 +2165,7 @@ * interrupts from any previous setup. */ reset_hc(uhci); - pci_write_config_word(hcd->pdev, USBLEGSUP, USBLEGSUP_DEFAULT); + pci_write_config_word(to_pci_dev(hcd->self.controller), USBLEGSUP, USBLEGSUP_DEFAULT); return 0; } @@ -2213,10 +2180,10 @@ * of the queues. We don't do that here, because * we'll create the actual TD entries on demand. * - The first queue is the interrupt queue. - * - The second queue is the control queue, split into low and high speed + * - The second queue is the control queue, split into low- and full-speed * - The third queue is bulk queue. * - The fourth queue is the bandwidth reclamation queue, which loops back - * to the high speed control queue. + * to the full-speed control queue. */ static int uhci_start(struct usb_hcd *hcd) { @@ -2230,7 +2197,7 @@ struct proc_dir_entry *ent; #endif - io_size = pci_resource_len(hcd->pdev, hcd->region); + io_size = pci_resource_len(to_pci_dev(hcd->self.controller), hcd->region); #ifdef CONFIG_PROC_FS ent = create_proc_entry(hcd->self.bus_name, S_IFREG|S_IRUGO|S_IWUSR, uhci_proc_root); @@ -2266,7 +2233,8 @@ spin_lock_init(&uhci->frame_list_lock); - uhci->fl = pci_alloc_consistent(hcd->pdev, sizeof(*uhci->fl), &dma_handle); + uhci->fl = dma_alloc_coherent(hcd->self.controller, + sizeof(*uhci->fl), &dma_handle, 0); if (!uhci->fl) { err("unable to allocate consistent memory for frame list"); goto err_alloc_fl; @@ -2276,17 +2244,17 @@ uhci->fl->dma_handle = dma_handle; - uhci->td_pool = pci_pool_create("uhci_td", hcd->pdev, + uhci->td_pool = dma_pool_create("uhci_td", hcd->self.controller, sizeof(struct uhci_td), 16, 0); if (!uhci->td_pool) { - err("unable to create td pci_pool"); + err("unable to create td dma_pool"); goto err_create_td_pool; } - uhci->qh_pool = pci_pool_create("uhci_qh", hcd->pdev, + uhci->qh_pool = dma_pool_create("uhci_qh", hcd->self.controller, sizeof(struct uhci_qh), 16, 0); if (!uhci->qh_pool) { - err("unable to create qh pci_pool"); + err("unable to create qh dma_pool"); goto err_create_qh_pool; } @@ -2336,16 +2304,17 @@ } /* - * 8 Interrupt queues; link int2 to int1, int4 to int2, etc + * 8 Interrupt queues; link all higher int queues to int1, * then link int1 to control and control to bulk */ - uhci->skel_int128_qh->link = cpu_to_le32(uhci->skel_int64_qh->dma_handle) | UHCI_PTR_QH; - uhci->skel_int64_qh->link = cpu_to_le32(uhci->skel_int32_qh->dma_handle) | UHCI_PTR_QH; - uhci->skel_int32_qh->link = cpu_to_le32(uhci->skel_int16_qh->dma_handle) | UHCI_PTR_QH; - uhci->skel_int16_qh->link = cpu_to_le32(uhci->skel_int8_qh->dma_handle) | UHCI_PTR_QH; - uhci->skel_int8_qh->link = cpu_to_le32(uhci->skel_int4_qh->dma_handle) | UHCI_PTR_QH; - uhci->skel_int4_qh->link = cpu_to_le32(uhci->skel_int2_qh->dma_handle) | UHCI_PTR_QH; - uhci->skel_int2_qh->link = cpu_to_le32(uhci->skel_int1_qh->dma_handle) | UHCI_PTR_QH; + uhci->skel_int128_qh->link = + uhci->skel_int64_qh->link = + uhci->skel_int32_qh->link = + uhci->skel_int16_qh->link = + uhci->skel_int8_qh->link = + uhci->skel_int4_qh->link = + uhci->skel_int2_qh->link = + cpu_to_le32(uhci->skel_int1_qh->dma_handle) | UHCI_PTR_QH; uhci->skel_int1_qh->link = cpu_to_le32(uhci->skel_ls_control_qh->dma_handle) | UHCI_PTR_QH; uhci->skel_ls_control_qh->link = cpu_to_le32(uhci->skel_hs_control_qh->dma_handle) | UHCI_PTR_QH; @@ -2361,39 +2330,33 @@ uhci->skel_term_qh->element = cpu_to_le32(uhci->term_td->dma_handle); /* - * Fill the frame list: make all entries point to - * the proper interrupt queue. + * Fill the frame list: make all entries point to the proper + * interrupt queue. * - * This is probably silly, but it's a simple way to - * scatter the interrupt queues in a way that gives - * us a reasonable dynamic range for irq latencies. + * The interrupt queues will be interleaved as evenly as possible. + * There's not much to be done about period-1 interrupts; they have + * to occur in every frame. But we can schedule period-2 interrupts + * in odd-numbered frames, period-4 interrupts in frames congruent + * to 2 (mod 4), and so on. This way each frame only has two + * interrupt QHs, which will help spread out bandwidth utilization. */ for (i = 0; i < UHCI_NUMFRAMES; i++) { - int irq = 0; + int irq; - if (i & 1) { - irq++; - if (i & 2) { - irq++; - if (i & 4) { - irq++; - if (i & 8) { - irq++; - if (i & 16) { - irq++; - if (i & 32) { - irq++; - if (i & 64) - irq++; - } - } - } - } - } - } + /* + * ffs (Find First bit Set) does exactly what we need: + * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[6], + * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[5], etc. + * ffs > 6 => not on any high-period queue, so use + * skel_int1_qh = skelqh[7]. + * Add UHCI_NUMFRAMES to insure at least one bit is set. + */ + irq = 6 - (int) __ffs(i + UHCI_NUMFRAMES); + if (irq < 0) + irq = 7; /* Only place we don't use the frame list routines */ - uhci->fl->frame[i] = cpu_to_le32(uhci->skelqh[7 - irq]->dma_handle); + uhci->fl->frame[i] = cpu_to_le32(uhci->skelqh[irq]->dma_handle); } start_hc(uhci); @@ -2402,7 +2365,7 @@ udev->speed = USB_SPEED_FULL; - if (usb_register_root_hub(udev, &hcd->pdev->dev) != 0) { + if (usb_register_root_hub(udev, hcd->self.controller) != 0) { err("unable to start root hub"); retval = -ENOMEM; goto err_start_root_hub; @@ -2433,15 +2396,16 @@ hcd->self.root_hub = NULL; err_alloc_root_hub: - pci_pool_destroy(uhci->qh_pool); + dma_pool_destroy(uhci->qh_pool); uhci->qh_pool = NULL; err_create_qh_pool: - pci_pool_destroy(uhci->td_pool); + dma_pool_destroy(uhci->td_pool); uhci->td_pool = NULL; err_create_td_pool: - pci_free_consistent(hcd->pdev, sizeof(*uhci->fl), uhci->fl, uhci->fl->dma_handle); + dma_free_coherent(hcd->self.controller, + sizeof(*uhci->fl), uhci->fl, uhci->fl->dma_handle); uhci->fl = NULL; err_alloc_fl: @@ -2458,6 +2422,7 @@ static void uhci_stop(struct usb_hcd *hcd) { struct uhci_hcd *uhci = hcd_to_uhci(hcd); + unsigned long flags; del_timer_sync(&uhci->stall_timer); @@ -2465,15 +2430,17 @@ * At this point, we're guaranteed that no new connects can be made * to this bus since there are no more parents */ + local_irq_save(flags); uhci_free_pending_qhs(uhci); uhci_free_pending_tds(uhci); - uhci_remove_pending_qhs(uhci); + uhci_remove_pending_urbps(uhci); reset_hc(uhci); uhci_free_pending_qhs(uhci); uhci_free_pending_tds(uhci); - + local_irq_restore(flags); + release_uhci(uhci); } @@ -2494,7 +2461,7 @@ { struct uhci_hcd *uhci = hcd_to_uhci(hcd); - pci_set_master(uhci->hcd.pdev); + pci_set_master(to_pci_dev(uhci->hcd.self.controller)); if (uhci->state == UHCI_SUSPENDED) uhci->resume_detect = 1; diff -Nru a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h --- a/drivers/usb/host/uhci-hcd.h Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/host/uhci-hcd.h Tue Feb 17 21:35:00 2004 @@ -200,8 +200,8 @@ * The UHCI driver places Interrupt, Control and Bulk into QH's both * to group together TD's for one transfer, and also to faciliate queuing * of URB's. To make it easy to insert entries into the schedule, we have - * a skeleton of QH's for each predefined Interrupt latency, low speed - * control, high speed control and terminating QH (see explanation for + * a skeleton of QH's for each predefined Interrupt latency, low-speed + * control, full-speed control and terminating QH (see explanation for * the terminating QH below). * * When we want to add a new QH, we add it to the end of the list for the @@ -216,9 +216,9 @@ * skel int32 QH * ... * skel int1 QH - * skel low speed control QH + * skel low-speed control QH * dev 5 control QH - * skel high speed control QH + * skel full-speed control QH * skel bulk QH * dev 1 bulk QH * dev 2 bulk QH @@ -227,7 +227,7 @@ * The terminating QH is used for 2 reasons: * - To place a terminating TD which is used to workaround a PIIX bug * (see Intel errata for explanation) - * - To loop back to the high speed control queue for full speed bandwidth + * - To loop back to the full-speed control queue for full-speed bandwidth * reclamation * * Isochronous transfers are stored before the start of the skeleton @@ -326,8 +326,8 @@ /* Grabbed from PCI */ unsigned long io_addr; - struct pci_pool *qh_pool; - struct pci_pool *td_pool; + struct dma_pool *qh_pool; + struct dma_pool *td_pool; struct usb_bus *bus; @@ -336,7 +336,7 @@ spinlock_t frame_list_lock; struct uhci_frame_list *fl; /* P: uhci->frame_list_lock */ - int fsbr; /* Full speed bandwidth reclamation */ + int fsbr; /* Full-speed bandwidth reclamation */ unsigned long fsbrtimeout; /* FSBR delay */ enum uhci_state state; /* FIXME: needs a spinlock */ @@ -383,13 +383,10 @@ /* a control transfer, retrigger */ /* the status phase */ - int status; /* Final status */ - unsigned long inserttime; /* In jiffies */ unsigned long fsbrtime; /* In jiffies */ struct list_head queue_list; /* P: uhci->frame_list_lock */ - struct list_head complete_list; /* P: uhci->complete_list_lock */ }; /* diff -Nru a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c --- a/drivers/usb/media/stv680.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/media/stv680.c Tue Feb 17 21:35:00 2004 @@ -490,10 +490,9 @@ stv680->hue = 32767; stv680->palette = STV_VIDEO_PALETTE; stv680->depth = 24; /* rgb24 bits */ - swapRGB = 0; if ((swapRGB_on == 0) && (swapRGB == 0)) PDEBUG (1, "STV(i): swapRGB is (auto) OFF"); - else if ((swapRGB_on == 1) && (swapRGB == 1)) + else if ((swapRGB_on == 0) && (swapRGB == 1)) PDEBUG (1, "STV(i): swapRGB is (auto) ON"); else if (swapRGB_on == 1) PDEBUG (1, "STV(i): swapRGB is (forced) ON"); @@ -657,7 +656,7 @@ /* Resubmit urb for new data */ urb->status = 0; urb->dev = stv680->udev; - if (usb_submit_urb (urb, GFP_KERNEL)) + if (usb_submit_urb (urb, GFP_ATOMIC)) PDEBUG (0, "STV(e): urb burned down in video irq"); return; } /* _video_irq */ @@ -1252,13 +1251,10 @@ return -EINVAL; } case VIDIOCSFBUF: - return -EINVAL; case VIDIOCGTUNER: case VIDIOCSTUNER: - return -EINVAL; case VIDIOCGFREQ: case VIDIOCSFREQ: - return -EINVAL; case VIDIOCGAUDIO: case VIDIOCSAUDIO: return -EINVAL; @@ -1434,7 +1430,7 @@ if (video_register_device (stv680->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { PDEBUG (0, "STV(e): video_register_device failed"); retval = -EIO; - goto error; + goto error_vdev; } PDEBUG (0, "STV(i): registered new video device: video%d", stv680->vdev->minor); @@ -1442,6 +1438,8 @@ stv680_create_sysfs_files(stv680->vdev); return 0; +error_vdev: + video_device_release(stv680->vdev); error: kfree(stv680); return retval; @@ -1466,9 +1464,7 @@ kfree (stv680->sbuf[i].data); } for (i = 0; i < STV680_NUMSCRATCH; i++) - if (stv680->scratch[i].data) { - kfree (stv680->scratch[i].data); - } + kfree (stv680->scratch[i].data); PDEBUG (0, "STV(i): %s disconnected", stv680->camera_name); /* Free the memory */ diff -Nru a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c --- a/drivers/usb/serial/ftdi_sio.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/serial/ftdi_sio.c Tue Feb 17 21:35:00 2004 @@ -17,6 +17,11 @@ * See http://ftdi-usb-sio.sourceforge.net for upto date testing info * and extra documentation * + * (09/Feb/2004) Ian Abbott + * Changed full name of USB-UIRT device to avoid "/" character. + * Added FTDI's alternate PID (0x6006) for FT232/245 devices. + * Added PID for "ELV USB Module UO100" from Stefan Frings. + * * (21/Oct/2003) Ian Abbott * Renamed some VID/PID macros for Matrix Orbital and Perle Systems * devices. Removed Matrix Orbital and Perle Systems devices from the @@ -282,6 +287,7 @@ static struct usb_device_id id_table_8U232AM [] = { { USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_PID, 0, 0x3ff) }, + { USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_ALT_PID, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_RELAIS_PID, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_XF_632_PID, 0, 0x3ff) }, @@ -346,12 +352,14 @@ { USB_DEVICE_VER(FTDI_VID, PROTEGO_R2X0, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0, 0x3ff) }, + { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0, 0x3ff) }, { } /* Terminating entry */ }; static struct usb_device_id id_table_FT232BM [] = { { USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_PID, 0x400, 0xffff) }, + { USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_ALT_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_RELAIS_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_XF_632_PID, 0x400, 0xffff) }, @@ -425,6 +433,7 @@ { USB_DEVICE_VER(FTDI_VID, PROTEGO_R2X0, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0x400, 0xffff) }, + { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0x400, 0xffff) }, { } /* Terminating entry */ }; @@ -444,6 +453,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) }, { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) }, @@ -518,6 +528,7 @@ { USB_DEVICE(FTDI_VID, PROTEGO_R2X0) }, { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_3) }, { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_4) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) }, { } /* Terminating entry */ }; @@ -669,7 +680,7 @@ static struct usb_serial_device_type ftdi_USB_UIRT_device = { .owner = THIS_MODULE, - .name = "USB-UIRT Infrared Receiver/Transmitter", + .name = "USB-UIRT Infrared Tranceiver", .id_table = id_table_USB_UIRT, .num_interrupt_in = 0, .num_bulk_in = 1, diff -Nru a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h --- a/drivers/usb/serial/ftdi_sio.h Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/serial/ftdi_sio.h Tue Feb 17 21:35:00 2004 @@ -25,6 +25,7 @@ #define FTDI_VID 0x0403 /* Vendor Id */ #define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ #define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */ +#define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */ #define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */ #define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ #define FTDI_NF_RIC_PID 0x0001 /* Product Id */ @@ -131,6 +132,9 @@ /* USB-UIRT - An infrared receiver and transmitter using the 8U232AM chip */ /* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */ #define FTDI_USB_UIRT_PID 0xF850 /* Product Id */ + +/* ELV USB Module UO100 (PID sent by Stefan Frings) */ +#define FTDI_ELV_UO100_PID 0xFB58 /* Product Id */ /* * Definitions for ID TECH (www.idt-net.com) devices diff -Nru a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c --- a/drivers/usb/storage/sddr09.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/storage/sddr09.c Tue Feb 17 21:35:00 2004 @@ -1478,7 +1478,7 @@ "mode page 0x%x\n", modepage); memcpy(ptr, mode_page_01, sizeof(mode_page_01)); - ((u16*)ptr)[0] = sizeof(mode_page_01) - 2; + ((u16*)ptr)[0] = cpu_to_be16(sizeof(mode_page_01) - 2); ptr[3] = (info->flags & SDDR09_WP) ? 0x80 : 0; usb_stor_set_xfer_buf(ptr, sizeof(mode_page_01), srb); return USB_STOR_TRANSPORT_GOOD; diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c --- a/drivers/usb/storage/transport.c Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/storage/transport.c Tue Feb 17 21:35:00 2004 @@ -552,6 +552,8 @@ return; } + srb->result = SAM_STAT_GOOD; + /* Determine if we need to auto-sense * * I normally don't use a flag like this, but it's almost impossible @@ -561,23 +563,14 @@ /* * If we're running the CB transport, which is incapable - * of determining status on it's own, we need to auto-sense almost - * every time. + * of determining status on its own, we need to auto-sense + * unless the operation involved a data-in transfer. Devices + * can signal data-in errors by stalling the bulk-in pipe. */ - if (us->protocol == US_PR_CB || us->protocol == US_PR_DPCM_USB) { + if ((us->protocol == US_PR_CB || us->protocol == US_PR_DPCM_USB) && + srb->sc_data_direction != SCSI_DATA_READ) { US_DEBUGP("-- CB transport device requiring auto-sense\n"); need_auto_sense = 1; - - /* There are some exceptions to this. Notably, if this is - * a UFI device and the command is REQUEST_SENSE or INQUIRY, - * then it is impossible to truly determine status. - */ - if (us->subclass == US_SC_UFI && - ((srb->cmnd[0] == REQUEST_SENSE) || - (srb->cmnd[0] == INQUIRY))) { - US_DEBUGP("** no auto-sense for a special command\n"); - need_auto_sense = 0; - } } /* @@ -591,8 +584,8 @@ } /* - * Also, if we have a short transfer on a command that can't have - * a short transfer, we're going to do this. + * A short transfer on a command where we don't expect it + * is unusual, but it doesn't mean we need to auto-sense. */ if ((srb->resid > 0) && !((srb->cmnd[0] == REQUEST_SENSE) || @@ -601,7 +594,6 @@ (srb->cmnd[0] == LOG_SENSE) || (srb->cmnd[0] == MODE_SENSE_10))) { US_DEBUGP("-- unexpectedly short transfer\n"); - need_auto_sense = 1; } /* Now, if we need to do the auto-sense, let's do it */ @@ -614,6 +606,7 @@ unsigned char old_cmd_len; unsigned char old_cmnd[MAX_COMMAND_SIZE]; unsigned long old_serial_number; + int old_resid; US_DEBUGP("Issuing auto-REQUEST_SENSE\n"); @@ -654,9 +647,12 @@ srb->serial_number ^= 0x80000000; /* issue the auto-sense command */ + old_resid = srb->resid; + srb->resid = 0; temp_result = us->transport(us->srb, us); /* let's clean up right away */ + srb->resid = old_resid; srb->request_buffer = old_request_buffer; srb->request_bufflen = old_request_bufflen; srb->use_sg = old_sg; @@ -698,26 +694,15 @@ /* set the result so the higher layers expect this data */ srb->result = SAM_STAT_CHECK_CONDITION; - /* If things are really okay, then let's show that */ - if ((srb->sense_buffer[2] & 0xf) == 0x0) + /* If things are really okay, then let's show that. Zero + * out the sense buffer so the higher layers won't realize + * we did an unsolicited auto-sense. */ + if (result == USB_STOR_TRANSPORT_GOOD && + (srb->sense_buffer[2] & 0xf) == 0x0) { srb->result = SAM_STAT_GOOD; - } else /* if (need_auto_sense) */ - srb->result = SAM_STAT_GOOD; - - /* Regardless of auto-sense, if we _know_ we have an error - * condition, show that in the result code - */ - if (result == USB_STOR_TRANSPORT_FAILED) - srb->result = SAM_STAT_CHECK_CONDITION; - - /* If we think we're good, then make sure the sense data shows it. - * This is necessary because the auto-sense for some devices always - * sets byte 0 == 0x70, even if there is no error - */ - if ((us->protocol == US_PR_CB || us->protocol == US_PR_DPCM_USB) && - (result == USB_STOR_TRANSPORT_GOOD) && - ((srb->sense_buffer[2] & 0xf) == 0x0)) - srb->sense_buffer[0] = 0x0; + srb->sense_buffer[0] = 0x0; + } + } return; /* abort processing: the bulk-only transport requires a reset @@ -792,6 +777,10 @@ srb->request_buffer, transfer_length, srb->use_sg, &srb->resid); US_DEBUGP("CBI data stage result is 0x%x\n", result); + + /* if we stalled the data transfer it means command failed */ + if (result == USB_STOR_XFER_STALLED) + return USB_STOR_TRANSPORT_FAILED; if (result > USB_STOR_XFER_STALLED) return USB_STOR_TRANSPORT_ERROR; } @@ -883,6 +872,10 @@ srb->request_buffer, transfer_length, srb->use_sg, &srb->resid); US_DEBUGP("CB data stage result is 0x%x\n", result); + + /* if we stalled the data transfer it means command failed */ + if (result == USB_STOR_XFER_STALLED) + return USB_STOR_TRANSPORT_FAILED; if (result > USB_STOR_XFER_STALLED) return USB_STOR_TRANSPORT_ERROR; } @@ -929,6 +922,7 @@ unsigned int residue; int result; int fake_sense = 0; + unsigned int cswlen; /* set up the command wrapper */ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); @@ -985,7 +979,17 @@ /* get CSW for device status */ US_DEBUGP("Attempting to get CSW...\n"); result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, - bcs, US_BULK_CS_WRAP_LEN, NULL); + bcs, US_BULK_CS_WRAP_LEN, &cswlen); + + /* Some broken devices add unnecessary zero-length packets to the + * end of their data transfers. Such packets show up as 0-length + * CSWs. If we encounter such a thing, try to read the CSW again. + */ + if (result == USB_STOR_XFER_SHORT && cswlen == 0) { + US_DEBUGP("Received 0-length CSW; retrying...\n"); + result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, + bcs, US_BULK_CS_WRAP_LEN, &cswlen); + } /* did the attempt to read the CSW fail? */ if (result == USB_STOR_XFER_STALLED) { diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h --- a/drivers/usb/storage/unusual_devs.h Tue Feb 17 21:35:00 2004 +++ b/drivers/usb/storage/unusual_devs.h Tue Feb 17 21:35:00 2004 @@ -108,6 +108,15 @@ "Finecam S5", US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY), +/* Patch for Kyocera Finecam L3 + * Submitted by Michael Krauth + */ +UNUSUAL_DEV( 0x0482, 0x0105, 0x0100, 0x0100, + "Kyocera", + "Finecam L3", + US_SC_SCSI, US_PR_BULK, NULL, + US_FL_FIX_INQUIRY), + /* Reported by Paul Stewart * This entry is needed because the device reports Sub=ff */ UNUSUAL_DEV( 0x04a4, 0x0004, 0x0001, 0x0001, @@ -414,6 +423,28 @@ US_FL_SINGLE_LUN ), #endif +/* Following three Minolta cameras reported by Martin Pool + * . Originally discovered by Kedar Petankar, + * Matthew Geier, Mikael Lofj"ard, Marcel de Boer. + */ +UNUSUAL_DEV( 0x0686, 0x4006, 0x0001, 0x0001, + "Minolta", + "DiMAGE 7", + US_SC_SCSI, US_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0686, 0x400b, 0x0001, 0x0001, + "Minolta", + "DiMAGE 7i", + US_SC_SCSI, US_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0686, 0x400f, 0x0001, 0x0001, + "Minolta", + "DiMAGE 7Hi", + US_SC_SCSI, US_PR_DEVICE, NULL, + 0 ), + /* Submitted by Benny Sjostrand */ UNUSUAL_DEV( 0x0686, 0x4011, 0x0001, 0x0001, "Minolta", @@ -426,28 +457,6 @@ "DIMAGE E223", US_SC_SCSI, US_PR_DEVICE, NULL, 0 ), -/* Following three Minolta cameras reported by Martin Pool - * . Originally discovered by Kedar Petankar, - * Matthew Geier, Mikael Lofj"ard, Marcel de Boer. - */ -UNUSUAL_DEV( 0x0686, 0x4006, 0x0001, 0x0001, - "Minolta", - "DiMAGE 7", - US_SC_SCSI, US_PR_DEVICE, NULL, - 0 ), - -UNUSUAL_DEV( 0x0686, 0x400b, 0x0001, 0x0001, - "Minolta", - "DiMAGE 7i", - US_SC_SCSI, US_PR_DEVICE, NULL, - 0 ), - -UNUSUAL_DEV( 0x0686, 0x400f, 0x0001, 0x0001, - "Minolta", - "DiMAGE 7Hi", - US_SC_SCSI, US_PR_DEVICE, NULL, - 0 ), - UNUSUAL_DEV( 0x0693, 0x0002, 0x0100, 0x0100, "Hagiwara", "FlashGate SmartMedia", @@ -607,7 +616,7 @@ UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9009, "Casio", "QV DigitalCamera", - US_SC_8070, US_PR_CB, NULL, + US_SC_DEVICE, US_PR_CB, NULL, US_FL_FIX_INQUIRY ), /* Later Casio cameras apparently tell the truth */ @@ -631,15 +640,6 @@ "AIPTEK", "PocketCAM 3Mega", US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_MODE_XLATE ), - -/*Medion 6047 Digital Camera -Davide Andrian <_nessuno_@katamail.com> -*/ -UNUSUAL_DEV( 0x08ca, 0x2011, 0x0001, 0x0001, - "3MegaCam", - "3MegaCam", - US_SC_DEVICE, US_PR_BULK, NULL, US_FL_MODE_XLATE ), /* Trumpion Microelectronics MP3 player (felipe_alfaro@linuxmail.org) */