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