# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.582   -> 1.583  
#	drivers/usb/media/konicawc.c	1.11    -> 1.12   
#	drivers/usb/media/ultracam.c	1.6     -> 1.7    
#	drivers/usb/media/ibmcam.c	1.12    -> 1.13   
#	drivers/usb/media/se401.c	1.25    -> 1.26   
#	drivers/usb/media/ov511.c	1.32    -> 1.33   
#	drivers/usb/media/vicam.c	1.16    -> 1.17   
#	drivers/usb/media/dsbr100.c	1.12    -> 1.13   
#	drivers/usb/media/usbvideo.h	1.16    -> 1.17   
#	drivers/usb/media/dabusb.c	1.22    -> 1.23   
#	drivers/usb/media/stv680.c	1.19    -> 1.20   
#	drivers/usb/media/pwc-if.c	1.24    -> 1.25   
#	drivers/usb/media/usbvideo.c	1.26    -> 1.27   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/16	greg@kroah.com	1.583
# USB: convert the drivers/usb/media files to the new USB driver model.
# --------------------------------------------
#
diff -Nru a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c
--- a/drivers/usb/media/dabusb.c	Mon Sep 16 15:00:27 2002
+++ b/drivers/usb/media/dabusb.c	Mon Sep 16 15:00:27 2002
@@ -713,9 +713,10 @@
 };
 
 /* --------------------------------------------------------------------- */
-static void *dabusb_probe (struct usb_device *usbdev, unsigned int ifnum,
-			   const struct usb_device_id *id)
+static int dabusb_probe (struct usb_interface *intf, 
+			 const struct usb_device_id *id)
 {
+	struct usb_device *usbdev = interface_to_usbdev(intf);
 	int devnum;
 	int retval;
 	pdabusb_t s;
@@ -725,14 +726,14 @@
 
 	/* We don't handle multiple configurations */
 	if (usbdev->descriptor.bNumConfigurations != 1)
-		return NULL;
+		return -ENODEV;
 
-	if (ifnum != _DABUSB_IF && usbdev->descriptor.idProduct == 0x9999)
-		return NULL;
+	if (intf->altsetting->bInterfaceNumber != _DABUSB_IF && usbdev->descriptor.idProduct == 0x9999)
+		return -ENODEV;
 
 	retval = usb_register_dev (&dabusb_fops, DABUSB_MINOR, 1, &devnum);
 	if (retval)
-		return NULL;
+		return -ENOMEM;
 
 	s = &dabusb[devnum];
 
@@ -760,28 +761,32 @@
 	dbg("bound to interface: %d", ifnum);
 	up (&s->mutex);
 	MOD_INC_USE_COUNT;
-	return s;
+	dev_set_drvdata (&intf->dev, s);
+	return 0;
 
       reject:
 	up (&s->mutex);
 	s->usbdev = NULL;
-	return NULL;
+	return -ENODEV;
 }
 
-static void dabusb_disconnect (struct usb_device *usbdev, void *ptr)
+static void dabusb_disconnect (struct usb_interface *intf)
 {
-	pdabusb_t s = (pdabusb_t) ptr;
+	pdabusb_t s = dev_get_drvdata (&intf->dev);
 
 	dbg("dabusb_disconnect");
 
-	usb_deregister_dev (1, s->devnum);
-	s->remove_pending = 1;
-	wake_up (&s->wait);
-	if (s->state == _started)
-		sleep_on (&s->remove_ok);
-	s->usbdev = NULL;
-	s->overruns = 0;
-	MOD_DEC_USE_COUNT;
+	dev_set_drvdata (&intf->dev, NULL);
+	if (s) {
+		usb_deregister_dev (1, s->devnum);
+		s->remove_pending = 1;
+		wake_up (&s->wait);
+		if (s->state == _started)
+			sleep_on (&s->remove_ok);
+		s->usbdev = NULL;
+		s->overruns = 0;
+		MOD_DEC_USE_COUNT;
+	}
 }
 
 static struct usb_device_id dabusb_ids [] = {
diff -Nru a/drivers/usb/media/dsbr100.c b/drivers/usb/media/dsbr100.c
--- a/drivers/usb/media/dsbr100.c	Mon Sep 16 15:00:27 2002
+++ b/drivers/usb/media/dsbr100.c	Mon Sep 16 15:00:27 2002
@@ -78,9 +78,9 @@
 
 #define TB_LEN 16
 
-static void *usb_dsbr100_probe(struct usb_device *dev, unsigned int ifnum,
-			 const struct usb_device_id *id);
-static void usb_dsbr100_disconnect(struct usb_device *dev, void *ptr);
+static int usb_dsbr100_probe(struct usb_interface *intf,
+			     const struct usb_device_id *id);
+static void usb_dsbr100_disconnect(struct usb_interface *intf);
 static int usb_dsbr100_ioctl(struct inode *inode, struct file *file,
 			     unsigned int cmd, unsigned long arg);
 static int usb_dsbr100_open(struct inode *inode, struct file *file);
@@ -95,7 +95,6 @@
 	unsigned char transfer_buffer[TB_LEN];
 	int curfreq;
 	int stereo;
-	int ifnum;
 } usb_dsbr100;
 
 
