linux/drivers/usb/serial/aircable.c
<<
>>
Prefs
   1/*
   2 * AIRcable USB Bluetooth Dongle Driver.
   3 *
   4 * Copyright (C) 2006 Manuel Francisco Naranjo (naranjo.manuel@gmail.com)
   5 * This program is free software; you can redistribute it and/or modify it under
   6 * the terms of the GNU General Public License version 2 as published by the
   7 * Free Software Foundation.
   8 *
   9 * The device works as an standard CDC device, it has 2 interfaces, the first
  10 * one is for firmware access and the second is the serial one.
  11 * The protocol is very simply, there are two posibilities reading or writing.
  12 * When writing the first urb must have a Header that starts with 0x20 0x29 the
  13 * next two bytes must say how much data will be sended.
  14 * When reading the process is almost equal except that the header starts with
  15 * 0x00 0x20.
  16 *
  17 * The device simply need some stuff to understand data comming from the usb
  18 * buffer: The First and Second byte is used for a Header, the Third and Fourth
  19 * tells the  device the amount of information the package holds.
  20 * Packages are 60 bytes long Header Stuff.
  21 * When writing to the device the first two bytes of the header are 0x20 0x29
  22 * When reading the bytes are 0x00 0x20, or 0x00 0x10, there is an strange
  23 * situation, when too much data arrives to the device because it sends the data
  24 * but with out the header. I will use a simply hack to override this situation,
  25 * if there is data coming that does not contain any header, then that is data
  26 * that must go directly to the tty, as there is no documentation about if there
  27 * is any other control code, I will simply check for the first
  28 * one.
  29 *
  30 * The driver registers himself with the USB-serial core and the USB Core. I had
  31 * to implement a probe function agains USB-serial, because other way, the
  32 * driver was attaching himself to both interfaces. I have tryed with different
  33 * configurations of usb_serial_driver with out exit, only the probe function
  34 * could handle this correctly.
  35 *
  36 * I have taken some info from a Greg Kroah-Hartman article:
  37 * http://www.linuxjournal.com/article/6573
  38 * And from Linux Device Driver Kit CD, which is a great work, the authors taken
  39 * the work to recompile lots of information an knowladge in drivers development
  40 * and made it all avaible inside a cd.
  41 * URL: http://kernel.org/pub/linux/kernel/people/gregkh/ddk/
  42 *
  43 */
  44
  45#include <linux/tty.h>
  46#include <linux/tty_flip.h>
  47#include <linux/circ_buf.h>
  48#include <linux/usb.h>
  49#include <linux/usb/serial.h>
  50
  51static int debug;
  52
  53/* Vendor and Product ID */
  54#define AIRCABLE_VID            0x16CA
  55#define AIRCABLE_USB_PID        0x1502
  56
  57/* write buffer size defines */
  58#define AIRCABLE_BUF_SIZE       2048
  59
  60/* Protocol Stuff */
  61#define HCI_HEADER_LENGTH       0x4
  62#define TX_HEADER_0             0x20
  63#define TX_HEADER_1             0x29
  64#define RX_HEADER_0             0x00
  65#define RX_HEADER_1             0x20
  66#define MAX_HCI_FRAMESIZE       60
  67#define HCI_COMPLETE_FRAME      64
  68
  69/* rx_flags */
  70#define THROTTLED               0x01
  71#define ACTUALLY_THROTTLED      0x02
  72
  73/*
  74 * Version Information
  75 */
  76#define DRIVER_VERSION "v1.0b2"
  77#define DRIVER_AUTHOR "Naranjo, Manuel Francisco <naranjo.manuel@gmail.com>"
  78#define DRIVER_DESC "AIRcable USB Driver"
  79
  80/* ID table that will be registered with USB core */
  81static struct usb_device_id id_table [] = {
  82        { USB_DEVICE(AIRCABLE_VID, AIRCABLE_USB_PID) },
  83        { },
  84};
  85MODULE_DEVICE_TABLE(usb, id_table);
  86
  87
  88/* Internal Structure */
  89struct aircable_private {
  90        spinlock_t rx_lock;             /* spinlock for the receive lines */
  91        struct circ_buf *tx_buf;        /* write buffer */
  92        struct circ_buf *rx_buf;        /* read buffer */
  93        int rx_flags;                   /* for throttilng */
  94        struct work_struct rx_work;     /* work cue for the receiving line */
  95        struct usb_serial_port *port;   /* USB port with which associated */
  96};
  97
  98/* Private methods */
  99
 100/* Circular Buffer Methods, code from ti_usb_3410_5052 used */
 101/*
 102 * serial_buf_clear
 103 *
 104 * Clear out all data in the circular buffer.
 105 */
 106static void serial_buf_clear(struct circ_buf *cb)
 107{
 108        cb->head = cb->tail = 0;
 109}
 110
 111/*
 112 * serial_buf_alloc
 113 *
 114 * Allocate a circular buffer and all associated memory.
 115 */
 116static struct circ_buf *serial_buf_alloc(void)
 117{
 118        struct circ_buf *cb;
 119        cb = kmalloc(sizeof(struct circ_buf), GFP_KERNEL);
 120        if (cb == NULL)
 121                return NULL;
 122        cb->buf = kmalloc(AIRCABLE_BUF_SIZE, GFP_KERNEL);
 123        if (cb->buf == NULL) {
 124                kfree(cb);
 125                return NULL;
 126        }
 127        serial_buf_clear(cb);
 128        return cb;
 129}
 130
 131/*
 132 * serial_buf_free
 133 *
 134 * Free the buffer and all associated memory.
 135 */
 136static void serial_buf_free(struct circ_buf *cb)
 137{
 138        kfree(cb->buf);
 139        kfree(cb);
 140}
 141
 142/*
 143 * serial_buf_data_avail
 144 *
 145 * Return the number of bytes of data available in the circular
 146 * buffer.
 147 */
 148static int serial_buf_data_avail(struct circ_buf *cb)
 149{
 150        return CIRC_CNT(cb->head, cb->tail, AIRCABLE_BUF_SIZE);
 151}
 152
 153/*
 154 * serial_buf_put
 155 *
 156 * Copy data data from a user buffer and put it into the circular buffer.
 157 * Restrict to the amount of space available.
 158 *
 159 * Return the number of bytes copied.
 160 */
 161static int serial_buf_put(struct circ_buf *cb, const char *buf, int count)
 162{
 163        int c, ret = 0;
 164        while (1) {
 165                c = CIRC_SPACE_TO_END(cb->head, cb->tail, AIRCABLE_BUF_SIZE);
 166                if (count < c)
 167                        c = count;
 168                if (c <= 0)
 169                        break;
 170                memcpy(cb->buf + cb->head, buf, c);
 171                cb->head = (cb->head + c) & (AIRCABLE_BUF_SIZE-1);
 172                buf += c;
 173                count -= c;
 174                ret = c;
 175        }
 176        return ret;
 177}
 178
 179/*
 180 * serial_buf_get
 181 *
 182 * Get data from the circular buffer and copy to the given buffer.
 183 * Restrict to the amount of data available.
 184 *
 185 * Return the number of bytes copied.
 186 */
 187static int serial_buf_get(struct circ_buf *cb, char *buf, int count)
 188{
 189        int c, ret = 0;
 190        while (1) {
 191                c = CIRC_CNT_TO_END(cb->head, cb->tail, AIRCABLE_BUF_SIZE);
 192                if (count < c)
 193                        c = count;
 194                if (c <= 0)
 195                        break;
 196                memcpy(buf, cb->buf + cb->tail, c);
 197                cb->tail = (cb->tail + c) & (AIRCABLE_BUF_SIZE-1);
 198                buf += c;
 199                count -= c;
 200                ret = c;
 201        }
 202        return ret;
 203}
 204
 205/* End of circula buffer methods */
 206
 207static void aircable_send(struct usb_serial_port *port)
 208{
 209        int count, result;
 210        struct aircable_private *priv = usb_get_serial_port_data(port);
 211        unsigned char *buf;
 212        __le16 *dbuf;
 213        dbg("%s - port %d", __func__, port->number);
 214        if (port->write_urb_busy)
 215                return;
 216
 217        count = min(serial_buf_data_avail(priv->tx_buf), MAX_HCI_FRAMESIZE);
 218        if (count == 0)
 219                return;
 220
 221        buf = kzalloc(count + HCI_HEADER_LENGTH, GFP_ATOMIC);
 222        if (!buf) {
 223                dev_err(&port->dev, "%s- kzalloc(%d) failed.\n",
 224                        __func__, count + HCI_HEADER_LENGTH);
 225                return;
 226        }
 227
 228        buf[0] = TX_HEADER_0;
 229        buf[1] = TX_HEADER_1;
 230        dbuf = (__le16 *)&buf[2];
 231        *dbuf = cpu_to_le16((u16)count);
 232        serial_buf_get(priv->tx_buf, buf + HCI_HEADER_LENGTH,
 233                                                        MAX_HCI_FRAMESIZE);
 234
 235        memcpy(port->write_urb->transfer_buffer, buf,
 236               count + HCI_HEADER_LENGTH);
 237
 238        kfree(buf);
 239        port->write_urb_busy = 1;
 240        usb_serial_debug_data(debug, &port->dev, __func__,
 241                              count + HCI_HEADER_LENGTH,
 242                              port->write_urb->transfer_buffer);
 243        port->write_urb->transfer_buffer_length = count + HCI_HEADER_LENGTH;
 244        port->write_urb->dev = port->serial->dev;
 245        result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
 246
 247        if (result) {
 248                dev_err(&port->dev,
 249                        "%s - failed submitting write urb, error %d\n",
 250                        __func__, result);
 251                port->write_urb_busy = 0;
 252        }
 253
 254        schedule_work(&port->work);
 255}
 256
 257static void aircable_read(struct work_struct *work)
 258{
 259        struct aircable_private *priv =
 260                container_of(work, struct aircable_private, rx_work);
 261        struct usb_serial_port *port = priv->port;
 262        struct tty_struct *tty;
 263        unsigned char *data;
 264        int count;
 265        if (priv->rx_flags & THROTTLED) {
 266                if (priv->rx_flags & ACTUALLY_THROTTLED)
 267                        schedule_work(&priv->rx_work);
 268                return;
 269        }
 270
 271        /* By now I will flush data to the tty in packages of no more than
 272         * 64 bytes, to ensure I do not get throttled.
 273         * Ask USB mailing list for better aproach.
 274         */
 275        tty = tty_port_tty_get(&port->port);
 276
 277        if (!tty) {
 278                schedule_work(&priv->rx_work);
 279                dev_err(&port->dev, "%s - No tty available\n", __func__);
 280                return ;
 281        }
 282
 283        count = min(64, serial_buf_data_avail(priv->rx_buf));
 284
 285        if (count <= 0)
 286                goto out; /* We have finished sending everything. */
 287
 288        tty_prepare_flip_string(tty, &data, count);
 289        if (!data) {
 290                dev_err(&port->dev, "%s- kzalloc(%d) failed.",
 291                                                        __func__, count);
 292                goto out;
 293        }
 294
 295        serial_buf_get(priv->rx_buf, data, count);
 296
 297        tty_flip_buffer_push(tty);
 298
 299        if (serial_buf_data_avail(priv->rx_buf))
 300                schedule_work(&priv->rx_work);
 301out:            
 302        tty_kref_put(tty);
 303        return;
 304}
 305/* End of private methods */
 306
 307static int aircable_probe(struct usb_serial *serial,
 308                          const struct usb_device_id *id)
 309{
 310        struct usb_host_interface *iface_desc = serial->interface->
 311                                                                cur_altsetting;
 312        struct usb_endpoint_descriptor *endpoint;
 313        int num_bulk_out = 0;
 314        int i;
 315
 316        for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
 317                endpoint = &iface_desc->endpoint[i].desc;
 318                if (usb_endpoint_is_bulk_out(endpoint)) {
 319                        dbg("found bulk out on endpoint %d", i);
 320                        ++num_bulk_out;
 321                }
 322        }
 323
 324        if (num_bulk_out == 0) {
 325                dbg("Invalid interface, discarding");
 326                return -ENODEV;
 327        }
 328
 329        return 0;
 330}
 331
 332static int aircable_attach(struct usb_serial *serial)
 333{
 334        struct usb_serial_port *port = serial->port[0];
 335        struct aircable_private *priv;
 336
 337        priv = kzalloc(sizeof(struct aircable_private), GFP_KERNEL);
 338        if (!priv) {
 339                dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", __func__,
 340                        sizeof(struct aircable_private));
 341                return -ENOMEM;
 342        }
 343
 344        /* Allocation of Circular Buffers */
 345        priv->tx_buf = serial_buf_alloc();
 346        if (priv->tx_buf == NULL) {
 347                kfree(priv);
 348                return -ENOMEM;
 349        }
 350
 351        priv->rx_buf = serial_buf_alloc();
 352        if (priv->rx_buf == NULL) {
 353                kfree(priv->tx_buf);
 354                kfree(priv);
 355                return -ENOMEM;
 356        }
 357
 358        priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED);
 359        priv->port = port;
 360        INIT_WORK(&priv->rx_work, aircable_read);
 361
 362        usb_set_serial_port_data(serial->port[0], priv);
 363
 364        return 0;
 365}
 366
 367static void aircable_release(struct usb_serial *serial)
 368{
 369
 370        struct usb_serial_port *port = serial->port[0];
 371        struct aircable_private *priv = usb_get_serial_port_data(port);
 372
 373        dbg("%s", __func__);
 374
 375        if (priv) {
 376                serial_buf_free(priv->tx_buf);
 377                serial_buf_free(priv->rx_buf);
 378                kfree(priv);
 379        }
 380}
 381
 382static int aircable_write_room(struct tty_struct *tty)
 383{
 384        struct usb_serial_port *port = tty->driver_data;
 385        struct aircable_private *priv = usb_get_serial_port_data(port);
 386        return serial_buf_data_avail(priv->tx_buf);
 387}
 388
 389static int aircable_write(struct tty_struct *tty, struct usb_serial_port *port,
 390                          const unsigned char *source, int count)
 391{
 392        struct aircable_private *priv = usb_get_serial_port_data(port);
 393        int temp;
 394
 395        dbg("%s - port %d, %d bytes", __func__, port->number, count);
 396
 397        usb_serial_debug_data(debug, &port->dev, __func__, count, source);
 398
 399        if (!count) {
 400                dbg("%s - write request of 0 bytes", __func__);
 401                return count;
 402        }
 403
 404        temp = serial_buf_put(priv->tx_buf, source, count);
 405
 406        aircable_send(port);
 407
 408        if (count > AIRCABLE_BUF_SIZE)
 409                count = AIRCABLE_BUF_SIZE;
 410
 411        return count;
 412
 413}
 414
 415static void aircable_write_bulk_callback(struct urb *urb)
 416{
 417        struct usb_serial_port *port = urb->context;
 418        int status = urb->status;
 419        int result;
 420
 421        dbg("%s - urb status: %d", __func__ , status);
 422
 423        /* This has been taken from cypress_m8.c cypress_write_int_callback */
 424        switch (status) {
 425        case 0:
 426                /* success */
 427                break;
 428        case -ECONNRESET:
 429        case -ENOENT:
 430        case -ESHUTDOWN:
 431                /* this urb is terminated, clean up */
 432                dbg("%s - urb shutting down with status: %d",
 433                    __func__, status);
 434                port->write_urb_busy = 0;
 435                return;
 436        default:
 437                /* error in the urb, so we have to resubmit it */
 438                dbg("%s - Overflow in write", __func__);
 439                dbg("%s - nonzero write bulk status received: %d",
 440                    __func__, status);
 441                port->write_urb->transfer_buffer_length = 1;
 442                port->write_urb->dev = port->serial->dev;
 443                result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
 444                if (result)
 445                        dev_err(&urb->dev->dev,
 446                            "%s - failed resubmitting write urb, error %d\n",
 447                                                        __func__, result);
 448                else
 449                        return;
 450        }
 451
 452        port->write_urb_busy = 0;
 453
 454        aircable_send(port);
 455}
 456
 457static void aircable_read_bulk_callback(struct urb *urb)
 458{
 459        struct usb_serial_port *port = urb->context;
 460        struct aircable_private *priv = usb_get_serial_port_data(port);
 461        struct tty_struct *tty;
 462        unsigned long no_packages, remaining, package_length, i;
 463        int result, shift = 0;
 464        unsigned char *temp;
 465        int status = urb->status;
 466
 467        dbg("%s - port %d", __func__, port->number);
 468
 469        if (status) {
 470                dbg("%s - urb status = %d", __func__, status);
 471                if (!port->port.count) {
 472                        dbg("%s - port is closed, exiting.", __func__);
 473                        return;
 474                }
 475                if (status == -EPROTO) {
 476                        dbg("%s - caught -EPROTO, resubmitting the urb",
 477                            __func__);
 478                        usb_fill_bulk_urb(port->read_urb, port->serial->dev,
 479                                usb_rcvbulkpipe(port->serial->dev,
 480                                        port->bulk_in_endpointAddress),
 481                                port->read_urb->transfer_buffer,
 482                                port->read_urb->transfer_buffer_length,
 483                                aircable_read_bulk_callback, port);
 484
 485                        result = usb_submit_urb(urb, GFP_ATOMIC);
 486                        if (result)
 487                                dev_err(&urb->dev->dev,
 488                                        "%s - failed resubmitting read urb, error %d\n",
 489                                        __func__, result);
 490                        return;
 491                }
 492                dbg("%s - unable to handle the error, exiting.", __func__);
 493                return;
 494        }
 495
 496        usb_serial_debug_data(debug, &port->dev, __func__,
 497                                urb->actual_length, urb->transfer_buffer);
 498
 499        tty = tty_port_tty_get(&port->port);
 500        if (tty && urb->actual_length) {
 501                if (urb->actual_length <= 2) {
 502                        /* This is an incomplete package */
 503                        serial_buf_put(priv->rx_buf, urb->transfer_buffer,
 504                                       urb->actual_length);
 505                } else {
 506                        temp = urb->transfer_buffer;
 507                        if (temp[0] == RX_HEADER_0)
 508                                shift = HCI_HEADER_LENGTH;
 509
 510                        remaining = urb->actual_length;
 511                        no_packages = urb->actual_length / (HCI_COMPLETE_FRAME);
 512
 513                        if (urb->actual_length % HCI_COMPLETE_FRAME != 0)
 514                                no_packages++;
 515
 516                        for (i = 0; i < no_packages; i++) {
 517                                if (remaining > (HCI_COMPLETE_FRAME))
 518                                        package_length = HCI_COMPLETE_FRAME;
 519                                else
 520                                        package_length = remaining;
 521                                remaining -= package_length;
 522
 523                                serial_buf_put(priv->rx_buf,
 524                                        urb->transfer_buffer + shift +
 525                                        (HCI_COMPLETE_FRAME) * (i),
 526                                        package_length - shift);
 527                        }
 528                }
 529                aircable_read(&priv->rx_work);
 530        }
 531        tty_kref_put(tty);
 532
 533        /* Schedule the next read _if_ we are still open */
 534        if (port->port.count) {
 535                usb_fill_bulk_urb(port->read_urb, port->serial->dev,
 536                                  usb_rcvbulkpipe(port->serial->dev,
 537                                          port->bulk_in_endpointAddress),
 538                                  port->read_urb->transfer_buffer,
 539                                  port->read_urb->transfer_buffer_length,
 540                                  aircable_read_bulk_callback, port);
 541
 542                result = usb_submit_urb(urb, GFP_ATOMIC);
 543                if (result)
 544                        dev_err(&urb->dev->dev,
 545                                "%s - failed resubmitting read urb, error %d\n",
 546                                __func__, result);
 547        }
 548
 549        return;
 550}
 551
 552/* Based on ftdi_sio.c throttle */
 553static void aircable_throttle(struct tty_struct *tty)
 554{
 555        struct usb_serial_port *port = tty->driver_data;
 556        struct aircable_private *priv = usb_get_serial_port_data(port);
 557
 558        dbg("%s - port %d", __func__, port->number);
 559
 560        spin_lock_irq(&priv->rx_lock);
 561        priv->rx_flags |= THROTTLED;
 562        spin_unlock_irq(&priv->rx_lock);
 563}
 564
 565/* Based on ftdi_sio.c unthrottle */
 566static void aircable_unthrottle(struct tty_struct *tty)
 567{
 568        struct usb_serial_port *port = tty->driver_data;
 569        struct aircable_private *priv = usb_get_serial_port_data(port);
 570        int actually_throttled;
 571
 572        dbg("%s - port %d", __func__, port->number);
 573
 574        spin_lock_irq(&priv->rx_lock);
 575        actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED;
 576        priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED);
 577        spin_unlock_irq(&priv->rx_lock);
 578
 579        if (actually_throttled)
 580                schedule_work(&priv->rx_work);
 581}
 582
 583static struct usb_driver aircable_driver = {
 584        .name =         "aircable",
 585        .probe =        usb_serial_probe,
 586        .disconnect =   usb_serial_disconnect,
 587        .id_table =     id_table,
 588        .no_dynamic_id =        1,
 589};
 590
 591static struct usb_serial_driver aircable_device = {
 592        .driver = {
 593                .owner =        THIS_MODULE,
 594                .name =         "aircable",
 595        },
 596        .usb_driver =           &aircable_driver,
 597        .id_table =             id_table,
 598        .num_ports =            1,
 599        .attach =               aircable_attach,
 600        .probe =                aircable_probe,
 601        .release =              aircable_release,
 602        .write =                aircable_write,
 603        .write_room =           aircable_write_room,
 604        .write_bulk_callback =  aircable_write_bulk_callback,
 605        .read_bulk_callback =   aircable_read_bulk_callback,
 606        .throttle =             aircable_throttle,
 607        .unthrottle =           aircable_unthrottle,
 608};
 609
 610static int __init aircable_init(void)
 611{
 612        int retval;
 613        retval = usb_serial_register(&aircable_device);
 614        if (retval)
 615                goto failed_serial_register;
 616        retval = usb_register(&aircable_driver);
 617        if (retval)
 618                goto failed_usb_register;
 619        return 0;
 620
 621failed_usb_register:
 622        usb_serial_deregister(&aircable_device);
 623failed_serial_register:
 624        return retval;
 625}
 626
 627static void __exit aircable_exit(void)
 628{
 629        usb_deregister(&aircable_driver);
 630        usb_serial_deregister(&aircable_device);
 631}
 632
 633MODULE_AUTHOR(DRIVER_AUTHOR);
 634MODULE_DESCRIPTION(DRIVER_DESC);
 635MODULE_VERSION(DRIVER_VERSION);
 636MODULE_LICENSE("GPL");
 637
 638module_init(aircable_init);
 639module_exit(aircable_exit);
 640
 641module_param(debug, bool, S_IRUGO | S_IWUSR);
 642MODULE_PARM_DESC(debug, "Debug enabled or not");
 643