root/drivers/usb/serial/opticon.c

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

DEFINITIONS

This source file includes following definitions.
  1. opticon_process_data_packet
  2. opticon_process_status_packet
  3. opticon_process_read_urb
  4. send_control_msg
  5. opticon_open
  6. opticon_write_control_callback
  7. opticon_write
  8. opticon_write_room
  9. opticon_tiocmget
  10. opticon_tiocmset
  11. get_serial_info
  12. opticon_port_probe
  13. opticon_port_remove

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Opticon USB barcode to serial driver
   4  *
   5  * Copyright (C) 2011 - 2012 Johan Hovold <jhovold@gmail.com>
   6  * Copyright (C) 2011 Martin Jansen <martin.jansen@opticon.com>
   7  * Copyright (C) 2008 - 2009 Greg Kroah-Hartman <gregkh@suse.de>
   8  * Copyright (C) 2008 - 2009 Novell Inc.
   9  */
  10 
  11 #include <linux/kernel.h>
  12 #include <linux/tty.h>
  13 #include <linux/tty_driver.h>
  14 #include <linux/slab.h>
  15 #include <linux/tty_flip.h>
  16 #include <linux/serial.h>
  17 #include <linux/module.h>
  18 #include <linux/usb.h>
  19 #include <linux/usb/serial.h>
  20 #include <linux/uaccess.h>
  21 
  22 #define CONTROL_RTS                     0x02
  23 #define RESEND_CTS_STATE        0x03
  24 
  25 /* max number of write urbs in flight */
  26 #define URB_UPPER_LIMIT 8
  27 
  28 /* This driver works for the Opticon 1D barcode reader
  29  * an examples of 1D barcode types are EAN, UPC, Code39, IATA etc.. */
  30 #define DRIVER_DESC     "Opticon USB barcode to serial driver (1D)"
  31 
  32 static const struct usb_device_id id_table[] = {
  33         { USB_DEVICE(0x065a, 0x0009) },
  34         { },
  35 };
  36 MODULE_DEVICE_TABLE(usb, id_table);
  37 
  38 /* This structure holds all of the individual device information */
  39 struct opticon_private {
  40         spinlock_t lock;        /* protects the following flags */
  41         bool rts;
  42         bool cts;
  43         int outstanding_urbs;
  44 };
  45 
  46 
  47 static void opticon_process_data_packet(struct usb_serial_port *port,
  48                                         const unsigned char *buf, size_t len)
  49 {
  50         tty_insert_flip_string(&port->port, buf, len);
  51         tty_flip_buffer_push(&port->port);
  52 }
  53 
  54 static void opticon_process_status_packet(struct usb_serial_port *port,
  55                                         const unsigned char *buf, size_t len)
  56 {
  57         struct opticon_private *priv = usb_get_serial_port_data(port);
  58         unsigned long flags;
  59 
  60         spin_lock_irqsave(&priv->lock, flags);
  61         if (buf[0] == 0x00)
  62                 priv->cts = false;
  63         else
  64                 priv->cts = true;
  65         spin_unlock_irqrestore(&priv->lock, flags);
  66 }
  67 
  68 static void opticon_process_read_urb(struct urb *urb)
  69 {
  70         struct usb_serial_port *port = urb->context;
  71         const unsigned char *hdr = urb->transfer_buffer;
  72         const unsigned char *data = hdr + 2;
  73         size_t data_len = urb->actual_length - 2;
  74 
  75         if (urb->actual_length <= 2) {
  76                 dev_dbg(&port->dev, "malformed packet received: %d bytes\n",
  77                                                         urb->actual_length);
  78                 return;
  79         }
  80         /*
  81          * Data from the device comes with a 2 byte header:
  82          *
  83          * <0x00><0x00>data...
  84          *      This is real data to be sent to the tty layer
  85          * <0x00><0x01>level
  86          *      This is a CTS level change, the third byte is the CTS
  87          *      value (0 for low, 1 for high).
  88          */
  89         if ((hdr[0] == 0x00) && (hdr[1] == 0x00)) {
  90                 opticon_process_data_packet(port, data, data_len);
  91         } else if ((hdr[0] == 0x00) && (hdr[1] == 0x01)) {
  92                 opticon_process_status_packet(port, data, data_len);
  93         } else {
  94                 dev_dbg(&port->dev, "unknown packet received: %02x %02x\n",
  95                                                         hdr[0], hdr[1]);
  96         }
  97 }
  98 
  99 static int send_control_msg(struct usb_serial_port *port, u8 requesttype,
 100                                 u8 val)
 101 {
 102         struct usb_serial *serial = port->serial;
 103         int retval;
 104         u8 *buffer;
 105 
 106         buffer = kzalloc(1, GFP_KERNEL);
 107         if (!buffer)
 108                 return -ENOMEM;
 109 
 110         buffer[0] = val;
 111         /* Send the message to the vendor control endpoint
 112          * of the connected device */
 113         retval = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
 114                                 requesttype,
 115                                 USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
 116                                 0, 0, buffer, 1, USB_CTRL_SET_TIMEOUT);
 117         kfree(buffer);
 118 
 119         if (retval < 0)
 120                 return retval;
 121 
 122         return 0;
 123 }
 124 
 125 static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port)
 126 {
 127         struct opticon_private *priv = usb_get_serial_port_data(port);
 128         unsigned long flags;
 129         int res;
 130 
 131         spin_lock_irqsave(&priv->lock, flags);
 132         priv->rts = false;
 133         spin_unlock_irqrestore(&priv->lock, flags);
 134 
 135         /* Clear RTS line */
 136         send_control_msg(port, CONTROL_RTS, 0);
 137 
 138         /* clear the halt status of the endpoint */
 139         usb_clear_halt(port->serial->dev, port->read_urb->pipe);
 140 
 141         res = usb_serial_generic_open(tty, port);
 142         if (res)
 143                 return res;
 144 
 145         /* Request CTS line state, sometimes during opening the current
 146          * CTS state can be missed. */
 147         send_control_msg(port, RESEND_CTS_STATE, 1);
 148 
 149         return res;
 150 }
 151 
 152 static void opticon_write_control_callback(struct urb *urb)
 153 {
 154         struct usb_serial_port *port = urb->context;
 155         struct opticon_private *priv = usb_get_serial_port_data(port);
 156         int status = urb->status;
 157         unsigned long flags;
 158 
 159         /* free up the transfer buffer, as usb_free_urb() does not do this */
 160         kfree(urb->transfer_buffer);
 161 
 162         /* setup packet may be set if we're using it for writing */
 163         kfree(urb->setup_packet);
 164 
 165         if (status)
 166                 dev_dbg(&port->dev,
 167                         "%s - non-zero urb status received: %d\n",
 168                         __func__, status);
 169 
 170         spin_lock_irqsave(&priv->lock, flags);
 171         --priv->outstanding_urbs;
 172         spin_unlock_irqrestore(&priv->lock, flags);
 173 
 174         usb_serial_port_softint(port);
 175 }
 176 
 177 static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port,
 178                          const unsigned char *buf, int count)
 179 {
 180         struct opticon_private *priv = usb_get_serial_port_data(port);
 181         struct usb_serial *serial = port->serial;
 182         struct urb *urb;
 183         unsigned char *buffer;
 184         unsigned long flags;
 185         int status;
 186         struct usb_ctrlrequest *dr;
 187 
 188         spin_lock_irqsave(&priv->lock, flags);
 189         if (priv->outstanding_urbs > URB_UPPER_LIMIT) {
 190                 spin_unlock_irqrestore(&priv->lock, flags);
 191                 dev_dbg(&port->dev, "%s - write limit hit\n", __func__);
 192                 return 0;
 193         }
 194         priv->outstanding_urbs++;
 195         spin_unlock_irqrestore(&priv->lock, flags);
 196 
 197         buffer = kmalloc(count, GFP_ATOMIC);
 198         if (!buffer) {
 199                 count = -ENOMEM;
 200                 goto error_no_buffer;
 201         }
 202 
 203         urb = usb_alloc_urb(0, GFP_ATOMIC);
 204         if (!urb) {
 205                 count = -ENOMEM;
 206                 goto error_no_urb;
 207         }
 208 
 209         memcpy(buffer, buf, count);
 210 
 211         usb_serial_debug_data(&port->dev, __func__, count, buffer);
 212 
 213         /* The connected devices do not have a bulk write endpoint,
 214          * to transmit data to de barcode device the control endpoint is used */
 215         dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
 216         if (!dr) {
 217                 count = -ENOMEM;
 218                 goto error_no_dr;
 219         }
 220 
 221         dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT;
 222         dr->bRequest = 0x01;
 223         dr->wValue = 0;
 224         dr->wIndex = 0;
 225         dr->wLength = cpu_to_le16(count);
 226 
 227         usb_fill_control_urb(urb, serial->dev,
 228                 usb_sndctrlpipe(serial->dev, 0),
 229                 (unsigned char *)dr, buffer, count,
 230                 opticon_write_control_callback, port);
 231 
 232         /* send it down the pipe */
 233         status = usb_submit_urb(urb, GFP_ATOMIC);
 234         if (status) {
 235                 dev_err(&port->dev,
 236                 "%s - usb_submit_urb(write endpoint) failed status = %d\n",
 237                                                         __func__, status);
 238                 count = status;
 239                 goto error;
 240         }
 241 
 242         /* we are done with this urb, so let the host driver
 243          * really free it when it is finished with it */
 244         usb_free_urb(urb);
 245 
 246         return count;
 247 error:
 248         kfree(dr);
 249 error_no_dr:
 250         usb_free_urb(urb);
 251 error_no_urb:
 252         kfree(buffer);
 253 error_no_buffer:
 254         spin_lock_irqsave(&priv->lock, flags);
 255         --priv->outstanding_urbs;
 256         spin_unlock_irqrestore(&priv->lock, flags);
 257         return count;
 258 }
 259 
 260 static int opticon_write_room(struct tty_struct *tty)
 261 {
 262         struct usb_serial_port *port = tty->driver_data;
 263         struct opticon_private *priv = usb_get_serial_port_data(port);
 264         unsigned long flags;
 265 
 266         /*
 267          * We really can take almost anything the user throws at us
 268          * but let's pick a nice big number to tell the tty
 269          * layer that we have lots of free space, unless we don't.
 270          */
 271         spin_lock_irqsave(&priv->lock, flags);
 272         if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) {
 273                 spin_unlock_irqrestore(&priv->lock, flags);
 274                 dev_dbg(&port->dev, "%s - write limit hit\n", __func__);
 275                 return 0;
 276         }
 277         spin_unlock_irqrestore(&priv->lock, flags);
 278 
 279         return 2048;
 280 }
 281 
 282 static int opticon_tiocmget(struct tty_struct *tty)
 283 {
 284         struct usb_serial_port *port = tty->driver_data;
 285         struct opticon_private *priv = usb_get_serial_port_data(port);
 286         unsigned long flags;
 287         int result = 0;
 288 
 289         spin_lock_irqsave(&priv->lock, flags);
 290         if (priv->rts)
 291                 result |= TIOCM_RTS;
 292         if (priv->cts)
 293                 result |= TIOCM_CTS;
 294         spin_unlock_irqrestore(&priv->lock, flags);
 295 
 296         dev_dbg(&port->dev, "%s - %x\n", __func__, result);
 297         return result;
 298 }
 299 
 300 static int opticon_tiocmset(struct tty_struct *tty,
 301                            unsigned int set, unsigned int clear)
 302 {
 303         struct usb_serial_port *port = tty->driver_data;
 304         struct opticon_private *priv = usb_get_serial_port_data(port);
 305         unsigned long flags;
 306         bool rts;
 307         bool changed = false;
 308         int ret;
 309 
 310         /* We only support RTS so we only handle that */
 311         spin_lock_irqsave(&priv->lock, flags);
 312 
 313         rts = priv->rts;
 314         if (set & TIOCM_RTS)
 315                 priv->rts = true;
 316         if (clear & TIOCM_RTS)
 317                 priv->rts = false;
 318         changed = rts ^ priv->rts;
 319         spin_unlock_irqrestore(&priv->lock, flags);
 320 
 321         if (!changed)
 322                 return 0;
 323 
 324         ret = send_control_msg(port, CONTROL_RTS, !rts);
 325         if (ret)
 326                 return usb_translate_errors(ret);
 327 
 328         return 0;
 329 }
 330 
 331 static int get_serial_info(struct tty_struct *tty,
 332                            struct serial_struct *ss)
 333 {
 334         struct usb_serial_port *port = tty->driver_data;
 335 
 336         /* fake emulate a 16550 uart to make userspace code happy */
 337         ss->type                = PORT_16550A;
 338         ss->line                = port->minor;
 339         ss->port                = 0;
 340         ss->irq                 = 0;
 341         ss->xmit_fifo_size      = 1024;
 342         ss->baud_base           = 9600;
 343         ss->close_delay         = 5*HZ;
 344         ss->closing_wait        = 30*HZ;
 345         return 0;
 346 }
 347 
 348 static int opticon_port_probe(struct usb_serial_port *port)
 349 {
 350         struct opticon_private *priv;
 351 
 352         priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 353         if (!priv)
 354                 return -ENOMEM;
 355 
 356         spin_lock_init(&priv->lock);
 357 
 358         usb_set_serial_port_data(port, priv);
 359 
 360         return 0;
 361 }
 362 
 363 static int opticon_port_remove(struct usb_serial_port *port)
 364 {
 365         struct opticon_private *priv = usb_get_serial_port_data(port);
 366 
 367         kfree(priv);
 368 
 369         return 0;
 370 }
 371 
 372 static struct usb_serial_driver opticon_device = {
 373         .driver = {
 374                 .owner =        THIS_MODULE,
 375                 .name =         "opticon",
 376         },
 377         .id_table =             id_table,
 378         .num_ports =            1,
 379         .num_bulk_in =          1,
 380         .bulk_in_size =         256,
 381         .port_probe =           opticon_port_probe,
 382         .port_remove =          opticon_port_remove,
 383         .open =                 opticon_open,
 384         .write =                opticon_write,
 385         .write_room =           opticon_write_room,
 386         .throttle =             usb_serial_generic_throttle,
 387         .unthrottle =           usb_serial_generic_unthrottle,
 388         .get_serial =           get_serial_info,
 389         .tiocmget =             opticon_tiocmget,
 390         .tiocmset =             opticon_tiocmset,
 391         .process_read_urb =     opticon_process_read_urb,
 392 };
 393 
 394 static struct usb_serial_driver * const serial_drivers[] = {
 395         &opticon_device, NULL
 396 };
 397 
 398 module_usb_serial_driver(serial_drivers, id_table);
 399 
 400 MODULE_DESCRIPTION(DRIVER_DESC);
 401 MODULE_LICENSE("GPL v2");

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