]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/usb/storage/uas-detect.h
uas: Honor no-uas quirk set in usb-storage's quirks module parameter
[karo-tx-linux.git] / drivers / usb / storage / uas-detect.h
1 #include <linux/usb.h>
2 #include <linux/usb/hcd.h>
3 #include "usb.h"
4
5 static int uas_is_interface(struct usb_host_interface *intf)
6 {
7         return (intf->desc.bInterfaceClass == USB_CLASS_MASS_STORAGE &&
8                 intf->desc.bInterfaceSubClass == USB_SC_SCSI &&
9                 intf->desc.bInterfaceProtocol == USB_PR_UAS);
10 }
11
12 static int uas_isnt_supported(struct usb_device *udev)
13 {
14         struct usb_hcd *hcd = bus_to_hcd(udev->bus);
15
16         dev_warn(&udev->dev, "The driver for the USB controller %s does not "
17                         "support scatter-gather which is\n",
18                         hcd->driver->description);
19         dev_warn(&udev->dev, "required by the UAS driver. Please try an"
20                         "alternative USB controller if you wish to use UAS.\n");
21         return -ENODEV;
22 }
23
24 static int uas_find_uas_alt_setting(struct usb_interface *intf)
25 {
26         int i;
27         struct usb_device *udev = interface_to_usbdev(intf);
28         int sg_supported = udev->bus->sg_tablesize != 0;
29
30         for (i = 0; i < intf->num_altsetting; i++) {
31                 struct usb_host_interface *alt = &intf->altsetting[i];
32
33                 if (uas_is_interface(alt)) {
34                         if (!sg_supported)
35                                 return uas_isnt_supported(udev);
36                         return alt->desc.bAlternateSetting;
37                 }
38         }
39
40         return -ENODEV;
41 }
42
43 static int uas_use_uas_driver(struct usb_interface *intf,
44                               const struct usb_device_id *id)
45 {
46         struct usb_device *udev = interface_to_usbdev(intf);
47         unsigned long flags = id->driver_info;
48
49         usb_stor_adjust_quirks(udev, &flags);
50
51         if (flags & US_FL_IGNORE_UAS)
52                 return 0;
53
54         return uas_find_uas_alt_setting(intf) >= 0;
55 }