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