diff options
| author | James Simmons <jsimmons@maxwell.earthlink.net> | 2002-09-16 19:34:34 -0700 |
|---|---|---|
| committer | James Simmons <jsimmons@maxwell.earthlink.net> | 2002-09-16 19:34:34 -0700 |
| commit | 586d2a0d222c497a8f707bf464e48e968129202f (patch) | |
| tree | e7d9bccb51e1505688aa53d4eaf7fce76f025281 | |
| parent | c598bcd01bd613127079f83a58cfda8cdfbc8bcc (diff) | |
| parent | 6b29059af3cb8607e055c5051c608a876572cdf7 (diff) | |
Merge http://linuxconsole.bkbits.net/stable
into maxwell.earthlink.net:/usr/src/console-stable
104 files changed, 1802 insertions, 1710 deletions
diff --git a/Documentation/usb/ov511.txt b/Documentation/usb/ov511.txt index 4c33f949dfb0..8c36ebe503fb 100644 --- a/Documentation/usb/ov511.txt +++ b/Documentation/usb/ov511.txt @@ -105,15 +105,6 @@ MODULE PARAMETERS: 4=most function calls and data parsing messages 5=highly repetitive mesgs - NAME: fix_rgb_offset - TYPE: integer (Boolean) - DEFAULT: 0 - DESC: Some people have reported that the blue component of the image is one - or so lines higher than the red component. This is only apparent in - images with white objects on black backgrounds at 640x480. Setting this - to 1 will realign the color planes correctly. NOTE: You will likely - need a fast (500 MHz) CPU. - NAME: snapshot TYPE: integer (Boolean) DEFAULT: 0 @@ -121,13 +112,6 @@ MODULE PARAMETERS: the snapshot button is pressed. Note: enabling this mode disables /proc/video/ov511/<minor#>/button - NAME: force_rgb (Deprecated; may be removed in the future) - TYPE: integer (Boolean) - DEFAULT: 0 - DESC: Force image to be read in RGB instead of BGR. This option allow - programs that expect RGB data (e.g. gqcam) to work with this driver. If - your colors look VERY wrong, you may want to change this. - NAME: cams TYPE: integer (1-4 for OV511, 1-31 for OV511+) DEFAULT: 1 @@ -234,12 +218,7 @@ MODULE PARAMETERS: greyscale mode with a color camera, for example. Supported modes are: 0 (Allows all the following formats) 1 VIDEO_PALETTE_GREY (Linear greyscale) - 3 VIDEO_PALETTE_RGB565 (565 16 bit RGB) - 4 VIDEO_PALETTE_RGB24 (24bit RGB) - 7 VIDEO_PALETTE_YUV422 (YUV422 capture) - 8 VIDEO_PALETTE_YUYV (YUV422 capture; same as 7) 10 VIDEO_PALETTE_YUV420 (YUV 4:2:0 Planar) - 13 VIDEO_PALETTE_YUV422P (YUV 4:2:2 Planar) 15 VIDEO_PALETTE_YUV420P (YUV 4:2:0 Planar, same as 10) NAME: backlight @@ -278,29 +257,17 @@ MODULE PARAMETERS: WORKING FEATURES: o Color streaming/capture at most widths and heights that are multiples of 8. - o RGB24, RGB565, YUV420/YUV420P, YUV422/YUYV, and YUV422P color o Monochrome (use force_palette=1 to enable) o Setting/getting of saturation, contrast, brightness, and hue (only some of them work the OV7620 and OV7620AE) o /proc status reporting o SAA7111A video capture support at 320x240 and 640x480 o Compression support - -EXPERIMENTAL FEATURES: - o OV518/OV518+ support - o OV6630 sensor support - o Banding filter o SMP compatibility -TO-DO: - o V4L2 support (This will be done after the next kernel patch release) - o Setting of hue not working with OV7620 - o Setting of contrast and hue not working with OV7620AE - o OV8600 sensor support (Not used in anything yet) - HOW TO CONTACT ME: -You can email me at mmcclell@bigfoot.com . Please prefix the subject line +You can email me at mark@alpha.dyndns.org . Please prefix the subject line with "OV511: " so that I am certain to notice your message. CREDITS: diff --git a/Documentation/usb/usb-serial.txt b/Documentation/usb/usb-serial.txt index 092434ccd56b..ded1563b064f 100644 --- a/Documentation/usb/usb-serial.txt +++ b/Documentation/usb/usb-serial.txt @@ -221,8 +221,8 @@ FTDI Single Port Serial Driver ZyXEL omni.net lcd plus ISDN TA - This is an ISDN TA. Please report both successes and troubles to the - author at omninet@kroah.com + This is an ISDN TA. Please report both successes and troubles to + azummo@towertech.it Digi AccelePort Driver diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index 9c7f94037fda..00b09cc403a2 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c @@ -157,24 +157,6 @@ static void __init init_amd(struct cpuinfo_x86 *c) // return r; } -static void amd_identify(struct cpuinfo_x86 * c) -{ - u32 xlvl; - - if (have_cpuid_p()) { - generic_identify(c); - - /* AMD-defined flags: level 0x80000001 */ - xlvl = cpuid_eax(0x80000000); - if ( (xlvl & 0xffff0000) == 0x80000000 ) { - if ( xlvl >= 0x80000001 ) - c->x86_capability[1] = cpuid_edx(0x80000001); - if ( xlvl >= 0x80000004 ) - get_model_name(c); /* Default name */ - } - } -} - static unsigned int amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) { /* AMD errata T13 (order #21922) */ @@ -204,7 +186,7 @@ static struct cpu_dev amd_cpu_dev __initdata = { }, }, .c_init = init_amd, - .c_identify = amd_identify, + .c_identify = generic_identify, .c_size_cache = amd_size_cache, }; diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 88041a31ce5d..2af5a1fa3e72 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -204,7 +204,7 @@ int __init have_cpuid_p(void) void __init generic_identify(struct cpuinfo_x86 * c) { - u32 tfms; + u32 tfms, xlvl; int junk; if (have_cpuid_p()) { @@ -230,6 +230,15 @@ void __init generic_identify(struct cpuinfo_x86 * c) /* Have CPUID level 0 only - unheard of */ c->x86 = 4; } + + /* AMD-defined flags: level 0x80000001 */ + xlvl = cpuid_eax(0x80000000); + if ( (xlvl & 0xffff0000) == 0x80000000 ) { + if ( xlvl >= 0x80000001 ) + c->x86_capability[1] = cpuid_edx(0x80000001); + if ( xlvl >= 0x80000004 ) + get_model_name(c); /* Default name */ + } } } diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c index 6aa1e33becaf..ff98d996d336 100644 --- a/arch/i386/kernel/cpu/intel.c +++ b/arch/i386/kernel/cpu/intel.c @@ -156,7 +156,6 @@ static void __init init_intel(struct cpuinfo_x86 *c) } #endif - get_model_name(c); if (c->cpuid_level > 1) { /* supports eax=2 call */ diff --git a/arch/i386/kernel/cpu/transmeta.c b/arch/i386/kernel/cpu/transmeta.c index 2314da6f8421..4bb3c5633b1f 100644 --- a/arch/i386/kernel/cpu/transmeta.c +++ b/arch/i386/kernel/cpu/transmeta.c @@ -64,6 +64,11 @@ static void __init init_transmeta(struct cpuinfo_x86 *c) wrmsr(0x80860004, ~0, uk); c->x86_capability[0] = cpuid_edx(0x00000001); wrmsr(0x80860004, cap_mask, uk); + + /* If we can run i686 user-space code, call us an i686 */ +#define USER686 (X86_FEATURE_TSC|X86_FEATURE_CX8|X86_FEATURE_CMOV) + if ( c->x86 == 5 && (c->x86_capability[0] & USER686) == USER686 ) + c->x86 = 6; } static void transmeta_identify(struct cpuinfo_x86 * c) diff --git a/drivers/base/core.c b/drivers/base/core.c index e9f7079058d4..977c4b9fe92a 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -103,12 +103,13 @@ static void device_detach(struct device * dev) 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 --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c index 056c142b9239..868b3bf30e43 100644 --- a/drivers/bluetooth/hci_usb.c +++ b/drivers/bluetooth/hci_usb.c @@ -656,8 +656,9 @@ static int hci_usb_fw_load(struct usb_device *udev) #endif /* CONFIG_BLUEZ_USB_FW_LOAD */ -static void * hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id) +static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_device *udev = interface_to_usbdev(intf); struct usb_endpoint_descriptor *bulk_out_ep[HCI_MAX_IFACE_NUM]; struct usb_endpoint_descriptor *isoc_out_ep[HCI_MAX_IFACE_NUM]; struct usb_endpoint_descriptor *bulk_in_ep[HCI_MAX_IFACE_NUM]; @@ -670,11 +671,11 @@ static void * hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const s struct hci_dev *hdev; int i, a, e, size, ifn, isoc_ifnum, isoc_alts; - BT_DBG("udev %p ifnum %d", udev, ifnum); + BT_DBG("intf %p", intf); /* Check number of endpoints */ - if (udev->actconfig->interface[ifnum].altsetting[0].bNumEndpoints < 3) - return NULL; + if (intf->altsetting[0].bNumEndpoints < 3) + return -ENODEV; MOD_INC_USE_COUNT; @@ -794,24 +795,27 @@ static void * hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const s goto probe_error; } - return husb; + dev_set_drvdata(&intf->dev, husb); + return 0; probe_error: kfree(husb); done: MOD_DEC_USE_COUNT; - return NULL; + return -EIO; } -static void hci_usb_disconnect(struct usb_device *udev, void *ptr) +static void hci_usb_disconnect(struct usb_interface *intf) { - struct hci_usb *husb = (struct hci_usb *) ptr; - struct hci_dev *hdev = &husb->hdev; + struct hci_usb *husb = dev_get_drvdata(&intf->dev); + struct hci_dev *hdev; + dev_set_drvdata(&intf->dev, NULL); if (!husb) return; + hdev = &husb->hdev; BT_DBG("%s", hdev->name); hci_usb_close(hdev); diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index ff691a53cc09..b5b07ca56cba 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c @@ -106,14 +106,15 @@ static void iforce_usb_ctrl(struct urb *urb) wake_up(&iforce->wait); } -static void *iforce_usb_probe(struct usb_device *dev, unsigned int ifnum, +static int iforce_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev(intf); struct usb_endpoint_descriptor *epirq, *epout; struct iforce *iforce; - epirq = dev->config[0].interface[ifnum].altsetting[0].endpoint + 0; - epout = dev->config[0].interface[ifnum].altsetting[0].endpoint + 1; + epirq = intf->altsetting[0].endpoint + 0; + epout = intf->altsetting[0].endpoint + 1; if (!(iforce = kmalloc(sizeof(struct iforce) + 32, GFP_KERNEL))) goto fail; @@ -150,7 +151,8 @@ static void *iforce_usb_probe(struct usb_device *dev, unsigned int ifnum, if (iforce_init_device(iforce)) goto fail; - return iforce; + dev_set_drvdata (&intf->dev, iforce); + return 0; fail: if (iforce) { @@ -160,7 +162,7 @@ fail: kfree(iforce); } - return NULL; + return -ENODEV; } /* Called by iforce_delete() */ @@ -176,17 +178,20 @@ void iforce_usb_delete(struct iforce* iforce) usb_free_urb(iforce->ctrl); } -static void iforce_usb_disconnect(struct usb_device *dev, void *ptr) +static void iforce_usb_disconnect(struct usb_interface *intf) { - struct iforce *iforce = ptr; + struct iforce *iforce = dev_get_drvdata (&intf->dev); int open = 0; /* FIXME! iforce->dev.handle->open; */ - iforce->usbdev = NULL; - input_unregister_device(&iforce->dev); + dev_set_drvdata (&intf->dev, NULL); + if (iforce) { + iforce->usbdev = NULL; + input_unregister_device(&iforce->dev); - if (!open) { - iforce_delete_device(iforce); - kfree(iforce); + if (!open) { + iforce_delete_device(iforce); + kfree(iforce); + } } } diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c index 4bfe03d0ce7e..f68156cbaea7 100644 --- a/drivers/isdn/hisax/st5481_init.c +++ b/drivers/isdn/hisax/st5481_init.c @@ -59,10 +59,10 @@ static LIST_HEAD(adapter_list); * This function will be called when the adapter is plugged * into the USB bus. */ -static void * __devinit probe_st5481(struct usb_device *dev, - unsigned int ifnum, - const struct usb_device_id *id) +static int probe_st5481(struct usb_interface *intf + const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev(intf); struct st5481_adapter *adapter; struct hisax_b_if *b_if[2]; int retval, i; @@ -73,7 +73,7 @@ static void * __devinit probe_st5481(struct usb_device *dev, adapter = kmalloc(sizeof(struct st5481_adapter), GFP_KERNEL); if (!adapter) - return NULL; + return -ENOMEM; memset(adapter, 0, sizeof(struct st5481_adapter)); @@ -114,6 +114,7 @@ static void * __devinit probe_st5481(struct usb_device *dev, hisax_register(&adapter->hisax_d_if, b_if, "st5481_usb", protocol); st5481_start(adapter); + dev_set_drvdata(&intf->dev, adapter); return adapter; err_b: @@ -123,19 +124,23 @@ static void * __devinit probe_st5481(struct usb_device *dev, err_usb: st5481_release_usb(adapter); err: - return NULL; + return -EIO; } /* * This function will be called when the adapter is removed * from the USB bus. */ -static void __devexit disconnect_st5481(struct usb_device *dev, void *arg) +static void disconnect_st5481(struct usb_interface *intf) { - struct st5481_adapter *adapter = arg; + struct st5481_adapter *adapter = dev_get_drvdata(&intf->dev); DBG(1,""); + dev_set_drvdata(&intf->dev, NULL); + if (!adapter) + return; + list_del(&adapter->list); st5481_stop(adapter); @@ -176,10 +181,10 @@ static struct usb_device_id st5481_ids[] = { MODULE_DEVICE_TABLE (usb, st5481_ids); static struct usb_driver st5481_usb_driver = { - .name = "st5481_usb", - .probe = probe_st5481, - .disconnect = __devexit_p(disconnect_st5481), - .id_table = st5481_ids, + .name = "st5481_usb", + .probe = probe_st5481, + .disconnect = disconnect_st5481, + .id_table = st5481_ids, }; static int __init st5481_usb_init(void) diff --git a/drivers/media/video/cpia_usb.c b/drivers/media/video/cpia_usb.c index 0a2069f6134c..b06262437bf8 100644 --- a/drivers/media/video/cpia_usb.c +++ b/drivers/media/video/cpia_usb.c @@ -479,9 +479,10 @@ int cpia_usb_init(void) /* Probing and initializing */ -static void *cpia_probe(struct usb_device *udev, unsigned int ifnum, - const struct usb_device_id *id) +static int cpia_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_cpia *ucpia; struct cam_data *cam; @@ -489,16 +490,16 @@ static void *cpia_probe(struct usb_device *udev, unsigned int ifnum, /* A multi-config CPiA camera? */ if (udev->descriptor.bNumConfigurations != 1) - return NULL; + return -ENODEV; - interface = &udev->actconfig->interface[ifnum].altsetting[0]; + interface = &intf->altsetting[0]; printk(KERN_INFO "USB CPiA camera found\n"); ucpia = kmalloc(sizeof(*ucpia), GFP_KERNEL); if (!ucpia) { printk(KERN_ERR "couldn't kmalloc cpia struct\n"); - return NULL; + return -ENOMEM; } memset(ucpia, 0, sizeof(*ucpia)); @@ -548,7 +549,8 @@ static void *cpia_probe(struct usb_device *udev, unsigned int ifnum, cpia_add_to_list(cam_list, cam); spin_unlock( &cam_list_lock_usb ); - return cam; + dev_set_drvdata(&intf->dev, cam); + return 0; fail_all: vfree(ucpia->buffers[2]); @@ -561,10 +563,10 @@ fail_alloc_1: ucpia->buffers[0] = NULL; fail_alloc_0: - return NULL; + return -EIO; } -static void cpia_disconnect(struct usb_device *dev, void *ptr); +static void cpia_disconnect(struct usb_interface *intf); static struct usb_device_id cpia_id_table [] = { { USB_DEVICE(0x0553, 0x0002) }, @@ -586,11 +588,17 @@ static struct usb_driver cpia_driver = { /* don't use dev, it may be NULL! (see usb_cpia_cleanup) */ /* _disconnect from usb_cpia_cleanup is not necessary since usb_deregister */ /* will do it for us as well as passing a udev structure - jerdfelt */ -static void cpia_disconnect(struct usb_device *udev, void *ptr) +static void cpia_disconnect(struct usb_interface *intf) { - struct cam_data *cam = (struct cam_data *) ptr; - struct usb_cpia *ucpia = (struct usb_cpia *) cam->lowlevel_data; + struct cam_data *cam = dev_get_drvdata(&intf->dev); + struct usb_cpia *ucpia; + struct usb_device *udev; + dev_set_drvdata(&intf->dev, NULL); + if (!cam) + return; + + ucpia = (struct usb_cpia *) cam->lowlevel_data; spin_lock( &cam_list_lock_usb ); cpia_remove_from_list(cam); spin_unlock( &cam_list_lock_usb ); @@ -607,6 +615,7 @@ static void cpia_disconnect(struct usb_device *udev, void *ptr) if (waitqueue_active(&ucpia->wq_stream)) wake_up_interruptible(&ucpia->wq_stream); + udev = interface_to_usbdev(intf); usb_driver_release_interface(&cpia_driver, &udev->actconfig->interface[0]); diff --git a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c index 1187e7b58ecc..036259bcd6d7 100644 --- a/drivers/usb/class/audio.c +++ b/drivers/usb/class/audio.c @@ -2740,9 +2740,9 @@ static /*const*/ struct file_operations usb_audio_fops = { /* --------------------------------------------------------------------- */ -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 @@ static struct usb_driver usb_audio_driver = { .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 @@ static void usb_audio_constructmixer(struct usb_audio_state *s, unsigned char *b 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 @@ ret: /* 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 *intf, + const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev (intf); 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 @@ static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum, 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; + } + s = usb_audio_parsecontrol(dev, buffer, buflen, intf->altsetting->bInterfaceNumber); + if (s) { + dev_set_drvdata (&intf->dev, s); + return 0; } - return usb_audio_parsecontrol(dev, buffer, buflen, ifnum); + 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 *intf) { - struct usb_audio_state *s = (struct usb_audio_state *)ptr; + struct usb_audio_state *s = dev_get_drvdata (&intf->dev); 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 @@ static void usb_audio_disconnect(struct usb_device *dev, void *ptr) list_del(&s->audiodev); INIT_LIST_HEAD(&s->audiodev); s->usbdev = NULL; + dev_set_drvdata (&intf->dev, 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 --git a/drivers/usb/class/bluetty.c b/drivers/usb/class/bluetty.c index 7d57b2e562d1..b2c097676307 100644 --- a/drivers/usb/class/bluetty.c +++ b/drivers/usb/class/bluetty.c @@ -221,9 +221,9 @@ static void bluetooth_ctrl_callback (struct urb *urb); 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 bluetooth_softint(void *private) } -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 *intf, + const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev (intf); struct usb_bluetooth *bluetooth = NULL; struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; @@ -1051,7 +1052,7 @@ static void * usb_bluetooth_probe(struct usb_device *dev, unsigned int ifnum, int num_bulk_in = 0; int num_bulk_out = 0; - interface = &dev->actconfig->interface[ifnum].altsetting[0]; + interface = &intf->altsetting[0]; control_out_endpoint = interface->bInterfaceNumber; /* find the endpoints that we need */ @@ -1088,7 +1089,7 @@ static void * usb_bluetooth_probe(struct usb_device *dev, unsigned int ifnum, (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 @@ static void * usb_bluetooth_probe(struct usb_device *dev, unsigned int ifnum, 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 @@ static void * usb_bluetooth_probe(struct usb_device *dev, unsigned int ifnum, bluetooth_table[minor] = bluetooth; - return bluetooth; /* success */ + /* success */ + dev_set_drvdata (&intf->dev, bluetooth); + return 0; probe_error: if (bluetooth->read_urb) @@ -1220,15 +1223,16 @@ probe_error: /* 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 *intf) { - struct usb_bluetooth *bluetooth = (struct usb_bluetooth *) ptr; + struct usb_bluetooth *bluetooth = dev_get_drvdata (&intf->dev); int i; + dev_set_drvdata (&intf->dev, NULL); if (bluetooth) { if ((bluetooth->open_count) && (bluetooth->tty)) tty_hangup(bluetooth->tty); @@ -1274,7 +1278,6 @@ static void usb_bluetooth_disconnect(struct usb_device *dev, void *ptr) /* free up any memory that we allocated */ kfree (bluetooth); - } else { info("device disconnected"); } diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 8fc07f6fb5d7..022ef711e81a 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -507,9 +507,10 @@ static void acm_tty_set_termios(struct tty_struct *tty, struct termios *termios_ * 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 *intf, + 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 @@ static void *acm_probe(struct usb_device *dev, unsigned int ifnum, int readsize, ctrlsize, minor, i; unsigned char *buf; + dev = interface_to_usbdev (intf); for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { cfacm = dev->config + i; @@ -561,12 +563,12 @@ static void *acm_probe(struct usb_device *dev, unsigned int ifnum, 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 @@ static void *acm_probe(struct usb_device *dev, unsigned int ifnum, 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 @@ static void *acm_probe(struct usb_device *dev, unsigned int ifnum, 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 @@ static void *acm_probe(struct usb_device *dev, unsigned int ifnum, 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; + dev_set_drvdata (&intf->dev, acm); + return 0; } - return NULL; + return -EIO; } -static void acm_disconnect(struct usb_device *dev, void *ptr) +static void acm_disconnect(struct usb_interface *intf) { - struct acm *acm = ptr; + struct acm *acm = dev_get_drvdata (&intf->dev); if (!acm || !acm->dev) { dbg("disconnect on nonexisting interface"); @@ -647,6 +652,7 @@ static void acm_disconnect(struct usb_device *dev, void *ptr) } acm->dev = NULL; + dev_set_drvdata (&intf->dev, NULL); usb_unlink_urb(acm->ctrlurb); usb_unlink_urb(acm->readurb); diff --git a/drivers/usb/class/usb-midi.c b/drivers/usb/class/usb-midi.c index 1a04189b3a49..87d65953ed88 100644 --- a/drivers/usb/class/usb-midi.c +++ b/drivers/usb/class/usb-midi.c @@ -2020,13 +2020,16 @@ static int detect_by_hand(struct usb_device *d, unsigned int ifnum, struct usb_m /* ------------------------------------------------------------------------- */ -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 *intf, + const struct usb_device_id *id) { struct usb_midi_state *s; + struct usb_device *dev = interface_to_usbdev(intf); + int ifnum = intf->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 @@ static void *usb_midi_probe(struct usb_device *dev, unsigned int ifnum, 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 @@ static void *usb_midi_probe(struct usb_device *dev, unsigned int ifnum, MOD_INC_USE_COUNT; #endif - return s; + dev_set_drvdata (&intf->dev, s); + return 0; } -static void usb_midi_disconnect(struct usb_device *dev, void *ptr) +static void usb_midi_disconnect(struct usb_interface *intf) { - struct usb_midi_state *s = (struct usb_midi_state *)ptr; + struct usb_midi_state *s = dev_get_drvdata (&intf->dev); struct list_head *list; struct usb_mididev *m; + if ( !s ) + return; + if ( s == (struct usb_midi_state *)-1 ) { return; } @@ -2073,6 +2080,7 @@ static void usb_midi_disconnect(struct usb_device *dev, void *ptr) list_del(&s->mididev); INIT_LIST_HEAD(&s->mididev); s->usbdev = NULL; + dev_set_drvdata (&intf->dev, NULL); for ( list = s->midiDevList.next; list != &s->midiDevList; list = list->next ) { m = list_entry(list, struct usb_mididev, list); @@ -2092,14 +2100,17 @@ static void usb_midi_disconnect(struct usb_device *dev, void *ptr) 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 --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 66408a47dfdb..0d9719dffe22 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -795,9 +795,10 @@ static struct file_operations usblp_fops = { .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 *intf, + const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev (intf); struct usblp *usblp = 0; int protocol; int retval; @@ -813,7 +814,7 @@ static void *usblp_probe(struct usb_device *dev, unsigned int ifnum, usblp->dev = dev; init_MUTEX (&usblp->sem); init_waitqueue_head(&usblp->wait); - usblp->ifnum = ifnum; + usblp->ifnum = intf->altsetting->bInterfaceNumber; retval = usb_register_dev(&usblp_fops, USBLP_MINOR_BASE, 1, &usblp->minor); if (retval) { @@ -886,12 +887,14 @@ static void *usblp_probe(struct usb_device *dev, unsigned int ifnum, 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; + dev_set_drvdata (&intf->dev, usblp); + return 0; abort_minor: usb_deregister_dev (1, usblp->minor); @@ -903,7 +906,7 @@ abort: if (usblp->device_id_string) kfree(usblp->device_id_string); kfree(usblp); } - return NULL; + return -EIO; } /* @@ -1065,9 +1068,9 @@ static int usblp_cache_device_id_string(struct usblp *usblp) return length; } -static void usblp_disconnect(struct usb_device *dev, void *ptr) +static void usblp_disconnect(struct usb_interface *intf) { - struct usblp *usblp = ptr; + struct usblp *usblp = dev_get_drvdata (&intf->dev); if (!usblp || !usblp->dev) { err("bogus disconnect"); @@ -1077,6 +1080,7 @@ static void usblp_disconnect(struct usb_device *dev, void *ptr) down (&usblp->sem); lock_kernel(); usblp->dev = NULL; + dev_set_drvdata (&intf->dev, NULL); usblp_unlink_urbs(usblp); diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index e701a4975071..1e819db95786 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c @@ -111,7 +111,6 @@ static char *format_endpt = /* * 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 --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 0b81ee069ec0..f4d58277aba0 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -298,15 +298,15 @@ static void destroy_all_async(struct dev_state *ps) * 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 = dev_get_drvdata (&intf->dev); if (!ps) return; @@ -317,6 +317,7 @@ static void driver_disconnect(struct usb_device *dev, void *context) /* prevent new I/O requests */ ps->dev = 0; ps->ifclaimed = 0; + dev_set_drvdata (&intf->dev, NULL); /* force async requests to complete */ destroy_all_async (ps); @@ -427,30 +428,6 @@ static int findintfif(struct usb_device *dev, unsigned int ifn) 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 @@ static int proc_resetdevice(struct dev_state *ps) 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 @@ static int proc_ioctl (struct dev_state *ps, void *arg) /* 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 --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 7145e151e1f8..e73c157c943e 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -722,12 +722,10 @@ int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev { 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); + 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); return retval; } EXPORT_SYMBOL (usb_register_root_hub); diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 06c2f0c9d7c5..099c7c80a64d 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -270,7 +270,7 @@ extern void usb_hc_died (struct usb_hcd *hcd); /* -------------------------------------------------------------------------- */ /* 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 @@ extern int usb_find_interface_driver (struct usb_device *dev, #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 --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 5f624d73327a..650df33243a2 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -175,6 +175,7 @@ static void hub_tt_kevent (void *arg) 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 @@ static void hub_tt_kevent (void *arg) /* 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 @@ void usb_hub_tt_clear_buffer (struct usb_device *dev, int pipe) 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 void usb_hub_power_on(struct usb_hub *hub) 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 @@ static int usb_hub_configure(struct usb_hub *hub, 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 = dev_get_drvdata (&intf->dev); + unsigned long flags; + + if (!hub) + return; + + dev_set_drvdata (&intf->dev, NULL); + 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); +} + +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 @@ static void *hub_probe(struct usb_device *dev, unsigned int i, != 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 @@ static void *hub_probe(struct usb_device *dev, unsigned int i, 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,65 +534,17 @@ static void *hub_probe(struct usb_device *dev, unsigned int i, list_add(&hub->hub_list, &hub_list); spin_unlock_irqrestore(&hub_event_lock, flags); + dev_set_drvdata (&intf->dev, 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); - /* free hub, but first clean up its list. */ - 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); - - 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); + hub_disconnect (intf); + return -ENODEV; } static int hub_ioctl(struct usb_device *hub, unsigned int code, void *user_data) @@ -584,7 +581,7 @@ static int hub_ioctl(struct usb_device *hub, unsigned int code, void *user_data) 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 +793,7 @@ static int usb_hub_port_debounce(struct usb_device *hub, int port) 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 +888,10 @@ static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port, /* 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.parent->parent; /* 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 +936,7 @@ static void usb_hub_events(void) 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 +1077,8 @@ MODULE_DEVICE_TABLE (usb, hub_id_table); 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 --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index 6b7a18e8f378..c7a976e561ac 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h @@ -170,7 +170,7 @@ struct usb_tt_clear { 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_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 --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index bea3ad76d840..e11e53190a9c 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -48,225 +48,139 @@ extern void usb_hub_cleanup(void); 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); - - /* Add it to the list of known drivers */ - list_add_tail(&new_driver->driver_list, &usb_driver_list); + return 0; +} +static int generic_remove (struct device *dev) +{ + return 0; +} +static void generic_release (struct device_driver * drv) +{ +} - usb_scan_devices(); +static struct device_driver usb_generic_driver = { + .name = "generic usb driver", + .probe = generic_probe, + .remove = generic_remove, + .release = generic_release, +}; + +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. + * usb_register - register a USB driver + * @new_driver: USB operations for the driver * - * 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. + * 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; i<USB_MAXCHILDREN; i++) - if (dev->children[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 +196,9 @@ static void usb_drivers_purge(struct usb_driver *driver,struct usb_device *dev) */ 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 +257,6 @@ struct usb_endpoint_descriptor *usb_epnum_to_ep_desc(struct usb_device *dev, uns 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; i<USB_MAXCHILDREN; i++) - if (dev->children[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 @@ -418,7 +288,7 @@ void usb_driver_claim_interface(struct usb_driver *driver, struct usb_interface iface->driver = driver; iface->private_data = priv; -} /* usb_driver_claim_interface() */ +} /** * usb_interface_claimed - returns true iff an interface is claimed @@ -463,7 +333,6 @@ void usb_driver_release_interface(struct usb_driver *driver, struct usb_interfac iface->private_data = NULL; } - /** * usb_match_id - find first usb_device_id matching device or interface * @interface: the interface of interest @@ -595,72 +464,25 @@ usb_match_id(struct usb_interface *interface, const struct usb_device_id *id) 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); - - if (usb_interface_claimed(interface)) - goto out_err; - - 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); + struct usb_interface *intf; + struct usb_driver *usb_drv; + const struct usb_device_id *id; - /* probe() may have changed the config on us */ - interface = dev->actconfig->interface + ifnum; + intf = to_usb_interface(dev); - 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 +712,6 @@ show_serial (struct device *dev, char *buf, size_t count, loff_t off) } 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 +866,21 @@ void usb_disconnect(struct usb_device **pdev) 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 +889,9 @@ void usb_disconnect(struct usb_device **pdev) 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 +1020,7 @@ static void set_device_description (struct usb_device *dev) */ #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 +1110,23 @@ int usb_new_device(struct usb_device *dev) 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; + 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 +1135,38 @@ int usb_new_device(struct usb_device *dev) 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; - /* find drivers willing to handle this device */ - usb_find_drivers(dev); + interface->dev.parent = &dev->dev; + interface->dev.bus = &usb_bus_type; + 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); + } + + /* add a /proc/bus/usb entry */ + usbfs_add_device(dev); /* userspace may load modules and/or configure further */ call_policy ("add", dev); @@ -1385,7 +1174,6 @@ int usb_new_device(struct usb_device *dev) return 0; } - /** * usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_DMA_MAP * @dev: device the buffer will be used with @@ -1531,7 +1319,6 @@ void usb_buffer_unmap (struct urb *urb) ? 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 +1429,10 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe, : 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 +1471,9 @@ EXPORT_SYMBOL(usb_epnum_to_ep_desc); 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 --git a/drivers/usb/image/hpusbscsi.c b/drivers/usb/image/hpusbscsi.c index 1782109ebeb0..8260ab224581 100644 --- a/drivers/usb/image/hpusbscsi.c +++ b/drivers/usb/image/hpusbscsi.c @@ -30,13 +30,14 @@ struct list_head hpusbscsi_devices; /* 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 @@ hpusbscsi_usb_probe (struct usb_device *dev, unsigned int interface, if (altsetting->bNumEndpoints != 3) { printk (KERN_ERR "Wrong number of endpoints\n"); - return NULL; + return -ENODEV; } /* descriptor allocation */ @@ -53,19 +54,19 @@ hpusbscsi_usb_probe (struct usb_device *dev, unsigned int interface, (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 @@ hpusbscsi_usb_probe (struct usb_device *dev, unsigned int interface, /* 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 --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index 662dba287d3d..12aafe9b9eb7 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c @@ -406,11 +406,12 @@ static struct file_operations mdc800_device_ops; /* * 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 @@ static void* mdc800_usb_probe (struct usb_device *dev ,unsigned int ifnum, 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 @@ static void* mdc800_usb_probe (struct usb_device *dev ,unsigned int ifnum, ) { err ("probe fails -> wrong Interface"); - return 0; + return -ENODEV; } /* Check the Endpoints */ @@ -461,16 +462,16 @@ static void* mdc800_usb_probe (struct usb_device *dev ,unsigned int ifnum, 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 @@ static void* mdc800_usb_probe (struct usb_device *dev ,unsigned int ifnum, 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 @@ static void* mdc800_usb_probe (struct usb_device *dev ,unsigned int ifnum, 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; - mdc800->state=NOT_CONNECTED; + usb_deregister_dev (1, mdc800->minor); - usb_unlink_urb (mdc800->irq_urb); - usb_unlink_urb (mdc800->write_urb); - usb_unlink_urb (mdc800->download_urb); + mdc800->state=NOT_CONNECTED; - usb_driver_release_interface (&mdc800_usb_driver, &dev->actconfig->interface[1]); + usb_unlink_urb (mdc800->irq_urb); + usb_unlink_urb (mdc800->write_urb); + usb_unlink_urb (mdc800->download_urb); - mdc800->dev=0; + usb_driver_release_interface (&mdc800_usb_driver, intf); + + mdc800->dev=0; + dev_set_drvdata(&intf->dev, NULL); + } info ("Mustek MDC800 disconnected from USB."); } diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 2a49b94b48d1..3189dffdb781 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c @@ -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 []; @@ -773,18 +773,21 @@ static Scsi_Host_Template mts_scsi_host_template = { /* 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 @@ -834,8 +837,8 @@ static struct usb_device_id mts_usb_ids [] = 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; @@ -846,6 +849,7 @@ static void * mts_usb_probe (struct usb_device *dev, unsigned int interface, 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; @@ -869,8 +873,7 @@ static void * mts_usb_probe (struct usb_device *dev, unsigned int interface, 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 */ @@ -878,7 +881,7 @@ static void * mts_usb_probe (struct usb_device *dev, unsigned int interface, 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++ ) { @@ -896,7 +899,7 @@ static void * mts_usb_probe (struct usb_device *dev, unsigned int interface, 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 & @@ -909,7 +912,7 @@ static void * mts_usb_probe (struct usb_device *dev, unsigned int interface, if ( ep_out == -1 ) { MTS_WARNING( "couldn't find an output bulk endpoint. Bailing out.\n" ); - return NULL; + return -ENODEV; } @@ -932,7 +935,7 @@ static void * mts_usb_probe (struct usb_device *dev, unsigned int interface, default: MTS_DEBUG( "unknown error %d from usb_set_interface\n", (int)result ); - return NULL; + return -ENODEV; } @@ -941,19 +944,18 @@ static void * mts_usb_probe (struct usb_device *dev, unsigned int interface, 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); @@ -1000,7 +1002,7 @@ static void * mts_usb_probe (struct usb_device *dev, unsigned int interface, /* FIXME: need more cleanup? */ kfree( new_desc ); - return NULL; + return -ENOMEM; } MTS_DEBUG_GOT_HERE(); @@ -1015,7 +1017,8 @@ static void * mts_usb_probe (struct usb_device *dev, unsigned int interface, MTS_DEBUG("completed probe and exiting happily\n"); - return (void *)new_desc; + dev_set_drvdata(&intf->dev, new_desc); + return 0; } diff --git a/drivers/usb/image/microtek.h b/drivers/usb/image/microtek.h index 7ab7cb3f2062..1dd70640c63b 100644 --- a/drivers/usb/image/microtek.h +++ b/drivers/usb/image/microtek.h @@ -33,8 +33,6 @@ struct mts_desc { struct usb_device *usb_dev; - int interface; - /* Endpoint addresses */ u8 ep_out; u8 ep_response; diff --git a/drivers/usb/image/scanner.c b/drivers/usb/image/scanner.c index f1248f7a3f07..81ec275403bc 100644 --- a/drivers/usb/image/scanner.c +++ b/drivers/usb/image/scanner.c @@ -818,10 +818,11 @@ file_operations usb_scanner_fops = { .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 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum, 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 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum, 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 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum, 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 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum, 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 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum, 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 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum, 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 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum, 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 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum, if (!scn->scn_irq) { kfree(scn); up(&scn_mutex); - return NULL; + return -ENOMEM; } init_MUTEX(&(scn->sem)); /* Initializes to unlocked */ @@ -1018,7 +1019,7 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum, err("probe_scanner(%d): Unable to allocate INT URB.", scn_minor); kfree(scn); up(&scn_mutex); - return NULL; + return -ENOMEM; } } @@ -1028,7 +1029,7 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum, 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 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum, 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 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum, 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); + 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); } - 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); } +/* 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 --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c index fd52d89ea1a9..adf717945866 100644 --- a/drivers/usb/input/aiptek.c +++ b/drivers/usb/input/aiptek.c @@ -204,6 +204,11 @@ aiptek_close(struct input_dev *dev) 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 @@ aiptek_command(struct usb_device *dev, unsigned int ifnum, 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_probe(struct usb_device *dev, unsigned int ifnum, 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 @@ aiptek_probe(struct usb_device *dev, unsigned int ifnum, 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 --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index c1c4bfd580b2..6dd0b31ab5d9 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1349,9 +1349,10 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) 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 @@ static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum) 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,10 +1500,14 @@ fail: 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 = dev_get_drvdata(&intf->dev); + if (!hid) + return; + + dev_set_drvdata (&intf->dev, NULL); usb_unlink_urb(hid->urbin); usb_unlink_urb(hid->urbout); usb_unlink_urb(hid->urbctrl); @@ -1517,22 +1522,21 @@ static void hid_disconnect(struct usb_device *dev, void *ptr) if (hid->urbout) usb_free_urb(hid->urbout); - hid_free_buffers(dev, hid); + hid_free_buffers(hid->dev, hid); hid_free_device(hid); } -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 @@ static void* hid_probe(struct usb_device *dev, unsigned int ifnum, if (!hiddev_connect(hid)) hid->claimed |= HID_CLAIMED_HIDDEV; + dev_set_drvdata(&intf->dev, hid); + if (!hid->claimed) { - hid_disconnect(dev, hid); - return NULL; + hid_disconnect(intf); + return -EIO; } printk(KERN_INFO); @@ -1568,12 +1574,12 @@ static void* hid_probe(struct usb_device *dev, unsigned int ifnum, } } - 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 --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c index c750b27252ec..8d52544ed32e 100644 --- a/drivers/usb/input/hiddev.c +++ b/drivers/usb/input/hiddev.c @@ -751,10 +751,10 @@ void hiddev_disconnect(struct hid_device *hid) /* 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 --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c index 4589679cf9bb..72d7c683bef0 100644 --- a/drivers/usb/input/powermate.c +++ b/drivers/usb/input/powermate.c @@ -268,18 +268,21 @@ static void powermate_free_buffers(struct usb_device *udev, struct powermate_dev } /* 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 @@ static void *powermate_probe(struct usb_device *udev, unsigned int ifnum, const 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 @@ static void *powermate_probe(struct usb_device *udev, unsigned int ifnum, const 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 @@ static void *powermate_probe(struct usb_device *udev, unsigned int ifnum, const usb_free_urb(pm->irq); powermate_free_buffers(udev, pm); kfree(pm); - return NULL; + return -ENOMEM; } init_MUTEX(&pm->lock); @@ -333,7 +336,7 @@ static void *powermate_probe(struct usb_device *udev, unsigned int ifnum, const 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 @@ static void *powermate_probe(struct usb_device *udev, unsigned int ifnum, const 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 --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c index 4fc1de730e53..1fc8de46f6f1 100644 --- a/drivers/usb/input/usbkbd.c +++ b/drivers/usb/input/usbkbd.c @@ -207,10 +207,10 @@ static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd) usb_buffer_free(dev, 1, kbd->leds, kbd->leds_dma); } -static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id) +static int usb_kbd_probe(struct usb_interface *iface, + const struct usb_device_id *id) { - struct usb_interface *iface; + struct usb_device * dev = interface_to_usbdev(iface); struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; struct usb_kbd *kbd; @@ -218,25 +218,28 @@ static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum, char path[64]; char *buf; - iface = &dev->actconfig->interface[ifnum]; interface = &iface->altsetting[iface->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 (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) return NULL; + if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) + return -ENOMEM; memset(kbd, 0, sizeof(struct usb_kbd)); if (usb_kbd_alloc_mem(dev, kbd)) { usb_kbd_free_mem(dev, kbd); kfree(kbd); - return NULL; + return -ENOMEM; } kbd->usbdev = dev; @@ -279,7 +282,7 @@ static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum, usb_free_urb(kbd->irq); usb_kbd_free_buffers(dev, kbd); kfree(kbd); - return NULL; + return -ENOMEM; } if (dev->descriptor.iManufacturer && @@ -306,16 +309,21 @@ static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum, printk(KERN_INFO "input: %s on %s\n", kbd->name, path); - return kbd; + dev_set_drvdata(&iface->dev, kbd); + return 0; } -static void usb_kbd_disconnect(struct usb_device *dev, void *ptr) +static void usb_kbd_disconnect(struct usb_interface *intf) { - struct usb_kbd *kbd = ptr; - usb_unlink_urb(kbd->irq); - input_unregister_device(&kbd->dev); - usb_kbd_free_buffers(dev, kbd); - kfree(kbd); + struct usb_kbd *kbd = dev_get_drvdata(&intf->dev); + + dev_set_drvdata(&intf->dev, NULL); + if (kbd) { + usb_unlink_urb(kbd->irq); + input_unregister_device(&kbd->dev); + usb_kbd_free_buffers(interface_to_usbdev(intf), kbd); + kfree(kbd); + } } static struct usb_device_id usb_kbd_id_table [] = { diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c index a39ea5ff34aa..f73e962a0971 100644 --- a/drivers/usb/input/usbmouse.c +++ b/drivers/usb/input/usbmouse.c @@ -100,10 +100,9 @@ static void usb_mouse_close(struct input_dev *dev) 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,32 +110,35 @@ static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum, 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); if (!mouse->data) { kfree(mouse); - return NULL; + return -ENOMEM; } mouse->irq = usb_alloc_urb(0, GFP_KERNEL); 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 @@ static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum, 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 @@ static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum, 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; + dev_set_drvdata(&intf->dev, 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 = dev_get_drvdata(&intf->dev); + + dev_set_drvdata(&intf->dev, NULL); + if (mouse) { + usb_unlink_urb(mouse->irq); + input_unregister_device(&mouse->dev); + usb_free_urb(mouse->irq); + usb_buffer_free(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma); + kfree(mouse); + } } static struct usb_device_id usb_mouse_id_table [] = { @@ -211,10 +217,10 @@ static struct usb_device_id usb_mouse_id_table [] = { 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 --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c index 7152389d7aa3..e0f43e7605f6 100644 --- a/drivers/usb/input/wacom.c +++ b/drivers/usb/input/wacom.c @@ -356,26 +356,28 @@ static void wacom_close(struct input_dev *dev) 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 @@ static void *wacom_probe(struct usb_device *dev, unsigned int ifnum, const struc 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 @@ static void *wacom_probe(struct usb_device *dev, unsigned int ifnum, const struc 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 --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index 70e80cadd920..b16abee76e88 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c @@ -195,8 +195,9 @@ static void xpad_close (struct input_dev *dev) 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 @@ static void * xpad_probe(struct usb_device *udev, unsigned int ifnum, const stru 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 @@ static void * xpad_probe(struct usb_device *udev, unsigned int ifnum, const stru 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 @@ static void * xpad_probe(struct usb_device *udev, unsigned int ifnum, const stru 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 @@ static void * xpad_probe(struct usb_device *udev, unsigned int ifnum, const stru 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 --git a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c index 01d02450bc0a..eaa447b2cfaf 100644 --- a/drivers/usb/media/dabusb.c +++ b/drivers/usb/media/dabusb.c @@ -713,9 +713,10 @@ static struct file_operations dabusb_fops = }; /* --------------------------------------------------------------------- */ -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 @@ static void *dabusb_probe (struct usb_device *usbdev, unsigned int ifnum, /* 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 @@ static void *dabusb_probe (struct usb_device *usbdev, unsigned int ifnum, 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 --git a/drivers/usb/media/dsbr100.c b/drivers/usb/media/dsbr100.c index ddaef26aa8eb..d958641579d5 100644 --- a/drivers/usb/media/dsbr100.c +++ b/drivers/usb/media/dsbr100.c @@ -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 @@ typedef struct unsigned char transfer_buffer[TB_LEN]; int curfreq; int stereo; - int ifnum; } usb_dsbr100; @@ -181,32 +180,36 @@ static void dsbr100_getstat(usb_dsbr100 *radio) } -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); + + dev_set_drvdata (&intf->dev, NULL); - lock_kernel(); - if (users) { + 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 --git a/drivers/usb/media/ibmcam.c b/drivers/usb/media/ibmcam.c index 1ab348355ec9..74b1c5303374 100644 --- a/drivers/usb/media/ibmcam.c +++ b/drivers/usb/media/ibmcam.c @@ -3656,39 +3656,41 @@ static void ibmcam_configure_video(struct uvd *uvd) * 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 @@ static void *ibmcam_probe(struct usb_device *dev, unsigned int ifnum, const stru 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 @@ static void *ibmcam_probe(struct usb_device *dev, unsigned int ifnum, const stru 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 @@ static void *ibmcam_probe(struct usb_device *dev, unsigned int ifnum, const stru 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 @@ static void *ibmcam_probe(struct usb_device *dev, unsigned int ifnum, const stru } if ((maxPS <= 0) || (actInterface < 0) || (inactInterface < 0)) { err("Failed to recognize the camera!"); - return NULL; + return -ENODEV; } /* Validate options */ @@ -3861,7 +3863,7 @@ static void *ibmcam_probe(struct usb_device *dev, unsigned int ifnum, const stru 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 @@ static void *ibmcam_probe(struct usb_device *dev, unsigned int ifnum, const stru } } MOD_DEC_USE_COUNT; - return uvd; + dev_set_drvdata (&intf->dev, uvd); + return 0; } diff --git a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c index 3a81d5f17485..89825b4ff9f7 100644 --- a/drivers/usb/media/konicawc.c +++ b/drivers/usb/media/konicawc.c @@ -717,38 +717,40 @@ static void konicawc_configure_video(struct uvd *uvd) } -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 @@ static void *konicawc_probe(struct usb_device *dev, unsigned int ifnum, const st 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 @@ static void *konicawc_probe(struct usb_device *dev, unsigned int ifnum, const st } 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 @@ static void *konicawc_probe(struct usb_device *dev, unsigned int ifnum, const st usb_free_urb(cam->sts_urb[i]); } err("cant allocate urbs"); - return NULL; + return -ENOMEM; } } cam->speed = speed; @@ -815,7 +819,7 @@ static void *konicawc_probe(struct usb_device *dev, unsigned int ifnum, const st 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 @@ static void *konicawc_probe(struct usb_device *dev, unsigned int ifnum, const st #endif } MOD_DEC_USE_COUNT; - return uvd; + + if (uvd) { + dev_set_drvdata (&intf->dev, uvd); + return 0; + } + return -EIO; } diff --git a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c index 9dff57ad4f38..f968afc3d5c6 100644 --- a/drivers/usb/media/ov511.c +++ b/drivers/usb/media/ov511.c @@ -60,9 +60,9 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.61 for Linux 2.5" -#define EMAIL "mmcclell@bigfoot.com" -#define DRIVER_AUTHOR "Mark McClelland <mmcclell@bigfoot.com> & Bret Wallach \ +#define DRIVER_VERSION "v1.62 for Linux 2.5" +#define EMAIL "mark@alpha.dyndns.org" +#define DRIVER_AUTHOR "Mark McClelland <mark@alpha.dyndns.org> & Bret Wallach \ & Orion Sky Lawlor <olawlor@acm.org> & Kevin Moore & Charl P. Botha \ <cpbotha@ieee.org> & Claudio Matsuoka <claudio@conectiva.com>" #define DRIVER_DESC "ov511 USB Camera Driver" @@ -97,7 +97,6 @@ static int snapshot; static int cams = 1; static int compress; static int testpat; -static int sensor_gbr; static int dumppix; static int led = 1; static int dump_bridge; @@ -113,16 +112,9 @@ static int qvy = 0x04; static int qvuv = 0x04; static int lightfreq; static int bandingfilter; - -/* Pixel clock divisor */ static int clockdiv = -1; - -/* Isoc packet size */ static int packetsize = -1; - -/* Frame drop register (16h) */ static int framedrop = -1; - static int fastset; static int force_palette; static int backlight; @@ -268,6 +260,7 @@ static struct symbolic_list camlist[] = { { 102, "AverMedia InterCam Elite" }, { 112, "MediaForte MV300" }, /* or OV7110 evaluation kit */ { 192, "Webeye 2000B" }, + { 253, "Alpha Vision Tech. AlphaCam SE" }, { -1, NULL } }; @@ -558,8 +551,8 @@ create_proc_ov511_cam(struct usb_ov511 *ov) ov511_read_proc_button, ov); if (!ov->proc_button) return; + ov->proc_button->owner = THIS_MODULE; } - ov->proc_button->owner = THIS_MODULE; /* Create "control" entry (ioctl() interface) */ PDEBUG(4, "creating /proc/video/ov511/%s/control", dirname); @@ -1137,8 +1130,6 @@ i2c_set_slave_internal(struct usb_ov511 *ov, unsigned char slave) return 0; } -#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) - /* Write to a specific I2C slave ID and register, using the specified mask */ static int i2c_w_slave(struct usb_ov511 *ov, @@ -1194,8 +1185,6 @@ out: return rc; } -#endif /* defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) */ - /* Sets I2C read and write slave IDs. Returns <0 for error */ static int ov51x_set_slave_ids(struct usb_ov511 *ov, unsigned char sid) @@ -1241,8 +1230,7 @@ write_regvals(struct usb_ov511 *ov, struct ov511_regvals * pRegvals) static void dump_i2c_range(struct usb_ov511 *ov, int reg1, int regn) { - int i; - int rc; + int i, rc; for (i = reg1; i <= regn; i++) { rc = i2c_r(ov, i); @@ -1260,8 +1248,7 @@ dump_i2c_regs(struct usb_ov511 *ov) static void dump_reg_range(struct usb_ov511 *ov, int reg1, int regn) { - int i; - int rc; + int i, rc; for (i = reg1; i <= regn; i++) { rc = reg_r(ov, i); @@ -1269,7 +1256,6 @@ dump_reg_range(struct usb_ov511 *ov, int reg1, int regn) } } -/* FIXME: Should there be an OV518 version of this? */ static void ov511_dump_regs(struct usb_ov511 *ov) { @@ -1295,6 +1281,31 @@ ov511_dump_regs(struct usb_ov511 *ov) dump_reg_range(ov, 0xa0, 0xbf); } + +static void +ov518_dump_regs(struct usb_ov511 *ov) +{ + info("VIDEO MODE REGS"); + dump_reg_range(ov, 0x20, 0x2f); + info("DATA PUMP AND SNAPSHOT REGS"); + dump_reg_range(ov, 0x30, 0x3f); + info("I2C REGS"); + dump_reg_range(ov, 0x40, 0x4f); + info("SYSTEM CONTROL AND VENDOR REGS"); + dump_reg_range(ov, 0x50, 0x5f); + info("60 - 6F"); + dump_reg_range(ov, 0x60, 0x6f); + info("70 - 7F"); + dump_reg_range(ov, 0x70, 0x7f); + info("Y QUANTIZATION TABLE"); + dump_reg_range(ov, 0x80, 0x8f); + info("UV QUANTIZATION TABLE"); + dump_reg_range(ov, 0x90, 0x9f); + info("A0 - BF"); + dump_reg_range(ov, 0xa0, 0xbf); + info("CBR"); + dump_reg_range(ov, 0xc0, 0xcf); +} #endif /*****************************************************************************/ @@ -1336,9 +1347,9 @@ static void ov51x_clear_snapshot(struct usb_ov511 *ov) { if (ov->bclass == BCL_OV511) { - reg_w(ov, R51x_SYS_SNAP, 0x01); - reg_w(ov, R51x_SYS_SNAP, 0x03); - reg_w(ov, R51x_SYS_SNAP, 0x01); + reg_w(ov, R51x_SYS_SNAP, 0x00); + reg_w(ov, R51x_SYS_SNAP, 0x02); + reg_w(ov, R51x_SYS_SNAP, 0x00); } else if (ov->bclass == BCL_OV518) { warn("snapshot reset not supported yet on OV518(+)"); } else { @@ -1383,7 +1394,7 @@ init_ov_sensor(struct usb_ov511 *ov) if (i2c_w(ov, 0x12, 0x80) < 0) return -EIO; /* Wait for it to initialize */ - schedule_timeout (1 + 150 * HZ / 1000); + schedule_timeout(1 + 150 * HZ / 1000); for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) { if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) && @@ -2018,10 +2029,6 @@ sensor_get_picture(struct usb_ov511 *ov, struct video_picture *p) p->whiteness = 105 << 8; - /* Can we get these from frame[0]? -claudio? */ - p->depth = ov->frame[0].depth; - p->palette = ov->frame[0].format; - return 0; } @@ -2424,9 +2431,10 @@ mode_init_ov_sensor_regs(struct usb_ov511 *ov, int width, int height, #endif break; case SEN_OV6620: - case SEN_OV6630: i2c_w(ov, 0x14, qvga?0x24:0x04); - /* No special settings yet */ + break; + case SEN_OV6630: + i2c_w(ov, 0x14, qvga?0xa4:0x84); break; default: err("Invalid sensor"); @@ -2504,19 +2512,11 @@ mode_init_ov_sensor_regs(struct usb_ov511 *ov, int width, int height, if (framedrop >= 0) i2c_w(ov, 0x16, framedrop); - if (sensor_gbr) - i2c_w_mask(ov, 0x12, 0x08, 0x08); - else - i2c_w_mask(ov, 0x12, 0x00, 0x08); - /* Test Pattern */ i2c_w_mask(ov, 0x12, (testpat?0x02:0x00), 0x02); - /* Auto white balance */ -// if (awb) - i2c_w_mask(ov, 0x12, 0x04, 0x04); -// else -// i2c_w_mask(ov, 0x12, 0x00, 0x04); + /* Enable auto white balance */ + i2c_w_mask(ov, 0x12, 0x04, 0x04); // This will go away as soon as ov51x_mode_init_sensor_regs() // is fully tested. @@ -2705,7 +2705,7 @@ ov511_mode_init_regs(struct usb_ov511 *ov, reg_w(ov, R511_CAM_PXDIV, 0x00); reg_w(ov, R511_CAM_LNDIV, 0x00); - /* YUV420, low pass filer on */ + /* YUV420, low pass filter on */ reg_w(ov, R511_CAM_OPTS, 0x03); /* Snapshot additions */ @@ -4120,11 +4120,6 @@ ov51x_alloc(struct usb_ov511 *ov) PDEBUG(4, "entered"); down(&ov->buf_lock); - if (ov->buf_state == BUF_PEND_DEALLOC) { - ov->buf_state = BUF_ALLOCATED; - del_timer(&ov->buf_timer); - } - if (ov->buf_state == BUF_ALLOCATED) goto out; @@ -4394,6 +4389,10 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file, if (sensor_get_picture(ov, p)) return -EIO; + /* Can we get these from frame[0]? -claudio? */ + p->depth = ov->frame[0].depth; + p->palette = ov->frame[0].format; + return 0; } case VIDIOCSPICT: @@ -4558,8 +4557,8 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file, depth = get_depth(vm->format); if (!depth) { - err("VIDIOCMCAPTURE: invalid format (%s)", - symbolic(v4l1_plist, vm->format)); + PDEBUG(2, "VIDIOCMCAPTURE: invalid format (%s)", + symbolic(v4l1_plist, vm->format)); return -EINVAL; } @@ -4580,8 +4579,8 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file, } if (force_palette && (vm->format != force_palette)) { - info("palette rejected (%s)", - symbolic(v4l1_plist, vm->format)); + PDEBUG(2, "palette rejected (%s)", + symbolic(v4l1_plist, vm->format)); return -EINVAL; } @@ -4710,6 +4709,24 @@ redo: return 0; } + case OV511IOC_WI2C: + { + struct ov511_i2c_struct *w = arg; + + return i2c_w_slave(ov, w->slave, w->reg, w->value, w->mask); + } + case OV511IOC_RI2C: + { + struct ov511_i2c_struct *r = arg; + int rc; + + rc = i2c_r_slave(ov, r->slave, r->reg); + if (rc < 0) + return rc; + + r->value = rc; + return 0; + } default: PDEBUG(3, "Unsupported IOCtl: 0x%X", cmd); return -ENOIOCTLCMD; @@ -4934,11 +4951,11 @@ ov51x_v4l1_mmap(struct file *file, struct vm_area_struct *vma) static struct file_operations ov511_fops = { .owner = THIS_MODULE, .open = ov51x_v4l1_open, - .release = ov51x_v4l1_close, + .release = ov51x_v4l1_close, .read = ov51x_v4l1_read, .mmap = ov51x_v4l1_mmap, - .ioctl = ov51x_v4l1_ioctl, - .llseek = no_llseek, + .ioctl = ov51x_v4l1_ioctl, + .llseek = no_llseek, }; static struct video_device vdev_template = { @@ -4946,7 +4963,7 @@ static struct video_device vdev_template = { .name = "OV511 USB Camera", .type = VID_TYPE_CAPTURE, .hardware = VID_HARDWARE_OV511, - .fops = &ov511_fops, + .fops = &ov511_fops, }; #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) @@ -5136,8 +5153,7 @@ ov51x_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd, if (copy_from_user(&w, arg, sizeof(w))) return -EFAULT; - return i2c_w_slave(ov, w.slave, w.reg, w.value, - w.mask); + return i2c_w_slave(ov, w.slave, w.reg, w.value, w.mask); } case OV511IOC_RI2C: { @@ -5343,17 +5359,16 @@ ov7xx0_configure(struct usb_ov511 *ov) ov->sensor = SEN_OV7610; } else if ((rc & 3) == 1) { /* I don't know what's different about the 76BE yet. */ - if (i2c_r(ov, 0x15) & 1) { + if (i2c_r(ov, 0x15) & 1) info("Sensor is an OV7620AE"); - } else { + else info("Sensor is an OV76BE"); - } /* OV511+ will return all zero isoc data unless we * configure the sensor as a 7620. Someone needs to * find the exact reg. setting that causes this. */ if (ov->bridge == BRG_OV511PLUS) { - info("Enabling 511+/76BE workaround"); + info("Enabling 511+/7620AE workaround"); ov->sensor = SEN_OV7620; } else { ov->sensor = SEN_OV76BE; @@ -5745,9 +5760,9 @@ ov511_configure(struct usb_ov511 *ov) static struct ov511_regvals aRegvalsNorm511[] = { { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0x01 }, - { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 }, - { OV511_REG_BUS, R51x_SYS_SNAP, 0x03 }, - { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 }, + { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 }, + { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, + { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 }, { OV511_REG_BUS, R511_FIFO_OPTS, 0x1f }, { OV511_REG_BUS, R511_COMP_EN, 0x00 }, { OV511_REG_BUS, R511_COMP_LUT_EN, 0x03 }, @@ -5756,9 +5771,9 @@ ov511_configure(struct usb_ov511 *ov) static struct ov511_regvals aRegvalsNorm511Plus[] = { { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0xff }, - { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 }, - { OV511_REG_BUS, R51x_SYS_SNAP, 0x03 }, - { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 }, + { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 }, + { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, + { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 }, { OV511_REG_BUS, R511_FIFO_OPTS, 0xff }, { OV511_REG_BUS, R511_COMP_EN, 0x00 }, { OV511_REG_BUS, R511_COMP_LUT_EN, 0x03 }, @@ -5970,11 +5985,20 @@ ov518_configure(struct usb_ov511 *ov) if (ov518_init_compression(ov)) goto error; - /* OV518+ has packet numbering turned on by default */ if (ov->bridge == BRG_OV518) - ov->packet_numbering = 0; - else + { + struct usb_interface *ifp = &ov->dev->config[0].interface[0]; + __u16 mxps = ifp->altsetting[7].endpoint[0].wMaxPacketSize; + + /* Some OV518s have packet numbering by default, some don't */ + if (mxps == 897) + ov->packet_numbering = 1; + else + ov->packet_numbering = 0; + } else { + /* OV518+ has packet numbering turned on by default */ ov->packet_numbering = 1; + } ov518_set_packet_size(ov, 0); @@ -6043,10 +6067,11 @@ error: * ***************************************************************************/ -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 +6081,15 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum, /* 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"); @@ -6126,7 +6151,8 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum, ov->buf_state = BUF_NOT_ALLOCATED; - /* Must be kmalloc()'ed, for DMA accessibility */ + /* Allocate control transfer buffer. */ + /* Must be kmalloc()'ed, for DMA compatibility */ ov->cbuf = kmalloc(OV511_CBUF_SIZE, GFP_KERNEL); if (!ov->cbuf) goto error; @@ -6156,8 +6182,12 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum, goto error; #ifdef OV511_DEBUG - if (dump_bridge) - ov511_dump_regs(ov); + if (dump_bridge) { + if (ov->bclass == BCL_OV511) + ov511_dump_regs(ov); + else + ov518_dump_regs(ov); + } #endif memcpy(&ov->vdev, &vdev_template, sizeof(vdev_template)); @@ -6188,7 +6218,8 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum, 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 +6242,21 @@ error_dealloc: 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"); @@ -6259,12 +6294,14 @@ ov51x_disconnect(struct usb_device *dev, void *ptr) kfree(ov); ov = NULL; } + + PDEBUG(3, "Disconnect complete"); } static struct usb_driver ov511_driver = { .owner = THIS_MODULE, .name = "ov511", - .id_table = device_table, + .id_table = device_table, .probe = ov51x_probe, .disconnect = ov51x_disconnect }; diff --git a/drivers/usb/media/ov511.h b/drivers/usb/media/ov511.h index 20e4011b1794..9fa16de5bb31 100644 --- a/drivers/usb/media/ov511.h +++ b/drivers/usb/media/ov511.h @@ -286,21 +286,6 @@ enum { SEN_SAA7111A, }; -// Not implemented yet -#if 0 -/* Sensor classes */ -enum { - SCL_UNKNOWN, - SCL_OV7610, /* 7610, 76BE, 7620AE (for now) */ - SCL_OV7620, - SCL_OV6620, - SCL_OV6630, /* 6630, 6630AE, 6630AF */ - SCL_OV8600, - SCL_KS0127, /* SEN_KS0127, SEN_KS0127B */ - SCL_SAA7111A, -}; -#endif - enum { STATE_SCANNING, /* Scanning for start */ STATE_HEADER, /* Parsing header */ @@ -311,7 +296,6 @@ enum { enum { BUF_NOT_ALLOCATED, BUF_ALLOCATED, - BUF_PEND_DEALLOC, /* ov511->buf_timer is set */ }; /* --------- Definition of ioctl interface --------- */ @@ -521,7 +505,6 @@ struct usb_ov511 { int bridge; /* Type of bridge (BRG_*) */ int bclass; /* Class of bridge (BCL_*) */ int sensor; /* Type of image sensor chip (SEN_*) */ - int sclass; /* Type of image sensor chip (SCL_*) */ int packet_size; /* Frame size per isoc desc */ int packet_numbering; /* Is ISO frame numbering enabled? */ @@ -537,7 +520,6 @@ struct usb_ov511 { /* Framebuffer/sbuf management */ int buf_state; struct semaphore buf_lock; - struct timer_list buf_timer; struct ov51x_decomp_ops *decomp_ops; diff --git a/drivers/usb/media/pwc-if.c b/drivers/usb/media/pwc-if.c index 72d110a78f05..3f871469997e 100644 --- a/drivers/usb/media/pwc-if.c +++ b/drivers/usb/media/pwc-if.c @@ -86,8 +86,8 @@ static struct usb_device_id pwc_device_table [] = { }; 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 @@ static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) * 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 @@ static void *usb_pwc_probe(struct usb_device *udev, unsigned int ifnum, const st 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 @@ static void *usb_pwc_probe(struct usb_device *udev, unsigned int ifnum, const st type_id = 750; break; default: - return NULL; + return -ENODEV; break; } } @@ -1613,7 +1614,7 @@ static void *usb_pwc_probe(struct usb_device *udev, unsigned int ifnum, const st type_id = 645; break; default: - return NULL; + return -ENODEV; break; } } @@ -1624,7 +1625,7 @@ static void *usb_pwc_probe(struct usb_device *udev, unsigned int ifnum, const st type_id = 730; break; default: - return NULL; + return -ENODEV; break; } } @@ -1643,7 +1644,7 @@ static void *usb_pwc_probe(struct usb_device *udev, unsigned int ifnum, const st type_id = 675; break; default: - return NULL; + return -ENODEV; break; } } @@ -1654,7 +1655,7 @@ static void *usb_pwc_probe(struct usb_device *udev, unsigned int ifnum, const st type_id = 730; break; default: - return NULL; + return -ENODEV; break; } } @@ -1665,11 +1666,11 @@ static void *usb_pwc_probe(struct usb_device *udev, unsigned int ifnum, const st 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 @@ static void *usb_pwc_probe(struct usb_device *udev, unsigned int ifnum, const st 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 @@ static void *usb_pwc_probe(struct usb_device *udev, unsigned int ifnum, const st 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 @@ static void *usb_pwc_probe(struct usb_device *udev, unsigned int ifnum, const st 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 @@ static void *usb_pwc_probe(struct usb_device *udev, unsigned int ifnum, const st 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 @@ static void usb_pwc_disconnect(struct usb_device *udev, void *ptr) 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 @@ static void usb_pwc_disconnect(struct usb_device *udev, void *ptr) 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 --git a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c index 7fb881cbadc3..ce740510f3ab 100644 --- a/drivers/usb/media/se401.c +++ b/drivers/usb/media/se401.c @@ -1420,9 +1420,10 @@ static int se401_init(struct usb_se401 *se401, int button) return 0; } -static void* se401_probe(struct usb_device *dev, unsigned int ifnum, +static int se401_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_se401 *se401; char *camera_name=NULL; @@ -1430,9 +1431,9 @@ static void* se401_probe(struct usb_device *dev, unsigned int ifnum, /* 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]; /* Is it an se401? */ if (dev->descriptor.idVendor == 0x03e8 && @@ -1452,20 +1453,20 @@ static void* se401_probe(struct usb_device *dev, unsigned int ifnum, camera_name="Kensington VideoCAM 67016"; button=0; } else - return NULL; + return -ENODEV; /* Checking vendor/product should be enough, but what the hell */ if (interface->bInterfaceClass != 0x00) - return NULL; + return -ENODEV; if (interface->bInterfaceSubClass != 0x00) - return NULL; + return -ENODEV; /* We found one */ info("SE401 camera found: %s", camera_name); if ((se401 = kmalloc(sizeof(*se401), GFP_KERNEL)) == NULL) { err("couldn't kmalloc se401 struct"); - return NULL; + return -ENOMEM; } memset(se401, 0, sizeof(*se401)); @@ -1478,7 +1479,7 @@ static void* se401_probe(struct usb_device *dev, unsigned int ifnum, if (se401_init(se401, button)) { kfree(se401); - return NULL; + return -EIO; } memcpy(&se401->vdev, &se401_template, sizeof(se401_template)); @@ -1490,43 +1491,46 @@ static void* se401_probe(struct usb_device *dev, unsigned int ifnum, if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { kfree(se401); err("video_register_device failed"); - return NULL; + return -EIO; } #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) create_proc_se401_cam(se401); #endif info("registered new video device: video%d", se401->vdev.minor); - return se401; + dev_set_drvdata (&intf->dev, se401); + return 0; } -static void se401_disconnect(struct usb_device *dev, void *ptr) +static void se401_disconnect(struct usb_interface *intf) { - struct usb_se401 *se401 = (struct usb_se401 *) ptr; + struct usb_se401 *se401 = dev_get_drvdata (&intf->dev); - video_unregister_device(&se401->vdev); - if (!se401->user){ - usb_se401_remove_disconnected(se401); - } else { - se401->frame[0].grabstate = FRAME_ERROR; - se401->frame[0].grabstate = FRAME_ERROR; + dev_set_drvdata (&intf->dev, NULL); + if (se401) { + video_unregister_device(&se401->vdev); + if (!se401->user){ + usb_se401_remove_disconnected(se401); + } else { + se401->frame[0].grabstate = FRAME_ERROR; + se401->frame[0].grabstate = FRAME_ERROR; - se401->streaming = 0; - - wake_up_interruptible(&se401->wq); - se401->removed = 1; - } + se401->streaming = 0; + + wake_up_interruptible(&se401->wq); + se401->removed = 1; + } #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) - destroy_proc_se401_cam(se401); + destroy_proc_se401_cam(se401); #endif - + } } static struct usb_driver se401_driver = { .name = "se401", .id_table = device_table, - .probe = se401_probe, - .disconnect = se401_disconnect + .probe = se401_probe, + .disconnect = se401_disconnect, }; diff --git a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c index ce5134c3dbde..3b048bd3152a 100644 --- a/drivers/usb/media/stv680.c +++ b/drivers/usb/media/stv680.c @@ -1448,8 +1448,9 @@ static struct video_device stv680_template = { .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 @@ static void *stv680_probe (struct usb_device *dev, unsigned int ifnum, const str /* 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 @@ static void *stv680_probe (struct usb_device *dev, unsigned int ifnum, const str } 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 @@ static void *stv680_probe (struct usb_device *dev, unsigned int ifnum, const str 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 @@ static inline void usb_stv680_remove_disconnected (struct usb_stv *stv680) 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 --git a/drivers/usb/media/ultracam.c b/drivers/usb/media/ultracam.c index 8f3f35992bf0..75fe954716be 100644 --- a/drivers/usb/media/ultracam.c +++ b/drivers/usb/media/ultracam.c @@ -537,67 +537,71 @@ static void ultracam_configure_video(struct uvd *uvd) * 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 @@ static void *ultracam_probe(struct usb_device *dev, unsigned int ifnum ,const st } 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 @@ static void *ultracam_probe(struct usb_device *dev, unsigned int ifnum ,const st 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 @@ static void *ultracam_probe(struct usb_device *dev, unsigned int ifnum ,const st } } MOD_DEC_USE_COUNT; - return uvd; + + if (uvd) { + dev_set_drvdata (&intf->dev, uvd); + return 0; + } + return -EIO; } diff --git a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c index 12ccc1cd94e5..4f5061d1a657 100644 --- a/drivers/usb/media/usbvideo.c +++ b/drivers/usb/media/usbvideo.c @@ -54,7 +54,7 @@ static int usbvideo_default_procfs_write_proc( 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 @@ EXPORT_SYMBOL(usbvideo_Deregister); * 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 --git a/drivers/usb/media/usbvideo.h b/drivers/usb/media/usbvideo.h index a3ae984b8bc0..d8813b6d9d18 100644 --- a/drivers/usb/media/usbvideo.h +++ b/drivers/usb/media/usbvideo.h @@ -254,9 +254,9 @@ struct uvd { * 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 --git a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c index 4426717cb016..5b673019b7e1 100644 --- a/drivers/usb/media/vicam.c +++ b/drivers/usb/media/vicam.c @@ -787,9 +787,10 @@ error: 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 @@ static void *vicam_probe(struct usb_device *udev, unsigned int ifnum, /* 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 @@ static void *vicam_probe(struct usb_device *udev, unsigned int ifnum, 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 @@ static void *vicam_probe(struct usb_device *udev, unsigned int ifnum, 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 @@ static void *vicam_probe(struct usb_device *udev, unsigned int ifnum, 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 @@ static void *vicam_probe(struct usb_device *udev, unsigned int ifnum, 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); + /* 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; + if (!vicam->open_count) { + /* Other random junk */ + usb_free_urb(vicam->readurb); + kfree(vicam); + vicam = NULL; + } } } diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index e663dd327a79..b4303edf2b54 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c @@ -1910,9 +1910,10 @@ static struct file_operations auerswald_fops = class based it might be necessary to parse some more USB descriptors because the device properties can differ in a wide range. */ -static void *auerswald_probe (struct usb_device *usbdev, unsigned int ifnum, - const struct usb_device_id *id) +static int auerswald_probe (struct usb_interface *intf, + const struct usb_device_id *id) { + struct usb_device *usbdev = interface_to_usbdev(intf); pauerswald_t cp = NULL; DECLARE_WAIT_QUEUE_HEAD (wqh); unsigned int dtindex; @@ -1920,14 +1921,16 @@ static void *auerswald_probe (struct usb_device *usbdev, unsigned int ifnum, char *pbuf; int ret; - dbg ("probe: vendor id 0x%x, device id 0x%x ifnum:%d", - usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, ifnum); + dbg ("probe: vendor id 0x%x, device id 0x%x", + usbdev->descriptor.idVendor, usbdev->descriptor.idProduct); /* See if the device offered us matches that we can accept */ - if (usbdev->descriptor.idVendor != ID_AUERSWALD) return NULL; + if (usbdev->descriptor.idVendor != ID_AUERSWALD) + return -ENODEV; /* we use only the first -and only- interface */ - if (ifnum != 0) return NULL; + if (intf->altsetting->bInterfaceNumber != 0) + return -ENODEV; /* prevent module unloading while sleeping */ MOD_INC_USE_COUNT; @@ -2044,12 +2047,13 @@ static void *auerswald_probe (struct usb_device *usbdev, unsigned int ifnum, } /* all OK */ - return cp; + dev_set_drvdata (&intf->dev, cp); + return 0; /* Error exit: clean up the memory */ pfail: auerswald_delete (cp); MOD_DEC_USE_COUNT; - return NULL; + return -EIO; } @@ -2065,11 +2069,15 @@ pfail: auerswald_delete (cp); this device. So especially the usb_device structure must not be used any longer by the usb driver. */ -static void auerswald_disconnect (struct usb_device *usbdev, void *driver_context) +static void auerswald_disconnect (struct usb_interface *intf) { - pauerswald_t cp = (pauerswald_t) driver_context; + pauerswald_t cp = dev_get_drvdata (&intf->dev); unsigned int u; + dev_set_drvdata (&intf->dev, NULL); + if (!cp) + return; + down (&cp->mutex); info ("device /dev/usb/%s now disconnecting", cp->name); diff --git a/drivers/usb/misc/brlvger.c b/drivers/usb/misc/brlvger.c index db4d3d1d19ad..1777a1ffdd83 100644 --- a/drivers/usb/misc/brlvger.c +++ b/drivers/usb/misc/brlvger.c @@ -105,9 +105,9 @@ MODULE_PARM_DESC(raw_voltage, "Parameter for the call to SET_DISPLAY_VOLTAGE"); #endif /* Prototypes */ -static void *brlvger_probe (struct usb_device *dev, unsigned ifnum, - const struct usb_device_id *id); -static void brlvger_disconnect(struct usb_device *dev, void *ptr); +static int brlvger_probe (struct usb_interface *intf, + const struct usb_device_id *id); +static void brlvger_disconnect(struct usb_interface *intf); static int brlvger_open(struct inode *inode, struct file *file); static int brlvger_release(struct inode *inode, struct file *file); static ssize_t brlvger_write(struct file *file, const char *buffer, @@ -281,10 +281,11 @@ module_exit (brlvger_cleanup); /* Probe and disconnect functions */ -static void * -brlvger_probe (struct usb_device *dev, unsigned ifnum, +static int +brlvger_probe (struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev(intf); struct brlvger_priv *priv = NULL; int i; int retval; @@ -301,14 +302,14 @@ brlvger_probe (struct usb_device *dev, unsigned ifnum, || dev->config->bNumInterfaces != 1 || actifsettings->bNumEndpoints != 1 ) { err ("Bogus braille display config info"); - return NULL; + return -ENODEV; } endpoint = actifsettings->endpoint; if (!(endpoint->bEndpointAddress & 0x80) || ((endpoint->bmAttributes & 3) != 0x03)) { err ("Bogus braille display config info, wrong endpoints"); - return NULL; + return -ENODEV; } down(&reserve_sem); @@ -404,15 +405,20 @@ brlvger_probe (struct usb_device *dev, unsigned ifnum, out: up(&reserve_sem); - return priv; + if (priv) { + dev_set_drvdata (&intf->dev, priv); + return 0; + } + return -EIO; } static void -brlvger_disconnect(struct usb_device *dev, void *ptr) +brlvger_disconnect(struct usb_interface *intf) { - struct brlvger_priv *priv = (struct brlvger_priv *)ptr; + struct brlvger_priv *priv = dev_get_drvdata (&intf->dev); int r; + dev_set_drvdata (&intf->dev, NULL); if(priv){ info("Display %d disconnecting", priv->subminor); diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c index 2440fa92405a..02e22f53b45b 100644 --- a/drivers/usb/misc/emi26.c +++ b/drivers/usb/misc/emi26.c @@ -41,8 +41,8 @@ typedef struct _INTEL_HEX_RECORD static int emi26_writememory( struct usb_device *dev, int address, unsigned char *data, int length, __u8 bRequest); static int emi26_set_reset(struct usb_device *dev, unsigned char reset_bit); static int emi26_load_firmware (struct usb_device *dev); -static void *emi26_probe(struct usb_device *dev, unsigned int if_num, const struct usb_device_id *id); -static void emi26_disconnect(struct usb_device *dev, void *drv_context); +static int emi26_probe(struct usb_interface *intf, const struct usb_device_id *id); +static void emi26_disconnect(struct usb_interface *intf); static int __init emi26_init (void); static void __exit emi26_exit (void); @@ -195,8 +195,10 @@ static __devinitdata struct usb_device_id id_table [] = { MODULE_DEVICE_TABLE (usb, id_table); -static void * emi26_probe(struct usb_device *dev, unsigned int if_num, const struct usb_device_id *id) +static int emi26_probe(struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev(intf); + info("%s start", __FUNCTION__); if((dev->descriptor.idVendor == EMI26_VENDOR_ID) && (dev->descriptor.idProduct == EMI26_PRODUCT_ID)) { @@ -204,10 +206,10 @@ static void * emi26_probe(struct usb_device *dev, unsigned int if_num, const str } /* do not return the driver context, let real audio driver do that */ - return 0; + return -EIO; } -static void emi26_disconnect(struct usb_device *dev, void *drv_context) +static void emi26_disconnect(struct usb_interface *intf) { } diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index 1c8731d1df5f..f4c86b6d19e6 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c @@ -450,9 +450,10 @@ file_operations usb_rio_fops = { .release = close_rio, }; -static void *probe_rio(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id) +static int probe_rio(struct usb_interface *intf, + const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev(intf); struct rio_usb_data *rio = &rio_instance; int retval; @@ -461,7 +462,7 @@ static void *probe_rio(struct usb_device *dev, unsigned int ifnum, retval = usb_register_dev(&usb_rio_fops, RIO_MINOR, 1, &rio->minor); if (retval) { err("Not able to get a minor for this device."); - return NULL; + return -ENOMEM; } rio->present = 1; @@ -469,14 +470,14 @@ static void *probe_rio(struct usb_device *dev, unsigned int ifnum, if (!(rio->obuf = (char *) kmalloc(OBUF_SIZE, GFP_KERNEL))) { err("probe_rio: Not enough memory for the output buffer"); - return NULL; + return -ENOMEM; } dbg("probe_rio: obuf address:%p", rio->obuf); if (!(rio->ibuf = (char *) kmalloc(IBUF_SIZE, GFP_KERNEL))) { err("probe_rio: Not enough memory for the input buffer"); kfree(rio->obuf); - return NULL; + return -ENOMEM; } dbg("probe_rio: ibuf address:%p", rio->ibuf); @@ -490,31 +491,35 @@ static void *probe_rio(struct usb_device *dev, unsigned int ifnum, init_MUTEX(&(rio->lock)); - return rio; + dev_set_drvdata (&intf->dev, rio); + return 0; } -static void disconnect_rio(struct usb_device *dev, void *ptr) +static void disconnect_rio(struct usb_interface *intf) { - struct rio_usb_data *rio = (struct rio_usb_data *) ptr; + struct rio_usb_data *rio = dev_get_drvdata (&intf->dev); + + dev_set_drvdata (&intf->dev, NULL); + if (rio) { + devfs_unregister(rio->devfs); + usb_deregister_dev(1, rio->minor); + + down(&(rio->lock)); + if (rio->isopen) { + rio->isopen = 0; + /* better let it finish - the release will do whats needed */ + rio->rio_dev = NULL; + up(&(rio->lock)); + return; + } + kfree(rio->ibuf); + kfree(rio->obuf); - devfs_unregister(rio->devfs); - usb_deregister_dev(1, rio->minor); + info("USB Rio disconnected."); - down(&(rio->lock)); - if (rio->isopen) { - rio->isopen = 0; - /* better let it finish - the release will do whats needed */ - rio->rio_dev = NULL; + rio->present = 0; up(&(rio->lock)); - return; } - kfree(rio->ibuf); - kfree(rio->obuf); - - info("USB Rio disconnected."); - - rio->present = 0; - up(&(rio->lock)); } static struct usb_device_id rio_table [] = { diff --git a/drivers/usb/misc/speedtouch.c b/drivers/usb/misc/speedtouch.c index 29fc6db95749..19876ed935aa 100644 --- a/drivers/usb/misc/speedtouch.c +++ b/drivers/usb/misc/speedtouch.c @@ -177,20 +177,20 @@ struct udsl_atm_dev_data { /* * usb driver prototypes and structures */ -static void *udsl_usb_probe (struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id); -static void udsl_usb_disconnect (struct usb_device *dev, void *ptr); +static int udsl_usb_probe (struct usb_interface *intf, + const struct usb_device_id *id); +static void udsl_usb_disconnect (struct usb_interface *intf); int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_vcc *vcc, struct sk_buff *skb); static int udsl_usb_ioctl (struct usb_device *hub, unsigned int code, void *user_data); static int udsl_usb_cancelsends (struct udsl_instance_data *instance, struct atm_vcc *vcc); static struct usb_driver udsl_usb_driver = { - name:udsl_driver_name, - probe:udsl_usb_probe, - disconnect:udsl_usb_disconnect, - ioctl:udsl_usb_ioctl, - id_table:udsl_usb_ids, + .name = udsl_driver_name, + .probe = udsl_usb_probe, + .disconnect = udsl_usb_disconnect, + .ioctl = udsl_usb_ioctl, + .id_table = udsl_usb_ids, }; /************ @@ -828,7 +828,7 @@ int udsl_usb_data_init (struct udsl_instance_data *instance) return 0; } -int udsl_usb_data_exit (struct udsl_instance_data *instance) +static int udsl_usb_data_exit (struct udsl_instance_data *instance) { int i; @@ -913,8 +913,10 @@ static int udsl_usb_ioctl (struct usb_device *dev, unsigned int code, void *user return -EINVAL; } -void *udsl_usb_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id) +static int udsl_usb_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; unsigned char mac[6]; unsigned char mac_str[13]; @@ -926,7 +928,7 @@ void *udsl_usb_probe (struct usb_device *dev, unsigned int ifnum, const struct u if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) || (dev->descriptor.idVendor != SPEEDTOUCH_VENDORID) || (dev->descriptor.idProduct != SPEEDTOUCH_PRODUCTID) || (ifnum != 1)) - return NULL; + return -ENODEV; MOD_INC_USE_COUNT; @@ -936,7 +938,7 @@ void *udsl_usb_probe (struct usb_device *dev, unsigned int ifnum, const struct u if (i >= MAX_UDSL) { printk (KERN_INFO "No minor table space available for SpeedTouch USB\n"); - return NULL; + return -ENOMEM; }; PDEBUG ("Device Accepted, assigning minor %d\n", i); @@ -945,7 +947,7 @@ void *udsl_usb_probe (struct usb_device *dev, unsigned int ifnum, const struct u instance = kmalloc (sizeof (struct udsl_instance_data), GFP_KERNEL); if (!instance) { PDEBUG ("No memory for Instance data!\n"); - return NULL; + return -ENOMEM; } /* initialize structure */ @@ -969,32 +971,37 @@ void *udsl_usb_probe (struct usb_device *dev, unsigned int ifnum, const struct u minor_data[instance->minor] = instance; - return instance; + dev_set_drvdata (&intf->dev, instance); + return 0; } -void udsl_usb_disconnect (struct usb_device *dev, void *ptr) +static void udsl_usb_disconnect (struct usb_interface *intf) { - struct udsl_instance_data *instance = (struct udsl_instance_data *) ptr; - int i = instance->minor; + struct udsl_instance_data *instance = dev_get_drvdata (&intf->dev); + int i; - /* unlinking receive buffers */ - udsl_usb_data_exit (instance); + dev_set_drvdata (&intf->dev, NULL); + if (instance) { + i = instance->minor; + /* unlinking receive buffers */ + udsl_usb_data_exit (instance); - /* removing atm device */ - if (instance->atm_dev) - udsl_atm_stopdevice (instance); + /* removing atm device */ + if (instance->atm_dev) + udsl_atm_stopdevice (instance); - PDEBUG ("disconnecting minor %d\n", i); + PDEBUG ("disconnecting minor %d\n", i); - while (MOD_IN_USE > 1) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout (1); - } + while (MOD_IN_USE > 1) { + current->state = TASK_INTERRUPTIBLE; + schedule_timeout (1); + } - kfree (instance); - minor_data[i] = NULL; + kfree (instance); + minor_data[i] = NULL; - MOD_DEC_USE_COUNT; + MOD_DEC_USE_COUNT; + } } /*************************************************************************** diff --git a/drivers/usb/misc/tiglusb.c b/drivers/usb/misc/tiglusb.c index 499908292ffa..6dada5ddf6f4 100644 --- a/drivers/usb/misc/tiglusb.c +++ b/drivers/usb/misc/tiglusb.c @@ -326,17 +326,18 @@ static struct file_operations tiglusb_fops = { /* --- initialisation code ------------------------------------- */ -static void * -tiglusb_probe (struct usb_device *dev, unsigned int ifnum, +static int +tiglusb_probe (struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev(intf); int minor = -1; int i; ptiglusb_t s; char name[8]; - dbg ("probing vendor id 0x%x, device id 0x%x ifnum:%d", - dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum); + dbg ("probing vendor id 0x%x, device id 0x%x", + dev->descriptor.idVendor, dev->descriptor.idProduct); /* * We don't handle multiple configurations. As of version 0x0103 of @@ -344,15 +345,15 @@ tiglusb_probe (struct usb_device *dev, unsigned int ifnum, */ if (dev->descriptor.bNumConfigurations != 1) - return NULL; + return -ENODEV; if ((dev->descriptor.idProduct != 0xe001) && (dev->descriptor.idVendor != 0x451)) - return NULL; + return -ENODEV; if (usb_set_configuration (dev, dev->config[0].bConfigurationValue) < 0) { err ("tiglusb_probe: set_configuration failed"); - return NULL; + return -ENODEV; } /* @@ -367,7 +368,7 @@ tiglusb_probe (struct usb_device *dev, unsigned int ifnum, } if (minor == -1) - return NULL; + return -ENODEV; s = &tiglusb[minor]; @@ -375,7 +376,7 @@ tiglusb_probe (struct usb_device *dev, unsigned int ifnum, s->remove_pending = 0; s->dev = dev; up (&s->mutex); - dbg ("bound to interface: %d", ifnum); + dbg ("bound to interface"); sprintf (name, "%d", s->minor); dbg ("registering to devfs : major = %d, minor = %d, node = %s", @@ -390,16 +391,20 @@ tiglusb_probe (struct usb_device *dev, unsigned int ifnum, dev->descriptor.bcdDevice >> 8, dev->descriptor.bcdDevice & 0xff); - return s; + dev_set_drvdata (&intf->dev, s); + return 0; } static void -tiglusb_disconnect (struct usb_device *dev, void *drv_context) +tiglusb_disconnect (struct usb_interface *intf) { - ptiglusb_t s = (ptiglusb_t) drv_context; + ptiglusb_t s = dev_get_drvdata (&intf->dev); - if (!s || !s->dev) + dev_set_drvdata (&intf->dev, NULL); + if (!s || !s->dev) { info ("bogus disconnect"); + return; + } s->remove_pending = 1; wake_up (&s->wait); diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index 50a22868d90c..4bde97856d75 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c @@ -245,20 +245,21 @@ file_operations usb_lcd_fops = { .release = close_lcd, }; -static void *probe_lcd(struct usb_device *dev, unsigned int ifnum) +static int probe_lcd(struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev(intf); struct lcd_usb_data *lcd = &lcd_instance; int i; int retval; if (dev->descriptor.idProduct != 0x0001 ) { warn(KERN_INFO "USBLCD model not supported."); - return NULL; + return -ENODEV; } if (lcd->present == 1) { warn(KERN_INFO "Multiple USBLCDs are not supported!"); - return NULL; + return -ENODEV; } i = dev->descriptor.bcdDevice; @@ -270,7 +271,7 @@ static void *probe_lcd(struct usb_device *dev, unsigned int ifnum) retval = usb_register_dev(&usb_lcd_fops, USBLCD_MINOR, 1, &lcd->minor); if (retval) { err("Not able to get a minor for this device."); - return NULL; + return -ENOMEM; } lcd->present = 1; @@ -278,38 +279,42 @@ static void *probe_lcd(struct usb_device *dev, unsigned int ifnum) if (!(lcd->obuf = (char *) kmalloc(OBUF_SIZE, GFP_KERNEL))) { err("probe_lcd: Not enough memory for the output buffer"); - return NULL; + return -ENOMEM; } dbg("probe_lcd: obuf address:%p", lcd->obuf); if (!(lcd->ibuf = (char *) kmalloc(IBUF_SIZE, GFP_KERNEL))) { err("probe_lcd: Not enough memory for the input buffer"); kfree(lcd->obuf); - return NULL; + return -ENOMEM; } dbg("probe_lcd: ibuf address:%p", lcd->ibuf); - return lcd; + dev_set_drvdata (&intf->dev, lcd); + return 0; } -static void disconnect_lcd(struct usb_device *dev, void *ptr) +static void disconnect_lcd(struct usb_interface *intf) { - struct lcd_usb_data *lcd = (struct lcd_usb_data *) ptr; + struct lcd_usb_data *lcd = dev_get_drvdata (&intf->dev); - usb_deregister_dev(1, lcd->minor); + dev_set_drvdata (&intf->dev, NULL); + if (lcd) { + usb_deregister_dev(1, lcd->minor); - if (lcd->isopen) { - lcd->isopen = 0; - /* better let it finish - the release will do whats needed */ - lcd->lcd_dev = NULL; - return; - } - kfree(lcd->ibuf); - kfree(lcd->obuf); + if (lcd->isopen) { + lcd->isopen = 0; + /* better let it finish - the release will do whats needed */ + lcd->lcd_dev = NULL; + return; + } + kfree(lcd->ibuf); + kfree(lcd->obuf); - info("USBLCD disconnected."); + info("USBLCD disconnected."); - lcd->present = 0; + lcd->present = 0; + } } static struct usb_device_id id_table [] = { diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 3940bb1fbe5c..36efa886c9e0 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c @@ -545,9 +545,10 @@ static struct parport_operations parport_uss720_ops = /* --------------------------------------------------------------------- */ -static void * uss720_probe(struct usb_device *usbdev, unsigned int ifnum, - const struct usb_device_id *id) +static int uss720_probe(struct usb_interface *intf, + const struct usb_device_id *id) { + struct usb_device *usbdev = interface_to_usbdev(intf); struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; struct parport_uss720_private *priv; @@ -558,13 +559,13 @@ static void * uss720_probe(struct usb_device *usbdev, unsigned int ifnum, usbdev->descriptor.idVendor, usbdev->descriptor.idProduct); /* our known interfaces have 3 alternate settings */ - if (usbdev->actconfig->interface[ifnum].num_altsetting != 3) - return NULL; + if (intf->num_altsetting != 3) + return -ENODEV; - i = usb_set_interface(usbdev, ifnum, 2); + i = usb_set_interface(usbdev, intf->altsetting->bInterfaceNumber, 2); printk(KERN_DEBUG "uss720: set inteface result %d\n", i); - interface = &usbdev->actconfig->interface[ifnum].altsetting[2]; + interface = &intf->altsetting[2]; /* * Allocate parport interface @@ -572,7 +573,7 @@ static void * uss720_probe(struct usb_device *usbdev, unsigned int ifnum, printk(KERN_INFO "uss720: (C) 1999 by Thomas Sailer, <sailer@ife.ee.ethz.ch>\n"); if (!(priv = kmalloc(sizeof(struct parport_uss720_private), GFP_KERNEL))) - return NULL; + return -ENOMEM; if (!(pp = parport_register_port(0, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, &parport_uss720_ops))) { printk(KERN_WARNING "usb-uss720: could not register parport\n"); goto probe_abort; @@ -607,7 +608,8 @@ static void * uss720_probe(struct usb_device *usbdev, unsigned int ifnum, parport_announce_port(pp); MOD_INC_USE_COUNT; - return pp; + dev_set_drvdata (&intf->dev, pp); + return 0; #if 0 probe_abort_port: @@ -615,22 +617,26 @@ probe_abort_port: #endif probe_abort: kfree(priv); - return NULL; + return -ENODEV; } -static void uss720_disconnect(struct usb_device *usbdev, void *ptr) +static void uss720_disconnect(struct usb_interface *intf) { - struct parport *pp = (struct parport *)ptr; - struct parport_uss720_private *priv = pp->private_data; + struct parport *pp = dev_get_drvdata (&intf->dev); + struct parport_uss720_private *priv; + dev_set_drvdata (&intf->dev, NULL); + if (pp) { + priv = pp->private_data; #if 0 - usb_release_irq(usbdev, priv->irqhandle, priv->irqpipe); + usb_release_irq(usbdev, priv->irqhandle, priv->irqpipe); #endif - priv->usbdev = NULL; - parport_proc_unregister(pp); - parport_unregister_port(pp); - kfree(priv); - MOD_DEC_USE_COUNT; + priv->usbdev = NULL; + parport_proc_unregister(pp); + parport_unregister_port(pp); + kfree(priv); + MOD_DEC_USE_COUNT; + } } /* table of cables that work through this driver */ diff --git a/drivers/usb/net/catc.c b/drivers/usb/net/catc.c index b270dc757afb..fda5b7d575d2 100644 --- a/drivers/usb/net/catc.c +++ b/drivers/usb/net/catc.c @@ -761,28 +761,29 @@ static int catc_stop(struct net_device *netdev) * USB probe, disconnect. */ -static void *catc_probe(struct usb_device *usbdev, unsigned int ifnum, const struct usb_device_id *id) +static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_device *usbdev = interface_to_usbdev(intf); struct net_device *netdev; struct catc *catc; u8 broadcast[6]; int i, pktsz; - if (usb_set_interface(usbdev, ifnum, 1)) { + if (usb_set_interface(usbdev, intf->altsetting->bInterfaceNumber, 1)) { err("Can't set altsetting 1."); - return NULL; + return -EIO; } catc = kmalloc(sizeof(struct catc), GFP_KERNEL); if (!catc) - return NULL; + return -ENOMEM; memset(catc, 0, sizeof(struct catc)); netdev = init_etherdev(0, 0); if (!netdev) { kfree(catc); - return NULL; + return -EIO; } netdev->open = catc_open; @@ -818,7 +819,7 @@ static void *catc_probe(struct usb_device *usbdev, unsigned int ifnum, const str if (catc->irq_urb) usb_free_urb(catc->irq_urb); kfree(netdev); kfree(catc); - return NULL; + return -ENOMEM; } /* The F5U011 has the same vendor/product as the netmate but a device version of 0x130 */ @@ -907,24 +908,29 @@ static void *catc_probe(struct usb_device *usbdev, unsigned int ifnum, const str f5u011_rxmode(catc, catc->rxmode); } dbg("Init done."); - printk(KERN_INFO "%s: %s USB Ethernet at usb-%s-%s/%d, ", + printk(KERN_INFO "%s: %s USB Ethernet at usb-%s-%s, ", netdev->name, (catc->is_f5u011) ? "Belkin F5U011" : "CATC EL1210A NetMate", - usbdev->bus->bus_name, usbdev->devpath, ifnum); + usbdev->bus->bus_name, usbdev->devpath); for (i = 0; i < 5; i++) printk("%2.2x:", netdev->dev_addr[i]); printk("%2.2x.\n", netdev->dev_addr[i]); - return catc; + dev_set_drvdata (&intf->dev, catc); + return 0; } -static void catc_disconnect(struct usb_device *usbdev, void *dev_ptr) +static void catc_disconnect(struct usb_interface *intf) { - struct catc *catc = dev_ptr; - unregister_netdev(catc->netdev); - usb_free_urb(catc->ctrl_urb); - usb_free_urb(catc->tx_urb); - usb_free_urb(catc->rx_urb); - usb_free_urb(catc->irq_urb); - kfree(catc->netdev); - kfree(catc); + struct catc *catc = dev_get_drvdata (&intf->dev); + + dev_set_drvdata (&intf->dev, NULL); + if (catc) { + unregister_netdev(catc->netdev); + usb_free_urb(catc->ctrl_urb); + usb_free_urb(catc->tx_urb); + usb_free_urb(catc->rx_urb); + usb_free_urb(catc->irq_urb); + kfree(catc->netdev); + kfree(catc); + } } /* diff --git a/drivers/usb/net/cdc-ether.c b/drivers/usb/net/cdc-ether.c index d77366e940b2..513f83c9bda1 100644 --- a/drivers/usb/net/cdc-ether.c +++ b/drivers/usb/net/cdc-ether.c @@ -1123,9 +1123,10 @@ static struct usb_driver CDCEther_driver ; // claims interfaces if they are for an Ethernet CDC ///////////////////////// ////////////////////////////////////////////////////////////////////////////// -static void * CDCEther_probe( struct usb_device *usb, unsigned int ifnum, - const struct usb_device_id *id) +static int CDCEther_probe( struct usb_interface *intf, + const struct usb_device_id *id) { + struct usb_device *usb = interface_to_usbdev(intf); struct net_device *net; ether_dev_t *ether_dev; int rc; @@ -1135,7 +1136,7 @@ static void * CDCEther_probe( struct usb_device *usb, unsigned int ifnum, if ( check_for_claimed_interfaces( usb->actconfig ) ) { // Someone has already put there grubby paws on this device. // We don't want it now... - return NULL; + return -ENODEV; } // We might be finding a device we can use. @@ -1144,7 +1145,7 @@ static void * CDCEther_probe( struct usb_device *usb, unsigned int ifnum, // we are going to need later. if(!(ether_dev = kmalloc(sizeof(ether_dev_t), GFP_KERNEL))) { err("out of memory allocating device structure"); - return NULL; + return -ENOMEM; } // Zero everything out. @@ -1153,20 +1154,20 @@ static void * CDCEther_probe( struct usb_device *usb, unsigned int ifnum, ether_dev->rx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!ether_dev->rx_urb) { kfree(ether_dev); - return NULL; + return -ENOMEM; } ether_dev->tx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!ether_dev->tx_urb) { usb_free_urb(ether_dev->rx_urb); kfree(ether_dev); - return NULL; + return -ENOMEM; } ether_dev->intr_urb = usb_alloc_urb(0, GFP_KERNEL); if (!ether_dev->intr_urb) { usb_free_urb(ether_dev->tx_urb); usb_free_urb(ether_dev->rx_urb); kfree(ether_dev); - return NULL; + return -ENOMEM; } // Let's see if we can find a configuration we can use. @@ -1261,8 +1262,12 @@ static void * CDCEther_probe( struct usb_device *usb, unsigned int ifnum, // TODO - last minute HACK ether_dev->comm_ep_in = 5; +/* FIXME!!! This driver needs to be fixed to work with the new USB interface logic + * this is not the correct thing to be doing here, we need to set the interface + * driver specific data field. + */ // Okay, we are finally done... - return NULL; + return 0; // bailing out with our tail between our knees error_all: @@ -1270,7 +1275,7 @@ error_all: usb_free_urb(ether_dev->rx_urb); usb_free_urb(ether_dev->intr_urb); kfree( ether_dev ); - return NULL; + return -EIO; } @@ -1280,9 +1285,12 @@ error_all: // (Whichever happens first assuming the driver suceeded at its probe) /////// ////////////////////////////////////////////////////////////////////////////// -static void CDCEther_disconnect( struct usb_device *usb, void *ptr ) +static void CDCEther_disconnect( struct usb_interface *intf ) { - ether_dev_t *ether_dev = ptr; + ether_dev_t *ether_dev = dev_get_drvdata (&intf->dev); + struct usb_device *usb; + + dev_set_drvdata (&intf->dev, NULL); // Sanity check!!! if ( !ether_dev || !ether_dev->usb ) { @@ -1294,6 +1302,8 @@ static void CDCEther_disconnect( struct usb_device *usb, void *ptr ) // Make sure we fail the sanity check if we try this again. ether_dev->usb = NULL; + usb = interface_to_usbdev(intf); + // It is possible that this function is called before // the "close" function. // This tells the close function we are already disconnected diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index ee4cbb9f9c6d..bc2be92fd8bc 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c @@ -114,12 +114,11 @@ MODULE_AUTHOR("Michael Zappe <zapman@interlan.net>, Stephane Alnet <stephane@u-p MODULE_DESCRIPTION("KL5USB101 USB Ethernet driver"); MODULE_LICENSE("GPL"); -static void *kaweth_probe( - struct usb_device *dev, /* the device */ - unsigned ifnum, /* what interface */ - const struct usb_device_id *id /* from id_table */ +static int kaweth_probe( + struct usb_interface *intf, + const struct usb_device_id *id /* from id_table */ ); -static void kaweth_disconnect(struct usb_device *dev, void *ptr); +static void kaweth_disconnect(struct usb_interface *intf); int kaweth_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe, struct usb_ctrlrequest *cmd, void *data, int len, int timeout); @@ -847,12 +846,12 @@ static void kaweth_tx_timeout(struct net_device *net) /**************************************************************** * kaweth_probe ****************************************************************/ -static void *kaweth_probe( - struct usb_device *dev, /* the device */ - unsigned ifnum, /* what interface */ - const struct usb_device_id *id /* from id_table */ +static int kaweth_probe( + struct usb_interface *intf, + const struct usb_device_id *id /* from id_table */ ) { + struct usb_device *dev = interface_to_usbdev(intf); struct kaweth_device *kaweth; struct net_device *netdev; const eth_addr_t bcast_addr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; @@ -871,7 +870,7 @@ static void *kaweth_probe( (int)dev->descriptor.bDescriptorType); if(!(kaweth = kmalloc(sizeof(struct kaweth_device), GFP_KERNEL))) - return NULL; + return -ENOMEM; memset(kaweth, 0, sizeof(struct kaweth_device)); @@ -902,7 +901,7 @@ static void *kaweth_probe( kaweth_err("Error downloading firmware (%d)", result); free_page((unsigned long)kaweth->firmware_buf); kfree(kaweth); - return NULL; + return -EIO; } if ((result = kaweth_download_firmware(kaweth, @@ -913,7 +912,7 @@ static void *kaweth_probe( kaweth_err("Error downloading firmware fix (%d)", result); free_page((unsigned long)kaweth->firmware_buf); kfree(kaweth); - return NULL; + return -EIO; } if ((result = kaweth_download_firmware(kaweth, @@ -924,7 +923,7 @@ static void *kaweth_probe( kaweth_err("Error downloading trigger code (%d)", result); free_page((unsigned long)kaweth->firmware_buf); kfree(kaweth); - return NULL; + return -EIO; } if ((result = kaweth_download_firmware(kaweth, @@ -935,7 +934,7 @@ static void *kaweth_probe( kaweth_err("Error downloading trigger code fix (%d)", result); free_page((unsigned long)kaweth->firmware_buf); kfree(kaweth); - return NULL; + return -EIO; } @@ -943,14 +942,14 @@ static void *kaweth_probe( kaweth_err("Error triggering firmware (%d)", result); free_page((unsigned long)kaweth->firmware_buf); kfree(kaweth); - return NULL; + return -EIO; } /* Device will now disappear for a moment... */ kaweth_info("Firmware loaded. I'll be back..."); free_page((unsigned long)kaweth->firmware_buf); kfree(kaweth); - return NULL; + return -EIO; } result = kaweth_read_configuration(kaweth); @@ -958,7 +957,7 @@ static void *kaweth_probe( if(result < 0) { kaweth_err("Error reading configuration (%d), no net device created", result); kfree(kaweth); - return NULL; + return -EIO; } kaweth_info("Statistics collection: %x", kaweth->configuration.statistics_mask); @@ -977,17 +976,17 @@ static void *kaweth_probe( sizeof(bcast_addr))) { kaweth_err("Firmware not functioning properly, no net device created"); kfree(kaweth); - return NULL; + return -EIO; } if(kaweth_set_urb_size(kaweth, KAWETH_BUF_SIZE) < 0) { kaweth_dbg("Error setting URB size"); - return kaweth; + goto err_no_netdev; } if(kaweth_set_sofs_wait(kaweth, KAWETH_SOFS_TO_WAIT) < 0) { kaweth_err("Error setting SOFS wait"); - return kaweth; + goto err_no_netdev; } result = kaweth_set_receive_filter(kaweth, @@ -998,14 +997,14 @@ static void *kaweth_probe( if(result < 0) { kaweth_err("Error setting receive filter"); kfree(kaweth); - return NULL; + return -EIO; } kaweth_dbg("Initializing net device."); if(!(netdev = kmalloc(sizeof(struct net_device), GFP_KERNEL))) { kfree(kaweth); - return NULL; + return -ENOMEM; } kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL); @@ -1050,27 +1049,30 @@ static void *kaweth_probe( kaweth_dbg("Kaweth probe returning."); - return kaweth; + dev_set_drvdata (&intf->dev, kaweth); + return 0; err_tx_and_rx: usb_free_urb(kaweth->rx_urb); err_only_tx: usb_free_urb(kaweth->tx_urb); err_no_urb: - kfree(kaweth); kfree(netdev); - return NULL; +err_no_netdev: + kfree(kaweth); + return -EIO; } /**************************************************************** * kaweth_disconnect ****************************************************************/ -static void kaweth_disconnect(struct usb_device *dev, void *ptr) +static void kaweth_disconnect(struct usb_interface *intf) { - struct kaweth_device *kaweth = ptr; + struct kaweth_device *kaweth = dev_get_drvdata (&intf->dev); kaweth_info("Unregistering"); + dev_set_drvdata (&intf->dev, NULL); if (!kaweth) { kaweth_warn("unregistering non-existant device"); return; diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 908d7b32ad59..9a398e427b4d 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c @@ -1045,20 +1045,21 @@ static inline void setup_pegasus_II(pegasus_t * pegasus) set_register(pegasus, Reg81, 2); } -static void *pegasus_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id) +static int pegasus_probe(struct usb_interface *intf, + const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev(intf); struct net_device *net; pegasus_t *pegasus; int dev_index = id - pegasus_ids; if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) { err("usb_set_configuration() failed"); - return NULL; + return -ENODEV; } if (!(pegasus = kmalloc(sizeof(struct pegasus), GFP_KERNEL))) { err("out of memory allocating device structure"); - return NULL; + return -ENOMEM; } usb_get_dev(dev); @@ -1068,14 +1069,14 @@ static void *pegasus_probe(struct usb_device *dev, unsigned int ifnum, if (!alloc_urbs(pegasus)) { kfree(pegasus); - return NULL; + return -ENOMEM; } net = init_etherdev(NULL, 0); if (!net) { free_all_urbs(pegasus); kfree(pegasus); - return NULL; + return -ENODEV; } init_MUTEX(&pegasus->sem); @@ -1122,13 +1123,18 @@ static void *pegasus_probe(struct usb_device *dev, unsigned int ifnum, } exit: up(&pegasus->sem); - return pegasus; + if (pegasus) { + dev_set_drvdata (&intf->dev, pegasus); + return 0; + } + return -EIO; } -static void pegasus_disconnect(struct usb_device *dev, void *ptr) +static void pegasus_disconnect(struct usb_interface *intf) { - struct pegasus *pegasus = ptr; + struct pegasus *pegasus = dev_get_drvdata (&intf->dev); + dev_set_drvdata (&intf->dev, NULL); if (!pegasus) { warn("unregistering non-existant device"); return; @@ -1136,7 +1142,7 @@ static void pegasus_disconnect(struct usb_device *dev, void *ptr) pegasus->flags |= PEGASUS_UNPLUG; unregister_netdev(pegasus->net); - usb_put_dev(dev); + usb_put_dev(interface_to_usbdev(intf)); unlink_all_urbs(pegasus); free_all_urbs(pegasus); free_skb_pool(pegasus); diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c index 24121afaafed..222639f5f9b5 100644 --- a/drivers/usb/net/rtl8150.c +++ b/drivers/usb/net/rtl8150.c @@ -109,9 +109,9 @@ unsigned long multicast_filter_limit = 32; static void fill_skb_pool(rtl8150_t *); static void free_skb_pool(rtl8150_t *); static inline struct sk_buff *pull_skb(rtl8150_t *); -static void rtl8150_disconnect(struct usb_device *dev, void *ptr); -static void *rtl8150_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id); +static void rtl8150_disconnect(struct usb_interface *intf); +static int rtl8150_probe(struct usb_interface *intf, + const struct usb_device_id *id); static struct usb_driver rtl8150_driver = { .name = "rtl8150", @@ -723,20 +723,21 @@ static int rtl8150_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) return res; } -static void *rtl8150_probe(struct usb_device *udev, unsigned int ifnum, - const struct usb_device_id *id) +static int rtl8150_probe(struct usb_interface *intf, + const struct usb_device_id *id) { + struct usb_device *udev = interface_to_usbdev(intf); rtl8150_t *dev; struct net_device *netdev; if (usb_set_configuration(udev, udev->config[0].bConfigurationValue)) { err("usb_set_configuration() failed"); - return NULL; + return -EIO; } dev = kmalloc(sizeof(rtl8150_t), GFP_KERNEL); if (!dev) { err("Out of memory"); - return NULL; + return -ENOMEM; } else memset(dev, 0, sizeof(rtl8150_t)); @@ -744,7 +745,7 @@ static void *rtl8150_probe(struct usb_device *udev, unsigned int ifnum, if (!netdev) { kfree(dev); err("Oh boy, out of memory again?!?"); - return NULL; + return -ENOMEM; } init_MUTEX(&dev->sem); @@ -781,31 +782,35 @@ static void *rtl8150_probe(struct usb_device *udev, unsigned int ifnum, info("%s: rtl8150 is detected", netdev->name); up(&dev->sem); - return dev; + dev_set_drvdata (&intf->dev, dev); + return 0; err: unregister_netdev(dev->netdev); up(&dev->sem); kfree(netdev); kfree(dev); - return NULL; + return -EIO; } -static void rtl8150_disconnect(struct usb_device *udev, void *ptr) +static void rtl8150_disconnect(struct usb_interface *intf) { - rtl8150_t *dev; + rtl8150_t *dev = dev_get_drvdata (&intf->dev); - dev = ptr; - set_bit(RTL8150_UNPLUG, &dev->flags); - unregister_netdev(dev->netdev); - unlink_all_urbs(dev); - free_all_urbs(dev); - free_skb_pool(dev); - if (dev->rx_skb) - dev_kfree_skb(dev->rx_skb); - kfree(dev->netdev); - kfree(dev); - dev->netdev = NULL; - dev = NULL; + dev_set_drvdata (&intf->dev, NULL); + + if (dev) { + set_bit(RTL8150_UNPLUG, &dev->flags); + unregister_netdev(dev->netdev); + unlink_all_urbs(dev); + free_all_urbs(dev); + free_skb_pool(dev); + if (dev->rx_skb) + dev_kfree_skb(dev->rx_skb); + kfree(dev->netdev); + kfree(dev); + dev->netdev = NULL; + dev = NULL; + } } int __init usb_rtl8150_init(void) diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index b922aef6d8ae..fb09fb3fdde2 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c @@ -1941,12 +1941,20 @@ static void usbnet_bh (unsigned long param) // precondition: never called in_interrupt -static void usbnet_disconnect (struct usb_device *udev, void *ptr) +static void usbnet_disconnect (struct usb_interface *intf) { - struct usbnet *dev = (struct usbnet *) ptr; + struct usbnet *dev; + struct usb_device *xdev; + + dev = dev_get_drvdata (&intf->dev); + dev_set_drvdata (&intf->dev, NULL); + if (!dev) + return; + + xdev = interface_to_usbdev (intf); 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); @@ -1960,7 +1968,7 @@ static void usbnet_disconnect (struct usb_device *udev, void *ptr) flush_scheduled_tasks (); kfree (dev); - usb_put_dev (udev); + usb_put_dev (xdev); } @@ -1968,46 +1976,38 @@ static void usbnet_disconnect (struct usb_device *udev, void *ptr) // 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); @@ -2040,10 +2040,11 @@ usbnet_probe (struct usb_device *udev, unsigned ifnum, 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. + dev_set_drvdata (&udev->dev, net); mutex_lock (&usbnet_mutex); list_add (&dev->dev_list, &usbnet_list); mutex_unlock (&dev->mutex); @@ -2052,7 +2053,7 @@ usbnet_probe (struct usb_device *udev, unsigned ifnum, netif_device_attach (&dev->net); mutex_unlock (&usbnet_mutex); - return dev; + return 0; } diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index adbbf74bdf4f..5c04f67b3410 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -115,6 +115,13 @@ static struct usb_device_id id_table_combined [] = { 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, @@ -527,6 +534,7 @@ static int belkin_sa_ioctl (struct usb_serial_port *port, struct file * file, un static int __init belkin_sa_init (void) { usb_serial_register (&belkin_device); + usb_register (&belkin_driver); info(DRIVER_DESC " " DRIVER_VERSION); return 0; } @@ -534,6 +542,7 @@ static int __init belkin_sa_init (void) static void __exit belkin_sa_exit (void) { + usb_deregister (&belkin_driver); usb_serial_deregister (&belkin_device); } diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index ff3268e517e7..2bed78c39ab2 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -73,6 +73,13 @@ static struct usb_device_id id_table [] = { 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 void cyberjack_write_bulk_callback (struct urb *urb) 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 int __init cyberjack_init (void) static void __exit cyberjack_exit (void) { + usb_deregister (&cyberjack_driver); usb_serial_deregister (&cyberjack_device); } diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index fd40a5992825..4b991e76067c 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -477,7 +477,7 @@ static int digi_read_oob_callback( struct urb *urb ); /* 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 @@ static struct usb_device_id id_table_4 [] = { 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 @@ static int __init digi_init (void) { 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 int __init digi_init (void) 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 --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 81c622bb876e..12bf572660e6 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c @@ -110,6 +110,13 @@ static struct usb_device_id id_table [] = { 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 @@ static int __init empeg_init (void) 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 @@ static int __init empeg_init (void) } } + usb_serial_register (&empeg_device); + usb_register (&empeg_driver); + info(DRIVER_VERSION ":" DRIVER_DESC); return 0; - } @@ -583,6 +590,7 @@ static void __exit empeg_exit (void) 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 @@ static void __exit empeg_exit (void) } spin_unlock_irqrestore (&write_urb_pool_lock, flags); - } diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index ac340015658f..1707de33b2de 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -140,7 +140,7 @@ static struct usb_device_id id_table_8U232AM [] = { }; -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 @@ static __devinitdata struct usb_device_id id_table_combined [] = { 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 @@ static int __init ftdi_sio_init (void) 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 int __init ftdi_sio_init (void) 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 --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index e91f74e7613f..600a9612148d 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -457,6 +457,12 @@ static void edge_shutdown (struct usb_serial *serial); #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 @@ int __init edgeport_init(void) 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 @@ int __init edgeport_init(void) ****************************************************************************/ 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 --git a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h index f50de482ed9c..0418ae0a5b67 100644 --- a/drivers/usb/serial/io_tables.h +++ b/drivers/usb/serial/io_tables.h @@ -61,7 +61,7 @@ static struct usb_device_id edgeport_8port_id_table [] = { }; /* 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 --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 56cf9de63b99..81fa9f2479eb 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -142,7 +142,7 @@ static struct usb_device_id edgeport_2port_id_table [] = { }; /* 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 @@ static __devinitdata struct usb_device_id id_table_combined [] = { 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 @@ static int __init edgeport_init(void) { 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 --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 9a9e7481353d..d4eda82398b2 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -94,6 +94,14 @@ static struct usb_device_id ipaq_id_table [] = { 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 void ipaq_shutdown(struct usb_serial *serial) 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 int __init ipaq_init(void) static void __exit ipaq_exit(void) { + usb_deregister(&ipaq_driver); usb_serial_deregister(&ipaq_device); } diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 875974dfdb69..d576176aa492 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c @@ -129,6 +129,13 @@ static struct usb_device_id id_table [] = { 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 void ir_set_termios (struct usb_serial_port *port, struct termios *old_te 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 int __init ir_init (void) static void __exit ir_exit (void) { + usb_deregister (&ir_driver); usb_serial_deregister (&ir_device); } diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 346feb9e4719..b7a94800bf62 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -183,6 +183,7 @@ static int __init keyspan_init (void) 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 int __init keyspan_init (void) 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 --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h index 793c62c00011..42459023bc33 100644 --- a/drivers/usb/serial/keyspan.h +++ b/drivers/usb/serial/keyspan.h @@ -408,7 +408,7 @@ static const struct keyspan_device_details *keyspan_devices[] = { 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 @@ static __devinitdata struct usb_device_id keyspan_ids_combined[] = { 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 --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index a02953f52440..d99e71214d5f 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -140,7 +140,7 @@ struct keyspan_pda_private { #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 @@ static __devinitdata struct usb_device_id id_table_combined [] = { 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 @@ static int __init keyspan_pda_init (void) #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 int __init keyspan_pda_init (void) 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 --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index cb419f5c5e9e..1974edc727e7 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -117,6 +117,12 @@ static struct usb_device_id id_table [] = { 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 void klsi_105_unthrottle (struct usb_serial_port *port) 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 int __init klsi_105_init (void) static void __exit klsi_105_exit (void) { + usb_deregister (&kl5kusb105d_driver); usb_serial_deregister (&kl5kusb105d_device); } diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index acd21aaca6ec..9fe49a3b591f 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -139,6 +139,12 @@ static struct usb_device_id id_table_combined [] = { 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 mct_u232_ioctl (struct usb_serial_port *port, struct file * file, 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 int __init mct_u232_init (void) static void __exit mct_u232_exit (void) { + usb_deregister (&mct_u232_driver); usb_serial_deregister (&mct_u232_device); } diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 29e1231cd124..6fbad950b224 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -83,6 +83,13 @@ static struct usb_device_id id_table [] = { 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 void omninet_shutdown (struct usb_serial *serial) 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 int __init omninet_init (void) static void __exit omninet_exit (void) { + usb_deregister (&omninet_driver); usb_serial_deregister (&zyxel_omninet_device); } diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 4932fb763689..45251e51d95f 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -78,6 +78,12 @@ static struct usb_device_id id_table [] = { 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 void pl2303_write_bulk_callback (struct urb *urb) 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 int __init pl2303_init (void) static void __exit pl2303_exit (void) { + usb_deregister (&pl2303_driver); usb_serial_deregister (&pl2303_device); } diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 196e940c8266..1f64274873de 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c @@ -161,6 +161,13 @@ static struct usb_device_id id_table[] = { 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 @@ static int __init safe_init (void) } 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 --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h index 3cfe84a65fd7..a8755213aefe 100644 --- a/drivers/usb/serial/usb-serial.h +++ b/drivers/usb/serial/usb-serial.h @@ -233,6 +233,9 @@ struct usb_serial_device_type { 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 --git a/drivers/usb/serial/usbserial.c b/drivers/usb/serial/usbserial.c index c893549b9a2e..aa421e58247e 100644 --- a/drivers/usb/serial/usbserial.c +++ b/drivers/usb/serial/usbserial.c @@ -379,30 +379,23 @@ static struct usb_serial_device_type generic_device = { .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 @@ static struct usb_driver usb_serial_driver = { 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 @@ static struct usb_serial * create_serial (struct usb_device *dev, 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 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum, /* 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 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum, 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 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum, if (retval < 0) { dbg ("sub driver rejected device"); kfree (serial); - return NULL; + return -ENODEV; } } @@ -1258,6 +1249,7 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum, } #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 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum, } /* END HORRIBLE HACK FOR PL2303 */ #endif +#endif /* found all that we need */ info("%s converter detected", type->name); @@ -1292,7 +1285,7 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum, if (num_ports == 0) { err("Generic device with no bulk out, not allowed."); kfree (serial); - return NULL; + return -EIO; } } #endif @@ -1312,7 +1305,7 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum, 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 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum, if (retval > 0) { /* quietly accept this device, but don't bind to a serial port * as it's about to disappear */ - return serial; + dev_set_drvdata (&interface->dev, serial); + return 0; } } @@ -1455,7 +1449,9 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum, } #endif - return serial; /* success */ + /* success */ + dev_set_drvdata (&interface->dev, serial); + return 0; probe_error: @@ -1486,16 +1482,18 @@ probe_error: /* 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 = dev_get_drvdata (&interface->dev); struct usb_serial_port *port; int i; dbg ("%s", __FUNCTION__); + + dev_set_drvdata (&interface->dev, NULL); if (serial) { /* fail all future close/read/write/ioctl/etc calls */ for (i = 0; i < serial->num_ports; ++i) { @@ -1554,10 +1552,8 @@ static void usb_serial_disconnect(struct usb_device *dev, void *ptr) /* free up any memory that we allocated */ kfree (serial); - - } else { - info("device disconnected"); } + info("device disconnected"); } @@ -1663,8 +1659,6 @@ int usb_serial_register(struct usb_serial_device_type *new_device) info ("USB Serial support registered for %s", new_device->name); - usb_scan_devices(); - return 0; } @@ -1681,7 +1675,7 @@ void usb_serial_deregister(struct usb_serial_device_type *device) 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 @@ void usb_serial_deregister(struct usb_serial_device_type *device) 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 --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 67078c7f8d41..caef61d6f86d 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -197,7 +197,7 @@ static struct usb_device_id clie_id_3_5_table [] = { { } /* 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 @@ static __devinitdata struct usb_device_id id_table_combined [] = { 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 @@ static int __init visor_init (void) { 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 int __init visor_init (void) static void __exit visor_exit (void) { + usb_deregister (&visor_driver); usb_serial_deregister (&handspring_device); usb_serial_deregister (&clie_3_5_device); } diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 3b6147b95958..925e9bf102ad 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -110,7 +110,7 @@ static struct usb_device_id id_table_prerenumeration [] = { { } /* 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 @@ static __devinitdata struct usb_device_id id_table_combined [] = { 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 @@ static int __init whiteheat_init (void) { 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 int __init whiteheat_init (void) static void __exit whiteheat_exit (void) { + usb_deregister (&whiteheat_driver); usb_serial_deregister (&whiteheat_fake_device); usb_serial_deregister (&whiteheat_device); } diff --git a/drivers/usb/storage/debug.c b/drivers/usb/storage/debug.c index cb477dfba3dc..142441d9e8c9 100644 --- a/drivers/usb/storage/debug.c +++ b/drivers/usb/storage/debug.c @@ -189,7 +189,7 @@ void usb_stor_print_Scsi_Cmnd( Scsi_Cmnd* cmd ) US_DEBUGP("Buffer has %d scatterlists.\n", cmd->use_sg ); for ( i=0; i<cmd->use_sg; i++ ) { - char *adr = page_address(sg[i].page) + sg[i].offset; + char *adr = sg_address(sg[i]); US_DEBUGP("Length of scatterlist %d is %d.\n",i,sg[i].length); US_DEBUGP("%02x %02x %02x %02x %02x %02x %02x %02x\n" diff --git a/drivers/usb/storage/debug.h b/drivers/usb/storage/debug.h index c1e5d95e1669..9ca10f2d724e 100644 --- a/drivers/usb/storage/debug.h +++ b/drivers/usb/storage/debug.h @@ -48,7 +48,7 @@ #include <linux/kernel.h> #include <linux/blk.h> #include <linux/cdrom.h> -#include "scsi.h" +#include "usb.h" #define USB_STORAGE "usb-storage: " diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c index c8d70991ae3a..e193ffe56a2e 100644 --- a/drivers/usb/storage/freecom.c +++ b/drivers/usb/storage/freecom.c @@ -148,11 +148,11 @@ static void us_transfer_freecom(Scsi_Cmnd *srb, struct us_data* us, int transfer if (transfer_amount - total_transferred >= sg[i].length) { result = usb_stor_transfer_partial(us, - page_address(sg[i].page) + sg[i].offset, sg[i].length); + sg_address(sg[i]), sg[i].length); total_transferred += sg[i].length; } else { result = usb_stor_transfer_partial(us, - page_address(sg[i].page) + sg[i].offset, + sg_address(sg[i]), transfer_amount - total_transferred); total_transferred += transfer_amount - total_transferred; } diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index f131cd2eb833..f80db3ba115b 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c @@ -425,7 +425,8 @@ static int isd200_transfer_partial( struct us_data *us, /* if we stall, we need to clear it before we go on */ if (result == -EPIPE) { US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe); - usb_stor_clear_halt(us, pipe); + if (usb_stor_clear_halt(us, pipe) < 0) + return ISD200_TRANSPORT_FAILED; } /* did we send all the data? */ @@ -501,13 +502,13 @@ static void isd200_transfer( struct us_data *us, Scsi_Cmnd *srb ) sg[i].length) { result = isd200_transfer_partial(us, srb->sc_data_direction, - page_address(sg[i].page) + sg[i].offset, + sg_address(sg[i]), sg[i].length); total_transferred += sg[i].length; } else result = isd200_transfer_partial(us, srb->sc_data_direction, - page_address(sg[i].page) + sg[i].offset, + sg_address(sg[i]), transfer_amount - total_transferred); /* if we get an error, end the loop here */ @@ -589,7 +590,8 @@ int isd200_Bulk_transport( struct us_data *us, Scsi_Cmnd *srb, else if (result == -EPIPE) { /* if we stall, we need to clear it before we go on */ US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe); - usb_stor_clear_halt(us, pipe); + if (usb_stor_clear_halt(us, pipe) < 0) + return ISD200_TRANSPORT_ERROR; } else if (result) return ISD200_TRANSPORT_ERROR; @@ -621,7 +623,8 @@ int isd200_Bulk_transport( struct us_data *us, Scsi_Cmnd *srb, /* did the attempt to read the CSW fail? */ if (result == -EPIPE) { US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe); - usb_stor_clear_halt(us, pipe); + if (usb_stor_clear_halt(us, pipe) < 0) + return ISD200_TRANSPORT_ERROR; /* get the status again */ US_DEBUGP("Attempting to get CSW (2nd try)...\n"); @@ -824,7 +827,7 @@ void isd200_invoke_transport( struct us_data *us, case ISD200_TRANSPORT_GOOD: /* Indicate a good result */ - srb->result = GOOD; + srb->result = GOOD << 1; break; case ISD200_TRANSPORT_ABORTED: @@ -946,15 +949,6 @@ int isd200_write_config( struct us_data *us ) US_DEBUGP(" ISD200 Config Data was written successfully\n"); } else { US_DEBUGP(" Request to write ISD200 Config Data failed!\n"); - - /* STALL must be cleared when they are detected */ - if (result == -EPIPE) { - US_DEBUGP("-- Stall on control pipe. Clearing\n"); - result = usb_stor_clear_halt(us, - usb_sndctrlpipe(us->pusb_dev, 0)); - US_DEBUGP("-- usb_stor_clear_halt() returns %d\n", result); - - } retStatus = ISD200_ERROR; } @@ -1000,15 +994,6 @@ int isd200_read_config( struct us_data *us ) #endif } else { US_DEBUGP(" Request to get ISD200 Config Data failed!\n"); - - /* STALL must be cleared when they are detected */ - if (result == -EPIPE) { - US_DEBUGP("-- Stall on control pipe. Clearing\n"); - result = usb_stor_clear_halt(us, - usb_sndctrlpipe(us->pusb_dev, 0)); - US_DEBUGP("-- usb_stor_clear_halt() returns %d\n", result); - - } retStatus = ISD200_ERROR; } @@ -1271,7 +1256,7 @@ int isd200_get_inquiry_data( struct us_data *us ) /* ATA Command Identify successful */ int i; __u16 *src, *dest; - ata_fix_driveid(&info->drive); + ide_fix_driveid(&info->drive); US_DEBUGP(" Identify Data Structure:\n"); US_DEBUGP(" config = 0x%x\n", info->drive.config); @@ -1409,10 +1394,10 @@ void isd200_data_copy(Scsi_Cmnd *srb, char * src, int length) /* transfer the lesser of the next buffer or the * remaining data */ if (len - total >= sg[i].length) { - memcpy(page_address(sg[i].page) + sg[i].offset, src + total, sg[i].length); + memcpy(sg_address(sg[i]), src + total, sg[i].length); total += sg[i].length; } else { - memcpy(page_address(sg[i].page) + sg[i].offset, src + total, len - total); + memcpy(sg_address(sg[i]), src + total, len - total); total = len; } } @@ -1462,7 +1447,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us, /* copy InquiryData */ isd200_data_copy(srb, (char *) &info->InquiryData, srb->request_bufflen); - srb->result = GOOD; + srb->result = GOOD << 1; sendToTransport = FALSE; break; @@ -1482,7 +1467,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us, srb->request_bufflen = 0; } else { US_DEBUGP(" Media Status not supported, just report okay\n"); - srb->result = GOOD; + srb->result = GOOD << 1; sendToTransport = FALSE; } break; @@ -1503,7 +1488,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us, srb->request_bufflen = 0; } else { US_DEBUGP(" Media Status not supported, just report okay\n"); - srb->result = GOOD; + srb->result = GOOD << 1; sendToTransport = FALSE; } break; @@ -1529,7 +1514,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us, srb->request_bufflen = sizeof(struct read_capacity_data); isd200_data_copy(srb, (char *) &readCapacityData, srb->request_bufflen); - srb->result = GOOD; + srb->result = GOOD << 1; sendToTransport = FALSE; } break; @@ -1613,7 +1598,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us, srb->request_bufflen = 0; } else { US_DEBUGP(" Not removeable media, just report okay\n"); - srb->result = GOOD; + srb->result = GOOD << 1; sendToTransport = FALSE; } break; @@ -1642,7 +1627,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us, srb->request_bufflen = 0; } else { US_DEBUGP(" Nothing to do, just report okay\n"); - srb->result = GOOD; + srb->result = GOOD << 1; sendToTransport = FALSE; } break; diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c index d80cb3377839..a57de85be614 100644 --- a/drivers/usb/storage/protocol.c +++ b/drivers/usb/storage/protocol.c @@ -65,7 +65,7 @@ find_data_location(Scsi_Cmnd *srb) { struct scatterlist *sg; sg = (struct scatterlist *) srb->request_buffer; - return (void *) page_address(sg[0].page) + sg[0].offset; + return (void *) sg_address(sg[0]); } else return (void *) srb->request_buffer; } diff --git a/drivers/usb/storage/raw_bulk.c b/drivers/usb/storage/raw_bulk.c index 14413f01282c..e5d109f337d1 100644 --- a/drivers/usb/storage/raw_bulk.c +++ b/drivers/usb/storage/raw_bulk.c @@ -67,12 +67,9 @@ usb_storage_send_control(struct us_data *us, // Check the return code for the command. if (result < 0) { - /* a stall is a fatal condition from the device */ + /* a stall indicates a protocol error */ if (result == -EPIPE) { - US_DEBUGP("-- Stall on control pipe. Clearing\n"); - result = usb_stor_clear_halt(us, pipe); - US_DEBUGP("-- usb_stor_clear_halt() returns %d\n", - result); + US_DEBUGP("-- Stall on control pipe\n"); return USB_STOR_TRANSPORT_FAILED; } @@ -102,7 +99,8 @@ usb_storage_raw_bulk(struct us_data *us, int direction, unsigned char *data, US_DEBUGP("EPIPE: clearing endpoint halt for" " pipe 0x%x, stalled at %d bytes\n", pipe, *act_len); - usb_stor_clear_halt(us, pipe); + if (usb_stor_clear_halt(us, pipe) < 0) + return US_BULK_TRANSFER_FAILED; /* return US_BULK_TRANSFER_SHORT; */ } @@ -191,7 +189,7 @@ usb_storage_bulk_transport(struct us_data *us, int direction, unsigned char *buf; unsigned int length; - buf = page_address(sg[i].page) + sg[i].offset; + buf = sg_address(sg[i]); length = len-transferred; if (length > sg[i].length) length = sg[i].length; @@ -261,7 +259,7 @@ us_copy_from_sgbuf(unsigned char *content, int len, unsigned char *ptr; unsigned int length, room; - ptr = page_address(sg[i].page) + sg[i].offset + *offset; + ptr = sg_address(sg[i]) + *offset; room = sg[i].length - *offset; length = len - transferred; @@ -310,7 +308,7 @@ us_copy_to_sgbuf(unsigned char *buffer, int buflen, unsigned char *ptr; unsigned int length, room; - ptr = page_address(sg[i].page) + sg[i].offset + *offset; + ptr = sg_address(sg[i]) + *offset; room = sg[i].length - *offset; length = buflen - transferred; diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 05afe6af3369..928b739597b4 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -252,7 +252,6 @@ static int bus_reset( Scsi_Cmnd *srb ) 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 @@ static int bus_reset( Scsi_Cmnd *srb ) /* 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); @@ -563,8 +559,8 @@ int usb_stor_scsiSense10to6( Scsi_Cmnd* the10 ) /* copy one byte */ { - char *src = page_address(sg[sb].page) + sg[sb].offset + si; - char *dst = page_address(sg[db].page) + sg[db].offset + di; + char *src = sg_address(sg[sb]) + si; + char *dst = sg_address(sg[db]) + di; *dst = *src; } @@ -605,7 +601,7 @@ int usb_stor_scsiSense10to6( Scsi_Cmnd* the10 ) break; } - *(char*)(page_address(sg[db].page) + sg[db].offset) = 0; + *(char*)(sg_address(sg[db])) = 0; /* get next destination */ if ( sg[db].length-1 == di ) @@ -756,8 +752,8 @@ int usb_stor_scsiSense6to10( Scsi_Cmnd* the6 ) /* copy one byte */ { - char *src = page_address(sg[sb].page) + sg[sb].offset + si; - char *dst = page_address(sg[db].page) + sg[db].offset + di; + char *src = sg_address(sg[sb]) + si; + char *dst = sg_address(sg[db]) + di; *dst = *src; } @@ -798,7 +794,7 @@ int usb_stor_scsiSense6to10( Scsi_Cmnd* the6 ) } { - char *dst = page_address(sg[db].page) + sg[db].offset + di; + char *dst = sg_address(sg[db]) + di; *dst = tempBuffer[element-USB_STOR_SCSI_SENSE_HDRSZ]; } @@ -852,17 +848,14 @@ void usb_stor_scsiSenseParseBuffer( Scsi_Cmnd* srb, Usb_Stor_Scsi_Sense_Hdr_u* t if ( element < USB_STOR_SCSI_SENSE_HDRSZ ) { /* fill in the pointers for both header types */ - the6->array[element] = page_address(sg[i].page) + - sg[i].offset + j; - the10->array[element] = page_address(sg[i].page) + - sg[i].offset + j; + the6->array[element] = sg_address(sg[i]) + j; + the10->array[element] = sg_address(sg[i]) + j; } else if ( element < USB_STOR_SCSI_SENSE_10_HDRSZ ) { /* only the longer headers still cares now */ - the10->array[element] = page_address(sg[i].page) + - sg[i].offset + j; + the10->array[element] = sg_address(sg[i]) + j; } /* increase element counter */ diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index ee1da8029fd1..9ec451ac69d2 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c @@ -1091,25 +1091,23 @@ sddr09_read_map(struct us_data *us) { return 0; for (i=0; i<alloc_blocks; i++) { - if (i<alloc_blocks-1) { - char *vaddr = kmalloc(1 << 17, GFP_NOIO); - sg[i].page = virt_to_page(vaddr); - sg[i].offset = ((unsigned long)vaddr & ~PAGE_MASK); - sg[i].length = (1<<17); - } else { - char *vaddr = kmalloc(alloc_len, GFP_NOIO); - sg[i].page = virt_to_page(vaddr); - sg[i].offset = ((unsigned long)vaddr & ~PAGE_MASK); - sg[i].length = alloc_len; - } - alloc_len -= sg[i].length; + int alloc_req = (i < alloc_blocks-1 ? 1 << 17 : alloc_len); + char *vaddr = kmalloc(alloc_req, GFP_NOIO); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,3) + sg[i].page = virt_to_page(vaddr); + sg[i].offset = ((unsigned long)vaddr & ~PAGE_MASK); +#else + sg[i].address = vaddr; +#endif + sg[i].length = alloc_req; + alloc_len -= alloc_req; } for (i=0; i<alloc_blocks; i++) if (sg[i].page == NULL) { for (i=0; i<alloc_blocks; i++) if (sg[i].page != NULL) - kfree(page_address(sg[i].page) + sg[i].offset); + kfree(sg_address(sg[i])); kfree(sg); return 0; } @@ -1120,7 +1118,7 @@ sddr09_read_map(struct us_data *us) { (unsigned char *)sg, alloc_blocks); if (result != USB_STOR_TRANSPORT_GOOD) { for (i=0; i<alloc_blocks; i++) - kfree(page_address(sg[i].page) + sg[i].offset); + kfree(sg_address(sg[i])); kfree(sg); return -1; } @@ -1136,7 +1134,7 @@ sddr09_read_map(struct us_data *us) { info->lba_to_pba = NULL; info->pba_to_lba = NULL; for (i=0; i<alloc_blocks; i++) - kfree(page_address(sg[i].page) + sg[i].offset); + kfree(sg_address(sg[i])); kfree(sg); return 0; } @@ -1144,7 +1142,7 @@ sddr09_read_map(struct us_data *us) { for (i = 0; i < numblocks; i++) info->lba_to_pba[i] = info->pba_to_lba[i] = UNDEF; - ptr = page_address(sg[0].page)+sg[0].offset; + ptr = sg_address(sg[0]); /* * Define lba-pba translation table @@ -1153,8 +1151,7 @@ sddr09_read_map(struct us_data *us) { // scatterlist block i*64/128k = i*(2^6)*(2^-17) = i*(2^-11) for (i=0; i<numblocks; i++) { - ptr = page_address(sg[i>>11].page) + - sg[i>>11].offset + ((i&0x7ff)<<6); + ptr = sg_address(sg[i>>11]) + ((i&0x7ff)<<6); if (i == 0 || i == 1) { info->pba_to_lba[i] = UNUSABLE; @@ -1264,7 +1261,7 @@ sddr09_read_map(struct us_data *us) { US_DEBUGP("Found %d LBA's\n", lbact); for (i=0; i<alloc_blocks; i++) - kfree(page_address(sg[i].page) + sg[i].offset); + kfree(sg_address(sg[i])); kfree(sg); return 0; } diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index 72f324831308..f908d3089eb7 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c @@ -348,10 +348,13 @@ int usbat_rw_block_test(struct us_data *us, * the bulk output pipe only the first time. */ - if (direction==SCSI_DATA_READ && i==0) - usb_stor_clear_halt(us, + if (direction==SCSI_DATA_READ && i==0) { + if (usb_stor_clear_halt(us, usb_sndbulkpipe(us->pusb_dev, - us->ep_out)); + us->ep_out)) < 0) + return USB_STOR_TRANSPORT_ERROR; + } + /* * Read status: is the device angry, or just busy? */ diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 70cac2634164..205e8ea7aea7 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -349,8 +349,8 @@ unsigned int usb_stor_transfer_length(Scsi_Cmnd *srb) * all the complex logic above, let's find them and eliminate them. */ if (len != srb->request_bufflen) { - printk("USB len=%d, request_bufflen=%d\n", len, srb->request_bufflen); - show_trace(NULL); + printk(KERN_ERR "USB len=%d, request_bufflen=%d\n", len, srb->request_bufflen); + printk(KERN_ERR "Fix this -- future 2.5 kernels will not work if this is not fixed!\n"); } return len; @@ -370,16 +370,20 @@ unsigned int usb_stor_transfer_length(Scsi_Cmnd *srb) * as those occurring during device-specific initialization, must be handled * by a separate code path.) * - * The abort function first sets the machine state, then acquires the lock - * on the current_urb before checking if it needs to be aborted. + * The abort function first sets the machine state, then atomically + * tests-and-clears the CAN_CANCEL bit in us->flags to see if the current_urb + * needs to be aborted. * - * When a function submits the current_urb, it must first grab the - * current_urb_sem to prevent the abort function from trying to cancel the - * URB while the submit call is underway. After a function submits the - * current_urb, it -MUST- test the state to see if we got aborted just before - * the submission. If so, it's essential to abort the URB if it's still in - * progress. Either way, the function must then release the lock and wait - * for the URB to finish. + * The submit function first verifies that the submission completed without + * errors, and only then sets the CAN_CANCEL bit. This prevents the abort + * function from trying to cancel the URB while the submit call is underway. + * Next, the submit function must test the state to see if we got aborted + * before the submission or before setting the CAN_CANCEL bit. If so, it's + * essential to abort the URB if it hasn't been cancelled already (i.e., + * if the CAN_CANCEL bit is still set). Either way, the function must then + * wait for the URB to finish. Note that because the USB_ASYNC_UNLINK flag + * is set, the URB can still be in progress even after a call to + * usb_unlink_urb() returns. * * (It's also permissible, but not necessary, to test the state -before- * submitting the URB. Doing so would prevent an unnecessary submission if @@ -389,7 +393,7 @@ unsigned int usb_stor_transfer_length(Scsi_Cmnd *srb) * * The idea is that (1) once the state is changed to ABORTING, either the * aborting function or the submitting function is guaranteed to call - * usb_unlink_urb() for an active URB, and (2) current_urb_sem prevents + * usb_unlink_urb() for an active URB, and (2) test_and_clear_bit() prevents * usb_unlink_urb() from being called more than once or from being called * during usb_submit_urb(). */ @@ -424,28 +428,30 @@ static int usb_stor_msg_common(struct us_data *us) us->current_urb->error_count = 0; us->current_urb->transfer_flags = USB_ASYNC_UNLINK; - /* lock and submit the URB */ - down(&(us->current_urb_sem)); + /* submit the URB */ status = usb_submit_urb(us->current_urb, GFP_NOIO); if (status) { /* something went wrong */ - up(&(us->current_urb_sem)); return status; } + /* since the URB has been submitted successfully, it's now okay + * to cancel it */ + set_bit(US_FLIDX_CAN_CANCEL, &us->flags); + /* has the current command been aborted? */ if (atomic_read(&us->sm_state) == US_STATE_ABORTING) { /* cancel the URB, if it hasn't been cancelled already */ - if (us->current_urb->status == -EINPROGRESS) { + if (test_and_clear_bit(US_FLIDX_CAN_CANCEL, &us->flags)) { US_DEBUGP("-- cancelling URB\n"); usb_unlink_urb(us->current_urb); } } - up(&(us->current_urb_sem)); /* wait for the completion of the URB */ wait_for_completion(&urb_done); + clear_bit(US_FLIDX_CAN_CANCEL, &us->flags); /* return the URB status */ return us->current_urb->status; @@ -565,7 +571,8 @@ int usb_stor_transfer_partial(struct us_data *us, char *buf, int length) /* if we stall, we need to clear it before we go on */ if (result == -EPIPE) { US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe); - usb_stor_clear_halt(us, pipe); + if (usb_stor_clear_halt(us, pipe) < 0) + return US_BULK_TRANSFER_FAILED; } /* did we abort this command? */ @@ -635,11 +642,11 @@ void usb_stor_transfer(Scsi_Cmnd *srb, struct us_data* us) if (transfer_amount - total_transferred >= sg[i].length) { result = usb_stor_transfer_partial(us, - page_address(sg[i].page) + sg[i].offset, sg[i].length); + sg_address(sg[i]), sg[i].length); total_transferred += sg[i].length; } else result = usb_stor_transfer_partial(us, - page_address(sg[i].page) + sg[i].offset, + sg_address(sg[i]), transfer_amount - total_transferred); /* if we get an error, end the loop here */ @@ -867,15 +874,13 @@ void usb_stor_abort_transport(struct us_data *us) /* If the state machine is blocked waiting for an URB or an IRQ, * let's wake it up */ - /* If we have an URB pending, cancel it. Note that we guarantee with - * the current_urb_sem that if a URB has just been submitted, it + /* If we have an URB pending, cancel it. The test_and_clear_bit() + * call guarantees that if a URB has just been submitted, it * won't be cancelled more than once. */ - down(&(us->current_urb_sem)); - if (us->current_urb->status == -EINPROGRESS) { + if (test_and_clear_bit(US_FLIDX_CAN_CANCEL, &us->flags)) { US_DEBUGP("-- cancelling URB\n"); usb_unlink_urb(us->current_urb); } - up(&(us->current_urb_sem)); /* If we are waiting for an IRQ, simulate it */ if (test_bit(US_FLIDX_IP_WANTED, &us->flags)) { @@ -993,18 +998,9 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us) return US_BULK_TRANSFER_ABORTED; } - /* STALL must be cleared when it is detected */ + /* a stall indicates a protocol error */ if (result == -EPIPE) { - US_DEBUGP("-- Stall on control pipe. Clearing\n"); - result = usb_stor_clear_halt(us, - usb_sndctrlpipe(us->pusb_dev, 0)); - - /* did we abort this command? */ - if (atomic_read(&us->sm_state) == US_STATE_ABORTING) { - US_DEBUGP("usb_stor_control_msg(): transfer aborted\n"); - return US_BULK_TRANSFER_ABORTED; - } - + US_DEBUGP("-- Stall on control pipe\n"); return USB_STOR_TRANSPORT_FAILED; } @@ -1110,17 +1106,9 @@ int usb_stor_CB_transport(Scsi_Cmnd *srb, struct us_data *us) return US_BULK_TRANSFER_ABORTED; } - /* a stall is a fatal condition from the device */ + /* a stall indicates a protocol error */ if (result == -EPIPE) { - US_DEBUGP("-- Stall on control pipe. Clearing\n"); - result = usb_stor_clear_halt(us, - usb_sndctrlpipe(us->pusb_dev, 0)); - - /* did we abort this command? */ - if (atomic_read(&us->sm_state) == US_STATE_ABORTING) { - US_DEBUGP("usb_stor_CB_transport(): transfer aborted\n"); - return US_BULK_TRANSFER_ABORTED; - } + US_DEBUGP("-- Stall on control pipe\n"); return USB_STOR_TRANSPORT_FAILED; } @@ -1178,15 +1166,6 @@ int usb_stor_Bulk_max_lun(struct us_data *us) if (result == 1) return data; - /* if we get a STALL, clear the stall */ - if (result == -EPIPE) { - US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe); - - /* Use usb_clear_halt() because this is not a - * scsi queued-command */ - usb_clear_halt(us->pusb_dev, pipe); - } - /* return the default -- no LUNs */ return 0; } @@ -1241,6 +1220,8 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } + if (result < 0) + return USB_STOR_TRANSPORT_ERROR; result = -EPIPE; } else if (result) { /* unknown error -- we've got a problem */ @@ -1289,6 +1270,8 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n"); return US_BULK_TRANSFER_ABORTED; } + if (result < 0) + return USB_STOR_TRANSPORT_ERROR; /* get the status again */ US_DEBUGP("Attempting to get CSW (2nd try)...\n"); diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 67d969a7fa99..2baa9de81604 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -103,10 +103,10 @@ static int my_host_number; 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, @@ -283,13 +283,13 @@ void fill_inquiry_response(struct us_data *us, unsigned char *data, if (us->srb->use_sg) { sg = (struct scatterlist *)us->srb->request_buffer; for (i=0; i<us->srb->use_sg; i++) - memset(page_address(sg[i].page) + sg[i].offset, 0, sg[i].length); + memset(sg_address(sg[i]), 0, sg[i].length); for (i=0, transferred=0; i<us->srb->use_sg && transferred < len; i++) { amt = sg[i].length > len-transferred ? len-transferred : sg[i].length; - memcpy(page_address(sg[i].page) + sg[i].offset, data+transferred, amt); + memcpy(sg_address(sg[i]), data+transferred, amt); transferred -= amt; } } else { @@ -623,9 +623,11 @@ static void usb_stor_deallocate_urbs(struct us_data *ss) } /* 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 */ @@ -650,7 +652,6 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum, /* 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); @@ -680,7 +681,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum, 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"); @@ -724,12 +725,11 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum, US_DEBUGP("Result from usb_set_configuration is %d\n", result); if (result == -EPIPE) { - US_DEBUGP("-- clearing stall on control interface\n"); - usb_clear_halt(dev, usb_sndctrlpipe(dev, 0)); + US_DEBUGP("-- stall on control interface\n"); } 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 @@ -737,7 +737,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum, /* 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 */ @@ -816,7 +816,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum, 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; @@ -825,7 +825,6 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum, init_completion(&(ss->notify)); init_MUTEX_LOCKED(&(ss->ip_waitq)); init_MUTEX(&(ss->irq_urb_sem)); - init_MUTEX(&(ss->current_urb_sem)); init_MUTEX_LOCKED(&(ss->dev_semaphore)); /* copy over the subclass and protocol data */ @@ -1093,8 +1092,9 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum, 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 */ + dev_set_drvdata (&intf->dev, ss); + return 0; /* we come here if there are any problems */ /* ss->dev_semaphore must be locked */ @@ -1104,16 +1104,18 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum, 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 = dev_get_drvdata (&intf->dev); US_DEBUGP("storage_disconnect() called\n"); + dev_set_drvdata (&intf->dev, NULL); + /* this is the odd case -- we disconnected but weren't using it */ if (!ss) { US_DEBUGP("-- device was not in use\n"); diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 19ecbe4b898e..2a9e9a1f6c2e 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -106,6 +106,7 @@ struct us_unusual_dev { #define US_FL_DEV_ATTACHED 0x00010000 /* is the device attached? */ #define US_FLIDX_IP_WANTED 17 /* 0x00020000 is an IRQ expected? */ +#define US_FLIDX_CAN_CANCEL 18 /* 0x00040000 okay to cancel current_urb? */ /* processing state machine states */ @@ -177,7 +178,6 @@ struct us_data { unsigned char irqdata[2]; /* data from USB IRQ */ /* control and bulk communications data */ - struct semaphore current_urb_sem; /* protect current_urb */ struct urb *current_urb; /* non-int USB requests */ struct usb_ctrlrequest *dr; /* control requests */ @@ -206,7 +206,6 @@ extern void fill_inquiry_response(struct us_data *us, * single queue element srb for write access */ #define scsi_unlock(host) spin_unlock_irq(host->host_lock) #define scsi_lock(host) spin_lock_irq(host->host_lock) - -#define sg_address(psg) (page_address((psg)->page) + (psg)->offset) +#define sg_address(psg) (page_address((psg).page) + (psg).offset) #endif diff --git a/fs/xfs/linux/xfs_aops.c b/fs/xfs/linux/xfs_aops.c index f0ba052d1b7d..72202e5a89ff 100644 --- a/fs/xfs/linux/xfs_aops.c +++ b/fs/xfs/linux/xfs_aops.c @@ -653,11 +653,11 @@ STATIC int linvfs_direct_IO( int rw, struct inode *inode, - char *buf, + const struct iovec *iov, loff_t offset, - size_t count) + unsigned long nr_segs) { - return generic_direct_IO(rw, inode, buf, offset, count, + return generic_direct_IO(rw, inode, iov, offset, nr_segs, linvfs_get_blocks_direct); } diff --git a/fs/xfs/linux/xfs_lrw.c b/fs/xfs/linux/xfs_lrw.c index b338349bf5b5..abb820267d95 100644 --- a/fs/xfs/linux/xfs_lrw.c +++ b/fs/xfs/linux/xfs_lrw.c @@ -433,6 +433,7 @@ xfs_write( xfs_fsize_t n, limit = XFS_MAX_FILE_OFFSET; xfs_iocore_t *io; vnode_t *vp; + struct iovec iov; int iolock; int direct = file->f_flags & O_DIRECT; int eventsent = 0; @@ -571,7 +572,10 @@ retry: xfs_inval_cached_pages(vp, &xip->i_iocore, *offset, 1, 1); } - ret = generic_file_write_nolock(file, buf, size, offset); + iov.iov_base = (void *)buf; + iov.iov_len = size; + + ret = generic_file_write_nolock(file, &iov, 1, offset); if ((ret == -ENOSPC) && DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_NOSPACE) && diff --git a/fs/xfs/linux/xfs_version.h b/fs/xfs/linux/xfs_version.h index 229bb86ee173..5a41ef00df68 100644 --- a/fs/xfs/linux/xfs_version.h +++ b/fs/xfs/linux/xfs_version.h @@ -39,6 +39,6 @@ #ifndef __XFS_VERSION_H__ #define __XFS_VERSION_H__ -#define XFS_VERSION_STRING "CVS" +#define XFS_VERSION_STRING "CVS-09/15/02:17" #endif /* __XFS_VERSION_H__ */ diff --git a/fs/xfs/support/time.h b/fs/xfs/support/time.h index f48b48e6fea4..f0a488fb4f63 100644 --- a/fs/xfs/support/time.h +++ b/fs/xfs/support/time.h @@ -43,7 +43,7 @@ static inline void delay(long ticks) static inline void nanotime(struct timespec *tvp) { tvp->tv_sec = xtime.tv_sec; - tvp->tv_nsec = xtime.tv_usec * 1000; + tvp->tv_nsec = xtime.tv_nsec; } #endif /* __XFS_SUPPORT_TIME_H__ */ diff --git a/include/asm-i386/hardirq.h b/include/asm-i386/hardirq.h index 291ce33484b3..0b521e86de2f 100644 --- a/include/asm-i386/hardirq.h +++ b/include/asm-i386/hardirq.h @@ -77,7 +77,7 @@ typedef struct { #define irq_enter() (preempt_count() += HARDIRQ_OFFSET) #if CONFIG_PREEMPT -# define in_atomic() (preempt_count() != kernel_locked()) +# define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked()) # define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1) #else # define in_atomic() (preempt_count() != 0) diff --git a/include/linux/device.h b/include/linux/device.h index 9b310071cb41..21f789350502 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -306,6 +306,18 @@ g_list_to_dev(struct list_head *g_list) 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 --git a/include/linux/usb.h b/include/linux/usb.h index 7e78883daa20..5d323aa0d36e 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -227,7 +227,7 @@ struct usb_interface { 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 struct usb_device *usb_get_dev(struct usb_device *dev); 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 @@ struct usb_device_id { * 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_device_id { */ 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() */ - ); - - struct list_head driver_list; - struct semaphore serialize; + int (*probe) (struct usb_interface *intf, + const struct usb_device_id *id); - /* ioctl -- userspace apps can talk to drivers through usbfs */ - int (*ioctl)(struct usb_device *dev, unsigned int code, void *buf); + void (*disconnect) (struct usb_interface *intf); + + 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 void usb_deregister(struct usb_driver *); 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); + /* -------------------------------------------------------------------------- */ /* |
