Successfully creates device nodes, but not in subdirectories
[people/mcb30/quickusb.git] / kernel / quickusb.c
1 /*
2  * QuickUSB driver
3  *
4  * Copyright 2006 Michael Brown <mbrown@fensystems.co.uk>
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; either version 2 of the
9  * License, or (at your option) any later version.
10  *
11  */
12
13 #include <linux/module.h>
14 #include <linux/fs.h>
15 #include <linux/devfs_fs_kernel.h>
16 #include <linux/kref.h>
17 #include <linux/usb.h>
18 #include <asm/uaccess.h>
19 #include "quickusb.h"
20
21 #define QUICKUSB_VENDOR_ID 0x0fbb
22 #define QUICKUSB_DEVICE_ID 0x0001
23
24 #define QUICKUSB_MAX_SUBDEVS 8
25 #define QUICKUSB_SUBDEV_MASK ( QUICKUSB_MAX_SUBDEVS - 1 )
26 #define QUICKUSB_MINOR_BOARD( dev_minor ) \
27         ( (dev_minor) / QUICKUSB_MAX_SUBDEVS )
28 #define QUICKUSB_MINOR_SUBDEV( dev_minor ) \
29         ( (dev_minor) & QUICKUSB_SUBDEV_MASK )
30 #define QUICKUSB_MINOR( board, subdev ) \
31         ( (board) * QUICKUSB_MAX_SUBDEVS + (subdev) )
32
33 #define QUICKUSB_MAX_GPPIO 5
34
35 struct quickusb_gppio {
36         struct quickusb_device *quickusb;
37         unsigned int port;
38 };
39
40 struct quickusb_subdev {
41         struct file_operations *f_op;
42         void *private_data;
43         dev_t dev;
44         unsigned char name[32];
45         struct class_device *class_dev;
46 };
47
48 struct quickusb_device {
49         struct usb_device *usb;
50         struct usb_interface *interface;
51         struct kref kref;
52         struct list_head list;
53         unsigned int board;
54         struct quickusb_gppio gppio[QUICKUSB_MAX_GPPIO];
55         struct quickusb_subdev subdev[QUICKUSB_MAX_SUBDEVS];
56 };
57
58 static void quickusb_delete ( struct kref *kref ) {
59         struct quickusb_device *quickusb;
60
61         quickusb = container_of ( kref, struct quickusb_device, kref );
62         usb_put_dev ( quickusb->usb );
63         kfree ( quickusb );
64 }
65
66 static LIST_HEAD ( quickusb_list );
67
68 static DECLARE_MUTEX ( quickusb_lock );
69
70 static struct class_simple *quickusb_class;
71
72 static int debug = 0;
73 static int dev_major = 0;
74
75 /****************************************************************************
76  *
77  * GPPIO char device operations
78  *
79  */
80
81 static ssize_t quickusb_gppio_read ( struct file *file, char __user *user_data,
82                                      size_t len, loff_t *ppos ) {
83         struct quickusb_gppio *gppio = file->private_data;
84         struct usb_device *usb = gppio->quickusb->usb;
85         unsigned char data[QUICKUSB_MAX_DATA_LEN];
86         int rc;
87
88         if ( len > sizeof ( data ) )
89                 len = sizeof ( data );
90
91         if ( ( rc = quickusb_read_port ( usb, gppio->port,
92                                          data, &len ) ) != 0 )
93                 return rc;
94
95         if ( ( rc = copy_to_user ( user_data, data, len ) ) != 0 )
96                 return rc;
97
98         *ppos += len;
99         return len;
100 }
101
102 static ssize_t quickusb_gppio_write ( struct file *file,
103                                       const char __user *user_data,
104                                       size_t len, loff_t *ppos ) {
105         struct quickusb_gppio *gppio = file->private_data;
106         struct usb_device *usb = gppio->quickusb->usb;
107         unsigned char data[QUICKUSB_MAX_DATA_LEN];
108         int rc;
109
110         if ( len > sizeof ( data ) )
111                 len = sizeof ( data );
112
113         if ( ( rc = copy_from_user ( data, user_data, len ) ) != 0 )
114                 return rc;
115
116         if ( ( rc = quickusb_write_port ( usb, gppio->port,
117                                           data, &len ) ) != 0 )
118                 return rc;
119
120         *ppos += len;
121         return len;
122 }
123
124 static int quickusb_gppio_release ( struct inode *inode, struct file *file ) {
125         struct quickusb_gppio *gppio = file->private_data;
126         
127         kref_put ( &gppio->quickusb->kref, quickusb_delete );
128         return 0;
129 }
130
131 static struct file_operations quickusb_gppio_fops = {
132         .owner          = THIS_MODULE,
133         .read           = quickusb_gppio_read,
134         .write          = quickusb_gppio_write,
135         .release        = quickusb_gppio_release,
136 };
137
138 /****************************************************************************
139  *
140  * Char device (subdev) operations
141  *
142  */
143
144 static int quickusb_open ( struct inode *inode, struct file *file ) {
145         unsigned int board = QUICKUSB_MINOR_BOARD ( iminor ( inode ) );
146         unsigned int subdev = QUICKUSB_MINOR_SUBDEV ( iminor ( inode ) );
147         struct quickusb_device *quickusb;
148         int found = 0;
149         int rc = 0;
150
151         /* Locate board and increase refcount */
152         down ( &quickusb_lock );
153         list_for_each_entry ( quickusb, &quickusb_list, list ) {
154                 if ( quickusb->board == board ) {
155                         kref_get ( &quickusb->kref );
156                         found = 1;
157                         break;
158                 }
159         }
160         up ( &quickusb_lock );
161         if ( ! found ) {
162                 quickusb = NULL;
163                 rc = -ENODEV;
164                 goto out;
165         }
166
167         /* Set up per-subdevice file operations and private data */
168         file->f_op = quickusb->subdev[subdev].f_op;
169         file->private_data = quickusb->subdev[subdev].private_data;
170         if ( ! file->f_op ) {
171                 rc = -ENODEV;
172                 goto out;
173         }
174         
175         /* Perform any subdev-specific open operation */
176         if ( file->f_op->open )
177                 rc = file->f_op->open ( inode, file );
178
179  out:
180         if ( ( rc != 0 ) && quickusb )
181                 kref_put ( &quickusb->kref, quickusb_delete );
182         return rc;
183 }
184
185 static struct file_operations quickusb_fops = {
186         .owner          = THIS_MODULE,
187         .open           = quickusb_open,
188 };
189
190 /****************************************************************************
191  *
192  * Char device (subdev) registration/deregistration
193  *
194  */
195
196 static int quickusb_register_subdev ( struct quickusb_device *quickusb,
197                                       unsigned int subdev_idx,
198                                       struct file_operations *f_op,
199                                       void *private_data,
200                                       const char *subdev_fmt, ... ) {
201         struct quickusb_subdev *subdev = &quickusb->subdev[subdev_idx];
202         struct device *device = &quickusb->interface->dev;
203         unsigned int dev_minor;
204         va_list ap;
205         int rc;
206
207         /* Construct device number */
208         dev_minor = QUICKUSB_MINOR ( quickusb->board, subdev_idx );
209         subdev->dev = MKDEV ( dev_major, dev_minor );
210
211         /* Fill subdev structure */
212         subdev->f_op = f_op;
213         subdev->private_data = private_data;
214
215         /* Construct device name */
216         va_start ( ap, subdev_fmt );
217         vsnprintf ( subdev->name, sizeof ( subdev->name ), subdev_fmt, ap );
218         va_end ( ap );
219
220         /* Create devfs device */
221         if ( ( rc = devfs_mk_cdev ( subdev->dev,
222                                     ( S_IFCHR | S_IRUSR | S_IWUSR |
223                                       S_IRGRP | S_IWGRP ),
224                                     subdev->name ) ) != 0 )
225                 goto err_devfs;
226
227         /* Create class device */
228         subdev->class_dev = class_simple_device_add ( quickusb_class,
229                                                       subdev->dev, device,
230                                                       subdev->name );
231         if ( IS_ERR ( subdev->class_dev ) ) {
232                 rc = PTR_ERR ( subdev->class_dev );
233                 goto err_class;
234         }
235
236         return 0;
237
238  err_class:
239         devfs_remove ( subdev->name );
240  err_devfs:
241         memset ( subdev, 0, sizeof ( *subdev ) );
242         return rc;
243 }
244                                       
245 static void quickusb_deregister_subdev ( struct quickusb_device *quickusb,
246                                          unsigned int subdev_idx ) {
247         struct quickusb_subdev *subdev = &quickusb->subdev[subdev_idx];
248
249         if ( ! subdev->f_op )
250                 return;
251
252         /* Remove class device */
253         class_simple_device_remove ( subdev->dev );
254
255         /* Remove devfs device */
256         devfs_remove ( subdev->name );
257
258         /* Clear subdev structure */
259         memset ( subdev, 0, sizeof ( *subdev ) );
260 }
261
262 /****************************************************************************
263  *
264  * Device creation / destruction
265  *
266  */
267
268 static int quickusb_register_devices ( struct quickusb_device *quickusb ) {
269         unsigned int subdev_idx = 0;
270         struct quickusb_gppio *gppio;
271         unsigned char gppio_char;
272         int i;
273         int rc;
274
275         /* Register GPPIO ports as subdevs */
276         for ( i = 0 ; i < QUICKUSB_MAX_GPPIO ; i++ ) {
277                 gppio = &quickusb->gppio[i];
278                 gppio_char = ( 'a' + gppio->port );
279                 if ( ( rc = quickusb_register_subdev ( quickusb, subdev_idx++,
280                                                        &quickusb_gppio_fops,
281                                                        gppio,
282                                                        "quickusb%d_gppio_%c",
283                                                        quickusb->board,
284                                                        gppio_char ) ) != 0 )
285                         return rc;
286         }
287         
288         return 0;
289 }
290
291 static void quickusb_deregister_devices ( struct quickusb_device *quickusb ) {
292         int i;
293
294         /* Deregister all subdevs */
295         for ( i = 0 ; i < QUICKUSB_MAX_SUBDEVS ; i++ ) {
296                 quickusb_deregister_subdev ( quickusb, i );
297         }
298 }
299
300 /****************************************************************************
301  *
302  * USB hotplug add/remove
303  *
304  */
305
306 static int quickusb_probe ( struct usb_interface *interface,
307                             const struct usb_device_id *id ) {
308         struct quickusb_device *quickusb = NULL;
309         struct quickusb_device *pre_existing_quickusb;
310         unsigned int board = 0;
311         int i;
312         int rc = 0;
313
314         down ( &quickusb_lock );
315
316         /* Create new quickusb device structure */
317         quickusb = kmalloc ( sizeof ( *quickusb ), GFP_KERNEL );
318         if ( ! quickusb ) {
319                 rc = -ENOMEM;
320                 goto err;
321         }
322         memset ( quickusb, 0, sizeof ( *quickusb ) );
323         kref_init ( &quickusb->kref );
324         INIT_LIST_HEAD ( &quickusb_list );
325         quickusb->usb = usb_get_dev ( interface_to_usbdev ( interface ) );
326         quickusb->interface = interface;
327         for ( i = 0 ; i < QUICKUSB_MAX_GPPIO ; i++ ) {
328                 quickusb->gppio[i].quickusb = quickusb;
329                 quickusb->gppio[i].port = i;
330         }
331         
332         /* Obtain a free board board and link into list */
333         list_for_each_entry ( pre_existing_quickusb, &quickusb_list, list ) {
334                 if ( pre_existing_quickusb->board != board )
335                         break;
336                 board++;
337         }
338         quickusb->board = board;
339         list_add_tail ( &quickusb->list, &pre_existing_quickusb->list );
340
341         /* Record driver private data */
342         usb_set_intfdata ( interface, quickusb );
343
344         /* Register devices */
345         if ( ( rc = quickusb_register_devices ( quickusb ) ) != 0 ) {
346                 printk ( KERN_ERR "quickusb unable to register devices\n" );
347                 goto err;
348         }
349
350         printk ( KERN_INFO "quickusb%d connected\n", quickusb->board ); 
351         goto out;
352
353  err:
354         usb_set_intfdata ( interface, NULL );
355         if ( quickusb ) {
356                 quickusb_deregister_devices ( quickusb );
357                 list_del ( &quickusb->list );
358                 kref_put ( &quickusb->kref, quickusb_delete );
359         }
360  out:
361         up ( &quickusb_lock );
362         return rc;
363 }
364
365 static void quickusb_disconnect ( struct usb_interface *interface ) {
366         struct quickusb_device *quickusb = usb_get_intfdata ( interface );
367
368         printk ( KERN_INFO "quickusb%d disconnected\n", quickusb->board );
369
370         down ( &quickusb_lock );
371         usb_set_intfdata ( interface, NULL );
372         quickusb_deregister_devices ( quickusb );
373         list_del ( &quickusb->list );
374         up ( &quickusb_lock );
375
376         kref_put ( &quickusb->kref, quickusb_delete );
377 }
378
379 static struct usb_device_id quickusb_ids[] = {
380         { USB_DEVICE ( QUICKUSB_VENDOR_ID, QUICKUSB_DEVICE_ID ) },
381         { },
382 };
383
384 static struct usb_driver quickusb_driver = {
385         .owner          = THIS_MODULE,
386         .name           = "quickusb",
387         .probe          = quickusb_probe,
388         .disconnect     = quickusb_disconnect,
389         .id_table       = quickusb_ids,
390 };
391
392 /****************************************************************************
393  *
394  * Kernel module interface
395  *
396  */
397
398 static int quickusb_init ( void ) {
399         int rc;
400
401         /* Register major char device */
402         if ( ( rc = register_chrdev ( dev_major, "quickusb",
403                                       &quickusb_fops ) ) < 0 ) {
404                 printk ( KERN_ERR "quickusb could not register char device: "
405                          "error %d\n", rc );
406                 goto err_chrdev;
407         }
408         if ( ! dev_major ) {
409                 dev_major = rc;
410                 printk ( KERN_INFO "quickusb using major device %d\n",
411                          dev_major );
412         }
413         
414         /* Create device class */
415         quickusb_class = class_simple_create ( THIS_MODULE, "quickusb" );
416         if ( IS_ERR ( quickusb_class ) ) {
417                 rc = PTR_ERR ( quickusb_class );
418                 printk ( KERN_ERR "quickusb could not create device class: "
419                          "error %d\n", rc );
420                 goto err_class;
421         }
422
423         if ( ( rc = usb_register ( &quickusb_driver ) ) != 0 )
424                 goto err_usb;
425
426         return 0;
427
428  err_usb:
429         class_simple_destroy ( quickusb_class );
430  err_class:
431         unregister_chrdev ( dev_major, "quickusb" );
432  err_chrdev:
433         return rc;
434 }
435
436 static void quickusb_exit ( void ) {
437         usb_deregister ( &quickusb_driver );
438         class_simple_destroy ( quickusb_class );
439         unregister_chrdev ( dev_major, "quickusb" );
440 }
441
442 module_init ( quickusb_init );
443 module_exit ( quickusb_exit );
444
445 MODULE_AUTHOR ( "Michael Brown <mbrown@fensystems.co.uk>" );
446 MODULE_DESCRIPTION ( "QuickUSB serial driver" );
447 MODULE_LICENSE ( "GPL" );
448 MODULE_DEVICE_TABLE ( usb, quickusb_ids );
449
450 module_param ( debug, bool, S_IRUGO | S_IWUSR );
451 MODULE_PARM_DESC ( debug, "Enable debugging" );
452
453 module_param ( dev_major, uint, S_IRUGO | S_IWUSR );
454 MODULE_PARM_DESC ( dev_major, "Major device number" );