95,14 → 95,12 |
if (!driver->probe) |
return error; |
|
/* driver claim() doesn't yet affect dev->driver... */ |
if (intf->driver) |
return error; |
|
id = usb_match_id (intf, driver->id_table); |
if (id) { |
dev_dbg (dev, "%s - got id\n", __FUNCTION__); |
down (&driver->serialize); |
error = driver->probe (intf, id); |
up (&driver->serialize); |
} |
if (!error) |
intf->driver = driver; |
113,21 → 111,21 |
int usb_unbind_interface(struct device *dev) |
{ |
struct usb_interface *intf = to_usb_interface(dev); |
struct usb_driver *driver = intf->driver; |
struct usb_driver *driver = to_usb_driver(dev->driver); |
|
down(&driver->serialize); |
|
/* release all urbs for this interface */ |
usb_disable_interface(interface_to_usbdev(intf), intf); |
|
if (driver && driver->disconnect) |
driver->disconnect(intf); |
if (intf->driver && intf->driver->disconnect) |
intf->driver->disconnect(intf); |
|
/* reset other interface state */ |
usb_set_interface(interface_to_usbdev(intf), |
intf->altsetting[0].desc.bInterfaceNumber, |
0); |
usb_set_intfdata(intf, NULL); |
intf->driver = NULL; |
/* force a release and re-initialize the interface */ |
usb_driver_release_interface(driver, intf); |
|
up(&driver->serialize); |
|
return 0; |
} |
|
274,12 → 272,20 |
if (!iface || !driver) |
return -EINVAL; |
|
if (iface->driver) |
/* this is mainly to lock against usbfs */ |
lock_kernel(); |
if (iface->driver) { |
unlock_kernel(); |
err ("%s driver booted %s off interface %p", |
driver->name, iface->driver->name, iface); |
return -EBUSY; |
} else { |
dbg("%s driver claimed interface %p", driver->name, iface); |
} |
|
/* FIXME should device_bind_driver() */ |
iface->driver = driver; |
usb_set_intfdata(iface, priv); |
unlock_kernel(); |
return 0; |
} |
|
323,15 → 329,9 |
void usb_driver_release_interface(struct usb_driver *driver, struct usb_interface *iface) |
{ |
/* this should never happen, don't release something that's not ours */ |
if (!iface || !iface->driver || iface->driver != driver) |
if (iface->driver && iface->driver != driver) |
return; |
|
if (iface->dev.driver) { |
/* FIXME should be the ONLY case here */ |
device_release_driver(&iface->dev); |
return; |
} |
|
usb_set_interface(interface_to_usbdev(iface), |
iface->altsetting[0].desc.bInterfaceNumber, |
0); |
582,7 → 582,7 |
* FIXME reduce hardwired intelligence here |
*/ |
envp [i++] = scratch; |
length += snprintf26 (scratch, buffer_size - length, |
length += snprintf (scratch, buffer_size - length, |
"DEVICE=/proc/bus/usb/%03d/%03d", |
usb_dev->bus->busnum, usb_dev->devnum); |
if ((buffer_size - length <= 0) || (i >= num_envp)) |
593,7 → 593,7 |
|
/* per-device configurations are common */ |
envp [i++] = scratch; |
length += snprintf26 (scratch, buffer_size - length, "PRODUCT=%x/%x/%x", |
length += snprintf (scratch, buffer_size - length, "PRODUCT=%x/%x/%x", |
usb_dev->descriptor.idVendor, |
usb_dev->descriptor.idProduct, |
usb_dev->descriptor.bcdDevice); |
604,7 → 604,7 |
|
/* class-based driver binding models */ |
envp [i++] = scratch; |
length += snprintf26 (scratch, buffer_size - length, "TYPE=%d/%d/%d", |
length += snprintf (scratch, buffer_size - length, "TYPE=%d/%d/%d", |
usb_dev->descriptor.bDeviceClass, |
usb_dev->descriptor.bDeviceSubClass, |
usb_dev->descriptor.bDeviceProtocol); |
621,7 → 621,7 |
* $DEVPATH/bInterfaceNumber if necessary. |
*/ |
envp [i++] = scratch; |
length += snprintf26 (scratch, buffer_size - length, |
length += snprintf (scratch, buffer_size - length, |
"INTERFACE=%d/%d/%d", |
intf->altsetting[alt].desc.bInterfaceClass, |
intf->altsetting[alt].desc.bInterfaceSubClass, |
993,9 → 993,7 |
int err = -EINVAL; |
int i; |
int j; |
int config; |
|
|
/* |
* Set the driver for the usb device to point to the "generic" driver. |
* This prevents the main usb device from being sent to the usb bus |
1111,35 → 1109,21 |
|
/* choose and set the configuration. that registers the interfaces |
* with the driver core, and lets usb device drivers bind to them. |
* NOTE: should interact with hub power budgeting. |
*/ |
config = dev->config[0].desc.bConfigurationValue; |
if (dev->descriptor.bNumConfigurations != 1) { |
for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { |
/* heuristic: Linux is more likely to have class |
* drivers, so avoid vendor-specific interfaces. |
*/ |
if (dev->config[i].interface[0]->altsetting |
->desc.bInterfaceClass |
== USB_CLASS_VENDOR_SPEC) |
continue; |
config = dev->config[i].desc.bConfigurationValue; |
break; |
} |
dev_info(&dev->dev, |
"configuration #%d chosen from %d choices\n", |
config, |
dev->config[0].desc.bConfigurationValue, |
dev->descriptor.bNumConfigurations); |
} |
err = usb_set_configuration(dev, config); |
|
err = usb_set_configuration(dev, |
dev->config[0].desc.bConfigurationValue); |
if (err) { |
dev_err(&dev->dev, "can't set config #%d, error %d\n", |
config, err); |
dev->config[0].desc.bConfigurationValue, err); |
device_del(&dev->dev); |
goto fail; |
} |
|
/* USB device state == configured ... usable */ |
|
/* add a /proc/bus/usb entry */ |