ChangeSet 1.1455.1.35, 2003/07/16 10:12:00-07:00, oliver@neukum.org

[PATCH] USB: fix race between probe and open in skeleton

registering a device only partially initialised is quite bad an
idea.


 drivers/usb/usb-skeleton.c |   37 +++++++++++++++----------------------
 1 files changed, 15 insertions(+), 22 deletions(-)


diff -Nru a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
--- a/drivers/usb/usb-skeleton.c	Thu Jul 17 17:03:43 2003
+++ b/drivers/usb/usb-skeleton.c	Thu Jul 17 17:03:43 2003
@@ -507,7 +507,7 @@
 	struct usb_endpoint_descriptor *endpoint;
 	size_t buffer_size;
 	int i;
-	int retval;
+	int retval = -ENOMEM;
 
 	/* See if the device offered us matches what we can accept */
 	if ((udev->descriptor.idVendor != USB_SKEL_VENDOR_ID) ||
@@ -515,18 +515,11 @@
 		return -ENODEV;
 	}
 
-	retval = usb_register_dev (interface, &skel_class);
-	if (retval) {
-		/* something prevented us from registering this driver */
-		err ("Not able to get a minor for this device.");
-		goto exit;
-	}
-
 	/* allocate memory for our device state and initialize it */
 	dev = kmalloc (sizeof(struct usb_skel), GFP_KERNEL);
 	if (dev == NULL) {
 		err ("Out of memory");
-		goto exit_minor;
+		goto error;
 	}
 	memset (dev, 0x00, sizeof (*dev));
 
@@ -603,24 +596,24 @@
 	/* allow device read, write and ioctl */
 	dev->present = 1;
 
+	/* we can register the device now, as it is ready */
+	usb_set_intfdata (interface, dev);
+	retval = usb_register_dev (interface, &skel_class);
+	if (retval) {
+		/* something prevented us from registering this driver */
+		err ("Not able to get a minor for this device.");
+		usb_set_intfdata (interface, NULL);
+		goto error;
+	}
+
+
 	/* let the user know what node this device is now attached to */
 	info ("USB Skeleton device now attached to USBSkel-%d", dev->minor);
-
-	goto exit;
+	return 0;
 
 error:
 	skel_delete (dev);
-	dev = NULL;
-
-exit_minor:
-	usb_deregister_dev (interface, &skel_class);
-
-exit:
-	if (dev) {
-		usb_set_intfdata (interface, dev);
-		return 0;
-	}
-	return -ENODEV;
+	return retval;
 }