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 bool 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 switch (status) { 58 case 0: 59 /* success */ 60 break; 61 case -ECONNRESET: 62 case -ENOENT: 63 case -ESHUTDOWN: 64 /* this urb is terminated, clean up */ 65 dbg("%s - urb shutting down with status: %d", 66 __func__, status); 67 return; 68 default: 69 dbg("%s - nonzero urb status received: %d", 70 __func__, status); 71 goto exit; 72 } 73 74 usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, 75 data); 76 77 if (urb->actual_length > 1) { 78 data_length = urb->actual_length - 1; 79 80 /* 81 * Data from the device comes with a 1 byte header: 82 * 83 * <size of data>data... 84 * This is real data to be sent to the tty layer 85 * we pretty much just ignore the size and send everything 86 * else to the tty layer. 87 */ 88 tty = tty_port_tty_get(&port->port); 89 if (tty) { 90 tty_insert_flip_string(tty, &data[1], data_length); 91 tty_flip_buffer_push(tty); 92 tty_kref_put(tty); 93 } 94 } else { 95 dev_dbg(&priv->udev->dev, 96 "Improper amount of data received from the device, " 97 "%d bytes", urb->actual_length); 98 } 99 100 exit: 101 spin_lock(&priv->lock); 102 103 /* Continue trying to always read if we should */ 104 if (!priv->throttled) { 105 usb_fill_int_urb(priv->int_urb, priv->udev, 106 usb_rcvintpipe(priv->udev, 107 priv->int_address), 108 priv->int_buffer, priv->buffer_size, 109 symbol_int_callback, priv, priv->bInterval); 110 result = usb_submit_urb(priv->int_urb, GFP_ATOMIC); 111 if (result) 112 dev_err(&port->dev, 113 "%s - failed resubmitting read urb, error %d\n", 114 __func__, result); 115 } else 116 priv->actually_throttled = true; 117 spin_unlock(&priv->lock); 118 } 119 120 static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port) 121 { 122 struct symbol_private *priv = usb_get_serial_data(port->serial); 123 unsigned long flags; 124 int result = 0; 125 126 spin_lock_irqsave(&priv->lock, flags); 127 priv->throttled = false; 128 priv->actually_throttled = false; 129 priv->port = port; 130 spin_unlock_irqrestore(&priv->lock, flags); 131 132 /* Start reading from the device */ 133 usb_fill_int_urb(priv->int_urb, priv->udev, 134 usb_rcvintpipe(priv->udev, priv->int_address), 135 priv->int_buffer, priv->buffer_size, 136 symbol_int_callback, priv, priv->bInterval); 137 result = usb_submit_urb(priv->int_urb, GFP_KERNEL); 138 if (result) 139 dev_err(&port->dev, 140 "%s - failed resubmitting read urb, error %d\n", 141 __func__, result); 142 return result; 143 } 144 145 static void symbol_close(struct usb_serial_port *port) 146 { 147 struct symbol_private *priv = usb_get_serial_data(port->serial); 148 149 /* shutdown our urbs */ 150 usb_kill_urb(priv->int_urb); 151 } 152 153 static void symbol_throttle(struct tty_struct *tty) 154 { 155 struct usb_serial_port *port = tty->driver_data; 156 struct symbol_private *priv = usb_get_serial_data(port->serial); 157 158 spin_lock_irq(&priv->lock); 159 priv->throttled = true; 160 spin_unlock_irq(&priv->lock); 161 } 162 163 static void symbol_unthrottle(struct tty_struct *tty) 164 { 165 struct usb_serial_port *port = tty->driver_data; 166 struct symbol_private *priv = usb_get_serial_data(port->serial); 167 int result; 168 bool was_throttled; 169 170 spin_lock_irq(&priv->lock); 171 priv->throttled = false; 172 was_throttled = priv->actually_throttled; 173 priv->actually_throttled = false; 174 spin_unlock_irq(&priv->lock); 175 176 if (was_throttled) { 177 result = usb_submit_urb(priv->int_urb, GFP_KERNEL); 178 if (result) 179 dev_err(&port->dev, 180 "%s - failed submitting read urb, error %d\n", 181 __func__, result); 182 } 183 } 184 185 static int symbol_startup(struct usb_serial *serial) 186 { 187 struct symbol_private *priv; 188 struct usb_host_interface *intf; 189 int i; 190 int retval = -ENOMEM; 191 bool int_in_found = false; 192 193 /* create our private serial structure */ 194 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 195 if (priv == NULL) { 196 dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__); 197 return -ENOMEM; 198 } 199 spin_lock_init(&priv->lock); 200 priv->serial = serial; 201 priv->port = serial->port[0]; 202 priv->udev = serial->dev; 203 204 /* find our interrupt endpoint */ 205 intf = serial->interface->altsetting; 206 for (i = 0; i < intf->desc.bNumEndpoints; ++i) { 207 struct usb_endpoint_descriptor *endpoint; 208 209 endpoint = &intf->endpoint[i].desc; 210 if (!usb_endpoint_is_int_in(endpoint)) 211 continue; 212 213 priv->int_urb = usb_alloc_urb(0, GFP_KERNEL); 214 if (!priv->int_urb) { 215 dev_err(&priv->udev->dev, "out of memory\n"); 216 goto error; 217 } 218 219 priv->buffer_size = usb_endpoint_maxp(endpoint) * 2; 220 priv->int_buffer = kmalloc(priv->buffer_size, GFP_KERNEL); 221 if (!priv->int_buffer) { 222 dev_err(&priv->udev->dev, "out of memory\n"); 223 goto error; 224 } 225 226 priv->int_address = endpoint->bEndpointAddress; 227 priv->bInterval = endpoint->bInterval; 228 229 /* set up our int urb */ 230 usb_fill_int_urb(priv->int_urb, priv->udev, 231 usb_rcvintpipe(priv->udev, 232 endpoint->bEndpointAddress), 233 priv->int_buffer, priv->buffer_size, 234 symbol_int_callback, priv, priv->bInterval); 235 236 int_in_found = true; 237 break; 238 } 239 240 if (!int_in_found) { 241 dev_err(&priv->udev->dev, 242 "Error - the proper endpoints were not found!\n"); 243 goto error; 244 } 245 246 usb_set_serial_data(serial, priv); 247 return 0; 248 249 error: 250 usb_free_urb(priv->int_urb); 251 kfree(priv->int_buffer); 252 kfree(priv); 253 return retval; 254 } 255 256 static void symbol_disconnect(struct usb_serial *serial) 257 { 258 struct symbol_private *priv = usb_get_serial_data(serial); 259 260 usb_kill_urb(priv->int_urb); 261 usb_free_urb(priv->int_urb); 262 } 263 264 static void symbol_release(struct usb_serial *serial) 265 { 266 struct symbol_private *priv = usb_get_serial_data(serial); 267 268 kfree(priv->int_buffer); 269 kfree(priv); 270 } 271 272 static struct usb_driver symbol_driver = { 273 .name = "symbol", 274 .probe = usb_serial_probe, 275 .disconnect = usb_serial_disconnect, 276 .id_table = id_table, 277 }; 278 279 static struct usb_serial_driver symbol_device = { 280 .driver = { 281 .owner = THIS_MODULE, 282 .name = "symbol", 283 }, 284 .id_table = id_table, 285 .num_ports = 1, 286 .attach = symbol_startup, 287 .open = symbol_open, 288 .close = symbol_close, 289 .disconnect = symbol_disconnect, 290 .release = symbol_release, 291 .throttle = symbol_throttle, 292 .unthrottle = symbol_unthrottle, 293 }; 294 295 static struct usb_serial_driver * const serial_drivers[] = { 296 &symbol_device, NULL 297 }; 298 299 module_usb_serial_driver(symbol_driver, serial_drivers); 300 301 MODULE_LICENSE("GPL"); 302 303 module_param(debug, bool, S_IRUGO | S_IWUSR); 304 MODULE_PARM_DESC(debug, "Debug enabled or not"); 305