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

Commit 631025b4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6:
  USB: don't use reset-resume if drivers don't support it
  USB: isp1760: Assign resource fields before adding hcd
  isight_firmware: Avoid crash on loading invalid firmware
  USB: fix build bug in USB_ISIGHTFW
parents aaef4d6c 5340ba82
Loading
Loading
Loading
Loading
+44 −2
Original line number Diff line number Diff line
@@ -644,6 +644,48 @@ static void hub_stop(struct usb_hub *hub)

#ifdef CONFIG_PM

/* Try to identify which devices need USB-PERSIST handling */
static int persistent_device(struct usb_device *udev)
{
	int i;
	int retval;
	struct usb_host_config *actconfig;

	/* Explicitly not marked persistent? */
	if (!udev->persist_enabled)
		return 0;

	/* No active config? */
	actconfig = udev->actconfig;
	if (!actconfig)
		return 0;

	/* FIXME! We should check whether it's open here or not! */

	/*
	 * Check that all the interface drivers have a
	 * 'reset_resume' entrypoint
	 */
	retval = 0;
	for (i = 0; i < actconfig->desc.bNumInterfaces; i++) {
		struct usb_interface *intf;
		struct usb_driver *driver;

		intf = actconfig->interface[i];
		if (!intf->dev.driver)
			continue;
		driver = to_usb_driver(intf->dev.driver);
		if (!driver->reset_resume)
			return 0;
		/*
		 * We have at least one driver, and that one
		 * has a reset_resume method.
		 */
		retval = 1;
	}
	return retval;
}

static void hub_restart(struct usb_hub *hub, int type)
{
	struct usb_device *hdev = hub->hdev;
@@ -689,8 +731,8 @@ static void hub_restart(struct usb_hub *hub, int type)
		 * turn off the various status changes to prevent
		 * khubd from disconnecting it later.
		 */
		if (udev->persist_enabled && status == 0 &&
				!(portstatus & USB_PORT_STAT_ENABLE)) {
		if (status == 0 && !(portstatus & USB_PORT_STAT_ENABLE) &&
				persistent_device(udev)) {
			if (portchange & USB_PORT_STAT_C_ENABLE)
				clear_port_feature(hub->hdev, port1,
						USB_PORT_FEAT_C_ENABLE);
+4 −4
Original line number Diff line number Diff line
@@ -2207,14 +2207,14 @@ struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq,
		goto err_put;
	}

	ret = usb_add_hcd(hcd, irq, irqflags);
	if (ret)
		goto err_unmap;

	hcd->irq = irq;
	hcd->rsrc_start = res_start;
	hcd->rsrc_len = res_len;

	ret = usb_add_hcd(hcd, irq, irqflags);
	if (ret)
		goto err_unmap;

	return hcd;

err_unmap:
+1 −0
Original line number Diff line number Diff line
@@ -272,6 +272,7 @@ config USB_TEST
config USB_ISIGHTFW
	tristate "iSight firmware loading support"
	depends on USB
	select FW_LOADER
	help
	  This driver loads firmware for USB Apple iSight cameras, allowing
	  them to be driven by the USB video class driver available at
+16 −7
Original line number Diff line number Diff line
@@ -39,9 +39,12 @@ static int isight_firmware_load(struct usb_interface *intf,
	struct usb_device *dev = interface_to_usbdev(intf);
	int llen, len, req, ret = 0;
	const struct firmware *firmware;
	unsigned char *buf;
	unsigned char *buf = kmalloc(50, GFP_KERNEL);
	unsigned char data[4];
	char *ptr;
	u8 *ptr;

	if (!buf)
		return -ENOMEM;

	if (request_firmware(&firmware, "isight.fw", &dev->dev) != 0) {
		printk(KERN_ERR "Unable to load isight firmware\n");
@@ -59,7 +62,7 @@ static int isight_firmware_load(struct usb_interface *intf,
		goto out;
	}

	while (1) {
	while (ptr+4 <= firmware->data+firmware->size) {
		memcpy(data, ptr, 4);
		len = (data[0] << 8 | data[1]);
		req = (data[2] << 8 | data[3]);
@@ -71,10 +74,14 @@ static int isight_firmware_load(struct usb_interface *intf,
			continue;

		for (; len > 0; req += 50) {
			llen = len > 50 ? 50 : len;
			llen = min(len, 50);
			len -= llen;

			buf = kmalloc(llen, GFP_KERNEL);
			if (ptr+llen > firmware->data+firmware->size) {
				printk(KERN_ERR
				       "Malformed isight firmware");
				ret = -ENODEV;
				goto out;
			}
			memcpy(buf, ptr, llen);

			ptr += llen;
@@ -89,16 +96,18 @@ static int isight_firmware_load(struct usb_interface *intf,
				goto out;
			}

			kfree(buf);
		}
	}

	if (usb_control_msg
	    (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\0", 1,
	     300) != 1) {
		printk(KERN_ERR "isight firmware loading completion failed\n");
		ret = -ENODEV;
	}

out:
	kfree(buf);
	release_firmware(firmware);
	return ret;
}