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 int result; 39 int data_length; 40 41 switch (status) { 42 case 0: 43 /* success */ 44 break; 45 case -ECONNRESET: 46 case -ENOENT: 47 case -ESHUTDOWN: 48 /* this urb is terminated, clean up */ 49 dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n", 50 __func__, status); 51 return; 52 default: 53 dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n", 54 __func__, status); 55 goto exit; 56 } 57 58 usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data); 59 60 /* 61 * Data from the device comes with a 1 byte header: 62 * 63 * <size of data> <data>... 64 */ 65 if (urb->actual_length > 1) { 66 data_length = data[0]; 67 if (data_length > (urb->actual_length - 1)) 68 data_length = urb->actual_length - 1; 69 tty_insert_flip_string(&port->port, &data[1], data_length); 70 tty_flip_buffer_push(&port->port); 71 } else { 72 dev_dbg(&port->dev, "%s - short packet\n", __func__); 73 } 74 75 exit: 76 spin_lock(&priv->lock); 77 78 /* Continue trying to always read if we should */ 79 if (!priv->throttled) { 80 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); 81 if (result) 82 dev_err(&port->dev, 83 "%s - failed resubmitting read urb, error %d\n", 84 __func__, result); 85 } else 86 priv->actually_throttled = true; 87 spin_unlock(&priv->lock); 88 } 89 90 static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port) 91 { 92 struct symbol_private *priv = usb_get_serial_port_data(port); 93 unsigned long flags; 94 int result = 0; 95 96 spin_lock_irqsave(&priv->lock, flags); 97 priv->throttled = false; 98 priv->actually_throttled = false; 99 spin_unlock_irqrestore(&priv->lock, flags); 100 101 /* Start reading from the device */ 102 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 103 if (result) 104 dev_err(&port->dev, 105 "%s - failed resubmitting read urb, error %d\n", 106 __func__, result); 107 return result; 108 } 109 110 static void symbol_close(struct usb_serial_port *port) 111 { 112 usb_kill_urb(port->interrupt_in_urb); 113 } 114 115 static void symbol_throttle(struct tty_struct *tty) 116 { 117 struct usb_serial_port *port = tty->driver_data; 118 struct symbol_private *priv = usb_get_serial_port_data(port); 119 120 spin_lock_irq(&priv->lock); 121 priv->throttled = true; 122 spin_unlock_irq(&priv->lock); 123 } 124 125 static void symbol_unthrottle(struct tty_struct *tty) 126 { 127 struct usb_serial_port *port = tty->driver_data; 128 struct symbol_private *priv = usb_get_serial_port_data(port); 129 int result; 130 bool was_throttled; 131 132 spin_lock_irq(&priv->lock); 133 priv->throttled = false; 134 was_throttled = priv->actually_throttled; 135 priv->actually_throttled = false; 136 spin_unlock_irq(&priv->lock); 137 138 if (was_throttled) { 139 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 140 if (result) 141 dev_err(&port->dev, 142 "%s - failed submitting read urb, error %d\n", 143 __func__, result); 144 } 145 } 146 147 static int symbol_port_probe(struct usb_serial_port *port) 148 { 149 struct symbol_private *priv; 150 151 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 152 if (!priv) 153 return -ENOMEM; 154 155 spin_lock_init(&priv->lock); 156 157 usb_set_serial_port_data(port, priv); 158 159 return 0; 160 } 161 162 static int symbol_port_remove(struct usb_serial_port *port) 163 { 164 struct symbol_private *priv = usb_get_serial_port_data(port); 165 166 kfree(priv); 167 168 return 0; 169 } 170 171 static struct usb_serial_driver symbol_device = { 172 .driver = { 173 .owner = THIS_MODULE, 174 .name = "symbol", 175 }, 176 .id_table = id_table, 177 .num_ports = 1, 178 .num_interrupt_in = 1, 179 .port_probe = symbol_port_probe, 180 .port_remove = symbol_port_remove, 181 .open = symbol_open, 182 .close = symbol_close, 183 .throttle = symbol_throttle, 184 .unthrottle = symbol_unthrottle, 185 .read_int_callback = symbol_int_callback, 186 }; 187 188 static struct usb_serial_driver * const serial_drivers[] = { 189 &symbol_device, NULL 190 }; 191 192 module_usb_serial_driver(serial_drivers, id_table); 193 194 MODULE_LICENSE("GPL v2"); 195