diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-06 11:41:17 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-06 11:41:17 -0700 |
commit | cc41f5cede3c63836d1c0958204630b07f5b5ee7 (patch) | |
tree | dfd94451c919b5185d8a01fd3e5a90244fb0de1c /drivers/staging/usbip/stub_rx.c | |
parent | Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6 (diff) | |
parent | Staging: wlan-ng: Update prism2_set_tx_power() to use mBm (diff) | |
download | linux-dev-cc41f5cede3c63836d1c0958204630b07f5b5ee7.tar.xz linux-dev-cc41f5cede3c63836d1c0958204630b07f5b5ee7.zip |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6: (524 commits)
Staging: wlan-ng: Update prism2_set_tx_power() to use mBm
Staging: ti-st: update TODO
Staging: wlags49_h2: use common PCI_VENDOR/DEVICE_ID name format
Staging: comedi : fix brace coding style issue in wwrap.c
Staging: quatech_usb2: remove unused qt2_box_flush function
Staging: slicoss: Remove net_device_stats from the driver's private
staging: rtl8192su: check whether requests succeeded
staging: panel: fix error path
staging: otus: check kmalloc() return value
staging: octeon: check request_irq() return value
Staging: wlan-ng: remove typedef in p80211hdr.h
Staging: wlan-ng: fix checkpatch issues in headers.
Staging: wlan-ng: remove typedef in p80211ioctl.h
Staging: wlan-ng: fix style issues in p80211conv.h
Staging: wlan-ng: fix style issues for p80211hdr.h
staging: vt6656: removed NTSTATUS definition
staging: vt6656: simplified tests involving both multi/broad-casts
Staging: vt6655: replace BOOL with in kernel bool
Staging: vt6655: replace FALSE with in kernel false
Staging: vt6655: replace TRUE with in kernel true
...
Diffstat (limited to 'drivers/staging/usbip/stub_rx.c')
-rw-r--r-- | drivers/staging/usbip/stub_rx.c | 101 |
1 files changed, 59 insertions, 42 deletions
diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c index 5972ae70e381..3de6fd2539dc 100644 --- a/drivers/staging/usbip/stub_rx.c +++ b/drivers/staging/usbip/stub_rx.c @@ -362,54 +362,16 @@ static struct stub_priv *stub_priv_alloc(struct stub_device *sdev, return priv; } - -static struct usb_host_endpoint *get_ep_from_epnum(struct usb_device *udev, - int epnum0) -{ - struct usb_host_config *config; - int i = 0, j = 0; - struct usb_host_endpoint *ep = NULL; - int epnum; - int found = 0; - - if (epnum0 == 0) - return &udev->ep0; - - config = udev->actconfig; - if (!config) - return NULL; - - for (i = 0; i < config->desc.bNumInterfaces; i++) { - struct usb_host_interface *setting; - - setting = config->interface[i]->cur_altsetting; - - for (j = 0; j < setting->desc.bNumEndpoints; j++) { - ep = &setting->endpoint[j]; - epnum = (ep->desc.bEndpointAddress & 0x7f); - - if (epnum == epnum0) { - /* usbip_uinfo("found epnum %d\n", epnum0);*/ - found = 1; - break; - } - } - } - - if (found) - return ep; - else - return NULL; -} - - static int get_pipe(struct stub_device *sdev, int epnum, int dir) { struct usb_device *udev = interface_to_usbdev(sdev->interface); struct usb_host_endpoint *ep; struct usb_endpoint_descriptor *epd = NULL; - ep = get_ep_from_epnum(udev, epnum); + if (dir == USBIP_DIR_IN) + ep = udev->ep_in[epnum & 0x7f]; + else + ep = udev->ep_out[epnum & 0x7f]; if (!ep) { dev_err(&sdev->interface->dev, "no such endpoint?, %d\n", epnum); @@ -462,6 +424,60 @@ static int get_pipe(struct stub_device *sdev, int epnum, int dir) return 0; } +static void masking_bogus_flags(struct urb *urb) +{ + int xfertype; + struct usb_device *dev; + struct usb_host_endpoint *ep; + int is_out; + unsigned int allowed; + + if (!urb || urb->hcpriv || !urb->complete) + return; + dev = urb->dev; + if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED)) + return; + + ep = (usb_pipein(urb->pipe) ? dev->ep_in : dev->ep_out) + [usb_pipeendpoint(urb->pipe)]; + if (!ep) + return; + + xfertype = usb_endpoint_type(&ep->desc); + if (xfertype == USB_ENDPOINT_XFER_CONTROL) { + struct usb_ctrlrequest *setup = + (struct usb_ctrlrequest *) urb->setup_packet; + + if (!setup) + return; + is_out = !(setup->bRequestType & USB_DIR_IN) || + !setup->wLength; + } else { + is_out = usb_endpoint_dir_out(&ep->desc); + } + + /* enforce simple/standard policy */ + allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT | + URB_DIR_MASK | URB_FREE_BUFFER); + switch (xfertype) { + case USB_ENDPOINT_XFER_BULK: + if (is_out) + allowed |= URB_ZERO_PACKET; + /* FALLTHROUGH */ + case USB_ENDPOINT_XFER_CONTROL: + allowed |= URB_NO_FSBR; /* only affects UHCI */ + /* FALLTHROUGH */ + default: /* all non-iso endpoints */ + if (!is_out) + allowed |= URB_SHORT_NOT_OK; + break; + case USB_ENDPOINT_XFER_ISOC: + allowed |= URB_ISO_ASAP; + break; + } + urb->transfer_flags &= allowed; +} + static void stub_recv_cmd_submit(struct stub_device *sdev, struct usbip_header *pdu) { @@ -528,6 +544,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev, /* no need to submit an intercepted request, but harmless? */ tweak_special_requests(priv->urb); + masking_bogus_flags(priv->urb); /* urb is now ready to submit */ ret = usb_submit_urb(priv->urb, GFP_KERNEL); |