Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ba35e02b authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman
Browse files

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: default avatarOliver Neukum <oneukum@suse.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 08a78cbb
Loading
Loading
Loading
Loading
+20 −11
Original line number Diff line number Diff line
@@ -40,11 +40,15 @@ MODULE_DEVICE_TABLE(usb, skel_table);

/* 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_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 */
@@ -201,12 +205,6 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou
		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 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou
		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 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou

	/* 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 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou
	/* 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 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou
		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 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i

error:
	if (dev)
		/* this frees allocated memory */
		kref_put(&dev->kref, skel_delete);
	return retval;
}
@@ -361,13 +368,14 @@ static void skel_disconnect(struct usb_interface *interface)

	/* 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 @@ static struct usb_driver skel_driver = {
	.probe =	skel_probe,
	.disconnect =	skel_disconnect,
	.id_table =	skel_table,
	.supports_autosuspend = 1,
};

static int __init usb_skel_init(void)