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