linux/drivers/usb/serial/airprime.c
<<
>>
Prefs
   1/*
   2 * AirPrime CDMA Wireless Serial USB driver
   3 *
   4 * Copyright (C) 2005-2006 Greg Kroah-Hartman <gregkh@suse.de>
   5 *
   6 *      This program is free software; you can redistribute it and/or
   7 *      modify it under the terms of the GNU General Public License version
   8 *      2 as published by the Free Software Foundation.
   9 */
  10
  11#include <linux/kernel.h>
  12#include <linux/init.h>
  13#include <linux/tty.h>
  14#include <linux/tty_flip.h>
  15#include <linux/module.h>
  16#include <linux/usb.h>
  17#include <linux/usb/serial.h>
  18
  19static struct usb_device_id id_table [] = {
  20        { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */
  21        { },
  22};
  23MODULE_DEVICE_TABLE(usb, id_table);
  24
  25#define URB_TRANSFER_BUFFER_SIZE        4096
  26#define NUM_READ_URBS                   4
  27#define NUM_WRITE_URBS                  4
  28#define NUM_BULK_EPS                    3
  29#define MAX_BULK_EPS                    6
  30
  31/* if overridden by the user, then use their value for the size of the
  32 * read and write urbs, and the number of endpoints */
  33static int buffer_size = URB_TRANSFER_BUFFER_SIZE;
  34static int endpoints = NUM_BULK_EPS;
  35static int debug;
  36struct airprime_private {
  37        spinlock_t lock;
  38        int outstanding_urbs;
  39        int throttled;
  40        struct urb *read_urbp[NUM_READ_URBS];
  41
  42        /* Settings for the port */
  43        int rts_state;  /* Handshaking pins (outputs) */
  44        int dtr_state;
  45        int cts_state;  /* Handshaking pins (inputs) */
  46        int dsr_state;
  47        int dcd_state;
  48        int ri_state;
  49};
  50
  51static int airprime_send_setup(struct usb_serial_port *port)
  52{
  53        struct usb_serial *serial = port->serial;
  54        struct airprime_private *priv;
  55
  56        dbg("%s", __FUNCTION__);
  57
  58        if (port->number != 0)
  59                return 0;
  60
  61        priv = usb_get_serial_port_data(port);
  62
  63        if (port->tty) {
  64                int val = 0;
  65                if (priv->dtr_state)
  66                        val |= 0x01;
  67                if (priv->rts_state)
  68                        val |= 0x02;
  69
  70                return usb_control_msg(serial->dev,
  71                                usb_rcvctrlpipe(serial->dev, 0),
  72                                0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT);
  73        }
  74
  75        return 0;
  76}
  77
  78static void airprime_read_bulk_callback(struct urb *urb)
  79{
  80        struct usb_serial_port *port = urb->context;
  81        unsigned char *data = urb->transfer_buffer;
  82        struct tty_struct *tty;
  83        int result;
  84        int status = urb->status;
  85
  86        dbg("%s - port %d", __FUNCTION__, port->number);
  87
  88        if (status) {
  89                dbg("%s - nonzero read bulk status received: %d",
  90                    __FUNCTION__, status);
  91                return;
  92        }
  93        usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
  94
  95        tty = port->tty;
  96        if (tty && urb->actual_length) {
  97                tty_insert_flip_string (tty, data, urb->actual_length);
  98                tty_flip_buffer_push (tty);
  99        }
 100
 101        result = usb_submit_urb (urb, GFP_ATOMIC);
 102        if (result)
 103                dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n",
 104                        __FUNCTION__, result);
 105        return;
 106}
 107
 108static void airprime_write_bulk_callback(struct urb *urb)
 109{
 110        struct usb_serial_port *port = urb->context;
 111        struct airprime_private *priv = usb_get_serial_port_data(port);
 112        int status = urb->status;
 113        unsigned long flags;
 114
 115        dbg("%s - port %d", __FUNCTION__, port->number);
 116
 117        /* free up the transfer buffer, as usb_free_urb() does not do this */
 118        kfree (urb->transfer_buffer);
 119
 120        if (status)
 121                dbg("%s - nonzero write bulk status received: %d",
 122                    __FUNCTION__, status);
 123        spin_lock_irqsave(&priv->lock, flags);
 124        --priv->outstanding_urbs;
 125        spin_unlock_irqrestore(&priv->lock, flags);
 126
 127        usb_serial_port_softint(port);
 128}
 129
 130static int airprime_open(struct usb_serial_port *port, struct file *filp)
 131{
 132        struct airprime_private *priv = usb_get_serial_port_data(port);
 133        struct usb_serial *serial = port->serial;
 134        struct urb *urb;
 135        char *buffer = NULL;
 136        int i;
 137        int result = 0;
 138
 139        dbg("%s - port %d", __FUNCTION__, port->number);
 140
 141        /* initialize our private data structure if it isn't already created */
 142        if (!priv) {
 143                priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 144                if (!priv) {
 145                        result = -ENOMEM;
 146                        goto out;
 147                }
 148                spin_lock_init(&priv->lock);
 149                usb_set_serial_port_data(port, priv);
 150        }
 151
 152        /* Set some sane defaults */
 153        priv->rts_state = 1;
 154        priv->dtr_state = 1;
 155
 156        for (i = 0; i < NUM_READ_URBS; ++i) {
 157                buffer = kmalloc(buffer_size, GFP_KERNEL);
 158                if (!buffer) {
 159                        dev_err(&port->dev, "%s - out of memory.\n",
 160                                __FUNCTION__);
 161                        result = -ENOMEM;
 162                        goto errout;
 163                }
 164                urb = usb_alloc_urb(0, GFP_KERNEL);
 165                if (!urb) {
 166                        kfree(buffer);
 167                        dev_err(&port->dev, "%s - no more urbs?\n",
 168                                __FUNCTION__);
 169                        result = -ENOMEM;
 170                        goto errout;
 171                }
 172                usb_fill_bulk_urb(urb, serial->dev,
 173                                  usb_rcvbulkpipe(serial->dev,
 174                                                  port->bulk_out_endpointAddress),
 175                                  buffer, buffer_size,
 176                                  airprime_read_bulk_callback, port);
 177                result = usb_submit_urb(urb, GFP_KERNEL);
 178                if (result) {
 179                        usb_free_urb(urb);
 180                        kfree(buffer);
 181                        dev_err(&port->dev,
 182                                "%s - failed submitting read urb %d for port %d, error %d\n",
 183                                __FUNCTION__, i, port->number, result);
 184                        goto errout;
 185                }
 186                /* remember this urb so we can kill it when the port is closed */
 187                priv->read_urbp[i] = urb;
 188        }
 189
 190        airprime_send_setup(port);
 191
 192        goto out;
 193
 194 errout:
 195        /* some error happened, cancel any submitted urbs and clean up anything that
 196           got allocated successfully */
 197
 198        while (i-- != 0) {
 199                urb = priv->read_urbp[i];
 200                buffer = urb->transfer_buffer;
 201                usb_kill_urb (urb);
 202                usb_free_urb (urb);
 203                kfree (buffer);
 204        }
 205
 206 out:
 207        return result;
 208}
 209
 210static void airprime_close(struct usb_serial_port *port, struct file * filp)
 211{
 212        struct airprime_private *priv = usb_get_serial_port_data(port);
 213        int i;
 214
 215        dbg("%s - port %d", __FUNCTION__, port->number);
 216
 217        priv->rts_state = 0;
 218        priv->dtr_state = 0;
 219
 220        airprime_send_setup(port);
 221
 222        for (i = 0; i < NUM_READ_URBS; ++i) {
 223                usb_kill_urb (priv->read_urbp[i]);
 224                kfree (priv->read_urbp[i]->transfer_buffer);
 225                usb_free_urb (priv->read_urbp[i]);
 226        }
 227
 228        /* free up private structure */
 229        kfree (priv);
 230        usb_set_serial_port_data(port, NULL);
 231}
 232
 233static int airprime_write(struct usb_serial_port *port,
 234                          const unsigned char *buf, int count)
 235{
 236        struct airprime_private *priv = usb_get_serial_port_data(port);
 237        struct usb_serial *serial = port->serial;
 238        struct urb *urb;
 239        unsigned char *buffer;
 240        unsigned long flags;
 241        int status;
 242        dbg("%s - port %d", __FUNCTION__, port->number);
 243
 244        spin_lock_irqsave(&priv->lock, flags);
 245        if (priv->outstanding_urbs > NUM_WRITE_URBS) {
 246                spin_unlock_irqrestore(&priv->lock, flags);
 247                dbg("%s - write limit hit\n", __FUNCTION__);
 248                return 0;
 249        }
 250        spin_unlock_irqrestore(&priv->lock, flags);
 251        buffer = kmalloc(count, GFP_ATOMIC);
 252        if (!buffer) {
 253                dev_err(&port->dev, "out of memory\n");
 254                return -ENOMEM;
 255        }
 256        urb = usb_alloc_urb(0, GFP_ATOMIC);
 257        if (!urb) {
 258                dev_err(&port->dev, "no more free urbs\n");
 259                kfree (buffer);
 260                return -ENOMEM;
 261        }
 262        memcpy (buffer, buf, count);
 263
 264        usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buffer);
 265
 266        usb_fill_bulk_urb(urb, serial->dev,
 267                          usb_sndbulkpipe(serial->dev,
 268                                          port->bulk_out_endpointAddress),
 269                          buffer, count,
 270                          airprime_write_bulk_callback, port);
 271
 272        /* send it down the pipe */
 273        status = usb_submit_urb(urb, GFP_ATOMIC);
 274        if (status) {
 275                dev_err(&port->dev,
 276                        "%s - usb_submit_urb(write bulk) failed with status = %d\n",
 277                        __FUNCTION__, status);
 278                count = status;
 279                kfree (buffer);
 280        } else {
 281                spin_lock_irqsave(&priv->lock, flags);
 282                ++priv->outstanding_urbs;
 283                spin_unlock_irqrestore(&priv->lock, flags);
 284        }
 285        /* we are done with this urb, so let the host driver
 286         * really free it when it is finished with it */
 287        usb_free_urb (urb);
 288        return count;
 289}
 290
 291static struct usb_driver airprime_driver = {
 292        .name =         "airprime",
 293        .probe =        usb_serial_probe,
 294        .disconnect =   usb_serial_disconnect,
 295        .id_table =     id_table,
 296        .no_dynamic_id =        1,
 297};
 298
 299static struct usb_serial_driver airprime_device = {
 300        .driver = {
 301                .owner =        THIS_MODULE,
 302                .name =         "airprime",
 303        },
 304        .usb_driver =           &airprime_driver,
 305        .id_table =             id_table,
 306        .num_interrupt_in =     NUM_DONT_CARE,
 307        .num_bulk_in =          NUM_DONT_CARE,
 308        .num_bulk_out =         NUM_DONT_CARE,
 309        .open =                 airprime_open,
 310        .close =                airprime_close,
 311        .write =                airprime_write,
 312};
 313
 314static int __init airprime_init(void)
 315{
 316        int retval;
 317
 318        airprime_device.num_ports =
 319                (endpoints > 0 && endpoints <= MAX_BULK_EPS) ? endpoints : NUM_BULK_EPS;
 320        retval = usb_serial_register(&airprime_device);
 321        if (retval)
 322                return retval;
 323        retval = usb_register(&airprime_driver);
 324        if (retval)
 325                usb_serial_deregister(&airprime_device);
 326        return retval;
 327}
 328
 329static void __exit airprime_exit(void)
 330{
 331        dbg("%s", __FUNCTION__);
 332
 333        usb_deregister(&airprime_driver);
 334        usb_serial_deregister(&airprime_device);
 335}
 336
 337module_init(airprime_init);
 338module_exit(airprime_exit);
 339MODULE_LICENSE("GPL");
 340
 341module_param(debug, bool, S_IRUGO | S_IWUSR);
 342MODULE_PARM_DESC(debug, "Debug enabled");
 343module_param(buffer_size, int, 0);
 344MODULE_PARM_DESC(buffer_size, "Size of the transfer buffers in bytes (default 4096)");
 345module_param(endpoints, int, 0);
 346MODULE_PARM_DESC(endpoints, "Number of bulk EPs to configure (default 3)");
 347