diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2007-07-30 17:06:16 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-10-12 14:55:00 -0700 |
commit | fea3409112a93581db18da4c4332c8bf8d68af6b (patch) | |
tree | c89b9fd9f8a64d2419d7888a6ab135851f4fee38 /drivers/usb/core/urb.c | |
parent | bdd016ba64d909329cb4bacacc8443901c00e112 (diff) | |
download | kernel_samsung_crespo-fea3409112a93581db18da4c4332c8bf8d68af6b.zip kernel_samsung_crespo-fea3409112a93581db18da4c4332c8bf8d68af6b.tar.gz kernel_samsung_crespo-fea3409112a93581db18da4c4332c8bf8d68af6b.tar.bz2 |
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>
Diffstat (limited to 'drivers/usb/core/urb.c')
-rw-r--r-- | drivers/usb/core/urb.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index ff53acb..1a64a6a 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) * and don't need to duplicate tests */ xfertype = usb_endpoint_type(&ep->desc); - is_out = usb_pipeout(urb->pipe); + if (xfertype == USB_ENDPOINT_XFER_CONTROL) { + struct usb_ctrlrequest *setup = + (struct usb_ctrlrequest *) urb->setup_packet; + + if (!setup) + return -ENOEXEC; + is_out = !(setup->bRequestType & USB_DIR_IN) || + !setup->wLength; + } else { + is_out = usb_endpoint_dir_out(&ep->desc); + } + + /* Cache the direction for later use */ + urb->transfer_flags = (urb->transfer_flags & ~URB_DIR_MASK) | + (is_out ? URB_DIR_OUT : URB_DIR_IN); if (xfertype != USB_ENDPOINT_XFER_CONTROL && dev->state < USB_STATE_CONFIGURED) @@ -363,7 +377,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) /* enforce simple/standard policy */ allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | - URB_NO_INTERRUPT); + URB_NO_INTERRUPT | URB_DIR_MASK); switch (xfertype) { case USB_ENDPOINT_XFER_BULK: if (is_out) |