patch-2_6_7-vs1_9_1_12
[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 already 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         dbg("%s - port %d", __FUNCTION__, port->number);
159
160         dbg("%s - usb_clear_halt", __FUNCTION__ );
161         usb_clear_halt(port->serial->dev, port->write_urb->pipe);
162
163         /* force low_latency on so that our tty_push actually forces
164          * the data through, otherwise it is scheduled, and with high
165          * data rates (like with OHCI) data can get lost.
166          */
167         port->tty->low_latency = 1;
168
169         priv = usb_get_serial_port_data(port);
170         spin_lock_irqsave(&priv->lock, flags);
171         priv->rdtodo = 0;
172         priv->wrfilled = 0;
173         priv->wrsent = 0;
174         spin_unlock_irqrestore(&priv->lock, flags);
175
176         /* shutdown any bulk reads that might be going on */
177         usb_unlink_urb (port->write_urb);
178         usb_unlink_urb (port->read_urb);
179         usb_unlink_urb (port->interrupt_in_urb);
180
181         port->interrupt_in_urb->dev = port->serial->dev;
182         result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
183         if (result)
184                 err(" usb_submit_urb(read int) failed");
185         dbg("%s - usb_submit_urb(int urb)", __FUNCTION__);
186
187         return result;
188 }
189
190 static void cyberjack_close (struct usb_serial_port *port, struct file *filp)
191 {
192         dbg("%s - port %d", __FUNCTION__, port->number);
193
194         if (port->serial->dev) {
195                 /* shutdown any bulk reads that might be going on */
196                 usb_unlink_urb (port->write_urb);
197                 usb_unlink_urb (port->read_urb);
198                 usb_unlink_urb (port->interrupt_in_urb);
199                 dbg("%s - usb_clear_halt", __FUNCTION__ );
200                 usb_clear_halt(port->serial->dev, port->write_urb->pipe);
201                 usb_clear_halt(port->serial->dev, port->read_urb->pipe);
202                 usb_clear_halt(port->serial->dev, port->interrupt_in_urb->pipe);
203         }
204 }
205
206 static int cyberjack_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
207 {
208         struct usb_serial *serial = port->serial;
209         struct cyberjack_private *priv = usb_get_serial_port_data(port);
210         unsigned long flags;
211         int result;
212         int wrexpected;
213
214         dbg("%s - port %d", __FUNCTION__, port->number);
215         dbg("%s - from_user %d", __FUNCTION__, from_user);
216
217         if (count == 0) {
218                 dbg("%s - write request of 0 bytes", __FUNCTION__);
219                 return (0);
220         }
221
222         if (port->write_urb->status == -EINPROGRESS) {
223                 dbg("%s - already writing", __FUNCTION__);
224                 return (0);
225         }
226
227         spin_lock_irqsave(&priv->lock, flags);
228
229         if( (count+priv->wrfilled)>sizeof(priv->wrbuf) ) {
230                 /* To much data for buffer. Reset buffer. */
231                 priv->wrfilled=0;
232                 spin_unlock_irqrestore(&priv->lock, flags);
233                 return (0);
234         }
235
236         /* Copy data */
237         if (from_user) {
238                 if (copy_from_user(priv->wrbuf+priv->wrfilled, buf, count)) {
239                         spin_unlock_irqrestore(&priv->lock, flags);
240                         return -EFAULT;
241                 }
242         } else {
243                 memcpy (priv->wrbuf+priv->wrfilled, buf, count);
244         }  
245
246         usb_serial_debug_data (__FILE__, __FUNCTION__, count,
247                 priv->wrbuf+priv->wrfilled);
248         priv->wrfilled += count;
249
250         if( priv->wrfilled >= 3 ) {
251                 wrexpected = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
252                 dbg("%s - expected data: %d", __FUNCTION__, wrexpected);
253         } else {
254                 wrexpected = sizeof(priv->wrbuf);
255         }
256
257         if( priv->wrfilled >= wrexpected ) {
258                 /* We have enough data to begin transmission */
259                 int length;
260
261                 dbg("%s - transmitting data (frame 1)", __FUNCTION__);
262                 length = (wrexpected > port->bulk_out_size) ? port->bulk_out_size : wrexpected;
263
264                 memcpy (port->write_urb->transfer_buffer, priv->wrbuf, length );
265                 priv->wrsent=length;
266
267                 /* set up our urb */
268                 usb_fill_bulk_urb(port->write_urb, serial->dev, 
269                               usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
270                               port->write_urb->transfer_buffer, length,
271                               ((serial->type->write_bulk_callback) ? 
272                                serial->type->write_bulk_callback : 
273                                cyberjack_write_bulk_callback), 
274                               port);
275
276                 /* send the data out the bulk port */
277                 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
278                 if (result) {
279                         err("%s - failed submitting write urb, error %d", __FUNCTION__, result);
280                         /* Throw away data. No better idea what to do with it. */
281                         priv->wrfilled=0;
282                         priv->wrsent=0;
283                         spin_unlock_irqrestore(&priv->lock, flags);
284                         return 0;
285                 }
286
287                 dbg("%s - priv->wrsent=%d", __FUNCTION__,priv->wrsent);
288                 dbg("%s - priv->wrfilled=%d", __FUNCTION__,priv->wrfilled);
289
290                 if( priv->wrsent>=priv->wrfilled ) {
291                         dbg("%s - buffer cleaned", __FUNCTION__);
292                         memset( priv->wrbuf, 0, sizeof(priv->wrbuf) );
293                         priv->wrfilled=0;
294                         priv->wrsent=0;
295                 }
296         }
297
298         spin_unlock_irqrestore(&priv->lock, flags);
299
300         return (count);
301
302
303 static int cyberjack_write_room( struct usb_serial_port *port )
304 {
305         return CYBERJACK_LOCAL_BUF_SIZE;
306 }
307
308 static void cyberjack_read_int_callback( struct urb *urb, struct pt_regs *regs )
309 {
310         struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
311         struct cyberjack_private *priv = usb_get_serial_port_data(port);
312         unsigned char *data = urb->transfer_buffer;
313         int result;
314
315         dbg("%s - port %d", __FUNCTION__, port->number);
316
317         /* the urb might have been killed. */
318         if (urb->status)
319                 return;
320
321         usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
322
323         /* React only to interrupts signaling a bulk_in transfer */
324         if( (urb->actual_length==4) && (data[0]==0x01) ) {
325                 short old_rdtodo;
326                 int result;
327
328                 /* This is a announcement of coming bulk_ins. */
329                 unsigned short size = ((unsigned short)data[3]<<8)+data[2]+3;
330
331                 spin_lock(&priv->lock);
332
333                 old_rdtodo = priv->rdtodo;
334
335                 if( (old_rdtodo+size)<(old_rdtodo) ) {
336                         dbg( "To many bulk_in urbs to do." );
337                         spin_unlock(&priv->lock);
338                         goto resubmit;
339                 }
340
341                 /* "+=" is probably more fault tollerant than "=" */
342                 priv->rdtodo += size;
343
344                 dbg("%s - rdtodo: %d", __FUNCTION__, priv->rdtodo);
345
346                 spin_unlock(&priv->lock);
347
348                 if( !old_rdtodo ) {
349                         port->read_urb->dev = port->serial->dev;
350                         result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
351                         if( result )
352                                 err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);
353                         dbg("%s - usb_submit_urb(read urb)", __FUNCTION__);
354                 }
355         }
356
357 resubmit:
358         port->interrupt_in_urb->dev = port->serial->dev;
359         result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
360         if (result)
361                 err(" usb_submit_urb(read int) failed");
362         dbg("%s - usb_submit_urb(int urb)", __FUNCTION__);
363 }
364
365 static void cyberjack_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
366 {
367         struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
368         struct cyberjack_private *priv = usb_get_serial_port_data(port);
369         struct tty_struct *tty;
370         unsigned char *data = urb->transfer_buffer;
371         short todo;
372         int i;
373         int result;
374
375         dbg("%s - port %d", __FUNCTION__, port->number);
376         
377         if (urb->status) {
378                 usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, urb->transfer_buffer);
379                 dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
380                 return;
381         }
382
383         usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
384
385         tty = port->tty;
386         if (urb->actual_length) {
387                 for (i = 0; i < urb->actual_length ; ++i) {
388                         /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
389                         if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
390                                 tty_flip_buffer_push(tty);
391                         }
392                         /* this doesn't actually push the data through unless tty->low_latency is set */
393                         tty_insert_flip_char(tty, data[i], 0);
394                 }
395                 tty_flip_buffer_push(tty);
396         }
397
398         spin_lock(&priv->lock);
399
400         /* Reduce urbs to do by one. */
401         priv->rdtodo-=urb->actual_length;
402         /* Just to be sure */
403         if ( priv->rdtodo<0 ) priv->rdtodo = 0;
404         todo = priv->rdtodo;
405
406         spin_unlock(&priv->lock);
407
408         dbg("%s - rdtodo: %d", __FUNCTION__, todo);
409
410         /* Continue to read if we have still urbs to do. */
411         if( todo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/ ) {
412                 port->read_urb->dev = port->serial->dev;
413                 result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
414                 if (result)
415                         err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);
416                 dbg("%s - usb_submit_urb(read urb)", __FUNCTION__);
417         }
418 }
419
420 static void cyberjack_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
421 {
422         struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
423         struct cyberjack_private *priv = usb_get_serial_port_data(port);
424
425         dbg("%s - port %d", __FUNCTION__, port->number);
426         
427         if (urb->status) {
428                 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
429                 return;
430         }
431
432         spin_lock(&priv->lock);
433
434         /* only do something if we have more data to send */
435         if( priv->wrfilled ) {
436                 int length, blksize, result;
437
438                 if (port->write_urb->status == -EINPROGRESS) {
439                         dbg("%s - already writing", __FUNCTION__);
440                         spin_unlock(&priv->lock);
441                         return;
442                 }
443
444                 dbg("%s - transmitting data (frame n)", __FUNCTION__);
445
446                 length = ((priv->wrfilled - priv->wrsent) > port->bulk_out_size) ?
447                         port->bulk_out_size : (priv->wrfilled - priv->wrsent);
448
449                 memcpy (port->write_urb->transfer_buffer, priv->wrbuf + priv->wrsent,
450                         length );
451                 priv->wrsent+=length;
452
453                 /* set up our urb */
454                 usb_fill_bulk_urb(port->write_urb, port->serial->dev, 
455                               usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress),
456                               port->write_urb->transfer_buffer, length,
457                               ((port->serial->type->write_bulk_callback) ? 
458                                port->serial->type->write_bulk_callback : 
459                                cyberjack_write_bulk_callback), 
460                               port);
461
462                 /* send the data out the bulk port */
463                 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
464                 if (result) {
465                         err("%s - failed submitting write urb, error %d", __FUNCTION__, result);
466                         /* Throw away data. No better idea what to do with it. */
467                         priv->wrfilled=0;
468                         priv->wrsent=0;
469                         goto exit;
470                 }
471
472                 dbg("%s - priv->wrsent=%d", __FUNCTION__,priv->wrsent);
473                 dbg("%s - priv->wrfilled=%d", __FUNCTION__,priv->wrfilled);
474
475                 blksize = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
476
477                 if( (priv->wrsent>=priv->wrfilled) || (priv->wrsent>=blksize) ) {
478                         dbg("%s - buffer cleaned", __FUNCTION__);
479                         memset( priv->wrbuf, 0, sizeof(priv->wrbuf) );
480                         priv->wrfilled=0;
481                         priv->wrsent=0;
482                 }
483         }
484
485 exit:
486         spin_unlock(&priv->lock);
487         schedule_work(&port->work);
488 }
489
490 static int __init cyberjack_init (void)
491 {
492         int retval;
493         retval  = usb_serial_register(&cyberjack_device);
494         if (retval)
495                 goto failed_usb_serial_register;
496         retval = usb_register(&cyberjack_driver);
497         if (retval) 
498                 goto failed_usb_register;
499
500         info(DRIVER_VERSION " " DRIVER_AUTHOR);
501         info(DRIVER_DESC);
502
503         return 0;
504 failed_usb_register:
505         usb_serial_deregister(&cyberjack_device);
506 failed_usb_serial_register:
507         return retval;
508 }
509
510 static void __exit cyberjack_exit (void)
511 {
512         usb_deregister (&cyberjack_driver);
513         usb_serial_deregister (&cyberjack_device);
514 }
515
516 module_init(cyberjack_init);
517 module_exit(cyberjack_exit);
518
519 MODULE_AUTHOR( DRIVER_AUTHOR );
520 MODULE_DESCRIPTION( DRIVER_DESC );
521 MODULE_LICENSE("GPL");
522
523 MODULE_PARM(debug, "i");
524 MODULE_PARM_DESC(debug, "Debug enabled or not");
525