diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/base/core.c linux-2.5.34-greg/drivers/base/core.c --- linux-2.5.34/drivers/base/core.c Mon Sep 9 10:35:01 2002 +++ linux-2.5.34-greg/drivers/base/core.c Wed Sep 11 15:33:33 2002 @@ -103,12 +103,13 @@ devclass_remove_device(dev); spin_lock(&device_lock); drv = dev->driver; - dev->driver = NULL; spin_unlock(&device_lock); /* detach from driver */ if (drv && drv->remove) drv->remove(dev); + + dev->driver = NULL; } } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/class/audio.c linux-2.5.34-greg/drivers/usb/class/audio.c --- linux-2.5.34/drivers/usb/class/audio.c Mon Sep 9 10:35:26 2002 +++ linux-2.5.34-greg/drivers/usb/class/audio.c Wed Sep 11 15:33:33 2002 @@ -2740,9 +2740,9 @@ /* --------------------------------------------------------------------- */ -static void * usb_audio_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id); -static void usb_audio_disconnect(struct usb_device *dev, void *ptr); +static int usb_audio_probe(struct usb_interface *iface, + const struct usb_device_id *id); +static void usb_audio_disconnect(struct usb_interface *iface); static struct usb_device_id usb_audio_ids [] = { { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS), @@ -2756,7 +2756,6 @@ .name = "audio", .probe = usb_audio_probe, .disconnect = usb_audio_disconnect, - .driver_list = LIST_HEAD_INIT(usb_audio_driver.driver_list), .id_table = usb_audio_ids, }; @@ -3643,7 +3642,7 @@ list_add_tail(&ms->list, &s->mixerlist); } -static void *usb_audio_parsecontrol(struct usb_device *dev, unsigned char *buffer, unsigned int buflen, unsigned int ctrlif) +static struct usb_audio_state *usb_audio_parsecontrol(struct usb_device *dev, unsigned char *buffer, unsigned int buflen, unsigned int ctrlif) { struct usb_audio_state *s; struct usb_config_descriptor *config = dev->actconfig; @@ -3766,10 +3765,12 @@ /* we only care for the currently active configuration */ -static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id) +static int usb_audio_probe(struct usb_interface *iface, + const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev (iface); struct usb_config_descriptor *config = dev->actconfig; + struct usb_audio_state *s; unsigned char *buffer; unsigned char buf[8]; unsigned int i, buflen; @@ -3789,39 +3790,47 @@ if (usb_set_configuration(dev, config->bConfigurationValue) < 0) { printk(KERN_ERR "usbaudio: set_configuration failed (ConfigValue 0x%x)\n", config->bConfigurationValue); - return NULL; + return -EIO; } ret = usb_get_descriptor(dev, USB_DT_CONFIG, i, buf, 8); if (ret < 0) { printk(KERN_ERR "usbaudio: cannot get first 8 bytes of config descriptor %d of device %d (error %d)\n", i, dev->devnum, ret); - return NULL; + return -EIO; } if (buf[1] != USB_DT_CONFIG || buf[0] < 9) { printk(KERN_ERR "usbaudio: invalid config descriptor %d of device %d\n", i, dev->devnum); - return NULL; + return -EIO; } buflen = buf[2] | (buf[3] << 8); if (!(buffer = kmalloc(buflen, GFP_KERNEL))) - return NULL; + return -ENOMEM; ret = usb_get_descriptor(dev, USB_DT_CONFIG, i, buffer, buflen); if (ret < 0) { kfree(buffer); printk(KERN_ERR "usbaudio: cannot get config descriptor %d of device %d (error %d)\n", i, dev->devnum, ret); - return NULL; + return -EIO; } - return usb_audio_parsecontrol(dev, buffer, buflen, ifnum); + s = usb_audio_parsecontrol(dev, buffer, buflen, iface->altsetting->bInterfaceNumber); + if (s) { + iface->dev.driver_data = s; + return 0; + } + return -ENODEV; } /* a revoke facility would make things simpler */ -static void usb_audio_disconnect(struct usb_device *dev, void *ptr) +static void usb_audio_disconnect(struct usb_interface *iface) { - struct usb_audio_state *s = (struct usb_audio_state *)ptr; + struct usb_audio_state *s = (struct usb_audio_state *)iface->dev.driver_data; struct list_head *list; struct usb_audiodev *as; struct usb_mixerdev *ms; + if (!s) + return; + /* we get called with -1 for every audiostreaming interface registered */ if (s == (struct usb_audio_state *)-1) { dprintk((KERN_DEBUG "usbaudio: note, usb_audio_disconnect called with -1\n")); @@ -3835,6 +3844,8 @@ list_del(&s->audiodev); INIT_LIST_HEAD(&s->audiodev); s->usbdev = NULL; + iface->dev.driver_data = NULL; + /* deregister all audio and mixer devices, so no new processes can open this device */ for(list = s->audiolist.next; list != &s->audiolist; list = list->next) { as = list_entry(list, struct usb_audiodev, list); diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/class/bluetty.c linux-2.5.34-greg/drivers/usb/class/bluetty.c --- linux-2.5.34/drivers/usb/class/bluetty.c Mon Sep 9 10:35:05 2002 +++ linux-2.5.34-greg/drivers/usb/class/bluetty.c Wed Sep 11 15:33:33 2002 @@ -221,9 +221,9 @@ static void bluetooth_read_bulk_callback (struct urb *urb); static void bluetooth_write_bulk_callback (struct urb *urb); -static void * usb_bluetooth_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id); -static void usb_bluetooth_disconnect (struct usb_device *dev, void *ptr); +static int usb_bluetooth_probe (struct usb_interface *intf, + const struct usb_device_id *id); +static void usb_bluetooth_disconnect (struct usb_interface *intf); static struct usb_device_id usb_bluetooth_ids [] = { @@ -1033,9 +1033,10 @@ } -static void * usb_bluetooth_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id) +static int usb_bluetooth_probe (struct usb_interface *iface, + const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev (iface); struct usb_bluetooth *bluetooth = NULL; struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; @@ -1051,7 +1052,7 @@ int num_bulk_in = 0; int num_bulk_out = 0; - interface = &dev->actconfig->interface[ifnum].altsetting[0]; + interface = &iface->altsetting[0]; control_out_endpoint = interface->bInterfaceNumber; /* find the endpoints that we need */ @@ -1088,7 +1089,7 @@ (num_bulk_out != 1) || (num_interrupt_in != 1)) { dbg ("%s - improper number of endpoints. Bluetooth driver not bound.", __FUNCTION__); - return NULL; + return -EIO; } MOD_INC_USE_COUNT; @@ -1099,13 +1100,13 @@ if (bluetooth_table[minor]) { err("No more free Bluetooth devices"); MOD_DEC_USE_COUNT; - return NULL; + return -ENODEV; } if (!(bluetooth = kmalloc(sizeof(struct usb_bluetooth), GFP_KERNEL))) { err("Out of memory"); MOD_DEC_USE_COUNT; - return NULL; + return -ENOMEM; } memset(bluetooth, 0, sizeof(struct usb_bluetooth)); @@ -1191,7 +1192,9 @@ bluetooth_table[minor] = bluetooth; - return bluetooth; /* success */ + /* success */ + iface->dev.driver_data = bluetooth; + return 0; probe_error: if (bluetooth->read_urb) @@ -1220,13 +1223,13 @@ /* free up any memory that we allocated */ kfree (bluetooth); MOD_DEC_USE_COUNT; - return NULL; + return -EIO; } -static void usb_bluetooth_disconnect(struct usb_device *dev, void *ptr) +static void usb_bluetooth_disconnect(struct usb_interface *iface) { - struct usb_bluetooth *bluetooth = (struct usb_bluetooth *) ptr; + struct usb_bluetooth *bluetooth = iface->dev.driver_data; int i; if (bluetooth) { @@ -1274,7 +1277,7 @@ /* free up any memory that we allocated */ kfree (bluetooth); - + iface->dev.driver_data = NULL; } else { info("device disconnected"); } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/class/cdc-acm.c linux-2.5.34-greg/drivers/usb/class/cdc-acm.c --- linux-2.5.34/drivers/usb/class/cdc-acm.c Mon Sep 9 10:35:02 2002 +++ linux-2.5.34-greg/drivers/usb/class/cdc-acm.c Wed Sep 11 15:33:33 2002 @@ -507,9 +507,10 @@ * USB probe and disconnect routines. */ -static void *acm_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id) +static int acm_probe (struct usb_interface *iface, + const struct usb_device_id *id) { + struct usb_device *dev; struct acm *acm; struct usb_config_descriptor *cfacm; struct usb_interface_descriptor *ifcom, *ifdata; @@ -517,6 +518,7 @@ int readsize, ctrlsize, minor, i; unsigned char *buf; + dev = interface_to_usbdev (iface); for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { cfacm = dev->config + i; @@ -561,12 +563,12 @@ for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++); if (acm_table[minor]) { err("no more free acm devices"); - return NULL; + return -ENODEV; } if (!(acm = kmalloc(sizeof(struct acm), GFP_KERNEL))) { err("out of memory"); - return NULL; + return -ENOMEM; } memset(acm, 0, sizeof(struct acm)); @@ -583,21 +585,21 @@ if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) { err("out of memory"); kfree(acm); - return NULL; + return -ENOMEM; } acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); if (!acm->ctrlurb) { err("out of memory"); kfree(acm); - return NULL; + return -ENOMEM; } acm->readurb = usb_alloc_urb(0, GFP_KERNEL); if (!acm->readurb) { err("out of memory"); usb_free_urb(acm->ctrlurb); kfree(acm); - return NULL; + return -ENOMEM; } acm->writeurb = usb_alloc_urb(0, GFP_KERNEL); if (!acm->writeurb) { @@ -605,7 +607,7 @@ usb_free_urb(acm->readurb); usb_free_urb(acm->ctrlurb); kfree(acm); - return NULL; + return -ENOMEM; } usb_fill_int_urb(acm->ctrlurb, dev, usb_rcvintpipe(dev, epctrl->bEndpointAddress), @@ -631,15 +633,18 @@ usb_driver_claim_interface(&acm_driver, acm->iface + 1, acm); tty_register_devfs(&acm_tty_driver, 0, minor); - return acm_table[minor] = acm; + + acm_table[minor] = acm; + iface->dev.driver_data = acm; + return 0; } - return NULL; + return -EIO; } -static void acm_disconnect(struct usb_device *dev, void *ptr) +static void acm_disconnect(struct usb_interface *iface) { - struct acm *acm = ptr; + struct acm *acm = iface->dev.driver_data; if (!acm || !acm->dev) { dbg("disconnect on nonexisting interface"); @@ -647,6 +652,7 @@ } acm->dev = NULL; + iface->dev.driver_data = NULL; usb_unlink_urb(acm->ctrlurb); usb_unlink_urb(acm->readurb); diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/class/usb-midi.c linux-2.5.34-greg/drivers/usb/class/usb-midi.c --- linux-2.5.34/drivers/usb/class/usb-midi.c Mon Sep 9 10:35:01 2002 +++ linux-2.5.34-greg/drivers/usb/class/usb-midi.c Wed Sep 11 15:33:33 2002 @@ -2020,13 +2020,16 @@ /* ------------------------------------------------------------------------- */ -static void *usb_midi_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id) +static int usb_midi_probe(struct usb_interface *iface, + const struct usb_device_id *id) { struct usb_midi_state *s; + struct usb_device *dev = interface_to_usbdev(iface); + int ifnum = iface->altsetting->bInterfaceNumber; s = (struct usb_midi_state *)kmalloc(sizeof(struct usb_midi_state), GFP_KERNEL); - if ( !s ) { return NULL; } + if ( !s ) + return -ENOMEM; memset( s, 0, sizeof(struct usb_midi_state) ); INIT_LIST_HEAD(&s->midiDevList); @@ -2042,7 +2045,7 @@ detect_vendor_specific_device( dev, ifnum, s ) && detect_yamaha_device( dev, ifnum, s) ) { kfree(s); - return NULL; + return -EIO; } down(&open_sem); @@ -2053,16 +2056,20 @@ MOD_INC_USE_COUNT; #endif - return s; + iface->dev.driver_data = s; + return 0; } -static void usb_midi_disconnect(struct usb_device *dev, void *ptr) +static void usb_midi_disconnect(struct usb_interface *iface) { - struct usb_midi_state *s = (struct usb_midi_state *)ptr; + struct usb_midi_state *s = (struct usb_midi_state *)iface->dev.driver_data; struct list_head *list; struct usb_mididev *m; + if ( !s ) + return; + if ( s == (struct usb_midi_state *)-1 ) { return; } @@ -2073,6 +2080,7 @@ list_del(&s->mididev); INIT_LIST_HEAD(&s->mididev); s->usbdev = NULL; + iface->dev.driver_data = NULL; for ( list = s->midiDevList.next; list != &s->midiDevList; list = list->next ) { m = list_entry(list, struct usb_mididev, list); @@ -2092,14 +2100,17 @@ return; } - +/* we want to look at all devices by hand */ +static struct usb_device_id id_table[] = { + {.driver_info = 42}, + {} +}; static struct usb_driver usb_midi_driver = { - .name = "midi", - .probe = usb_midi_probe, - .disconnect = usb_midi_disconnect, - .id_table = NULL, /* check all devices */ - .driver_list = LIST_HEAD_INIT(usb_midi_driver.driver_list) + .name = "midi", + .probe = usb_midi_probe, + .disconnect = usb_midi_disconnect, + .id_table = id_table, }; /* ------------------------------------------------------------------------- */ diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/class/usblp.c linux-2.5.34-greg/drivers/usb/class/usblp.c --- linux-2.5.34/drivers/usb/class/usblp.c Mon Sep 9 10:35:04 2002 +++ linux-2.5.34-greg/drivers/usb/class/usblp.c Wed Sep 11 15:33:33 2002 @@ -795,9 +795,10 @@ .release = usblp_release, }; -static void *usblp_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id) +static int usblp_probe(struct usb_interface *iface, + const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev (iface); struct usblp *usblp = 0; int protocol; int retval; @@ -813,7 +814,7 @@ usblp->dev = dev; init_MUTEX (&usblp->sem); init_waitqueue_head(&usblp->wait); - usblp->ifnum = ifnum; + usblp->ifnum = iface->altsetting->bInterfaceNumber; retval = usb_register_dev(&usblp_fops, USBLP_MINOR_BASE, 1, &usblp->minor); if (retval) { @@ -886,12 +887,14 @@ info("usblp%d: USB %sdirectional printer dev %d " "if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X", - usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum, ifnum, + usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum, + usblp->ifnum, usblp->protocol[usblp->current_protocol].alt_setting, usblp->current_protocol, usblp->dev->descriptor.idVendor, usblp->dev->descriptor.idProduct); - return usblp; + iface->dev.driver_data = usblp; + return 0; abort_minor: usb_deregister_dev (1, usblp->minor); @@ -903,7 +906,7 @@ if (usblp->device_id_string) kfree(usblp->device_id_string); kfree(usblp); } - return NULL; + return -EIO; } /* @@ -1065,9 +1068,9 @@ return length; } -static void usblp_disconnect(struct usb_device *dev, void *ptr) +static void usblp_disconnect(struct usb_interface *iface) { - struct usblp *usblp = ptr; + struct usblp *usblp = iface->dev.driver_data; if (!usblp || !usblp->dev) { err("bogus disconnect"); @@ -1077,6 +1080,7 @@ down (&usblp->sem); lock_kernel(); usblp->dev = NULL; + iface->dev.driver_data = NULL; usblp_unlink_urbs(usblp); diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/core/devices.c linux-2.5.34-greg/drivers/usb/core/devices.c --- linux-2.5.34/drivers/usb/core/devices.c Mon Sep 9 10:35:09 2002 +++ linux-2.5.34-greg/drivers/usb/core/devices.c Wed Sep 11 15:33:33 2002 @@ -111,7 +111,6 @@ /* * Need access to the driver and USB bus lists. - * extern struct list_head usb_driver_list; * extern struct list_head usb_bus_list; * However, these will come from functions that return ptrs to each of them. */ diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/core/devio.c linux-2.5.34-greg/drivers/usb/core/devio.c --- linux-2.5.34/drivers/usb/core/devio.c Mon Sep 9 10:35:11 2002 +++ linux-2.5.34-greg/drivers/usb/core/devio.c Wed Sep 11 15:33:33 2002 @@ -298,15 +298,15 @@ * they're also undone when devices disconnect. */ -static void *driver_probe(struct usb_device *dev, unsigned int intf, - const struct usb_device_id *id) +static int driver_probe (struct usb_interface *intf, + const struct usb_device_id *id) { - return NULL; + return -ENODEV; } -static void driver_disconnect(struct usb_device *dev, void *context) +static void driver_disconnect(struct usb_interface *intf) { - struct dev_state *ps = (struct dev_state *)context; + struct dev_state *ps = (struct dev_state *)intf->dev.driver_data; if (!ps) return; @@ -317,6 +317,7 @@ /* prevent new I/O requests */ ps->dev = 0; ps->ifclaimed = 0; + intf->dev.driver_data = NULL; /* force async requests to complete */ destroy_all_async (ps); @@ -427,30 +428,6 @@ return -ENOENT; } -extern struct list_head usb_driver_list; - -#if 0 -static int finddriver(struct usb_driver **driver, char *name) -{ - struct list_head *tmp; - - tmp = usb_driver_list.next; - while (tmp != &usb_driver_list) { - struct usb_driver *d = list_entry(tmp, struct usb_driver, - driver_list); - - if (!strcmp(d->name, name)) { - *driver = d; - return 0; - } - - tmp = tmp->next; - } - - return -EINVAL; -} -#endif - static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsigned int index) { int ret; @@ -723,11 +700,10 @@ if (test_bit(i, &ps->ifclaimed)) continue; - lock_kernel(); + err ("%s - this function is broken", __FUNCTION__); if (intf->driver && ps->dev) { - usb_bind_driver (intf->driver, intf); + usb_device_probe (&intf->dev); } - unlock_kernel(); } return 0; @@ -1090,22 +1066,19 @@ /* disconnect kernel driver from interface, leaving it unbound. */ case USBDEVFS_DISCONNECT: - /* this function is voodoo. without locking it is a maybe thing */ - lock_kernel(); - driver = ifp->driver; - if (driver) { - dbg ("disconnect '%s' from dev %d interface %d", - driver->name, ps->dev->devnum, ctrl.ifno); - usb_unbind_driver(ps->dev, ifp); - usb_driver_release_interface (driver, ifp); - } else + /* this function is voodoo. */ + driver = ifp->driver; + if (driver) { + dbg ("disconnect '%s' from dev %d interface %d", + driver->name, ps->dev->devnum, ctrl.ifno); + usb_device_remove(&ifp->dev); + } else retval = -EINVAL; - unlock_kernel(); - break; + break; /* let kernel drivers try to (re)bind to the interface */ case USBDEVFS_CONNECT: - usb_find_interface_driver (ps->dev, ifp); + retval = usb_device_probe (&ifp->dev); break; /* talk directly to the interface's driver */ diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/core/hcd.c linux-2.5.34-greg/drivers/usb/core/hcd.c --- linux-2.5.34/drivers/usb/core/hcd.c Mon Sep 9 10:35:13 2002 +++ linux-2.5.34-greg/drivers/usb/core/hcd.c Wed Sep 11 15:33:33 2002 @@ -722,13 +722,16 @@ { int retval; - usb_dev->dev.parent = parent_dev; - strcpy (&usb_dev->dev.name[0], "usb_name"); - strcpy (&usb_dev->dev.bus_id[0], "usb_bus"); - retval = usb_new_device (usb_dev); +// usb_dev->dev.parent = parent_dev; +// strcpy (&usb_dev->dev.name[0], "usb_name"); +// strcpy (&usb_dev->dev.bus_id[0], "usb_bus"); + sprintf (&usb_dev->dev.bus_id[0], "usb%d", usb_dev->bus->busnum); + retval = usb_new_device (usb_dev, parent_dev); if (retval) - put_device (&usb_dev->dev); + err("%s - usb_new_device failed with value %d", __FUNCTION__, retval); +// put_device (&usb_dev->dev); return retval; +// return usb_new_device (usb_dev, parent_dev); } EXPORT_SYMBOL (usb_register_root_hub); diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/core/hcd.h linux-2.5.34-greg/drivers/usb/core/hcd.h --- linux-2.5.34/drivers/usb/core/hcd.h Mon Sep 9 10:35:07 2002 +++ linux-2.5.34-greg/drivers/usb/core/hcd.h Wed Sep 11 15:33:33 2002 @@ -270,7 +270,7 @@ /* -------------------------------------------------------------------------- */ /* Enumeration is only for the hub driver, or HCD virtual root hubs */ -extern int usb_new_device(struct usb_device *dev); +extern int usb_new_device(struct usb_device *dev, struct device *parent); extern void usb_connect(struct usb_device *dev); extern void usb_disconnect(struct usb_device **); @@ -396,12 +396,6 @@ #define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN)) -/* for probe/disconnect with correct module usage counting */ -void *usb_bind_driver(struct usb_driver *driver, struct usb_interface *intf); -void usb_unbind_driver(struct usb_device *device, struct usb_interface *intf); - -extern struct list_head usb_driver_list; - /* * USB device fs stuff */ diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/core/hub.c linux-2.5.34-greg/drivers/usb/core/hub.c --- linux-2.5.34/drivers/usb/core/hub.c Mon Sep 9 10:35:11 2002 +++ linux-2.5.34-greg/drivers/usb/core/hub.c Wed Sep 11 15:33:33 2002 @@ -175,6 +175,7 @@ while (!list_empty (&hub->tt.clear_list)) { struct list_head *temp; struct usb_tt_clear *clear; + struct usb_device *dev; int status; temp = hub->tt.clear_list.next; @@ -183,13 +184,13 @@ /* drop lock so HCD can concurrently report other TT errors */ spin_unlock_irqrestore (&hub->tt.lock, flags); - status = hub_clear_tt_buffer (hub->dev, - clear->devinfo, clear->tt); + dev = interface_to_usbdev (hub->intf); + status = hub_clear_tt_buffer (dev, clear->devinfo, clear->tt); spin_lock_irqsave (&hub->tt.lock, flags); if (status) err ("usb-%s-%s clear tt %d (%04x) error %d", - hub->dev->bus->bus_name, hub->dev->devpath, + dev->bus->bus_name, dev->devpath, clear->tt, clear->devinfo, status); kfree (clear); } @@ -245,12 +246,14 @@ static void usb_hub_power_on(struct usb_hub *hub) { + struct usb_device *dev; int i; /* Enable power to the ports */ dbg("enabling power on all ports"); + dev = interface_to_usbdev(hub->intf); for (i = 0; i < hub->descriptor->bNbrPorts; i++) - usb_set_port_feature(hub->dev, i + 1, USB_PORT_FEAT_POWER); + usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER); /* Wait for power to be enabled */ wait_ms(hub->descriptor->bPwrOn2PwrGood * 2); @@ -259,7 +262,7 @@ static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor *endpoint) { - struct usb_device *dev = hub->dev; + struct usb_device *dev = interface_to_usbdev (hub->intf); struct usb_hub_status hubstatus; unsigned int pipe; int maxp, ret; @@ -425,39 +428,81 @@ return 0; } -static void *hub_probe(struct usb_device *dev, unsigned int i, - const struct usb_device_id *id) +static void hub_disconnect(struct usb_interface *intf) { - struct usb_interface_descriptor *interface; + struct usb_hub *hub = (struct usb_hub *)intf->dev.driver_data; + unsigned long flags; + + if (!hub) + return; + + spin_lock_irqsave(&hub_event_lock, flags); + + /* Delete it and then reset it */ + list_del(&hub->event_list); + INIT_LIST_HEAD(&hub->event_list); + list_del(&hub->hub_list); + INIT_LIST_HEAD(&hub->hub_list); + + spin_unlock_irqrestore(&hub_event_lock, flags); + + down(&hub->khubd_sem); /* Wait for khubd to leave this hub alone. */ + up(&hub->khubd_sem); + + /* assuming we used keventd, it must quiesce too */ + if (hub->tt.hub) + flush_scheduled_tasks (); + + if (hub->urb) { + usb_unlink_urb(hub->urb); + usb_free_urb(hub->urb); + hub->urb = NULL; + } + + if (hub->descriptor) { + kfree(hub->descriptor); + hub->descriptor = NULL; + } + + /* Free the memory */ + kfree(hub); + intf->dev.driver_data = NULL; +} + +static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + struct usb_interface_descriptor *desc; struct usb_endpoint_descriptor *endpoint; + struct usb_device *dev; struct usb_hub *hub; unsigned long flags; - interface = &dev->actconfig->interface[i].altsetting[0]; + desc = intf->altsetting + intf->act_altsetting; + dev = interface_to_usbdev(intf); /* Some hubs have a subclass of 1, which AFAICT according to the */ /* specs is not defined, but it works */ - if ((interface->bInterfaceSubClass != 0) && - (interface->bInterfaceSubClass != 1)) { + if ((desc->bInterfaceSubClass != 0) && + (desc->bInterfaceSubClass != 1)) { err("invalid subclass (%d) for USB hub device #%d", - interface->bInterfaceSubClass, dev->devnum); - return NULL; + desc->bInterfaceSubClass, dev->devnum); + return -EIO; } /* Multiple endpoints? What kind of mutant ninja-hub is this? */ - if (interface->bNumEndpoints != 1) { + if (desc->bNumEndpoints != 1) { err("invalid bNumEndpoints (%d) for USB hub device #%d", - interface->bNumEndpoints, dev->devnum); - return NULL; + desc->bNumEndpoints, dev->devnum); + return -EIO; } - endpoint = &interface->endpoint[0]; + endpoint = &desc->endpoint[0]; /* Output endpoint? Curiousier and curiousier.. */ if (!(endpoint->bEndpointAddress & USB_DIR_IN)) { err("Device #%d is hub class, but has output endpoint?", dev->devnum); - return NULL; + return -EIO; } /* If it's not an interrupt endpoint, we'd better punt! */ @@ -465,7 +510,7 @@ != USB_ENDPOINT_XFER_INT) { err("Device #%d is hub class, but endpoint is not interrupt?", dev->devnum); - return NULL; + return -EIO; } /* We found a hub */ @@ -474,13 +519,13 @@ hub = kmalloc(sizeof(*hub), GFP_KERNEL); if (!hub) { err("couldn't kmalloc hub struct"); - return NULL; + return -ENOMEM; } memset(hub, 0, sizeof(*hub)); INIT_LIST_HEAD(&hub->event_list); - hub->dev = dev; + hub->intf = intf; init_MUTEX(&hub->khubd_sem); /* Record the new hub's existence */ @@ -489,14 +534,18 @@ list_add(&hub->hub_list, &hub_list); spin_unlock_irqrestore(&hub_event_lock, flags); + intf->dev.driver_data = hub; + if (usb_hub_configure(hub, endpoint) >= 0) { - strcpy (dev->actconfig->interface[i].dev.name, - "Hub/Port Status Changes"); - return hub; + strcpy (intf->dev.name, "Hub/Port Status Changes"); + return 0; } err("hub configuration failed for device at %s", dev->devpath); + hub_disconnect (intf); + return -ENODEV; +#if 0 /* free hub, but first clean up its list. */ spin_lock_irqsave(&hub_event_lock, flags); @@ -511,43 +560,7 @@ kfree(hub); return NULL; -} - -static void hub_disconnect(struct usb_device *dev, void *ptr) -{ - struct usb_hub *hub = (struct usb_hub *)ptr; - unsigned long flags; - - spin_lock_irqsave(&hub_event_lock, flags); - - /* Delete it and then reset it */ - list_del(&hub->event_list); - INIT_LIST_HEAD(&hub->event_list); - list_del(&hub->hub_list); - INIT_LIST_HEAD(&hub->hub_list); - - spin_unlock_irqrestore(&hub_event_lock, flags); - - down(&hub->khubd_sem); /* Wait for khubd to leave this hub alone. */ - up(&hub->khubd_sem); - - /* assuming we used keventd, it must quiesce too */ - if (hub->tt.hub) - flush_scheduled_tasks (); - - if (hub->urb) { - usb_unlink_urb(hub->urb); - usb_free_urb(hub->urb); - hub->urb = NULL; - } - - if (hub->descriptor) { - kfree(hub->descriptor); - hub->descriptor = NULL; - } - - /* Free the memory */ - kfree(hub); +#endif } static int hub_ioctl(struct usb_device *hub, unsigned int code, void *user_data) @@ -584,7 +597,7 @@ static int usb_hub_reset(struct usb_hub *hub) { - struct usb_device *dev = hub->dev; + struct usb_device *dev = interface_to_usbdev(hub->intf); int i; /* Disconnect any attached devices */ @@ -796,7 +809,7 @@ static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port, u16 portstatus, u16 portchange) { - struct usb_device *hub = hubstate->dev; + struct usb_device *hub = interface_to_usbdev(hubstate->intf); struct usb_device *dev; unsigned int delay = HUB_SHORT_RESET_TIME; int i; @@ -891,11 +904,15 @@ /* put the device in the global device tree. the hub port * is the "bus_id"; hubs show in hierarchy like bridges */ - dev->dev.parent = &dev->parent->dev; - sprintf (&dev->dev.bus_id[0], "%d", port + 1); +// dev->dev.parent = &dev->parent->dev; +// if (dev->parent->dev.parent) + dev->dev.parent = dev->parent->dev.parent->parent; +// else +// dev->dev.parent = &dev->parent->dev; +// sprintf (&dev->dev.bus_id[0], "%d", port + 1); /* Run it through the hoops (find a driver, etc) */ - if (!usb_new_device(dev)) + if (!usb_new_device(dev, &hub->dev)) goto done; /* Free the configuration if there was an error */ @@ -940,7 +957,7 @@ tmp = hub_event_list.next; hub = list_entry(tmp, struct usb_hub, event_list); - dev = hub->dev; + dev = interface_to_usbdev(hub->intf); list_del(tmp); INIT_LIST_HEAD(tmp); @@ -1081,8 +1098,8 @@ static struct usb_driver hub_driver = { .name = "hub", .probe = hub_probe, - .ioctl = hub_ioctl, .disconnect = hub_disconnect, + .ioctl = hub_ioctl, .id_table = hub_id_table, }; diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/core/hub.h linux-2.5.34-greg/drivers/usb/core/hub.h --- linux-2.5.34/drivers/usb/core/hub.h Mon Sep 9 10:35:02 2002 +++ linux-2.5.34-greg/drivers/usb/core/hub.h Wed Sep 11 15:33:33 2002 @@ -170,7 +170,8 @@ extern void usb_hub_tt_clear_buffer (struct usb_device *dev, int pipe); struct usb_hub { - struct usb_device *dev; /* the "real" device */ +// struct usb_device *dev; /* the "real" device */ + struct usb_interface *intf; /* the "real" device */ struct urb *urb; /* for interrupt polling pipe */ /* buffer for urb ... 1 bit each for hub and children, rounded up */ diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/core/usb.c linux-2.5.34-greg/drivers/usb/core/usb.c --- linux-2.5.34/drivers/usb/core/usb.c Mon Sep 9 10:35:12 2002 +++ linux-2.5.34-greg/drivers/usb/core/usb.c Wed Sep 11 15:33:33 2002 @@ -48,225 +48,140 @@ extern int usb_major_init(void); extern void usb_major_cleanup(void); -/* - * Prototypes for the device driver probing/loading functions - */ -static void usb_find_drivers(struct usb_device *); -static void usb_check_support(struct usb_device *); - -/* - * We have a per-interface "registered driver" list. - */ -LIST_HEAD(usb_driver_list); -/** - * usb_register - register a USB driver - * @new_driver: USB operations for the driver - * - * Registers a USB driver with the USB core. The list of unattached - * interfaces will be rescanned whenever a new driver is added, allowing - * the new driver to attach to any recognized devices. - * Returns a negative error code on failure and 0 on success. - * - * NOTE: if you want your driver to use the USB major number, you must call - * usb_register_dev() to enable that functionality. This function no longer - * takes care of that. - */ -int usb_register(struct usb_driver *new_driver) +static int generic_probe (struct device *dev) { - int retval = 0; - - info("registered new driver %s", new_driver->name); - - init_MUTEX(&new_driver->serialize); + return 0; +} +static int generic_remove (struct device *dev) +{ + return 0; +} +static void generic_release (struct device_driver * drv) +{ +} - /* Add it to the list of known drivers */ - list_add_tail(&new_driver->driver_list, &usb_driver_list); +static struct device_driver usb_generic_driver = { + .name = "generic usb driver", + .probe = generic_probe, + .remove = generic_remove, + .release = generic_release, +}; + - usb_scan_devices(); +int usb_device_probe(struct device *dev) +{ + struct usb_interface * intf = to_usb_interface(dev); + struct usb_driver * driver = to_usb_driver(dev->driver); + const struct usb_device_id *id; + int error = -ENODEV; + int m; - usbfs_update_special(); + dbg("%s", __FUNCTION__); - return retval; -} + if (!driver->probe) + return error; + if (driver->owner) { + m = try_inc_mod_count(driver->owner); + if (m == 0) + return error; + } -/** - * usb_scan_devices - scans all unclaimed USB interfaces - * Context: !in_interrupt () - * - * Goes through all unclaimed USB interfaces, and offers them to all - * registered USB drivers through the 'probe' function. - * This will automatically be called after usb_register is called. - * It is called by some of the subsystems layered over USB - * after one of their subdrivers are registered. - */ -void usb_scan_devices(void) -{ - struct list_head *tmp; + id = usb_match_id (intf, driver->id_table); + if (id) { + dbg ("%s - got id", __FUNCTION__); + down (&driver->serialize); + error = driver->probe (intf, id); + up (&driver->serialize); + } + if (!error) + intf->driver = driver; - down (&usb_bus_list_lock); - tmp = usb_bus_list.next; - while (tmp != &usb_bus_list) { - struct usb_bus *bus = list_entry(tmp,struct usb_bus, bus_list); + if (driver->owner) + __MOD_DEC_USE_COUNT(driver->owner); - tmp = tmp->next; - usb_check_support(bus->root_hub); - } - up (&usb_bus_list_lock); + return error; } -/** - * usb_unbind_driver - disconnects a driver from a device (usbcore-internal) - * @device: usb device to be disconnected - * @intf: interface of the device to be disconnected - * Context: BKL held - * - * Handles module usage count correctly - */ - -void usb_unbind_driver(struct usb_device *device, struct usb_interface *intf) +int usb_device_remove(struct device *dev) { + struct usb_interface *intf; struct usb_driver *driver; - void *priv; int m; - - driver = intf->driver; - priv = intf->private_data; - - if (!driver || !driver->disconnect) - return; + intf = list_entry(dev,struct usb_interface,dev); + driver = to_usb_driver(dev->driver); + + if (!driver) { + err("%s does not have a valid driver to work with!", + __FUNCTION__); + return -ENODEV; + } - /* as soon as we increase the module use count we drop the BKL - before that we must not sleep */ if (driver->owner) { m = try_inc_mod_count(driver->owner); if (m == 0) { err("Dieing driver still bound to device.\n"); - return; + return -EIO; } - unlock_kernel(); } - down(&driver->serialize); /* if we sleep here on an umanaged driver - the holder of the lock guards against - module unload */ - driver->disconnect(device, priv); + /* if we sleep here on an umanaged driver + * the holder of the lock guards against + * module unload */ + down(&driver->serialize); + + if (intf->driver && intf->driver->disconnect) + intf->driver->disconnect(intf); + + /* if driver->disconnect didn't release the interface */ + if (intf->driver) + usb_driver_release_interface(driver, intf); up(&driver->serialize); - if (driver->owner) { - lock_kernel(); + if (driver->owner) __MOD_DEC_USE_COUNT(driver->owner); - } + + return 0; } /** - * usb_bind_driver - connect a driver to a device's interface (usbcore-internal) - * @driver: device driver to be bound to interface - * @interface: interface that the driver will be using - * Context: BKL held - * - * Does a safe binding of a driver to one of a device's interfaces. - * Returns the driver's data for the binding, or null indicating - * that the driver did not bind to this interface. - * - * This differs from usb_driver_claim_interface(), which is called from - * drivers and neither calls the driver's probe() entry nor does any - * locking to guard against removing driver modules. + * usb_register - register a USB driver + * @new_driver: USB operations for the driver + * + * Registers a USB driver with the USB core. The list of unattached + * interfaces will be rescanned whenever a new driver is added, allowing + * the new driver to attach to any recognized devices. + * Returns a negative error code on failure and 0 on success. + * + * NOTE: if you want your driver to use the USB major number, you must call + * usb_register_dev() to enable that functionality. This function no longer + * takes care of that. */ -void * -usb_bind_driver (struct usb_driver *driver, struct usb_interface *interface) +int usb_register(struct usb_driver *new_driver) { - int i,m; - void *private = NULL; - const struct usb_device_id *id; - struct usb_device *dev = interface_to_usbdev (interface); - int ifnum; - - if (driver->owner) { - m = try_inc_mod_count(driver->owner); - if (m == 0) - return NULL; /* this horse is dead - don't ride*/ - unlock_kernel(); - } - - // START TEMPORARY - // driver->probe() hasn't yet changed to take interface not dev+ifnum, - // so we still need ifnum here. - for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) - if (&dev->actconfig->interface [ifnum] == interface) - break; - BUG_ON (ifnum == dev->actconfig->bNumInterfaces); - // END TEMPORARY - - id = driver->id_table; - /* new style driver? */ - if (id) { - for (i = 0; i < interface->num_altsetting; i++) { - interface->act_altsetting = i; - id = usb_match_id(interface, id); - if (id) { - down(&driver->serialize); - private = driver->probe(dev,ifnum,id); - up(&driver->serialize); - if (private != NULL) - break; - } - } + int retval = 0; - /* if driver not bound, leave defaults unchanged */ - if (private == NULL) - interface->act_altsetting = 0; - } else { /* "old style" driver */ - down(&driver->serialize); - private = driver->probe(dev, ifnum, NULL); - up(&driver->serialize); - } - if (driver->owner) { - lock_kernel(); - __MOD_DEC_USE_COUNT(driver->owner); - } + new_driver->driver.name = (char *)new_driver->name; + new_driver->driver.bus = &usb_bus_type; + new_driver->driver.probe = usb_device_probe; + new_driver->driver.remove = usb_device_remove; - return private; -} + init_MUTEX(&new_driver->serialize); -/* - * This function is part of a depth-first search down the device tree, - * removing any instances of a device driver. - */ -static void usb_drivers_purge(struct usb_driver *driver,struct usb_device *dev) -{ - int i; + retval = driver_register(&new_driver->driver); - if (!dev) { - err("null device being purged!!!"); - return; + if (!retval) { + info("registered new driver %s", new_driver->name); + usbfs_update_special(); + } else { + err("problem %d when registering driver %s", + retval, new_driver->name); } - for (i=0; ichildren[i]) - usb_drivers_purge(driver, dev->children[i]); - - if (!dev->actconfig) - return; - - for (i = 0; i < dev->actconfig->bNumInterfaces; i++) { - struct usb_interface *interface = &dev->actconfig->interface[i]; - - if (interface->driver == driver) { - usb_unbind_driver(dev, interface); - /* if driver->disconnect didn't release the interface */ - if (interface->driver) - usb_driver_release_interface(driver, interface); - /* - * This will go through the list looking for another - * driver that can handle the device - */ - usb_find_interface_driver(dev, interface); - } - } + return retval; } /** @@ -282,25 +197,9 @@ */ void usb_deregister(struct usb_driver *driver) { - struct list_head *tmp; - info("deregistering driver %s", driver->name); - /* - * first we remove the driver, to be sure it doesn't get used by - * another thread while we are stepping through removing entries - */ - list_del(&driver->driver_list); - - down (&usb_bus_list_lock); - tmp = usb_bus_list.next; - while (tmp != &usb_bus_list) { - struct usb_bus *bus = list_entry(tmp,struct usb_bus,bus_list); - - tmp = tmp->next; - usb_drivers_purge(driver, bus->root_hub); - } - up (&usb_bus_list_lock); + remove_driver (&driver->driver); usbfs_update_special(); } @@ -359,34 +258,6 @@ return NULL; } -/* - * This function is for doing a depth-first search for devices which - * have support, for dynamic loading of driver modules. - */ -static void usb_check_support(struct usb_device *dev) -{ - int i; - - if (!dev) { - err("null device being checked!!!"); - return; - } - - for (i=0; ichildren[i]) - usb_check_support(dev->children[i]); - - if (!dev->actconfig) - return; - - /* now we check this device */ - if (dev->devnum > 0) - for (i = 0; i < dev->actconfig->bNumInterfaces; i++) - usb_find_interface_driver (dev, - dev->actconfig->interface + i); -} - - /** * usb_driver_claim_interface - bind a driver to an interface * @driver: the driver to be bound @@ -595,72 +466,25 @@ return NULL; } -/* - * This entrypoint gets called for unclaimed interfaces. - * - * We now walk the list of registered USB drivers, - * looking for one that will accept this interface. - * - * "New Style" drivers use a table describing the devices and interfaces - * they handle. Those tables are available to user mode tools deciding - * whether to load driver modules for a new device. - * - * The probe return value is changed to be a private pointer. This way - * the drivers don't have to dig around in our structures to set the - * private pointer if they only need one interface. - * - * Returns: 0 if a driver accepted the interface, -1 otherwise - */ -int usb_find_interface_driver ( - struct usb_device *dev, - struct usb_interface *interface -) +static int usb_device_match (struct device *dev, struct device_driver *drv) { - struct list_head *tmp; - void *private; - struct usb_driver *driver; - int ifnum; - - down(&dev->serialize); - - /* FIXME It's just luck that for some devices with drivers that set - * configuration in probe(), the interface numbers still make sense. - * That's one of several unsafe assumptions involved in configuring - * devices, and in binding drivers to their interfaces. - */ - for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) - if (&dev->actconfig->interface [ifnum] == interface) - break; - BUG_ON (ifnum == dev->actconfig->bNumInterfaces); + struct usb_interface *intf; + struct usb_driver *usb_drv; + const struct usb_device_id *id; - if (usb_interface_claimed(interface)) - goto out_err; + intf = to_usb_interface(dev); - private = NULL; - lock_kernel(); - for (tmp = usb_driver_list.next; tmp != &usb_driver_list;) { - driver = list_entry(tmp, struct usb_driver, driver_list); - tmp = tmp->next; - - private = usb_bind_driver(driver, interface); - - /* probe() may have changed the config on us */ - interface = dev->actconfig->interface + ifnum; - - if (private) { - usb_driver_claim_interface(driver, interface, private); - up(&dev->serialize); - unlock_kernel(); - return 0; - } - } - unlock_kernel(); + usb_drv = to_usb_driver(drv); + id = usb_drv->id_table; + + id = usb_match_id (intf, usb_drv->id_table); + if (id) + return 1; -out_err: - up(&dev->serialize); - return -1; + return 0; } + #ifdef CONFIG_HOTPLUG /* @@ -890,71 +714,6 @@ } static DEVICE_ATTR(serial,S_IRUGO,show_serial,NULL); -/* - * This entrypoint gets called for each new device. - * - * All interfaces are scanned for matching drivers. - */ -static void usb_find_drivers(struct usb_device *dev) -{ - unsigned ifnum; - unsigned rejected = 0; - unsigned claimed = 0; - - /* FIXME should get called for each new configuration not just the - * first one for a device. switching configs (or altsettings) should - * undo driverfs and HCD state for the previous interfaces. - */ - for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) { - struct usb_interface *interface = &dev->actconfig->interface[ifnum]; - struct usb_interface_descriptor *desc = interface->altsetting; - - /* register this interface with driverfs */ - interface->dev.parent = &dev->dev; - interface->dev.bus = &usb_bus_type; - sprintf (&interface->dev.bus_id[0], "%s-%s:%d", - dev->bus->bus_name, dev->devpath, - interface->altsetting->bInterfaceNumber); - if (!desc->iInterface - || usb_string (dev, desc->iInterface, - interface->dev.name, - sizeof interface->dev.name) <= 0) { - /* typically devices won't bother with interface - * descriptions; this is the normal case. an - * interface's driver might describe it better. - * (also: iInterface is per-altsetting ...) - */ - sprintf (&interface->dev.name[0], - "usb-%s-%s interface %d", - dev->bus->bus_name, dev->devpath, - interface->altsetting->bInterfaceNumber); - } - device_register (&interface->dev); - device_create_file (&interface->dev, &dev_attr_altsetting); - - /* if this interface hasn't already been claimed */ - if (!usb_interface_claimed(interface)) { - if (usb_find_interface_driver(dev, interface)) - rejected++; - else - claimed++; - } - } - - if (rejected) - dbg("unhandled interfaces on device"); - - if (!claimed) { - warn("USB device %d (vend/prod 0x%x/0x%x) is not claimed by any active driver.", - dev->devnum, - dev->descriptor.idVendor, - dev->descriptor.idProduct); -#ifdef DEBUG - usb_show_device(dev); -#endif - } -} - /** * usb_alloc_dev - allocate a usb device structure (usbcore-internal) * @parent: hub to which device is connected @@ -1109,32 +868,21 @@ info("USB disconnect on device %d", dev->devnum); - lock_kernel(); - if (dev->actconfig) { - for (i = 0; i < dev->actconfig->bNumInterfaces; i++) { - struct usb_interface *interface = &dev->actconfig->interface[i]; - struct usb_driver *driver = interface->driver; - if (driver) { - usb_unbind_driver(dev, interface); - /* if driver->disconnect didn't release the interface */ - if (interface->driver) - usb_driver_release_interface(driver, interface); - } - /* remove our device node for this interface */ - put_device(&interface->dev); - } - } - unlock_kernel(); - - /* Free up all the children.. */ + /* Free up all the children before we remove this device */ for (i = 0; i < USB_MAXCHILDREN; i++) { struct usb_device **child = dev->children + i; if (*child) usb_disconnect(child); } - /* Let policy agent unload modules etc */ - call_policy ("remove", dev); + if (dev->actconfig) { + for (i = 0; i < dev->actconfig->bNumInterfaces; i++) { + struct usb_interface *interface = &dev->actconfig->interface[i]; + + /* remove this interface */ + put_device(&interface->dev); + } + } /* Free the device number and remove the /proc/bus/usb entry */ if (dev->devnum > 0) { @@ -1143,6 +891,9 @@ put_device(&dev->dev); } + /* Let policy agent unload modules etc */ + call_policy ("remove", dev); + /* Decrement the reference count, it'll auto free everything when */ /* it hits 0 which could very well be now */ usb_put_dev(dev); @@ -1271,7 +1022,7 @@ */ #define NEW_DEVICE_RETRYS 2 #define SET_ADDRESS_RETRYS 2 -int usb_new_device(struct usb_device *dev) +int usb_new_device(struct usb_device *dev, struct device *parent) { int err = 0; int i; @@ -1361,10 +1112,25 @@ usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber); #endif - /* register this device in the driverfs tree */ + /* + * 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 + * probe function. Yes, it's a hack, but a nice one :) + */ + usb_generic_driver.bus = &usb_bus_type; + dev->dev.parent = parent; + dev->dev.driver = &usb_generic_driver; + dev->dev.bus = &usb_bus_type; +// sprintf (&dev->dev.bus_id[0], "%s-%s", +// dev->bus->bus_name, dev->devpath); + if (dev->dev.bus_id[0] == 0) + sprintf (&dev->dev.bus_id[0], "%d-%s", + dev->bus->busnum, dev->devpath); err = device_register (&dev->dev); if (err) return err; + + /* add the USB device specific driverfs files */ device_create_file (&dev->dev, &dev_attr_configuration); if (dev->descriptor.iManufacturer) device_create_file (&dev->dev, &dev_attr_manufacturer); @@ -1373,11 +1139,41 @@ if (dev->descriptor.iSerialNumber) device_create_file (&dev->dev, &dev_attr_serial); - /* now that the basic setup is over, add a /proc/bus/usb entry */ - usbfs_add_device(dev); + /* Register all of the interfaces for this device with the driver core. + * Remember, interfaces get bound to drivers, not devices. */ + for (i = 0; i < dev->actconfig->bNumInterfaces; i++) { + struct usb_interface *interface = &dev->actconfig->interface[i]; + struct usb_interface_descriptor *desc = interface->altsetting; + + interface->dev.parent = &dev->dev; + interface->dev.bus = &usb_bus_type; +// sprintf (&interface->dev.bus_id[0], "%s-%s:%d", +// dev->bus->bus_name, dev->devpath, +// interface->altsetting->bInterfaceNumber); + sprintf (&interface->dev.bus_id[0], "%d-%s:%d", + dev->bus->busnum, dev->devpath, + interface->altsetting->bInterfaceNumber); + if (!desc->iInterface + || usb_string (dev, desc->iInterface, + interface->dev.name, + sizeof interface->dev.name) <= 0) { + /* typically devices won't bother with interface + * descriptions; this is the normal case. an + * interface's driver might describe it better. + * (also: iInterface is per-altsetting ...) + */ + sprintf (&interface->dev.name[0], + "usb-%s-%s interface %d", + dev->bus->bus_name, dev->devpath, + interface->altsetting->bInterfaceNumber); + } + dbg ("%s - registering %s", __FUNCTION__, interface->dev.bus_id); + device_register (&interface->dev); + device_create_file (&interface->dev, &dev_attr_altsetting); + } - /* find drivers willing to handle this device */ - usb_find_drivers(dev); + /* add a /proc/bus/usb entry */ + usbfs_add_device(dev); /* userspace may load modules and/or configure further */ call_policy ("add", dev); @@ -1385,7 +1181,6 @@ return 0; } - /** * usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_DMA_MAP * @dev: device the buffer will be used with @@ -1531,7 +1326,6 @@ ? USB_DIR_IN : USB_DIR_OUT); } - /** * usb_buffer_map_sg - create scatterlist DMA mapping(s) for an endpoint * @dev: device to which the scatterlist will be mapped @@ -1642,20 +1436,10 @@ : USB_DIR_OUT); } -#ifdef CONFIG_PROC_FS -struct list_head *usb_driver_get_list(void) -{ - return &usb_driver_list; -} - -struct list_head *usb_bus_get_list(void) -{ - return &usb_bus_list; -} -#endif struct bus_type usb_bus_type = { - .name = "usb", + .name = "usb", + .match = usb_device_match, }; /* @@ -1694,7 +1478,9 @@ EXPORT_SYMBOL(usb_register); EXPORT_SYMBOL(usb_deregister); -EXPORT_SYMBOL(usb_scan_devices); + +EXPORT_SYMBOL(usb_device_probe); +EXPORT_SYMBOL(usb_device_remove); EXPORT_SYMBOL(usb_alloc_dev); EXPORT_SYMBOL(usb_free_dev); diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/image/hpusbscsi.c linux-2.5.34-greg/drivers/usb/image/hpusbscsi.c --- linux-2.5.34/drivers/usb/image/hpusbscsi.c Mon Sep 9 10:35:29 2002 +++ linux-2.5.34-greg/drivers/usb/image/hpusbscsi.c Wed Sep 11 15:33:33 2002 @@ -30,13 +30,14 @@ /* USB related parts */ -static void * -hpusbscsi_usb_probe (struct usb_device *dev, unsigned int interface, +static int +hpusbscsi_usb_probe (struct usb_interface *intf, const struct usb_device_id *id) { struct hpusbscsi *new; + struct usb_device *dev = interface_to_usbdev (intf); struct usb_interface_descriptor *altsetting = - &(dev->actconfig->interface[interface].altsetting[0]); + &(intf->altsetting[0]); int i, result; @@ -44,7 +45,7 @@ if (altsetting->bNumEndpoints != 3) { printk (KERN_ERR "Wrong number of endpoints\n"); - return NULL; + return -ENODEV; } /* descriptor allocation */ @@ -53,19 +54,19 @@ (struct hpusbscsi *) kmalloc (sizeof (struct hpusbscsi), GFP_KERNEL); if (new == NULL) - return NULL; + return -ENOMEM; DEBUG ("Allocated memory\n"); memset (new, 0, sizeof (struct hpusbscsi)); new->dataurb = usb_alloc_urb(0, GFP_KERNEL); if (!new->dataurb) { kfree (new); - return NULL; + return -ENOMEM; } new->controlurb = usb_alloc_urb(0, GFP_KERNEL); if (!new->controlurb) { usb_free_urb (new->dataurb); kfree (new); - return NULL; + return -ENOMEM; } new->dev = dev; init_waitqueue_head (&new->pending); @@ -135,20 +136,24 @@ /* adding to list for module unload */ list_add (&hpusbscsi_devices, &new->lh); - return new; + dev_set_drvdata(&intf->dev, new); + return 0; err_out: usb_free_urb (new->controlurb); usb_free_urb (new->dataurb); kfree (new); - return NULL; + return -ENODEV; } static void -hpusbscsi_usb_disconnect (struct usb_device *dev, void *ptr) +hpusbscsi_usb_disconnect (struct usb_interface *intf) { - usb_unlink_urb((((struct hpusbscsi *) ptr)->controlurb)); - ((struct hpusbscsi *) ptr)->dev = NULL; + struct hpusbscsi *desc = dev_get_drvdata(&intf->dev); + + dev_set_drvdata(&intf->dev, NULL); + if (desc) + usb_unlink_urb(desc->controlurb); } static struct usb_device_id hpusbscsi_usb_ids[] = { diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/image/mdc800.c linux-2.5.34-greg/drivers/usb/image/mdc800.c --- linux-2.5.34/drivers/usb/image/mdc800.c Mon Sep 9 10:34:59 2002 +++ linux-2.5.34-greg/drivers/usb/image/mdc800.c Wed Sep 11 15:33:33 2002 @@ -406,11 +406,12 @@ /* * Callback to search the Mustek MDC800 on the USB Bus */ -static void* mdc800_usb_probe (struct usb_device *dev ,unsigned int ifnum, +static int mdc800_usb_probe (struct usb_interface *intf, const struct usb_device_id *id) { int i,j; struct usb_interface_descriptor *intf_desc; + struct usb_device *dev = interface_to_usbdev (intf); int irq_interval=0; int retval; @@ -420,15 +421,15 @@ if (mdc800->dev != 0) { warn ("only one Mustek MDC800 is supported."); - return 0; + return -ENODEV; } if (dev->descriptor.bNumConfigurations != 1) { err ("probe fails -> wrong Number of Configuration"); - return 0; + return -ENODEV; } - intf_desc=&dev->actconfig->interface[ifnum].altsetting[0]; + intf_desc = &intf->altsetting[0]; if ( ( intf_desc->bInterfaceClass != 0xff ) @@ -438,7 +439,7 @@ ) { err ("probe fails -> wrong Interface"); - return 0; + return -ENODEV; } /* Check the Endpoints */ @@ -461,16 +462,16 @@ if (mdc800->endpoint[i] == -1) { err ("probe fails -> Wrong Endpoints."); - return 0; + return -ENODEV; } } - usb_driver_claim_interface (&mdc800_usb_driver, &dev->actconfig->interface[ifnum], mdc800); - if (usb_set_interface (dev, ifnum, 0) < 0) + usb_driver_claim_interface (&mdc800_usb_driver, intf, mdc800); + if (usb_set_interface (dev, intf_desc->bInterfaceNumber, 0) < 0) { err ("MDC800 Configuration fails."); - return 0; + return -ENODEV; } info ("Found Mustek MDC800 on USB."); @@ -480,7 +481,7 @@ retval = usb_register_dev (&mdc800_device_ops, MDC800_DEVICE_MINOR_BASE, 1, &mdc800->minor); if (retval && (retval != -ENODEV)) { err ("Not able to get a minor for this device."); - return 0; + return -ENODEV; } mdc800->dev=dev; @@ -522,33 +523,37 @@ up (&mdc800->io_lock); - return mdc800; + dev_set_drvdata(&intf->dev, mdc800); + return 0; } /* * Disconnect USB device (maybe the MDC800) */ -static void mdc800_usb_disconnect (struct usb_device *dev,void* ptr) +static void mdc800_usb_disconnect (struct usb_interface *intf) { - struct mdc800_data* mdc800=(struct mdc800_data*) ptr; + struct mdc800_data* mdc800 = dev_get_drvdata(&intf->dev); dbg ("(mdc800_usb_disconnect) called"); - if (mdc800->state == NOT_CONNECTED) - return; - - usb_deregister_dev (1, mdc800->minor); + if (mdc800) { + if (mdc800->state == NOT_CONNECTED) + return; + + usb_deregister_dev (1, mdc800->minor); - mdc800->state=NOT_CONNECTED; + mdc800->state=NOT_CONNECTED; - usb_unlink_urb (mdc800->irq_urb); - usb_unlink_urb (mdc800->write_urb); - usb_unlink_urb (mdc800->download_urb); + usb_unlink_urb (mdc800->irq_urb); + usb_unlink_urb (mdc800->write_urb); + usb_unlink_urb (mdc800->download_urb); - usb_driver_release_interface (&mdc800_usb_driver, &dev->actconfig->interface[1]); + usb_driver_release_interface (&mdc800_usb_driver, intf); - mdc800->dev=0; + mdc800->dev=0; + dev_set_drvdata(&intf->dev, NULL); + } info ("Mustek MDC800 disconnected from USB."); } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/image/microtek.c linux-2.5.34-greg/drivers/usb/image/microtek.c --- linux-2.5.34/drivers/usb/image/microtek.c Mon Sep 9 10:35:12 2002 +++ linux-2.5.34-greg/drivers/usb/image/microtek.c Wed Sep 11 15:33:33 2002 @@ -154,9 +154,9 @@ /* USB layer driver interface */ -static void *mts_usb_probe(struct usb_device *dev, unsigned int interface, +static int mts_usb_probe(struct usb_interface *intf, const struct usb_device_id *id); -static void mts_usb_disconnect(struct usb_device *dev, void *ptr); +static void mts_usb_disconnect(struct usb_interface *intf); static struct usb_device_id mts_usb_ids []; @@ -764,18 +764,21 @@ /* USB layer driver interface implementation */ -static void mts_usb_disconnect (struct usb_device *dev, void *ptr) +static void mts_usb_disconnect (struct usb_interface *intf) { - struct mts_desc* to_remove = (struct mts_desc*)ptr; + struct mts_desc* to_remove = dev_get_drvdata(&intf->dev); MTS_DEBUG_GOT_HERE(); - /* leave the list - lock it */ - down(&mts_list_semaphore); + dev_set_drvdata(&intf->dev, NULL); + if (to_remove) { + /* leave the list - lock it */ + down(&mts_list_semaphore); - mts_remove_nolock(to_remove); + mts_remove_nolock(to_remove); - up(&mts_list_semaphore); + up(&mts_list_semaphore); + } } struct vendor_product @@ -825,8 +828,8 @@ MODULE_DEVICE_TABLE (usb, mts_usb_ids); -static void * mts_usb_probe (struct usb_device *dev, unsigned int interface, - const struct usb_device_id *id) +static int mts_usb_probe (struct usb_interface *intf, + const struct usb_device_id *id) { int i; int result; @@ -837,6 +840,7 @@ struct mts_desc * new_desc; struct vendor_product const* p; + struct usb_device *dev = interface_to_usbdev (intf); /* the altsettting 0 on the interface we're probing */ struct usb_interface_descriptor *altsetting; @@ -860,8 +864,7 @@ p->name ); /* the altsettting 0 on the interface we're probing */ - altsetting = - &(dev->actconfig->interface[interface].altsetting[0]); + altsetting = &(intf->altsetting[0]); /* Check if the config is sane */ @@ -869,7 +872,7 @@ if ( altsetting->bNumEndpoints != MTS_EP_TOTAL ) { MTS_WARNING( "expecting %d got %d endpoints! Bailing out.\n", (int)MTS_EP_TOTAL, (int)altsetting->bNumEndpoints ); - return NULL; + return -ENODEV; } for( i = 0; i < altsetting->bNumEndpoints; i++ ) { @@ -887,7 +890,7 @@ else { if ( ep_out != -1 ) { MTS_WARNING( "can only deal with one output endpoints. Bailing out." ); - return NULL; + return -ENODEV; } ep_out = altsetting->endpoint[i].bEndpointAddress & @@ -900,7 +903,7 @@ if ( ep_out == -1 ) { MTS_WARNING( "couldn't find an output bulk endpoint. Bailing out.\n" ); - return NULL; + return -ENODEV; } @@ -923,7 +926,7 @@ default: MTS_DEBUG( "unknown error %d from usb_set_interface\n", (int)result ); - return NULL; + return -ENODEV; } @@ -932,19 +935,18 @@ if (new_desc == NULL) { MTS_ERROR("couldn't allocate scanner desc, bailing out!\n"); - return NULL; + return -ENOMEM; } memset( new_desc, 0, sizeof(*new_desc) ); new_desc->urb = usb_alloc_urb(0, GFP_KERNEL); if (!new_desc->urb) { kfree(new_desc); - return NULL; + return -ENOMEM; } /* initialising that descriptor */ new_desc->usb_dev = dev; - new_desc->interface = interface; init_MUTEX(&new_desc->lock); @@ -991,7 +993,7 @@ /* FIXME: need more cleanup? */ kfree( new_desc ); - return NULL; + return -ENOMEM; } MTS_DEBUG_GOT_HERE(); @@ -1006,7 +1008,8 @@ MTS_DEBUG("completed probe and exiting happily\n"); - return (void *)new_desc; + dev_set_drvdata(&intf->dev, new_desc); + return 0; } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/image/microtek.h linux-2.5.34-greg/drivers/usb/image/microtek.h --- linux-2.5.34/drivers/usb/image/microtek.h Mon Sep 9 10:35:05 2002 +++ linux-2.5.34-greg/drivers/usb/image/microtek.h Wed Sep 11 15:33:33 2002 @@ -33,8 +33,6 @@ struct usb_device *usb_dev; - int interface; - /* Endpoint addresses */ u8 ep_out; u8 ep_response; diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/image/scanner.c linux-2.5.34-greg/drivers/usb/image/scanner.c --- linux-2.5.34/drivers/usb/image/scanner.c Mon Sep 9 10:35:06 2002 +++ linux-2.5.34-greg/drivers/usb/image/scanner.c Wed Sep 11 15:33:33 2002 @@ -818,10 +818,11 @@ .release = close_scanner, }; -static void * -probe_scanner(struct usb_device *dev, unsigned int ifnum, +static int +probe_scanner(struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev (intf); struct scn_usb_data *scn; struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; @@ -876,8 +877,8 @@ valid_device = 1; } - if (!valid_device) - return NULL; /* We didn't find anything pleasing */ + if (!valid_device) + return -ENODEV; /* We didn't find anything pleasing */ /* * After this point we can be a little noisy about what we are trying to @@ -886,16 +887,16 @@ if (dev->descriptor.bNumConfigurations != 1) { info("probe_scanner: Only one device configuration is supported."); - return NULL; + return -ENODEV; } if (dev->config[0].bNumInterfaces != 1) { info("probe_scanner: Only one device interface is supported."); - return NULL; + return -ENODEV; } - interface = dev->config[0].interface[ifnum].altsetting; - endpoint = interface[ifnum].endpoint; + interface = intf->altsetting; + endpoint = interface->endpoint; /* * Start checking for two bulk endpoints OR two bulk endpoints *and* one @@ -907,7 +908,7 @@ if ((interface->bNumEndpoints != 2) && (interface->bNumEndpoints != 3)) { info("probe_scanner: Only two or three endpoints supported."); - return NULL; + return -ENODEV; } ep_cnt = have_bulk_in = have_bulk_out = have_intr = 0; @@ -935,7 +936,7 @@ continue; } info("probe_scanner: Undetected endpoint -- consult Documentation/usb/scanner.txt."); - return NULL; /* Shouldn't ever get here unless we have something weird */ + return -EIO; /* Shouldn't ever get here unless we have something weird */ } @@ -948,18 +949,18 @@ case 2: if (!have_bulk_in || !have_bulk_out) { info("probe_scanner: Two bulk endpoints required."); - return NULL; + return -EIO; } break; case 3: if (!have_bulk_in || !have_bulk_out || !have_intr) { info("probe_scanner: Two bulk endpoints and one interrupt endpoint required."); - return NULL; + return -EIO; } break; default: info("probe_scanner: Endpoint determination failed -- consult Documentation/usb/scanner.txt"); - return NULL; + return -EIO; } @@ -975,14 +976,14 @@ if (retval) { err ("Not able to get a minor for this device."); up(&scn_mutex); - return NULL; + return -ENOMEM; } /* Check to make sure that the last slot isn't already taken */ if (p_scn_table[scn_minor]) { err("probe_scanner: No more minor devices remaining."); up(&scn_mutex); - return NULL; + return -ENOMEM; } dbg("probe_scanner: Allocated minor:%d", scn_minor); @@ -990,7 +991,7 @@ if (!(scn = kmalloc (sizeof (struct scn_usb_data), GFP_KERNEL))) { err("probe_scanner: Out of memory."); up(&scn_mutex); - return NULL; + return -ENOMEM; } memset (scn, 0, sizeof(struct scn_usb_data)); @@ -998,7 +999,7 @@ if (!scn->scn_irq) { kfree(scn); up(&scn_mutex); - return NULL; + return -ENOMEM; } init_MUTEX(&(scn->sem)); /* Initializes to unlocked */ @@ -1018,7 +1019,7 @@ err("probe_scanner(%d): Unable to allocate INT URB.", scn_minor); kfree(scn); up(&scn_mutex); - return NULL; + return -ENOMEM; } } @@ -1028,7 +1029,7 @@ err("probe_scanner(%d): Not enough memory for the output buffer.", scn_minor); kfree(scn); up(&scn_mutex); - return NULL; + return -ENOMEM; } dbg("probe_scanner(%d): obuf address:%p", scn_minor, scn->obuf); @@ -1037,7 +1038,7 @@ kfree(scn->obuf); kfree(scn); up(&scn_mutex); - return NULL; + return -ENOMEM; } dbg("probe_scanner(%d): ibuf address:%p", scn_minor, scn->ibuf); @@ -1083,45 +1084,54 @@ up(&scn_mutex); - return scn; + dev_set_drvdata(&intf->dev, scn); + return 0; } static void -disconnect_scanner(struct usb_device *dev, void *ptr) +disconnect_scanner(struct usb_interface *intf) { - struct scn_usb_data *scn = (struct scn_usb_data *) ptr; + struct scn_usb_data *scn = dev_get_drvdata(&intf->dev); - down (&scn_mutex); - down (&(scn->sem)); + dev_set_drvdata(&intf->dev, NULL); + if (scn) { + down (&scn_mutex); + down (&(scn->sem)); + + if(scn->intr_ep) { + dbg("disconnect_scanner(%d): Unlinking IRQ URB", scn->scn_minor); + usb_unlink_urb(scn->scn_irq); + } + usb_driver_release_interface(&scanner_driver, + &scn->scn_dev->actconfig->interface[scn->ifnum]); + + kfree(scn->ibuf); + kfree(scn->obuf); - if(scn->intr_ep) { - dbg("disconnect_scanner(%d): Unlinking IRQ URB", scn->scn_minor); - usb_unlink_urb(scn->scn_irq); - } - usb_driver_release_interface(&scanner_driver, - &scn->scn_dev->actconfig->interface[scn->ifnum]); - - kfree(scn->ibuf); - kfree(scn->obuf); - - dbg("disconnect_scanner: De-allocating minor:%d", scn->scn_minor); - devfs_unregister(scn->devfs); - usb_deregister_dev(1, scn->scn_minor); - p_scn_table[scn->scn_minor] = NULL; - usb_free_urb(scn->scn_irq); - up (&(scn->sem)); - kfree (scn); - up (&scn_mutex); + dbg("disconnect_scanner: De-allocating minor:%d", scn->scn_minor); + devfs_unregister(scn->devfs); + usb_deregister_dev(1, scn->scn_minor); + p_scn_table[scn->scn_minor] = NULL; + usb_free_urb(scn->scn_irq); + up (&(scn->sem)); + kfree (scn); + up (&scn_mutex); + } } +/* we want to look at all devices, as the vendor/product id can change + * depending on the command line argument */ +static struct usb_device_id ids[] = { + {.driver_info = 42}, + {} +}; + static struct usb_driver scanner_driver = { .name = "usbscanner", .probe = probe_scanner, .disconnect = disconnect_scanner, - .id_table = NULL, /* This would be scanner_device_ids, but we - need to check every USB device, in case - we match a user defined vendor/product ID. */ + .id_table = ids, }; void __exit diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/input/aiptek.c linux-2.5.34-greg/drivers/usb/input/aiptek.c --- linux-2.5.34/drivers/usb/input/aiptek.c Mon Sep 9 10:35:05 2002 +++ linux-2.5.34-greg/drivers/usb/input/aiptek.c Wed Sep 11 15:33:33 2002 @@ -204,6 +204,11 @@ usb_unlink_urb(aiptek->irq); } +/* + * FIXME, either remove this call, or talk the maintainer into + * adding usb_set_report back into the core. + */ +#if 0 static void aiptek_command(struct usb_device *dev, unsigned int ifnum, unsigned char command, unsigned char data) @@ -214,47 +219,43 @@ buf[1] = command; buf[2] = data; - /* - * FIXME, either remove this call, or talk the maintainer into - * adding it back into the core. - */ -#if 0 if (usb_set_report(dev, ifnum, 3, 2, buf, 3) != 3) { dbg("aiptek_command: 0x%x 0x%x\n", command, data); } -#endif } +#endif -static void* -aiptek_probe(struct usb_device *dev, unsigned int ifnum, +static int +aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev (intf); struct usb_endpoint_descriptor *endpoint; struct aiptek *aiptek; if (!(aiptek = kmalloc(sizeof (struct aiptek), GFP_KERNEL))) - return NULL; + return -ENOMEM; memset(aiptek, 0, sizeof (struct aiptek)); aiptek->data = usb_buffer_alloc(dev, 10, SLAB_ATOMIC, &aiptek->data_dma); if (!aiptek->data) { kfree(aiptek); - return NULL; + return -ENOMEM; } aiptek->irq = usb_alloc_urb(0, GFP_KERNEL); if (!aiptek->irq) { usb_buffer_free(dev, 10, aiptek->data, aiptek->data_dma); kfree(aiptek); - return NULL; + return -ENOMEM; } // Resolution500LPI - aiptek_command(dev, ifnum, 0x18, 0x04); +// aiptek_command(dev, ifnum, 0x18, 0x04); // SwitchToTablet - aiptek_command(dev, ifnum, 0x10, 0x01); +// aiptek_command(dev, ifnum, 0x10, 0x01); aiptek->features = aiptek_features + id->driver_info; @@ -294,7 +295,7 @@ aiptek->dev.id.version = dev->descriptor.bcdDevice; aiptek->usbdev = dev; - endpoint = dev->config[0].interface[ifnum].altsetting[0].endpoint + 0; + endpoint = intf->altsetting[0].endpoint + 0; if (aiptek->features->pktlen > 10) BUG(); @@ -308,28 +309,33 @@ input_register_device(&aiptek->dev); - printk(KERN_INFO "input: %s on usb%d:%d.%d\n", - aiptek->features->name, dev->bus->busnum, dev->devnum, ifnum); + printk(KERN_INFO "input: %s on usb%d:%d\n", + aiptek->features->name, dev->bus->busnum, dev->devnum); - return aiptek; + dev_set_drvdata(&intf->dev, aiptek); + return 0; } static void -aiptek_disconnect(struct usb_device *dev, void *ptr) +aiptek_disconnect(struct usb_interface *intf) { - struct aiptek *aiptek = ptr; - usb_unlink_urb(aiptek->irq); - input_unregister_device(&aiptek->dev); - usb_free_urb(aiptek->irq); - usb_buffer_free(dev, 10, aiptek->data, aiptek->data_dma); - kfree(aiptek); + struct aiptek *aiptek = dev_get_drvdata(&intf->dev); + + dev_set_drvdata(&intf->dev, NULL); + if (aiptek) { + usb_unlink_urb(aiptek->irq); + input_unregister_device(&aiptek->dev); + usb_free_urb(aiptek->irq); + usb_buffer_free(interface_to_usbdev(intf), 10, aiptek->data, aiptek->data_dma); + kfree(aiptek); + } } static struct usb_driver aiptek_driver = { - .name ="aiptek", - .probe =aiptek_probe, - .disconnect =aiptek_disconnect, - .id_table =aiptek_ids, + .name = "aiptek", + .probe = aiptek_probe, + .disconnect = aiptek_disconnect, + .id_table = aiptek_ids, }; static int __init diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/input/hid-core.c linux-2.5.34-greg/drivers/usb/input/hid-core.c --- linux-2.5.34/drivers/usb/input/hid-core.c Mon Sep 9 10:35:13 2002 +++ linux-2.5.34-greg/drivers/usb/input/hid-core.c Wed Sep 11 15:33:33 2002 @@ -1349,9 +1349,10 @@ usb_buffer_free(dev, HID_BUFFER_SIZE, hid->ctrlbuf, hid->ctrlbuf_dma); } -static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum) +static struct hid_device *usb_hid_configure(struct usb_interface *intf) { - struct usb_interface_descriptor *interface = dev->actconfig->interface[ifnum].altsetting + 0; + struct usb_interface_descriptor *interface = intf->altsetting + intf->act_altsetting; + struct usb_device *dev = interface_to_usbdev (intf); struct hid_descriptor *hdesc; struct hid_device *hid; unsigned quirks = 0, rsize = 0; @@ -1472,7 +1473,7 @@ snprintf(hid->name, 128, "%04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct); usb_make_path(dev, buf, 64); - snprintf(hid->phys, 64, "%s/input%d", buf, ifnum); + snprintf(hid->phys, 64, "%s/input%d", buf, intf->altsetting[0].bInterfaceNumber); if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) hid->uniq[0] = 0; @@ -1499,9 +1500,12 @@ return NULL; } -static void hid_disconnect(struct usb_device *dev, void *ptr) +static void hid_disconnect(struct usb_interface *intf) { - struct hid_device *hid = ptr; + struct hid_device *hid = intf->dev.driver_data; + + if (!hid) + return; usb_unlink_urb(hid->urbin); usb_unlink_urb(hid->urbout); @@ -1517,22 +1521,22 @@ if (hid->urbout) usb_free_urb(hid->urbout); - hid_free_buffers(dev, hid); + hid_free_buffers(hid->dev, hid); hid_free_device(hid); + intf->dev.driver_data = NULL; } -static void* hid_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id) +static int hid_probe (struct usb_interface *intf, const struct usb_device_id *id) { struct hid_device *hid; char path[64]; int i; char *c; - dbg("HID probe called for ifnum %d", ifnum); + dbg("HID probe called for ifnum %d", intf->ifnum); - if (!(hid = usb_hid_configure(dev, ifnum))) - return NULL; + if (!(hid = usb_hid_configure(intf))) + return -EIO; hid_init_reports(hid); hid_dump_device(hid); @@ -1544,9 +1548,11 @@ if (!hiddev_connect(hid)) hid->claimed |= HID_CLAIMED_HIDDEV; + intf->dev.driver_data = hid; + if (!hid->claimed) { - hid_disconnect(dev, hid); - return NULL; + hid_disconnect(intf); + return -EIO; } printk(KERN_INFO); @@ -1568,12 +1574,12 @@ } } - usb_make_path(dev, path, 63); + usb_make_path(interface_to_usbdev(intf), path, 63); printk(": USB HID v%x.%02x %s [%s] on %s\n", hid->version >> 8, hid->version & 0xff, c, hid->name, path); - return hid; + return 0; } static struct usb_device_id hid_usb_ids [] = { diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/input/hiddev.c linux-2.5.34-greg/drivers/usb/input/hiddev.c --- linux-2.5.34/drivers/usb/input/hiddev.c Mon Sep 9 10:35:09 2002 +++ linux-2.5.34-greg/drivers/usb/input/hiddev.c Wed Sep 11 15:33:33 2002 @@ -751,10 +751,10 @@ /* We never attach in this manner, and rely on HID to connect us. This * is why there is no disconnect routine defined in the usb_driver either. */ -static void *hiddev_usbd_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *hiddev_info) +static int hiddev_usbd_probe(struct usb_interface *intf, + const struct usb_device_id *hiddev_info) { - return NULL; + return -ENODEV; } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/input/powermate.c linux-2.5.34-greg/drivers/usb/input/powermate.c --- linux-2.5.34/drivers/usb/input/powermate.c Mon Sep 9 10:35:13 2002 +++ linux-2.5.34-greg/drivers/usb/input/powermate.c Wed Sep 11 15:33:33 2002 @@ -268,18 +268,21 @@ } /* Called whenever a USB device matching one in our supported devices table is connected */ -static void *powermate_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id) +static int powermate_probe(struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_device *udev = interface_to_usbdev (intf); struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; struct powermate_device *pm; int pipe, maxp; char path[64]; - interface = udev->config[0].interface[ifnum].altsetting + 0; + interface = intf->altsetting + 0; endpoint = interface->endpoint + 0; - if (!(endpoint->bEndpointAddress & 0x80)) return NULL; - if ((endpoint->bmAttributes & 3) != 3) return NULL; + if (!(endpoint->bEndpointAddress & 0x80)) + return -EIO; + if ((endpoint->bmAttributes & 3) != 3) + return -EIO; usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0a, USB_TYPE_CLASS | USB_RECIP_INTERFACE, @@ -287,7 +290,7 @@ HZ * USB_CTRL_SET_TIMEOUT); if (!(pm = kmalloc(sizeof(struct powermate_device), GFP_KERNEL))) - return NULL; + return -ENOMEM; memset(pm, 0, sizeof(struct powermate_device)); pm->udev = udev; @@ -295,14 +298,14 @@ if (powermate_alloc_buffers(udev, pm)) { powermate_free_buffers(udev, pm); kfree(pm); - return NULL; + return -ENOMEM; } pm->irq = usb_alloc_urb(0, GFP_KERNEL); if (!pm->irq) { powermate_free_buffers(udev, pm); kfree(pm); - return NULL; + return -ENOMEM; } pm->config = usb_alloc_urb(0, GFP_KERNEL); @@ -310,7 +313,7 @@ usb_free_urb(pm->irq); powermate_free_buffers(udev, pm); kfree(pm); - return NULL; + return -ENOMEM; } init_MUTEX(&pm->lock); @@ -333,7 +336,7 @@ if (usb_submit_urb(pm->irq, GFP_KERNEL)) { powermate_free_buffers(udev, pm); kfree(pm); - return NULL; /* failure */ + return -EIO; /* failure */ } switch (udev->descriptor.idProduct) { @@ -365,22 +368,27 @@ pm->requires_update = UPDATE_PULSE_ASLEEP | UPDATE_PULSE_AWAKE | UPDATE_PULSE_MODE | UPDATE_STATIC_BRIGHTNESS; powermate_pulse_led(pm, 0x80, 255, 0, 1, 0); // set default pulse parameters - return pm; + dev_set_drvdata(&intf->dev, pm); + return 0; } /* Called when a USB device we've accepted ownership of is removed */ -static void powermate_disconnect(struct usb_device *dev, void *ptr) +static void powermate_disconnect(struct usb_interface *intf) { - struct powermate_device *pm = ptr; - down(&pm->lock); - pm->requires_update = 0; - usb_unlink_urb(pm->irq); - input_unregister_device(&pm->input); - usb_free_urb(pm->irq); - usb_free_urb(pm->config); - powermate_free_buffers(dev, pm); - - kfree(pm); + struct powermate_device *pm = dev_get_drvdata(&intf->dev); + + dev_set_drvdata(&intf->dev, NULL); + if (pm) { + down(&pm->lock); + pm->requires_update = 0; + usb_unlink_urb(pm->irq); + input_unregister_device(&pm->input); + usb_free_urb(pm->irq); + usb_free_urb(pm->config); + powermate_free_buffers(interface_to_usbdev(intf), pm); + + kfree(pm); + } } static struct usb_device_id powermate_devices [] = { diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/input/usbmouse.c linux-2.5.34-greg/drivers/usb/input/usbmouse.c --- linux-2.5.34/drivers/usb/input/usbmouse.c Mon Sep 9 10:35:16 2002 +++ linux-2.5.34-greg/drivers/usb/input/usbmouse.c Wed Sep 11 15:33:33 2002 @@ -100,10 +100,9 @@ usb_unlink_urb(mouse->irq); } -static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id) +static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_id * id) { - struct usb_interface *iface; + struct usb_device * dev = interface_to_usbdev(intf); struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; struct usb_mouse *mouse; @@ -111,19 +110,22 @@ char path[64]; char *buf; - iface = &dev->actconfig->interface[ifnum]; - interface = &iface->altsetting[iface->act_altsetting]; + interface = &intf->altsetting[intf->act_altsetting]; - if (interface->bNumEndpoints != 1) return NULL; + if (interface->bNumEndpoints != 1) + return -ENODEV; endpoint = interface->endpoint + 0; - if (!(endpoint->bEndpointAddress & 0x80)) return NULL; - if ((endpoint->bmAttributes & 3) != 3) return NULL; + if (!(endpoint->bEndpointAddress & 0x80)) + return -ENODEV; + if ((endpoint->bmAttributes & 3) != 3) + return -ENODEV; pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); - if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) return NULL; + if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) + return -ENOMEM; memset(mouse, 0, sizeof(struct usb_mouse)); mouse->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &mouse->data_dma); @@ -136,7 +138,7 @@ if (!mouse->irq) { usb_buffer_free(dev, 8, mouse->data, mouse->data_dma); kfree(mouse); - return NULL; + return -ENODEV; } mouse->usbdev = dev; @@ -164,7 +166,7 @@ if (!(buf = kmalloc(63, GFP_KERNEL))) { usb_buffer_free(dev, 8, mouse->data, mouse->data_dma); kfree(mouse); - return NULL; + return -ENOMEM; } if (dev->descriptor.iManufacturer && @@ -187,20 +189,24 @@ mouse->irq->transfer_flags |= URB_NO_DMA_MAP; input_register_device(&mouse->dev); - printk(KERN_INFO "input: %s on %s\n", mouse->name, path); - return mouse; + intf->dev.driver_data = mouse; + return 0; } -static void usb_mouse_disconnect(struct usb_device *dev, void *ptr) +static void usb_mouse_disconnect(struct usb_interface * intf) { - struct usb_mouse *mouse = ptr; - usb_unlink_urb(mouse->irq); - input_unregister_device(&mouse->dev); - usb_free_urb(mouse->irq); - usb_buffer_free(dev, 8, mouse->data, mouse->data_dma); - kfree(mouse); + struct usb_mouse *mouse = intf->dev.driver_data; + intf->dev.driver_data = NULL; + + if (mouse) { + usb_unlink_urb(mouse->irq); + input_unregister_device(&mouse->dev); + usb_free_urb(mouse->irq); + usb_buffer_free(dev, 8, mouse->data, mouse->data_dma); + kfree(mouse); + } } static struct usb_device_id usb_mouse_id_table [] = { @@ -211,10 +217,10 @@ MODULE_DEVICE_TABLE (usb, usb_mouse_id_table); static struct usb_driver usb_mouse_driver = { - .name = "usb_mouse", - .probe = usb_mouse_probe, - .disconnect = usb_mouse_disconnect, - .id_table = usb_mouse_id_table, + .name = "usb_mouse", + .probe = usb_mouse_probe, + .disconnect = usb_mouse_disconnect, + .id_table = usb_mouse_id_table, }; static int __init usb_mouse_init(void) diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/input/wacom.c linux-2.5.34-greg/drivers/usb/input/wacom.c --- linux-2.5.34/drivers/usb/input/wacom.c Mon Sep 9 10:35:01 2002 +++ linux-2.5.34-greg/drivers/usb/input/wacom.c Wed Sep 11 15:33:33 2002 @@ -356,26 +356,28 @@ usb_unlink_urb(wacom->irq); } -static void *wacom_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id) +static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev (intf); struct usb_endpoint_descriptor *endpoint; struct wacom *wacom; char path[64]; - if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL))) return NULL; + if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL))) + return -ENOMEM; memset(wacom, 0, sizeof(struct wacom)); wacom->data = usb_buffer_alloc(dev, 10, SLAB_ATOMIC, &wacom->data_dma); if (!wacom->data) { kfree(wacom); - return NULL; + return -ENOMEM; } wacom->irq = usb_alloc_urb(0, GFP_KERNEL); if (!wacom->irq) { usb_buffer_free(dev, 10, wacom->data, wacom->data_dma); kfree(wacom); - return NULL; + return -ENOMEM; } wacom->features = wacom_features + id->driver_info; @@ -419,7 +421,7 @@ wacom->dev.id.version = dev->descriptor.bcdDevice; wacom->usbdev = dev; - endpoint = dev->config[0].interface[ifnum].altsetting[0].endpoint + 0; + endpoint = intf->altsetting[0].endpoint + 0; if (wacom->features->pktlen > 10) BUG(); @@ -435,17 +437,22 @@ printk(KERN_INFO "input: %s on %s\n", wacom->features->name, path); - return wacom; + dev_set_drvdata(&intf->dev, wacom); + return 0; } -static void wacom_disconnect(struct usb_device *dev, void *ptr) +static void wacom_disconnect(struct usb_interface *intf) { - struct wacom *wacom = ptr; - usb_unlink_urb(wacom->irq); - input_unregister_device(&wacom->dev); - usb_free_urb(wacom->irq); - usb_buffer_free(dev, 10, wacom->data, wacom->data_dma); - kfree(wacom); + struct wacom *wacom = dev_get_drvdata(&intf->dev); + + dev_set_drvdata(&intf->dev, NULL); + if (wacom) { + usb_unlink_urb(wacom->irq); + input_unregister_device(&wacom->dev); + usb_free_urb(wacom->irq); + usb_buffer_free(interface_to_usbdev(intf), 10, wacom->data, wacom->data_dma); + kfree(wacom); + } } static struct usb_driver wacom_driver = { diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/input/xpad.c linux-2.5.34-greg/drivers/usb/input/xpad.c --- linux-2.5.34/drivers/usb/input/xpad.c Mon Sep 9 10:35:11 2002 +++ linux-2.5.34-greg/drivers/usb/input/xpad.c Wed Sep 11 15:33:33 2002 @@ -195,8 +195,9 @@ usb_unlink_urb(xpad->irq_in); } -static void * xpad_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id) +static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_device *udev = interface_to_usbdev (intf); struct usb_xpad *xpad = NULL; struct usb_endpoint_descriptor *ep_irq_in; char path[64]; @@ -210,7 +211,7 @@ if ((xpad = kmalloc (sizeof(struct usb_xpad), GFP_KERNEL)) == NULL) { err("cannot allocate memory for new pad"); - return NULL; + return -ENOMEM; } memset(xpad, 0, sizeof(struct usb_xpad)); @@ -218,7 +219,7 @@ SLAB_ATOMIC, &xpad->idata_dma); if (!xpad->idata) { kfree(xpad); - return NULL; + return -ENOMEM; } xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); @@ -226,10 +227,10 @@ err("cannot allocate memory for new pad irq urb"); usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); kfree(xpad); - return NULL; + return -ENOMEM; } - ep_irq_in = udev->actconfig->interface[ifnum].altsetting[0].endpoint + 0; + ep_irq_in = intf->altsetting[0].endpoint + 0; usb_fill_int_urb(xpad->irq_in, udev, usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), @@ -291,18 +292,22 @@ printk(KERN_INFO "input: %s on %s", xpad->dev.name, path); - return xpad; + dev_set_drvdata(&intf->dev, xpad); + return 0; } -static void xpad_disconnect(struct usb_device *udev, void *ptr) +static void xpad_disconnect(struct usb_interface *intf) { - struct usb_xpad *xpad = ptr; + struct usb_xpad *xpad = dev_get_drvdata(&intf->dev); - usb_unlink_urb(xpad->irq_in); - input_unregister_device(&xpad->dev); - usb_free_urb(xpad->irq_in); - usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); - kfree(xpad); + dev_set_drvdata(&intf->dev, NULL); + if (xpad) { + usb_unlink_urb(xpad->irq_in); + input_unregister_device(&xpad->dev); + usb_free_urb(xpad->irq_in); + usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); + kfree(xpad); + } } static struct usb_driver xpad_driver = { diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/dabusb.c linux-2.5.34-greg/drivers/usb/media/dabusb.c --- linux-2.5.34/drivers/usb/media/dabusb.c Mon Sep 9 10:35:12 2002 +++ linux-2.5.34-greg/drivers/usb/media/dabusb.c Wed Sep 11 15:33:33 2002 @@ -713,9 +713,10 @@ }; /* --------------------------------------------------------------------- */ -static void *dabusb_probe (struct usb_device *usbdev, unsigned int ifnum, - const struct usb_device_id *id) +static int dabusb_probe (struct usb_interface *intf, + const struct usb_device_id *id) { + struct usb_device *usbdev = interface_to_usbdev(intf); int devnum; int retval; pdabusb_t s; @@ -725,14 +726,14 @@ /* We don't handle multiple configurations */ if (usbdev->descriptor.bNumConfigurations != 1) - return NULL; + return -ENODEV; - if (ifnum != _DABUSB_IF && usbdev->descriptor.idProduct == 0x9999) - return NULL; + if (intf->altsetting->bInterfaceNumber != _DABUSB_IF && usbdev->descriptor.idProduct == 0x9999) + return -ENODEV; retval = usb_register_dev (&dabusb_fops, DABUSB_MINOR, 1, &devnum); if (retval) - return NULL; + return -ENOMEM; s = &dabusb[devnum]; @@ -760,28 +761,32 @@ dbg("bound to interface: %d", ifnum); up (&s->mutex); MOD_INC_USE_COUNT; - return s; + dev_set_drvdata (&intf->dev, s); + return 0; reject: up (&s->mutex); s->usbdev = NULL; - return NULL; + return -ENODEV; } -static void dabusb_disconnect (struct usb_device *usbdev, void *ptr) +static void dabusb_disconnect (struct usb_interface *intf) { - pdabusb_t s = (pdabusb_t) ptr; + pdabusb_t s = dev_get_drvdata (&intf->dev); dbg("dabusb_disconnect"); - usb_deregister_dev (1, s->devnum); - s->remove_pending = 1; - wake_up (&s->wait); - if (s->state == _started) - sleep_on (&s->remove_ok); - s->usbdev = NULL; - s->overruns = 0; - MOD_DEC_USE_COUNT; + dev_set_drvdata (&intf->dev, NULL); + if (s) { + usb_deregister_dev (1, s->devnum); + s->remove_pending = 1; + wake_up (&s->wait); + if (s->state == _started) + sleep_on (&s->remove_ok); + s->usbdev = NULL; + s->overruns = 0; + MOD_DEC_USE_COUNT; + } } static struct usb_device_id dabusb_ids [] = { diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/dsbr100.c linux-2.5.34-greg/drivers/usb/media/dsbr100.c --- linux-2.5.34/drivers/usb/media/dsbr100.c Mon Sep 9 10:35:08 2002 +++ linux-2.5.34-greg/drivers/usb/media/dsbr100.c Wed Sep 11 15:33:33 2002 @@ -78,9 +78,9 @@ #define TB_LEN 16 -static void *usb_dsbr100_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id); -static void usb_dsbr100_disconnect(struct usb_device *dev, void *ptr); +static int usb_dsbr100_probe(struct usb_interface *intf, + const struct usb_device_id *id); +static void usb_dsbr100_disconnect(struct usb_interface *intf); static int usb_dsbr100_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); static int usb_dsbr100_open(struct inode *inode, struct file *file); @@ -95,7 +95,6 @@ unsigned char transfer_buffer[TB_LEN]; int curfreq; int stereo; - int ifnum; } usb_dsbr100; @@ -181,32 +180,36 @@ } -static void *usb_dsbr100_probe(struct usb_device *dev, unsigned int ifnum, +static int usb_dsbr100_probe(struct usb_interface *intf, const struct usb_device_id *id) { usb_dsbr100 *radio; if (!(radio = kmalloc(sizeof(usb_dsbr100),GFP_KERNEL))) - return NULL; + return -ENOMEM; usb_dsbr100_radio.priv = radio; - radio->dev = dev; - radio->ifnum = ifnum; + radio->dev = interface_to_usbdev (intf); radio->curfreq = 1454000; - return (void*)radio; + dev_set_drvdata (&intf->dev, radio); + return 0; } -static void usb_dsbr100_disconnect(struct usb_device *dev, void *ptr) +static void usb_dsbr100_disconnect(struct usb_interface *intf) { - usb_dsbr100 *radio=ptr; + usb_dsbr100 *radio = dev_get_drvdata (&intf->dev); - lock_kernel(); - if (users) { + dev_set_drvdata (&intf->dev, NULL); + + if (radio) { + lock_kernel(); + if (users) { + unlock_kernel(); + return; + } + kfree(radio); + usb_dsbr100_radio.priv = NULL; unlock_kernel(); - return; } - kfree(radio); - usb_dsbr100_radio.priv = NULL; - unlock_kernel(); } static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file, diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/ibmcam.c linux-2.5.34-greg/drivers/usb/media/ibmcam.c --- linux-2.5.34/drivers/usb/media/ibmcam.c Mon Sep 9 10:35:06 2002 +++ linux-2.5.34-greg/drivers/usb/media/ibmcam.c Wed Sep 11 15:33:33 2002 @@ -3656,39 +3656,41 @@ * 12-Nov-2000 Reworked to comply with new probe() signature. * 23-Jan-2001 Added compatibility with 2.2.x kernels. */ -static void *ibmcam_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *devid) +static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id *devid) { + struct usb_device *dev = interface_to_usbdev(intf); struct uvd *uvd = NULL; int i, nas, model=0, canvasX=0, canvasY=0; int actInterface=-1, inactInterface=-1, maxPS=0; + __u8 ifnum = intf->altsetting->bInterfaceNumber; unsigned char video_ep = 0; if (debug >= 1) - info("ibmcam_probe(%p,%u.)", dev, ifnum); + info("ibmcam_probe(%p,%u.)", intf, ifnum); /* We don't handle multi-config cameras */ if (dev->descriptor.bNumConfigurations != 1) - return NULL; + return -ENODEV; /* Is it an IBM camera? */ if (dev->descriptor.idVendor != IBMCAM_VENDOR_ID) - return NULL; + return -ENODEV; if ((dev->descriptor.idProduct != IBMCAM_PRODUCT_ID) && (dev->descriptor.idProduct != VEO_800C_PRODUCT_ID) && (dev->descriptor.idProduct != VEO_800D_PRODUCT_ID) && (dev->descriptor.idProduct != NETCAM_PRODUCT_ID)) - return NULL; + return -ENODEV; /* Check the version/revision */ switch (dev->descriptor.bcdDevice) { case 0x0002: if (ifnum != 2) - return NULL; + return -ENODEV; model = IBMCAM_MODEL_1; break; case 0x030A: if (ifnum != 0) - return NULL; + return -ENODEV; if ((dev->descriptor.idProduct == NETCAM_PRODUCT_ID) || (dev->descriptor.idProduct == VEO_800D_PRODUCT_ID)) model = IBMCAM_MODEL_4; @@ -3697,13 +3699,13 @@ break; case 0x0301: if (ifnum != 0) - return NULL; + return -ENODEV; model = IBMCAM_MODEL_3; break; default: err("IBM camera with revision 0x%04x is not supported.", dev->descriptor.bcdDevice); - return NULL; + return -ENODEV; } /* Print detailed info on what we found so far */ @@ -3734,7 +3736,7 @@ info("Number of alternate settings=%d.", nas); if (nas < 2) { err("Too few alternate settings for this camera!"); - return NULL; + return -ENODEV; } /* Validate all alternate settings */ for (i=0; i < nas; i++) { @@ -3745,29 +3747,29 @@ if (interface->bNumEndpoints != 1) { err("Interface %d. has %u. endpoints!", ifnum, (unsigned)(interface->bNumEndpoints)); - return NULL; + return -ENODEV; } endpoint = &interface->endpoint[0]; if (video_ep == 0) video_ep = endpoint->bEndpointAddress; else if (video_ep != endpoint->bEndpointAddress) { err("Alternate settings have different endpoint addresses!"); - return NULL; + return -ENODEV; } if ((endpoint->bmAttributes & 0x03) != 0x01) { err("Interface %d. has non-ISO endpoint!", ifnum); - return NULL; + return -ENODEV; } if ((endpoint->bEndpointAddress & 0x80) == 0) { err("Interface %d. has ISO OUT endpoint!", ifnum); - return NULL; + return -ENODEV; } if (endpoint->wMaxPacketSize == 0) { if (inactInterface < 0) inactInterface = i; else { err("More than one inactive alt. setting!"); - return NULL; + return -ENODEV; } } else { if (actInterface < 0) { @@ -3781,7 +3783,7 @@ } if ((maxPS <= 0) || (actInterface < 0) || (inactInterface < 0)) { err("Failed to recognize the camera!"); - return NULL; + return -ENODEV; } /* Validate options */ @@ -3861,7 +3863,7 @@ break; default: err("IBM camera: Model %d. not supported!", model); - return NULL; + return -ENODEV; } /* Code below may sleep, need to lock module while we are here */ @@ -3896,7 +3898,8 @@ } } MOD_DEC_USE_COUNT; - return uvd; + dev_set_drvdata (&intf->dev, uvd); + return 0; } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/konicawc.c linux-2.5.34-greg/drivers/usb/media/konicawc.c --- linux-2.5.34/drivers/usb/media/konicawc.c Mon Sep 9 10:34:59 2002 +++ linux-2.5.34-greg/drivers/usb/media/konicawc.c Wed Sep 11 15:33:33 2002 @@ -717,38 +717,40 @@ } -static void *konicawc_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *devid) +static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id *devid) { + struct usb_device *dev = interface_to_usbdev(intf); struct uvd *uvd = NULL; int i, nas; int actInterface=-1, inactInterface=-1, maxPS=0; unsigned char video_ep = 0; - DEBUG(1, "konicawc_probe(%p,%u.)", dev, ifnum); + DEBUG(1, "konicawc_probe(%p)", intf); /* We don't handle multi-config cameras */ if (dev->descriptor.bNumConfigurations != 1) - return NULL; + return -ENODEV; info("Konica Webcam (rev. 0x%04x)", dev->descriptor.bcdDevice); RESTRICT_TO_RANGE(speed, 0, MAX_SPEED); /* Validate found interface: must have one ISO endpoint */ - nas = dev->actconfig->interface[ifnum].num_altsetting; + nas = intf->num_altsetting; if (nas != 8) { err("Incorrect number of alternate settings (%d) for this camera!", nas); - return NULL; + return -ENODEV; } /* Validate all alternate settings */ for (i=0; i < nas; i++) { const struct usb_interface_descriptor *interface; const struct usb_endpoint_descriptor *endpoint; - interface = &dev->actconfig->interface[ifnum].altsetting[i]; + interface = &intf->altsetting[i]; if (interface->bNumEndpoints != 2) { err("Interface %d. has %u. endpoints!", - ifnum, (unsigned)(interface->bNumEndpoints)); - return NULL; + interface->bInterfaceNumber, + (unsigned)(interface->bNumEndpoints)); + return -ENODEV; } endpoint = &interface->endpoint[1]; DEBUG(1, "found endpoint: addr: 0x%2.2x maxps = 0x%4.4x", @@ -757,22 +759,24 @@ video_ep = endpoint->bEndpointAddress; else if (video_ep != endpoint->bEndpointAddress) { err("Alternate settings have different endpoint addresses!"); - return NULL; + return -ENODEV; } if ((endpoint->bmAttributes & 0x03) != 0x01) { - err("Interface %d. has non-ISO endpoint!", ifnum); - return NULL; + err("Interface %d. has non-ISO endpoint!", + interface->bInterfaceNumber); + return -ENODEV; } if ((endpoint->bEndpointAddress & 0x80) == 0) { - err("Interface %d. has ISO OUT endpoint!", ifnum); - return NULL; + err("Interface %d. has ISO OUT endpoint!", + interface->bInterfaceNumber); + return -ENODEV; } if (endpoint->wMaxPacketSize == 0) { if (inactInterface < 0) inactInterface = i; else { err("More than one inactive alt. setting!"); - return NULL; + return -ENODEV; } } else { if (i == spd_to_iface[speed]) { @@ -785,7 +789,7 @@ } if(actInterface == -1) { err("Cant find required endpoint"); - return NULL; + return -ENODEV; } DEBUG(1, "Selecting requested active setting=%d. maxPS=%d.", actInterface, maxPS); @@ -803,7 +807,7 @@ usb_free_urb(cam->sts_urb[i]); } err("cant allocate urbs"); - return NULL; + return -ENOMEM; } } cam->speed = speed; @@ -815,7 +819,7 @@ uvd->flags = 0; uvd->debug = debug; uvd->dev = dev; - uvd->iface = ifnum; + uvd->iface = intf->altsetting->bInterfaceNumber; uvd->ifaceAltInactive = inactInterface; uvd->ifaceAltActive = actInterface; uvd->video_endp = video_ep; @@ -854,7 +858,12 @@ #endif } MOD_DEC_USE_COUNT; - return uvd; + + if (uvd) { + dev_set_drvdata (&intf->dev, uvd); + return 0; + } + return -EIO; } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/ov511.c linux-2.5.34-greg/drivers/usb/media/ov511.c --- linux-2.5.34/drivers/usb/media/ov511.c Mon Sep 9 10:35:07 2002 +++ linux-2.5.34-greg/drivers/usb/media/ov511.c Wed Sep 11 15:33:33 2002 @@ -6043,10 +6043,11 @@ * ***************************************************************************/ -static void * -ov51x_probe(struct usb_device *dev, unsigned int ifnum, +static int +ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev(intf); struct usb_interface_descriptor *interface; struct usb_ov511 *ov; int i; @@ -6056,15 +6057,15 @@ /* We don't handle multi-config cameras */ if (dev->descriptor.bNumConfigurations != 1) - return NULL; + return -ENODEV; - interface = &dev->actconfig->interface[ifnum].altsetting[0]; + interface = &intf->altsetting[0]; /* Checking vendor/product should be enough, but what the hell */ if (interface->bInterfaceClass != 0xFF) - return NULL; + return -ENODEV; if (interface->bInterfaceSubClass != 0x00) - return NULL; + return -ENODEV; if ((ov = kmalloc(sizeof(*ov), GFP_KERNEL)) == NULL) { err("couldn't kmalloc ov struct"); @@ -6188,7 +6189,8 @@ create_proc_ov511_cam(ov); #endif - return ov; + dev_set_drvdata (&intf->dev, ov); + return 0; error: #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) @@ -6211,17 +6213,21 @@ error_out: err("Camera initialization failed"); - return NULL; + return -ENOMEM; } static void -ov51x_disconnect(struct usb_device *dev, void *ptr) +ov51x_disconnect(struct usb_interface *intf) { - struct usb_ov511 *ov = (struct usb_ov511 *) ptr; + struct usb_ov511 *ov = dev_get_drvdata (&intf->dev); int n; PDEBUG(3, ""); + dev_set_drvdata (&intf->dev, NULL); + if (!ov) + return; + video_unregister_device(&ov->vdev); if (ov->user) PDEBUG(3, "Device open...deferring video_unregister_device"); diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/pwc-if.c linux-2.5.34-greg/drivers/usb/media/pwc-if.c --- linux-2.5.34/drivers/usb/media/pwc-if.c Mon Sep 9 10:35:14 2002 +++ linux-2.5.34-greg/drivers/usb/media/pwc-if.c Wed Sep 11 15:33:33 2002 @@ -86,8 +86,8 @@ }; MODULE_DEVICE_TABLE(usb, pwc_device_table); -static void *usb_pwc_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id); -static void usb_pwc_disconnect(struct usb_device *udev, void *ptr); +static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id); +static void usb_pwc_disconnect(struct usb_interface *intf); static struct usb_driver pwc_driver = { @@ -1539,8 +1539,9 @@ * is loaded. */ -static void *usb_pwc_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id) +static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_device *udev = interface_to_usbdev(intf); struct pwc_device *pdev = NULL; struct video_device *vdev; int vendor_id, product_id, type_id; @@ -1551,14 +1552,14 @@ free_mem_leak(); /* Check if we can handle this device */ - Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n", udev->descriptor.idVendor, udev->descriptor.idProduct, ifnum); + Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n", udev->descriptor.idVendor, udev->descriptor.idProduct, intf->altsetting->bInterfaceNumber); /* the interfaces are probed one by one. We are only interested in the video interface (0) now. Interface 1 is the Audio Control, and interface 2 Audio itself. */ - if (ifnum > 0) - return NULL; + if (intf->altsetting->bInterfaceNumber > 0) + return -ENODEV; vendor_id = udev->descriptor.idVendor; product_id = udev->descriptor.idProduct; @@ -1602,7 +1603,7 @@ type_id = 750; break; default: - return NULL; + return -ENODEV; break; } } @@ -1613,7 +1614,7 @@ type_id = 645; break; default: - return NULL; + return -ENODEV; break; } } @@ -1624,7 +1625,7 @@ type_id = 730; break; default: - return NULL; + return -ENODEV; break; } } @@ -1643,7 +1644,7 @@ type_id = 675; break; default: - return NULL; + return -ENODEV; break; } } @@ -1654,7 +1655,7 @@ type_id = 730; break; default: - return NULL; + return -ENODEV; break; } } @@ -1665,11 +1666,11 @@ type_id = 730; break; default: - return NULL; + return -ENODEV; break; } } - else return NULL; /* Not Philips, Askey, Logitech, Samsung, Creative or SOTEC, for sure. */ + else return -ENODEV; /* Not Philips, Askey, Logitech, Samsung, Creative or SOTEC, for sure. */ memset(serial_number, 0, 30); usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29); @@ -1682,7 +1683,7 @@ pdev = kmalloc(sizeof(struct pwc_device), GFP_KERNEL); if (pdev == NULL) { Err("Oops, could not allocate memory for pwc_device.\n"); - return NULL; + return -ENOMEM; } memset(pdev, 0, sizeof(struct pwc_device)); pdev->type = type_id; @@ -1700,7 +1701,7 @@ vdev = kmalloc(sizeof(struct video_device), GFP_KERNEL); if (vdev == NULL) { Err("Oops, could not allocate memory for video_device.\n"); - return NULL; + return -ENOMEM; } memcpy(vdev, &pwc_template, sizeof(pwc_template)); sprintf(vdev->name, "Philips %d webcam", pdev->type); @@ -1729,7 +1730,7 @@ i = video_register_device(vdev, VFL_TYPE_GRABBER, video_nr); if (i < 0) { Err("Failed to register as video device (%d).\n", i); - return NULL; + return -EIO; } else { Trace(TRACE_PROBE, "Registered video struct at 0x%p.\n", vdev); @@ -1740,11 +1741,12 @@ device_hint[hint].pdev = pdev; Trace(TRACE_PROBE, "probe() function returning struct at 0x%p.\n", pdev); - return pdev; + dev_set_drvdata (&intf->dev, pdev); + return 0; } /* The user janked out the cable... */ -static void usb_pwc_disconnect(struct usb_device *udev, void *ptr) +static void usb_pwc_disconnect(struct usb_interface *intf) { struct pwc_device *pdev; int hint; @@ -1753,7 +1755,8 @@ lock_kernel(); free_mem_leak(); - pdev = (struct pwc_device *)ptr; + pdev = dev_get_drvdata (&intf->dev); + dev_set_drvdata (&intf->dev, NULL); if (pdev == NULL) { Err("pwc_disconnect() Called without private pointer.\n"); goto out_err; @@ -1762,7 +1765,7 @@ Err("pwc_disconnect() already called for %p\n", pdev); goto out_err; } - if (pdev->udev != udev) { + if (pdev->udev != interface_to_usbdev(intf)) { Err("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n"); goto out_err; } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/stv680.c linux-2.5.34-greg/drivers/usb/media/stv680.c --- linux-2.5.34/drivers/usb/media/stv680.c Mon Sep 9 10:35:14 2002 +++ linux-2.5.34-greg/drivers/usb/media/stv680.c Wed Sep 11 15:33:33 2002 @@ -1448,8 +1448,9 @@ .fops = &stv680_fops, }; -static void *stv680_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id) +static int stv680_probe (struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev(intf); struct usb_interface_descriptor *interface; struct usb_stv *stv680; char *camera_name = NULL; @@ -1457,10 +1458,10 @@ /* We don't handle multi-config cameras */ if (dev->descriptor.bNumConfigurations != 1) { PDEBUG (0, "STV(e): Number of Configurations != 1"); - return NULL; + return -ENODEV; } - interface = &dev->actconfig->interface[ifnum].altsetting[0]; + interface = &intf->altsetting[0]; /* Is it a STV680? */ if ((dev->descriptor.idVendor == USB_PENCAM_VENDOR_ID) && (dev->descriptor.idProduct == USB_PENCAM_PRODUCT_ID)) { camera_name = "STV0680"; @@ -1468,12 +1469,12 @@ } else { PDEBUG (0, "STV(e): Vendor/Product ID do not match STV0680 values."); PDEBUG (0, "STV(e): Check that the STV0680 camera is connected to the computer."); - return NULL; + return -ENODEV; } /* We found one */ if ((stv680 = kmalloc (sizeof (*stv680), GFP_KERNEL)) == NULL) { PDEBUG (0, "STV(e): couldn't kmalloc stv680 struct."); - return NULL; + return -ENOMEM; } memset (stv680, 0, sizeof (*stv680)); @@ -1490,14 +1491,15 @@ if (video_register_device (&stv680->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { kfree (stv680); PDEBUG (0, "STV(e): video_register_device failed"); - return NULL; + return -EIO; } #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) create_proc_stv680_cam (stv680); #endif PDEBUG (0, "STV(i): registered new video device: video%d", stv680->vdev.minor); - return stv680; + dev_set_drvdata (&intf->dev, stv680); + return 0; } static inline void usb_stv680_remove_disconnected (struct usb_stv *stv680) @@ -1531,16 +1533,20 @@ kfree (stv680); } -static void stv680_disconnect (struct usb_device *dev, void *ptr) +static void stv680_disconnect (struct usb_interface *intf) { - struct usb_stv *stv680 = (struct usb_stv *) ptr; + struct usb_stv *stv680 = dev_get_drvdata (&intf->dev); - /* We don't want people trying to open up the device */ - video_unregister_device (&stv680->vdev); - if (!stv680->user) { - usb_stv680_remove_disconnected (stv680); - } else { - stv680->removed = 1; + dev_set_drvdata (&intf->dev, NULL); + + if (stv680) { + /* We don't want people trying to open up the device */ + video_unregister_device (&stv680->vdev); + if (!stv680->user) { + usb_stv680_remove_disconnected (stv680); + } else { + stv680->removed = 1; + } } } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/ultracam.c linux-2.5.34-greg/drivers/usb/media/ultracam.c --- linux-2.5.34/drivers/usb/media/ultracam.c Mon Sep 9 10:35:04 2002 +++ linux-2.5.34-greg/drivers/usb/media/ultracam.c Wed Sep 11 15:33:33 2002 @@ -537,67 +537,71 @@ * 12-Nov-2000 Reworked to comply with new probe() signature. * 23-Jan-2001 Added compatibility with 2.2.x kernels. */ -static void *ultracam_probe(struct usb_device *dev, unsigned int ifnum ,const struct usb_device_id *devid) +static int ultracam_probe(struct usb_interface *intf, const struct usb_device_id *devid) { + struct usb_device *dev = interface_to_usbdev(intf); struct uvd *uvd = NULL; int i, nas; int actInterface=-1, inactInterface=-1, maxPS=0; unsigned char video_ep = 0; if (debug >= 1) - info("ultracam_probe(%p,%u.)", dev, ifnum); + info("ultracam_probe(%p)", intf); /* We don't handle multi-config cameras */ if (dev->descriptor.bNumConfigurations != 1) - return NULL; + return -ENODEV; /* Is it an IBM camera? */ if ((dev->descriptor.idVendor != ULTRACAM_VENDOR_ID) || (dev->descriptor.idProduct != ULTRACAM_PRODUCT_ID)) - return NULL; + return -ENODEV; info("IBM Ultra camera found (rev. 0x%04x)", dev->descriptor.bcdDevice); /* Validate found interface: must have one ISO endpoint */ - nas = dev->actconfig->interface[ifnum].num_altsetting; + nas = intf->num_altsetting; if (debug > 0) info("Number of alternate settings=%d.", nas); if (nas < 8) { err("Too few alternate settings for this camera!"); - return NULL; + return -ENODEV; } /* Validate all alternate settings */ for (i=0; i < nas; i++) { const struct usb_interface_descriptor *interface; const struct usb_endpoint_descriptor *endpoint; - interface = &dev->actconfig->interface[ifnum].altsetting[i]; + interface = &intf->altsetting[i]; if (interface->bNumEndpoints != 1) { err("Interface %d. has %u. endpoints!", - ifnum, (unsigned)(interface->bNumEndpoints)); - return NULL; + interface->bInterfaceNumber, + (unsigned)(interface->bNumEndpoints)); + return -ENODEV; } endpoint = &interface->endpoint[0]; if (video_ep == 0) video_ep = endpoint->bEndpointAddress; else if (video_ep != endpoint->bEndpointAddress) { err("Alternate settings have different endpoint addresses!"); - return NULL; + return -ENODEV; } if ((endpoint->bmAttributes & 0x03) != 0x01) { - err("Interface %d. has non-ISO endpoint!", ifnum); - return NULL; + err("Interface %d. has non-ISO endpoint!", + interface->bInterfaceNumber); + return -ENODEV; } if ((endpoint->bEndpointAddress & 0x80) == 0) { - err("Interface %d. has ISO OUT endpoint!", ifnum); - return NULL; + err("Interface %d. has ISO OUT endpoint!", + interface->bInterfaceNumber); + return -ENODEV; } if (endpoint->wMaxPacketSize == 0) { if (inactInterface < 0) inactInterface = i; else { err("More than one inactive alt. setting!"); - return NULL; + return -ENODEV; } } else { if (actInterface < 0) { @@ -621,7 +625,7 @@ } if ((maxPS <= 0) || (actInterface < 0) || (inactInterface < 0)) { err("Failed to recognize the camera!"); - return NULL; + return -ENODEV; } /* Code below may sleep, need to lock module while we are here */ @@ -632,7 +636,7 @@ uvd->flags = flags; uvd->debug = debug; uvd->dev = dev; - uvd->iface = ifnum; + uvd->iface = intf->altsetting->bInterfaceNumber; uvd->ifaceAltInactive = inactInterface; uvd->ifaceAltActive = actInterface; uvd->video_endp = video_ep; @@ -656,7 +660,12 @@ } } MOD_DEC_USE_COUNT; - return uvd; + + if (uvd) { + dev_set_drvdata (&intf->dev, uvd); + return 0; + } + return -EIO; } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/usbvideo.c linux-2.5.34-greg/drivers/usb/media/usbvideo.c --- linux-2.5.34/drivers/usb/media/usbvideo.c Mon Sep 9 10:35:37 2002 +++ linux-2.5.34-greg/drivers/usb/media/usbvideo.c Wed Sep 11 15:33:33 2002 @@ -54,7 +54,7 @@ unsigned long count, void *data); #endif -static void usbvideo_Disconnect(struct usb_device *dev, void *ptr); +static void usbvideo_Disconnect(struct usb_interface *intf); static void usbvideo_CameraRelease(struct uvd *uvd); static int usbvideo_v4l_ioctl(struct inode *inode, struct file *file, @@ -966,18 +966,21 @@ * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT). * 19-Oct-2000 Moved to usbvideo module. */ -static void usbvideo_Disconnect(struct usb_device *dev, void *ptr) +static void usbvideo_Disconnect(struct usb_interface *intf) { - struct uvd *uvd = (struct uvd *) ptr; + struct uvd *uvd = dev_get_drvdata (&intf->dev); int i; - if ((dev == NULL) || (uvd == NULL)) { - err("%s($%p,$%p): Illegal call.", __FUNCTION__, dev, ptr); + if (uvd == NULL) { + err("%s($%p): Illegal call.", __FUNCTION__, intf); return; } + + dev_set_drvdata (&intf->dev, NULL); + usbvideo_ClientIncModCount(uvd); if (uvd->debug > 0) - info("%s(%p,%p.)", __FUNCTION__, dev, ptr); + info("%s(%p.)", __FUNCTION__, intf); down(&uvd->lock); uvd->remove_pending = 1; /* Now all ISO data will be ignored */ diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/usbvideo.h linux-2.5.34-greg/drivers/usb/media/usbvideo.h --- linux-2.5.34/drivers/usb/media/usbvideo.h Mon Sep 9 10:35:09 2002 +++ linux-2.5.34-greg/drivers/usb/media/usbvideo.h Wed Sep 11 15:33:33 2002 @@ -254,9 +254,9 @@ * that default to usbvideo-provided methods. */ struct usbvideo_cb { - void *(*probe)(struct usb_device *, unsigned int,const struct usb_device_id *); + int (*probe)(struct usb_interface *, const struct usb_device_id *); void (*userFree)(struct uvd *); - void (*disconnect)(struct usb_device *, void *); + void (*disconnect)(struct usb_interface *); int (*setupOnOpen)(struct uvd *); void (*videoStart)(struct uvd *); void (*videoStop)(struct uvd *); diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/media/vicam.c linux-2.5.34-greg/drivers/usb/media/vicam.c --- linux-2.5.34/drivers/usb/media/vicam.c Mon Sep 9 10:35:07 2002 +++ linux-2.5.34-greg/drivers/usb/media/vicam.c Wed Sep 11 15:33:33 2002 @@ -787,9 +787,10 @@ return 1; } -static void *vicam_probe(struct usb_device *udev, unsigned int ifnum, +static int vicam_probe(struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_device *udev = interface_to_usbdev(intf); struct usb_vicam *vicam; char *camera_name=NULL; @@ -798,7 +799,7 @@ /* See if the device offered us matches what we can accept */ if ((udev->descriptor.idVendor != USB_VICAM_VENDOR_ID) || (udev->descriptor.idProduct != USB_VICAM_PRODUCT_ID)) { - return NULL; + return -ENODEV; } camera_name="3Com HomeConnect USB"; @@ -807,14 +808,14 @@ vicam = kmalloc (sizeof(struct usb_vicam), GFP_KERNEL); if (vicam == NULL) { err ("couldn't kmalloc vicam struct"); - return NULL; + return -ENOMEM; } memset(vicam, 0, sizeof(*vicam)); vicam->readurb = usb_alloc_urb(0, GFP_KERNEL); if (!vicam->readurb) { kfree(vicam); - return NULL; + return -ENOMEM; } vicam->udev = udev; @@ -826,7 +827,7 @@ if (vicam_init(vicam)) { usb_free_urb(vicam->readurb); kfree(vicam); - return NULL; + return -ENOMEM; } memcpy(&vicam->vdev, &vicam_template, sizeof(vicam_template)); memcpy(vicam->vdev.name, vicam->camera_name, strlen(vicam->camera_name)); @@ -835,7 +836,7 @@ err("video_register_device"); usb_free_urb(vicam->readurb); kfree(vicam); - return NULL; + return -EIO; } info("registered new video device: video%d", vicam->vdev.minor); @@ -843,34 +844,38 @@ init_MUTEX (&vicam->sem); init_waitqueue_head(&vicam->wait); - return vicam; + dev_set_drvdata (&intf->dev, vicam); + return 0; } /* FIXME - vicam_disconnect - important */ -static void vicam_disconnect(struct usb_device *udev, void *ptr) +static void vicam_disconnect(struct usb_interface *intf) { struct usb_vicam *vicam; - vicam = (struct usb_vicam *) ptr; + vicam = dev_get_drvdata (&intf->dev); - video_unregister_device(&vicam->vdev); - vicam->udev = NULL; + dev_set_drvdata (&intf->dev, NULL); + + if (vicam) { + video_unregister_device(&vicam->vdev); + vicam->udev = NULL; /* - vicam->frame[0].grabstate = FRAME_ERROR; - vicam->frame[1].grabstate = FRAME_ERROR; + vicam->frame[0].grabstate = FRAME_ERROR; + vicam->frame[1].grabstate = FRAME_ERROR; */ - /* Free buffers and shit */ - - info("%s disconnected", vicam->camera_name); - synchronize(vicam); - - if (!vicam->open_count) { - /* Other random junk */ - usb_free_urb(vicam->readurb); - kfree(vicam); - vicam = NULL; + /* Free buffers and shit */ + info("%s disconnected", vicam->camera_name); + synchronize(vicam); + + if (!vicam->open_count) { + /* Other random junk */ + usb_free_urb(vicam->readurb); + kfree(vicam); + vicam = NULL; + } } } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/net/usbnet.c linux-2.5.34-greg/drivers/usb/net/usbnet.c --- linux-2.5.34/drivers/usb/net/usbnet.c Mon Sep 9 10:34:59 2002 +++ linux-2.5.34-greg/drivers/usb/net/usbnet.c Wed Sep 11 15:33:33 2002 @@ -1921,12 +1921,16 @@ // precondition: never called in_interrupt -static void usbnet_disconnect (struct usb_device *udev, void *ptr) +static void usbnet_disconnect (struct usb_interface *udev) { - struct usbnet *dev = (struct usbnet *) ptr; + struct usbnet *dev; + struct usb_device *xdev; + + dev = (struct usbnet *) udev->dev.driver_data; + xdev = interface_to_usbdev (udev); devinfo (dev, "unregister usbnet usb-%s-%s, %s", - udev->bus->bus_name, udev->devpath, + xdev->bus->bus_name, xdev->devpath, dev->driver_info->description); unregister_netdev (&dev->net); @@ -1940,7 +1944,7 @@ flush_scheduled_tasks (); kfree (dev); - usb_put_dev (udev); + usb_put_dev (xdev); } @@ -1948,46 +1952,38 @@ // precondition: never called in_interrupt -static void * -usbnet_probe (struct usb_device *udev, unsigned ifnum, - const struct usb_device_id *prod) +int +usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) { struct usbnet *dev; struct net_device *net; struct usb_interface_descriptor *interface; struct driver_info *info; - int altnum = 0; + struct usb_device *xdev; info = (struct driver_info *) prod->driver_info; - // sanity check; expect dedicated interface/devices for now. - interface = &udev->actconfig->interface [ifnum].altsetting [altnum]; - if (udev->descriptor.bNumConfigurations != 1 - || udev->config[0].bNumInterfaces != 1 -// || interface->bInterfaceClass != USB_CLASS_VENDOR_SPEC - ) { - dbg ("Bogus config info"); - return 0; - } + xdev = interface_to_usbdev (udev); + interface = &udev->altsetting [udev->act_altsetting]; - // more sanity (unless the device is broken) if (!(info->flags & FLAG_NO_SETINT)) { - if (usb_set_interface (udev, ifnum, altnum) < 0) { + if (usb_set_interface (xdev, interface->bInterfaceNumber, + interface->bAlternateSetting) < 0) { err ("set_interface failed"); - return 0; + return -EIO; } } // set up our own records if (!(dev = kmalloc (sizeof *dev, GFP_KERNEL))) { dbg ("can't kmalloc dev"); - return 0; + return -ENOMEM; } memset (dev, 0, sizeof *dev); init_MUTEX_LOCKED (&dev->mutex); - usb_get_dev (udev); - dev->udev = udev; + usb_get_dev (xdev); + dev->udev = xdev; dev->driver_info = info; dev->msg_level = msg_level; INIT_LIST_HEAD (&dev->dev_list); @@ -2020,10 +2016,11 @@ register_netdev (&dev->net); devinfo (dev, "register usbnet usb-%s-%s, %s", - udev->bus->bus_name, udev->devpath, + xdev->bus->bus_name, xdev->devpath, dev->driver_info->description); // ok, it's ready to go. + udev->dev.driver_data = net; mutex_lock (&usbnet_mutex); list_add (&dev->dev_list, &usbnet_list); mutex_unlock (&dev->mutex); @@ -2032,7 +2029,7 @@ netif_device_attach (&dev->net); mutex_unlock (&usbnet_mutex); - return dev; + return 0; } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/belkin_sa.c linux-2.5.34-greg/drivers/usb/serial/belkin_sa.c --- linux-2.5.34/drivers/usb/serial/belkin_sa.c Mon Sep 9 10:35:13 2002 +++ linux-2.5.34-greg/drivers/usb/serial/belkin_sa.c Wed Sep 11 15:33:33 2002 @@ -114,6 +114,13 @@ MODULE_DEVICE_TABLE (usb, id_table_combined); +static struct usb_driver belkin_driver = { + .name = "belkin", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table_combined, +}; + /* All of the device info needed for the serial converters */ static struct usb_serial_device_type belkin_device = { .owner = THIS_MODULE, @@ -526,6 +533,7 @@ static int __init belkin_sa_init (void) { usb_serial_register (&belkin_device); + usb_register (&belkin_driver); info(DRIVER_DESC " " DRIVER_VERSION); return 0; } @@ -533,6 +541,7 @@ static void __exit belkin_sa_exit (void) { + usb_deregister (&belkin_driver); usb_serial_deregister (&belkin_device); } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/cyberjack.c linux-2.5.34-greg/drivers/usb/serial/cyberjack.c --- linux-2.5.34/drivers/usb/serial/cyberjack.c Mon Sep 9 10:35:15 2002 +++ linux-2.5.34-greg/drivers/usb/serial/cyberjack.c Wed Sep 11 15:33:33 2002 @@ -73,6 +73,13 @@ MODULE_DEVICE_TABLE (usb, id_table); +static struct usb_driver cyberjack_driver = { + .name = "cyberjack", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table, +}; + static struct usb_serial_device_type cyberjack_device = { .owner = THIS_MODULE, .name = "Reiner SCT Cyberjack USB card reader", @@ -461,6 +468,7 @@ static int __init cyberjack_init (void) { usb_serial_register (&cyberjack_device); + usb_register (&cyberjack_driver); info(DRIVER_VERSION " " DRIVER_AUTHOR); info(DRIVER_DESC); @@ -470,6 +478,7 @@ static void __exit cyberjack_exit (void) { + usb_deregister (&cyberjack_driver); usb_serial_deregister (&cyberjack_device); } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/digi_acceleport.c linux-2.5.34-greg/drivers/usb/serial/digi_acceleport.c --- linux-2.5.34/drivers/usb/serial/digi_acceleport.c Mon Sep 9 10:35:11 2002 +++ linux-2.5.34-greg/drivers/usb/serial/digi_acceleport.c Wed Sep 11 15:33:33 2002 @@ -477,7 +477,7 @@ /* Statics */ -static __devinitdata struct usb_device_id id_table_combined [] = { +static struct usb_device_id id_table_combined [] = { { USB_DEVICE(DIGI_VENDOR_ID, DIGI_2_ID) }, { USB_DEVICE(DIGI_VENDOR_ID, DIGI_4_ID) }, { } /* Terminating entry */ @@ -495,6 +495,14 @@ MODULE_DEVICE_TABLE (usb, id_table_combined); +static struct usb_driver digi_driver = { + .name = "digi_acceleport", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table_combined, +}; + + /* device info needed for the Digi serial converter */ static struct usb_serial_device_type digi_acceleport_2_device = { @@ -2025,6 +2033,7 @@ { usb_serial_register (&digi_acceleport_2_device); usb_serial_register (&digi_acceleport_4_device); + usb_register (&digi_driver); info(DRIVER_VERSION ":" DRIVER_DESC); return 0; } @@ -2032,6 +2041,7 @@ static void __exit digi_exit (void) { + usb_deregister (&digi_driver); usb_serial_deregister (&digi_acceleport_2_device); usb_serial_deregister (&digi_acceleport_4_device); } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/empeg.c linux-2.5.34-greg/drivers/usb/serial/empeg.c --- linux-2.5.34/drivers/usb/serial/empeg.c Mon Sep 9 10:35:11 2002 +++ linux-2.5.34-greg/drivers/usb/serial/empeg.c Wed Sep 11 15:33:33 2002 @@ -110,6 +110,13 @@ MODULE_DEVICE_TABLE (usb, id_table); +static struct usb_driver empeg_driver = { + .name = "empeg", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table, +}; + static struct usb_serial_device_type empeg_device = { .owner = THIS_MODULE, .name = "Empeg", @@ -550,8 +557,6 @@ struct urb *urb; int i; - usb_serial_register (&empeg_device); - /* create our write urb pool and transfer buffers */ spin_lock_init (&write_urb_pool_lock); for (i = 0; i < NUM_URBS; ++i) { @@ -571,10 +576,12 @@ } } + usb_serial_register (&empeg_device); + usb_register (&empeg_driver); + info(DRIVER_VERSION ":" DRIVER_DESC); return 0; - } @@ -583,6 +590,7 @@ int i; unsigned long flags; + usb_register (&empeg_driver); usb_serial_deregister (&empeg_device); spin_lock_irqsave (&write_urb_pool_lock, flags); @@ -600,7 +608,6 @@ } spin_unlock_irqrestore (&write_urb_pool_lock, flags); - } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/ftdi_sio.c linux-2.5.34-greg/drivers/usb/serial/ftdi_sio.c --- linux-2.5.34/drivers/usb/serial/ftdi_sio.c Mon Sep 9 10:35:05 2002 +++ linux-2.5.34-greg/drivers/usb/serial/ftdi_sio.c Wed Sep 11 15:33:33 2002 @@ -140,7 +140,7 @@ }; -static __devinitdata struct usb_device_id id_table_combined [] = { +static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) }, @@ -149,6 +149,13 @@ MODULE_DEVICE_TABLE (usb, id_table_combined); +static struct usb_driver ftdi_driver = { + .name = "ftdi_sio", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table_combined, +}; + struct ftdi_private { enum ftdi_type ftdi_type; @@ -944,6 +951,7 @@ dbg("%s", __FUNCTION__); usb_serial_register (&ftdi_sio_device); usb_serial_register (&ftdi_8U232AM_device); + usb_register (&ftdi_driver); info(DRIVER_VERSION ":" DRIVER_DESC); return 0; } @@ -952,6 +960,7 @@ static void __exit ftdi_sio_exit (void) { dbg("%s", __FUNCTION__); + usb_deregister (&ftdi_driver); usb_serial_deregister (&ftdi_sio_device); usb_serial_deregister (&ftdi_8U232AM_device); } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/io_edgeport.c linux-2.5.34-greg/drivers/usb/serial/io_edgeport.c --- linux-2.5.34/drivers/usb/serial/io_edgeport.c Mon Sep 9 10:35:01 2002 +++ linux-2.5.34-greg/drivers/usb/serial/io_edgeport.c Wed Sep 11 15:33:33 2002 @@ -457,6 +457,12 @@ #include "io_tables.h" /* all of the devices that this driver supports */ +static struct usb_driver io_driver = { + .name = "io_edgeport", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table_combined, +}; /* function prototypes for all of our local functions */ static int process_rcvd_data (struct edgeport_serial *edge_serial, unsigned char *buffer, __u16 bufferLength); @@ -3050,6 +3056,7 @@ usb_serial_register (&edgeport_2port_device); usb_serial_register (&edgeport_4port_device); usb_serial_register (&edgeport_8port_device); + usb_register (&io_driver); info(DRIVER_DESC " " DRIVER_VERSION); return 0; } @@ -3062,6 +3069,7 @@ ****************************************************************************/ void __exit edgeport_exit (void) { + usb_deregister (&io_driver); usb_serial_deregister (&edgeport_1port_device); usb_serial_deregister (&edgeport_2port_device); usb_serial_deregister (&edgeport_4port_device); diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/io_tables.h linux-2.5.34-greg/drivers/usb/serial/io_tables.h --- linux-2.5.34/drivers/usb/serial/io_tables.h Mon Sep 9 10:35:02 2002 +++ linux-2.5.34-greg/drivers/usb/serial/io_tables.h Wed Sep 11 15:33:33 2002 @@ -61,7 +61,7 @@ }; /* Devices that this driver supports */ -static __devinitdata struct usb_device_id id_table_combined [] = { +static struct usb_device_id id_table_combined [] = { { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4) }, { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_RAPIDPORT_4) }, { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4T) }, diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/io_ti.c linux-2.5.34-greg/drivers/usb/serial/io_ti.c --- linux-2.5.34/drivers/usb/serial/io_ti.c Mon Sep 9 10:35:09 2002 +++ linux-2.5.34-greg/drivers/usb/serial/io_ti.c Wed Sep 11 15:33:33 2002 @@ -142,7 +142,7 @@ }; /* Devices that this driver supports */ -static __devinitdata struct usb_device_id id_table_combined [] = { +static struct usb_device_id id_table_combined [] = { { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_1) }, { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2) }, { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2I) }, @@ -161,6 +161,13 @@ MODULE_DEVICE_TABLE (usb, id_table_combined); +static struct usb_driver io_driver = { + .name = "io_ti", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table_combined, +}; + static struct EDGE_FIRMWARE_VERSION_INFO OperationalCodeImageVersion; @@ -2658,12 +2665,14 @@ { usb_serial_register (&edgeport_1port_device); usb_serial_register (&edgeport_2port_device); + usb_register (&io_driver); info(DRIVER_DESC " " DRIVER_VERSION); return 0; } static void __exit edgeport_exit (void) { + usb_deregister (&io_driver); usb_serial_deregister (&edgeport_1port_device); usb_serial_deregister (&edgeport_2port_device); } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/ipaq.c linux-2.5.34-greg/drivers/usb/serial/ipaq.c --- linux-2.5.34/drivers/usb/serial/ipaq.c Mon Sep 9 10:35:06 2002 +++ linux-2.5.34-greg/drivers/usb/serial/ipaq.c Wed Sep 11 15:33:33 2002 @@ -94,6 +94,14 @@ MODULE_DEVICE_TABLE (usb, ipaq_id_table); +static struct usb_driver ipaq_driver = { + .name = "ipaq", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = ipaq_id_table, +}; + + /* All of the device info needed for the Compaq iPAQ */ struct usb_serial_device_type ipaq_device = { .owner = THIS_MODULE, @@ -516,6 +524,7 @@ static int __init ipaq_init(void) { usb_serial_register(&ipaq_device); + usb_register(&ipaq_driver); info(DRIVER_DESC " " DRIVER_VERSION); return 0; @@ -524,6 +533,7 @@ static void __exit ipaq_exit(void) { + usb_deregister(&ipaq_driver); usb_serial_deregister(&ipaq_device); } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/ir-usb.c linux-2.5.34-greg/drivers/usb/serial/ir-usb.c --- linux-2.5.34/drivers/usb/serial/ir-usb.c Mon Sep 9 10:35:11 2002 +++ linux-2.5.34-greg/drivers/usb/serial/ir-usb.c Wed Sep 11 15:33:33 2002 @@ -129,6 +129,13 @@ MODULE_DEVICE_TABLE (usb, id_table); +static struct usb_driver ir_driver = { + .name = "ir-usb", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table, +}; + struct usb_serial_device_type ir_device = { .owner = THIS_MODULE, @@ -606,6 +613,7 @@ static int __init ir_init (void) { usb_serial_register (&ir_device); + usb_register (&ir_driver); info(DRIVER_DESC " " DRIVER_VERSION); return 0; } @@ -613,6 +621,7 @@ static void __exit ir_exit (void) { + usb_deregister (&ir_driver); usb_serial_deregister (&ir_device); } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/keyspan.c linux-2.5.34-greg/drivers/usb/serial/keyspan.c --- linux-2.5.34/drivers/usb/serial/keyspan.c Mon Sep 9 10:35:02 2002 +++ linux-2.5.34-greg/drivers/usb/serial/keyspan.c Wed Sep 11 15:33:33 2002 @@ -183,6 +183,7 @@ usb_serial_register (&keyspan_1port_device); usb_serial_register (&keyspan_2port_device); usb_serial_register (&keyspan_4port_device); + usb_register (&keyspan_driver); info(DRIVER_VERSION ":" DRIVER_DESC); @@ -191,6 +192,7 @@ static void __exit keyspan_exit (void) { + usb_deregister (&keyspan_driver); usb_serial_deregister (&keyspan_pre_device); usb_serial_deregister (&keyspan_1port_device); usb_serial_deregister (&keyspan_2port_device); diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/keyspan.h linux-2.5.34-greg/drivers/usb/serial/keyspan.h --- linux-2.5.34/drivers/usb/serial/keyspan.h Mon Sep 9 10:35:14 2002 +++ linux-2.5.34-greg/drivers/usb/serial/keyspan.h Wed Sep 11 15:33:33 2002 @@ -408,7 +408,7 @@ NULL, }; -static __devinitdata struct usb_device_id keyspan_ids_combined[] = { +static struct usb_device_id keyspan_ids_combined[] = { { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_pre_product_id) }, { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_pre_product_id) }, { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_pre_product_id) }, @@ -434,6 +434,13 @@ MODULE_DEVICE_TABLE(usb, keyspan_ids_combined); +static struct usb_driver keyspan_driver = { + .name = "keyspan", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = keyspan_ids_combined, +}; + /* usb_device_id table for the pre-firmware download keyspan devices */ static struct usb_device_id keyspan_pre_ids[] = { { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_pre_product_id) }, diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/keyspan_pda.c linux-2.5.34-greg/drivers/usb/serial/keyspan_pda.c --- linux-2.5.34/drivers/usb/serial/keyspan_pda.c Mon Sep 9 10:35:13 2002 +++ linux-2.5.34-greg/drivers/usb/serial/keyspan_pda.c Wed Sep 11 15:33:33 2002 @@ -140,7 +140,7 @@ #define ENTREGRA_VENDOR_ID 0x1645 #define ENTREGRA_FAKE_ID 0x8093 -static __devinitdata struct usb_device_id id_table_combined [] = { +static struct usb_device_id id_table_combined [] = { #ifdef KEYSPAN { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) }, #endif @@ -154,6 +154,13 @@ MODULE_DEVICE_TABLE (usb, id_table_combined); +static struct usb_driver keyspan_pda_driver = { + .name = "keyspan_pda", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table_combined, +}; + static struct usb_device_id id_table_std [] = { { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_ID) }, { } /* Terminating entry */ @@ -862,6 +869,7 @@ #ifdef XIRCOM usb_serial_register (&xircom_pgs_fake_device); #endif + usb_register (&keyspan_pda_driver); info(DRIVER_DESC " " DRIVER_VERSION); return 0; } @@ -869,6 +877,7 @@ static void __exit keyspan_pda_exit (void) { + usb_deregister (&keyspan_pda_driver); usb_serial_deregister (&keyspan_pda_device); #ifdef KEYSPAN usb_serial_deregister (&keyspan_pda_fake_device); diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/kl5kusb105.c linux-2.5.34-greg/drivers/usb/serial/kl5kusb105.c --- linux-2.5.34/drivers/usb/serial/kl5kusb105.c Mon Sep 9 10:35:12 2002 +++ linux-2.5.34-greg/drivers/usb/serial/kl5kusb105.c Wed Sep 11 15:33:33 2002 @@ -117,6 +117,12 @@ MODULE_DEVICE_TABLE (usb, id_table); +static struct usb_driver kl5kusb105d_driver = { + .name = "kl5kusb105d", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table, +}; static struct usb_serial_device_type kl5kusb105d_device = { .owner = THIS_MODULE, @@ -1009,6 +1015,7 @@ static int __init klsi_105_init (void) { usb_serial_register (&kl5kusb105d_device); + usb_register (&kl5kusb105d_driver); info(DRIVER_DESC " " DRIVER_VERSION); return 0; @@ -1017,6 +1024,7 @@ static void __exit klsi_105_exit (void) { + usb_deregister (&kl5kusb105d_driver); usb_serial_deregister (&kl5kusb105d_device); } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/mct_u232.c linux-2.5.34-greg/drivers/usb/serial/mct_u232.c --- linux-2.5.34/drivers/usb/serial/mct_u232.c Mon Sep 9 10:35:13 2002 +++ linux-2.5.34-greg/drivers/usb/serial/mct_u232.c Wed Sep 11 15:33:33 2002 @@ -139,6 +139,12 @@ MODULE_DEVICE_TABLE (usb, id_table_combined); +static struct usb_driver mct_u232_driver = { + .name = "mct_u232", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table_combined, +}; static struct usb_serial_device_type mct_u232_device = { .owner = THIS_MODULE, @@ -782,6 +788,7 @@ static int __init mct_u232_init (void) { usb_serial_register (&mct_u232_device); + usb_register (&mct_u232_driver); info(DRIVER_DESC " " DRIVER_VERSION); return 0; } @@ -789,6 +796,7 @@ static void __exit mct_u232_exit (void) { + usb_deregister (&mct_u232_driver); usb_serial_deregister (&mct_u232_device); } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/omninet.c linux-2.5.34-greg/drivers/usb/serial/omninet.c --- linux-2.5.34/drivers/usb/serial/omninet.c Mon Sep 9 10:35:07 2002 +++ linux-2.5.34-greg/drivers/usb/serial/omninet.c Wed Sep 11 15:33:33 2002 @@ -83,6 +83,13 @@ MODULE_DEVICE_TABLE (usb, id_table); +static struct usb_driver omninet_driver = { + .name = "omninet", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table, +}; + static struct usb_serial_device_type zyxel_omninet_device = { .owner = THIS_MODULE, @@ -370,6 +377,7 @@ static int __init omninet_init (void) { usb_serial_register (&zyxel_omninet_device); + usb_register (&omninet_driver); info(DRIVER_VERSION ":" DRIVER_DESC); return 0; } @@ -377,6 +385,7 @@ static void __exit omninet_exit (void) { + usb_deregister (&omninet_driver); usb_serial_deregister (&zyxel_omninet_device); } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/pl2303.c linux-2.5.34-greg/drivers/usb/serial/pl2303.c --- linux-2.5.34/drivers/usb/serial/pl2303.c Mon Sep 9 10:35:11 2002 +++ linux-2.5.34-greg/drivers/usb/serial/pl2303.c Wed Sep 11 15:33:33 2002 @@ -78,6 +78,12 @@ MODULE_DEVICE_TABLE (usb, id_table); +static struct usb_driver pl2303_driver = { + .name = "pl2303", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table, +}; #define SET_LINE_REQUEST_TYPE 0x21 #define SET_LINE_REQUEST 0x20 @@ -709,6 +715,7 @@ static int __init pl2303_init (void) { usb_serial_register (&pl2303_device); + usb_register (&pl2303_driver); info(DRIVER_DESC " " DRIVER_VERSION); return 0; } @@ -716,6 +723,7 @@ static void __exit pl2303_exit (void) { + usb_deregister (&pl2303_driver); usb_serial_deregister (&pl2303_device); } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/safe_serial.c linux-2.5.34-greg/drivers/usb/serial/safe_serial.c --- linux-2.5.34/drivers/usb/serial/safe_serial.c Mon Sep 9 10:35:05 2002 +++ linux-2.5.34-greg/drivers/usb/serial/safe_serial.c Wed Sep 11 15:33:33 2002 @@ -161,6 +161,13 @@ MODULE_DEVICE_TABLE (usb, id_table); +static struct usb_driver safe_driver = { + .name = "safe_serial", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table, +}; + static __u16 crc10_table[256] = { 0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff, 0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe, 0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce, 0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf, @@ -434,12 +441,14 @@ } usb_serial_register (&safe_device); + usb_register (&safe_driver); return 0; } static void __exit safe_exit (void) { + usb_deregister (&safe_driver); usb_serial_deregister (&safe_device); } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/usb-serial.h linux-2.5.34-greg/drivers/usb/serial/usb-serial.h --- linux-2.5.34/drivers/usb/serial/usb-serial.h Mon Sep 9 10:35:12 2002 +++ linux-2.5.34-greg/drivers/usb/serial/usb-serial.h Wed Sep 11 15:33:33 2002 @@ -233,6 +233,9 @@ extern int usb_serial_register(struct usb_serial_device_type *new_device); extern void usb_serial_deregister(struct usb_serial_device_type *device); +extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id); +extern void usb_serial_disconnect(struct usb_interface *iface); + /* determine if we should include the EzUSB loader functions */ #undef USES_EZUSB_FUNCTIONS #if defined(CONFIG_USB_SERIAL_KEYSPAN_PDA) || defined(CONFIG_USB_SERIAL_KEYSPAN_PDA_MODULE) diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/usbserial.c linux-2.5.34-greg/drivers/usb/serial/usbserial.c --- linux-2.5.34/drivers/usb/serial/usbserial.c Mon Sep 9 10:35:09 2002 +++ linux-2.5.34-greg/drivers/usb/serial/usbserial.c Wed Sep 11 15:33:33 2002 @@ -379,30 +379,23 @@ .num_ports = 1, .shutdown = generic_shutdown, }; -#endif - -/* local function prototypes */ -static int serial_open (struct tty_struct *tty, struct file * filp); -static void serial_close (struct tty_struct *tty, struct file * filp); -static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count); -static int serial_write_room (struct tty_struct *tty); -static int serial_chars_in_buffer (struct tty_struct *tty); -static void serial_throttle (struct tty_struct * tty); -static void serial_unthrottle (struct tty_struct * tty); -static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg); -static void serial_set_termios (struct tty_struct *tty, struct termios * old); -static void serial_shutdown (struct usb_serial *serial); - -static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id); -static void usb_serial_disconnect(struct usb_device *dev, void *ptr); +/* we want to look at all devices, as the vendor/product id can change + * depending on the command line argument */ +static struct usb_device_id generic_serial_ids[] = { + {.driver_info = 42}, + {} +}; +#endif +/* Driver structure we register with the USB core */ static struct usb_driver usb_serial_driver = { .name = "serial", .probe = usb_serial_probe, .disconnect = usb_serial_disconnect, - .id_table = NULL, /* check all devices */ +#ifdef CONFIG_USB_SERIAL_GENERIC + .id_table = generic_serial_ids, +#endif }; /* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead @@ -412,7 +405,6 @@ drivers depend on it. */ - static int serial_refcount; static struct tty_driver serial_tty_driver; static struct tty_struct * serial_tty[SERIAL_TTY_MINORS]; @@ -1161,12 +1153,12 @@ return serial; } -static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum, +int usb_serial_probe(struct usb_interface *interface, const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev (interface); struct usb_serial *serial = NULL; struct usb_serial_port *port; - struct usb_interface *interface; struct usb_interface_descriptor *iface_desc; struct usb_endpoint_descriptor *endpoint; struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS]; @@ -1189,7 +1181,6 @@ /* loop through our list of known serial converters, and see if this device matches. */ found = 0; - interface = &dev->actconfig->interface[ifnum]; list_for_each (tmp, &usb_serial_driver_list) { type = list_entry(tmp, struct usb_serial_device_type, driver_list); id_pattern = usb_match_id(interface, type->id_table); @@ -1202,13 +1193,13 @@ if (!found) { /* no match */ dbg("none matched"); - return(NULL); + return -ENODEV; } serial = create_serial (dev, interface, type); if (!serial) { err ("%s - out of memory", __FUNCTION__); - return NULL; + return -ENODEV; } /* if this device type has a probe function, call it */ @@ -1222,7 +1213,7 @@ if (retval < 0) { dbg ("sub driver rejected device"); kfree (serial); - return NULL; + return -ENODEV; } } @@ -1258,6 +1249,7 @@ } #if defined(CONFIG_USB_SERIAL_PL2303) || defined(CONFIG_USB_SERIAL_PL2303_MODULE) +#if 0 /* BEGIN HORRIBLE HACK FOR PL2303 */ /* this is needed due to the looney way its endpoints are set up */ if (ifnum == 1) { @@ -1282,6 +1274,7 @@ } /* END HORRIBLE HACK FOR PL2303 */ #endif +#endif /* found all that we need */ info("%s converter detected", type->name); @@ -1292,7 +1285,7 @@ if (num_ports == 0) { err("Generic device with no bulk out, not allowed."); kfree (serial); - return NULL; + return -EIO; } } #endif @@ -1312,7 +1305,7 @@ if (get_free_serial (serial, num_ports, &minor) == NULL) { err("No more free serial devices"); kfree (serial); - return NULL; + return -ENOMEM; } serial->minor = minor; @@ -1424,7 +1417,8 @@ if (retval > 0) { /* quietly accept this device, but don't bind to a serial port * as it's about to disappear */ - return serial; + interface->dev.driver_data = serial; + return 0; } } @@ -1455,7 +1449,9 @@ } #endif - return serial; /* success */ + /* success */ + interface->dev.driver_data = serial; + return 0; probe_error: @@ -1486,16 +1482,18 @@ /* free up any memory that we allocated */ kfree (serial); - return NULL; + return -EIO; } -static void usb_serial_disconnect(struct usb_device *dev, void *ptr) +void usb_serial_disconnect(struct usb_interface *interface) { - struct usb_serial *serial = (struct usb_serial *) ptr; + struct usb_serial *serial = (struct usb_serial *)interface->dev.driver_data; struct usb_serial_port *port; int i; dbg ("%s", __FUNCTION__); + + interface->dev.driver_data = NULL; if (serial) { /* fail all future close/read/write/ioctl/etc calls */ for (i = 0; i < serial->num_ports; ++i) { @@ -1554,10 +1552,8 @@ /* free up any memory that we allocated */ kfree (serial); - - } else { - info("device disconnected"); } + info("device disconnected"); } @@ -1663,8 +1659,6 @@ info ("USB Serial support registered for %s", new_device->name); - usb_scan_devices(); - return 0; } @@ -1681,7 +1675,7 @@ serial = serial_table[i]; if ((serial != NULL) && (serial->type == device)) { usb_driver_release_interface (&usb_serial_driver, serial->interface); - usb_serial_disconnect (NULL, serial); + usb_serial_disconnect (serial->interface); } } @@ -1694,6 +1688,8 @@ need these symbols to load properly as modules. */ EXPORT_SYMBOL(usb_serial_register); EXPORT_SYMBOL(usb_serial_deregister); +EXPORT_SYMBOL(usb_serial_probe); +EXPORT_SYMBOL(usb_serial_disconnect); #ifdef USES_EZUSB_FUNCTIONS EXPORT_SYMBOL(ezusb_writememory); EXPORT_SYMBOL(ezusb_set_reset); diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/visor.c linux-2.5.34-greg/drivers/usb/serial/visor.c --- linux-2.5.34/drivers/usb/serial/visor.c Mon Sep 9 10:35:07 2002 +++ linux-2.5.34-greg/drivers/usb/serial/visor.c Wed Sep 11 15:33:33 2002 @@ -197,7 +197,7 @@ { } /* Terminating entry */ }; -static __devinitdata struct usb_device_id id_table_combined [] = { +static struct usb_device_id id_table_combined [] = { { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) }, @@ -214,7 +214,12 @@ MODULE_DEVICE_TABLE (usb, id_table_combined); - +static struct usb_driver visor_driver = { + .name = "visor", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table_combined, +}; /* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */ static struct usb_serial_device_type handspring_device = { @@ -763,6 +768,7 @@ { usb_serial_register (&handspring_device); usb_serial_register (&clie_3_5_device); + usb_register (&visor_driver); info(DRIVER_DESC " " DRIVER_VERSION); return 0; @@ -771,6 +777,7 @@ static void __exit visor_exit (void) { + usb_deregister (&visor_driver); usb_serial_deregister (&handspring_device); usb_serial_deregister (&clie_3_5_device); } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/serial/whiteheat.c linux-2.5.34-greg/drivers/usb/serial/whiteheat.c --- linux-2.5.34/drivers/usb/serial/whiteheat.c Mon Sep 9 10:35:08 2002 +++ linux-2.5.34-greg/drivers/usb/serial/whiteheat.c Wed Sep 11 15:33:33 2002 @@ -110,7 +110,7 @@ { } /* Terminating entry */ }; -static __devinitdata struct usb_device_id id_table_combined [] = { +static struct usb_device_id id_table_combined [] = { { USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_WHITE_HEAT_ID) }, { USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_FAKE_WHITE_HEAT_ID) }, { } /* Terminating entry */ @@ -118,6 +118,13 @@ MODULE_DEVICE_TABLE (usb, id_table_combined); +static struct usb_driver whiteheat_driver = { + .name = "whiteheat", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table_combined, +}; + /* function prototypes for the Connect Tech WhiteHEAT serial converter */ static int whiteheat_open (struct usb_serial_port *port, struct file *filp); static void whiteheat_close (struct usb_serial_port *port, struct file *filp); @@ -674,6 +681,7 @@ { usb_serial_register (&whiteheat_fake_device); usb_serial_register (&whiteheat_device); + usb_register (&whiteheat_driver); info(DRIVER_DESC " " DRIVER_VERSION); return 0; } @@ -681,6 +689,7 @@ static void __exit whiteheat_exit (void) { + usb_deregister (&whiteheat_driver); usb_serial_deregister (&whiteheat_fake_device); usb_serial_deregister (&whiteheat_device); } diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/storage/scsiglue.c linux-2.5.34-greg/drivers/usb/storage/scsiglue.c --- linux-2.5.34/drivers/usb/storage/scsiglue.c Mon Sep 9 10:35:11 2002 +++ linux-2.5.34-greg/drivers/usb/storage/scsiglue.c Wed Sep 11 15:33:33 2002 @@ -252,7 +252,6 @@ for (i = 0; i < pusb_dev_save->actconfig->bNumInterfaces; i++) { struct usb_interface *intf = &pusb_dev_save->actconfig->interface[i]; - const struct usb_device_id *id; /* if this is an unclaimed interface, skip it */ if (!intf->driver) { @@ -263,11 +262,8 @@ /* simulate a disconnect and reconnect for all interfaces */ US_DEBUGPX("simulating disconnect/reconnect.\n"); - down(&intf->driver->serialize); - intf->driver->disconnect(pusb_dev_save, intf->private_data); - id = usb_match_id(intf, intf->driver->id_table); - intf->driver->probe(pusb_dev_save, i, id); - up(&intf->driver->serialize); + usb_device_remove (&intf->dev); + usb_device_probe (&intf->dev); } US_DEBUGP("bus_reset() complete\n"); scsi_lock(srb->host); diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/drivers/usb/storage/usb.c linux-2.5.34-greg/drivers/usb/storage/usb.c --- linux-2.5.34/drivers/usb/storage/usb.c Mon Sep 9 10:35:06 2002 +++ linux-2.5.34-greg/drivers/usb/storage/usb.c Wed Sep 11 15:33:33 2002 @@ -103,10 +103,10 @@ struct us_data *us_list; struct semaphore us_list_semaphore; -static void * storage_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id); +static int storage_probe(struct usb_interface *iface, + const struct usb_device_id *id); -static void storage_disconnect(struct usb_device *dev, void *ptr); +static void storage_disconnect(struct usb_interface *iface); /* The entries in this table, except for final ones here * (USB_MASS_STORAGE_CLASS and the empty entry), correspond, @@ -617,9 +617,11 @@ } /* Probe to see if a new device is actually a SCSI device */ -static void * storage_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id) +static int storage_probe(struct usb_interface *intf, + const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev(intf); + int ifnum = intf->altsetting->bInterfaceNumber; int i; const int id_index = id - storage_usb_ids; char mf[USB_STOR_STRING_LEN]; /* manufacturer */ @@ -644,7 +646,6 @@ /* the altsetting on the interface we're probing that matched our * usb_match_id table */ - struct usb_interface *intf = dev->actconfig->interface; struct usb_interface_descriptor *altsetting = intf[ifnum].altsetting + intf[ifnum].act_altsetting; US_DEBUGP("act_altsetting is %d\n", intf[ifnum].act_altsetting); @@ -674,7 +675,7 @@ US_DEBUGP("Product: %s\n", unusual_dev->productName); } else /* no, we can't support it */ - return NULL; + return -EIO; /* At this point, we know we've got a live one */ US_DEBUGP("USB Mass Storage device detected\n"); @@ -723,7 +724,7 @@ } else if (result != 0) { /* it's not a stall, but another error -- time to bail */ US_DEBUGP("-- Unknown error. Rejecting device\n"); - return NULL; + return -EIO; } } #endif @@ -731,7 +732,7 @@ /* Do some basic sanity checks, and bail if we find a problem */ if (!ep_in || !ep_out || (protocol == US_PR_CBI && !ep_int)) { US_DEBUGP("Endpoint sanity check failed! Rejecting dev.\n"); - return NULL; + return -EIO; } /* At this point, we've decided to try to use the device */ @@ -810,7 +811,7 @@ GFP_KERNEL)) == NULL) { printk(KERN_WARNING USB_STORAGE "Out of memory\n"); usb_put_dev(dev); - return NULL; + return -ENOMEM; } memset(ss, 0, sizeof(struct us_data)); new_device = 1; @@ -1087,8 +1088,9 @@ printk(KERN_DEBUG "USB Mass Storage device found at %d\n", dev->devnum); - /* return a pointer for the disconnect function */ - return ss; + /* save a pointer to our structure */ + intf->dev.driver_data = ss; + return 0; /* we come here if there are any problems */ /* ss->dev_semaphore must be locked */ @@ -1098,16 +1100,18 @@ up(&ss->dev_semaphore); if (new_device) kfree(ss); - return NULL; + return -EIO; } /* Handle a disconnect event from the USB core */ -static void storage_disconnect(struct usb_device *dev, void *ptr) +static void storage_disconnect(struct usb_interface *intf) { - struct us_data *ss = ptr; + struct us_data *ss = intf->dev.driver_data; US_DEBUGP("storage_disconnect() called\n"); + intf->dev.driver_data = NULL; + /* this is the odd case -- we disconnected but weren't using it */ if (!ss) { US_DEBUGP("-- device was not in use\n"); diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/include/linux/device.h linux-2.5.34-greg/include/linux/device.h --- linux-2.5.34/include/linux/device.h Mon Sep 9 10:35:08 2002 +++ linux-2.5.34-greg/include/linux/device.h Wed Sep 11 15:33:33 2002 @@ -306,6 +306,18 @@ return list_entry(g_list, struct device, g_list); } +static inline void * +dev_get_drvdata (struct device *dev) +{ + return dev->driver_data; +} + +static inline void +dev_set_drvdata (struct device *dev, void *data) +{ + dev->driver_data = data; +} + /* * High level routines for use by the bus drivers */ diff -Naur -X /home/greg/linux/dontdiff linux-2.5.34/include/linux/usb.h linux-2.5.34-greg/include/linux/usb.h --- linux-2.5.34/include/linux/usb.h Mon Sep 9 10:35:09 2002 +++ linux-2.5.34-greg/include/linux/usb.h Wed Sep 11 15:33:33 2002 @@ -227,7 +227,7 @@ int act_altsetting; /* active alternate setting */ int num_altsetting; /* number of alternate settings */ int max_altsetting; /* total memory allocated */ - + struct usb_driver *driver; /* driver */ struct device dev; /* interface specific device info */ void *private_data; @@ -399,9 +399,6 @@ extern void usb_free_dev(struct usb_device *); #define usb_put_dev usb_free_dev -/* for when layers above USB add new non-USB drivers */ -extern void usb_scan_devices(void); - /* mostly for devices emulating SCSI over USB */ extern int usb_reset_device(struct usb_device *dev); @@ -623,10 +620,10 @@ * expose information to user space regardless of where they * do (or don't) show up otherwise in the filesystem. * @id_table: USB drivers use ID table to support hotplugging. - * Export this with MODULE_DEVICE_TABLE(usb,...), or use NULL to - * say that probe() should be called for any unclaimed interfce. + * Export this with MODULE_DEVICE_TABLE(usb,...). This must be set + * or your driver's probe function will never get called. * - * USB drivers should provide a name, probe() and disconnect() methods, + * USB drivers must provide a name, probe() and disconnect() methods, * and an id_table. Other driver fields are optional. * * The id_table is used in hotplugging. It holds a set of descriptors, @@ -643,32 +640,23 @@ */ struct usb_driver { struct module *owner; + const char *name; - void *(*probe)( - struct usb_device *dev, /* the device */ - unsigned intf, /* what interface */ - const struct usb_device_id *id /* from id_table */ - ); - void (*disconnect)( - struct usb_device *dev, /* the device */ - void *handle /* as returned by probe() */ - ); + int (*probe) (struct usb_interface *intf, + const struct usb_device_id *id); - struct list_head driver_list; - struct semaphore serialize; + void (*disconnect) (struct usb_interface *intf); - /* ioctl -- userspace apps can talk to drivers through usbfs */ - int (*ioctl)(struct usb_device *dev, unsigned int code, void *buf); + int (*ioctl) (struct usb_device *dev, unsigned int code, void *buf); - /* support for "new-style" USB hotplugging */ const struct usb_device_id *id_table; - /* suspend before the bus suspends; - * disconnect or resume when the bus resumes */ - /* void (*suspend)(struct usb_device *dev); */ - /* void (*resume)(struct usb_device *dev); */ + struct device_driver driver; + + struct semaphore serialize; }; +#define to_usb_driver(d) container_of(d, struct usb_driver, driver) extern struct bus_type usb_bus_type; @@ -682,6 +670,9 @@ extern int usb_register_dev(struct file_operations *fops, int minor, int num_minors, int *start_minor); extern void usb_deregister_dev(int num_minors, int start_minor); +extern int usb_device_probe(struct device *dev); +extern int usb_device_remove(struct device *dev); + /* -------------------------------------------------------------------------- */ /*