diff options
-rw-r--r-- | drivers/usb/core/hcd.c | 22 | ||||
-rw-r--r-- | include/linux/usb.h | 1 | ||||
-rw-r--r-- | include/linux/usb/hcd.h | 15 |
3 files changed, 36 insertions, 2 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 335c1ddb260d..d0b782c4523a 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -1281,6 +1281,14 @@ void usb_hcd_unmap_urb_setup_for_dma(struct usb_hcd *hcd, struct urb *urb) | |||
1281 | } | 1281 | } |
1282 | EXPORT_SYMBOL_GPL(usb_hcd_unmap_urb_setup_for_dma); | 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 | void usb_hcd_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) | 1292 | void usb_hcd_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) |
1285 | { | 1293 | { |
1286 | enum dma_data_direction dir; | 1294 | enum dma_data_direction dir; |
@@ -1319,6 +1327,15 @@ EXPORT_SYMBOL_GPL(usb_hcd_unmap_urb_for_dma); | |||
1319 | static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, | 1327 | static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, |
1320 | gfp_t mem_flags) | 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 | enum dma_data_direction dir; | 1339 | enum dma_data_direction dir; |
1323 | int ret = 0; | 1340 | int ret = 0; |
1324 | 1341 | ||
@@ -1414,6 +1431,7 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, | |||
1414 | } | 1431 | } |
1415 | return ret; | 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 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) | |||
1451 | if (likely(status == 0)) { | 1469 | if (likely(status == 0)) { |
1452 | status = hcd->driver->urb_enqueue(hcd, urb, mem_flags); | 1470 | status = hcd->driver->urb_enqueue(hcd, urb, mem_flags); |
1453 | if (unlikely(status)) | 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 @@ void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status) | |||
1557 | !status)) | 1575 | !status)) |
1558 | status = -EREMOTEIO; | 1576 | status = -EREMOTEIO; |
1559 | 1577 | ||
1560 | usb_hcd_unmap_urb_for_dma(hcd, urb); | 1578 | unmap_urb_for_dma(hcd, urb); |
1561 | usbmon_urb_complete(&hcd->self, urb, status); | 1579 | usbmon_urb_complete(&hcd->self, urb, status); |
1562 | usb_unanchor_urb(urb); | 1580 | usb_unanchor_urb(urb); |
1563 | 1581 | ||
diff --git a/include/linux/usb.h b/include/linux/usb.h index bd69b65f3356..e63efeb378e3 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
@@ -976,6 +976,7 @@ extern int usb_disabled(void); | |||
976 | #define URB_SETUP_MAP_SINGLE 0x00100000 /* Setup packet DMA mapped */ | 976 | #define URB_SETUP_MAP_SINGLE 0x00100000 /* Setup packet DMA mapped */ |
977 | #define URB_SETUP_MAP_LOCAL 0x00200000 /* HCD-local setup packet */ | 977 | #define URB_SETUP_MAP_LOCAL 0x00200000 /* HCD-local setup packet */ |
978 | #define URB_DMA_SG_COMBINED 0x00400000 /* S-G entries were combined */ | 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 | struct usb_iso_packet_descriptor { | 981 | struct usb_iso_packet_descriptor { |
981 | unsigned int offset; | 982 | unsigned int offset; |
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 395704bdf5cc..92b96fe39307 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h | |||
@@ -233,6 +233,19 @@ struct hc_driver { | |||
233 | int (*urb_dequeue)(struct usb_hcd *hcd, | 233 | int (*urb_dequeue)(struct usb_hcd *hcd, |
234 | struct urb *urb, int status); | 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 | /* hw synch, freeing endpoint resources that urb_dequeue can't */ | 249 | /* hw synch, freeing endpoint resources that urb_dequeue can't */ |
237 | void (*endpoint_disable)(struct usb_hcd *hcd, | 250 | void (*endpoint_disable)(struct usb_hcd *hcd, |
238 | struct usb_host_endpoint *ep); | 251 | struct usb_host_endpoint *ep); |
@@ -329,6 +342,8 @@ extern int usb_hcd_submit_urb(struct urb *urb, gfp_t mem_flags); | |||
329 | extern int usb_hcd_unlink_urb(struct urb *urb, int status); | 342 | extern int usb_hcd_unlink_urb(struct urb *urb, int status); |
330 | extern void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, | 343 | extern void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, |
331 | int status); | 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 | extern void usb_hcd_unmap_urb_setup_for_dma(struct usb_hcd *, struct urb *); | 347 | extern void usb_hcd_unmap_urb_setup_for_dma(struct usb_hcd *, struct urb *); |
333 | extern void usb_hcd_unmap_urb_for_dma(struct usb_hcd *, struct urb *); | 348 | extern void usb_hcd_unmap_urb_for_dma(struct usb_hcd *, struct urb *); |
334 | extern void usb_hcd_flush_endpoint(struct usb_device *udev, | 349 | extern void usb_hcd_flush_endpoint(struct usb_device *udev, |