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"); 196