Towards compiling on 2.4
[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/usb.h>
17 #include <asm/uaccess.h>
18 #include "quickusb.h"
19 #include "kernel_compat.h"
20
21 #define QUICKUSB_VENDOR_ID 0x0fbb
22 #define QUICKUSB_DEVICE_ID 0x0001
23
24 #define QUICKUSB_MAX_SUBDEVS 16
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_hspio {
41         struct quickusb_device *quickusb;
42 };
43
44 struct quickusb_subdev {
45         struct file_operations *f_op;
46         void *private_data;
47         dev_t dev;
48         unsigned char name[32];
49         struct class_device *class_dev;
50 };
51
52 struct quickusb_device {
53         struct usb_device *usb;
54         struct usb_interface *interface;
55         struct kref kref;
56         struct list_head list;
57         unsigned int board;
58         struct quickusb_gppio gppio[QUICKUSB_MAX_GPPIO];
59         struct quickusb_hspio hspio;
60         struct quickusb_subdev subdev[QUICKUSB_MAX_SUBDEVS];
61 };
62
63 static void quickusb_delete ( struct kref *kref ) {
64         struct quickusb_device *quickusb;
65
66         quickusb = container_of ( kref, struct quickusb_device, kref );
67         usb_put_dev ( quickusb->usb );
68         kfree ( quickusb );
69 }
70
71 static LIST_HEAD ( quickusb_list );
72
73 static DECLARE_MUTEX ( quickusb_lock );
74
75 static struct class_simple *quickusb_class;
76
77 static int debug = 0;
78 static int dev_major = 0;
79
80 /****************************************************************************
81  *
82  * GPPIO char device operations
83  *
84  */
85
86 static ssize_t quickusb_gppio_read ( struct file *file, char __user *user_data,
87                                      size_t len, loff_t *ppos ) {
88         struct quickusb_gppio *gppio = file->private_data;
89         unsigned char data[QUICKUSB_MAX_DATA_LEN];
90         int rc;
91
92         if ( len > sizeof ( data ) )
93                 len = sizeof ( data );
94
95         if ( ( rc = quickusb_read_port ( gppio->quickusb->usb, gppio->port,
96                                          data, len ) ) != 0 )
97                 return rc;
98
99         if ( ( rc = copy_to_user ( user_data, data, len ) ) != 0 )
100                 return rc;
101
102         *ppos += len;
103         return len;
104 }
105
106 static ssize_t quickusb_gppio_write ( struct file *file,
107                                       const char __user *user_data,
108                                       size_t len, loff_t *ppos ) {
109         struct quickusb_gppio *gppio = file->private_data;
110         unsigned char data[QUICKUSB_MAX_DATA_LEN];
111         int rc;
112
113         if ( len > sizeof ( data ) )
114                 len = sizeof ( data );
115
116         if ( ( rc = copy_from_user ( data, user_data, len ) ) != 0 )
117                 return rc;
118
119         if ( ( rc = quickusb_write_port ( gppio->quickusb->usb, gppio->port,
120                                           data, len ) ) != 0 )
121                 return rc;
122
123         *ppos += len;
124         return len;
125 }
126
127 static int quickusb_gppio_ioctl ( struct inode *inode, struct file *file,
128                                   unsigned int cmd, unsigned long arg ) {
129         struct quickusb_gppio *gppio = file->private_data;
130         void __user *user_data = ( void __user * ) arg;
131         quickusb_gppio_ioctl_data_t data;
132         unsigned char outputs;
133         int rc;
134
135         if ( ( rc = copy_from_user ( &data, user_data, sizeof (data) ) ) != 0 )
136                 return rc;
137
138         switch ( cmd ) {
139         case QUICKUSB_IOC_GPPIO_GET_OUTPUTS:
140                 if ( ( rc = quickusb_read_port_dir ( gppio->quickusb->usb,
141                                                      gppio->port,
142                                                      &outputs ) ) != 0 )
143                         return rc;
144                 data = outputs;
145                 break;
146         case QUICKUSB_IOC_GPPIO_SET_OUTPUTS:
147                 outputs = data;
148                 if ( ( rc = quickusb_write_port_dir ( gppio->quickusb->usb,
149                                                       gppio->port,
150                                                       outputs ) ) != 0 )
151                         return rc;
152                 break;
153         default:
154                 return -ENOTTY;
155         }
156
157         if ( ( rc = copy_to_user ( user_data, &data, sizeof ( data ) ) ) != 0 )
158                 return rc;
159
160         return 0;
161 }
162
163 static int quickusb_gppio_release ( struct inode *inode, struct file *file ) {
164         struct quickusb_gppio *gppio = file->private_data;
165         
166         kref_put ( &gppio->quickusb->kref, quickusb_delete );
167         return 0;
168 }
169
170 static struct file_operations quickusb_gppio_fops = {
171         .owner          = THIS_MODULE,
172         .read           = quickusb_gppio_read,
173         .write          = quickusb_gppio_write,
174         .ioctl          = quickusb_gppio_ioctl,
175         .release        = quickusb_gppio_release,
176 };
177
178 /****************************************************************************
179  *
180  * HSPIO char device operations
181  *
182  */
183
184 static ssize_t quickusb_hspio_read_command ( struct file *file,
185                                              char __user *user_data,
186                                              size_t len, loff_t *ppos ) {
187         struct quickusb_hspio *hspio = file->private_data;
188         unsigned char data[QUICKUSB_MAX_DATA_LEN];
189         int rc;
190
191         if ( len > sizeof ( data ) )
192                 len = sizeof ( data );
193
194         if ( ( rc = quickusb_read_command ( hspio->quickusb->usb, *ppos,
195                                             data, len ) ) != 0 )
196                 return rc;
197
198         if ( ( rc = copy_to_user ( user_data, data, len ) ) != 0 )
199                 return rc;
200
201         *ppos += len;
202         return len;
203 }
204
205 static ssize_t quickusb_hspio_write_command ( struct file *file,
206                                               const char __user *user_data,
207                                               size_t len, loff_t *ppos ) {
208         struct quickusb_hspio *hspio = file->private_data;
209         unsigned char data[QUICKUSB_MAX_DATA_LEN];
210         int rc;
211
212         if ( len > sizeof ( data ) )
213                 len = sizeof ( data );
214
215         if ( ( rc = copy_from_user ( data, user_data, len ) ) != 0 )
216                 return rc;
217
218         if ( ( rc = quickusb_write_command ( hspio->quickusb->usb, *ppos,
219                                              data, len ) ) != 0 )
220                 return rc;
221
222         *ppos += len;
223         return len;
224 }
225
226 static ssize_t quickusb_hspio_read_data ( struct file *file,
227                                           char __user *user_data,
228                                           size_t len, loff_t *ppos ) {
229         struct quickusb_hspio *hspio = file->private_data;
230         unsigned char data[QUICKUSB_MAX_BULK_DATA_LEN];
231         int rc;
232
233         if ( len > sizeof ( data ) )
234                 len = sizeof ( data );
235
236         if ( ( rc = quickusb_read_data ( hspio->quickusb->usb,
237                                          data, len ) ) != 0 )
238                 return rc;
239
240         if ( ( rc = copy_to_user ( user_data, data, len ) ) != 0 )
241                 return rc;
242
243         *ppos += len;
244         return len;
245 }
246
247 static ssize_t quickusb_hspio_write_data ( struct file *file,
248                                            const char __user *user_data,
249                                            size_t len, loff_t *ppos ) {
250         struct quickusb_hspio *hspio = file->private_data;
251         unsigned char data[QUICKUSB_MAX_BULK_DATA_LEN];
252         int rc;
253
254         if ( len > sizeof ( data ) )
255                 len = sizeof ( data );
256
257         if ( ( rc = copy_from_user ( data, user_data, len ) ) != 0 )
258                 return rc;
259
260         if ( ( rc = quickusb_write_data ( hspio->quickusb->usb,
261                                           data, len ) ) != 0 )
262                 return rc;
263
264         *ppos += len;
265         return len;
266 }
267
268 static int quickusb_hspio_release ( struct inode *inode, struct file *file ) {
269         struct quickusb_hspio *hspio = file->private_data;
270         
271         kref_put ( &hspio->quickusb->kref, quickusb_delete );
272         return 0;
273 }
274
275 static struct file_operations quickusb_hspio_command_fops = {
276         .owner          = THIS_MODULE,
277         .read           = quickusb_hspio_read_command,
278         .write          = quickusb_hspio_write_command,
279         .release        = quickusb_hspio_release,
280 };
281
282 static struct file_operations quickusb_hspio_data_fops = {
283         .owner          = THIS_MODULE,
284         .read           = quickusb_hspio_read_data,
285         .write          = quickusb_hspio_write_data,
286         .release        = quickusb_hspio_release,
287 };
288
289 /****************************************************************************
290  *
291  * Char device (subdev) operations
292  *
293  */
294
295 static int quickusb_open ( struct inode *inode, struct file *file ) {
296         unsigned int board = QUICKUSB_MINOR_BOARD ( iminor ( inode ) );
297         unsigned int subdev = QUICKUSB_MINOR_SUBDEV ( iminor ( inode ) );
298         struct quickusb_device *quickusb;
299         int found = 0;
300         int rc = 0;
301
302         /* Locate board and increase refcount */
303         down ( &quickusb_lock );
304         list_for_each_entry ( quickusb, &quickusb_list, list ) {
305                 if ( quickusb->board == board ) {
306                         kref_get ( &quickusb->kref );
307                         found = 1;
308                         break;
309                 }
310         }
311         up ( &quickusb_lock );
312         if ( ! found ) {
313                 quickusb = NULL;
314                 rc = -ENODEV;
315                 goto out;
316         }
317
318         /* Set up per-subdevice file operations and private data */
319         file->f_op = quickusb->subdev[subdev].f_op;
320         file->private_data = quickusb->subdev[subdev].private_data;
321         if ( ! file->f_op ) {
322                 rc = -ENODEV;
323                 goto out;
324         }
325         
326         /* Perform any subdev-specific open operation */
327         if ( file->f_op->open )
328                 rc = file->f_op->open ( inode, file );
329
330  out:
331         if ( ( rc != 0 ) && quickusb )
332                 kref_put ( &quickusb->kref, quickusb_delete );
333         return rc;
334 }
335
336 static struct file_operations quickusb_fops = {
337         .owner          = THIS_MODULE,
338         .open           = quickusb_open,
339 };
340
341 /****************************************************************************
342  *
343  * Char device (subdev) registration/deregistration
344  *
345  */
346
347 static int quickusb_register_subdev ( struct quickusb_device *quickusb,
348                                       unsigned int subdev_idx,
349                                       struct file_operations *f_op,
350                                       void *private_data,
351                                       const char *subdev_fmt, ... ) {
352         struct quickusb_subdev *subdev = &quickusb->subdev[subdev_idx];
353         struct usb_interface *interface = quickusb->interface;
354         unsigned int dev_minor;
355         va_list ap;
356         int rc;
357
358         /* Construct device number */
359         dev_minor = QUICKUSB_MINOR ( quickusb->board, subdev_idx );
360         subdev->dev = MKDEV ( dev_major, dev_minor );
361
362         /* Fill subdev structure */
363         subdev->f_op = f_op;
364         subdev->private_data = private_data;
365
366         /* Construct device name */
367         va_start ( ap, subdev_fmt );
368         vsnprintf ( subdev->name, sizeof ( subdev->name ), subdev_fmt, ap );
369         va_end ( ap );
370
371         /* Create devfs device */
372         if ( ( rc = devfs_mk_cdev ( subdev->dev,
373                                     ( S_IFCHR | S_IRUSR | S_IWUSR |
374                                       S_IRGRP | S_IWGRP ),
375                                     subdev->name ) ) != 0 )
376                 goto err_devfs;
377
378         /* Create class device */
379         subdev->class_dev = class_simple_device_add ( quickusb_class,
380                                                       subdev->dev,
381                                                       &interface->dev,
382                                                       subdev->name );
383         if ( IS_ERR ( subdev->class_dev ) ) {
384                 rc = PTR_ERR ( subdev->class_dev );
385                 goto err_class;
386         }
387
388         return 0;
389
390  err_class:
391         devfs_remove ( subdev->name );
392  err_devfs:
393         memset ( subdev, 0, sizeof ( *subdev ) );
394         return rc;
395 }
396                                       
397 static void quickusb_deregister_subdev ( struct quickusb_device *quickusb,
398                                          unsigned int subdev_idx ) {
399         struct quickusb_subdev *subdev = &quickusb->subdev[subdev_idx];
400
401         if ( ! subdev->f_op )
402                 return;
403
404         /* Remove class device */
405         class_simple_device_remove ( subdev->dev );
406
407         /* Remove devfs device */
408         devfs_remove ( subdev->name );
409
410         /* Clear subdev structure */
411         memset ( subdev, 0, sizeof ( *subdev ) );
412 }
413
414 /****************************************************************************
415  *
416  * Device creation / destruction
417  *
418  */
419
420 static int quickusb_register_devices ( struct quickusb_device *quickusb ) {
421         unsigned int subdev_idx = 0;
422         struct quickusb_gppio *gppio;
423         unsigned char gppio_char;
424         int i;
425         int rc;
426
427         /* Register GPPIO ports as subdevs */
428         for ( i = 0 ; i < QUICKUSB_MAX_GPPIO ; i++ ) {
429                 gppio = &quickusb->gppio[i];
430                 gppio_char = ( 'a' + gppio->port );
431                 if ( ( rc = quickusb_register_subdev ( quickusb, subdev_idx++,
432                                                        &quickusb_gppio_fops,
433                                                        gppio,
434                                                        "qu%dg%c",
435                                                        quickusb->board,
436                                                        gppio_char ) ) != 0 )
437                         return rc;
438         }
439
440         /* Register HSPIO port in all its variants */
441         if ( ( rc = quickusb_register_subdev ( quickusb, subdev_idx++,
442                                                &quickusb_hspio_command_fops,
443                                                &quickusb->hspio,
444                                                "qu%dhc",
445                                                quickusb->board ) ) != 0 )
446                 return rc;
447         if ( ( rc = quickusb_register_subdev ( quickusb, subdev_idx++,
448                                                &quickusb_hspio_data_fops,
449                                                &quickusb->hspio,
450                                                "qu%dhd",
451                                                quickusb->board ) ) != 0 )
452                 return rc;
453         
454         return 0;
455 }
456
457 static void quickusb_deregister_devices ( struct quickusb_device *quickusb ) {
458         int i;
459
460         /* Deregister all subdevs */
461         for ( i = 0 ; i < QUICKUSB_MAX_SUBDEVS ; i++ ) {
462                 quickusb_deregister_subdev ( quickusb, i );
463         }
464 }
465
466 /****************************************************************************
467  *
468  * USB hotplug add/remove
469  *
470  */
471
472 static int quickusb_probe ( struct usb_interface *interface,
473                             const struct usb_device_id *id ) {
474         struct quickusb_device *quickusb = NULL;
475         struct quickusb_device *pre_existing_quickusb;
476         unsigned int board = 0;
477         int i;
478         int rc = 0;
479
480         down ( &quickusb_lock );
481
482         /* Create new quickusb device structure */
483         quickusb = kmalloc ( sizeof ( *quickusb ), GFP_KERNEL );
484         if ( ! quickusb ) {
485                 rc = -ENOMEM;
486                 goto err;
487         }
488         memset ( quickusb, 0, sizeof ( *quickusb ) );
489         kref_init ( &quickusb->kref );
490         INIT_LIST_HEAD ( &quickusb_list );
491         quickusb->usb = usb_get_dev ( interface_to_usbdev ( interface ) );
492         quickusb->interface = interface;
493         for ( i = 0 ; i < QUICKUSB_MAX_GPPIO ; i++ ) {
494                 quickusb->gppio[i].quickusb = quickusb;
495                 quickusb->gppio[i].port = i;
496         }
497         quickusb->hspio.quickusb = quickusb;
498         
499         /* Obtain a free board board and link into list */
500         list_for_each_entry ( pre_existing_quickusb, &quickusb_list, list ) {
501                 if ( pre_existing_quickusb->board != board )
502                         break;
503                 board++;
504         }
505         quickusb->board = board;
506         list_add_tail ( &quickusb->list, &pre_existing_quickusb->list );
507
508         /* Record driver private data */
509         usb_set_intfdata ( interface, quickusb );
510
511         /* Register devices */
512         if ( ( rc = quickusb_register_devices ( quickusb ) ) != 0 ) {
513                 printk ( KERN_ERR "quickusb unable to register devices\n" );
514                 goto err;
515         }
516
517         printk ( KERN_INFO "quickusb%d connected\n", quickusb->board ); 
518         goto out;
519
520  err:
521         usb_set_intfdata ( interface, NULL );
522         if ( quickusb ) {
523                 quickusb_deregister_devices ( quickusb );
524                 list_del ( &quickusb->list );
525                 kref_put ( &quickusb->kref, quickusb_delete );
526         }
527  out:
528         up ( &quickusb_lock );
529         return rc;
530 }
531
532 static void quickusb_disconnect ( struct usb_interface *interface ) {
533         struct quickusb_device *quickusb = usb_get_intfdata ( interface );
534
535         printk ( KERN_INFO "quickusb%d disconnected\n", quickusb->board );
536
537         down ( &quickusb_lock );
538         usb_set_intfdata ( interface, NULL );
539         quickusb_deregister_devices ( quickusb );
540         list_del ( &quickusb->list );
541         up ( &quickusb_lock );
542
543         kref_put ( &quickusb->kref, quickusb_delete );
544 }
545
546 static struct usb_device_id quickusb_ids[] = {
547         { USB_DEVICE ( QUICKUSB_VENDOR_ID, QUICKUSB_DEVICE_ID ) },
548         { },
549 };
550
551 static struct usb_driver quickusb_driver = {
552         .owner          = THIS_MODULE,
553         .name           = "quickusb",
554         .probe          = quickusb_probe,
555         .disconnect     = quickusb_disconnect,
556         .id_table       = quickusb_ids,
557 };
558
559 /****************************************************************************
560  *
561  * Kernel module interface
562  *
563  */
564
565 static int quickusb_init ( void ) {
566         int rc;
567
568         /* Register major char device */
569         if ( ( rc = register_chrdev ( dev_major, "quickusb",
570                                       &quickusb_fops ) ) < 0 ) {
571                 printk ( KERN_ERR "quickusb could not register char device: "
572                          "error %d\n", rc );
573                 goto err_chrdev;
574         }
575         if ( ! dev_major ) {
576                 dev_major = rc;
577                 printk ( KERN_INFO "quickusb using major device %d\n",
578                          dev_major );
579         }
580         
581         /* Create device class */
582         quickusb_class = class_simple_create ( THIS_MODULE, "quickusb" );
583         if ( IS_ERR ( quickusb_class ) ) {
584                 rc = PTR_ERR ( quickusb_class );
585                 printk ( KERN_ERR "quickusb could not create device class: "
586                          "error %d\n", rc );
587                 goto err_class;
588         }
589
590         if ( ( rc = usb_register ( &quickusb_driver ) ) != 0 )
591                 goto err_usb;
592
593         return 0;
594
595  err_usb:
596         class_simple_destroy ( quickusb_class );
597  err_class:
598         unregister_chrdev ( dev_major, "quickusb" );
599  err_chrdev:
600         return rc;
601 }
602
603 static void quickusb_exit ( void ) {
604         usb_deregister ( &quickusb_driver );
605         class_simple_destroy ( quickusb_class );
606         unregister_chrdev ( dev_major, "quickusb" );
607 }
608
609 module_init ( quickusb_init );
610 module_exit ( quickusb_exit );
611
612 MODULE_AUTHOR ( "Michael Brown <mbrown@fensystems.co.uk>" );
613 MODULE_DESCRIPTION ( "QuickUSB serial driver" );
614 MODULE_LICENSE ( "GPL" );
615 MODULE_DEVICE_TABLE ( usb, quickusb_ids );
616
617 module_param ( debug, bool, S_IRUGO | S_IWUSR );
618 MODULE_PARM_DESC ( debug, "Enable debugging" );
619
620 module_param ( dev_major, uint, S_IRUGO | S_IWUSR );
621 MODULE_PARM_DESC ( dev_major, "Major device number" );