aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2007-07-30 17:06:16 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-10-12 17:55:00 -0400
commitfea3409112a93581db18da4c4332c8bf8d68af6b (patch)
treec89b9fd9f8a64d2419d7888a6ab135851f4fee38
parentbdd016ba64d909329cb4bacacc8443901c00e112 (diff)
USB: add direction bit to urb->transfer_flags
This patch (as945) adds a bit to urb->transfer_flags for recording the direction of the URB. The bit is set/cleared automatically in usb_submit_urb() so drivers don't have to worry about it (although as a result, it isn't valid until the URB has been submitted). Inline routines are added for easily checking an URB's direction. They replace calls to usb_pipein in the DMA-mapping parts of hcd.c. For non-control endpoints, the direction is determined directly from the endpoint descriptor. However control endpoints are bi-directional; for them the direction is determined from the bRequestType byte and the wLength value in the setup packet. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/core/hcd.c4
-rw-r--r--drivers/usb/core/urb.c18
-rw-r--r--include/linux/usb.h30
3 files changed, 48 insertions, 4 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index cc5b1d3c3680..bcbaedc897d5 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -928,7 +928,7 @@ static void urb_unlink(struct usb_hcd *hcd, struct urb *urb)
928 dma_unmap_single (hcd->self.controller, 928 dma_unmap_single (hcd->self.controller,
929 urb->transfer_dma, 929 urb->transfer_dma,
930 urb->transfer_buffer_length, 930 urb->transfer_buffer_length,
931 usb_pipein (urb->pipe) 931 usb_urb_dir_in(urb)
932 ? DMA_FROM_DEVICE 932 ? DMA_FROM_DEVICE
933 : DMA_TO_DEVICE); 933 : DMA_TO_DEVICE);
934 } 934 }
@@ -1014,7 +1014,7 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags)
1014 hcd->self.controller, 1014 hcd->self.controller,
1015 urb->transfer_buffer, 1015 urb->transfer_buffer,
1016 urb->transfer_buffer_length, 1016 urb->transfer_buffer_length,
1017 usb_pipein (urb->pipe) 1017 usb_urb_dir_in(urb)
1018 ? DMA_FROM_DEVICE 1018 ? DMA_FROM_DEVICE
1019 : DMA_TO_DEVICE); 1019 : DMA_TO_DEVICE);
1020 } 1020 }
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index ff53acb4fab2..1a64a6a850f3 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -309,7 +309,21 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
309 * and don't need to duplicate tests 309 * and don't need to duplicate tests
310 */ 310 */
311 xfertype = usb_endpoint_type(&ep->desc); 311 xfertype = usb_endpoint_type(&ep->desc);
312 is_out = usb_pipeout(urb->pipe); 312 if (xfertype == USB_ENDPOINT_XFER_CONTROL) {
313 struct usb_ctrlrequest *setup =
314 (struct usb_ctrlrequest *) urb->setup_packet;
315
316 if (!setup)
317 return -ENOEXEC;
318 is_out = !(setup->bRequestType & USB_DIR_IN) ||
319 !setup->wLength;
320 } else {
321 is_out = usb_endpoint_dir_out(&ep->desc);
322 }
323
324 /* Cache the direction for later use */
325 urb->transfer_flags = (urb->transfer_flags & ~URB_DIR_MASK) |
326 (is_out ? URB_DIR_OUT : URB_DIR_IN);
313 327
314 if (xfertype != USB_ENDPOINT_XFER_CONTROL && 328 if (xfertype != USB_ENDPOINT_XFER_CONTROL &&
315 dev->state < USB_STATE_CONFIGURED) 329 dev->state < USB_STATE_CONFIGURED)
@@ -363,7 +377,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
363 377
364 /* enforce simple/standard policy */ 378 /* enforce simple/standard policy */
365 allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | 379 allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP |
366 URB_NO_INTERRUPT); 380 URB_NO_INTERRUPT | URB_DIR_MASK);
367 switch (xfertype) { 381 switch (xfertype) {
368 case USB_ENDPOINT_XFER_BULK: 382 case USB_ENDPOINT_XFER_BULK:
369 if (is_out) 383 if (is_out)
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 818a1b4f737a..9d08f5a5ba76 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -1021,6 +1021,8 @@ extern int usb_disabled(void);
1021 1021
1022/* 1022/*
1023 * urb->transfer_flags: 1023 * urb->transfer_flags:
1024 *
1025 * Note: URB_DIR_IN/OUT is automatically set in usb_submit_urb().
1024 */ 1026 */
1025#define URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */ 1027#define URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */
1026#define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame 1028#define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame
@@ -1033,6 +1035,10 @@ extern int usb_disabled(void);
1033 * needed */ 1035 * needed */
1034#define URB_FREE_BUFFER 0x0100 /* Free transfer buffer with the URB */ 1036#define URB_FREE_BUFFER 0x0100 /* Free transfer buffer with the URB */
1035 1037
1038#define URB_DIR_IN 0x0200 /* Transfer from device to host */
1039#define URB_DIR_OUT 0
1040#define URB_DIR_MASK URB_DIR_IN
1041
1036struct usb_iso_packet_descriptor { 1042struct usb_iso_packet_descriptor {
1037 unsigned int offset; 1043 unsigned int offset;
1038 unsigned int length; /* expected length */ 1044 unsigned int length; /* expected length */
@@ -1380,6 +1386,30 @@ extern void usb_unanchor_urb(struct urb *urb);
1380extern int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor, 1386extern int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor,
1381 unsigned int timeout); 1387 unsigned int timeout);
1382 1388
1389/**
1390 * usb_urb_dir_in - check if an URB describes an IN transfer
1391 * @urb: URB to be checked
1392 *
1393 * Returns 1 if @urb describes an IN transfer (device-to-host),
1394 * otherwise 0.
1395 */
1396static inline int usb_urb_dir_in(struct urb *urb)
1397{
1398 return (urb->transfer_flags & URB_DIR_MASK) != URB_DIR_OUT;
1399}
1400
1401/**
1402 * usb_urb_dir_out - check if an URB describes an OUT transfer
1403 * @urb: URB to be checked
1404 *
1405 * Returns 1 if @urb describes an OUT transfer (host-to-device),
1406 * otherwise 0.
1407 */
1408static inline int usb_urb_dir_out(struct urb *urb)
1409{
1410 return (urb->transfer_flags & URB_DIR_MASK) == URB_DIR_OUT;
1411}
1412
1383void *usb_buffer_alloc (struct usb_device *dev, size_t size, 1413void *usb_buffer_alloc (struct usb_device *dev, size_t size,
1384 gfp_t mem_flags, dma_addr_t *dma); 1414 gfp_t mem_flags, dma_addr_t *dma);
1385void usb_buffer_free (struct usb_device *dev, size_t size, 1415void usb_buffer_free (struct usb_device *dev, size_t size,