|
13 | 13 | #include <linux/types.h>
|
14 | 14 | #include <linux/module.h>
|
15 | 15 | #include <linux/usb.h>
|
| 16 | +#include <linux/usb/hcd.h> |
16 | 17 | #include <linux/usb/storage.h>
|
17 | 18 |
|
18 | 19 | #include <scsi/scsi.h>
|
@@ -621,22 +622,34 @@ static int uas_is_interface(struct usb_host_interface *intf)
|
621 | 622 | intf->desc.bInterfaceProtocol == USB_PR_UAS);
|
622 | 623 | }
|
623 | 624 |
|
| 625 | +static int uas_isnt_supported(struct usb_device *udev) |
| 626 | +{ |
| 627 | + struct usb_hcd *hcd = bus_to_hcd(udev->bus); |
| 628 | + |
| 629 | + dev_warn(&udev->dev, "The driver for the USB controller %s does not " |
| 630 | + "support scatter-gather which is\n", |
| 631 | + hcd->driver->description); |
| 632 | + dev_warn(&udev->dev, "required by the UAS driver. Please try an" |
| 633 | + "alternative USB controller if you wish to use UAS.\n"); |
| 634 | + return -ENODEV; |
| 635 | +} |
| 636 | + |
624 | 637 | static int uas_switch_interface(struct usb_device *udev,
|
625 | 638 | struct usb_interface *intf)
|
626 | 639 | {
|
627 | 640 | int i;
|
628 |
| - |
629 |
| - if (uas_is_interface(intf->cur_altsetting)) |
630 |
| - return 0; |
| 641 | + int sg_supported = udev->bus->sg_tablesize != 0; |
631 | 642 |
|
632 | 643 | for (i = 0; i < intf->num_altsetting; i++) {
|
633 | 644 | struct usb_host_interface *alt = &intf->altsetting[i];
|
634 |
| - if (alt == intf->cur_altsetting) |
635 |
| - continue; |
636 |
| - if (uas_is_interface(alt)) |
| 645 | + |
| 646 | + if (uas_is_interface(alt)) { |
| 647 | + if (!sg_supported) |
| 648 | + return uas_isnt_supported(udev); |
637 | 649 | return usb_set_interface(udev,
|
638 | 650 | alt->desc.bInterfaceNumber,
|
639 | 651 | alt->desc.bAlternateSetting);
|
| 652 | + } |
640 | 653 | }
|
641 | 654 |
|
642 | 655 | return -ENODEV;
|
|
0 commit comments