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