1/*
2 * USB Skeleton driver - 2.2
3 *
4 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
5 *
6 *	This program is free software; you can redistribute it and/or
7 *	modify it under the terms of the GNU General Public License as
8 *	published by the Free Software Foundation, version 2.
9 *
10 * This driver is based on the 2.6.3 version of drivers/usb/usb-skeleton.c
11 * but has been rewritten to be easier to read and use.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/errno.h>
17#include <linux/init.h>
18#include <linux/slab.h>
19#include <linux/module.h>
20#include <linux/kref.h>
21#include <asm/uaccess.h>
22#include <linux/usb.h>
23#include <linux/mutex.h>
24
25
26/* Define these values to match your devices */
27#define USB_SKEL_VENDOR_ID	0xfff0
28#define USB_SKEL_PRODUCT_ID	0xfff0
29
30/* table of devices that work with this driver */
31static struct usb_device_id skel_table [] = {
32	{ USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
33	{ }					/* Terminating entry */
34};
35MODULE_DEVICE_TABLE(usb, skel_table);
36
37/* to prevent a race between open and disconnect */
38static DEFINE_MUTEX(skel_open_lock);
39
40
41/* Get a minor range for your devices from the usb maintainer */
42#define USB_SKEL_MINOR_BASE	192
43
44/* our private defines. if this grows any larger, use your own .h file */
45#define MAX_TRANSFER		(PAGE_SIZE - 512)
46/* MAX_TRANSFER is chosen so that the VM is not stressed by
47   allocations > PAGE_SIZE and the number of packets in a page
48   is an integer 512 is the largest possible packet on EHCI */
49#define WRITES_IN_FLIGHT	8
50/* arbitrarily chosen */
51
52/* Structure to hold all of our device specific stuff */
53struct usb_skel {
54	struct usb_device	*udev;			/* the usb device for this device */
55	struct usb_interface	*interface;		/* the interface for this device */
56	struct semaphore	limit_sem;		/* limiting the number of writes in progress */
57	unsigned char           *bulk_in_buffer;	/* the buffer to receive data */
58	size_t			bulk_in_size;		/* the size of the receive buffer */
59	__u8			bulk_in_endpointAddr;	/* the address of the bulk in endpoint */
60	__u8			bulk_out_endpointAddr;	/* the address of the bulk out endpoint */
61	struct kref		kref;
62	struct mutex		io_mutex;		/* synchronize I/O with disconnect */
63};
64#define to_skel_dev(d) container_of(d, struct usb_skel, kref)
65
66static struct usb_driver skel_driver;
67
68static void skel_delete(struct kref *kref)
69{
70	struct usb_skel *dev = to_skel_dev(kref);
71
72	usb_put_dev(dev->udev);
73	kfree(dev->bulk_in_buffer);
74	kfree(dev);
75}
76
77static int skel_open(struct inode *inode, struct file *file)
78{
79	struct usb_skel *dev;
80	struct usb_interface *interface;
81	int subminor;
82	int retval = 0;
83
84	subminor = iminor(inode);
85
86	mutex_lock(&skel_open_lock);
87	interface = usb_find_interface(&skel_driver, subminor);
88	if (!interface) {
89		mutex_unlock(&skel_open_lock);
90		err ("%s - error, can't find device for minor %d",
91		     __FUNCTION__, subminor);
92		retval = -ENODEV;
93		goto exit;
94	}
95
96	dev = usb_get_intfdata(interface);
97	if (!dev) {
98		mutex_unlock(&skel_open_lock);
99		retval = -ENODEV;
100		goto exit;
101	}
102
103	/* increment our usage count for the device */
104	kref_get(&dev->kref);
105	/* now we can drop the lock */
106	mutex_unlock(&skel_open_lock);
107
108	/* prevent the device from being autosuspended */
109	retval = usb_autopm_get_interface(interface);
110	if (retval) {
111		kref_put(&dev->kref, skel_delete);
112		goto exit;
113	}
114
115	/* save our object in the file's private structure */
116	file->private_data = dev;
117
118exit:
119	return retval;
120}
121
122static int skel_release(struct inode *inode, struct file *file)
123{
124	struct usb_skel *dev;
125
126	dev = (struct usb_skel *)file->private_data;
127	if (dev == NULL)
128		return -ENODEV;
129
130	/* allow the device to be autosuspended */
131	mutex_lock(&dev->io_mutex);
132	if (dev->interface)
133		usb_autopm_put_interface(dev->interface);
134	mutex_unlock(&dev->io_mutex);
135
136	/* decrement the count on our device */
137	kref_put(&dev->kref, skel_delete);
138	return 0;
139}
140
141static ssize_t skel_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
142{
143	struct usb_skel *dev;
144	int retval;
145	int bytes_read;
146
147	dev = (struct usb_skel *)file->private_data;
148
149	mutex_lock(&dev->io_mutex);
150	if (!dev->interface) {		/* disconnect() was called */
151		retval = -ENODEV;
152		goto exit;
153	}
154
155	/* do a blocking bulk read to get data from the device */
156	retval = usb_bulk_msg(dev->udev,
157			      usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),
158			      dev->bulk_in_buffer,
159			      min(dev->bulk_in_size, count),
160			      &bytes_read, 10000);
161
162	/* if the read was successful, copy the data to userspace */
163	if (!retval) {
164		if (copy_to_user(buffer, dev->bulk_in_buffer, bytes_read))
165			retval = -EFAULT;
166		else
167			retval = bytes_read;
168	}
169
170exit:
171	mutex_unlock(&dev->io_mutex);
172	return retval;
173}
174
175static void skel_write_bulk_callback(struct urb *urb)
176{
177	struct usb_skel *dev;
178
179	dev = (struct usb_skel *)urb->context;
180
181	/* sync/async unlink faults aren't errors */
182	if (urb->status &&
183	    !(urb->status == -ENOENT ||
184	      urb->status == -ECONNRESET ||
185	      urb->status == -ESHUTDOWN)) {
186		err("%s - nonzero write bulk status received: %d",
187		    __FUNCTION__, urb->status);
188	}
189
190	/* free up our allocated buffer */
191	usb_buffer_free(urb->dev, urb->transfer_buffer_length,
192			urb->transfer_buffer, urb->transfer_dma);
193	up(&dev->limit_sem);
194}
195
196static ssize_t skel_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos)
197{
198	struct usb_skel *dev;
199	int retval = 0;
200	struct urb *urb = NULL;
201	char *buf = NULL;
202	size_t writesize = min(count, (size_t)MAX_TRANSFER);
203
204	dev = (struct usb_skel *)file->private_data;
205
206	/* verify that we actually have some data to write */
207	if (count == 0)
208		goto exit;
209
210	/* limit the number of URBs in flight to stop a user from using up all RAM */
211	if (down_interruptible(&dev->limit_sem)) {
212		retval = -ERESTARTSYS;
213		goto exit;
214	}
215
216	/* create a urb, and a buffer for it, and copy the data to the urb */
217	urb = usb_alloc_urb(0, GFP_KERNEL);
218	if (!urb) {
219		retval = -ENOMEM;
220		goto error;
221	}
222
223	buf = usb_buffer_alloc(dev->udev, writesize, GFP_KERNEL, &urb->transfer_dma);
224	if (!buf) {
225		retval = -ENOMEM;
226		goto error;
227	}
228
229	if (copy_from_user(buf, user_buffer, writesize)) {
230		retval = -EFAULT;
231		goto error;
232	}
233
234	/* this lock makes sure we don't submit URBs to gone devices */
235	mutex_lock(&dev->io_mutex);
236	if (!dev->interface) {		/* disconnect() was called */
237		mutex_unlock(&dev->io_mutex);
238		retval = -ENODEV;
239		goto error;
240	}
241
242	/* initialize the urb properly */
243	usb_fill_bulk_urb(urb, dev->udev,
244			  usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
245			  buf, writesize, skel_write_bulk_callback, dev);
246	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
247
248	/* send the data out the bulk port */
249	retval = usb_submit_urb(urb, GFP_KERNEL);
250	mutex_unlock(&dev->io_mutex);
251	if (retval) {
252		err("%s - failed submitting write urb, error %d", __FUNCTION__, retval);
253		goto error;
254	}
255
256	/* release our reference to this urb, the USB core will eventually free it entirely */
257	usb_free_urb(urb);
258
259
260	return writesize;
261
262error:
263	if (urb) {
264		usb_buffer_free(dev->udev, writesize, buf, urb->transfer_dma);
265		usb_free_urb(urb);
266	}
267	up(&dev->limit_sem);
268
269exit:
270	return retval;
271}
272
273static const struct file_operations skel_fops = {
274	.owner =	THIS_MODULE,
275	.read =		skel_read,
276	.write =	skel_write,
277	.open =		skel_open,
278	.release =	skel_release,
279};
280
281/*
282 * usb class driver info in order to get a minor number from the usb core,
283 * and to have the device registered with the driver core
284 */
285static struct usb_class_driver skel_class = {
286	.name =		"skel%d",
287	.fops =		&skel_fops,
288	.minor_base =	USB_SKEL_MINOR_BASE,
289};
290
291static int skel_probe(struct usb_interface *interface, const struct usb_device_id *id)
292{
293	struct usb_skel *dev;
294	struct usb_host_interface *iface_desc;
295	struct usb_endpoint_descriptor *endpoint;
296	size_t buffer_size;
297	int i;
298	int retval = -ENOMEM;
299
300	/* allocate memory for our device state and initialize it */
301	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
302	if (!dev) {
303		err("Out of memory");
304		goto error;
305	}
306	kref_init(&dev->kref);
307	sema_init(&dev->limit_sem, WRITES_IN_FLIGHT);
308	mutex_init(&dev->io_mutex);
309
310	dev->udev = usb_get_dev(interface_to_usbdev(interface));
311	dev->interface = interface;
312
313	/* set up the endpoint information */
314	/* use only the first bulk-in and bulk-out endpoints */
315	iface_desc = interface->cur_altsetting;
316	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
317		endpoint = &iface_desc->endpoint[i].desc;
318
319		if (!dev->bulk_in_endpointAddr &&
320		    usb_endpoint_is_bulk_in(endpoint)) {
321			/* we found a bulk in endpoint */
322			buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
323			dev->bulk_in_size = buffer_size;
324			dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
325			dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
326			if (!dev->bulk_in_buffer) {
327				err("Could not allocate bulk_in_buffer");
328				goto error;
329			}
330		}
331
332		if (!dev->bulk_out_endpointAddr &&
333		    usb_endpoint_is_bulk_out(endpoint)) {
334			/* we found a bulk out endpoint */
335			dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
336		}
337	}
338	if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
339		err("Could not find both bulk-in and bulk-out endpoints");
340		goto error;
341	}
342
343	/* save our data pointer in this interface device */
344	usb_set_intfdata(interface, dev);
345
346	/* we can register the device now, as it is ready */
347	retval = usb_register_dev(interface, &skel_class);
348	if (retval) {
349		/* something prevented us from registering this driver */
350		err("Not able to get a minor for this device.");
351		usb_set_intfdata(interface, NULL);
352		goto error;
353	}
354
355	/* let the user know what node this device is now attached to */
356	info("USB Skeleton device now attached to USBSkel-%d", interface->minor);
357	return 0;
358
359error:
360	if (dev)
361		/* this frees allocated memory */
362		kref_put(&dev->kref, skel_delete);
363	return retval;
364}
365
366static void skel_disconnect(struct usb_interface *interface)
367{
368	struct usb_skel *dev;
369	int minor = interface->minor;
370
371	/* prevent skel_open() from racing skel_disconnect() */
372	mutex_lock(&skel_open_lock);
373
374	dev = usb_get_intfdata(interface);
375	usb_set_intfdata(interface, NULL);
376
377	/* give back our minor */
378	usb_deregister_dev(interface, &skel_class);
379	mutex_unlock(&skel_open_lock);
380
381	/* prevent more I/O from starting */
382	mutex_lock(&dev->io_mutex);
383	dev->interface = NULL;
384	mutex_unlock(&dev->io_mutex);
385
386
387
388	/* decrement our usage count */
389	kref_put(&dev->kref, skel_delete);
390
391	info("USB Skeleton #%d now disconnected", minor);
392}
393
394static struct usb_driver skel_driver = {
395	.name =		"skeleton",
396	.probe =	skel_probe,
397	.disconnect =	skel_disconnect,
398	.id_table =	skel_table,
399	.supports_autosuspend = 1,
400};
401
402static int __init usb_skel_init(void)
403{
404	int result;
405
406	/* register this driver with the USB subsystem */
407	result = usb_register(&skel_driver);
408	if (result)
409		err("usb_register failed. Error number %d", result);
410
411	return result;
412}
413
414static void __exit usb_skel_exit(void)
415{
416	/* deregister this driver with the USB subsystem */
417	usb_deregister(&skel_driver);
418}
419
420module_init(usb_skel_init);
421module_exit(usb_skel_exit);
422
423MODULE_LICENSE("GPL");
424