|
@@ -424,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_SETUP_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)
|
|
|
{
|
|
@@ -490,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);
|
|
|
|