David:

Here's a revision of my DMA-flags patch, incorporating the changes you
suggested before.

Greg:

If David gives this the okay, please apply.

This will impact the patch that Oliver Neukum sent in this morning for the
kaweth driver.  I couldn't include these changes in my patch because
Oliver's hasn't been applied to the tree yet.  In his hunk starting at
line 526, change

+       kaweth->rx_urb->transfer_flags |= URB_NO_DMA_MAP;

to

+       kaweth->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

Likewise, in the hunk starting at line 634, change

+       kaweth->irq_urb->transfer_flags |= URB_NO_DMA_MAP;

to

+       kaweth->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

Alan Stern


# This is a BitKeeper generated patch for the following project:
# Project Name: greg k-h's linux 2.5 USB kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#                  ChangeSet    1.1648  -> 1.1649 
#       drivers/usb/input/usbkbd.c      1.47    -> 1.48   
#       drivers/usb/input/aiptek.c      1.21    -> 1.22   
#       drivers/usb/class/usblp.c       1.65    -> 1.66   
#       drivers/usb/core/message.c      1.45    -> 1.46   
#       drivers/usb/input/xpad.c        1.22    -> 1.23   
#       drivers/usb/core/usb.c  1.207   -> 1.208  
#       drivers/usb/input/wacom.c       1.34    -> 1.35   
#       drivers/usb/input/powermate.c   1.19    -> 1.20   
#       drivers/usb/core/hub.c  1.108   -> 1.109  
#       Documentation/usb/dma.txt       1.1     -> 1.2    
#       drivers/usb/input/hid-core.c    1.90    -> 1.91   
#       drivers/usb/input/kbtab.c       1.4     -> 1.5    
#        include/linux/usb.h    1.141   -> 1.142  
#       drivers/usb/input/usbmouse.c    1.41    -> 1.42   
#       drivers/usb/misc/usbtest.c      1.27    -> 1.28   
#       drivers/usb/core/urb.c  1.31    -> 1.32   
#       drivers/usb/core/hcd.c  1.105   -> 1.106  
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/06/12      [EMAIL PROTECTED]       1.1649
# Use separate transfer_flags bits for transfer_dma and setup_dma
# --------------------------------------------
#
diff -Nru a/Documentation/usb/dma.txt b/Documentation/usb/dma.txt
--- a/Documentation/usb/dma.txt Thu Jun 12 14:28:01 2003
+++ b/Documentation/usb/dma.txt Thu Jun 12 14:28:01 2003
@@ -15,10 +15,12 @@
   manage dma mappings for existing dma-ready buffers (see below).
 
 - URBs have an additional "transfer_dma" field, as well as a transfer_flags
-  bit saying if it's valid.  (Control requests also needed "setup_dma".) 
+  bit saying if it's valid.  (Control requests also have "setup_dma" and a
+  corresponding transfer_flags bit.)
 
-- "usbcore" will map those DMA addresses, if a DMA-aware driver didn't do it
-  first and set URB_NO_DMA_MAP.  HCDs don't manage dma mappings for urbs.
+- "usbcore" will map those DMA addresses, if a DMA-aware driver didn't do
+  it first and set URB_NO_TRANSFER_DMA_MAP or URB_NO_SETUP_DMA_MAP.  HCDs
+  don't manage dma mappings for URBs.
 
 - There's a new "generic DMA API", parts of which are usable by USB device
   drivers.  Never use dma_set_mask() on any USB interface or device; that
@@ -33,8 +35,9 @@
 - When you're allocating a buffer for DMA purposes anyway, use the buffer
   primitives.  Think of them as kmalloc and kfree that give you the right
   kind of addresses to store in urb->transfer_buffer and urb->transfer_dma,
-  while guaranteeing that hidden copies through DMA "bounce" buffers won't
-  slow things down.  You'd also set URB_NO_DMA_MAP in urb->transfer_flags:
+  while guaranteeing that no hidden copies through DMA "bounce" buffers will
+  slow things down.  You'd also set URB_NO_TRANSFER_DMA_MAP in
+  urb->transfer_flags:
 
        void *usb_buffer_alloc (struct usb_device *dev, size_t size,
                int mem_flags, dma_addr_t *dma);
@@ -42,10 +45,18 @@
        void usb_buffer_free (struct usb_device *dev, size_t size,
                void *addr, dma_addr_t dma);
 