@@ -181,32 +180,36 @@
 }
 
 
-static void *usb_dsbr100_probe(struct usb_device *dev, unsigned int ifnum,
+static int usb_dsbr100_probe(struct usb_interface *intf, 
 			 const struct usb_device_id *id)
 {
 	usb_dsbr100 *radio;
 
 	if (!(radio = kmalloc(sizeof(usb_dsbr100),GFP_KERNEL)))
-		return NULL;
+		return -ENOMEM;
 	usb_dsbr100_radio.priv = radio;
-	radio->dev = dev;
-	radio->ifnum = ifnum;
+	radio->dev = interface_to_usbdev (intf);
 	radio->curfreq = 1454000;
-	return (void*)radio;
+	dev_set_drvdata (&intf->dev, radio);
+	return 0;
 }
 
-static void usb_dsbr100_disconnect(struct usb_device *dev, void *ptr)
+static void usb_dsbr100_disconnect(struct usb_interface *intf)
 {
-	usb_dsbr100 *radio=ptr;
+	usb_dsbr100 *radio = dev_get_drvdata (&intf->dev);
 
-	lock_kernel();
-	if (users) {
+	dev_set_drvdata (&intf->dev, NULL);
+
+	if (radio) {
+		lock_kernel();
+		if (users) {
+			unlock_kernel();
+			return;
+		}
+		kfree(radio);
+		usb_dsbr100_radio.priv = NULL;
 		unlock_kernel();
-		return;
 	}
-	kfree(radio);
-	usb_dsbr100_radio.priv = NULL;
-	unlock_kernel();
 }
 
 static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file,
diff -Nru a/drivers/usb/media/ibmcam.c b/drivers/usb/media/ibmcam.c
--- a/drivers/usb/media/ibmcam.c	Mon Sep 16 15:00:27 2002
+++ b/drivers/usb/media/ibmcam.c	Mon Sep 16 15:00:27 2002
@@ -3656,39 +3656,41 @@
  * 12-Nov-2000 Reworked to comply with new probe() signature.
  * 23-Jan-2001 Added compatibility with 2.2.x kernels.
  */
-static void *ibmcam_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *devid)
+static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id *devid)
 {
+	struct usb_device *dev = interface_to_usbdev(intf);
 	struct uvd *uvd = NULL;
 	int i, nas, model=0, canvasX=0, canvasY=0;
 	int actInterface=-1, inactInterface=-1, maxPS=0;
+	__u8 ifnum = intf->altsetting->bInterfaceNumber;
 	unsigned char video_ep = 0;
 
 	if (debug >= 1)
-		info("ibmcam_probe(%p,%u.)", dev, ifnum);
+		info("ibmcam_probe(%p,%u.)", intf, ifnum);
 
 	/* We don't handle multi-config cameras */
 	if (dev->descriptor.bNumConfigurations != 1)
-		return NULL;
+		return -ENODEV;
 
 	/* Is it an IBM camera? */
 	if (dev->descriptor.idVendor != IBMCAM_VENDOR_ID)
-		return NULL;
+		return -ENODEV;
 	if ((dev->descriptor.idProduct != IBMCAM_PRODUCT_ID) &&
 	    (dev->descriptor.idProduct != VEO_800C_PRODUCT_ID) &&
 	    (dev->descriptor.idProduct != VEO_800D_PRODUCT_ID) &&
 	    (dev->descriptor.idProduct != NETCAM_PRODUCT_ID))
-		return NULL;
+		return -ENODEV;
 
 	/* Check the version/revision */
 	switch (dev->descriptor.bcdDevice) {
 	case 0x0002:
 		if (ifnum != 2)
-			return NULL;
+			return -ENODEV;
 		model = IBMCAM_MODEL_1;
 		break;
 	case 0x030A:
 		if (ifnum != 0)
-			return NULL;
+			return -ENODEV;
 		if ((dev->descriptor.idProduct == NETCAM_PRODUCT_ID) ||
 		    (dev->descriptor.idProduct == VEO_800D_PRODUCT_ID))
 			model = IBMCAM_MODEL_4;
@@ -3697,13 +3699,13 @@
 		break;
 	case 0x0301:
 		if (ifnum != 0)
-			return NULL;
+			return -ENODEV;
 		model = IBMCAM_MODEL_3;
 		break;
 	default:
 		err("IBM camera with revision 0x%04x is not supported.",
 			dev->descriptor.bcdDevice);
-		return NULL;
+		return -ENODEV;
 	}
 
 	/* Print detailed info on what we found so far */
@@ -3734,7 +3736,7 @@
 		info("Number of alternate settings=%d.", nas);
 	if (nas < 2) {
 		err("Too few alternate settings for this camera!");
-		return NULL;
+		return -ENODEV;
 	}
 	/* Validate all alternate settings */
 	for (i=0; i < nas; i++) {
@@ -3745,29 +3747,29 @@
 		if (interface->bNumEndpoints != 1) {
 			err("Interface %d. has %u. endpoints!",
 			    ifnum, (unsigned)(interface->bNumEndpoints));
-			return NULL;
+			return -ENODEV;
 		}
 		endpoint = &interface->endpoint[0];
 		if (video_ep == 0)
 			video_ep = endpoint->bEndpointAddress;
 		else if (video_ep != endpoint->bEndpointAddress) {
 			err("Alternate settings have different endpoint addresses!");
-			return NULL;
+			return -ENODEV;
 		}
 		if ((endpoint->bmAttributes & 0x03) != 0x01) {
 			err("Interface %d. has non-ISO endpoint!", ifnum);
-			return NULL;
+			return -ENODEV;
 		}
 		if ((endpoint->bEndpointAddress & 0x80) == 0) {
 			err("Interface %d. has ISO OUT endpoint!", ifnum);
-			return NULL;
+			return -ENODEV;
 		}
 		if (endpoint->wMaxPacketSize == 0) {
 			if (inactInterface < 0)
 				inactInterface = i;
 			else {
 				err("More than one inactive alt. setting!");
-				return NULL;
+				return -ENODEV;
 			}
 		} else {
 			if (actInterface < 0) {
@@ -3781,7 +3783,7 @@
 	}
 	if ((maxPS <= 0) || (actInterface < 0) || (inactInterface < 0)) {
 		err("Failed to recognize the camera!");
-		return NULL;
+		return -ENODEV;
 	}
 
 	/* Validate options */
@@ -3861,7 +3863,7 @@
 		break;
 	default:
 		err("IBM camera: Model %d. not supported!", model);
-		return NULL;
+		return -ENODEV;
 	}
 
 	/* Code below may sleep, need to lock module while we are here */
@@ -3896,7 +3898,8 @@
 		}
 	}
 	MOD_DEC_USE_COUNT;
