root/drivers/usb/serial/cyberjack.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cyberjack_port_probe
  2. cyberjack_port_remove
  3. cyberjack_open
  4. cyberjack_close
  5. cyberjack_write
  6. cyberjack_write_room
  7. cyberjack_read_int_callback
  8. cyberjack_read_bulk_callback
  9. cyberjack_write_bulk_callback

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

/* [<][>][^][v][top][bottom][index][help] */