ChangeSet 1.1305.7.4, 2003/06/13 16:41:21-07:00, [EMAIL PROTECTED]
[PATCH] USB: Use separate transport_flags bits for transfer_dma
Use separate transfer_flags bits for transfer_dma and setup_dma
Documentation/usb/dma.txt | 31 ++++++++++++++++-------
drivers/usb/class/usblp.c | 4 +--
drivers/usb/core/hcd.c | 20 +++++++++------
drivers/usb/core/hub.c | 2 -
drivers/usb/core/message.c | 3 +-
drivers/usb/core/urb.c | 2 -
drivers/usb/core/usb.c | 56 +++++++++++++++++++++++++++---------------
drivers/usb/input/aiptek.c | 2 -
drivers/usb/input/hid-core.c | 7 +++--
drivers/usb/input/kbtab.c | 2 -
drivers/usb/input/powermate.c | 4 +--
drivers/usb/input/usbkbd.c | 5 ++-
drivers/usb/input/usbmouse.c | 2 -
drivers/usb/input/wacom.c | 2 -
drivers/usb/input/xpad.c | 2 -
drivers/usb/misc/usbtest.c | 2 -
include/linux/usb.h | 51 +++++++++++++++++++++-----------------
17 files changed, 121 insertions(+), 76 deletions(-)
diff -Nru a/Documentation/usb/dma.txt b/Documentation/usb/dma.txt
--- a/Documentation/usb/dma.txt Wed Jun 18 11:16:00 2003
+++ b/Documentation/usb/dma.txt Wed Jun 18 11:16:00 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 Wed Jun 18 11:16:00 2003
+++ b/drivers/usb/class/usblp.c Wed Jun 18 11:16:00 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 Wed Jun 18 11:16:00 2003
+++ b/drivers/usb/core/hcd.c Wed Jun 18 11:16:00 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 Wed Jun 18 11:16:00 2003
+++ b/drivers/usb/core/hub.c Wed Jun 18 11:16:00 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 Wed Jun 18 11:16:00 2003
+++ b/drivers/usb/core/message.c Wed Jun 18 11:16:00 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 Wed Jun 18 11:16:00 2003
+++ b/drivers/usb/core/urb.c Wed Jun 18 11:16:00 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 Wed Jun 18 11:16:00 2003
+++ b/drivers/usb/core/usb.c Wed Jun 18 11:16:00 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 Wed Jun 18 11:16:00 2003
+++ b/drivers/usb/input/aiptek.c Wed Jun 18 11:16:00 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 Wed Jun 18 11:16:00 2003
+++ b/drivers/usb/input/hid-core.c Wed Jun 18 11:16:00 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 Wed Jun 18 11:16:00 2003
+++ b/drivers/usb/input/kbtab.c Wed Jun 18 11:16:00 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 Wed Jun 18 11:16:00 2003
+++ b/drivers/usb/input/powermate.c Wed Jun 18 11:16:00 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 Wed Jun 18 11:16:00 2003
+++ b/drivers/usb/input/usbkbd.c Wed Jun 18 11:16:00 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 Wed Jun 18 11:16:00 2003
+++ b/drivers/usb/input/usbmouse.c Wed Jun 18 11:16:00 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 Wed Jun 18 11:16:00 2003
+++ b/drivers/usb/input/wacom.c Wed Jun 18 11:16:00 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 Wed Jun 18 11:16:00 2003
+++ b/drivers/usb/input/xpad.c Wed Jun 18 11:16:00 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 Wed Jun 18 11:16:00 2003
+++ b/drivers/usb/misc/usbtest.c Wed Jun 18 11:16:00 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 Wed Jun 18 11:16:00 2003
+++ b/include/linux/usb.h Wed Jun 18 11:16:00 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: INetU
Attention Web Developers & Consultants: Become An INetU Hosting Partner.
Refer Dedicated Servers. We Manage Them. You Get 10% Monthly Commission!
INetU Dedicated Managed Hosting http://www.inetu.net/partner/index.php
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel