xref: /linux/drivers/usb/serial/safe_serial.c (revision a5766f11cfd3a0c03450d99c8fe548c2940be884)
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 	struct tty_struct *tty;
221 	int result;
222 	int status = urb->status;
223 
224 	dbg("%s", __func__);
225 
226 	if (status) {
227 		dbg("%s - nonzero read bulk status received: %d",
228 		    __func__, status);
229 		return;
230 	}
231 
232 	dbg("safe_read_bulk_callback length: %d",
233 					port->read_urb->actual_length);
234 #ifdef ECHO_RCV
235 	{
236 		int i;
237 		unsigned char *cp = port->read_urb->transfer_buffer;
238 		for (i = 0; i < port->read_urb->actual_length; i++) {
239 			if ((i % 32) == 0)
240 				printk("\nru[%02x] ", i);
241 			printk("%02x ", *cp++);
242 		}
243 		printk("\n");
244 	}
245 #endif
246 	tty = tty_port_tty_get(&port->port);
247 	if (safe) {
248 		__u16 fcs;
249 		fcs = fcs_compute10(data, length, CRC10_INITFCS);
250 		if (!fcs) {
251 			int actual_length = data[length - 2] >> 2;
252 			if (actual_length <= (length - 2)) {
253 				info("%s - actual: %d", __func__,
254 							actual_length);
255 				tty_insert_flip_string(tty,
256 							data, actual_length);
257 				tty_flip_buffer_push(tty);
258 			} else {
259 				err("%s - inconsistent lengths %d:%d",
260 					__func__, actual_length, length);
261 			}
262 		} else {
263 			err("%s - bad CRC %x", __func__, fcs);
264 		}
265 	} else {
266 		tty_insert_flip_string(tty, data, length);
267 		tty_flip_buffer_push(tty);
268 	}
269 	tty_kref_put(tty);
270 
271 	/* Continue trying to always read  */
272 	usb_fill_bulk_urb(urb, port->serial->dev,
273 			usb_rcvbulkpipe(port->serial->dev,
274 					port->bulk_in_endpointAddress),
275 			urb->transfer_buffer, urb->transfer_buffer_length,
276 			safe_read_bulk_callback, port);
277 
278 	result = usb_submit_urb(urb, GFP_ATOMIC);
279 	if (result)
280 		err("%s - failed resubmitting read urb, error %d",
281 							__func__, result);
282 		/* FIXME: Need a mechanism to retry later if this happens */
283 }
284 
285 static int safe_write(struct tty_struct *tty, struct usb_serial_port *port,
286 					const unsigned char *buf, int count)
287 {
288 	unsigned char *data;
289 	int result;
290 	int i;
291 	int packet_length;
292 
293 	dbg("safe_write port: %p %d urb: %p count: %d",
294 				port, port->number, port->write_urb, count);
295 
296 	if (!port->write_urb) {
297 		dbg("%s - write urb NULL", __func__);
298 		return 0;
299 	}
300 
301 	dbg("safe_write write_urb: %d transfer_buffer_length",
302 	     port->write_urb->transfer_buffer_length);
303 
304 	if (!port->write_urb->transfer_buffer_length) {
305 		dbg("%s - write urb transfer_buffer_length zero", __func__);
306 		return 0;
307 	}
308 	if (count == 0) {
309 		dbg("%s - write request of 0 bytes", __func__);
310 		return 0;
311 	}
312 	spin_lock_bh(&port->lock);
313 	if (port->write_urb_busy) {
314 		spin_unlock_bh(&port->lock);
315 		dbg("%s - already writing", __func__);
316 		return 0;
317 	}
318 	port->write_urb_busy = 1;
319 	spin_unlock_bh(&port->lock);
320 
321 	packet_length = port->bulk_out_size;	/* get max packetsize */
322 
323 	i = packet_length - (safe ? 2 : 0);	/* get bytes to send */
324 	count = (count > i) ? i : count;
325 
326 
327 	/* get the data into the transfer buffer */
328 	data = port->write_urb->transfer_buffer;
329 	memset(data, '0', packet_length);
330 
331 	memcpy(data, buf, count);
332 
333 	if (safe) {
334 		__u16 fcs;
335 
336 		/* pad if necessary */
337 		if (!padded)
338 			packet_length = count + 2;
339 		/* set count */
340 		data[packet_length - 2] = count << 2;
341 		data[packet_length - 1] = 0;
342 
343 		/* compute fcs and insert into trailer */
344 		fcs = fcs_compute10(data, packet_length, CRC10_INITFCS);
345 		data[packet_length - 2] |= fcs >> 8;
346 		data[packet_length - 1] |= fcs & 0xff;
347 
348 		/* set length to send */
349 		port->write_urb->transfer_buffer_length = packet_length;
350 	} else {
351 		port->write_urb->transfer_buffer_length = count;
352 	}
353 
354 	usb_serial_debug_data(debug, &port->dev, __func__, count,
355 					port->write_urb->transfer_buffer);
356 #ifdef ECHO_TX
357 	{
358 		int i;
359 		unsigned char *cp = port->write_urb->transfer_buffer;
360 		for (i = 0; i < port->write_urb->transfer_buffer_length; i++) {
361 			if ((i % 32) == 0)
362 				printk("\nsu[%02x] ", i);
363 			printk("%02x ", *cp++);
364 		}
365 		printk("\n");
366 	}
367 #endif
368 	port->write_urb->dev = port->serial->dev;
369 	result = usb_submit_urb(port->write_urb, GFP_KERNEL);
370 	if (result) {
371 		port->write_urb_busy = 0;
372 		err("%s - failed submitting write urb, error %d",
373 							__func__, result);
374 		return 0;
375 	}
376 	dbg("%s urb: %p submitted", __func__, port->write_urb);
377 
378 	return count;
379 }
380 
381 static int safe_write_room(struct tty_struct *tty)
382 {
383 	struct usb_serial_port *port = tty->driver_data;
384 	int room = 0;		/* Default: no room */
385 	unsigned long flags;
386 
387 	dbg("%s", __func__);
388 
389 	spin_lock_irqsave(&port->lock, flags);
390 	if (port->write_urb_busy)
391 		room = port->bulk_out_size - (safe ? 2 : 0);
392 	spin_unlock_irqrestore(&port->lock, flags);
393 
394 	if (room)
395 		dbg("safe_write_room returns %d", room);
396 	return room;
397 }
398 
399 static int safe_startup(struct usb_serial *serial)
400 {
401 	switch (serial->interface->cur_altsetting->desc.bInterfaceProtocol) {
402 	case LINEO_SAFESERIAL_CRC:
403 		break;
404 	case LINEO_SAFESERIAL_CRC_PADDED:
405 		padded = 1;
406 		break;
407 	default:
408 		return -EINVAL;
409 	}
410 	return 0;
411 }
412 
413 static struct usb_serial_driver safe_device = {
414 	.driver = {
415 		.owner =	THIS_MODULE,
416 		.name =		"safe_serial",
417 	},
418 	.id_table =		id_table,
419 	.usb_driver =		&safe_driver,
420 	.num_ports =		1,
421 	.write =		safe_write,
422 	.write_room =		safe_write_room,
423 	.read_bulk_callback =	safe_read_bulk_callback,
424 	.attach =		safe_startup,
425 };
426 
427 static int __init safe_init(void)
428 {
429 	int i, retval;
430 
431 	info(DRIVER_VERSION " " DRIVER_AUTHOR);
432 	info(DRIVER_DESC);
433 	info("vendor: %x product: %x safe: %d padded: %d\n",
434 					vendor, product, safe, padded);
435 
436 	/* if we have vendor / product parameters patch them into id list */
437 	if (vendor || product) {
438 		info("vendor: %x product: %x\n", vendor, product);
439 
440 		for (i = 0; i < ARRAY_SIZE(id_table); i++) {
441 			if (!id_table[i].idVendor && !id_table[i].idProduct) {
442 				id_table[i].idVendor = vendor;
443 				id_table[i].idProduct = product;
444 				break;
445 			}
446 		}
447 	}
448 
449 	retval = usb_serial_register(&safe_device);
450 	if (retval)
451 		goto failed_usb_serial_register;
452 	retval = usb_register(&safe_driver);
453 	if (retval)
454 		goto failed_usb_register;
455 
456 	return 0;
457 failed_usb_register:
458 	usb_serial_deregister(&safe_device);
459 failed_usb_serial_register:
460 	return retval;
461 }
462 
463 static void __exit safe_exit(void)
464 {
465 	usb_deregister(&safe_driver);
466 	usb_serial_deregister(&safe_device);
467 }
468 
469 module_init(safe_init);
470 module_exit(safe_exit);
471