summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Simmons <jsimmons@maxwell.earthlink.net>2002-09-16 19:34:34 -0700
committerJames Simmons <jsimmons@maxwell.earthlink.net>2002-09-16 19:34:34 -0700
commit586d2a0d222c497a8f707bf464e48e968129202f (patch)
treee7d9bccb51e1505688aa53d4eaf7fce76f025281
parentc598bcd01bd613127079f83a58cfda8cdfbc8bcc (diff)
parent6b29059af3cb8607e055c5051c608a876572cdf7 (diff)
Merge http://linuxconsole.bkbits.net/stable
into maxwell.earthlink.net:/usr/src/console-stable
-rw-r--r--Documentation/usb/ov511.txt35
-rw-r--r--Documentation/usb/usb-serial.txt4
-rw-r--r--arch/i386/kernel/cpu/amd.c20
-rw-r--r--arch/i386/kernel/cpu/common.c11
-rw-r--r--arch/i386/kernel/cpu/intel.c1
-rw-r--r--arch/i386/kernel/cpu/transmeta.c5
-rw-r--r--drivers/base/core.c3
-rw-r--r--drivers/bluetooth/hci_usb.c22
-rw-r--r--drivers/input/joystick/iforce/iforce-usb.c29
-rw-r--r--drivers/isdn/hisax/st5481_init.c27
-rw-r--r--drivers/media/video/cpia_usb.c31
-rw-r--r--drivers/usb/class/audio.c41
-rw-r--r--drivers/usb/class/bluetty.c31
-rw-r--r--drivers/usb/class/cdc-acm.c30
-rw-r--r--drivers/usb/class/usb-midi.c37
-rw-r--r--drivers/usb/class/usblp.c20
-rw-r--r--drivers/usb/core/devices.c1
-rw-r--r--drivers/usb/core/devio.c61
-rw-r--r--drivers/usb/core/hcd.c8
-rw-r--r--drivers/usb/core/hcd.h8
-rw-r--r--drivers/usb/core/hub.c160
-rw-r--r--drivers/usb/core/hub.h2
-rw-r--r--drivers/usb/core/usb.c565
-rw-r--r--drivers/usb/image/hpusbscsi.c29
-rw-r--r--drivers/usb/image/mdc800.c51
-rw-r--r--drivers/usb/image/microtek.c45
-rw-r--r--drivers/usb/image/microtek.h2
-rw-r--r--drivers/usb/image/scanner.c100
-rw-r--r--drivers/usb/input/aiptek.c62
-rw-r--r--drivers/usb/input/hid-core.c36
-rw-r--r--drivers/usb/input/hiddev.c6
-rw-r--r--drivers/usb/input/powermate.c50
-rw-r--r--drivers/usb/input/usbkbd.c42
-rw-r--r--drivers/usb/input/usbmouse.c56
-rw-r--r--drivers/usb/input/wacom.c33
-rw-r--r--drivers/usb/input/xpad.c31
-rw-r--r--drivers/usb/media/dabusb.c41
-rw-r--r--drivers/usb/media/dsbr100.c37
-rw-r--r--drivers/usb/media/ibmcam.c39
-rw-r--r--drivers/usb/media/konicawc.c45
-rw-r--r--drivers/usb/media/ov511.c205
-rw-r--r--drivers/usb/media/ov511.h18
-rw-r--r--drivers/usb/media/pwc-if.c43
-rw-r--r--drivers/usb/media/se401.c58
-rw-r--r--drivers/usb/media/stv680.c36
-rw-r--r--drivers/usb/media/ultracam.c45
-rw-r--r--drivers/usb/media/usbvideo.c15
-rw-r--r--drivers/usb/media/usbvideo.h4
-rw-r--r--drivers/usb/media/vicam.c49
-rw-r--r--drivers/usb/misc/auerswald.c28
-rw-r--r--drivers/usb/misc/brlvger.c26
-rw-r--r--drivers/usb/misc/emi26.c12
-rw-r--r--drivers/usb/misc/rio500.c51
-rw-r--r--drivers/usb/misc/speedtouch.c67
-rw-r--r--drivers/usb/misc/tiglusb.c31
-rw-r--r--drivers/usb/misc/usblcd.c45
-rw-r--r--drivers/usb/misc/uss720.c42
-rw-r--r--drivers/usb/net/catc.c42
-rw-r--r--drivers/usb/net/cdc-ether.c32
-rw-r--r--drivers/usb/net/kaweth.c56
-rw-r--r--drivers/usb/net/pegasus.c26
-rw-r--r--drivers/usb/net/rtl8150.c53
-rw-r--r--drivers/usb/net/usbnet.c51
-rw-r--r--drivers/usb/serial/belkin_sa.c9
-rw-r--r--drivers/usb/serial/cyberjack.c9
-rw-r--r--drivers/usb/serial/digi_acceleport.c12
-rw-r--r--drivers/usb/serial/empeg.c15
-rw-r--r--drivers/usb/serial/ftdi_sio.c11
-rw-r--r--drivers/usb/serial/io_edgeport.c8
-rw-r--r--drivers/usb/serial/io_tables.h2
-rw-r--r--drivers/usb/serial/io_ti.c11
-rw-r--r--drivers/usb/serial/ipaq.c10
-rw-r--r--drivers/usb/serial/ir-usb.c9
-rw-r--r--drivers/usb/serial/keyspan.c2
-rw-r--r--drivers/usb/serial/keyspan.h9
-rw-r--r--drivers/usb/serial/keyspan_pda.c11
-rw-r--r--drivers/usb/serial/kl5kusb105.c8
-rw-r--r--drivers/usb/serial/mct_u232.c8
-rw-r--r--drivers/usb/serial/omninet.c9
-rw-r--r--drivers/usb/serial/pl2303.c8
-rw-r--r--drivers/usb/serial/safe_serial.c9
-rw-r--r--drivers/usb/serial/usb-serial.h3
-rw-r--r--drivers/usb/serial/usbserial.c72
-rw-r--r--drivers/usb/serial/visor.c11
-rw-r--r--drivers/usb/serial/whiteheat.c11
-rw-r--r--drivers/usb/storage/debug.c2
-rw-r--r--drivers/usb/storage/debug.h2
-rw-r--r--drivers/usb/storage/freecom.c4
-rw-r--r--drivers/usb/storage/isd200.c51
-rw-r--r--drivers/usb/storage/protocol.c2
-rw-r--r--drivers/usb/storage/raw_bulk.c16
-rw-r--r--drivers/usb/storage/scsiglue.c29
-rw-r--r--drivers/usb/storage/sddr09.c35
-rw-r--r--drivers/usb/storage/shuttle_usbat.c9
-rw-r--r--drivers/usb/storage/transport.c93
-rw-r--r--drivers/usb/storage/usb.c42
-rw-r--r--drivers/usb/storage/usb.h5
-rw-r--r--fs/xfs/linux/xfs_aops.c6
-rw-r--r--fs/xfs/linux/xfs_lrw.c6
-rw-r--r--fs/xfs/linux/xfs_version.h2
-rw-r--r--fs/xfs/support/time.h2
-rw-r--r--include/asm-i386/hardirq.h2
-rw-r--r--include/linux/device.h12
-rw-r--r--include/linux/usb.h43
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);
+
/* -------------------------------------------------------------------------- */
/*