xref: /openbmc/linux/drivers/usb/serial/safe_serial.c (revision 384740dc)
1 /*
2  * Safe Encapsulated USB Serial Driver
3  *
4  *      Copyright (C) 2001 Lineo
5  *      Copyright (C) 2001 Hewlett-Packard
6  *
7  *	This program is free software; you can redistribute it and/or modify
8  *	it under the terms of the GNU General Public License as published by
9  *	the Free Software Foundation; either version 2 of the License, or
10  *	(at your option) any later version.
11  *
12  * By:
13  *      Stuart Lynne <sl@lineo.com>, Tom Rushworth <tbr@lineo.com>
14  */
15 
16 /*
17  * The encapsultaion is designed to overcome difficulties with some USB
18  * hardware.
19  *
20  * While the USB protocol has a CRC over the data while in transit, i.e. while
21  * being carried over the bus, there is no end to end protection. If the
22  * hardware has any problems getting the data into or out of the USB transmit
23  * and receive FIFO's then data can be lost.
24  *
25  * This protocol adds a two byte trailer to each USB packet to specify the
26  * number of bytes of valid data and a 10 bit CRC that will allow the receiver
27  * to verify that the entire USB packet was received without error.
28  *
29  * Because in this case the sender and receiver are the class and function
30  * drivers there is now end to end protection.
31  *
32  * There is an additional option that can be used to force all transmitted
33  * packets to be padded to the maximum packet size. This provides a work
34  * around for some devices which have problems with small USB packets.
35  *
36  * Assuming a packetsize of N:
37  *
38  *      0..N-2  data and optional padding
39  *
40  *      N-2     bits 7-2 - number of bytes of valid data
41  *              bits 1-0 top two bits of 10 bit CRC
42  *      N-1     bottom 8 bits of 10 bit CRC
43  *
44  *
45  *      | Data Length       | 10 bit CRC                                |
46  *      + 7 . 6 . 5 . 4 . 3 . 2 . 1 . 0 | 7 . 6 . 5 . 4 . 3 . 2 . 1 . 0 +
47  *
48  * The 10 bit CRC is computed across the sent data, followed by the trailer
49  * with the length set and the CRC set to zero. The CRC is then OR'd into
50  * the trailer.
51  *
52  * When received a 10 bit CRC is computed over the entire frame including
53  * the trailer and should be equal to zero.
54  *
55  * Two module parameters are used to control the encapsulation, if both are
56  * turned of the module works as a simple serial device with NO
57  * encapsulation.
58  *
59  * See linux/drivers/usbd/serial_fd for a device function driver
60  * implementation of this.
61  *
62  */
63 
64 
65 #include <linux/kernel.h>
66 #include <linux/errno.h>
67 #include <linux/init.h>
68 #include <linux/slab.h>
69 #include <linux/tty.h>
70 #include <linux/tty_driver.h>
71 #include <linux/tty_flip.h>
72 #include <linux/module.h>
73 #include <linux/spinlock.h>
74 #include <linux/uaccess.h>
75 #include <linux/usb.h>
76 #include <linux/usb/serial.h>
77 
78 
79 #ifndef CONFIG_USB_SERIAL_SAFE_PADDED
80 #define CONFIG_USB_SERIAL_SAFE_PADDED 0
81 #endif
82 
83 static int debug;
84 static int safe = 1;
85 static int padded = CONFIG_USB_SERIAL_SAFE_PADDED;
86 
87 #define DRIVER_VERSION "v0.0b"
88 #define DRIVER_AUTHOR "sl@lineo.com, tbr@lineo.com"
89 #define DRIVER_DESC "USB Safe Encapsulated Serial"
90 
91 MODULE_AUTHOR(DRIVER_AUTHOR);
92 MODULE_DESCRIPTION(DRIVER_DESC);
93 MODULE_LICENSE("GPL");
94 
95 static __u16 vendor;		/* no default */
96 static __u16 product;		/* no default */
97 module_param(vendor, ushort, 0);
98 MODULE_PARM_DESC(vendor, "User specified USB idVendor (required)");
99 module_param(product, ushort, 0);
100 MODULE_PARM_DESC(product, "User specified USB idProduct (required)");
101 
102 module_param(debug, bool, S_IRUGO | S_IWUSR);
103 MODULE_PARM_DESC(debug, "Debug enabled or not");
104 
105 module_param(safe, bool, 0);
106 MODULE_PARM_DESC(safe, "Turn Safe Encapsulation On/Off");
107 
108 module_param(padded, bool, 0);
109 MODULE_PARM_DESC(padded, "Pad to full wMaxPacketSize On/Off");
110 
111 #define CDC_DEVICE_CLASS                        0x02
112 
113 #define CDC_INTERFACE_CLASS                     0x02
114 #define CDC_INTERFACE_SUBCLASS                  0x06
115 
116 #define LINEO_INTERFACE_CLASS                   0xff
117 
118 #define LINEO_INTERFACE_SUBCLASS_SAFENET        0x01
119 #define LINEO_SAFENET_CRC                       0x01
120 #define LINEO_SAFENET_CRC_PADDED                0x02
121 
122 #define LINEO_INTERFACE_SUBCLASS_SAFESERIAL     0x02
123 #define LINEO_SAFESERIAL_CRC                    0x01
124 #define LINEO_SAFESERIAL_CRC_PADDED             0x02
125 
126 
127 #define MY_USB_DEVICE(vend, prod, dc, ic, isc) \
128 	.match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
129 		       USB_DEVICE_ID_MATCH_DEV_CLASS | \
130 		       USB_DEVICE_ID_MATCH_INT_CLASS | \
131 		       USB_DEVICE_ID_MATCH_INT_SUBCLASS, \
132 	.idVendor = (vend), \
133 	.idProduct = (prod),\
134 	.bDeviceClass = (dc),\
135 	.bInterfaceClass = (ic), \
136 	.bInterfaceSubClass = (isc),
137 
138 static struct usb_device_id id_table[] = {
139 	{MY_USB_DEVICE(0x49f, 0xffff, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},	/* Itsy */
140 	{MY_USB_DEVICE(0x3f0, 0x2101, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},	/* Calypso */
141 	{MY_USB_DEVICE(0x4dd, 0x8001, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},	/* Iris */
142 	{MY_USB_DEVICE(0x4dd, 0x8002, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},	/* Collie */
143 	{MY_USB_DEVICE(0x4dd, 0x8003, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},	/* Collie */
144 	{MY_USB_DEVICE(0x4dd, 0x8004, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},	/* Collie */
145 	{MY_USB_DEVICE(0x5f9, 0xffff, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},	/* Sharp tmp */
146 	/* extra null entry for module vendor/produc parameters */
147 	{MY_USB_DEVICE(0, 0, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},
148 	{}			/* terminating entry  */
149 };
150 
151 MODULE_DEVICE_TABLE(usb, id_table);
152 
153 static struct usb_driver safe_driver = {
154 	.name =		"safe_serial",
155 	.probe =	usb_serial_probe,
156 	.disconnect =	usb_serial_disconnect,
157 	.id_table =	id_table,
158 	.no_dynamic_id = 	1,
159 };
160 
161 static const __u16 crc10_table[256] = {
162 	0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff,
163 	0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe,
164 	0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce,
165 	0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf,
166 	0x062, 0x251, 0x237, 0x004, 0x2fb, 0x0c8, 0x0ae, 0x29d,
167 	0x363, 0x150, 0x136, 0x305, 0x1fa, 0x3c9, 0x3af, 0x19c,
168 	0x053, 0x260, 0x206, 0x035, 0x2ca, 0x0f9, 0x09f, 0x2ac,
169 	0x352, 0x161, 0x107, 0x334, 0x1cb, 0x3f8, 0x39e, 0x1ad,
170 	0x0c4, 0x2f7, 0x291, 0x0a2, 0x25d, 0x06e, 0x008, 0x23b,
171 	0x3c5, 0x1f6, 0x190, 0x3a3, 0x15c, 0x36f, 0x309, 0x13a,
172 	0x0f5, 0x2c6, 0x2a0, 0x093, 0x26c, 0x05f, 0x039, 0x20a,
173 	0x3f4, 0x1c7, 0x1a1, 0x392, 0x16d, 0x35e, 0x338, 0x10b,
174 	0x0a6, 0x295, 0x2f3, 0x0c0, 0x23f, 0x00c, 0x06a, 0x259,
175 	0x3a7, 0x194, 0x1f2, 0x3c1, 0x13e, 0x30d, 0x36b, 0x158,
176 	0x097, 0x2a4, 0x2c2, 0x0f1, 0x20e, 0x03d, 0x05b, 0x268,
177 	0x396, 0x1a5, 0x1c3, 0x3f0, 0x10f, 0x33c, 0x35a, 0x169,
178 	0x188, 0x3bb, 0x3dd, 0x1ee, 0x311, 0x122, 0x144, 0x377,
179 	0x289, 0x0ba, 0x0dc, 0x2ef, 0x010, 0x223, 0x245, 0x076,
180 	0x1b9, 0x38a, 0x3ec, 0x1df, 0x320, 0x113, 0x175, 0x346,
181 	0x2b8, 0x08b, 0x0ed, 0x2de, 0x021, 0x212, 0x274, 0x047,
182 	0x1ea, 0x3d9, 0x3bf, 0x18c, 0x373, 0x140, 0x126, 0x315,
183 	0x2eb, 0x0d8, 0x0be, 0x28d, 0x072, 0x241, 0x227, 0x014,
184 	0x1db, 0x3e8, 0x38e, 0x1bd, 0x342, 0x171, 0x117, 0x324,
185 	0x2da, 0x0e9, 0x08f, 0x2bc, 0x043, 0x270, 0x216, 0x025,
186 	0x14c, 0x37f, 0x319, 0x12a, 0x3d5, 0x1e6, 0x180, 0x3b3,
187 	0x24d, 0x07e, 0x018, 0x22b, 0x0d4, 0x2e7, 0x281, 0x0b2,
188 	0x17d, 0x34e, 0x328, 0x11b, 0x3e4, 0x1d7, 0x1b1, 0x382,
189 	0x27c, 0x04f, 0x029, 0x21a, 0x0e5, 0x2d6, 0x2b0, 0x083,
190 	0x12e, 0x31d, 0x37b, 0x148, 0x3b7, 0x184, 0x1e2, 0x3d1,
191 	0x22f, 0x01c, 0x07a, 0x249, 0x0b6, 0x285, 0x2e3, 0x0d0,
192 	0x11f, 0x32c, 0x34a, 0x179, 0x386, 0x1b5, 0x1d3, 0x3e0,
193 	0x21e, 0x02d, 0x04b, 0x278, 0x087, 0x2b4, 0x2d2, 0x0e1,
194 };
195 
196 #define CRC10_INITFCS     0x000	/* Initial FCS value */
197 #define CRC10_GOODFCS     0x000	/* Good final FCS value */
198 #define CRC10_FCS(fcs, c) ((((fcs) << 8) & 0x3ff) ^ crc10_table[((fcs) >> 2) & 0xff] ^ (c))
199 
200 /**
201  * fcs_compute10 - memcpy and calculate 10 bit CRC across buffer
202  * @sp: pointer to buffer
203  * @len: number of bytes
204  * @fcs: starting FCS
205  *
206  * Perform a memcpy and calculate fcs using ppp 10bit CRC algorithm. Return
207  * new 10 bit FCS.
208  */
209 static __u16 __inline__ fcs_compute10(unsigned char *sp, int len, __u16 fcs)
210 {
211 	for (; len-- > 0; fcs = CRC10_FCS(fcs, *sp++));
212 	return fcs;
213 }
214 
215 static void safe_read_bulk_callback(struct urb *urb)
216 {
217 	struct usb_serial_port *port =  urb->context;
218 	unsigned char *data = urb->transfer_buffer;
219 	unsigned char length = urb->actual_length;
220 	int result;
221 	int status = urb->status;
222 
223 	dbg("%s", __func__);
224 
225 	if (status) {
226 		dbg("%s - nonzero read bulk status received: %d",
227 		    __func__, status);
228 		return;
229 	}
230 
231 	dbg("safe_read_bulk_callback length: %d",
232 					port->read_urb->actual_length);
233 #ifdef ECHO_RCV
234 	{
235 		int i;
236 		unsigned char *cp = port->read_urb->transfer_buffer;
237 		for (i = 0; i < port->read_urb->actual_length; i++) {
238 			if ((i % 32) == 0)
239 				printk("\nru[%02x] ", i);
240 			printk("%02x ", *cp++);
241 		}
242 		printk("\n");
243 	}
244 #endif
245 	if (safe) {
246 		__u16 fcs;
247 		fcs = fcs_compute10(data, length, CRC10_INITFCS);
248 		if (!fcs) {
249 			int actual_length = data[length - 2] >> 2;
250 			if (actual_length <= (length - 2)) {
251 				info("%s - actual: %d", __func__,
252 							actual_length);
253 				tty_insert_flip_string(port->port.tty,
254 							data, actual_length);
255 				tty_flip_buffer_push(port->port.tty);
256 			} else {
257 				err("%s - inconsistent lengths %d:%d",
258 					__func__, actual_length, length);
259 			}
260 		} else {
261 			err("%s - bad CRC %x", __func__, fcs);
262 		}
263 	} else {
264 		tty_insert_flip_string(port->port.tty, data, length);
265 		tty_flip_buffer_push(port->port.tty);
266 	}
267 
268 	/* Continue trying to always read  */
269 	usb_fill_bulk_urb(urb, port->serial->dev,
270 			usb_rcvbulkpipe(port->serial->dev,
271 					port->bulk_in_endpointAddress),
272 			urb->transfer_buffer, urb->transfer_buffer_length,
273 			safe_read_bulk_callback, port);
274 
275 	result = usb_submit_urb(urb, GFP_ATOMIC);
276 	if (result)
277 		err("%s - failed resubmitting read urb, error %d",
278 							__func__, result);
279 		/* FIXME: Need a mechanism to retry later if this happens */
280 }
281 
282 static int safe_write(struct tty_struct *tty, struct usb_serial_port *port,
283 					const unsigned char *buf, int count)
284 {
285 	unsigned char *data;
286 	int result;
287 	int i;
288 	int packet_length;
289 
290 	dbg("safe_write port: %p %d urb: %p count: %d",
291 				port, port->number, port->write_urb, count);
292 
293 	if (!port->write_urb) {
294 		dbg("%s - write urb NULL", __func__);
295 		return 0;
296 	}
297 
298 	dbg("safe_write write_urb: %d transfer_buffer_length",
299 	     port->write_urb->transfer_buffer_length);
300 
301 	if (!port->write_urb->transfer_buffer_length) {
302 		dbg("%s - write urb transfer_buffer_length zero", __func__);
303 		return 0;
304 	}
305 	if (count == 0) {
306 		dbg("%s - write request of 0 bytes", __func__);
307 		return 0;
308 	}
309 	spin_lock_bh(&port->lock);
310 	if (port->write_urb_busy) {
311 		spin_unlock_bh(&port->lock);
312 		dbg("%s - already writing", __func__);
313 		return 0;
314 	}
315 	port->write_urb_busy = 1;
316 	spin_unlock_bh(&port->lock);
317 
318 	packet_length = port->bulk_out_size;	/* get max packetsize */
319 
320 	i = packet_length - (safe ? 2 : 0);	/* get bytes to send */
321 	count = (count > i) ? i : count;
322 
323 
324 	/* get the data into the transfer buffer */
325 	data = port->write_urb->transfer_buffer;
326 	memset(data, '0', packet_length);
327 
328 	memcpy(data, buf, count);
329 
330 	if (safe) {
331 		__u16 fcs;
332 
333 		/* pad if necessary */
334 		if (!padded)
335 			packet_length = count + 2;
336 		/* set count */
337 		data[packet_length - 2] = count << 2;
338 		data[packet_length - 1] = 0;
339 
340 		/* compute fcs and insert into trailer */
341 		fcs = fcs_compute10(data, packet_length, CRC10_INITFCS);
342 		data[packet_length - 2] |= fcs >> 8;
343 		data[packet_length - 1] |= fcs & 0xff;
344 
345 		/* set length to send */
346 		port->write_urb->transfer_buffer_length = packet_length;
347 	} else {
348 		port->write_urb->transfer_buffer_length = count;
349 	}
350 
351 	usb_serial_debug_data(debug, &port->dev, __func__, count,
352 					port->write_urb->transfer_buffer);
353 #ifdef ECHO_TX
354 	{
355 		int i;
356 		unsigned char *cp = port->write_urb->transfer_buffer;
357 		for (i = 0; i < port->write_urb->transfer_buffer_length; i++) {
358 			if ((i % 32) == 0)
359 				printk("\nsu[%02x] ", i);
360 			printk("%02x ", *cp++);
361 		}
362 		printk("\n");
363 	}
364 #endif
365 	port->write_urb->dev = port->serial->dev;
366 	result = usb_submit_urb(port->write_urb, GFP_KERNEL);
367 	if (result) {
368 		port->write_urb_busy = 0;
369 		err("%s - failed submitting write urb, error %d",
370 							__func__, result);
371 		return 0;
372 	}
373 	dbg("%s urb: %p submitted", __func__, port->write_urb);
374 
375 	return count;
376 }
377 
378 static int safe_write_room(struct tty_struct *tty)
379 {
380 	struct usb_serial_port *port = tty->driver_data;
381 	int room = 0;		/* Default: no room */
382 	unsigned long flags;
383 
384 	dbg("%s", __func__);
385 
386 	spin_lock_irqsave(&port->lock, flags);
387 	if (port->write_urb_busy)
388 		room = port->bulk_out_size - (safe ? 2 : 0);
389 	spin_unlock_irqrestore(&port->lock, flags);
390 
391 	if (room)
392 		dbg("safe_write_room returns %d", room);
393 	return room;
394 }
395 
396 static int safe_startup(struct usb_serial *serial)
397 {
398 	switch (serial->interface->cur_altsetting->desc.bInterfaceProtocol) {
399 	case LINEO_SAFESERIAL_CRC:
400 		break;
401 	case LINEO_SAFESERIAL_CRC_PADDED:
402 		padded = 1;
403 		break;
404 	default:
405 		return -EINVAL;
406 	}
407 	return 0;
408 }
409 
410 static struct usb_serial_driver safe_device = {
411 	.driver = {
412 		.owner =	THIS_MODULE,
413 		.name =		"safe_serial",
414 	},
415 	.id_table =		id_table,
416 	.usb_driver =		&safe_driver,
417 	.num_ports =		1,
418 	.write =		safe_write,
419 	.write_room =		safe_write_room,
420 	.read_bulk_callback =	safe_read_bulk_callback,
421 	.attach =		safe_startup,
422 };
423 
424 static int __init safe_init(void)
425 {
426 	int i, retval;
427 
428 	info(DRIVER_VERSION " " DRIVER_AUTHOR);
429 	info(DRIVER_DESC);
430 	info("vendor: %x product: %x safe: %d padded: %d\n",
431 					vendor, product, safe, padded);
432 
433 	/* if we have vendor / product parameters patch them into id list */
434 	if (vendor || product) {
435 		info("vendor: %x product: %x\n", vendor, product);
436 
437 		for (i = 0; i < ARRAY_SIZE(id_table); i++) {
438 			if (!id_table[i].idVendor && !id_table[i].idProduct) {
439 				id_table[i].idVendor = vendor;
440 				id_table[i].idProduct = product;
441 				break;
442 			}
443 		}
444 	}
445 
446 	retval = usb_serial_register(&safe_device);
447 	if (retval)
448 		goto failed_usb_serial_register;
449 	retval = usb_register(&safe_driver);
450 	if (retval)
451 		goto failed_usb_register;
452 
453 	return 0;
454 failed_usb_register:
455 	usb_serial_deregister(&safe_device);
456 failed_usb_serial_register:
457 	return retval;
458 }
459 
460 static void __exit safe_exit(void)
461 {
462 	usb_deregister(&safe_driver);
463 	usb_serial_deregister(&safe_device);
464 }
465 
466 module_init(safe_init);
467 module_exit(safe_exit);
468