+  For control transfers you can use the buffer primitives or not for each
+  of the transfer buffer and setup buffer independently.  Set the flag bits
+  URB_NO_TRANSFER_DMA_MAP and URB_NO_SETUP_DMA_MAP to indicate which
+  buffers you have prepared.  For non-control transfers URB_NO_SETUP_DMA_MAP
+  is ignored.
+
   The memory buffer returned is "dma-coherent"; sometimes you might need to
   force a consistent memory access ordering by using memory barriers.  It's
   not using a streaming DMA mapping, so it's good for small transfers on
-  systems where the I/O would otherwise tie up an IOMMU mapping.
+  systems where the I/O would otherwise tie up an IOMMU mapping.  (See
+  Documentation/DMA-mapping.txt for definitions of "coherent" and "streaming"
+  DMA mappings.)
 
   Asking for 1/Nth of a page (as well as asking for N pages) is reasonably
   space-efficient.
@@ -91,7 +102,8 @@
 
   These calls all work with initialized urbs:  urb->dev, urb->pipe,
   urb->transfer_buffer, and urb->transfer_buffer_length must all be
-  valid when these calls are used:
+  valid when these calls are used (urb->setup_packet must be valid too
+  if urb is a control request):
 
        struct urb *usb_buffer_map (struct urb *urb);
 
@@ -99,6 +111,6 @@
 
        void usb_buffer_unmap (struct urb *urb);
 
-  The calls manage urb->transfer_dma for you, and set URB_NO_DMA_MAP so that
-  usbcore won't map or unmap the buffer.
-
+  The calls manage urb->transfer_dma for you, and set URB_NO_TRANSFER_DMA_MAP
+  so that usbcore won't map or unmap the buffer.  The same goes for
+  urb->setup_dma and URB_NO_SETUP_DMA_MAP for control requests.
diff -Nru a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
--- a/drivers/usb/class/usblp.c Thu Jun 12 14:28:01 2003
+++ b/drivers/usb/class/usblp.c Thu Jun 12 14:28:01 2003
@@ -858,8 +858,8 @@
        }
 
        usblp->writebuf = usblp->readbuf = NULL;
-       usblp->writeurb->transfer_flags = URB_NO_DMA_MAP;
-       usblp->readurb->transfer_flags = URB_NO_DMA_MAP;
+       usblp->writeurb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
+       usblp->readurb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
        /* Malloc write & read buffers.  We somewhat wastefully
         * malloc both regardless of bidirectionality, because the
         * alternate setting can be changed later via an ioctl. */
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c    Thu Jun 12 14:28:01 2003
+++ b/drivers/usb/core/hcd.c    Thu Jun 12 14:28:01 2003
@@ -1027,7 +1027,8 @@
                 * valid and usb_buffer_{sync,unmap}() not be needed, since
                 * they could clobber root hub response data.
                 */
-               urb->transfer_flags |= URB_NO_DMA_MAP;
+               urb->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP
+                                       | URB_NO_SETUP_DMA_MAP);
                status = rh_urb_enqueue (hcd, urb);
                goto done;
        }
@@ -1035,15 +1036,16 @@
        /* lower level hcd code should use *_dma exclusively,
         * unless it uses pio or talks to another transport.
         */
