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 /* 64 * Data from the device comes with a 1 byte header: 65 * 66 * <size of data> <data>... 67 */ 68 if (urb->actual_length > 1) { 69 data_length = data[0]; 70 if (data_length > (urb->actual_length - 1)) 71 data_length = urb->actual_length - 1; 72 tty_insert_flip_string(&port->port, &data[1], data_length); 73 tty_flip_buffer_push(&port->port); 74 } else { 75 dev_dbg(&port->dev, "%s - short packet\n", __func__); 76 } 77 78 exit: 79 spin_lock(&priv->lock); 80 81 /* Continue trying to always read if we should */ 82 if (!priv->throttled) { 83 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); 84 if (result) 85 dev_err(&port->dev, 86 "%s - failed resubmitting read urb, error %d\n", 87 __func__, result); 88 } else 89 priv->actually_throttled = true; 90 spin_unlock(&priv->lock); 91 } 92 93 static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port) 94 { 95 struct symbol_private *priv = usb_get_serial_port_data(port); 96 unsigned long flags; 97 int result = 0; 98 99 spin_lock_irqsave(&priv->lock, flags); 100 priv->throttled = false; 101 priv->actually_throttled = false; 102 spin_unlock_irqrestore(&priv->lock, flags); 103 104 /* Start reading from the device */ 105 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 106 if (result) 107 dev_err(&port->dev, 108 "%s - failed resubmitting read urb, error %d\n", 109 __func__, result); 110 return result; 111 } 112 113 static void symbol_close(struct usb_serial_port *port) 114 { 115 usb_kill_urb(port->interrupt_in_urb); 116 } 117 118 static void symbol_throttle(struct tty_struct *tty) 119 { 120 struct usb_serial_port *port = tty->driver_data; 121 struct symbol_private *priv = usb_get_serial_port_data(port); 122 123 spin_lock_irq(&priv->lock); 124 priv->throttled = true; 125 spin_unlock_irq(&priv->lock); 126 } 127 128 static void symbol_unthrottle(struct tty_struct *tty) 129 { 130 struct usb_serial_port *port = tty->driver_data; 131 struct symbol_private *priv = usb_get_serial_port_data(port); 132 int result; 133 bool was_throttled; 134 135 spin_lock_irq(&priv->lock); 136 priv->throttled = false; 137 was_throttled = priv->actually_throttled; 138 priv->actually_throttled = false; 139 spin_unlock_irq(&priv->lock); 140 141 if (was_throttled) { 142 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 143 if (result) 144 dev_err(&port->dev, 145 "%s - failed submitting read urb, error %d\n", 146 __func__, result); 147 } 148 } 149 150 static int symbol_port_probe(struct usb_serial_port *port) 151 { 152 struct symbol_private *priv; 153 154 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 155 if (!priv) 156 return -ENOMEM; 157 158 spin_lock_init(&priv->lock); 159 160 usb_set_serial_port_data(port, priv); 161 162 return 0; 163 } 164 165 static int symbol_port_remove(struct usb_serial_port *port) 166 { 167 struct symbol_private *priv = usb_get_serial_port_data(port); 168 169 kfree(priv); 170 171 return 0; 172 } 173 174 static struct usb_serial_driver symbol_device = { 175 .driver = { 176 .owner = THIS_MODULE, 177 .name = "symbol", 178 }, 179 .id_table = id_table, 180 .num_ports = 1, 181 .num_interrupt_in = 1, 182 .port_probe = symbol_port_probe, 183 .port_remove = symbol_port_remove, 184 .open = symbol_open, 185 .close = symbol_close, 186 .throttle = symbol_throttle, 187 .unthrottle = symbol_unthrottle, 188 .read_int_callback = symbol_int_callback, 189 }; 190 191 static struct usb_serial_driver * const serial_drivers[] = { 192 &symbol_device, NULL 193 }; 194 195 module_usb_serial_driver(serial_drivers, id_table); 196 197 MODULE_LICENSE("GPL"); 198