diff options
-rw-r--r-- | drivers/usb/core/urb.c | 3 | ||||
-rw-r--r-- | include/linux/usb.h | 8 |
2 files changed, 9 insertions, 2 deletions
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 4e7a311ff6d7..c12bc790a6a7 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -416,7 +416,8 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) urb->iso_frame_desc[n].status = -EXDEV; urb->iso_frame_desc[n].actual_length = 0; } - } else if (dev->speed != USB_SPEED_WIRELESS && urb->num_sgs) { + } else if (urb->num_sgs && !urb->dev->bus->no_sg_constraint && + dev->speed != USB_SPEED_WIRELESS) { struct scatterlist *sg; int i; diff --git a/include/linux/usb.h b/include/linux/usb.h index acb1b0aa77d8..001629cd1a97 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -337,6 +337,7 @@ struct usb_bus { * the ep queue on a short transfer * with the URB_SHORT_NOT_OK flag set. */ + unsigned no_sg_constraint:1; /* no sg constraint */ unsigned sg_tablesize; /* 0 or largest number of sg list entries */ int devnum_next; /* Next open device number in @@ -684,6 +685,11 @@ static inline bool usb_device_supports_ltm(struct usb_device *udev) return udev->bos->ss_cap->bmAttributes & USB_LTM_SUPPORT; } +static inline bool usb_device_no_sg_constraint(struct usb_device *udev) +{ + return udev && udev->bus && udev->bus->no_sg_constraint; +} + /*-------------------------------------------------------------------------*/ @@ -1253,7 +1259,7 @@ typedef void (*usb_complete_t)(struct urb *); * transfer_buffer. * @sg: scatter gather buffer list, the buffer size of each element in * the list (except the last) must be divisible by the endpoint's - * max packet size + * max packet size if no_sg_constraint isn't set in 'struct usb_bus' * @num_mapped_sgs: (internal) number of mapped sg entries * @num_sgs: number of entries in the sg list * @transfer_buffer_length: How big is transfer_buffer. The transfer may |