-       if (!(urb->transfer_flags & URB_NO_DMA_MAP)
-                       && hcd->controller->dma_mask) {
-               if (usb_pipecontrol (urb->pipe))
+       if (hcd->controller->dma_mask) {
+               if (usb_pipecontrol (urb->pipe)
+                       && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
                        urb->setup_dma = dma_map_single (
                                        hcd->controller,
                                        urb->setup_packet,
                                        sizeof (struct usb_ctrlrequest),
                                        DMA_TO_DEVICE);
-               if (urb->transfer_buffer_length != 0)
+               if (urb->transfer_buffer_length != 0
+                       && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))
                        urb->transfer_dma = dma_map_single (
                                        hcd->controller,
                                        urb->transfer_buffer,
@@ -1410,12 +1412,14 @@
        // It would catch exit/unlink paths for all urbs.
 
        /* lower level hcd code should use *_dma exclusively */
-       if (!(urb->transfer_flags & URB_NO_DMA_MAP)) {
-               if (usb_pipecontrol (urb->pipe))
+       if (hcd->controller->dma_mask) {
+               if (usb_pipecontrol (urb->pipe)
+                       && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
                        pci_unmap_single (hcd->pdev, urb->setup_dma,
                                        sizeof (struct usb_ctrlrequest),
                                        PCI_DMA_TODEVICE);
-               if (urb->transfer_buffer_length != 0)
+               if (urb->transfer_buffer_length != 0
+                       && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))
                        pci_unmap_single (hcd->pdev, urb->transfer_dma,
                                        urb->transfer_buffer_length,
                                        usb_pipein (urb->pipe)
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c    Thu Jun 12 14:28:01 2003
+++ b/drivers/usb/core/hub.c    Thu Jun 12 14:28:01 2003
@@ -461,7 +461,7 @@
        usb_fill_int_urb(hub->urb, dev, pipe, *hub->buffer, maxp, hub_irq,
                hub, endpoint->bInterval);
        hub->urb->transfer_dma = hub->buffer_dma;
-       hub->urb->transfer_flags |= URB_NO_DMA_MAP;
+       hub->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
        ret = usb_submit_urb(hub->urb, GFP_KERNEL);
        if (ret) {
                message = "couldn't submit status urb";
diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c
--- a/drivers/usb/core/message.c        Thu Jun 12 14:28:01 2003
+++ b/drivers/usb/core/message.c        Thu Jun 12 14:28:01 2003
@@ -344,7 +344,8 @@
        if (!io->urbs)
                goto nomem;
 
-       urb_flags = URB_ASYNC_UNLINK | URB_NO_DMA_MAP | URB_NO_INTERRUPT;
+       urb_flags = URB_ASYNC_UNLINK | URB_NO_TRANSFER_DMA_MAP
+                       | URB_NO_INTERRUPT;
        if (usb_pipein (pipe))
                urb_flags |= URB_SHORT_NOT_OK;
 
diff -Nru a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
--- a/drivers/usb/core/urb.c    Thu Jun 12 14:28:01 2003
+++ b/drivers/usb/core/urb.c    Thu Jun 12 14:28:01 2003
@@ -297,7 +297,7 @@
 
        /* enforce simple/standard policy */
        allowed = URB_ASYNC_UNLINK;     // affects later unlinks
-       allowed |= URB_NO_DMA_MAP;
+       allowed |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
        allowed |= URB_NO_INTERRUPT;
        switch (temp) {
        case PIPE_BULK:
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c    Thu Jun 12 14:28:01 2003
+++ b/drivers/usb/core/usb.c    Thu Jun 12 14:28:01 2003
@@ -1234,7 +1234,7 @@
 }
 
 /**
- * usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_DMA_MAP
+ * usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP
  * @dev: device the buffer will be used with
  * @size: requested buffer size
  * @mem_flags: affect whether allocation may block
@@ -1245,9 +1245,9 @@
  * specified device.  Such cpu-space buffers are returned along with the DMA
  * address (through the pointer provided).
  *
- * These buffers are used with URB_NO_DMA_MAP set in urb->transfer_flags to
- * avoid behaviors like using "DMA bounce buffers", or tying down I/O mapping
- * hardware for long idle periods.  The implementation varies between
+ * These buffers are used with URB_NO_xxx_DMA_MAP set in urb->transfer_flags
+ * to avoid behaviors like using "DMA bounce buffers", or tying down I/O
+ * mapping hardware for long idle periods.  The implementation varies between
  * platforms, depending on details of how DMA will work to this device.
  * Using these buffers also helps prevent cacheline sharing problems on
  * architectures where CPU caches are not DMA-coherent.
@@ -1291,17 +1291,17 @@
 
 /**
  * usb_buffer_map - create DMA mapping(s) for an urb
- * @urb: urb whose transfer_buffer will be mapped
+ * @urb: urb whose transfer_buffer/setup_packet will be mapped
  *
  * Return value is either null (indicating no buffer could be mapped), or
- * the parameter.  URB_NO_DMA_MAP is added to urb->transfer_flags if the
- * operation succeeds.  If the device is connected to this system through
- * a non-DMA controller, this operation always succeeds.
+ * the parameter.  URB_NO_TRANSFER_DMA_MAP and URB_NO_SETUP_DMA_MAP are
+ * added to urb->transfer_flags if the operation succeeds.  If the device
+ * is connected to this system through a non-DMA controller, this operation
+ * always succeeds.
  *
  * This call would normally be used for an urb which is reused, perhaps
  * as the target of a large periodic transfer, with usb_buffer_dmasync()
- * calls to synchronize memory and dma state.  It may not be used for
- * control requests.
+ * calls to synchronize memory and dma state.
  *
  * Reverse the effect of this call with usb_buffer_unmap().
  */
@@ -1311,7 +1311,6 @@
        struct device           *controller;
 
        if (!urb
-                       || usb_pipecontrol (urb->pipe)
                        || !urb->dev
                        || !(bus = urb->dev->bus)
                        || !(controller = bus->controller))
@@ -1322,17 +1321,23 @@
                        urb->transfer_buffer, urb->transfer_buffer_length,
                        usb_pipein (urb->pipe)
                                ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+               if (usb_pipecontrol (urb->pipe))
+                       urb->setup_dma = dma_map_single (controller,
+                                       urb->setup_packet,
+                                       sizeof (struct usb_ctrlrequest),
+                                       DMA_TO_DEVICE);
        // FIXME generic api broken like pci, can't report errors
        // if (urb->transfer_dma == DMA_ADDR_INVALID) return 0;
        } else
                urb->transfer_dma = ~0;
-       urb->transfer_flags |= URB_NO_DMA_MAP;
+       urb->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP
+                               | URB_NO_SETUP_DMA_MAP);
        return urb;
 }
 
 /**
  * usb_buffer_dmasync - synchronize DMA and CPU view of buffer(s)
- * @urb: urb whose transfer_buffer will be synchronized
+ * @urb: urb whose transfer_buffer/setup_packet will be synchronized
  */
 void usb_buffer_dmasync (struct urb *urb)
 {
@@ -1340,17 +1345,23 @@
        struct device           *controller;
 
        if (!urb
-                       || !(urb->transfer_flags & URB_NO_DMA_MAP)
+                       || !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
                        || !urb->dev
                        || !(bus = urb->dev->bus)
                        || !(controller = bus->controller))
                return;
 
-       if (controller->dma_mask)
+       if (controller->dma_mask) {
                dma_sync_single (controller,
                        urb->transfer_dma, urb->transfer_buffer_length,
                        usb_pipein (urb->pipe)
                                ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+               if (usb_pipecontrol (urb->pipe))
+                       dma_sync_single (controller,
+                                       urb->setup_dma,
+                                       sizeof (struct usb_ctrlrequest),
+                                       DMA_TO_DEVICE);
+       }
 }
 
 /**
@@ -1365,18 +1376,25 @@
        struct device           *controller;
 
        if (!urb
-                       || !(urb->transfer_flags & URB_NO_DMA_MAP)
+                       || !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
                        || !urb->dev
                        || !(bus = urb->dev->bus)
                        || !(controller = bus->controller))
                return;
 
-       if (controller->dma_mask)
+       if (controller->dma_mask) {
                dma_unmap_single (controller,
                        urb->transfer_dma, urb->transfer_buffer_length,
                        usb_pipein (urb->pipe)
                                ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
-       urb->transfer_flags &= ~URB_NO_DMA_MAP;
+               if (usb_pipecontrol (urb->pipe))
+                       dma_unmap_single (controller,
+                                       urb->setup_dma,
+                                       sizeof (struct usb_ctrlrequest),
+                                       DMA_TO_DEVICE);
+       }
+       urb->transfer_flags &= ~(URB_NO_TRANSFER_DMA_MAP
+                               | URB_NO_SETUP_DMA_MAP);
 }
 
 /**
@@ -1391,7 +1409,7 @@
  *
  * The caller is responsible for placing the resulting DMA addresses from
  * the scatterlist into URB transfer buffer pointers, and for setting the
- * URB_NO_DMA_MAP transfer flag in each of those URBs.
+ * URB_NO_TRANSFER_DMA_MAP transfer flag in each of those URBs.
  *
  * Top I/O rates come from queuing URBs, instead of waiting for each one
  * to complete before starting the next I/O.   This is particularly easy
diff -Nru a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
--- a/drivers/usb/input/aiptek.c        Thu Jun 12 14:28:01 2003
+++ b/drivers/usb/input/aiptek.c        Thu Jun 12 14:28:01 2003
@@ -330,7 +330,7 @@
                         aiptek->data, aiptek->features->pktlen,
                         aiptek->features->irq, aiptek, endpoint->bInterval);
        aiptek->irq->transfer_dma = aiptek->data_dma;
-       aiptek->irq->transfer_flags |= URB_NO_DMA_MAP;
+       aiptek->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
        input_register_device(&aiptek->dev);
 
diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c      Thu Jun 12 14:28:01 2003
+++ b/drivers/usb/input/hid-core.c      Thu Jun 12 14:28:01 2003
@@ -1510,7 +1510,7 @@
                        usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, 0,
                                         hid_irq_in, hid, endpoint->bInterval);
                        hid->urbin->transfer_dma = hid->inbuf_dma;
-                       hid->urbin->transfer_flags |= URB_NO_DMA_MAP;
+                       hid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
                } else {
                        if (hid->urbout)
                                continue;
@@ -1520,7 +1520,7 @@
                        usb_fill_bulk_urb(hid->urbout, dev, pipe, hid->outbuf, 0,
                                          hid_irq_out, hid);
                        hid->urbout->transfer_dma = hid->outbuf_dma;
-                       hid->urbout->transfer_flags |= URB_NO_DMA_MAP;
+                       hid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
                }
        }
 
@@ -1569,7 +1569,8 @@
                             hid->ctrlbuf, 1, hid_ctrl, hid);
        hid->urbctrl->setup_dma = hid->cr_dma;
        hid->urbctrl->transfer_dma = hid->ctrlbuf_dma;
-       hid->urbctrl->transfer_flags |= URB_NO_DMA_MAP;
+       hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP
+                               | URB_NO_SETUP_DMA_MAP);
 
        return hid;
 
diff -Nru a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c
--- a/drivers/usb/input/kbtab.c Thu Jun 12 14:28:01 2003
+++ b/drivers/usb/input/kbtab.c Thu Jun 12 14:28:01 2003
@@ -181,7 +181,7 @@
                         kbtab->data, 8,
                         kbtab_irq, kbtab, endpoint->bInterval);
        kbtab->irq->transfer_dma = kbtab->data_dma;
-       kbtab->irq->transfer_flags |= URB_NO_DMA_MAP;
+       kbtab->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
        input_register_device(&kbtab->dev);
 
diff -Nru a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
--- a/drivers/usb/input/powermate.c     Thu Jun 12 14:28:01 2003
+++ b/drivers/usb/input/powermate.c     Thu Jun 12 14:28:01 2003
@@ -180,7 +180,7 @@
                             (void *) pm->configcr, 0, 0,
                             powermate_config_complete, pm);
        pm->config->setup_dma = pm->configcr_dma;
-       pm->config->transfer_flags |= URB_NO_DMA_MAP;
+       pm->config->transfer_flags |= URB_NO_SETUP_DMA_MAP;
 
        if (usb_submit_urb(pm->config, GFP_ATOMIC))
                printk(KERN_ERR "powermate: usb_submit_urb(config) failed");
@@ -355,7 +355,7 @@
                         POWERMATE_PAYLOAD_SIZE, powermate_irq,
                         pm, endpoint->bInterval);
        pm->irq->transfer_dma = pm->data_dma;
-       pm->irq->transfer_flags |= URB_NO_DMA_MAP;
+       pm->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
        /* register our interrupt URB with the USB system */
        if (usb_submit_urb(pm->irq, GFP_KERNEL)) {
diff -Nru a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c
--- a/drivers/usb/input/usbkbd.c        Thu Jun 12 14:28:01 2003
+++ b/drivers/usb/input/usbkbd.c        Thu Jun 12 14:28:01 2003
@@ -282,7 +282,7 @@
                         kbd->new, (maxp > 8 ? 8 : maxp),
                         usb_kbd_irq, kbd, endpoint->bInterval);
        kbd->irq->transfer_dma = kbd->new_dma;
-       kbd->irq->transfer_flags |= URB_NO_DMA_MAP;
+       kbd->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
        kbd->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
        kbd->cr->bRequest = 0x09;
@@ -325,7 +325,8 @@
                             usb_kbd_led, kbd);
        kbd->led->setup_dma = kbd->cr_dma;
        kbd->led->transfer_dma = kbd->leds_dma;
-       kbd->led->transfer_flags |= URB_NO_DMA_MAP;
+       kbd->led->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP
+                               | URB_NO_SETUP_DMA_MAP);
 
        input_register_device(&kbd->dev);
 
diff -Nru a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c
--- a/drivers/usb/input/usbmouse.c      Thu Jun 12 14:28:01 2003
+++ b/drivers/usb/input/usbmouse.c      Thu Jun 12 14:28:01 2003
@@ -207,7 +207,7 @@
                         (maxp > 8 ? 8 : maxp),
                         usb_mouse_irq, mouse, endpoint->bInterval);
        mouse->irq->transfer_dma = mouse->data_dma;
-       mouse->irq->transfer_flags |= URB_NO_DMA_MAP;
+       mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
        input_register_device(&mouse->dev);
        printk(KERN_INFO "input: %s on %s\n", mouse->name, path);
diff -Nru a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
--- a/drivers/usb/input/wacom.c Thu Jun 12 14:28:01 2003
+++ b/drivers/usb/input/wacom.c Thu Jun 12 14:28:01 2003
@@ -590,7 +590,7 @@
                         wacom->data, wacom->features->pktlen,
                         wacom->features->irq, wacom, endpoint->bInterval);
        wacom->irq->transfer_dma = wacom->data_dma;
-       wacom->irq->transfer_flags |= URB_NO_DMA_MAP;
+       wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
        input_register_device(&wacom->dev);
 
diff -Nru a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
--- a/drivers/usb/input/xpad.c  Thu Jun 12 14:28:01 2003
+++ b/drivers/usb/input/xpad.c  Thu Jun 12 14:28:01 2003
@@ -259,7 +259,7 @@
                         xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
                         xpad, ep_irq_in->bInterval);
        xpad->irq_in->transfer_dma = xpad->idata_dma;