-	return uvd;
+	dev_set_drvdata (&intf->dev, uvd);
+	return 0;
 }
 
 
diff -Nru a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c
--- a/drivers/usb/media/konicawc.c	Mon Sep 16 15:00:27 2002
+++ b/drivers/usb/media/konicawc.c	Mon Sep 16 15:00:27 2002
@@ -717,38 +717,40 @@
 }
 
 
-static void *konicawc_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *devid)
+static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id *devid)
 {
+	struct usb_device *dev = interface_to_usbdev(intf);
 	struct uvd *uvd = NULL;
 	int i, nas;
 	int actInterface=-1, inactInterface=-1, maxPS=0;
 	unsigned char video_ep = 0;
 
-	DEBUG(1, "konicawc_probe(%p,%u.)", dev, ifnum);
+	DEBUG(1, "konicawc_probe(%p)", intf);
 
 	/* We don't handle multi-config cameras */
 	if (dev->descriptor.bNumConfigurations != 1)
-		return NULL;
+		return -ENODEV;
 
 	info("Konica Webcam (rev. 0x%04x)", dev->descriptor.bcdDevice);
 	RESTRICT_TO_RANGE(speed, 0, MAX_SPEED);
 
 	/* Validate found interface: must have one ISO endpoint */
-	nas = dev->actconfig->interface[ifnum].num_altsetting;
+	nas = intf->num_altsetting;
 	if (nas != 8) {
 		err("Incorrect number of alternate settings (%d) for this camera!", nas);
-		return NULL;
+		return -ENODEV;
 	}
 	/* Validate all alternate settings */
 	for (i=0; i < nas; i++) {
 		const struct usb_interface_descriptor *interface;
 		const struct usb_endpoint_descriptor *endpoint;
 
-		interface = &dev->actconfig->interface[ifnum].altsetting[i];
+		interface = &intf->altsetting[i];
 		if (interface->bNumEndpoints != 2) {
 			err("Interface %d. has %u. endpoints!",
-			    ifnum, (unsigned)(interface->bNumEndpoints));
-			return NULL;
+			    interface->bInterfaceNumber,
+			    (unsigned)(interface->bNumEndpoints));
+			return -ENODEV;
 		}
 		endpoint = &interface->endpoint[1];
 		DEBUG(1, "found endpoint: addr: 0x%2.2x maxps = 0x%4.4x",
@@ -757,22 +759,24 @@
 			video_ep = endpoint->bEndpointAddress;
 		else if (video_ep != endpoint->bEndpointAddress) {
 			err("Alternate settings have different endpoint addresses!");
-			return NULL;
+			return -ENODEV;
 		}
 		if ((endpoint->bmAttributes & 0x03) != 0x01) {
-			err("Interface %d. has non-ISO endpoint!", ifnum);
-			return NULL;
+			err("Interface %d. has non-ISO endpoint!",
+			    interface->bInterfaceNumber);
+			return -ENODEV;
 		}
 		if ((endpoint->bEndpointAddress & 0x80) == 0) {
-			err("Interface %d. has ISO OUT endpoint!", ifnum);
-			return NULL;
+			err("Interface %d. has ISO OUT endpoint!",
+			    interface->bInterfaceNumber);
+			return -ENODEV;
 		}
 		if (endpoint->wMaxPacketSize == 0) {
 			if (inactInterface < 0)
 				inactInterface = i;
 			else {
 				err("More than one inactive alt. setting!");
-				return NULL;
+				return -ENODEV;
 			}
 		} else {
 			if (i == spd_to_iface[speed]) {
@@ -785,7 +789,7 @@
 	}
 	if(actInterface == -1) {
 		err("Cant find required endpoint");
-		return NULL;
+		return -ENODEV;
 	}
 
 	DEBUG(1, "Selecting requested active setting=%d. maxPS=%d.", actInterface, maxPS);
@@ -803,7 +807,7 @@
 					usb_free_urb(cam->sts_urb[i]);
 				}
 				err("cant allocate urbs");
-				return NULL;
+				return -ENOMEM;
 			}
 		}
 		cam->speed = speed;
