ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / usb / serial / cyberjack.c
1 /*
2  *  REINER SCT cyberJack pinpad/e-com USB Chipcard Reader Driver
3  *
4  *  Copyright (C) 2001  REINER SCT
5  *  Author: Matthias Bruestle
6  *
7  *  Contact: linux-usb@sii.li (see MAINTAINERS)
8  *
9  *  This program is largely derived from work by the linux-usb group
10  *  and associated source files.  Please see the usb/serial files for
11  *  individual credits and copyrights.
12  *
13  *  This program is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License as published by
15  *  the Free Software Foundation; either version 2 of the License, or
16  *  (at your option) any later version.
17  *
18  *  Thanks to Greg Kroah-Hartman (greg@kroah.com) for his help and
19  *  patience.
20  *
21  *  In case of problems, please write to the contact e-mail address
22  *  mentioned above.
23  */
24
25
26 #include <linux/config.h>
27 #include <linux/kernel.h>
28 #include <linux/errno.h>
29 #include <linux/init.h>
30 #include <linux/slab.h>
31 #include <linux/tty.h>
32 #include <linux/tty_driver.h>
33 #include <linux/tty_flip.h>
34 #include <linux/module.h>
35 #include <linux/spinlock.h>
36 #include <asm/uaccess.h>
37 #include <linux/usb.h>
38
39 #define CYBERJACK_LOCAL_BUF_SIZE 32
40
41 #ifdef CONFIG_USB_SERIAL_DEBUG
42         static int debug = 1;
43 #else
44         static int debug;
45 #endif
46
47 #include "usb-serial.h"
48
49 /*
50  * Version Information
51  */
52 #define DRIVER_VERSION "v1.0"
53 #define DRIVER_AUTHOR "Matthias Bruestle"
54 #define DRIVER_DESC "REINER SCT cyberJack pinpad/e-com USB Chipcard Reader Driver"
55
56
57 #define CYBERJACK_VENDOR_ID     0x0C4B
58 #define CYBERJACK_PRODUCT_ID    0x0100
59
60 /* Function prototypes */
61 static int cyberjack_startup (struct usb_serial *serial);
62 static void cyberjack_shutdown (struct usb_serial *serial);
63 static int  cyberjack_open (struct usb_serial_port *port, struct file *filp);
64 static void cyberjack_close (struct usb_serial_port *port, struct file *filp);
65 static int cyberjack_write (struct usb_serial_port *port, int from_user,
66         const unsigned char *buf, int count);
67 static int cyberjack_write_room( struct usb_serial_port *port );
68 static void cyberjack_read_int_callback (struct urb *urb, struct pt_regs *regs);
69 static void cyberjack_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
70 static void cyberjack_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
71
72 static struct usb_device_id id_table [] = {
73         { USB_DEVICE(CYBERJACK_VENDOR_ID, CYBERJACK_PRODUCT_ID) },
74         { }                     /* Terminating entry */
75 };
76
77 MODULE_DEVICE_TABLE (usb, id_table);
78
79 static struct usb_driver cyberjack_driver = {
80         .owner =        THIS_MODULE,
81         .name =         "cyberjack",
82         .probe =        usb_serial_probe,
83         .disconnect =   usb_serial_disconnect,
84         .id_table =     id_table,
85 };
86
87 static struct usb_serial_device_type cyberjack_device = {
88         .owner =                THIS_MODULE,
89         .name =                 "Reiner SCT Cyberjack USB card reader",
90         .short_name =           "cyberjack",
91         .id_table =             id_table,
92         .num_interrupt_in =     1,
93         .num_bulk_in =          1,
94         .num_bulk_out =         1,
95         .num_ports =            1,
96         .attach =               cyberjack_startup,
97         .shutdown =             cyberjack_shutdown,
98         .open =                 cyberjack_open,
99         .close =                cyberjack_close,
100         .write =                cyberjack_write,
101         .write_room =   cyberjack_write_room,
102         .read_int_callback =    cyberjack_read_int_callback,
103         .read_bulk_callback =   cyberjack_read_bulk_callback,
104         .write_bulk_callback =  cyberjack_write_bulk_callback,
105 };
106
107 struct cyberjack_private {
108         spinlock_t      lock;           /* Lock for SMP */
109         short           rdtodo;         /* Bytes still to read */
110         unsigned char   wrbuf[5*64];    /* Buffer for collecting data to write */
111         short           wrfilled;       /* Overall data size we already got */
112         short           wrsent;         /* Data akready sent */
113 };
114
115 /* do some startup allocations not currently performed by usb_serial_probe() */
116 static int cyberjack_startup (struct usb_serial *serial)
117 {
118         struct cyberjack_private *priv;
119
120         dbg("%s", __FUNCTION__);
121
122         /* allocate the private data structure */
123         priv = kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL);
124         if (!priv)
125                 return -ENOMEM;
126
127         /* set initial values */
128         spin_lock_init(&priv->lock);
129         priv->rdtodo = 0;
130         priv->wrfilled = 0;
131         priv->wrsent = 0;
132         usb_set_serial_port_data(serial->port[0], priv);
133
134         init_waitqueue_head(&serial->port[0]->write_wait);
135
136         return( 0 );
137 }
138
139 static void cyberjack_shutdown (struct usb_serial *serial)
140 {
141         int i;
142         
143         dbg("%s", __FUNCTION__);
144
145         for (i=0; i < serial->num_ports; ++i) {
146                 /* My special items, the standard routines free my urbs */
147                 kfree(usb_get_serial_port_data(serial->port[i]));
148                 usb_set_serial_port_data(serial->port[i], NULL);
149         }
150 }
151         
152 static int  cyberjack_open (struct usb_serial_port *port, struct file *filp)
153 {
154         struct cyberjack_private *priv;
155         unsigned long flags;
156         int result = 0;
157
158         if (port_paranoia_check (port, __FUNCTION__))
159                 return -ENODEV;
160
161         dbg("%s - port %d", __FUNCTION__, port->number);
162
163         dbg("%s - usb_clear_halt", __FUNCTION__ );
164         usb_clear_halt(port->serial->dev, port->write_urb->pipe);
165         usb_clear_halt(port->serial->dev, port->read_urb->pipe);
166         usb_clear_halt(port->serial->dev, port->interrupt_in_urb->pipe);
167
168         /* force low_latency on so that our tty_push actually forces
169          * the data through, otherwise it is scheduled, and with high
170          * data rates (like with OHCI) data can get lost.
171          */
172         port->tty->low_latency = 1;
173
174         priv = usb_get_serial_port_data(port);
175         spin_lock_irqsave(&priv->lock, flags);
176         priv->rdtodo = 0;
177         priv->wrfilled = 0;
178         priv->wrsent = 0;
179         spin_unlock_irqrestore(&priv->lock, flags);
180
181         /* shutdown any bulk reads that might be going on */
182         usb_unlink_urb (port->write_urb);
183         usb_unlink_urb (port->read_urb);
184         usb_unlink_urb (port->interrupt_in_urb);
185
186         port->interrupt_in_urb->dev = port->serial->dev;
187         result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
188         if (result)
189                 err(" usb_submit_urb(read int) failed");
190         dbg("%s - usb_submit_urb(int urb)", __FUNCTION__);
191
192         return result;
193 }
194
195 static void cyberjack_close (struct usb_serial_port *port, struct file *filp)
196 {
197         dbg("%s - port %d", __FUNCTION__, port->number);
198
199         if (port->serial->dev) {
200                 /* shutdown any bulk reads that might be going on */
201                 usb_unlink_urb (port->write_urb);
202                 usb_unlink_urb (port->read_urb);
203                 usb_unlink_urb (port->interrupt_in_urb);
204                 dbg("%s - usb_clear_halt", __FUNCTION__ );
205                 usb_clear_halt(port->serial->dev, port->write_urb->pipe);
206                 usb_clear_halt(port->serial->dev, port->read_urb->pipe);
207                 usb_clear_halt(port->serial->dev, port->interrupt_in_urb->pipe);
208         }
209 }
210
211 static int cyberjack_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
212 {
213         struct usb_serial *serial = port->serial;
214         struct cyberjack_private *priv = usb_get_serial_port_data(port);
215         unsigned long flags;
216         int result;
217         int wrexpected;
218         unsigned char localbuf[CYBERJACK_LOCAL_BUF_SIZE];       /* Buffer for collecting data to write */
219
220         dbg("%s - port %d", __FUNCTION__, port->number);
221         dbg("%s - from_user %d", __FUNCTION__, from_user);
222
223         if (count == 0) {
224                 dbg("%s - write request of 0 bytes", __FUNCTION__);
225                 return (0);
226         }
227
228         if (port->write_urb->status == -EINPROGRESS) {
229                 dbg("%s - already writing", __FUNCTION__);
230                 return (0);
231         }
232
233         spin_lock_irqsave(&priv->lock, flags);
234
235         if( (count+priv->wrfilled)>sizeof(priv->wrbuf) ||
236                 (count>sizeof(localbuf)) ) {
237                 /* To much data  for buffer. Reset buffer. */
238                 priv->wrfilled=0;
239                 spin_unlock_irqrestore(&priv->lock, flags);
240                 return (0);
241         }
242
243         spin_unlock_irqrestore(&priv->lock, flags);
244
245         /* Copy data */
246         if (from_user) {
247                 if (copy_from_user(localbuf, buf, count)) {
248                         return -EFAULT;
249                 }
250         } else {
251                 memcpy (localbuf, buf, count);
252         }  
253
254         spin_lock_irqsave(&priv->lock, flags);
255
256         memcpy (priv->wrbuf+priv->wrfilled, localbuf, count);
257
258         usb_serial_debug_data (__FILE__, __FUNCTION__, count,
259                 priv->wrbuf+priv->wrfilled);
260         priv->wrfilled += count;
261
262         if( priv->wrfilled >= 3 ) {
263                 wrexpected = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
264                 dbg("%s - expected data: %d", __FUNCTION__, wrexpected);
265         } else {
266                 wrexpected = sizeof(priv->wrbuf);
267         }
268
269         if( priv->wrfilled >= wrexpected ) {
270                 /* We have enough data to begin transmission */
271                 int length;
272
273                 dbg("%s - transmitting data (frame 1)", __FUNCTION__);
274                 length = (wrexpected > port->bulk_out_size) ? port->bulk_out_size : wrexpected;
275
276                 memcpy (port->write_urb->transfer_buffer, priv->wrbuf, length );
277                 priv->wrsent=length;
278
279                 /* set up our urb */
280                 usb_fill_bulk_urb(port->write_urb, serial->dev, 
281                               usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
282                               port->write_urb->transfer_buffer, length,
283                               ((serial->type->write_bulk_callback) ? 
284                                serial->type->write_bulk_callback : 
285                                cyberjack_write_bulk_callback), 
286                               port);
287
288                 /* send the data out the bulk port */
289                 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
290                 if (result) {
291                         err("%s - failed submitting write urb, error %d", __FUNCTION__, result);
292                         /* Throw away data. No better idea what to do with it. */
293                         priv->wrfilled=0;
294                         priv->wrsent=0;
295                         spin_unlock_irqrestore(&priv->lock, flags);
296                         return 0;
297                 }
298
299                 dbg("%s - priv->wrsent=%d", __FUNCTION__,priv->wrsent);
300                 dbg("%s - priv->wrfilled=%d", __FUNCTION__,priv->wrfilled);
301
302                 if( priv->wrsent>=priv->wrfilled ) {
303                         dbg("%s - buffer cleaned", __FUNCTION__);
304                         memset( priv->wrbuf, 0, sizeof(priv->wrbuf) );
305                         priv->wrfilled=0;
306                         priv->wrsent=0;
307                 }
308         }
309
310         spin_unlock_irqrestore(&priv->lock, flags);
311
312         return (count);
313
314
315 static int cyberjack_write_room( struct usb_serial_port *port )
316 {
317         return CYBERJACK_LOCAL_BUF_SIZE;
318 }
319
320 static void cyberjack_read_int_callback( struct urb *urb, struct pt_regs *regs )
321 {
322         struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
323         struct cyberjack_private *priv = usb_get_serial_port_data(port);
324         struct usb_serial *serial;
325         unsigned char *data = urb->transfer_buffer;
326         int result;
327
328         if (port_paranoia_check (port, __FUNCTION__))
329                 return;
330
331         dbg("%s - port %d", __FUNCTION__, port->number);
332
333         /* the urb might have been killed. */
334         if (urb->status)
335                 return;
336
337         serial = port->serial;
338         if (serial_paranoia_check (serial, __FUNCTION__))
339                 return;
340
341         usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
342
343         /* React only to interrupts signaling a bulk_in transfer */
344         if( (urb->actual_length==4) && (data[0]==0x01) ) {
345                 short old_rdtodo;
346                 int result;
347
348                 /* This is a announcement of coming bulk_ins. */
349                 unsigned short size = ((unsigned short)data[3]<<8)+data[2]+3;
350
351                 spin_lock(&priv->lock);
352
353                 old_rdtodo = priv->rdtodo;
354
355                 if( (old_rdtodo+size)<(old_rdtodo) ) {
356                         dbg( "To many bulk_in urbs to do." );
357                         spin_unlock(&priv->lock);
358                         goto resubmit;
359                 }
360
361                 /* "+=" is probably more fault tollerant than "=" */
362                 priv->rdtodo += size;
363
364                 dbg("%s - rdtodo: %d", __FUNCTION__, priv->rdtodo);
365
366                 spin_unlock(&priv->lock);
367
368                 if( !old_rdtodo ) {
369                         port->read_urb->dev = port->serial->dev;
370                         result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
371                         if( result )
372                                 err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);
373                         dbg("%s - usb_submit_urb(read urb)", __FUNCTION__);
374                 }
375         }
376
377 resubmit:
378         port->interrupt_in_urb->dev = port->serial->dev;
379         result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
380         if (result)
381                 err(" usb_submit_urb(read int) failed");
382         dbg("%s - usb_submit_urb(int urb)", __FUNCTION__);
383 }
384
385 static void cyberjack_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
386 {
387         struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
388         struct cyberjack_private *priv = usb_get_serial_port_data(port);
389         struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
390         struct tty_struct *tty;
391         unsigned char *data = urb->transfer_buffer;
392         short todo;
393         int i;
394         int result;
395
396         dbg("%s - port %d", __FUNCTION__, port->number);
397         
398         if (!serial) {
399                 dbg("%s - bad serial pointer, exiting", __FUNCTION__);
400                 return;
401         }
402
403         if (urb->status) {
404                 usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, urb->transfer_buffer);
405                 dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
406                 return;
407         }
408
409         usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
410
411         tty = port->tty;
412         if (urb->actual_length) {
413                 for (i = 0; i < urb->actual_length ; ++i) {
414                         /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
415                         if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
416                                 tty_flip_buffer_push(tty);
417                         }
418                         /* this doesn't actually push the data through unless tty->low_latency is set */
419                         tty_insert_flip_char(tty, data[i], 0);
420                 }
421                 tty_flip_buffer_push(tty);
422         }
423
424         spin_lock(&priv->lock);
425
426         /* Reduce urbs to do by one. */
427         priv->rdtodo-=urb->actual_length;
428         /* Just to be sure */
429         if ( priv->rdtodo<0 ) priv->rdtodo = 0;
430         todo = priv->rdtodo;
431
432         spin_unlock(&priv->lock);
433
434         dbg("%s - rdtodo: %d", __FUNCTION__, todo);
435
436         /* Continue to read if we have still urbs to do. */
437         if( todo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/ ) {
438                 port->read_urb->dev = port->serial->dev;
439                 result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
440                 if (result)
441                         err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);
442                 dbg("%s - usb_submit_urb(read urb)", __FUNCTION__);
443         }
444 }
445
446 static void cyberjack_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
447 {
448         struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
449         struct cyberjack_private *priv = usb_get_serial_port_data(port);
450         struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
451
452         dbg("%s - port %d", __FUNCTION__, port->number);
453         
454         if (!serial) {
455                 dbg("%s - bad serial pointer, exiting", __FUNCTION__);
456                 return;
457         }
458
459         if (urb->status) {
460                 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
461                 return;
462         }
463
464         spin_lock(&priv->lock);
465
466         /* only do something if we have more data to send */
467         if( priv->wrfilled ) {
468                 int length, blksize, result;
469
470                 if (port->write_urb->status == -EINPROGRESS) {
471                         dbg("%s - already writing", __FUNCTION__);
472                         spin_unlock(&priv->lock);
473                         return;
474                 }
475
476                 dbg("%s - transmitting data (frame n)", __FUNCTION__);
477
478                 length = ((priv->wrfilled - priv->wrsent) > port->bulk_out_size) ?
479                         port->bulk_out_size : (priv->wrfilled - priv->wrsent);
480
481                 memcpy (port->write_urb->transfer_buffer, priv->wrbuf + priv->wrsent,
482                         length );
483                 priv->wrsent+=length;
484
485                 /* set up our urb */
486                 usb_fill_bulk_urb(port->write_urb, serial->dev, 
487                               usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
488                               port->write_urb->transfer_buffer, length,
489                               ((serial->type->write_bulk_callback) ? 
490                                serial->type->write_bulk_callback : 
491                                cyberjack_write_bulk_callback), 
492                               port);
493
494                 /* send the data out the bulk port */
495                 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
496                 if (result) {
497                         err("%s - failed submitting write urb, error %d", __FUNCTION__, result);
498                         /* Throw away data. No better idea what to do with it. */
499                         priv->wrfilled=0;
500                         priv->wrsent=0;
501                         goto exit;
502                 }
503
504                 dbg("%s - priv->wrsent=%d", __FUNCTION__,priv->wrsent);
505                 dbg("%s - priv->wrfilled=%d", __FUNCTION__,priv->wrfilled);
506
507                 blksize = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
508
509                 if( (priv->wrsent>=priv->wrfilled) || (priv->wrsent>=blksize) ) {
510                         dbg("%s - buffer cleaned", __FUNCTION__);
511                         memset( priv->wrbuf, 0, sizeof(priv->wrbuf) );
512                         priv->wrfilled=0;
513                         priv->wrsent=0;
514                 }
515         }
516
517 exit:
518         spin_unlock(&priv->lock);
519         schedule_work(&port->work);
520 }
521
522 static int __init cyberjack_init (void)
523 {
524         int retval;
525         retval  = usb_serial_register(&cyberjack_device);
526         if (retval)
527                 goto failed_usb_serial_register;
528         retval = usb_register(&cyberjack_driver);
529         if (retval) 
530                 goto failed_usb_register;
531
532         info(DRIVER_VERSION " " DRIVER_AUTHOR);
533         info(DRIVER_DESC);
534
535         return 0;
536 failed_usb_register:
537         usb_serial_deregister(&cyberjack_device);
538 failed_usb_serial_register:
539         return retval;
540 }
541
542 static void __exit cyberjack_exit (void)
543 {
544         usb_deregister (&cyberjack_driver);
545         usb_serial_deregister (&cyberjack_device);
546 }
547
548 module_init(cyberjack_init);
549 module_exit(cyberjack_exit);
550
551 MODULE_AUTHOR( DRIVER_AUTHOR );
552 MODULE_DESCRIPTION( DRIVER_DESC );
553 MODULE_LICENSE("GPL");
554
555 MODULE_PARM(debug, "i");
556 MODULE_PARM_DESC(debug, "Debug enabled or not");
557