diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/core/hcd.c | 4 | ||||
-rw-r--r-- | drivers/usb/core/urb.c | 18 |
2 files changed, 18 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) dma_unmap_single (hcd->self.controller, urb->transfer_dma, urb->transfer_buffer_length, - usb_pipein (urb->pipe) + usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); } @@ -1014,7 +1014,7 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) hcd->self.controller, urb->transfer_buffer, urb->transfer_buffer_length, - usb_pipein (urb->pipe) + usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); } 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) * 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) |