@@ -815,7 +819,7 @@
 		uvd->flags = 0;
 		uvd->debug = debug;
 		uvd->dev = dev;
-		uvd->iface = ifnum;
+		uvd->iface = intf->altsetting->bInterfaceNumber;
 		uvd->ifaceAltInactive = inactInterface;
 		uvd->ifaceAltActive = actInterface;
 		uvd->video_endp = video_ep;
@@ -854,7 +858,12 @@
 #endif
 	}
 	MOD_DEC_USE_COUNT;
-	return uvd;
+
+	if (uvd) {
+		dev_set_drvdata (&intf->dev, uvd);
+		return 0;
+	}
+	return -EIO;
 }
 
 
diff -Nru a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c
--- a/drivers/usb/media/ov511.c	Mon Sep 16 15:00:27 2002
+++ b/drivers/usb/media/ov511.c	Mon Sep 16 15:00:27 2002
@@ -6067,10 +6067,11 @@
  *
  ***************************************************************************/
 
-static void *
-ov51x_probe(struct usb_device *dev, unsigned int ifnum,
+static int
+ov51x_probe(struct usb_interface *intf, 
 	    const struct usb_device_id *id)
 {
+	struct usb_device *dev = interface_to_usbdev(intf);
 	struct usb_interface_descriptor *interface;
 	struct usb_ov511 *ov;
 	int i;
@@ -6080,15 +6081,15 @@
 
 	/* We don't handle multi-config cameras */
 	if (dev->descriptor.bNumConfigurations != 1)
-		return NULL;
+		return -ENODEV;
 
-	interface = &dev->actconfig->interface[ifnum].altsetting[0];
+	interface = &intf->altsetting[0];
 
 	/* Checking vendor/product should be enough, but what the hell */
 	if (interface->bInterfaceClass != 0xFF)
-		return NULL;
+		return -ENODEV;
 	if (interface->bInterfaceSubClass != 0x00)
-		return NULL;
+		return -ENODEV;
 
 	if ((ov = kmalloc(sizeof(*ov), GFP_KERNEL)) == NULL) {
 		err("couldn't kmalloc ov struct");
@@ -6217,7 +6218,8 @@
 	create_proc_ov511_cam(ov);
 #endif
 
-     	return ov;
+	dev_set_drvdata (&intf->dev, ov);
+     	return 0;
 
 error:
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
@@ -6240,16 +6242,20 @@
 
 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)
diff -Nru a/drivers/usb/media/pwc-if.c b/drivers/usb/media/pwc-if.c
--- a/drivers/usb/media/pwc-if.c	Mon Sep 16 15:00:27 2002
+++ b/drivers/usb/media/pwc-if.c	Mon Sep 16 15:00:27 2002
@@ -86,8 +86,8 @@
 };
 MODULE_DEVICE_TABLE(usb, pwc_device_table);
 
-static void *usb_pwc_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id);
-static void usb_pwc_disconnect(struct usb_device *udev, void *ptr);
+static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id);
+static void usb_pwc_disconnect(struct usb_interface *intf);
 
 static struct usb_driver pwc_driver =
 {
@@ -1539,8 +1539,9 @@
  * is loaded.
  */
 
-static void *usb_pwc_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
+static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
+	struct usb_device *udev = interface_to_usbdev(intf);
 	struct pwc_device *pdev = NULL;
 	struct video_device *vdev;
 	int vendor_id, product_id, type_id;
@@ -1551,14 +1552,14 @@
 	free_mem_leak();
 	
 	/* Check if we can handle this device */
-	Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n", udev->descriptor.idVendor, udev->descriptor.idProduct, ifnum);
+	Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n", udev->descriptor.idVendor, udev->descriptor.idProduct, intf->altsetting->bInterfaceNumber);
 
 	/* the interfaces are probed one by one. We are only interested in the
 	   video interface (0) now.
 	   Interface 1 is the Audio Control, and interface 2 Audio itself.
 	 */
-	if (ifnum > 0) 
-		return NULL;
+	if (intf->altsetting->bInterfaceNumber > 0)
+		return -ENODEV;
 
 	vendor_id = udev->descriptor.idVendor;
 	product_id = udev->descriptor.idProduct;
@@ -1602,7 +1603,7 @@
 			type_id = 750;
 			break;
 		default:
-			return NULL;
+			return -ENODEV;
 			break;
 		}
 	}
