Commit 2694a48d9007a8bdf1731c1b97d4942c9cc49296

Authored by Robert Morell
Committed by Greg Kroah-Hartman
1 parent c8cf203a1d

USB: HCD: Add driver hooks for (un)?map_urb_for_dma

Provide optional hooks for the host controller driver to override the
default DMA mapping and unmapping routines.  In general, these shouldn't
be necessary unless the host controller has special DMA requirements,
such as alignment contraints.  If these are not specified, the
general usb_hcd_(un)?map_urb_for_dma functions will be used instead.
Also, pass the status to unmap_urb_for_dma so it can know whether the
DMA buffer has been overwritten.

Finally, add a flag to be used by these implementations if they
allocated a temporary buffer so it can be freed properly when unmapping.

Signed-off-by: Robert Morell <rmorell@nvidia.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

Showing 3 changed files with 36 additions and 2 deletions Side-by-side Diff

drivers/usb/core/hcd.c
... ... @@ -1281,6 +1281,14 @@
1281 1281 }
1282 1282 EXPORT_SYMBOL_GPL(usb_hcd_unmap_urb_setup_for_dma);
1283 1283  
  1284 +static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
  1285 +{
  1286 + if (hcd->driver->unmap_urb_for_dma)
  1287 + hcd->driver->unmap_urb_for_dma(hcd, urb);
  1288 + else
  1289 + usb_hcd_unmap_urb_for_dma(hcd, urb);
  1290 +}
  1291 +
1284 1292 void usb_hcd_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
1285 1293 {
1286 1294 enum dma_data_direction dir;
... ... @@ -1319,6 +1327,15 @@
1319 1327 static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
1320 1328 gfp_t mem_flags)
1321 1329 {
  1330 + if (hcd->driver->map_urb_for_dma)
  1331 + return hcd->driver->map_urb_for_dma(hcd, urb, mem_flags);
  1332 + else
  1333 + return usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
  1334 +}
  1335 +
  1336 +int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
  1337 + gfp_t mem_flags)
  1338 +{
1322 1339 enum dma_data_direction dir;
1323 1340 int ret = 0;
1324 1341  
... ... @@ -1414,6 +1431,7 @@
1414 1431 }
1415 1432 return ret;
1416 1433 }
  1434 +EXPORT_SYMBOL_GPL(usb_hcd_map_urb_for_dma);
1417 1435  
1418 1436 /*-------------------------------------------------------------------------*/
1419 1437  
... ... @@ -1451,7 +1469,7 @@
1451 1469 if (likely(status == 0)) {
1452 1470 status = hcd->driver->urb_enqueue(hcd, urb, mem_flags);
1453 1471 if (unlikely(status))
1454   - usb_hcd_unmap_urb_for_dma(hcd, urb);
  1472 + unmap_urb_for_dma(hcd, urb);
1455 1473 }
1456 1474 }
1457 1475  
... ... @@ -1557,7 +1575,7 @@
1557 1575 !status))
1558 1576 status = -EREMOTEIO;
1559 1577  
1560   - usb_hcd_unmap_urb_for_dma(hcd, urb);
  1578 + unmap_urb_for_dma(hcd, urb);
1561 1579 usbmon_urb_complete(&hcd->self, urb, status);
1562 1580 usb_unanchor_urb(urb);
1563 1581  
... ... @@ -976,6 +976,7 @@
976 976 #define URB_SETUP_MAP_SINGLE 0x00100000 /* Setup packet DMA mapped */
977 977 #define URB_SETUP_MAP_LOCAL 0x00200000 /* HCD-local setup packet */
978 978 #define URB_DMA_SG_COMBINED 0x00400000 /* S-G entries were combined */
  979 +#define URB_ALIGNED_TEMP_BUFFER 0x00800000 /* Temp buffer was alloc'd */
979 980  
980 981 struct usb_iso_packet_descriptor {
981 982 unsigned int offset;
include/linux/usb/hcd.h
... ... @@ -233,6 +233,19 @@
233 233 int (*urb_dequeue)(struct usb_hcd *hcd,
234 234 struct urb *urb, int status);
235 235  
  236 + /*
  237 + * (optional) these hooks allow an HCD to override the default DMA
  238 + * mapping and unmapping routines. In general, they shouldn't be
  239 + * necessary unless the host controller has special DMA requirements,
  240 + * such as alignment contraints. If these are not specified, the
  241 + * general usb_hcd_(un)?map_urb_for_dma functions will be used instead
  242 + * (and it may be a good idea to call these functions in your HCD
  243 + * implementation)
  244 + */
  245 + int (*map_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb,
  246 + gfp_t mem_flags);
  247 + void (*unmap_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb);
  248 +
236 249 /* hw synch, freeing endpoint resources that urb_dequeue can't */
237 250 void (*endpoint_disable)(struct usb_hcd *hcd,
238 251 struct usb_host_endpoint *ep);
... ... @@ -329,6 +342,8 @@
329 342 extern int usb_hcd_unlink_urb(struct urb *urb, int status);
330 343 extern void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb,
331 344 int status);
  345 +extern int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
  346 + gfp_t mem_flags);
332 347 extern void usb_hcd_unmap_urb_setup_for_dma(struct usb_hcd *, struct urb *);
333 348 extern void usb_hcd_unmap_urb_for_dma(struct usb_hcd *, struct urb *);
334 349 extern void usb_hcd_flush_endpoint(struct usb_device *udev,