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