Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Linus Torvalds committed Jun 12, 2008
2 parents aaef4d6 + 5340ba8 commit 631025b
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 13 deletions.
46 changes: 44 additions & 2 deletions drivers/usb/core/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 4 additions & 4 deletions drivers/usb/host/isp1760-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/misc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 16 additions & 7 deletions drivers/usb/misc/isight_firmware.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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]);
Expand All @@ -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;
Expand All @@ -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;
}
Expand Down

0 comments on commit 631025b

Please sign in to comment.