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