xref: /linux/drivers/usb/serial/cyberjack.c (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *  REINER SCT cyberJack pinpad/e-com USB Chipcard Reader Driver
4  *
5  *  Copyright (C) 2001  REINER SCT
6  *  Author: Matthias Bruestle
7  *
8  *  Contact: support@reiner-sct.com (see MAINTAINERS)
9  *
10  *  This program is largely derived from work by the linux-usb group
11  *  and associated source files.  Please see the usb/serial files for
12  *  individual credits and copyrights.
13  *
14  *  Thanks to Greg Kroah-Hartman (greg@kroah.com) for his help and
15  *  patience.
16  *
17  *  In case of problems, please write to the contact e-mail address
18  *  mentioned above.
19  *
20  *  Please note that later models of the cyberjack reader family are
21  *  supported by a libusb-based userspace device driver.
22  *
23  *  Homepage: http://www.reiner-sct.de/support/treiber_cyberjack.php#linux
24  */
25 
26 
27 #include <linux/kernel.h>
28 #include <linux/errno.h>
29 #include <linux/slab.h>
30 #include <linux/tty.h>
31 #include <linux/tty_driver.h>
32 #include <linux/tty_flip.h>
33 #include <linux/module.h>
34 #include <linux/spinlock.h>
35 #include <linux/uaccess.h>
36 #include <linux/usb.h>
37 #include <linux/usb/serial.h>
38 
39 #define CYBERJACK_LOCAL_BUF_SIZE 32
40 
41 #define DRIVER_AUTHOR "Matthias Bruestle"
42 #define DRIVER_DESC "REINER SCT cyberJack pinpad/e-com USB Chipcard Reader Driver"
43 
44 
45 #define CYBERJACK_VENDOR_ID	0x0C4B
46 #define CYBERJACK_PRODUCT_ID	0x0100
47 
48 /* Function prototypes */
49 static int cyberjack_port_probe(struct usb_serial_port *port);
50 static void cyberjack_port_remove(struct usb_serial_port *port);
51 static int  cyberjack_open(struct tty_struct *tty,
52 	struct usb_serial_port *port);
53 static void cyberjack_close(struct usb_serial_port *port);
54 static int cyberjack_write(struct tty_struct *tty,
55 	struct usb_serial_port *port, const unsigned char *buf, int count);
56 static unsigned int cyberjack_write_room(struct tty_struct *tty);
57 static void cyberjack_read_int_callback(struct urb *urb);
58 static void cyberjack_read_bulk_callback(struct urb *urb);
59 static void cyberjack_write_bulk_callback(struct urb *urb);
60 
61 static const struct usb_device_id id_table[] = {
62 	{ USB_DEVICE(CYBERJACK_VENDOR_ID, CYBERJACK_PRODUCT_ID) },
63 	{ }			/* Terminating entry */
64 };
65 
66 MODULE_DEVICE_TABLE(usb, id_table);
67 
68 static struct usb_serial_driver cyberjack_device = {
69 	.driver = {
70 		.name =		"cyberjack",
71 	},
72 	.description =		"Reiner SCT Cyberjack USB card reader",
73 	.id_table =		id_table,
74 	.num_ports =		1,
75 	.num_bulk_out =		1,
76 	.port_probe =		cyberjack_port_probe,
77 	.port_remove =		cyberjack_port_remove,
78 	.open =			cyberjack_open,
79 	.close =		cyberjack_close,
80 	.write =		cyberjack_write,
81 	.write_room =		cyberjack_write_room,
82 	.read_int_callback =	cyberjack_read_int_callback,
83 	.read_bulk_callback =	cyberjack_read_bulk_callback,
84 	.write_bulk_callback =	cyberjack_write_bulk_callback,
85 };
86 
87 static struct usb_serial_driver * const serial_drivers[] = {
88 	&cyberjack_device, NULL
89 };
90 
91 struct cyberjack_private {
92 	spinlock_t	lock;		/* Lock for SMP */
93 	short		rdtodo;		/* Bytes still to read */
94 	unsigned char	wrbuf[5*64];	/* Buffer for collecting data to write */
95 	short		wrfilled;	/* Overall data size we already got */
96 	short		wrsent;		/* Data already sent */
97 };
98 
cyberjack_port_probe(struct usb_serial_port * port)99 static int cyberjack_port_probe(struct usb_serial_port *port)
100 {
101 	struct cyberjack_private *priv;
102 	int result;
103 
104 	priv = kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL);
105 	if (!priv)
106 		return -ENOMEM;
107 
108 	spin_lock_init(&priv->lock);
109 	priv->rdtodo = 0;
110 	priv->wrfilled = 0;
111 	priv->wrsent = 0;
112 
113 	usb_set_serial_port_data(port, priv);
114 
115 	result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
116 	if (result)
117 		dev_err(&port->dev, "usb_submit_urb(read int) failed\n");
118 
119 	return 0;
120 }
121 
cyberjack_port_remove(struct usb_serial_port * port)122 static void cyberjack_port_remove(struct usb_serial_port *port)
123 {
124 	struct cyberjack_private *priv;
125 
126 	usb_kill_urb(port->interrupt_in_urb);
127 
128 	priv = usb_get_serial_port_data(port);
129 	kfree(priv);
130 }
131 
cyberjack_open(struct tty_struct * tty,struct usb_serial_port * port)132 static int  cyberjack_open(struct tty_struct *tty,
133 					struct usb_serial_port *port)
134 {
135 	struct cyberjack_private *priv;
136 	unsigned long flags;
137 
138 	dev_dbg(&port->dev, "%s - usb_clear_halt\n", __func__);
139 	usb_clear_halt(port->serial->dev, port->write_urb->pipe);
140 
141 	priv = usb_get_serial_port_data(port);
142 	spin_lock_irqsave(&priv->lock, flags);
143 	priv->rdtodo = 0;
144 	priv->wrfilled = 0;
145 	priv->wrsent = 0;
146 	spin_unlock_irqrestore(&priv->lock, flags);
147 
148 	return 0;
149 }
150 
cyberjack_close(struct usb_serial_port * port)151 static void cyberjack_close(struct usb_serial_port *port)
152 {
153 	usb_kill_urb(port->write_urb);
154 	usb_kill_urb(port->read_urb);
155 }
156 
cyberjack_write(struct tty_struct * tty,struct usb_serial_port * port,const unsigned char * buf,int count)157 static int cyberjack_write(struct tty_struct *tty,
158 	struct usb_serial_port *port, const unsigned char *buf, int count)
159 {
160 	struct device *dev = &port->dev;
161 	struct cyberjack_private *priv = usb_get_serial_port_data(port);
162 	unsigned long flags;
163 	int result;
164 	int wrexpected;
165 
166 	if (count == 0) {
167 		dev_dbg(dev, "%s - write request of 0 bytes\n", __func__);
168 		return 0;
169 	}
170 
171 	if (!test_and_clear_bit(0, &port->write_urbs_free)) {
172 		dev_dbg(dev, "%s - already writing\n", __func__);
173 		return 0;
174 	}
175 
176 	spin_lock_irqsave(&priv->lock, flags);
177 
178 	if (count+priv->wrfilled > sizeof(priv->wrbuf)) {
179 		/* To much data for buffer. Reset buffer. */
180 		priv->wrfilled = 0;
181 		spin_unlock_irqrestore(&priv->lock, flags);
182 		set_bit(0, &port->write_urbs_free);
183 		return 0;
184 	}
185 
186 	/* Copy data */
187 	memcpy(priv->wrbuf + priv->wrfilled, buf, count);
188 
189 	usb_serial_debug_data(dev, __func__, count, priv->wrbuf + priv->wrfilled);
190 	priv->wrfilled += count;
191 
192 	if (priv->wrfilled >= 3) {
193 		wrexpected = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
194 		dev_dbg(dev, "%s - expected data: %d\n", __func__, wrexpected);
195 	} else
196 		wrexpected = sizeof(priv->wrbuf);
197 
198 	if (priv->wrfilled >= wrexpected) {
199 		/* We have enough data to begin transmission */
200 		int length;
201 
202 		dev_dbg(dev, "%s - transmitting data (frame 1)\n", __func__);
203 		length = (wrexpected > port->bulk_out_size) ?
204 					port->bulk_out_size : wrexpected;
205 
206 		memcpy(port->write_urb->transfer_buffer, priv->wrbuf, length);
207 		priv->wrsent = length;
208 
209 		/* set up our urb */
210 		port->write_urb->transfer_buffer_length = length;
211 
212 		/* send the data out the bulk port */
213 		result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
214 		if (result) {
215 			dev_err(&port->dev,
216 				"%s - failed submitting write urb, error %d\n",
217 				__func__, result);
218 			/* Throw away data. No better idea what to do with it. */
219 			priv->wrfilled = 0;
220 			priv->wrsent = 0;
221 			spin_unlock_irqrestore(&priv->lock, flags);
222 			set_bit(0, &port->write_urbs_free);
223 			return 0;
224 		}
225 
226 		dev_dbg(dev, "%s - priv->wrsent=%d\n", __func__, priv->wrsent);
227 		dev_dbg(dev, "%s - priv->wrfilled=%d\n", __func__, priv->wrfilled);
228 
229 		if (priv->wrsent >= priv->wrfilled) {
230 			dev_dbg(dev, "%s - buffer cleaned\n", __func__);
231 			memset(priv->wrbuf, 0, sizeof(priv->wrbuf));
232 			priv->wrfilled = 0;
233 			priv->wrsent = 0;
234 		}
235 	}
236 
237 	spin_unlock_irqrestore(&priv->lock, flags);
238 
239 	return count;
240 }
241 
cyberjack_write_room(struct tty_struct * tty)242 static unsigned int cyberjack_write_room(struct tty_struct *tty)
243 {
244 	/* FIXME: .... */
245 	return CYBERJACK_LOCAL_BUF_SIZE;
246 }
247 
cyberjack_read_int_callback(struct urb * urb)248 static void cyberjack_read_int_callback(struct urb *urb)
249 {
250 	struct usb_serial_port *port = urb->context;
251 	struct cyberjack_private *priv = usb_get_serial_port_data(port);
252 	struct device *dev = &port->dev;
253 	unsigned char *data = urb->transfer_buffer;
254 	int status = urb->status;
255 	unsigned long flags;
256 	int result;
257 
258 	/* the urb might have been killed. */
259 	if (status)
260 		return;
261 
262 	usb_serial_debug_data(dev, __func__, urb->actual_length, data);
263 
264 	/* React only to interrupts signaling a bulk_in transfer */
265 	if (urb->actual_length == 4 && data[0] == 0x01) {
266 		short old_rdtodo;
267 
268 		/* This is a announcement of coming bulk_ins. */
269 		unsigned short size = ((unsigned short)data[3]<<8)+data[2]+3;
270 
271 		spin_lock_irqsave(&priv->lock, flags);
272 
273 		old_rdtodo = priv->rdtodo;
274 
275 		if (old_rdtodo > SHRT_MAX - size) {
276 			dev_dbg(dev, "Too many bulk_in urbs to do.\n");
277 			spin_unlock_irqrestore(&priv->lock, flags);
278 			goto resubmit;
279 		}
280 
281 		/* "+=" is probably more fault tolerant than "=" */
282 		priv->rdtodo += size;
283 
284 		dev_dbg(dev, "%s - rdtodo: %d\n", __func__, priv->rdtodo);
285 
286 		spin_unlock_irqrestore(&priv->lock, flags);
287 
288 		if (!old_rdtodo) {
289 			result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
290 			if (result)
291 				dev_err(dev, "%s - failed resubmitting read urb, error %d\n",
292 					__func__, result);
293 			dev_dbg(dev, "%s - usb_submit_urb(read urb)\n", __func__);
294 		}
295 	}
296 
297 resubmit:
298 	result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
299 	if (result)
300 		dev_err(&port->dev, "usb_submit_urb(read int) failed\n");
301 	dev_dbg(dev, "%s - usb_submit_urb(int urb)\n", __func__);
302 }
303 
cyberjack_read_bulk_callback(struct urb * urb)304 static void cyberjack_read_bulk_callback(struct urb *urb)
305 {
306 	struct usb_serial_port *port = urb->context;
307 	struct cyberjack_private *priv = usb_get_serial_port_data(port);
308 	struct device *dev = &port->dev;
309 	unsigned char *data = urb->transfer_buffer;
310 	unsigned long flags;
311 	short todo;
312 	int result;
313 	int status = urb->status;
314 
315 	usb_serial_debug_data(dev, __func__, urb->actual_length, data);
316 	if (status) {
317 		dev_dbg(dev, "%s - nonzero read bulk status received: %d\n",
318 			__func__, status);
319 		return;
320 	}
321 
322 	if (urb->actual_length) {
323 		tty_insert_flip_string(&port->port, data, urb->actual_length);
324 		tty_flip_buffer_push(&port->port);
325 	}
326 
327 	spin_lock_irqsave(&priv->lock, flags);
328 
329 	/* Reduce urbs to do by one. */
330 	priv->rdtodo -= urb->actual_length;
331 	/* Just to be sure */
332 	if (priv->rdtodo < 0)
333 		priv->rdtodo = 0;
334 	todo = priv->rdtodo;
335 
336 	spin_unlock_irqrestore(&priv->lock, flags);
337 
338 	dev_dbg(dev, "%s - rdtodo: %d\n", __func__, todo);
339 
340 	/* Continue to read if we have still urbs to do. */
341 	if (todo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/) {
342 		result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
343 		if (result)
344 			dev_err(dev, "%s - failed resubmitting read urb, error %d\n",
345 				__func__, result);
346 		dev_dbg(dev, "%s - usb_submit_urb(read urb)\n", __func__);
347 	}
348 }
349 
cyberjack_write_bulk_callback(struct urb * urb)350 static void cyberjack_write_bulk_callback(struct urb *urb)
351 {
352 	struct usb_serial_port *port = urb->context;
353 	struct cyberjack_private *priv = usb_get_serial_port_data(port);
354 	struct device *dev = &port->dev;
355 	int status = urb->status;
356 	unsigned long flags;
357 	bool resubmitted = false;
358 
359 	if (status) {
360 		dev_dbg(dev, "%s - nonzero write bulk status received: %d\n",
361 			__func__, status);
362 		set_bit(0, &port->write_urbs_free);
363 		return;
364 	}
365 
366 	spin_lock_irqsave(&priv->lock, flags);
367 
368 	/* only do something if we have more data to send */
369 	if (priv->wrfilled) {
370 		int length, blksize, result;
371 
372 		dev_dbg(dev, "%s - transmitting data (frame n)\n", __func__);
373 
374 		length = ((priv->wrfilled - priv->wrsent) > port->bulk_out_size) ?
375 			port->bulk_out_size : (priv->wrfilled - priv->wrsent);
376 
377 		memcpy(port->write_urb->transfer_buffer,
378 					priv->wrbuf + priv->wrsent, length);
379 		priv->wrsent += length;
380 
381 		/* set up our urb */
382 		port->write_urb->transfer_buffer_length = length;
383 
384 		/* send the data out the bulk port */
385 		result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
386 		if (result) {
387 			dev_err(dev, "%s - failed submitting write urb, error %d\n",
388 				__func__, result);
389 			/* Throw away data. No better idea what to do with it. */
390 			priv->wrfilled = 0;
391 			priv->wrsent = 0;
392 			goto exit;
393 		}
394 
395 		resubmitted = true;
396 
397 		dev_dbg(dev, "%s - priv->wrsent=%d\n", __func__, priv->wrsent);
398 		dev_dbg(dev, "%s - priv->wrfilled=%d\n", __func__, priv->wrfilled);
399 
400 		blksize = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
401 
402 		if (priv->wrsent >= priv->wrfilled ||
403 					priv->wrsent >= blksize) {
404 			dev_dbg(dev, "%s - buffer cleaned\n", __func__);
405 			memset(priv->wrbuf, 0, sizeof(priv->wrbuf));
406 			priv->wrfilled = 0;
407 			priv->wrsent = 0;
408 		}
409 	}
410 
411 exit:
412 	spin_unlock_irqrestore(&priv->lock, flags);
413 	if (!resubmitted)
414 		set_bit(0, &port->write_urbs_free);
415 	usb_serial_port_softint(port);
416 }
417 
418 module_usb_serial_driver(serial_drivers, id_table);
419 
420 MODULE_AUTHOR(DRIVER_AUTHOR);
421 MODULE_DESCRIPTION(DRIVER_DESC);
422 MODULE_LICENSE("GPL");
423