1 /* 2 * Symbol USB barcode to serial driver 3 * 4 * Copyright (C) 2009 Greg Kroah-Hartman <gregkh@suse.de> 5 * Copyright (C) 2009 Novell Inc. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License version 9 * 2 as published by the Free Software Foundation. 10 */ 11 12 #include <linux/kernel.h> 13 #include <linux/init.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 int debug; 24 25 static const struct usb_device_id id_table[] = { 26 { USB_DEVICE(0x05e0, 0x0600) }, 27 { }, 28 }; 29 MODULE_DEVICE_TABLE(usb, id_table); 30 31 /* This structure holds all of the individual device information */ 32 struct symbol_private { 33 struct usb_device *udev; 34 struct usb_serial *serial; 35 struct usb_serial_port *port; 36 unsigned char *int_buffer; 37 struct urb *int_urb; 38 int buffer_size; 39 u8 bInterval; 40 u8 int_address; 41 spinlock_t lock; /* protects the following flags */ 42 bool throttled; 43 bool actually_throttled; 44 bool rts; 45 }; 46 47 static void symbol_int_callback(struct urb *urb) 48 { 49 struct symbol_private *priv = urb->context; 50 unsigned char *data = urb->transfer_buffer; 51 struct usb_serial_port *port = priv->port; 52 int status = urb->status; 53 struct tty_struct *tty; 54 int result; 55 int data_length; 56 57 dbg("%s - port %d", __func__, port->number); 58 59 switch (status) { 60 case 0: 61 /* success */ 62 break; 63 case -ECONNRESET: 64 case -ENOENT: 65 case -ESHUTDOWN: 66 /* this urb is terminated, clean up */ 67 dbg("%s - urb shutting down with status: %d", 68 __func__, status); 69 return; 70 default: 71 dbg("%s - nonzero urb status received: %d", 72 __func__, status); 73 goto exit; 74 } 75 76 usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, 77 data); 78 79 if (urb->actual_length > 1) { 80 data_length = urb->actual_length - 1; 81 82 /* 83 * Data from the device comes with a 1 byte header: 84 * 85 * <size of data>data... 86 * This is real data to be sent to the tty layer 87 * we pretty much just ignore the size and send everything 88 * else to the tty layer. 89 */ 90 tty = tty_port_tty_get(&port->port); 91 if (tty) { 92 tty_insert_flip_string(tty, &data[1], data_length); 93 tty_flip_buffer_push(tty); 94 tty_kref_put(tty); 95 } 96 } else { 97 dev_dbg(&priv->udev->dev, 98 "Improper amount of data received from the device, " 99 "%d bytes", urb->actual_length); 100 } 101 102 exit: 103 spin_lock(&priv->lock); 104 105 /* Continue trying to always read if we should */ 106 if (!priv->throttled) { 107 usb_fill_int_urb(priv->int_urb, priv->udev, 108 usb_rcvintpipe(priv->udev, 109 priv->int_address), 110 priv->int_buffer, priv->buffer_size, 111 symbol_int_callback, priv, priv->bInterval); 112 result = usb_submit_urb(priv->int_urb, GFP_ATOMIC); 113 if (result) 114 dev_err(&port->dev, 115 "%s - failed resubmitting read urb, error %d\n", 116 __func__, result); 117 } else 118 priv->actually_throttled = true; 119 spin_unlock(&priv->lock); 120 } 121 122 static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port) 123 { 124 struct symbol_private *priv = usb_get_serial_data(port->serial); 125 unsigned long flags; 126 int result = 0; 127 128 dbg("%s - port %d", __func__, port->number); 129 130 spin_lock_irqsave(&priv->lock, flags); 131 priv->throttled = false; 132 priv->actually_throttled = false; 133 priv->port = port; 134 spin_unlock_irqrestore(&priv->lock, flags); 135 136 /* Start reading from the device */ 137 usb_fill_int_urb(priv->int_urb, priv->udev, 138 usb_rcvintpipe(priv->udev, priv->int_address), 139 priv->int_buffer, priv->buffer_size, 140 symbol_int_callback, priv, priv->bInterval); 141 result = usb_submit_urb(priv->int_urb, GFP_KERNEL); 142 if (result) 143 dev_err(&port->dev, 144 "%s - failed resubmitting read urb, error %d\n", 145 __func__, result); 146 return result; 147 } 148 149 static void symbol_close(struct usb_serial_port *port) 150 { 151 struct symbol_private *priv = usb_get_serial_data(port->serial); 152 153 dbg("%s - port %d", __func__, port->number); 154 155 /* shutdown our urbs */ 156 usb_kill_urb(priv->int_urb); 157 } 158 159 static void symbol_throttle(struct tty_struct *tty) 160 { 161 struct usb_serial_port *port = tty->driver_data; 162 struct symbol_private *priv = usb_get_serial_data(port->serial); 163 164 dbg("%s - port %d", __func__, port->number); 165 spin_lock_irq(&priv->lock); 166 priv->throttled = true; 167 spin_unlock_irq(&priv->lock); 168 } 169 170 static void symbol_unthrottle(struct tty_struct *tty) 171 { 172 struct usb_serial_port *port = tty->driver_data; 173 struct symbol_private *priv = usb_get_serial_data(port->serial); 174 int result; 175 bool was_throttled; 176 177 dbg("%s - port %d", __func__, port->number); 178 179 spin_lock_irq(&priv->lock); 180 priv->throttled = false; 181 was_throttled = priv->actually_throttled; 182 priv->actually_throttled = false; 183 spin_unlock_irq(&priv->lock); 184 185 priv->int_urb->dev = port->serial->dev; 186 if (was_throttled) { 187 result = usb_submit_urb(priv->int_urb, GFP_KERNEL); 188 if (result) 189 dev_err(&port->dev, 190 "%s - failed submitting read urb, error %d\n", 191 __func__, result); 192 } 193 } 194 195 static int symbol_startup(struct usb_serial *serial) 196 { 197 struct symbol_private *priv; 198 struct usb_host_interface *intf; 199 int i; 200 int retval = -ENOMEM; 201 bool int_in_found = false; 202 203 /* create our private serial structure */ 204 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 205 if (priv == NULL) { 206 dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__); 207 return -ENOMEM; 208 } 209 spin_lock_init(&priv->lock); 210 priv->serial = serial; 211 priv->port = serial->port[0]; 212 priv->udev = serial->dev; 213 214 /* find our interrupt endpoint */ 215 intf = serial->interface->altsetting; 216 for (i = 0; i < intf->desc.bNumEndpoints; ++i) { 217 struct usb_endpoint_descriptor *endpoint; 218 219 endpoint = &intf->endpoint[i].desc; 220 if (!usb_endpoint_is_int_in(endpoint)) 221 continue; 222 223 priv->int_urb = usb_alloc_urb(0, GFP_KERNEL); 224 if (!priv->int_urb) { 225 dev_err(&priv->udev->dev, "out of memory\n"); 226 goto error; 227 } 228 229 priv->buffer_size = le16_to_cpu(endpoint->wMaxPacketSize) * 2; 230 priv->int_buffer = kmalloc(priv->buffer_size, GFP_KERNEL); 231 if (!priv->int_buffer) { 232 dev_err(&priv->udev->dev, "out of memory\n"); 233 goto error; 234 } 235 236 priv->int_address = endpoint->bEndpointAddress; 237 priv->bInterval = endpoint->bInterval; 238 239 /* set up our int urb */ 240 usb_fill_int_urb(priv->int_urb, priv->udev, 241 usb_rcvintpipe(priv->udev, 242 endpoint->bEndpointAddress), 243 priv->int_buffer, priv->buffer_size, 244 symbol_int_callback, priv, priv->bInterval); 245 246 int_in_found = true; 247 break; 248 } 249 250 if (!int_in_found) { 251 dev_err(&priv->udev->dev, 252 "Error - the proper endpoints were not found!\n"); 253 goto error; 254 } 255 256 usb_set_serial_data(serial, priv); 257 return 0; 258 259 error: 260 usb_free_urb(priv->int_urb); 261 kfree(priv->int_buffer); 262 kfree(priv); 263 return retval; 264 } 265 266 static void symbol_disconnect(struct usb_serial *serial) 267 { 268 struct symbol_private *priv = usb_get_serial_data(serial); 269 270 dbg("%s", __func__); 271 272 usb_kill_urb(priv->int_urb); 273 usb_free_urb(priv->int_urb); 274 } 275 276 static void symbol_release(struct usb_serial *serial) 277 { 278 struct symbol_private *priv = usb_get_serial_data(serial); 279 280 dbg("%s", __func__); 281 282 kfree(priv->int_buffer); 283 kfree(priv); 284 } 285 286 static struct usb_driver symbol_driver = { 287 .name = "symbol", 288 .probe = usb_serial_probe, 289 .disconnect = usb_serial_disconnect, 290 .id_table = id_table, 291 .no_dynamic_id = 1, 292 }; 293 294 static struct usb_serial_driver symbol_device = { 295 .driver = { 296 .owner = THIS_MODULE, 297 .name = "symbol", 298 }, 299 .id_table = id_table, 300 .usb_driver = &symbol_driver, 301 .num_ports = 1, 302 .attach = symbol_startup, 303 .open = symbol_open, 304 .close = symbol_close, 305 .disconnect = symbol_disconnect, 306 .release = symbol_release, 307 .throttle = symbol_throttle, 308 .unthrottle = symbol_unthrottle, 309 }; 310 311 static int __init symbol_init(void) 312 { 313 int retval; 314 315 retval = usb_serial_register(&symbol_device); 316 if (retval) 317 return retval; 318 retval = usb_register(&symbol_driver); 319 if (retval) 320 usb_serial_deregister(&symbol_device); 321 return retval; 322 } 323 324 static void __exit symbol_exit(void) 325 { 326 usb_deregister(&symbol_driver); 327 usb_serial_deregister(&symbol_device); 328 } 329 330 module_init(symbol_init); 331 module_exit(symbol_exit); 332 MODULE_LICENSE("GPL"); 333 334 module_param(debug, bool, S_IRUGO | S_IWUSR); 335 MODULE_PARM_DESC(debug, "Debug enabled or not"); 336