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