linux/drivers/usb/serial/empeg.c
<<
>>
Prefs
   1/*
   2 * USB Empeg empeg-car player driver
   3 *
   4 *      Copyright (C) 2000, 2001
   5 *          Gary Brubaker (xavyer@ix.netcom.com)
   6 *
   7 *      Copyright (C) 1999 - 2001
   8 *          Greg Kroah-Hartman (greg@kroah.com)
   9 *
  10 *      This program is free software; you can redistribute it and/or modify
  11 *      it under the terms of the GNU General Public License, as published by
  12 *      the Free Software Foundation, version 2.
  13 *
  14 * See Documentation/usb/usb-serial.txt for more information on using this
  15 * driver
  16 *
  17 * (07/16/2001) gb
  18 *      remove unused code in empeg_close() (thanks to Oliver Neukum for
  19 *      pointing this out) and rewrote empeg_set_termios().
  20 *
  21 * (05/30/2001) gkh
  22 *      switched from using spinlock to a semaphore, which fixes lots of
  23 * problems.
  24 *
  25 * (04/08/2001) gb
  26 *      Identify version on module load.
  27 *
  28 * (01/22/2001) gb
  29 *      Added write_room() and chars_in_buffer() support.
  30 *
  31 * (12/21/2000) gb
  32 *      Moved termio stuff inside the port->active check.
  33 *      Moved MOD_DEC_USE_COUNT to end of empeg_close().
  34 *
  35 * (12/03/2000) gb
  36 *      Added port->port.tty->ldisc.set_termios(port->port.tty, NULL) to
  37 *      empeg_open(). This notifies the tty driver that the termios have
  38 *      changed.
  39 *
  40 * (11/13/2000) gb
  41 *      Moved tty->low_latency = 1 from empeg_read_bulk_callback() to
  42 *      empeg_open() (It only needs to be set once - Doh!)
  43 *
  44 * (11/11/2000) gb
  45 *      Updated to work with id_table structure.
  46 *
  47 * (11/04/2000) gb
  48 *      Forked this from visor.c, and hacked it up to work with an
  49 *      Empeg ltd. empeg-car player.  Constructive criticism welcomed.
  50 *      I would like to say, 'Thank You' to Greg Kroah-Hartman for the
  51 *      use of his code, and for his guidance, advice and patience. :)
  52 *      A 'Thank You' is in order for John Ripley of Empeg ltd for his
  53 *      advice, and patience too.
  54 *
  55 */
  56
  57#include <linux/kernel.h>
  58#include <linux/errno.h>
  59#include <linux/init.h>
  60#include <linux/slab.h>
  61#include <linux/tty.h>
  62#include <linux/tty_driver.h>
  63#include <linux/tty_flip.h>
  64#include <linux/module.h>
  65#include <linux/spinlock.h>
  66#include <linux/uaccess.h>
  67#include <linux/usb.h>
  68#include <linux/usb/serial.h>
  69
  70static int debug;
  71
  72/*
  73 * Version Information
  74 */
  75#define DRIVER_VERSION "v1.2"
  76#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Gary Brubaker <xavyer@ix.netcom.com>"
  77#define DRIVER_DESC "USB Empeg Mark I/II Driver"
  78
  79#define EMPEG_VENDOR_ID                 0x084f
  80#define EMPEG_PRODUCT_ID                0x0001
  81
  82/* function prototypes for an empeg-car player */
  83static int  empeg_open(struct tty_struct *tty, struct usb_serial_port *port,
  84                                                struct file *filp);
  85static void empeg_close(struct tty_struct *tty, struct usb_serial_port *port,
  86                                                struct file *filp);
  87static int  empeg_write(struct tty_struct *tty, struct usb_serial_port *port,
  88                                                const unsigned char *buf,
  89                                                int count);
  90static int  empeg_write_room(struct tty_struct *tty);
  91static int  empeg_chars_in_buffer(struct tty_struct *tty);
  92static void empeg_throttle(struct tty_struct *tty);
  93static void empeg_unthrottle(struct tty_struct *tty);
  94static int  empeg_startup(struct usb_serial *serial);
  95static void empeg_set_termios(struct tty_struct *tty,
  96                struct usb_serial_port *port, struct ktermios *old_termios);
  97static void empeg_write_bulk_callback(struct urb *urb);
  98static void empeg_read_bulk_callback(struct urb *urb);
  99
 100static struct usb_device_id id_table [] = {
 101        { USB_DEVICE(EMPEG_VENDOR_ID, EMPEG_PRODUCT_ID) },
 102        { }                                     /* Terminating entry */
 103};
 104
 105MODULE_DEVICE_TABLE(usb, id_table);
 106
 107static struct usb_driver empeg_driver = {
 108        .name =         "empeg",
 109        .probe =        usb_serial_probe,
 110        .disconnect =   usb_serial_disconnect,
 111        .id_table =     id_table,
 112        .no_dynamic_id =        1,
 113};
 114
 115static struct usb_serial_driver empeg_device = {
 116        .driver = {
 117                .owner =        THIS_MODULE,
 118                .name =         "empeg",
 119        },
 120        .id_table =             id_table,
 121        .usb_driver =           &empeg_driver,
 122        .num_ports =            1,
 123        .open =                 empeg_open,
 124        .close =                empeg_close,
 125        .throttle =             empeg_throttle,
 126        .unthrottle =           empeg_unthrottle,
 127        .attach =               empeg_startup,
 128        .set_termios =          empeg_set_termios,
 129        .write =                empeg_write,
 130        .write_room =           empeg_write_room,
 131        .chars_in_buffer =      empeg_chars_in_buffer,
 132        .write_bulk_callback =  empeg_write_bulk_callback,
 133        .read_bulk_callback =   empeg_read_bulk_callback,
 134};
 135
 136#define NUM_URBS                        16
 137#define URB_TRANSFER_BUFFER_SIZE        4096
 138
 139static struct urb       *write_urb_pool[NUM_URBS];
 140static spinlock_t       write_urb_pool_lock;
 141static int              bytes_in;
 142static int              bytes_out;
 143
 144/******************************************************************************
 145 * Empeg specific driver functions
 146 ******************************************************************************/
 147static int empeg_open(struct tty_struct *tty, struct usb_serial_port *port,
 148                                struct file *filp)
 149{
 150        struct usb_serial *serial = port->serial;
 151        int result = 0;
 152
 153        dbg("%s - port %d", __func__, port->number);
 154
 155        /* Force default termio settings */
 156        empeg_set_termios(tty, port, NULL) ;
 157
 158        bytes_in = 0;
 159        bytes_out = 0;
 160
 161        /* Start reading from the device */
 162        usb_fill_bulk_urb(
 163                port->read_urb,
 164                serial->dev,
 165                usb_rcvbulkpipe(serial->dev,
 166                        port->bulk_in_endpointAddress),
 167                port->read_urb->transfer_buffer,
 168                port->read_urb->transfer_buffer_length,
 169                empeg_read_bulk_callback,
 170                port);
 171
 172        result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 173
 174        if (result)
 175                dev_err(&port->dev,
 176                        "%s - failed submitting read urb, error %d\n",
 177                                                        __func__, result);
 178
 179        return result;
 180}
 181
 182
 183static void empeg_close(struct tty_struct *tty, struct usb_serial_port *port,
 184                                struct file *filp)
 185{
 186        dbg("%s - port %d", __func__, port->number);
 187
 188        /* shutdown our bulk read */
 189        usb_kill_urb(port->read_urb);
 190        /* Uncomment the following line if you want to see some statistics in your syslog */
 191        /* dev_info (&port->dev, "Bytes In = %d  Bytes Out = %d\n", bytes_in, bytes_out); */
 192}
 193
 194
 195static int empeg_write(struct tty_struct *tty, struct usb_serial_port *port,
 196                                        const unsigned char *buf, int count)
 197{
 198        struct usb_serial *serial = port->serial;
 199        struct urb *urb;
 200        const unsigned char *current_position = buf;
 201        unsigned long flags;
 202        int status;
 203        int i;
 204        int bytes_sent = 0;
 205        int transfer_size;
 206
 207        dbg("%s - port %d", __func__, port->number);
 208
 209        while (count > 0) {
 210                /* try to find a free urb in our list of them */
 211                urb = NULL;
 212
 213                spin_lock_irqsave(&write_urb_pool_lock, flags);
 214
 215                for (i = 0; i < NUM_URBS; ++i) {
 216                        if (write_urb_pool[i]->status != -EINPROGRESS) {
 217                                urb = write_urb_pool[i];
 218                                break;
 219                        }
 220                }
 221
 222                spin_unlock_irqrestore(&write_urb_pool_lock, flags);
 223
 224                if (urb == NULL) {
 225                        dbg("%s - no more free urbs", __func__);
 226                        goto exit;
 227                }
 228
 229                if (urb->transfer_buffer == NULL) {
 230                        urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC);
 231                        if (urb->transfer_buffer == NULL) {
 232                                dev_err(&port->dev,
 233                                        "%s no more kernel memory...\n",
 234                                                                __func__);
 235                                goto exit;
 236                        }
 237                }
 238
 239                transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE);
 240
 241                memcpy(urb->transfer_buffer, current_position, transfer_size);
 242
 243                usb_serial_debug_data(debug, &port->dev, __func__, transfer_size, urb->transfer_buffer);
 244
 245                /* build up our urb */
 246                usb_fill_bulk_urb(
 247                        urb,
 248                        serial->dev,
 249                        usb_sndbulkpipe(serial->dev,
 250                                        port->bulk_out_endpointAddress),
 251                        urb->transfer_buffer,
 252                        transfer_size,
 253                        empeg_write_bulk_callback,
 254                        port);
 255
 256                /* send it down the pipe */
 257                status = usb_submit_urb(urb, GFP_ATOMIC);
 258                if (status) {
 259                        dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n", __func__, status);
 260                        bytes_sent = status;
 261                        break;
 262                }
 263
 264                current_position += transfer_size;
 265                bytes_sent += transfer_size;
 266                count -= transfer_size;
 267                bytes_out += transfer_size;
 268
 269        }
 270exit:
 271        return bytes_sent;
 272}
 273
 274
 275static int empeg_write_room(struct tty_struct *tty)
 276{
 277        struct usb_serial_port *port = tty->driver_data;
 278        unsigned long flags;
 279        int i;
 280        int room = 0;
 281
 282        dbg("%s - port %d", __func__, port->number);
 283
 284        spin_lock_irqsave(&write_urb_pool_lock, flags);
 285        /* tally up the number of bytes available */
 286        for (i = 0; i < NUM_URBS; ++i) {
 287                if (write_urb_pool[i]->status != -EINPROGRESS)
 288                        room += URB_TRANSFER_BUFFER_SIZE;
 289        }
 290        spin_unlock_irqrestore(&write_urb_pool_lock, flags);
 291        dbg("%s - returns %d", __func__, room);
 292        return room;
 293
 294}
 295
 296
 297static int empeg_chars_in_buffer(struct tty_struct *tty)
 298{
 299        struct usb_serial_port *port = tty->driver_data;
 300        unsigned long flags;
 301        int i;
 302        int chars = 0;
 303
 304        dbg("%s - port %d", __func__, port->number);
 305
 306        spin_lock_irqsave(&write_urb_pool_lock, flags);
 307
 308        /* tally up the number of bytes waiting */
 309        for (i = 0; i < NUM_URBS; ++i) {
 310                if (write_urb_pool[i]->status == -EINPROGRESS)
 311                        chars += URB_TRANSFER_BUFFER_SIZE;
 312        }
 313
 314        spin_unlock_irqrestore(&write_urb_pool_lock, flags);
 315        dbg("%s - returns %d", __func__, chars);
 316        return chars;
 317}
 318
 319
 320static void empeg_write_bulk_callback(struct urb *urb)
 321{
 322        struct usb_serial_port *port = urb->context;
 323        int status = urb->status;
 324
 325        dbg("%s - port %d", __func__, port->number);
 326
 327        if (status) {
 328                dbg("%s - nonzero write bulk status received: %d",
 329                    __func__, status);
 330                return;
 331        }
 332
 333        usb_serial_port_softint(port);
 334}
 335
 336
 337static void empeg_read_bulk_callback(struct urb *urb)
 338{
 339        struct usb_serial_port *port = urb->context;
 340        struct tty_struct *tty;
 341        unsigned char *data = urb->transfer_buffer;
 342        int result;
 343        int status = urb->status;
 344
 345        dbg("%s - port %d", __func__, port->number);
 346
 347        if (status) {
 348                dbg("%s - nonzero read bulk status received: %d",
 349                    __func__, status);
 350                return;
 351        }
 352
 353        usb_serial_debug_data(debug, &port->dev, __func__,
 354                                                urb->actual_length, data);
 355        tty = port->port.tty;
 356
 357        if (urb->actual_length) {
 358                tty_buffer_request_room(tty, urb->actual_length);
 359                tty_insert_flip_string(tty, data, urb->actual_length);
 360                tty_flip_buffer_push(tty);
 361                bytes_in += urb->actual_length;
 362        }
 363
 364        /* Continue trying to always read  */
 365        usb_fill_bulk_urb(
 366                port->read_urb,
 367                port->serial->dev,
 368                usb_rcvbulkpipe(port->serial->dev,
 369                        port->bulk_in_endpointAddress),
 370                port->read_urb->transfer_buffer,
 371                port->read_urb->transfer_buffer_length,
 372                empeg_read_bulk_callback,
 373                port);
 374
 375        result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
 376
 377        if (result)
 378                dev_err(&urb->dev->dev,
 379                        "%s - failed resubmitting read urb, error %d\n",
 380                                                        __func__, result);
 381
 382        return;
 383
 384}
 385
 386
 387static void empeg_throttle(struct tty_struct *tty)
 388{
 389        struct usb_serial_port *port = tty->driver_data;
 390        dbg("%s - port %d", __func__, port->number);
 391        usb_kill_urb(port->read_urb);
 392}
 393
 394
 395static void empeg_unthrottle(struct tty_struct *tty)
 396{
 397        struct usb_serial_port *port = tty->driver_data;
 398        int result;
 399        dbg("%s - port %d", __func__, port->number);
 400
 401        port->read_urb->dev = port->serial->dev;
 402        result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
 403        if (result)
 404                dev_err(&port->dev,
 405                        "%s - failed submitting read urb, error %d\n",
 406                                                        __func__, result);
 407}
 408
 409
 410static int  empeg_startup(struct usb_serial *serial)
 411{
 412        int r;
 413
 414        dbg("%s", __func__);
 415
 416        if (serial->dev->actconfig->desc.bConfigurationValue != 1) {
 417                err("active config #%d != 1 ??",
 418                        serial->dev->actconfig->desc.bConfigurationValue);
 419                return -ENODEV;
 420        }
 421        dbg("%s - reset config", __func__);
 422        r = usb_reset_configuration(serial->dev);
 423
 424        /* continue on with initialization */
 425        return r;
 426
 427}
 428
 429
 430static void empeg_set_termios(struct tty_struct *tty,
 431                struct usb_serial_port *port, struct ktermios *old_termios)
 432{
 433        struct ktermios *termios = tty->termios;
 434        dbg("%s - port %d", __func__, port->number);
 435
 436        /*
 437         * The empeg-car player wants these particular tty settings.
 438         * You could, for example, change the baud rate, however the
 439         * player only supports 115200 (currently), so there is really
 440         * no point in support for changes to the tty settings.
 441         * (at least for now)
 442         *
 443         * The default requirements for this device are:
 444         */
 445        termios->c_iflag
 446                &= ~(IGNBRK     /* disable ignore break */
 447                | BRKINT        /* disable break causes interrupt */
 448                | PARMRK        /* disable mark parity errors */
 449                | ISTRIP        /* disable clear high bit of input characters */
 450                | INLCR         /* disable translate NL to CR */
 451                | IGNCR         /* disable ignore CR */
 452                | ICRNL         /* disable translate CR to NL */
 453                | IXON);        /* disable enable XON/XOFF flow control */
 454
 455        termios->c_oflag
 456                &= ~OPOST;      /* disable postprocess output characters */
 457
 458        termios->c_lflag
 459                &= ~(ECHO       /* disable echo input characters */
 460                | ECHONL        /* disable echo new line */
 461                | ICANON        /* disable erase, kill, werase, and rprnt special characters */
 462                | ISIG          /* disable interrupt, quit, and suspend special characters */
 463                | IEXTEN);      /* disable non-POSIX special characters */
 464
 465        termios->c_cflag
 466                &= ~(CSIZE      /* no size */
 467                | PARENB        /* disable parity bit */
 468                | CBAUD);       /* clear current baud rate */
 469
 470        termios->c_cflag
 471                |= CS8;         /* character size 8 bits */
 472
 473        tty_encode_baud_rate(tty, 115200, 115200);
 474}
 475
 476
 477static int __init empeg_init(void)
 478{
 479        struct urb *urb;
 480        int i, retval;
 481
 482        /* create our write urb pool and transfer buffers */
 483        spin_lock_init(&write_urb_pool_lock);
 484        for (i = 0; i < NUM_URBS; ++i) {
 485                urb = usb_alloc_urb(0, GFP_KERNEL);
 486                write_urb_pool[i] = urb;
 487                if (urb == NULL) {
 488                        err("No more urbs???");
 489                        continue;
 490                }
 491
 492                urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
 493                                                                GFP_KERNEL);
 494                if (!urb->transfer_buffer) {
 495                        err("%s - out of memory for urb buffers.",
 496                            __func__);
 497                        continue;
 498                }
 499        }
 500
 501        retval = usb_serial_register(&empeg_device);
 502        if (retval)
 503                goto failed_usb_serial_register;
 504        retval = usb_register(&empeg_driver);
 505        if (retval)
 506                goto failed_usb_register;
 507
 508        info(DRIVER_VERSION ":" DRIVER_DESC);
 509
 510        return 0;
 511failed_usb_register:
 512        usb_serial_deregister(&empeg_device);
 513failed_usb_serial_register:
 514        for (i = 0; i < NUM_URBS; ++i) {
 515                if (write_urb_pool[i]) {
 516                        kfree(write_urb_pool[i]->transfer_buffer);
 517                        usb_free_urb(write_urb_pool[i]);
 518                }
 519        }
 520        return retval;
 521}
 522
 523
 524static void __exit empeg_exit(void)
 525{
 526        int i;
 527        unsigned long flags;
 528
 529        usb_deregister(&empeg_driver);
 530        usb_serial_deregister(&empeg_device);
 531
 532        spin_lock_irqsave(&write_urb_pool_lock, flags);
 533
 534        for (i = 0; i < NUM_URBS; ++i) {
 535                if (write_urb_pool[i]) {
 536                        /* FIXME - uncomment the following usb_kill_urb call
 537                         * when the host controllers get fixed to set urb->dev
 538                         * = NULL after the urb is finished.  Otherwise this
 539                         * call oopses. */
 540                        /* usb_kill_urb(write_urb_pool[i]); */
 541                        kfree(write_urb_pool[i]->transfer_buffer);
 542                        usb_free_urb(write_urb_pool[i]);
 543                }
 544        }
 545        spin_unlock_irqrestore(&write_urb_pool_lock, flags);
 546}
 547
 548
 549module_init(empeg_init);
 550module_exit(empeg_exit);
 551
 552MODULE_AUTHOR(DRIVER_AUTHOR);
 553MODULE_DESCRIPTION(DRIVER_DESC);
 554MODULE_LICENSE("GPL");
 555
 556module_param(debug, bool, S_IRUGO | S_IWUSR);
 557MODULE_PARM_DESC(debug, "Debug enabled or not");
 558
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.