-       xpad->irq_in->transfer_flags |= URB_NO_DMA_MAP;
+       xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
        
        xpad->udev = udev;
        
diff -Nru a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
--- a/drivers/usb/misc/usbtest.c        Thu Jun 12 14:28:01 2003
+++ b/drivers/usb/misc/usbtest.c        Thu Jun 12 14:28:01 2003
@@ -107,7 +107,7 @@
        urb->interval = (udev->speed == USB_SPEED_HIGH)
                        ? (INTERRUPT_RATE << 3)
                        : INTERRUPT_RATE;
-       urb->transfer_flags = URB_NO_DMA_MAP;
+       urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
        if (usb_pipein (pipe))
                urb->transfer_flags |= URB_SHORT_NOT_OK;
        urb->transfer_buffer = usb_buffer_alloc (udev, bytes, SLAB_KERNEL,
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h       Thu Jun 12 14:28:01 2003
+++ b/include/linux/usb.h       Thu Jun 12 14:28:01 2003
@@ -492,8 +492,9 @@
  */
 #define URB_SHORT_NOT_OK       0x0001  /* report short reads as errors */
 #define URB_ISO_ASAP           0x0002  /* iso-only, urb->start_frame ignored */
-#define URB_NO_DMA_MAP         0x0004  /* urb->*_dma are valid on submit */
-#define URB_ASYNC_UNLINK       0x0008  /* usb_unlink_urb() returns asap */
+#define URB_NO_TRANSFER_DMA_MAP        0x0004  /* urb->transfer_dma valid on submit */
+#define URB_NO_SETUP_DMA_MAP   0x0008  /* urb->setup_dma valid on submit */
+#define URB_ASYNC_UNLINK       0x0010  /* usb_unlink_urb() returns asap */
 #define URB_NO_FSBR            0x0020  /* UHCI-specific */
 #define URB_ZERO_PACKET                0x0040  /* Finish bulk OUTs with short packet 
*/
 #define URB_NO_INTERRUPT       0x0080  /* HINT: no non-error interrupt needed */
@@ -531,14 +532,15 @@
  *     submission, unlinking, or operation are handled.  Different
  *     kinds of URB can use different flags.
  * @transfer_buffer:  This identifies the buffer to (or from) which
- *     the I/O request will be performed (unless URB_NO_DMA_MAP is set).
- *     This buffer must be suitable for DMA; allocate it with kmalloc()
- *     or equivalent.  For transfers to "in" endpoints, contents of
- *     this buffer will be modified.  This buffer is used for data
+ *     the I/O request will be performed (unless URB_NO_TRANSFER_DMA_MAP
+ *     is set).  This buffer must be suitable for DMA; allocate it with
+ *     kmalloc() or equivalent.  For transfers to "in" endpoints, contents
+ *     of this buffer will be modified.  This buffer is used for data
  *     phases of control transfers.
- * @transfer_dma: When transfer_flags includes URB_NO_DMA_MAP, the device
- *     driver is saying that it provided this DMA address, which the host
- *     controller driver should use instead of the transfer_buffer.
+ * @transfer_dma: When transfer_flags includes URB_NO_TRANSFER_DMA_MAP,
+ *     the device driver is saying that it provided this DMA address,
+ *     which the host controller driver should use in preference to the
+ *     transfer_buffer.
  * @transfer_buffer_length: How big is transfer_buffer.  The transfer may
  *     be broken up into chunks according to the current maximum packet
  *     size for the endpoint, which is a function of the configuration
@@ -553,11 +555,10 @@
  * @setup_packet: Only used for control transfers, this points to eight bytes
  *     of setup data.  Control transfers always start by sending this data
  *     to the device.  Then transfer_buffer is read or written, if needed.
- *     (Not used when URB_NO_DMA_MAP is set.)
- * @setup_dma: For control transfers with URB_NO_DMA_MAP set, the device
- *     driver has provided this DMA address for the setup packet.  The
- *     host controller driver should use this instead of setup_buffer.
- *     If there is a data phase, its buffer is identified by transfer_dma.
+ * @setup_dma: For control transfers with URB_NO_SETUP_DMA_MAP set, the
+ *     device driver has provided this DMA address for the setup packet.
+ *     The host controller driver should use this in preference to
+ *     setup_packet.
  * @start_frame: Returns the initial frame for interrupt or isochronous
  *     transfers.
  * @number_of_packets: Lists the number of ISO transfer buffers.
@@ -589,13 +590,15 @@
  * bounce buffer or talking to an IOMMU),
  * although they're cheap on commodity x86 and ppc hardware.
  *