@@ -1613,7 +1614,7 @@
 			type_id = 645;
 			break;
 		default:
-			return NULL;
+			return -ENODEV;
 			break;
 		}
 	}
@@ -1624,7 +1625,7 @@
 			type_id = 730;
         		break;
         	default:
-        		return NULL;
+			return -ENODEV;
         		break;
         	}
         }
@@ -1643,7 +1644,7 @@
 			type_id = 675;
 			break;
 		default:
-			return NULL;
+			return -ENODEV;
 			break;
 		}
 	}
@@ -1654,7 +1655,7 @@
 			type_id = 730;
 			break;
 		default:
-			return NULL;
+			return -ENODEV;
 			break;
 		}
 	}
@@ -1665,11 +1666,11 @@
 			type_id = 730;
 			break;  
 		default:
-			return NULL;
+			return -ENODEV;
 			break;
 		}
 	}
-	else return NULL; /* Not Philips, Askey, Logitech, Samsung, Creative or SOTEC, for sure. */
+	else return -ENODEV; /* Not Philips, Askey, Logitech, Samsung, Creative or SOTEC, for sure. */
 
 	memset(serial_number, 0, 30);
 	usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29);
@@ -1682,7 +1683,7 @@
 	pdev = kmalloc(sizeof(struct pwc_device), GFP_KERNEL);
 	if (pdev == NULL) {
 		Err("Oops, could not allocate memory for pwc_device.\n");
-		return NULL;
+		return -ENOMEM;
 	}
 	memset(pdev, 0, sizeof(struct pwc_device));
 	pdev->type = type_id;
@@ -1700,7 +1701,7 @@
 	vdev = kmalloc(sizeof(struct video_device), GFP_KERNEL);
 	if (vdev == NULL) {
 		Err("Oops, could not allocate memory for video_device.\n");
-		return NULL;
+		return -ENOMEM;
 	}
 	memcpy(vdev, &pwc_template, sizeof(pwc_template));
 	sprintf(vdev->name, "Philips %d webcam", pdev->type);
@@ -1729,7 +1730,7 @@
 	i = video_register_device(vdev, VFL_TYPE_GRABBER, video_nr);
 	if (i < 0) {
 		Err("Failed to register as video device (%d).\n", i);
-		return NULL;
+		return -EIO;
 	}
 	else {
 		Trace(TRACE_PROBE, "Registered video struct at 0x%p.\n", vdev);
@@ -1740,11 +1741,12 @@
 		device_hint[hint].pdev = pdev;
 
 	Trace(TRACE_PROBE, "probe() function returning struct at 0x%p.\n", pdev);
-	return pdev;
+	dev_set_drvdata (&intf->dev, pdev);
+	return 0;
 }
 
 /* The user janked out the cable... */
