v2.4.9.9 -> v2.4.9.10
[opensuse:kernel.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/sched.h>
29 #include <linux/signal.h>
30 #include <linux/errno.h>
31 #include <linux/poll.h>
32 #include <linux/init.h>
33 #include <linux/slab.h>
34 #include <linux/fcntl.h>
35 #include <linux/tty.h>
36 #include <linux/tty_driver.h>
37 #include <linux/tty_flip.h>
38 #include <linux/module.h>
39 #include <linux/spinlock.h>
40 #include <linux/usb.h>
41
42 #ifdef CONFIG_USB_SERIAL_DEBUG
43         static int debug = 1;
44 #else
45         static int debug;
46 #endif
47
48 #include "usb-serial.h"
49
50 /*
51  * Version Information
52  */
53 #define DRIVER_VERSION "v1.0"
54 #define DRIVER_AUTHOR "Matthias Bruestle"
55 #define DRIVER_DESC "REINER SCT cyberJack pinpad/e-com USB Chipcard Reader Driver"
56
57
58 #define CYBERJACK_VENDOR_ID     0x0C4B
59 #define CYBERJACK_PRODUCT_ID    0x0100
60
61 /* Function prototypes */
62 static int cyberjack_startup (struct usb_serial *serial);
63 static void cyberjack_shutdown (struct usb_serial *serial);
64 static int  cyberjack_open (struct usb_serial_port *port, struct file *filp);
65 static void cyberjack_close (struct usb_serial_port *port, struct file *filp);
66 static int cyberjack_write (struct usb_serial_port *port, int from_user,
67         const unsigned char *buf, int count);
68 static void cyberjack_read_int_callback( struct urb *urb );
69 static void cyberjack_read_bulk_callback (struct urb *urb);
70 static void cyberjack_write_bulk_callback (struct urb *urb);
71
72 static __devinitdata 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 struct usb_serial_device_type cyberjack_device = {
80         name:                   "Reiner SCT Cyberjack USB card reader",
81         id_table:               id_table,
82         needs_interrupt_in:     MUST_HAVE,
83         needs_bulk_in:          MUST_HAVE,
84         needs_bulk_out:         MUST_HAVE,
85         num_interrupt_in:       1,
86         num_bulk_in:            1,
87         num_bulk_out:           1,
88         num_ports:              1,
89         startup:                cyberjack_startup,
90         shutdown:               cyberjack_shutdown,
91         open:                   cyberjack_open,
92         close:                  cyberjack_close,
93         write:                  cyberjack_write,
94         read_int_callback:      cyberjack_read_int_callback,
95         read_bulk_callback:     cyberjack_read_bulk_callback,
96         write_bulk_callback:    cyberjack_write_bulk_callback,
97 };
98
99 struct cyberjack_private {
100         short   rdtodo;         /* Bytes still to read */
101         unsigned char   wrbuf[5*64];    /* Buffer for collecting data to write */
102         short   wrfilled;       /* Overall data size we already got */
103         short   wrsent;         /* Data akready sent */
104 };
105
106 /* do some startup allocations not currently performed by usb_serial_probe() */
107 static int cyberjack_startup (struct usb_serial *serial)
108 {
109         struct cyberjack_private *priv;
110
111         dbg (__FUNCTION__);
112
113         /* allocate the private data structure */
114         serial->port->private = kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL);
115         if (!serial->port->private)
116                 return (-1); /* error */
117
118         /* set initial values */
119         priv = (struct cyberjack_private *)serial->port->private;
120         priv->rdtodo = 0;
121         priv->wrfilled = 0;
122         priv->wrsent = 0;
123
124         init_waitqueue_head(&serial->port->write_wait);
125
126         return( 0 );
127 }
128
129 static void cyberjack_shutdown (struct usb_serial *serial)
130 {
131         int i;
132         
133         dbg (__FUNCTION__);
134
135         /* stop reads and writes on all ports */
136         for (i=0; i < serial->num_ports; ++i) {
137                 while (serial->port[i].open_count > 0) {
138                         cyberjack_close (&serial->port[i], NULL);
139                 }
140                 /* My special items, the standard routines free my urbs */
141                 if (serial->port[i].private)
142                         kfree(serial->port[i].private);
143         }
144 }
145         
146 static int  cyberjack_open (struct usb_serial_port *port, struct file *filp)
147 {
148         struct cyberjack_private *priv;
149         int result = 0;
150
151         if (port_paranoia_check (port, __FUNCTION__))
152                 return -ENODEV;
153
154         MOD_INC_USE_COUNT;
155
156         dbg(__FUNCTION__ " - port %d", port->number);
157
158         down (&port->sem);
159
160         ++port->open_count;
161
162         if (!port->active) {
163                 port->active = 1;
164                 /* force low_latency on so that our tty_push actually forces
165                  * the data through, otherwise it is scheduled, and with high
166                  * data rates (like with OHCI) data can get lost.
167                  */
168                 port->tty->low_latency = 1;
169
170                 priv = (struct cyberjack_private *)port->private;
171                 priv->rdtodo = 0;
172                 priv->wrfilled = 0;
173                 priv->wrsent = 0;
174
175                 /* shutdown any bulk reads that might be going on */
176                 usb_unlink_urb (port->write_urb);
177                 usb_unlink_urb (port->read_urb);
178                 usb_unlink_urb (port->interrupt_in_urb);
179
180                 port->interrupt_in_urb->dev = port->serial->dev;
181                 result = usb_submit_urb(port->interrupt_in_urb);
182                 if (result)
183                         err(" usb_submit_urb(read int) failed");
184                 dbg(__FUNCTION__ " - usb_submit_urb(int urb)");
185         }
186
187         up (&port->sem);
188
189         return result;
190 }
191
192 static void cyberjack_close (struct usb_serial_port *port, struct file *filp)
193 {
194         dbg(__FUNCTION__ " - port %d", port->number);
195
196         down (&port->sem);
197
198         --port->open_count;
199
200         if (port->open_count <= 0) {
201                 /* shutdown any bulk reads that might be going on */
202                 usb_unlink_urb (port->write_urb);
203                 usb_unlink_urb (port->read_urb);
204                 usb_unlink_urb (port->interrupt_in_urb);
205
206                 port->active = 0;
207                 port->open_count = 0;
208         }
209
210         up (&port->sem);
211         MOD_DEC_USE_COUNT;
212 }
213
214 static int cyberjack_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
215 {
216         struct usb_serial *serial = port->serial;
217         struct cyberjack_private *priv = (struct cyberjack_private *)port->private;
218         int result;
219         int wrexpected;
220
221         dbg(__FUNCTION__ " - port %d", port->number);
222         dbg(__FUNCTION__ " - from_user %d", from_user);
223
224         if (count == 0) {
225                 dbg(__FUNCTION__ " - write request of 0 bytes");
226                 return (0);
227         }
228
229         if (port->write_urb->status == -EINPROGRESS) {
230                 dbg (__FUNCTION__ " - already writing");
231                 return (0);
232         }
233
234         down (&port->sem);
235
236         if( (count+priv->wrfilled)>sizeof(priv->wrbuf) ) {
237                 /* To much data  for buffer. Reset buffer. */
238                 priv->wrfilled=0;
239                 return (0);
240         }
241
242         /* Copy data */
243         if (from_user) {
244                 if (copy_from_user(priv->wrbuf+priv->wrfilled, buf, count))
245                         return -EFAULT;
246         } else {
247                 memcpy (priv->wrbuf+priv->wrfilled, buf, count);
248         }  
249         usb_serial_debug_data (__FILE__, __FUNCTION__, count,
250                 priv->wrbuf+priv->wrfilled);
251         priv->wrfilled += count;
252
253         if( priv->wrfilled >= 3 ) {
254                 wrexpected = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
255                 dbg(__FUNCTION__ " - expected data: %d", wrexpected);
256         } else {
257                 wrexpected = sizeof(priv->wrbuf);
258         }
259
260         if( priv->wrfilled >= wrexpected ) {
261                 /* We have enough data to begin transmission */
262                 int length;
263
264                 dbg(__FUNCTION__ " - transmitting data (frame 1)");
265                 length = (wrexpected > port->bulk_out_size) ? port->bulk_out_size : wrexpected;
266
267                 memcpy (port->write_urb->transfer_buffer, priv->wrbuf, length );
268                 priv->wrsent=length;
269
270                 /* set up our urb */
271                 FILL_BULK_URB(port->write_urb, serial->dev, 
272                               usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
273                               port->write_urb->transfer_buffer, length,
274                               ((serial->type->write_bulk_callback) ? 
275                                serial->type->write_bulk_callback : 
276                                cyberjack_write_bulk_callback), 
277                               port);
278
279                 /* send the data out the bulk port */
280                 result = usb_submit_urb(port->write_urb);
281                 if (result) {
282                         err(__FUNCTION__ " - failed submitting write urb, error %d", result);
283                         /* Throw away data. No better idea what to do with it. */
284                         priv->wrfilled=0;
285                         priv->wrsent=0;
286                         up (&port->sem);
287                         return 0;
288                 }
289
290                 dbg(__FUNCTION__ " - priv->wrsent=%d",priv->wrsent);
291                 dbg(__FUNCTION__ " - priv->wrfilled=%d",priv->wrfilled);
292
293                 if( priv->wrsent>=priv->wrfilled ) {
294                         dbg(__FUNCTION__ " - buffer cleaned");
295                         memset( priv->wrbuf, 0, sizeof(priv->wrbuf) );
296                         priv->wrfilled=0;
297                         priv->wrsent=0;
298                 }
299         }
300
301         up (&port->sem);
302         return (count);
303
304
305 static void cyberjack_read_int_callback( struct urb *urb )
306 {
307         struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
308         struct cyberjack_private *priv = (struct cyberjack_private *)port->private;
309         struct usb_serial *serial;
310         unsigned char *data = urb->transfer_buffer;
311
312         dbg(__FUNCTION__ " - port %d", port->number);
313
314         /* the urb might have been killed. */
315         if (urb->status)
316                 return;
317
318         if (port_paranoia_check (port, "cyberjack_read_interrupt")) return;
319
320         serial = port->serial;
321         if (serial_paranoia_check (serial, "cyberjack_read_interrupt")) return;
322
323         usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
324
325         /* React only to interrupts signaling a bulk_in transfer */
326         if( (urb->actual_length==4) && (data[0]==0x01) ) {
327                 short old_rdtodo = priv->rdtodo;
328                 int result;
329
330                 /* This is a announcement of comming bulk_ins. */
331                 unsigned short size = ((unsigned short)data[3]<<8)+data[2]+3;
332
333                 if( (size>259) || (size==0) ) {
334                         dbg( "Bad announced bulk_in data length: %d", size );
335                         /* Dunno what is most reliable to do here. */
336                         /* return; */
337                 }
338
339                 if( (old_rdtodo+size)<(old_rdtodo) ) {
340                         dbg( "To many bulk_in urbs to do." );
341                         return;
342                 }
343
344                 /* "+=" is probably more fault tollerant than "=" */
345                 priv->rdtodo += size;
346
347                 dbg(__FUNCTION__ " - rdtodo: %d", priv->rdtodo);
348
349                 if( !old_rdtodo ) {
350                         port->read_urb->dev = port->serial->dev;
351                         result = usb_submit_urb(port->read_urb);
352                         if( result )
353                                 err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
354                         dbg(__FUNCTION__ " - usb_submit_urb(read urb)");
355                 }
356         }
357 }
358
359 static void cyberjack_read_bulk_callback (struct urb *urb)
360 {
361         struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
362         struct cyberjack_private *priv = (struct cyberjack_private *)port->private;
363         struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
364         struct tty_struct *tty;
365         unsigned char *data = urb->transfer_buffer;
366         int i;
367         int result;
368
369         dbg(__FUNCTION__ " - port %d", port->number);
370         
371         if (!serial) {
372                 dbg(__FUNCTION__ " - bad serial pointer, exiting");
373                 return;
374         }
375
376         if (urb->status) {
377                 usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, urb->transfer_buffer);
378                 dbg(__FUNCTION__ " - nonzero read bulk status received: %d", urb->status);
379                 return;
380         }
381
382         usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
383
384         tty = port->tty;
385         if (urb->actual_length) {
386                 for (i = 0; i < urb->actual_length ; ++i) {
387                         /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
388                         if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
389                                 tty_flip_buffer_push(tty);
390                         }
391                         /* this doesn't actually push the data through unless tty->low_latency is set */
392                         tty_insert_flip_char(tty, data[i], 0);
393                 }
394                 tty_flip_buffer_push(tty);
395         }
396
397         /* Reduce urbs to do by one. */
398         priv->rdtodo-=urb->actual_length;
399         /* Just to be sure */
400         if( priv->rdtodo<0 ) priv->rdtodo=0;
401
402         dbg(__FUNCTION__ " - rdtodo: %d", priv->rdtodo);
403
404         /* Continue to read if we have still urbs to do. */
405         if( priv->rdtodo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/ ) {
406                 port->read_urb->dev = port->serial->dev;
407                 result = usb_submit_urb(port->read_urb);
408                 if (result)
409                         err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
410                 dbg(__FUNCTION__ " - usb_submit_urb(read urb)");
411         }
412 }
413
414 static void cyberjack_write_bulk_callback (struct urb *urb)
415 {
416         struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
417         struct cyberjack_private *priv = (struct cyberjack_private *)port->private;
418         struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
419
420         dbg(__FUNCTION__ " - port %d", port->number);
421         
422         if (!serial) {
423                 dbg(__FUNCTION__ " - bad serial pointer, exiting");
424                 return;
425         }
426
427         if (urb->status) {
428                 dbg(__FUNCTION__ " - nonzero write bulk status received: %d", urb->status);
429                 return;
430         }
431
432         /* only do something if we have more data to send */
433         if( priv->wrfilled ) {
434                 int length, blksize, result;
435
436                 if (port->write_urb->status == -EINPROGRESS) {
437                         dbg (__FUNCTION__ " - already writing");
438                         return;
439                 }
440
441                 down (&port->sem);
442
443                 dbg(__FUNCTION__ " - transmitting data (frame n)");
444
445                 length = ((priv->wrfilled - priv->wrsent) > port->bulk_out_size) ?
446                         port->bulk_out_size : (priv->wrfilled - priv->wrsent);
447
448                 memcpy (port->write_urb->transfer_buffer, priv->wrbuf + priv->wrsent,
449                         length );
450                 priv->wrsent+=length;
451
452                 /* set up our urb */
453                 FILL_BULK_URB(port->write_urb, serial->dev, 
454                               usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
455                               port->write_urb->transfer_buffer, length,
456                               ((serial->type->write_bulk_callback) ? 
457                                serial->type->write_bulk_callback : 
458                                cyberjack_write_bulk_callback), 
459                               port);
460
461                 /* send the data out the bulk port */
462                 result = usb_submit_urb(port->write_urb);
463                 if (result) {
464                         err(__FUNCTION__ " - failed submitting write urb, error %d", result);
465                         /* Throw away data. No better idea what to do with it. */
466                         priv->wrfilled=0;
467                         priv->wrsent=0;
468                         up (&port->sem);
469                         queue_task(&port->tqueue, &tq_immediate);
470                         mark_bh(IMMEDIATE_BH);
471                         return;
472                 }
473
474                 dbg(__FUNCTION__ " - priv->wrsent=%d",priv->wrsent);
475                 dbg(__FUNCTION__ " - priv->wrfilled=%d",priv->wrfilled);
476
477                 blksize = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
478
479                 if( (priv->wrsent>=priv->wrfilled) || (priv->wrsent>=blksize) ) {
480                         dbg(__FUNCTION__ " - buffer cleaned");
481                         memset( priv->wrbuf, 0, sizeof(priv->wrbuf) );
482                         priv->wrfilled=0;
483                         priv->wrsent=0;
484                 }
485
486                 up (&port->sem);
487                 queue_task(&port->tqueue, &tq_immediate);
488                 mark_bh(IMMEDIATE_BH);
489                 return;
490         }
491
492         queue_task(&port->tqueue, &tq_immediate);
493         mark_bh(IMMEDIATE_BH);
494         
495         return;
496 }
497
498 static int __init cyberjack_init (void)
499 {
500         usb_serial_register (&cyberjack_device);
501
502         info(DRIVER_VERSION " " DRIVER_AUTHOR);
503         info(DRIVER_DESC);
504
505         return 0;
506 }
507
508 static void __exit cyberjack_exit (void)
509 {
510         usb_serial_deregister (&cyberjack_device);
511 }
512
513 module_init(cyberjack_init);
514 module_exit(cyberjack_exit);
515
516 MODULE_AUTHOR( DRIVER_AUTHOR );
517 MODULE_DESCRIPTION( DRIVER_DESC );
518 MODULE_LICENSE("GPL");
519
520 MODULE_PARM(debug, "i");
521 MODULE_PARM_DESC(debug, "Debug enabled or not");
522