xref: /linux/drivers/usb/serial/symbolserial.c (revision ca55b2fef3a9373fcfc30f82fd26bc7fccbda732)
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_startup(struct usb_serial *serial)
151 {
152 	if (!serial->num_interrupt_in) {
153 		dev_err(&serial->dev->dev, "no interrupt-in endpoint\n");
154 		return -ENODEV;
155 	}
156 
157 	return 0;
158 }
159 
160 static int symbol_port_probe(struct usb_serial_port *port)
161 {
162 	struct symbol_private *priv;
163 
164 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
165 	if (!priv)
166 		return -ENOMEM;
167 
168 	spin_lock_init(&priv->lock);
169 
170 	usb_set_serial_port_data(port, priv);
171 
172 	return 0;
173 }
174 
175 static int symbol_port_remove(struct usb_serial_port *port)
176 {
177 	struct symbol_private *priv = usb_get_serial_port_data(port);
178 
179 	kfree(priv);
180 
181 	return 0;
182 }
183 
184 static struct usb_serial_driver symbol_device = {
185 	.driver = {
186 		.owner =	THIS_MODULE,
187 		.name =		"symbol",
188 	},
189 	.id_table =		id_table,
190 	.num_ports =		1,
191 	.attach =		symbol_startup,
192 	.port_probe =		symbol_port_probe,
193 	.port_remove =		symbol_port_remove,
194 	.open =			symbol_open,
195 	.close =		symbol_close,
196 	.throttle = 		symbol_throttle,
197 	.unthrottle =		symbol_unthrottle,
198 	.read_int_callback =	symbol_int_callback,
199 };
200 
201 static struct usb_serial_driver * const serial_drivers[] = {
202 	&symbol_device, NULL
203 };
204 
205 module_usb_serial_driver(serial_drivers, id_table);
206 
207 MODULE_LICENSE("GPL");
208