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