-static void usb_pwc_disconnect(struct usb_device *udev, void *ptr)
+static void usb_pwc_disconnect(struct usb_interface *intf)
 {
 	struct pwc_device *pdev;
 	int hint;
@@ -1753,7 +1755,8 @@
 	lock_kernel();
 	free_mem_leak();
 
-	pdev = (struct pwc_device *)ptr;
+	pdev = dev_get_drvdata (&intf->dev);
+	dev_set_drvdata (&intf->dev, NULL);
 	if (pdev == NULL) {
 		Err("pwc_disconnect() Called without private pointer.\n");
 		goto out_err;
@@ -1762,7 +1765,7 @@
 		Err("pwc_disconnect() already called for %p\n", pdev);
 		goto out_err;
 	}
-	if (pdev->udev != udev) {
+	if (pdev->udev != interface_to_usbdev(intf)) {
 		Err("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n");
 		goto out_err;
 	}
diff -Nru a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c
--- a/drivers/usb/media/se401.c	Mon Sep 16 15:00:27 2002
+++ b/drivers/usb/media/se401.c	Mon Sep 16 15:00:27 2002
@@ -1420,9 +1420,10 @@
         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 @@
 
         /* 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 @@
 		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 @@
 
         if (se401_init(se401, button)) {
 		kfree(se401);
-		return NULL;
+		return -EIO;
 	}
 
 	memcpy(&se401->vdev, &se401_template, sizeof(se401_template));
@@ -1490,43 +1491,46 @@
 	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;
-
-		se401->streaming = 0;
-		
-		wake_up_interruptible(&se401->wq);
-		se401->removed = 1;
-	}
+	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;
+		}
 #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 -Nru a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c
--- a/drivers/usb/media/stv680.c	Mon Sep 16 15:00:27 2002
+++ b/drivers/usb/media/stv680.c	Mon Sep 16 15:00:27 2002
@@ -1448,8 +1448,9 @@
 	.fops =         &stv680_fops,
 };
 
-static void *stv680_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id)
+static int stv680_probe (struct usb_interface *intf, const struct usb_device_id *id)
 {
+	struct usb_device *dev = interface_to_usbdev(intf);
 	struct usb_interface_descriptor *interface;
 	struct usb_stv *stv680;
 	char *camera_name = NULL;
@@ -1457,10 +1458,10 @@
 	/* We don't handle multi-config cameras */
 	if (dev->descriptor.bNumConfigurations != 1) {
 		PDEBUG (0, "STV(e): Number of Configurations != 1");
-		return NULL;
+		return -ENODEV;
 	}
 
-	interface = &dev->actconfig->interface[ifnum].altsetting[0];
+	interface = &intf->altsetting[0];
 	/* Is it a STV680? */
 	if ((dev->descriptor.idVendor == USB_PENCAM_VENDOR_ID) && (dev->descriptor.idProduct == USB_PENCAM_PRODUCT_ID)) {
 		camera_name = "STV0680";
@@ -1468,12 +1469,12 @@
 	} else {
 		PDEBUG (0, "STV(e): Vendor/Product ID do not match STV0680 values.");
 		PDEBUG (0, "STV(e): Check that the STV0680 camera is connected to the computer.");
-		return NULL;
+		return -ENODEV;
 	}
 	/* We found one */
 	if ((stv680 = kmalloc (sizeof (*stv680), GFP_KERNEL)) == NULL) {
 		PDEBUG (0, "STV(e): couldn't kmalloc stv680 struct.");
-		return NULL;
+		return -ENOMEM;
 	}
 
 	memset (stv680, 0, sizeof (*stv680));
@@ -1490,14 +1491,15 @@
 	if (video_register_device (&stv680->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
 		kfree (stv680);
 		PDEBUG (0, "STV(e): video_register_device failed");
-		return NULL;
+		return -EIO;
 	}
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
 	create_proc_stv680_cam (stv680);
 #endif
 	PDEBUG (0, "STV(i): registered new video device: video%d", stv680->vdev.minor);
 
-	return stv680;
+	dev_set_drvdata (&intf->dev, stv680);
+	return 0;
 }
 
 static inline void usb_stv680_remove_disconnected (struct usb_stv *stv680)
@@ -1531,16 +1533,20 @@
 	kfree (stv680);
 }
 
-static void stv680_disconnect (struct usb_device *dev, void *ptr)
+static void stv680_disconnect (struct usb_interface *intf)
 {
-	struct usb_stv *stv680 = (struct usb_stv *) ptr;
+	struct usb_stv *stv680 = dev_get_drvdata (&intf->dev);
 
-	/* We don't want people trying to open up the device */
-	video_unregister_device (&stv680->vdev);
-	if (!stv680->user) {
-		usb_stv680_remove_disconnected (stv680);
-	} else {
-		stv680->removed = 1;
+	dev_set_drvdata (&intf->dev, NULL);
+
+	if (stv680) {
+		/* We don't want people trying to open up the device */
+		video_unregister_device (&stv680->vdev);
+		if (!stv680->user) {
+			usb_stv680_remove_disconnected (stv680);
+		} else {
+			stv680->removed = 1;
+		}
 	}
 }
 
diff -Nru a/drivers/usb/media/ultracam.c b/drivers/usb/media/ultracam.c
--- a/drivers/usb/media/ultracam.c	Mon Sep 16 15:00:27 2002
+++ b/drivers/usb/media/ultracam.c	Mon Sep 16 15:00:27 2002
@@ -537,67 +537,71 @@
  * 12-Nov-2000 Reworked to comply with new probe() signature.
  * 23-Jan-2001 Added compatibility with 2.2.x kernels.
  */
-static void *ultracam_probe(struct usb_device *dev, unsigned int ifnum ,const struct usb_device_id *devid)
+static int ultracam_probe(struct usb_interface *intf, const struct usb_device_id *devid)
 {
+	struct usb_device *dev = interface_to_usbdev(intf);
 	struct uvd *uvd = NULL;
 	int i, nas;
 	int actInterface=-1, inactInterface=-1, maxPS=0;
 	unsigned char video_ep = 0;
 
 	if (debug >= 1)
-		info("ultracam_probe(%p,%u.)", dev, ifnum);
+		info("ultracam_probe(%p)", intf);
 
 	/* We don't handle multi-config cameras */
 	if (dev->descriptor.bNumConfigurations != 1)
-		return NULL;
+		return -ENODEV;
 
 	/* Is it an IBM camera? */
 	if ((dev->descriptor.idVendor != ULTRACAM_VENDOR_ID) ||
 	    (dev->descriptor.idProduct != ULTRACAM_PRODUCT_ID))
-		return NULL;
+		return -ENODEV;
 
 	info("IBM Ultra camera found (rev. 0x%04x)", dev->descriptor.bcdDevice);
 
 	/* Validate found interface: must have one ISO endpoint */
-	nas = dev->actconfig->interface[ifnum].num_altsetting;
+	nas = intf->num_altsetting;
 	if (debug > 0)
 		info("Number of alternate settings=%d.", nas);
 	if (nas < 8) {
 		err("Too few alternate settings for this camera!");
-		return NULL;
+		return -ENODEV;
 	}
 	/* Validate all alternate settings */
 	for (i=0; i < nas; i++) {
 		const struct usb_interface_descriptor *interface;
 		const struct usb_endpoint_descriptor *endpoint;
 
-		interface = &dev->actconfig->interface[ifnum].altsetting[i];
+		interface = &intf->altsetting[i];
 		if (interface->bNumEndpoints != 1) {
 			err("Interface %d. has %u. endpoints!",
-			    ifnum, (unsigned)(interface->bNumEndpoints));
-			return NULL;
+			    interface->bInterfaceNumber,
+			    (unsigned)(interface->bNumEndpoints));
+			return -ENODEV;
 		}
 		endpoint = &interface->endpoint[0];
 		if (video_ep == 0)
 			video_ep = endpoint->bEndpointAddress;
 		else if (video_ep != endpoint->bEndpointAddress) {
 			err("Alternate settings have different endpoint addresses!");
-			return NULL;
+			return -ENODEV;
 		}
 		if ((endpoint->bmAttributes & 0x03) != 0x01) {
-			err("Interface %d. has non-ISO endpoint!", ifnum);
-			return NULL;
+			err("Interface %d. has non-ISO endpoint!",
+			    interface->bInterfaceNumber);
+			return -ENODEV;
 		}
 		if ((endpoint->bEndpointAddress & 0x80) == 0) {
-			err("Interface %d. has ISO OUT endpoint!", ifnum);
-			return NULL;
+			err("Interface %d. has ISO OUT endpoint!",
+			    interface->bInterfaceNumber);
+			return -ENODEV;
 		}
 		if (endpoint->wMaxPacketSize == 0) {
 			if (inactInterface < 0)
 				inactInterface = i;
 			else {
 				err("More than one inactive alt. setting!");
-				return NULL;
+				return -ENODEV;
 			}
 		} else {
 			if (actInterface < 0) {
@@ -621,7 +625,7 @@
 	}
 	if ((maxPS <= 0) || (actInterface < 0) || (inactInterface < 0)) {
 		err("Failed to recognize the camera!");
-		return NULL;
+		return -ENODEV;
 	}
 
 	/* Code below may sleep, need to lock module while we are here */
@@ -632,7 +636,7 @@
 		uvd->flags = flags;
 		uvd->debug = debug;
 		uvd->dev = dev;
-		uvd->iface = ifnum;
+		uvd->iface = intf->altsetting->bInterfaceNumber;
 		uvd->ifaceAltInactive = inactInterface;
 		uvd->ifaceAltActive = actInterface;
 		uvd->video_endp = video_ep;
@@ -656,7 +660,12 @@
 		}
 	}
 	MOD_DEC_USE_COUNT;
-	return uvd;
+
+	if (uvd) {
+		dev_set_drvdata (&intf->dev, uvd);
+		return 0;
+	}
+	return -EIO;
 }
 
 
diff -Nru a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c
--- a/drivers/usb/media/usbvideo.c	Mon Sep 16 15:00:27 2002
+++ b/drivers/usb/media/usbvideo.c	Mon Sep 16 15:00:27 2002
@@ -54,7 +54,7 @@
 	unsigned long count, void *data);
 #endif
 
