xref: /openbmc/linux/drivers/usb/serial/opticon.c (revision 57262b82)
1 /*
2  * Opticon USB barcode to serial driver
3  *
4  * Copyright (C) 2008 Greg Kroah-Hartman <gregkh@suse.de>
5  * Copyright (C) 2008 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/tty_driver.h>
16 #include <linux/tty_flip.h>
17 #include <linux/module.h>
18 #include <linux/usb.h>
19 #include <linux/usb/serial.h>
20 #include <linux/uaccess.h>
21 
22 static int debug;
23 
24 static struct usb_device_id id_table[] = {
25 	{ USB_DEVICE(0x065a, 0x0009) },
26 	{ },
27 };
28 MODULE_DEVICE_TABLE(usb, id_table);
29 
30 /* This structure holds all of the individual device information */
31 struct opticon_private {
32 	struct usb_device *udev;
33 	struct usb_serial *serial;
34 	struct usb_serial_port *port;
35 	unsigned char *bulk_in_buffer;
36 	struct urb *bulk_read_urb;
37 	int buffer_size;
38 	u8 bulk_address;
39 	spinlock_t lock;	/* protects the following flags */
40 	bool throttled;
41 	bool actually_throttled;
42 	bool rts;
43 };
44 
45 static void opticon_bulk_callback(struct urb *urb)
46 {
47 	struct opticon_private *priv = urb->context;
48 	unsigned char *data = urb->transfer_buffer;
49 	struct usb_serial_port *port = priv->port;
50 	int status = urb->status;
51 	struct tty_struct *tty;
52 	int result;
53 	int available_room = 0;
54 	int data_length;
55 
56 	dbg("%s - port %d", __func__, port->number);
57 
58 	switch (status) {
59 	case 0:
60 		/* success */
61 		break;
62 	case -ECONNRESET:
63 	case -ENOENT:
64 	case -ESHUTDOWN:
65 		/* this urb is terminated, clean up */
66 		dbg("%s - urb shutting down with status: %d",
67 		    __func__, status);
68 		return;
69 	default:
70 		dbg("%s - nonzero urb status received: %d",
71 		    __func__, status);
72 		goto exit;
73 	}
74 
75 	usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length,
76 			      data);
77 
78 	if (urb->actual_length > 2) {
79 		data_length = urb->actual_length - 2;
80 
81 		/*
82 		 * Data from the device comes with a 2 byte header:
83 		 *
84 		 * <0x00><0x00>data...
85 		 * 	This is real data to be sent to the tty layer
86 		 * <0x00><0x01)level
87 		 * 	This is a RTS level change, the third byte is the RTS
88 		 * 	value (0 for low, 1 for high).
89 		 */
90 		if ((data[0] == 0x00) && (data[1] == 0x00)) {
91 			/* real data, send it to the tty layer */
92 			tty = tty_port_tty_get(&port->port);
93 			if (tty) {
94 				available_room = tty_buffer_request_room(tty,
95 								data_length);
96 				if (available_room) {
97 					tty_insert_flip_string(tty, data,
98 							       available_room);
99 					tty_flip_buffer_push(tty);
100 				}
101 				tty_kref_put(tty);
102 			}
103 		} else {
104 			if ((data[0] == 0x00) && (data[1] == 0x01)) {
105 				if (data[2] == 0x00)
106 					priv->rts = false;
107 				else
108 					priv->rts = true;
109 				/* FIXME change the RTS level */
110 			} else {
111 			dev_dbg(&priv->udev->dev,
112 				"Unknown data packet received from the device:"
113 				" %2x %2x\n",
114 				data[0], data[1]);
115 			}
116 		}
117 	} else {
118 		dev_dbg(&priv->udev->dev,
119 			"Improper ammount of data received from the device, "
120 			"%d bytes", urb->actual_length);
121 	}
122 
123 exit:
124 	spin_lock(&priv->lock);
125 
126 	/* Continue trying to always read if we should */
127 	if (!priv->throttled) {
128 		usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev,
129 				  usb_rcvbulkpipe(priv->udev,
130 						  priv->bulk_address),
131 				  priv->bulk_in_buffer, priv->buffer_size,
132 				  opticon_bulk_callback, priv);
133 		result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
134 		if (result)
135 			dev_err(&port->dev,
136 			    "%s - failed resubmitting read urb, error %d\n",
137 							__func__, result);
138 	} else
139 		priv->actually_throttled = true;
140 	spin_unlock(&priv->lock);
141 }
142 
143 static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port,
144 			struct file *filp)
145 {
146 	struct opticon_private *priv = usb_get_serial_data(port->serial);
147 	unsigned long flags;
148 	int result = 0;
149 
150 	dbg("%s - port %d", __func__, port->number);
151 
152 	spin_lock_irqsave(&priv->lock, flags);
153 	priv->throttled = false;
154 	priv->actually_throttled = false;
155 	priv->port = port;
156 	spin_unlock_irqrestore(&priv->lock, flags);
157 
158 	/*
159 	 * Force low_latency on so that our tty_push actually forces the data
160 	 * through, otherwise it is scheduled, and with high data rates (like
161 	 * with OHCI) data can get lost.
162 	 */
163 	if (tty)
164 		tty->low_latency = 1;
165 
166 	/* Start reading from the device */
167 	usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev,
168 			  usb_rcvbulkpipe(priv->udev,
169 					  priv->bulk_address),
170 			  priv->bulk_in_buffer, priv->buffer_size,
171 			  opticon_bulk_callback, priv);
172 	result = usb_submit_urb(priv->bulk_read_urb, GFP_KERNEL);
173 	if (result)
174 		dev_err(&port->dev,
175 			"%s - failed resubmitting read urb, error %d\n",
176 			__func__, result);
177 	return result;
178 }
179 
180 static void opticon_close(struct tty_struct *tty, struct usb_serial_port *port,
181 			  struct file *filp)
182 {
183 	struct opticon_private *priv = usb_get_serial_data(port->serial);
184 
185 	dbg("%s - port %d", __func__, port->number);
186 
187 	/* shutdown our urbs */
188 	usb_kill_urb(priv->bulk_read_urb);
189 }
190 
191 static void opticon_throttle(struct tty_struct *tty)
192 {
193 	struct usb_serial_port *port = tty->driver_data;
194 	struct opticon_private *priv = usb_get_serial_data(port->serial);
195 	unsigned long flags;
196 
197 	dbg("%s - port %d", __func__, port->number);
198 	spin_lock_irqsave(&priv->lock, flags);
199 	priv->throttled = true;
200 	spin_unlock_irqrestore(&priv->lock, flags);
201 }
202 
203 
204 static void opticon_unthrottle(struct tty_struct *tty)
205 {
206 	struct usb_serial_port *port = tty->driver_data;
207 	struct opticon_private *priv = usb_get_serial_data(port->serial);
208 	unsigned long flags;
209 	int result;
210 
211 	dbg("%s - port %d", __func__, port->number);
212 
213 	spin_lock_irqsave(&priv->lock, flags);
214 	priv->throttled = false;
215 	priv->actually_throttled = false;
216 	spin_unlock_irqrestore(&priv->lock, flags);
217 
218 	priv->bulk_read_urb->dev = port->serial->dev;
219 	result = usb_submit_urb(priv->bulk_read_urb, GFP_ATOMIC);
220 	if (result)
221 		dev_err(&port->dev,
222 			"%s - failed submitting read urb, error %d\n",
223 							__func__, result);
224 }
225 
226 static int opticon_startup(struct usb_serial *serial)
227 {
228 	struct opticon_private *priv;
229 	struct usb_host_interface *intf;
230 	int i;
231 	int retval = -ENOMEM;
232 	bool bulk_in_found = false;
233 
234 	/* create our private serial structure */
235 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
236 	if (priv == NULL) {
237 		dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__);
238 		return -ENOMEM;
239 	}
240 	spin_lock_init(&priv->lock);
241 	priv->serial = serial;
242 	priv->port = serial->port[0];
243 	priv->udev = serial->dev;
244 
245 	/* find our bulk endpoint */
246 	intf = serial->interface->altsetting;
247 	for (i = 0; i < intf->desc.bNumEndpoints; ++i) {
248 		struct usb_endpoint_descriptor *endpoint;
249 
250 		endpoint = &intf->endpoint[i].desc;
251 		if (!usb_endpoint_is_bulk_in(endpoint))
252 			continue;
253 
254 		priv->bulk_read_urb = usb_alloc_urb(0, GFP_KERNEL);
255 		if (!priv->bulk_read_urb) {
256 			dev_err(&priv->udev->dev, "out of memory\n");
257 			goto error;
258 		}
259 
260 		priv->buffer_size = le16_to_cpu(endpoint->wMaxPacketSize) * 2;
261 		priv->bulk_in_buffer = kmalloc(priv->buffer_size, GFP_KERNEL);
262 		if (!priv->bulk_in_buffer) {
263 			dev_err(&priv->udev->dev, "out of memory\n");
264 			goto error;
265 		}
266 
267 		priv->bulk_address = endpoint->bEndpointAddress;
268 
269 		/* set up our bulk urb */
270 		usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev,
271 				  usb_rcvbulkpipe(priv->udev,
272 						  endpoint->bEndpointAddress),
273 				  priv->bulk_in_buffer, priv->buffer_size,
274 				  opticon_bulk_callback, priv);
275 
276 		bulk_in_found = true;
277 		break;
278 		}
279 
280 	if (!bulk_in_found) {
281 		dev_err(&priv->udev->dev,
282 			"Error - the proper endpoints were not found!\n");
283 		goto error;
284 	}
285 
286 	usb_set_serial_data(serial, priv);
287 	return 0;
288 
289 error:
290 	usb_free_urb(priv->bulk_read_urb);
291 	kfree(priv->bulk_in_buffer);
292 	kfree(priv);
293 	return retval;
294 }
295 
296 static void opticon_shutdown(struct usb_serial *serial)
297 {
298 	struct opticon_private *priv = usb_get_serial_data(serial);
299 
300 	dbg("%s", __func__);
301 
302 	usb_kill_urb(priv->bulk_read_urb);
303 	usb_free_urb(priv->bulk_read_urb);
304 	kfree(priv->bulk_in_buffer);
305 	kfree(priv);
306 	usb_set_serial_data(serial, NULL);
307 }
308 
309 
310 static struct usb_driver opticon_driver = {
311 	.name =		"opticon",
312 	.probe =	usb_serial_probe,
313 	.disconnect =	usb_serial_disconnect,
314 	.id_table =	id_table,
315 	.no_dynamic_id = 	1,
316 };
317 
318 static struct usb_serial_driver opticon_device = {
319 	.driver = {
320 		.owner =	THIS_MODULE,
321 		.name =		"opticon",
322 	},
323 	.id_table =		id_table,
324 	.usb_driver = 		&opticon_driver,
325 	.num_ports =		1,
326 	.attach =		opticon_startup,
327 	.open =			opticon_open,
328 	.close =		opticon_close,
329 	.shutdown =		opticon_shutdown,
330 	.throttle = 		opticon_throttle,
331 	.unthrottle =		opticon_unthrottle,
332 };
333 
334 static int __init opticon_init(void)
335 {
336 	int retval;
337 
338 	retval = usb_serial_register(&opticon_device);
339 	if (retval)
340 		return retval;
341 	retval = usb_register(&opticon_driver);
342 	if (retval)
343 		usb_serial_deregister(&opticon_device);
344 	return retval;
345 }
346 
347 static void __exit opticon_exit(void)
348 {
349 	usb_deregister(&opticon_driver);
350 	usb_serial_deregister(&opticon_device);
351 }
352 
353 module_init(opticon_init);
354 module_exit(opticon_exit);
355 MODULE_LICENSE("GPL");
356 
357 module_param(debug, bool, S_IRUGO | S_IWUSR);
358 MODULE_PARM_DESC(debug, "Debug enabled or not");
359