Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 89dc2905 authored by Matthew Wilcox's avatar Matthew Wilcox Committed by Greg Kroah-Hartman
Browse files

USB: uas: Ensure we only bind to a UAS interface



While all existing UAS devices use alternate interface 1, this is not
guaranteed, and it has caused confusion with people trying to bind the
uas driver to non-uas devices.

Signed-off-by: default avatarMatthew Wilcox <willy@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 92a3f767
Loading
Loading
Loading
Loading
+30 −7
Original line number Original line Diff line number Diff line
@@ -582,6 +582,34 @@ static struct usb_device_id uas_usb_ids[] = {
};
};
MODULE_DEVICE_TABLE(usb, uas_usb_ids);
MODULE_DEVICE_TABLE(usb, uas_usb_ids);


static int uas_is_interface(struct usb_host_interface *intf)
{
	return (intf->desc.bInterfaceClass == USB_CLASS_MASS_STORAGE &&
		intf->desc.bInterfaceSubClass == USB_SC_SCSI &&
		intf->desc.bInterfaceProtocol == USB_PR_UAS);
}

static int uas_switch_interface(struct usb_device *udev,
						struct usb_interface *intf)
{
	int i;

	if (uas_is_interface(intf->cur_altsetting))
		return 0;

	for (i = 0; i < intf->num_altsetting; i++) {
		struct usb_host_interface *alt = &intf->altsetting[i];
		if (alt == intf->cur_altsetting)
			continue;
		if (uas_is_interface(alt))
			return usb_set_interface(udev,
						alt->desc.bInterfaceNumber,
						alt->desc.bAlternateSetting);
	}

	return -ENODEV;
}

static void uas_configure_endpoints(struct uas_dev_info *devinfo)
static void uas_configure_endpoints(struct uas_dev_info *devinfo)
{
{
	struct usb_host_endpoint *eps[4] = { };
	struct usb_host_endpoint *eps[4] = { };
@@ -655,13 +683,8 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
	struct uas_dev_info *devinfo;
	struct uas_dev_info *devinfo;
	struct usb_device *udev = interface_to_usbdev(intf);
	struct usb_device *udev = interface_to_usbdev(intf);


	if (id->bInterfaceProtocol == 0x50) {
	if (uas_switch_interface(udev, intf))
		int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
/* XXX: Shouldn't assume that 1 is the alternative we want */
		int ret = usb_set_interface(udev, ifnum, 1);
		if (ret)
		return -ENODEV;
		return -ENODEV;
	}


	devinfo = kmalloc(sizeof(struct uas_dev_info), GFP_KERNEL);
	devinfo = kmalloc(sizeof(struct uas_dev_info), GFP_KERNEL);
	if (!devinfo)
	if (!devinfo)