-static void usbvideo_Disconnect(struct usb_device *dev, void *ptr);
+static void usbvideo_Disconnect(struct usb_interface *intf);
 static void usbvideo_CameraRelease(struct uvd *uvd);
 
 static int usbvideo_v4l_ioctl(struct inode *inode, struct file *file,
@@ -966,18 +966,21 @@
  * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT).
  * 19-Oct-2000 Moved to usbvideo module.
  */
-static void usbvideo_Disconnect(struct usb_device *dev, void *ptr)
+static void usbvideo_Disconnect(struct usb_interface *intf)
 {
-	struct uvd *uvd = (struct uvd *) ptr;
+	struct uvd *uvd = dev_get_drvdata (&intf->dev);
 	int i;
 
-	if ((dev == NULL) || (uvd == NULL)) {
-		err("%s($%p,$%p): Illegal call.", __FUNCTION__, dev, ptr);
+	if (uvd == NULL) {
+		err("%s($%p): Illegal call.", __FUNCTION__, intf);
 		return;
 	}
+
+	dev_set_drvdata (&intf->dev, NULL);
+
 	usbvideo_ClientIncModCount(uvd);
 	if (uvd->debug > 0)
-		info("%s(%p,%p.)", __FUNCTION__, dev, ptr);
+		info("%s(%p.)", __FUNCTION__, intf);
 
 	down(&uvd->lock);
 	uvd->remove_pending = 1; /* Now all ISO data will be ignored */
diff -Nru a/drivers/usb/media/usbvideo.h b/drivers/usb/media/usbvideo.h
--- a/drivers/usb/media/usbvideo.h	Mon Sep 16 15:00:27 2002
+++ b/drivers/usb/media/usbvideo.h	Mon Sep 16 15:00:27 2002
@@ -254,9 +254,9 @@
  * that default to usbvideo-provided methods.
  */
 struct usbvideo_cb {
-	void *(*probe)(struct usb_device *, unsigned int,const struct usb_device_id *);
+	int (*probe)(struct usb_interface *, const struct usb_device_id *);
 	void (*userFree)(struct uvd *);
-	void (*disconnect)(struct usb_device *, void *);
+	void (*disconnect)(struct usb_interface *);
 	int (*setupOnOpen)(struct uvd *);
 	void (*videoStart)(struct uvd *);
 	void (*videoStop)(struct uvd *);
diff -Nru a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c
--- a/drivers/usb/media/vicam.c	Mon Sep 16 15:00:27 2002
+++ b/drivers/usb/media/vicam.c	Mon Sep 16 15:00:27 2002
@@ -787,9 +787,10 @@
 	return 1;
 }
 
-static void *vicam_probe(struct usb_device *udev, unsigned int ifnum,
+static int vicam_probe(struct usb_interface *intf, 
 	const struct usb_device_id *id)
 {
+	struct usb_device *udev = interface_to_usbdev(intf);
 	struct usb_vicam *vicam;
 	char *camera_name=NULL;
 
@@ -798,7 +799,7 @@
 	/* See if the device offered us matches what we can accept */
 	if ((udev->descriptor.idVendor != USB_VICAM_VENDOR_ID) ||
 	    (udev->descriptor.idProduct != USB_VICAM_PRODUCT_ID)) {
-		return NULL;
+		return -ENODEV;
 	}
 	
 	camera_name="3Com HomeConnect USB";
@@ -807,14 +808,14 @@
 	vicam = kmalloc (sizeof(struct usb_vicam), GFP_KERNEL);
 	if (vicam == NULL) {
 		err ("couldn't kmalloc vicam struct");
-		return NULL;
+		return -ENOMEM;
 	}
 	memset(vicam, 0, sizeof(*vicam));
 
 	vicam->readurb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!vicam->readurb) {
 		kfree(vicam);
-		return NULL;
+		return -ENOMEM;
 	}
 
 	vicam->udev = udev;
@@ -826,7 +827,7 @@
 	if (vicam_init(vicam)) {
 		usb_free_urb(vicam->readurb);
 		kfree(vicam);
-		return NULL;
+		return -ENOMEM;
 	}
 	memcpy(&vicam->vdev, &vicam_template, sizeof(vicam_template));
 	memcpy(vicam->vdev.name, vicam->camera_name, strlen(vicam->camera_name));
@@ -835,7 +836,7 @@
 		err("video_register_device");
 		usb_free_urb(vicam->readurb);
 		kfree(vicam);
-		return NULL;
+		return -EIO;
 	}
 
 	info("registered new video device: video%d", vicam->vdev.minor);
@@ -843,34 +844,38 @@
 	init_MUTEX (&vicam->sem);
 	init_waitqueue_head(&vicam->wait);
 	
-	return vicam;
+	dev_set_drvdata (&intf->dev, vicam);
+	return 0;
 }
 
 
 /* FIXME - vicam_disconnect - important */
-static void vicam_disconnect(struct usb_device *udev, void *ptr)
+static void vicam_disconnect(struct usb_interface *intf)
 {
 	struct usb_vicam *vicam;
 
-	vicam = (struct usb_vicam *) ptr;
+	vicam = dev_get_drvdata (&intf->dev);
 
-	video_unregister_device(&vicam->vdev);
-	vicam->udev = NULL;
+	dev_set_drvdata (&intf->dev, NULL);
+
+	if (vicam) {
+		video_unregister_device(&vicam->vdev);
+		vicam->udev = NULL;
 /*
-	vicam->frame[0].grabstate = FRAME_ERROR;
-	vicam->frame[1].grabstate = FRAME_ERROR;
+		vicam->frame[0].grabstate = FRAME_ERROR;
+		vicam->frame[1].grabstate = FRAME_ERROR;
 */
 
-	/* Free buffers and shit */
-
-	info("%s disconnected", vicam->camera_name);
-	synchronize(vicam);
-
-	if (!vicam->open_count) {
-		/* Other random junk */
-		usb_free_urb(vicam->readurb);
-		kfree(vicam);
-		vicam = NULL;
+		/* Free buffers and shit */
+		info("%s disconnected", vicam->camera_name);
+		synchronize(vicam);
+
+		if (!vicam->open_count) {
+			/* Other random junk */
+			usb_free_urb(vicam->readurb);
+			kfree(vicam);
+			vicam = NULL;
+		}
 	}
 }