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