• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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: support@reiner-sct.com (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  *  Please note that later models of the cyberjack reader family are
25  *  supported by a libusb-based userspace device driver.
26  *
27  *  Homepage: http://www.reiner-sct.de/support/treiber_cyberjack.php#linux
28  */
29 
30 
31 #include <linux/kernel.h>
32 #include <linux/errno.h>
33 #include <linux/init.h>
34 #include <linux/slab.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/uaccess.h>
41 #include <linux/usb.h>
42 #include <linux/usb/serial.h>
43 
44 #define CYBERJACK_LOCAL_BUF_SIZE 32
45 
46 static bool debug;
47 
48 /*
49  * Version Information
50  */
51 #define DRIVER_VERSION "v1.01"
52 #define DRIVER_AUTHOR "Matthias Bruestle"
53 #define DRIVER_DESC "REINER SCT cyberJack pinpad/e-com USB Chipcard Reader Driver"
54 
55 
56 #define CYBERJACK_VENDOR_ID	0x0C4B
57 #define CYBERJACK_PRODUCT_ID	0x0100
58 
59 /* Function prototypes */
60 static int cyberjack_startup(struct usb_serial *serial);
61 static void cyberjack_disconnect(struct usb_serial *serial);
62 static void cyberjack_release(struct usb_serial *serial);
63 static int  cyberjack_open(struct tty_struct *tty,
64 	struct usb_serial_port *port);
65 static void cyberjack_close(struct usb_serial_port *port);
66 static int cyberjack_write(struct tty_struct *tty,
67 	struct usb_serial_port *port, const unsigned char *buf, int count);
68 static int cyberjack_write_room(struct tty_struct *tty);
69 static void cyberjack_read_int_callback(struct urb *urb);
70 static void cyberjack_read_bulk_callback(struct urb *urb);
71 static void cyberjack_write_bulk_callback(struct urb *urb);
72 
73 static const struct usb_device_id id_table[] = {
74 	{ USB_DEVICE(CYBERJACK_VENDOR_ID, CYBERJACK_PRODUCT_ID) },
75 	{ }			/* Terminating entry */
76 };
77 
78 MODULE_DEVICE_TABLE(usb, id_table);
79 
80 static struct usb_driver cyberjack_driver = {
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_driver cyberjack_device = {
88 	.driver = {
89 		.owner =	THIS_MODULE,
90 		.name =		"cyberjack",
91 	},
92 	.description =		"Reiner SCT Cyberjack USB card reader",
93 	.id_table =		id_table,
94 	.num_ports =		1,
95 	.attach =		cyberjack_startup,
96 	.disconnect =		cyberjack_disconnect,
97 	.release =		cyberjack_release,
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 static struct usb_serial_driver * const serial_drivers[] = {
108 	&cyberjack_device, NULL
109 };
110 
111 struct cyberjack_private {
112 	spinlock_t	lock;		/* Lock for SMP */
113 	short		rdtodo;		/* Bytes still to read */
114 	unsigned char	wrbuf[5*64];	/* Buffer for collecting data to write */
115 	short		wrfilled;	/* Overall data size we already got */
116 	short		wrsent;		/* Data already sent */
117 };
118 
119 /* do some startup allocations not currently performed by usb_serial_probe() */
cyberjack_startup(struct usb_serial * serial)120 static int cyberjack_startup(struct usb_serial *serial)
121 {
122 	struct cyberjack_private *priv;
123 	int i;
124 
125 	dbg("%s", __func__);
126 
127 	/* allocate the private data structure */
128 	priv = kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL);
129 	if (!priv)
130 		return -ENOMEM;
131 
132 	/* set initial values */
133 	spin_lock_init(&priv->lock);
134 	priv->rdtodo = 0;
135 	priv->wrfilled = 0;
136 	priv->wrsent = 0;
137 	usb_set_serial_port_data(serial->port[0], priv);
138 
139 	init_waitqueue_head(&serial->port[0]->write_wait);
140 
141 	for (i = 0; i < serial->num_ports; ++i) {
142 		int result;
143 		result = usb_submit_urb(serial->port[i]->interrupt_in_urb,
144 					GFP_KERNEL);
145 		if (result)
146 			dev_err(&serial->dev->dev,
147 				"usb_submit_urb(read int) failed\n");
148 		dbg("%s - usb_submit_urb(int urb)", __func__);
149 	}
150 
151 	return 0;
152 }
153 
cyberjack_disconnect(struct usb_serial * serial)154 static void cyberjack_disconnect(struct usb_serial *serial)
155 {
156 	int i;
157 
158 	dbg("%s", __func__);
159 
160 	for (i = 0; i < serial->num_ports; ++i)
161 		usb_kill_urb(serial->port[i]->interrupt_in_urb);
162 }
163 
cyberjack_release(struct usb_serial * serial)164 static void cyberjack_release(struct usb_serial *serial)
165 {
166 	int i;
167 
168 	dbg("%s", __func__);
169 
170 	for (i = 0; i < serial->num_ports; ++i) {
171 		/* My special items, the standard routines free my urbs */
172 		kfree(usb_get_serial_port_data(serial->port[i]));
173 	}
174 }
175 
cyberjack_open(struct tty_struct * tty,struct usb_serial_port * port)176 static int  cyberjack_open(struct tty_struct *tty,
177 					struct usb_serial_port *port)
178 {
179 	struct cyberjack_private *priv;
180 	unsigned long flags;
181 	int result = 0;
182 
183 	dbg("%s - port %d", __func__, port->number);
184 
185 	dbg("%s - usb_clear_halt", __func__);
186 	usb_clear_halt(port->serial->dev, port->write_urb->pipe);
187 
188 	priv = usb_get_serial_port_data(port);
189 	spin_lock_irqsave(&priv->lock, flags);
190 	priv->rdtodo = 0;
191 	priv->wrfilled = 0;
192 	priv->wrsent = 0;
193 	spin_unlock_irqrestore(&priv->lock, flags);
194 
195 	return result;
196 }
197 
cyberjack_close(struct usb_serial_port * port)198 static void cyberjack_close(struct usb_serial_port *port)
199 {
200 	dbg("%s - port %d", __func__, port->number);
201 
202 	if (port->serial->dev) {
203 		/* shutdown any bulk reads that might be going on */
204 		usb_kill_urb(port->write_urb);
205 		usb_kill_urb(port->read_urb);
206 	}
207 }
208 
cyberjack_write(struct tty_struct * tty,struct usb_serial_port * port,const unsigned char * buf,int count)209 static int cyberjack_write(struct tty_struct *tty,
210 	struct usb_serial_port *port, const unsigned char *buf, int count)
211 {
212 	struct cyberjack_private *priv = usb_get_serial_port_data(port);
213 	unsigned long flags;
214 	int result;
215 	int wrexpected;
216 
217 	dbg("%s - port %d", __func__, port->number);
218 
219 	if (count == 0) {
220 		dbg("%s - write request of 0 bytes", __func__);
221 		return 0;
222 	}
223 
224 	if (!test_and_clear_bit(0, &port->write_urbs_free)) {
225 		dbg("%s - already writing", __func__);
226 		return 0;
227 	}
228 
229 	spin_lock_irqsave(&priv->lock, flags);
230 
231 	if (count+priv->wrfilled > sizeof(priv->wrbuf)) {
232 		/* To much data for buffer. Reset buffer. */
233 		priv->wrfilled = 0;
234 		spin_unlock_irqrestore(&priv->lock, flags);
235 		set_bit(0, &port->write_urbs_free);
236 		return 0;
237 	}
238 
239 	/* Copy data */
240 	memcpy(priv->wrbuf + priv->wrfilled, buf, count);
241 
242 	usb_serial_debug_data(debug, &port->dev, __func__, count,
243 		priv->wrbuf + priv->wrfilled);
244 	priv->wrfilled += count;
245 
246 	if (priv->wrfilled >= 3) {
247 		wrexpected = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
248 		dbg("%s - expected data: %d", __func__, wrexpected);
249 	} else
250 		wrexpected = sizeof(priv->wrbuf);
251 
252 	if (priv->wrfilled >= wrexpected) {
253 		/* We have enough data to begin transmission */
254 		int length;
255 
256 		dbg("%s - transmitting data (frame 1)", __func__);
257 		length = (wrexpected > port->bulk_out_size) ?
258 					port->bulk_out_size : wrexpected;
259 
260 		memcpy(port->write_urb->transfer_buffer, priv->wrbuf, length);
261 		priv->wrsent = length;
262 
263 		/* set up our urb */
264 		port->write_urb->transfer_buffer_length = length;
265 
266 		/* send the data out the bulk port */
267 		result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
268 		if (result) {
269 			dev_err(&port->dev,
270 				"%s - failed submitting write urb, error %d",
271 				__func__, result);
272 			/* Throw away data. No better idea what to do with it. */
273 			priv->wrfilled = 0;
274 			priv->wrsent = 0;
275 			spin_unlock_irqrestore(&priv->lock, flags);
276 			set_bit(0, &port->write_urbs_free);
277 			return 0;
278 		}
279 
280 		dbg("%s - priv->wrsent=%d", __func__, priv->wrsent);
281 		dbg("%s - priv->wrfilled=%d", __func__, priv->wrfilled);
282 
283 		if (priv->wrsent >= priv->wrfilled) {
284 			dbg("%s - buffer cleaned", __func__);
285 			memset(priv->wrbuf, 0, sizeof(priv->wrbuf));
286 			priv->wrfilled = 0;
287 			priv->wrsent = 0;
288 		}
289 	}
290 
291 	spin_unlock_irqrestore(&priv->lock, flags);
292 
293 	return count;
294 }
295 
cyberjack_write_room(struct tty_struct * tty)296 static int cyberjack_write_room(struct tty_struct *tty)
297 {
298 	/* FIXME: .... */
299 	return CYBERJACK_LOCAL_BUF_SIZE;
300 }
301 
cyberjack_read_int_callback(struct urb * urb)302 static void cyberjack_read_int_callback(struct urb *urb)
303 {
304 	struct usb_serial_port *port = urb->context;
305 	struct cyberjack_private *priv = usb_get_serial_port_data(port);
306 	unsigned char *data = urb->transfer_buffer;
307 	int status = urb->status;
308 	int result;
309 
310 	dbg("%s - port %d", __func__, port->number);
311 
312 	/* the urb might have been killed. */
313 	if (status)
314 		return;
315 
316 	usb_serial_debug_data(debug, &port->dev, __func__,
317 						urb->actual_length, data);
318 
319 	/* React only to interrupts signaling a bulk_in transfer */
320 	if (urb->actual_length == 4 && data[0] == 0x01) {
321 		short old_rdtodo;
322 
323 		/* This is a announcement of coming bulk_ins. */
324 		unsigned short size = ((unsigned short)data[3]<<8)+data[2]+3;
325 
326 		spin_lock(&priv->lock);
327 
328 		old_rdtodo = priv->rdtodo;
329 
330 		if (old_rdtodo + size < old_rdtodo) {
331 			dbg("To many bulk_in urbs to do.");
332 			spin_unlock(&priv->lock);
333 			goto resubmit;
334 		}
335 
336 		/* "+=" is probably more fault tollerant than "=" */
337 		priv->rdtodo += size;
338 
339 		dbg("%s - rdtodo: %d", __func__, priv->rdtodo);
340 
341 		spin_unlock(&priv->lock);
342 
343 		if (!old_rdtodo) {
344 			result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
345 			if (result)
346 				dev_err(&port->dev, "%s - failed resubmitting "
347 					"read urb, error %d\n",
348 					__func__, result);
349 			dbg("%s - usb_submit_urb(read urb)", __func__);
350 		}
351 	}
352 
353 resubmit:
354 	result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
355 	if (result)
356 		dev_err(&port->dev, "usb_submit_urb(read int) failed\n");
357 	dbg("%s - usb_submit_urb(int urb)", __func__);
358 }
359 
cyberjack_read_bulk_callback(struct urb * urb)360 static void cyberjack_read_bulk_callback(struct urb *urb)
361 {
362 	struct usb_serial_port *port = urb->context;
363 	struct cyberjack_private *priv = usb_get_serial_port_data(port);
364 	struct tty_struct *tty;
365 	unsigned char *data = urb->transfer_buffer;
366 	short todo;
367 	int result;
368 	int status = urb->status;
369 
370 	dbg("%s - port %d", __func__, port->number);
371 
372 	usb_serial_debug_data(debug, &port->dev, __func__,
373 						urb->actual_length, data);
374 	if (status) {
375 		dbg("%s - nonzero read bulk status received: %d",
376 		    __func__, status);
377 		return;
378 	}
379 
380 	tty = tty_port_tty_get(&port->port);
381 	if (!tty) {
382 		dbg("%s - ignoring since device not open", __func__);
383 		return;
384 	}
385 	if (urb->actual_length) {
386 		tty_insert_flip_string(tty, data, urb->actual_length);
387 		tty_flip_buffer_push(tty);
388 	}
389 	tty_kref_put(tty);
390 
391 	spin_lock(&priv->lock);
392 
393 	/* Reduce urbs to do by one. */
394 	priv->rdtodo -= urb->actual_length;
395 	/* Just to be sure */
396 	if (priv->rdtodo < 0)
397 		priv->rdtodo = 0;
398 	todo = priv->rdtodo;
399 
400 	spin_unlock(&priv->lock);
401 
402 	dbg("%s - rdtodo: %d", __func__, todo);
403 
404 	/* Continue to read if we have still urbs to do. */
405 	if (todo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/) {
406 		result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
407 		if (result)
408 			dev_err(&port->dev, "%s - failed resubmitting read "
409 				"urb, error %d\n", __func__, result);
410 		dbg("%s - usb_submit_urb(read urb)", __func__);
411 	}
412 }
413 
cyberjack_write_bulk_callback(struct urb * urb)414 static void cyberjack_write_bulk_callback(struct urb *urb)
415 {
416 	struct usb_serial_port *port = urb->context;
417 	struct cyberjack_private *priv = usb_get_serial_port_data(port);
418 	int status = urb->status;
419 
420 	dbg("%s - port %d", __func__, port->number);
421 
422 	set_bit(0, &port->write_urbs_free);
423 	if (status) {
424 		dbg("%s - nonzero write bulk status received: %d",
425 		    __func__, status);
426 		return;
427 	}
428 
429 	spin_lock(&priv->lock);
430 
431 	/* only do something if we have more data to send */
432 	if (priv->wrfilled) {
433 		int length, blksize, result;
434 
435 		dbg("%s - transmitting data (frame n)", __func__);
436 
437 		length = ((priv->wrfilled - priv->wrsent) > port->bulk_out_size) ?
438 			port->bulk_out_size : (priv->wrfilled - priv->wrsent);
439 
440 		memcpy(port->write_urb->transfer_buffer,
441 					priv->wrbuf + priv->wrsent, length);
442 		priv->wrsent += length;
443 
444 		/* set up our urb */
445 		port->write_urb->transfer_buffer_length = length;
446 
447 		/* send the data out the bulk port */
448 		result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
449 		if (result) {
450 			dev_err(&port->dev,
451 				"%s - failed submitting write urb, error %d\n",
452 				__func__, result);
453 			/* Throw away data. No better idea what to do with it. */
454 			priv->wrfilled = 0;
455 			priv->wrsent = 0;
456 			goto exit;
457 		}
458 
459 		dbg("%s - priv->wrsent=%d", __func__, priv->wrsent);
460 		dbg("%s - priv->wrfilled=%d", __func__, priv->wrfilled);
461 
462 		blksize = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
463 
464 		if (priv->wrsent >= priv->wrfilled ||
465 					priv->wrsent >= blksize) {
466 			dbg("%s - buffer cleaned", __func__);
467 			memset(priv->wrbuf, 0, sizeof(priv->wrbuf));
468 			priv->wrfilled = 0;
469 			priv->wrsent = 0;
470 		}
471 	}
472 
473 exit:
474 	spin_unlock(&priv->lock);
475 	usb_serial_port_softint(port);
476 }
477 
478 module_usb_serial_driver(cyberjack_driver, serial_drivers);
479 
480 MODULE_AUTHOR(DRIVER_AUTHOR);
481 MODULE_DESCRIPTION(DRIVER_DESC);
482 MODULE_VERSION(DRIVER_VERSION);
483 MODULE_LICENSE("GPL");
484 
485 module_param(debug, bool, S_IRUGO | S_IWUSR);
486 MODULE_PARM_DESC(debug, "Debug enabled or not");
487