docs: driver-api: usb: update dma info

We should not hide the recommend APIs in a obscure place.

Signed-off-by: Randy Li <ayaka@soulik.info>
Link: https://lore.kernel.org/r/20230914172336.18761-3-ayaka@soulik.info
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Randy Li 2023-09-15 01:23:24 +08:00 committed by Greg Kroah-Hartman
parent 1cf56299f9
commit 44ceac8c92
1 changed files with 11 additions and 37 deletions

View File

@ -93,44 +93,18 @@ DMA address space of the device. However, most buffers passed to your
driver can safely be used with such DMA mapping. (See the first section
of Documentation/core-api/dma-api-howto.rst, titled "What memory is DMA-able?")
- When you're using scatterlists, you can map everything at once. On some
systems, this kicks in an IOMMU and turns the scatterlists into single
DMA transactions::
- When you have the scatterlists which have been mapped for the USB controller,
you could use the new ``usb_sg_*()`` calls, which would turn scatterlist
into URBs::
int usb_buffer_map_sg (struct usb_device *dev, unsigned pipe,
struct scatterlist *sg, int nents);
int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev,
unsigned pipe, unsigned period, struct scatterlist *sg,
int nents, size_t length, gfp_t mem_flags);
void usb_buffer_dmasync_sg (struct usb_device *dev, unsigned pipe,
struct scatterlist *sg, int n_hw_ents);
void usb_sg_wait(struct usb_sg_request *io);
void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe,
struct scatterlist *sg, int n_hw_ents);
void usb_sg_cancel(struct usb_sg_request *io);
It's probably easier to use the new ``usb_sg_*()`` calls, which do the DMA
mapping and apply other tweaks to make scatterlist i/o be fast.
- Some drivers may prefer to work with the model that they're mapping large
buffers, synchronizing their safe re-use. (If there's no re-use, then let
usbcore do the map/unmap.) Large periodic transfers make good examples
here, since it's cheaper to just synchronize the buffer than to unmap it
each time an urb completes and then re-map it on during resubmission.
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 (``urb->setup_packet`` must be valid too
if urb is a control request)::
struct urb *usb_buffer_map (struct urb *urb);
void usb_buffer_dmasync (struct urb *urb);
void usb_buffer_unmap (struct urb *urb);
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.
They cannot be used for setup_packet buffers in control requests.
Note that several of those interfaces are currently commented out, since
they don't have current users. See the source code. Other than the dmasync
calls (where the underlying DMA primitives have changed), most of them can
easily be commented back in if you want to use them.
When the USB controller doesn't support DMA, the ``usb_sg_init()`` would try
to submit URBs in PIO way as long as the page in scatterlists is not in the
Highmem, which could be very rare in modern architectures.