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