Commit 6843246f authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

[PATCH] USB: Use separate transport_flags bits for transfer_dma

Use separate transfer_flags bits for transfer_dma and setup_dma
parent 6d10b0c3
...@@ -15,10 +15,12 @@ OR: they can now be DMA-aware. ...@@ -15,10 +15,12 @@ OR: they can now be DMA-aware.
manage dma mappings for existing dma-ready buffers (see below). manage dma mappings for existing dma-ready buffers (see below).
- URBs have an additional "transfer_dma" field, as well as a transfer_flags - 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 - "usbcore" will map those DMA addresses, if a DMA-aware driver didn't do
first and set URB_NO_DMA_MAP. HCDs don't manage dma mappings for urbs. 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 - 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 drivers. Never use dma_set_mask() on any USB interface or device; that
...@@ -33,8 +35,9 @@ and effects like cache-trashing can impose subtle penalties. ...@@ -33,8 +35,9 @@ and effects like cache-trashing can impose subtle penalties.
- When you're allocating a buffer for DMA purposes anyway, use the buffer - 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 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, kind of addresses to store in urb->transfer_buffer and urb->transfer_dma,
while guaranteeing that hidden copies through DMA "bounce" buffers won't while guaranteeing that no hidden copies through DMA "bounce" buffers will
slow things down. You'd also set URB_NO_DMA_MAP in urb->transfer_flags: 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, void *usb_buffer_alloc (struct usb_device *dev, size_t size,
int mem_flags, dma_addr_t *dma); int mem_flags, dma_addr_t *dma);
...@@ -42,10 +45,18 @@ and effects like cache-trashing can impose subtle penalties. ...@@ -42,10 +45,18 @@ and effects like cache-trashing can impose subtle penalties.
void usb_buffer_free (struct usb_device *dev, size_t size, void usb_buffer_free (struct usb_device *dev, size_t size,
void *addr, dma_addr_t dma); 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 The memory buffer returned is "dma-coherent"; sometimes you might need to
force a consistent memory access ordering by using memory barriers. It's 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 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 Asking for 1/Nth of a page (as well as asking for N pages) is reasonably
space-efficient. space-efficient.
...@@ -91,7 +102,8 @@ DMA address space of the device. ...@@ -91,7 +102,8 @@ DMA address space of the device.
These calls all work with initialized urbs: urb->dev, urb->pipe, These calls all work with initialized urbs: urb->dev, urb->pipe,
urb->transfer_buffer, and urb->transfer_buffer_length must all be 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); struct urb *usb_buffer_map (struct urb *urb);
...@@ -99,6 +111,6 @@ DMA address space of the device. ...@@ -99,6 +111,6 @@ DMA address space of the device.
void usb_buffer_unmap (struct urb *urb); void usb_buffer_unmap (struct urb *urb);
The calls manage urb->transfer_dma for you, and set URB_NO_DMA_MAP so that The calls manage urb->transfer_dma for you, and set URB_NO_TRANSFER_DMA_MAP
usbcore won't map or unmap the buffer. 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.
...@@ -858,8 +858,8 @@ static int usblp_probe(struct usb_interface *intf, ...@@ -858,8 +858,8 @@ static int usblp_probe(struct usb_interface *intf,
} }
usblp->writebuf = usblp->readbuf = NULL; usblp->writebuf = usblp->readbuf = NULL;
usblp->writeurb->transfer_flags = URB_NO_DMA_MAP; usblp->writeurb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
usblp->readurb->transfer_flags = URB_NO_DMA_MAP; usblp->readurb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
/* Malloc write & read buffers. We somewhat wastefully /* Malloc write & read buffers. We somewhat wastefully
* malloc both regardless of bidirectionality, because the * malloc both regardless of bidirectionality, because the
* alternate setting can be changed later via an ioctl. */ * alternate setting can be changed later via an ioctl. */
......
...@@ -1027,7 +1027,8 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags) ...@@ -1027,7 +1027,8 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
* valid and usb_buffer_{sync,unmap}() not be needed, since * valid and usb_buffer_{sync,unmap}() not be needed, since
* they could clobber root hub response data. * 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); status = rh_urb_enqueue (hcd, urb);
goto done; goto done;
} }
...@@ -1035,15 +1036,16 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags) ...@@ -1035,15 +1036,16 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
/* lower level hcd code should use *_dma exclusively, /* lower level hcd code should use *_dma exclusively,
* unless it uses pio or talks to another transport. * unless it uses pio or talks to another transport.
*/ */
if (!(urb->transfer_flags & URB_NO_DMA_MAP) if (hcd->controller->dma_mask) {
&& hcd->controller->dma_mask) { if (usb_pipecontrol (urb->pipe)
if (usb_pipecontrol (urb->pipe)) && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
urb->setup_dma = dma_map_single ( urb->setup_dma = dma_map_single (
hcd->controller, hcd->controller,
urb->setup_packet, urb->setup_packet,
sizeof (struct usb_ctrlrequest), sizeof (struct usb_ctrlrequest),
DMA_TO_DEVICE); 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 ( urb->transfer_dma = dma_map_single (
hcd->controller, hcd->controller,
urb->transfer_buffer, urb->transfer_buffer,
...@@ -1410,12 +1412,14 @@ void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs ...@@ -1410,12 +1412,14 @@ void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs
// It would catch exit/unlink paths for all urbs. // It would catch exit/unlink paths for all urbs.
/* lower level hcd code should use *_dma exclusively */ /* lower level hcd code should use *_dma exclusively */
if (!(urb->transfer_flags & URB_NO_DMA_MAP)) { if (hcd->controller->dma_mask) {
if (usb_pipecontrol (urb->pipe)) if (usb_pipecontrol (urb->pipe)
&& !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
pci_unmap_single (hcd->pdev, urb->setup_dma, pci_unmap_single (hcd->pdev, urb->setup_dma,
sizeof (struct usb_ctrlrequest), sizeof (struct usb_ctrlrequest),
PCI_DMA_TODEVICE); 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, pci_unmap_single (hcd->pdev, urb->transfer_dma,
urb->transfer_buffer_length, urb->transfer_buffer_length,
usb_pipein (urb->pipe) usb_pipein (urb->pipe)
......
...@@ -461,7 +461,7 @@ static int hub_configure(struct usb_hub *hub, ...@@ -461,7 +461,7 @@ static int hub_configure(struct usb_hub *hub,
usb_fill_int_urb(hub->urb, dev, pipe, *hub->buffer, maxp, hub_irq, usb_fill_int_urb(hub->urb, dev, pipe, *hub->buffer, maxp, hub_irq,
hub, endpoint->bInterval); hub, endpoint->bInterval);
hub->urb->transfer_dma = hub->buffer_dma; 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); ret = usb_submit_urb(hub->urb, GFP_KERNEL);
if (ret) { if (ret) {
message = "couldn't submit status urb"; message = "couldn't submit status urb";
......
...@@ -344,7 +344,8 @@ int usb_sg_init ( ...@@ -344,7 +344,8 @@ int usb_sg_init (
if (!io->urbs) if (!io->urbs)
goto nomem; 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)) if (usb_pipein (pipe))
urb_flags |= URB_SHORT_NOT_OK; urb_flags |= URB_SHORT_NOT_OK;
......
...@@ -297,7 +297,7 @@ int usb_submit_urb(struct urb *urb, int mem_flags) ...@@ -297,7 +297,7 @@ int usb_submit_urb(struct urb *urb, int mem_flags)
/* enforce simple/standard policy */ /* enforce simple/standard policy */
allowed = URB_ASYNC_UNLINK; // affects later unlinks 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; allowed |= URB_NO_INTERRUPT;
switch (temp) { switch (temp) {
case PIPE_BULK: case PIPE_BULK:
......
...@@ -1234,7 +1234,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent) ...@@ -1234,7 +1234,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
} }
/** /**
* 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 * @dev: device the buffer will be used with
* @size: requested buffer size * @size: requested buffer size
* @mem_flags: affect whether allocation may block * @mem_flags: affect whether allocation may block
...@@ -1245,9 +1245,9 @@ int usb_new_device(struct usb_device *dev, struct device *parent) ...@@ -1245,9 +1245,9 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
* specified device. Such cpu-space buffers are returned along with the DMA * specified device. Such cpu-space buffers are returned along with the DMA
* address (through the pointer provided). * address (through the pointer provided).
* *
* These buffers are used with URB_NO_DMA_MAP set in urb->transfer_flags to * These buffers are used with URB_NO_xxx_DMA_MAP set in urb->transfer_flags
* avoid behaviors like using "DMA bounce buffers", or tying down I/O mapping * to avoid behaviors like using "DMA bounce buffers", or tying down I/O
* hardware for long idle periods. The implementation varies between * mapping hardware for long idle periods. The implementation varies between
* platforms, depending on details of how DMA will work to this device. * platforms, depending on details of how DMA will work to this device.
* Using these buffers also helps prevent cacheline sharing problems on * Using these buffers also helps prevent cacheline sharing problems on
* architectures where CPU caches are not DMA-coherent. * architectures where CPU caches are not DMA-coherent.
...@@ -1291,17 +1291,17 @@ void usb_buffer_free ( ...@@ -1291,17 +1291,17 @@ void usb_buffer_free (
/** /**
* usb_buffer_map - create DMA mapping(s) for an urb * 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 * 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 * the parameter. URB_NO_TRANSFER_DMA_MAP and URB_NO_SETUP_DMA_MAP are
* operation succeeds. If the device is connected to this system through * added to urb->transfer_flags if the operation succeeds. If the device
* a non-DMA controller, this operation always succeeds. * 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 * 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() * 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 * calls to synchronize memory and dma state.
* control requests.
* *
* Reverse the effect of this call with usb_buffer_unmap(). * Reverse the effect of this call with usb_buffer_unmap().
*/ */
...@@ -1311,7 +1311,6 @@ struct urb *usb_buffer_map (struct urb *urb) ...@@ -1311,7 +1311,6 @@ struct urb *usb_buffer_map (struct urb *urb)
struct device *controller; struct device *controller;
if (!urb if (!urb
|| usb_pipecontrol (urb->pipe)
|| !urb->dev || !urb->dev
|| !(bus = urb->dev->bus) || !(bus = urb->dev->bus)
|| !(controller = bus->controller)) || !(controller = bus->controller))
...@@ -1322,17 +1321,23 @@ struct urb *usb_buffer_map (struct urb *urb) ...@@ -1322,17 +1321,23 @@ struct urb *usb_buffer_map (struct urb *urb)
urb->transfer_buffer, urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_buffer_length,
usb_pipein (urb->pipe) usb_pipein (urb->pipe)
? DMA_FROM_DEVICE : DMA_TO_DEVICE); ? 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 // FIXME generic api broken like pci, can't report errors
// if (urb->transfer_dma == DMA_ADDR_INVALID) return 0; // if (urb->transfer_dma == DMA_ADDR_INVALID) return 0;
} else } else
urb->transfer_dma = ~0; 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; return urb;
} }
/** /**
* usb_buffer_dmasync - synchronize DMA and CPU view of buffer(s) * 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) void usb_buffer_dmasync (struct urb *urb)
{ {
...@@ -1340,17 +1345,23 @@ void usb_buffer_dmasync (struct urb *urb) ...@@ -1340,17 +1345,23 @@ void usb_buffer_dmasync (struct urb *urb)
struct device *controller; struct device *controller;
if (!urb if (!urb
|| !(urb->transfer_flags & URB_NO_DMA_MAP) || !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
|| !urb->dev || !urb->dev
|| !(bus = urb->dev->bus) || !(bus = urb->dev->bus)
|| !(controller = bus->controller)) || !(controller = bus->controller))
return; return;
if (controller->dma_mask) if (controller->dma_mask) {
dma_sync_single (controller, dma_sync_single (controller,
urb->transfer_dma, urb->transfer_buffer_length, urb->transfer_dma, urb->transfer_buffer_length,
usb_pipein (urb->pipe) usb_pipein (urb->pipe)
? DMA_FROM_DEVICE : DMA_TO_DEVICE); ? 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 @@ void usb_buffer_unmap (struct urb *urb) ...@@ -1365,18 +1376,25 @@ void usb_buffer_unmap (struct urb *urb)
struct device *controller; struct device *controller;
if (!urb if (!urb
|| !(urb->transfer_flags & URB_NO_DMA_MAP) || !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
|| !urb->dev || !urb->dev
|| !(bus = urb->dev->bus) || !(bus = urb->dev->bus)
|| !(controller = bus->controller)) || !(controller = bus->controller))
return; return;
if (controller->dma_mask) if (controller->dma_mask) {
dma_unmap_single (controller, dma_unmap_single (controller,
urb->transfer_dma, urb->transfer_buffer_length, urb->transfer_dma, urb->transfer_buffer_length,
usb_pipein (urb->pipe) usb_pipein (urb->pipe)
? DMA_FROM_DEVICE : DMA_TO_DEVICE); ? 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 @@ void usb_buffer_unmap (struct urb *urb) ...@@ -1391,7 +1409,7 @@ void usb_buffer_unmap (struct urb *urb)
* *
* The caller is responsible for placing the resulting DMA addresses from * The caller is responsible for placing the resulting DMA addresses from
* the scatterlist into URB transfer buffer pointers, and for setting the * 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 * 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 * to complete before starting the next I/O. This is particularly easy
......
...@@ -330,7 +330,7 @@ aiptek_probe(struct usb_interface *intf, ...@@ -330,7 +330,7 @@ aiptek_probe(struct usb_interface *intf,
aiptek->data, aiptek->features->pktlen, aiptek->data, aiptek->features->pktlen,
aiptek->features->irq, aiptek, endpoint->bInterval); aiptek->features->irq, aiptek, endpoint->bInterval);
aiptek->irq->transfer_dma = aiptek->data_dma; 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); input_register_device(&aiptek->dev);
......
...@@ -1510,7 +1510,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) ...@@ -1510,7 +1510,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, 0, usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, 0,
hid_irq_in, hid, endpoint->bInterval); hid_irq_in, hid, endpoint->bInterval);
hid->urbin->transfer_dma = hid->inbuf_dma; 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 { } else {
if (hid->urbout) if (hid->urbout)
continue; continue;
...@@ -1520,7 +1520,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) ...@@ -1520,7 +1520,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
usb_fill_bulk_urb(hid->urbout, dev, pipe, hid->outbuf, 0, usb_fill_bulk_urb(hid->urbout, dev, pipe, hid->outbuf, 0,
hid_irq_out, hid); hid_irq_out, hid);
hid->urbout->transfer_dma = hid->outbuf_dma; 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 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) ...@@ -1569,7 +1569,8 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
hid->ctrlbuf, 1, hid_ctrl, hid); hid->ctrlbuf, 1, hid_ctrl, hid);
hid->urbctrl->setup_dma = hid->cr_dma; hid->urbctrl->setup_dma = hid->cr_dma;
hid->urbctrl->transfer_dma = hid->ctrlbuf_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; return hid;
......
...@@ -181,7 +181,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -181,7 +181,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
kbtab->data, 8, kbtab->data, 8,
kbtab_irq, kbtab, endpoint->bInterval); kbtab_irq, kbtab, endpoint->bInterval);
kbtab->irq->transfer_dma = kbtab->data_dma; 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); input_register_device(&kbtab->dev);
......
...@@ -180,7 +180,7 @@ static void powermate_sync_state(struct powermate_device *pm) ...@@ -180,7 +180,7 @@ static void powermate_sync_state(struct powermate_device *pm)
(void *) pm->configcr, 0, 0, (void *) pm->configcr, 0, 0,
powermate_config_complete, pm); powermate_config_complete, pm);
pm->config->setup_dma = pm->configcr_dma; 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)) if (usb_submit_urb(pm->config, GFP_ATOMIC))
printk(KERN_ERR "powermate: usb_submit_urb(config) failed"); printk(KERN_ERR "powermate: usb_submit_urb(config) failed");
...@@ -355,7 +355,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i ...@@ -355,7 +355,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
POWERMATE_PAYLOAD_SIZE, powermate_irq, POWERMATE_PAYLOAD_SIZE, powermate_irq,
pm, endpoint->bInterval); pm, endpoint->bInterval);
pm->irq->transfer_dma = pm->data_dma; 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 */ /* register our interrupt URB with the USB system */
if (usb_submit_urb(pm->irq, GFP_KERNEL)) { if (usb_submit_urb(pm->irq, GFP_KERNEL)) {
......
...@@ -282,7 +282,7 @@ static int usb_kbd_probe(struct usb_interface *iface, ...@@ -282,7 +282,7 @@ static int usb_kbd_probe(struct usb_interface *iface,
kbd->new, (maxp > 8 ? 8 : maxp), kbd->new, (maxp > 8 ? 8 : maxp),
usb_kbd_irq, kbd, endpoint->bInterval); usb_kbd_irq, kbd, endpoint->bInterval);
kbd->irq->transfer_dma = kbd->new_dma; 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->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
kbd->cr->bRequest = 0x09; kbd->cr->bRequest = 0x09;
...@@ -325,7 +325,8 @@ static int usb_kbd_probe(struct usb_interface *iface, ...@@ -325,7 +325,8 @@ static int usb_kbd_probe(struct usb_interface *iface,
usb_kbd_led, kbd); usb_kbd_led, kbd);
kbd->led->setup_dma = kbd->cr_dma; kbd->led->setup_dma = kbd->cr_dma;
kbd->led->transfer_dma = kbd->leds_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); input_register_device(&kbd->dev);
......
...@@ -207,7 +207,7 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_ ...@@ -207,7 +207,7 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_
(maxp > 8 ? 8 : maxp), (maxp > 8 ? 8 : maxp),
usb_mouse_irq, mouse, endpoint->bInterval); usb_mouse_irq, mouse, endpoint->bInterval);
mouse->irq->transfer_dma = mouse->data_dma; 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); input_register_device(&mouse->dev);
printk(KERN_INFO "input: %s on %s\n", mouse->name, path); printk(KERN_INFO "input: %s on %s\n", mouse->name, path);
......
...@@ -590,7 +590,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -590,7 +590,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
wacom->data, wacom->features->pktlen, wacom->data, wacom->features->pktlen,
wacom->features->irq, wacom, endpoint->bInterval); wacom->features->irq, wacom, endpoint->bInterval);
wacom->irq->transfer_dma = wacom->data_dma; 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); input_register_device(&wacom->dev);
......
...@@ -259,7 +259,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id ...@@ -259,7 +259,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
xpad->idata, XPAD_PKT_LEN, xpad_irq_in, xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
xpad, ep_irq_in->bInterval); xpad, ep_irq_in->bInterval);
xpad->irq_in->transfer_dma = xpad->idata_dma; 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; xpad->udev = udev;
......
...@@ -107,7 +107,7 @@ static struct urb *simple_alloc_urb ( ...@@ -107,7 +107,7 @@ static struct urb *simple_alloc_urb (
urb->interval = (udev->speed == USB_SPEED_HIGH) urb->interval = (udev->speed == USB_SPEED_HIGH)
? (INTERRUPT_RATE << 3) ? (INTERRUPT_RATE << 3)
: INTERRUPT_RATE; : INTERRUPT_RATE;
urb->transfer_flags = URB_NO_DMA_MAP; urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
if (usb_pipein (pipe)) if (usb_pipein (pipe))
urb->transfer_flags |= URB_SHORT_NOT_OK; urb->transfer_flags |= URB_SHORT_NOT_OK;
urb->transfer_buffer = usb_buffer_alloc (udev, bytes, SLAB_KERNEL, urb->transfer_buffer = usb_buffer_alloc (udev, bytes, SLAB_KERNEL,
......
...@@ -492,8 +492,9 @@ extern int usb_disabled(void); ...@@ -492,8 +492,9 @@ extern int usb_disabled(void);
*/ */
#define URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */ #define URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */
#define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame ignored */ #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_NO_TRANSFER_DMA_MAP 0x0004 /* urb->transfer_dma valid on submit */
#define URB_ASYNC_UNLINK 0x0008 /* usb_unlink_urb() returns asap */ #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_NO_FSBR 0x0020 /* UHCI-specific */
#define URB_ZERO_PACKET 0x0040 /* Finish bulk OUTs with short packet */ #define URB_ZERO_PACKET 0x0040 /* Finish bulk OUTs with short packet */
#define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt needed */ #define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt needed */
...@@ -531,14 +532,15 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *); ...@@ -531,14 +532,15 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
* submission, unlinking, or operation are handled. Different * submission, unlinking, or operation are handled. Different
* kinds of URB can use different flags. * kinds of URB can use different flags.
* @transfer_buffer: This identifies the buffer to (or from) which * @transfer_buffer: This identifies the buffer to (or from) which
* the I/O request will be performed (unless URB_NO_DMA_MAP is set). * the I/O request will be performed (unless URB_NO_TRANSFER_DMA_MAP
* This buffer must be suitable for DMA; allocate it with kmalloc() * is set). This buffer must be suitable for DMA; allocate it with
* or equivalent. For transfers to "in" endpoints, contents of * kmalloc() or equivalent. For transfers to "in" endpoints, contents
* this buffer will be modified. This buffer is used for data * of this buffer will be modified. This buffer is used for data
* phases of control transfers. * phases of control transfers.
* @transfer_dma: When transfer_flags includes URB_NO_DMA_MAP, the device * @transfer_dma: When transfer_flags includes URB_NO_TRANSFER_DMA_MAP,
* driver is saying that it provided this DMA address, which the host * the device driver is saying that it provided this DMA address,
* controller driver should use instead of the transfer_buffer. * which the host controller driver should use in preference to the
* transfer_buffer.
* @transfer_buffer_length: How big is transfer_buffer. The transfer may * @transfer_buffer_length: How big is transfer_buffer. The transfer may
* be broken up into chunks according to the current maximum packet * be broken up into chunks according to the current maximum packet
* size for the endpoint, which is a function of the configuration * size for the endpoint, which is a function of the configuration
...@@ -553,11 +555,10 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *); ...@@ -553,11 +555,10 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
* @setup_packet: Only used for control transfers, this points to eight bytes * @setup_packet: Only used for control transfers, this points to eight bytes
* of setup data. Control transfers always start by sending this data * of setup data. Control transfers always start by sending this data
* to the device. Then transfer_buffer is read or written, if needed. * 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_SETUP_DMA_MAP set, the
* @setup_dma: For control transfers with URB_NO_DMA_MAP set, the device * device driver has provided this DMA address for the setup packet.
* driver has provided this DMA address for the setup packet. The * The host controller driver should use this in preference to
* host controller driver should use this instead of setup_buffer. * setup_packet.
* If there is a data phase, its buffer is identified by transfer_dma.
* @start_frame: Returns the initial frame for interrupt or isochronous * @start_frame: Returns the initial frame for interrupt or isochronous
* transfers. * transfers.
* @number_of_packets: Lists the number of ISO transfer buffers. * @number_of_packets: Lists the number of ISO transfer buffers.
...@@ -589,13 +590,15 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *); ...@@ -589,13 +590,15 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
* bounce buffer or talking to an IOMMU), * bounce buffer or talking to an IOMMU),
* although they're cheap on commodity x86 and ppc hardware. * although they're cheap on commodity x86 and ppc hardware.
* *
* Alternatively, drivers may pass the URB_NO_DMA_MAP transfer flag, which * Alternatively, drivers may pass the URB_NO_xxx_DMA_MAP transfer flags,
* tells the host controller driver that no such mapping is needed since * which tell the host controller driver that no such mapping is needed since
* the device driver is DMA-aware. For example, they might allocate a DMA * the device driver is DMA-aware. For example, a device driver might
* buffer with usb_buffer_alloc(), or call usb_buffer_map(). * 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 * When these transfer flags are provided, host controller drivers will
* dma addresses found in the transfer_dma and/or setup_dma fields rather than * attempt to use the dma addresses found in the transfer_dma and/or
* determing a dma address themselves. * 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: * Initialization:
* *
...@@ -614,7 +617,11 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *); ...@@ -614,7 +617,11 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
* should always terminate with a short packet, even if it means adding an * should always terminate with a short packet, even if it means adding an
* extra zero length packet. * 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 * Interrupt UBS must provide an interval, saying how often (in milliseconds
* or, for highspeed devices, 125 microsecond units) * or, for highspeed devices, 125 microsecond units)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment