# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.474.2.3 -> 1.474.2.4 # drivers/usb/host/ehci-q.c 1.21 -> 1.22 # drivers/usb/host/ehci-sched.c 1.16 -> 1.17 # drivers/usb/host/ohci-sa1111.c 1.4 -> 1.5 # drivers/usb/host/uhci-hcd.h 1.1 -> 1.2 # drivers/usb/host/ehci.h 1.6 -> 1.7 # drivers/usb/host/uhci-hcd.c 1.9 -> 1.10 # drivers/usb/host/ohci-q.c 1.18 -> 1.19 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/08/13 david-b@pacbell.net 1.474.2.4 # [PATCH] HCDs support new DMA APIs (part 1 of 2) # # - teaches the hardware-specific code to # use urb->*_dma instead of creating mappings. # (And tells ohci-sa1111 to init its buffer pools.) # EHCI and UHCI also eliminated duplicated state; # all the HCDs are now a smidgeon smaller. # # Sanity checked by enumerating, including through # a hub, and using a USB Ethernet adapter, with each # of the three host controllers. # # Worth noting: this removes pci_dma_sync_single() # calls from UHCI. On x86 (and some others) that's # a NOP, but for UHCI on other platforms (rare except # maybe on IA64, as I understand) this anticipates # the upcoming patch to remove interrupt automagic. # (I'll likely submit that after a Linus release that # catches up to your USB tree. :) # -------------------------------------------- # diff -Nru a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c --- a/drivers/usb/host/ehci-q.c Tue Aug 13 15:34:06 2002 +++ b/drivers/usb/host/ehci-q.c Tue Aug 13 15:34:06 2002 @@ -163,7 +163,6 @@ static void ehci_urb_done ( struct ehci_hcd *ehci, - dma_addr_t addr, struct urb *urb ) { #ifdef INTR_AUTOMAGIC @@ -171,13 +170,6 @@ struct usb_device *dev = 0; #endif - if (urb->transfer_buffer_length) - pci_unmap_single (ehci->hcd.pdev, - addr, - urb->transfer_buffer_length, - usb_pipein (urb->pipe) - ? PCI_DMA_FROMDEVICE - : PCI_DMA_TODEVICE); if (likely (urb->hcpriv != 0)) { struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv; @@ -263,7 +255,7 @@ if (likely (last->urb != urb)) { /* complete() can reenter this HCD */ spin_unlock_irqrestore (&ehci->lock, flags); - ehci_urb_done (ehci, last->buf_dma, last->urb); + ehci_urb_done (ehci, last->urb); spin_lock_irqsave (&ehci->lock, flags); } @@ -347,12 +339,6 @@ urb, urb->status, qtd, token, urb->actual_length); #endif - - /* SETUP for control urb? */ - if (unlikely (QTD_PID (token) == 2)) - pci_unmap_single (ehci->hcd.pdev, - qtd->buf_dma, sizeof (struct usb_ctrlrequest), - PCI_DMA_TODEVICE); } /* patch up list head? */ @@ -364,7 +350,7 @@ /* last urb's completion might still need calling */ if (likely (last != 0)) { - ehci_urb_done (ehci, last->buf_dma, last->urb); + ehci_urb_done (ehci, last->urb); ehci_qtd_free (ehci, last); } } @@ -405,10 +391,6 @@ size = qtd->urb->transfer_buffer_length; unmapped++; } - if (qtd->buf_dma) - pci_unmap_single (ehci->hcd.pdev, - qtd->buf_dma, - size, direction); } ehci_qtd_free (ehci, qtd); } @@ -425,7 +407,7 @@ int flags ) { struct ehci_qtd *qtd, *qtd_prev; - dma_addr_t buf, map_buf; + dma_addr_t buf; int len, maxpacket; int is_input; u32 token; @@ -445,17 +427,8 @@ /* for split transactions, SplitXState initialized to zero */ if (usb_pipecontrol (urb->pipe)) { - /* control request data is passed in the "setup" pid */ - qtd->buf_dma = pci_map_single ( - ehci->hcd.pdev, - urb->setup_packet, - sizeof (struct usb_ctrlrequest), - PCI_DMA_TODEVICE); - if (unlikely (!qtd->buf_dma)) - goto cleanup; - /* SETUP pid */ - qtd_fill (qtd, qtd->buf_dma, sizeof (struct usb_ctrlrequest), + qtd_fill (qtd, urb->setup_dma, sizeof (struct usb_ctrlrequest), token | (2 /* "setup" */ << 8)); /* ... and always at least one more pid */ @@ -474,16 +447,10 @@ */ len = urb->transfer_buffer_length; is_input = usb_pipein (urb->pipe); - if (likely (len > 0)) { - buf = map_buf = pci_map_single (ehci->hcd.pdev, - urb->transfer_buffer, len, - is_input - ? PCI_DMA_FROMDEVICE - : PCI_DMA_TODEVICE); - if (unlikely (!buf)) - goto cleanup; - } else - buf = map_buf = 0; + if (likely (len > 0)) + buf = urb->transfer_dma; + else + buf = 0; if (!buf || is_input) token |= (1 /* "in" */ << 8); @@ -500,7 +467,6 @@ int this_qtd_len; qtd->urb = urb; - qtd->buf_dma = map_buf; this_qtd_len = qtd_fill (qtd, buf, len, token); len -= this_qtd_len; buf += this_qtd_len; diff -Nru a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c --- a/drivers/usb/host/ehci-sched.c Tue Aug 13 15:34:06 2002 +++ b/drivers/usb/host/ehci-sched.c Tue Aug 13 15:34:06 2002 @@ -530,11 +530,6 @@ { struct ehci_itd *first_itd = urb->hcpriv; - pci_unmap_single (ehci->hcd.pdev, - first_itd->buf_dma, urb->transfer_buffer_length, - usb_pipein (urb->pipe) - ? PCI_DMA_FROMDEVICE - : PCI_DMA_TODEVICE); while (!list_empty (&first_itd->itd_list)) { struct ehci_itd *itd; @@ -630,16 +625,7 @@ int frame_index; struct ehci_itd *first_itd, *itd; int status; - dma_addr_t buf_dma, itd_dma; - - /* set up one dma mapping for this urb */ - buf_dma = pci_map_single (ehci->hcd.pdev, - urb->transfer_buffer, urb->transfer_buffer_length, - usb_pipein (urb->pipe) - ? PCI_DMA_FROMDEVICE - : PCI_DMA_TODEVICE); - if (buf_dma == 0) - return -ENOMEM; + dma_addr_t itd_dma; /* allocate/init ITDs */ for (frame_index = 0, first_itd = 0; @@ -653,7 +639,8 @@ memset (itd, 0, sizeof *itd); itd->itd_dma = itd_dma; - status = itd_fill (ehci, itd, urb, frame_index, buf_dma); + status = itd_fill (ehci, itd, urb, frame_index, + urb->transfer_dma); if (status != 0) goto fail; diff -Nru a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h --- a/drivers/usb/host/ehci.h Tue Aug 13 15:34:06 2002 +++ b/drivers/usb/host/ehci.h Tue Aug 13 15:34:06 2002 @@ -219,7 +219,6 @@ /* dma same in urb's qtds, except 1st control qtd (setup buffer) */ struct urb *urb; /* qtd's urb */ - dma_addr_t buf_dma; /* buffer address */ size_t length; /* length of buffer */ } __attribute__ ((aligned (32))); diff -Nru a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c --- a/drivers/usb/host/ohci-q.c Tue Aug 13 15:34:06 2002 +++ b/drivers/usb/host/ohci-q.c Tue Aug 13 15:34:06 2002 @@ -14,27 +14,8 @@ if (last >= 0) { int i; - struct td *td = urb_priv->td [0]; - int len = td->urb->transfer_buffer_length; - int dir = usb_pipeout (td->urb->pipe) - ? PCI_DMA_TODEVICE - : PCI_DMA_FROMDEVICE; - - /* unmap CTRL URB setup buffer (always td 0) */ - if (usb_pipecontrol (td->urb->pipe)) { - pci_unmap_single (hc->hcd.pdev, - td->data_dma, 8, PCI_DMA_TODEVICE); - - /* CTRL data buffer starts at td 1 if len > 0 */ - if (len && last > 0) - td = urb_priv->td [1]; - } - /* else: ISOC, BULK, INTR data buffer starts at td 0 */ - - /* unmap data buffer */ - if (len && td->data_dma) - pci_unmap_single (hc->hcd.pdev, - td->data_dma, len, dir); + struct td *td; + for (i = 0; i <= last; i++) { td = urb_priv->td [i]; if (td) @@ -85,15 +66,8 @@ struct urb_priv *urb_priv = urb->hcpriv; unsigned long flags; -// FIXME rewrite this resubmit path. use pci_dma_sync_single() -// and requeue more cheaply, and only if needed. -// Better yet ... abolish the notion of automagic resubmission. - pci_unmap_single (hc->hcd.pdev, - urb_priv->td [0]->data_dma, - urb->transfer_buffer_length, - usb_pipeout (urb->pipe) - ? PCI_DMA_TODEVICE - : PCI_DMA_FROMDEVICE); +// FIXME going away along with the rest of interrrupt automagic... + /* FIXME: MP race. If another CPU partially unlinks * this URB (urb->status was updated, hasn't yet told * us to dequeue) before we call complete() here, an @@ -612,13 +586,9 @@ urb_priv->td_cnt = 0; - if (data_len) { - data = pci_map_single (ohci->hcd.pdev, - urb->transfer_buffer, data_len, - is_out - ? PCI_DMA_TODEVICE - : PCI_DMA_FROMDEVICE); - } else + if (data_len) + data = urb->transfer_dma; + else data = 0; /* NOTE: TD_CC is set so we can tell which TDs the HC processed by @@ -665,11 +635,7 @@ */ case PIPE_CONTROL: info = TD_CC | TD_DP_SETUP | TD_T_DATA0; - td_fill (info, - pci_map_single (ohci->hcd.pdev, - urb->setup_packet, 8, - PCI_DMA_TODEVICE), - 8, urb, cnt++); + td_fill (info, urb->setup_dma, 8, urb, cnt++); if (data_len > 0) { info = TD_CC | TD_R | TD_T_DATA1; info |= is_out ? TD_DP_OUT : TD_DP_IN; diff -Nru a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c --- a/drivers/usb/host/ohci-sa1111.c Tue Aug 13 15:34:06 2002 +++ b/drivers/usb/host/ohci-sa1111.c Tue Aug 13 15:34:06 2002 @@ -161,6 +161,12 @@ hcd->regs = (void *) &USB_OHCI_OP_BASE; hcd->pdev = SA1111_FAKE_PCIDEV; + retval = hcd_buffer_create (hcd); + if (retval != 0) { + dbg ("pool alloc fail"); + goto err1; + } + set_irq_type(NIRQHCIM, IRQT_RISING); retval = request_irq (NIRQHCIM, usb_hcd_sa1111_hcim_irq, SA_INTERRUPT, hcd->description, hcd); @@ -193,6 +199,7 @@ return 0; err2: + hcd_buffer_destroy (hcd); if (hcd) driver->hcd_free(hcd); err1: sa1111_stop_hc(); @@ -233,6 +240,7 @@ hcd->state = USB_STATE_HALT; free_irq (hcd->irq, hcd); + hcd_buffer_destroy (hcd); usb_deregister_bus (&hcd->self); if (atomic_read (&hcd->self.refcnt) != 1) diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c --- a/drivers/usb/host/uhci-hcd.c Tue Aug 13 15:34:06 2002 +++ b/drivers/usb/host/uhci-hcd.c Tue Aug 13 15:34:06 2002 @@ -646,23 +646,6 @@ urb->hcpriv = urbp; - if (urb->transfer_buffer_length) { - urbp->transfer_buffer_dma_handle = pci_map_single(uhci->dev, - urb->transfer_buffer, urb->transfer_buffer_length, - usb_pipein(urb->pipe) ? PCI_DMA_FROMDEVICE : - PCI_DMA_TODEVICE); - if (!urbp->transfer_buffer_dma_handle) - return NULL; - } - - if (usb_pipetype(urb->pipe) == PIPE_CONTROL && urb->setup_packet) { - urbp->setup_packet_dma_handle = pci_map_single(uhci->dev, - urb->setup_packet, sizeof(struct usb_ctrlrequest), - PCI_DMA_TODEVICE); - if (!urbp->setup_packet_dma_handle) - return NULL; - } - return urbp; } @@ -721,19 +704,6 @@ uhci_free_td(uhci, td); } - if (urbp->setup_packet_dma_handle) { - pci_unmap_single(uhci->dev, urbp->setup_packet_dma_handle, - sizeof(struct usb_ctrlrequest), PCI_DMA_TODEVICE); - urbp->setup_packet_dma_handle = 0; - } - - if (urbp->transfer_buffer_dma_handle) { - pci_unmap_single(uhci->dev, urbp->transfer_buffer_dma_handle, - urb->transfer_buffer_length, usb_pipein(urb->pipe) ? - PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); - urbp->transfer_buffer_dma_handle = 0; - } - urb->hcpriv = NULL; kmem_cache_free(uhci_up_cachep, urbp); } @@ -813,7 +783,7 @@ unsigned long destination, status; int maxsze = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); int len = urb->transfer_buffer_length; - dma_addr_t data = urbp->transfer_buffer_dma_handle; + dma_addr_t data = urb->transfer_dma; /* The "pipe" thing contains the destination in bits 8--18 */ destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP; @@ -832,7 +802,7 @@ uhci_add_td_to_urb(urb, td); uhci_fill_td(td, status, destination | uhci_explen(7), - urbp->setup_packet_dma_handle); + urb->setup_dma); /* * If direction is "send", change the frame from SETUP (0x2D) @@ -1072,7 +1042,6 @@ { struct uhci_td *td; unsigned long destination, status; - struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; if (urb->transfer_buffer_length > usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe))) return -EINVAL; @@ -1094,7 +1063,7 @@ usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe)); uhci_add_td_to_urb(urb, td); - uhci_fill_td(td, status, destination, urbp->transfer_buffer_dma_handle); + uhci_fill_td(td, status, destination, urb->transfer_dma); uhci_insert_td(uhci, uhci->skeltd[__interval_to_skel(urb->interval)], td); @@ -1196,7 +1165,7 @@ int maxsze = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); int len = urb->transfer_buffer_length; struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; - dma_addr_t data = urbp->transfer_buffer_dma_handle; + dma_addr_t data = urb->transfer_dma; if (len < 0) return -EINVAL; @@ -1358,7 +1327,6 @@ struct uhci_td *td; int i, ret, frame; int status, destination; - struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; status = TD_CTRL_ACTIVE | TD_CTRL_IOS; destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); @@ -1378,7 +1346,7 @@ uhci_add_td_to_urb(urb, td); uhci_fill_td(td, status, destination | uhci_explen(urb->iso_frame_desc[i].length - 1), - urbp->transfer_buffer_dma_handle + urb->iso_frame_desc[i].offset); + urb->transfer_dma + urb->iso_frame_desc[i].offset); if (i + 1 >= urb->number_of_packets) td->status |= cpu_to_le32(TD_CTRL_IOC); @@ -1831,15 +1799,6 @@ urb->status == -ECONNRESET); resubmit_interrupt = (usb_pipetype(urb->pipe) == PIPE_INTERRUPT && urb->interval); - - if (urbp->transfer_buffer_dma_handle) - pci_dma_sync_single(uhci->dev, urbp->transfer_buffer_dma_handle, - urb->transfer_buffer_length, usb_pipein(urb->pipe) ? - PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); - - if (urbp->setup_packet_dma_handle) - pci_dma_sync_single(uhci->dev, urbp->setup_packet_dma_handle, - sizeof(struct usb_ctrlrequest), PCI_DMA_TODEVICE); status = urbp->status; if (!resubmit_interrupt || killed) diff -Nru a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h --- a/drivers/usb/host/uhci-hcd.h Tue Aug 13 15:34:06 2002 +++ b/drivers/usb/host/uhci-hcd.h Tue Aug 13 15:34:06 2002 @@ -338,9 +338,6 @@ struct urb *urb; struct usb_device *dev; - dma_addr_t setup_packet_dma_handle; - dma_addr_t transfer_buffer_dma_handle; - struct uhci_qh *qh; /* QH for this URB */ struct list_head td_list; /* P: urb->lock */