- * Alternatively, drivers may pass the URB_NO_DMA_MAP transfer flag, which
- * tells the host controller driver that no such mapping is needed since
- * the device driver is DMA-aware.  For example, they might allocate a DMA
- * buffer with usb_buffer_alloc(), or call usb_buffer_map().
- * When this transfer flag is provided, host controller drivers will use the
- * dma addresses found in the transfer_dma and/or setup_dma fields rather than
- * determing a dma address themselves.
+ * Alternatively, drivers may pass the URB_NO_xxx_DMA_MAP transfer flags,
+ * which tell the host controller driver that no such mapping is needed since
+ * the device driver is DMA-aware.  For example, a device driver might
+ * allocate a DMA buffer with usb_buffer_alloc() or call usb_buffer_map().
+ * When these transfer flags are provided, host controller drivers will
+ * attempt to use the dma addresses found in the transfer_dma and/or
+ * setup_dma fields rather than determining a dma address themselves.  (Note
+ * that transfer_buffer and setup_packet must still be set because not all
+ * host controllers use DMA, nor do virtual root hubs).
  *
  * Initialization:
  *
@@ -614,7 +617,11 @@
  * should always terminate with a short packet, even if it means adding an
  * extra zero length packet.
  *
- * Control URBs must provide a setup_packet.
+ * Control URBs must provide a setup_packet.  The setup_packet and
+ * transfer_buffer may each be mapped for DMA or not, independently of
+ * the other.  The transfer_flags bits URB_NO_TRANSFER_DMA_MAP and
+ * URB_NO_SETUP_DMA_MAP indicate which buffers have already been mapped.
+ * URB_NO_SETUP_DMA_MAP is ignored for non-control URBs.
  *
  * Interrupt UBS must provide an interval, saying how often (in milliseconds
  * or, for highspeed devices, 125 microsecond units)






-------------------------------------------------------
This SF.NET email is sponsored by: eBay
Great deals on office technology -- on eBay now! Click here:
http://adfarm.mediaplex.com/ad/ck/711-11697-6916-5
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to