root/drivers/usb/serial/symbolserial.c

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

DEFINITIONS

This source file includes following definitions.
  1. symbol_int_callback
  2. symbol_open
  3. symbol_close
  4. symbol_throttle
  5. symbol_unthrottle
  6. symbol_port_probe
  7. symbol_port_remove

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Symbol USB barcode to serial driver
   4  *
   5  * Copyright (C) 2013 Johan Hovold <jhovold@gmail.com>
   6  * Copyright (C) 2009 Greg Kroah-Hartman <gregkh@suse.de>
   7  * Copyright (C) 2009 Novell Inc.
   8  */
   9 
  10 #include <linux/kernel.h>
  11 #include <linux/tty.h>
  12 #include <linux/slab.h>
  13 #include <linux/tty_driver.h>
  14 #include <linux/tty_flip.h>
  15 #include <linux/module.h>
  16 #include <linux/usb.h>
  17 #include <linux/usb/serial.h>
  18 #include <linux/uaccess.h>
  19 
  20 static const struct usb_device_id id_table[] = {
  21         { USB_DEVICE(0x05e0, 0x0600) },
  22         { },
  23 };
  24 MODULE_DEVICE_TABLE(usb, id_table);
  25 
  26 struct symbol_private {
  27         spinlock_t lock;        /* protects the following flags */
  28         bool throttled;
  29         bool actually_throttled;
  30 };
  31 
  32 static void symbol_int_callback(struct urb *urb)
  33 {
  34         struct usb_serial_port *port = urb->context;
  35         struct symbol_private *priv = usb_get_serial_port_data(port);
  36         unsigned char *data = urb->transfer_buffer;
  37         int status = urb->status;
  38         unsigned long flags;
  39         int result;
  40         int data_length;
  41 
  42         switch (status) {
  43         case 0:
  44                 /* success */
  45                 break;
  46         case -ECONNRESET:
  47         case -ENOENT:
  48         case -ESHUTDOWN:
  49                 /* this urb is terminated, clean up */
  50                 dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
  51                         __func__, status);
  52                 return;
  53         default:
  54                 dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
  55                         __func__, status);
  56                 goto exit;
  57         }
  58 
  59         usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
  60 
  61         /*
  62          * Data from the device comes with a 1 byte header:
  63          *
  64          * <size of data> <data>...
  65          */
  66         if (urb->actual_length > 1) {
  67                 data_length = data[0];
  68                 if (data_length > (urb->actual_length - 1))
  69                         data_length = urb->actual_length - 1;
  70                 tty_insert_flip_string(&port->port, &data[1], data_length);
  71                 tty_flip_buffer_push(&port->port);
  72         } else {
  73                 dev_dbg(&port->dev, "%s - short packet\n", __func__);
  74         }
  75 
  76 exit:
  77         spin_lock_irqsave(&priv->lock, flags);
  78 
  79         /* Continue trying to always read if we should */
  80         if (!priv->throttled) {
  81                 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
  82                 if (result)
  83                         dev_err(&port->dev,
  84                             "%s - failed resubmitting read urb, error %d\n",
  85                                                         __func__, result);
  86         } else
  87                 priv->actually_throttled = true;
  88         spin_unlock_irqrestore(&priv->lock, flags);
  89 }
  90 
  91 static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port)
  92 {
  93         struct symbol_private *priv = usb_get_serial_port_data(port);
  94         unsigned long flags;
  95         int result = 0;
  96 
  97         spin_lock_irqsave(&priv->lock, flags);
  98         priv->throttled = false;
  99         priv->actually_throttled = false;
 100         spin_unlock_irqrestore(&priv->lock, flags);
 101 
 102         /* Start reading from the device */
 103         result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 104         if (result)
 105                 dev_err(&port->dev,
 106                         "%s - failed resubmitting read urb, error %d\n",
 107                         __func__, result);
 108         return result;
 109 }
 110 
 111 static void symbol_close(struct usb_serial_port *port)
 112 {
 113         usb_kill_urb(port->interrupt_in_urb);
 114 }
 115 
 116 static void symbol_throttle(struct tty_struct *tty)
 117 {
 118         struct usb_serial_port *port = tty->driver_data;
 119         struct symbol_private *priv = usb_get_serial_port_data(port);
 120 
 121         spin_lock_irq(&priv->lock);
 122         priv->throttled = true;
 123         spin_unlock_irq(&priv->lock);
 124 }
 125 
 126 static void symbol_unthrottle(struct tty_struct *tty)
 127 {
 128         struct usb_serial_port *port = tty->driver_data;
 129         struct symbol_private *priv = usb_get_serial_port_data(port);
 130         int result;
 131         bool was_throttled;
 132 
 133         spin_lock_irq(&priv->lock);
 134         priv->throttled = false;
 135         was_throttled = priv->actually_throttled;
 136         priv->actually_throttled = false;
 137         spin_unlock_irq(&priv->lock);
 138 
 139         if (was_throttled) {
 140                 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 141                 if (result)
 142                         dev_err(&port->dev,
 143                                 "%s - failed submitting read urb, error %d\n",
 144                                                         __func__, result);
 145         }
 146 }
 147 
 148 static int symbol_port_probe(struct usb_serial_port *port)
 149 {
 150         struct symbol_private *priv;
 151 
 152         priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 153         if (!priv)
 154                 return -ENOMEM;
 155 
 156         spin_lock_init(&priv->lock);
 157 
 158         usb_set_serial_port_data(port, priv);
 159 
 160         return 0;
 161 }
 162 
 163 static int symbol_port_remove(struct usb_serial_port *port)
 164 {
 165         struct symbol_private *priv = usb_get_serial_port_data(port);
 166 
 167         kfree(priv);
 168 
 169         return 0;
 170 }
 171 
 172 static struct usb_serial_driver symbol_device = {
 173         .driver = {
 174                 .owner =        THIS_MODULE,
 175                 .name =         "symbol",
 176         },
 177         .id_table =             id_table,
 178         .num_ports =            1,
 179         .num_interrupt_in =     1,
 180         .port_probe =           symbol_port_probe,
 181         .port_remove =          symbol_port_remove,
 182         .open =                 symbol_open,
 183         .close =                symbol_close,
 184         .throttle =             symbol_throttle,
 185         .unthrottle =           symbol_unthrottle,
 186         .read_int_callback =    symbol_int_callback,
 187 };
 188 
 189 static struct usb_serial_driver * const serial_drivers[] = {
 190         &symbol_device, NULL
 191 };
 192 
 193 module_usb_serial_driver(serial_drivers, id_table);
 194 
 195 MODULE_LICENSE("GPL v2");

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