USB: fix skeleton driver

compilation of the skeleton driver is currently broken. It doesn't compile.
So while I am it:

- fix typo
- add comments to answer common questions
- actually allow autosuspend in the driver struct
- increase paralellism by restricting code under locks

Signed-off-by: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
index 46929a1..962b28c 100644
--- a/drivers/usb/usb-skeleton.c
+++ b/drivers/usb/usb-skeleton.c
@@ -40,12 +40,16 @@
 
 /* our private defines. if this grows any larger, use your own .h file */
 #define MAX_TRANSFER		(PAGE_SIZE - 512)
+/* MAX_TRANSFER is chosen so that the VM is not stressed by
+   allocations > PAGE_SIZE and the number of packets in a page
+   is an integer 512 is the largest possible packet on EHCI */
 #define WRITES_IN_FLIGHT	8
+/* arbitrarily chosen */
 
 /* Structure to hold all of our device specific stuff */
 struct usb_skel {
-	struct usb_device       *dev;			/* the usb device for this device */
-	struct usb_interface    *interface;		/* the interface for this device */
+	struct usb_device	*udev;			/* the usb device for this device */
+	struct usb_interface	*interface;		/* the interface for this device */
 	struct semaphore	limit_sem;		/* limiting the number of writes in progress */
 	unsigned char           *bulk_in_buffer;	/* the buffer to receive data */
 	size_t			bulk_in_size;		/* the size of the receive buffer */
@@ -201,12 +205,6 @@
 		goto exit;
 	}
 
-	mutex_lock(&dev->io_mutex);
-	if (!dev->interface) {		/* disconnect() was called */
-		retval = -ENODEV;
-		goto error;
-	}
-
 	/* create a urb, and a buffer for it, and copy the data to the urb */
 	urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!urb) {
@@ -225,6 +223,14 @@
 		goto error;
 	}
 
+	/* this lock makes sure we don't submit URBs to gone devices */
+	mutex_lock(&dev->io_mutex);
+	if (!dev->interface) {		/* disconnect() was called */
+		mutex_unlock(&dev->io_mutex);
+		retval = -ENODEV;
+		goto error;
+	}
+
 	/* initialize the urb properly */
 	usb_fill_bulk_urb(urb, dev->udev,
 			  usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
@@ -233,6 +239,7 @@
 
 	/* send the data out the bulk port */
 	retval = usb_submit_urb(urb, GFP_KERNEL);
+	mutex_unlock(&dev->io_mutex);
 	if (retval) {
 		err("%s - failed submitting write urb, error %d", __FUNCTION__, retval);
 		goto error;
@@ -241,7 +248,7 @@
 	/* release our reference to this urb, the USB core will eventually free it entirely */
 	usb_free_urb(urb);
 
-	mutex_unlock(&dev->io_mutex);
+
 	return writesize;
 
 error:
@@ -249,7 +256,6 @@
 		usb_buffer_free(dev->udev, writesize, buf, urb->transfer_dma);
 		usb_free_urb(urb);
 	}
-	mutex_unlock(&dev->io_mutex);
 	up(&dev->limit_sem);
 
 exit:
@@ -344,6 +350,7 @@
 
 error:
 	if (dev)
+		/* this frees allocated memory */
 		kref_put(&dev->kref, skel_delete);
 	return retval;
 }
@@ -361,13 +368,14 @@
 
 	/* give back our minor */
 	usb_deregister_dev(interface, &skel_class);
+	unlock_kernel();
 
 	/* prevent more I/O from starting */
 	mutex_lock(&dev->io_mutex);
 	dev->interface = NULL;
 	mutex_unlock(&dev->io_mutex);
 
-	unlock_kernel();
+
 
 	/* decrement our usage count */
 	kref_put(&dev->kref, skel_delete);
@@ -380,6 +388,7 @@
 	.probe =	skel_probe,
 	.disconnect =	skel_disconnect,
 	.id_table =	skel_table,
+	.supports_autosuspend = 1,
 };
 
 static int __init usb_skel_init(void)