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_interrupt_in =     0,
 122        .num_bulk_in =          1,
 123        .num_bulk_out =         1,
 124        .num_ports =            1,
 125        .open =                 empeg_open,
 126        .close =                empeg_close,
 127        .throttle =             empeg_throttle,
 128        .unthrottle =           empeg_unthrottle,
 129        .attach =               empeg_startup,
 130        .shutdown =             empeg_shutdown,
 131        .ioctl =                empeg_ioctl,
 132        .set_termios =          empeg_set_termios,
 133        .write =                empeg_write,
 134        .write_room =           empeg_write_room,
 135        .chars_in_buffer =      empeg_chars_in_buffer,
 136        .write_bulk_callback =  empeg_write_bulk_callback,
 137        .read_bulk_callback =   empeg_read_bulk_callback,
 138};
 139
 140#define NUM_URBS                        16
 141#define URB_TRANSFER_BUFFER_SIZE        4096
 142
 143static struct urb       *write_urb_pool[NUM_URBS];
 144static spinlock_t       write_urb_pool_lock;
 145static int              bytes_in;
 146static int              bytes_out;
 147
 148/******************************************************************************
 149 * Empeg specific driver functions
 150 ******************************************************************************/
 151static int empeg_open (struct usb_serial_port *port, struct file *filp)
 152{
 153        struct usb_serial *serial = port->serial;
 154        int result = 0;
 155
 156        dbg("%s - port %d", __FUNCTION__, port->number);
 157
 158        /* Force default termio settings */
 159        empeg_set_termios (port, NULL) ;
 160
 161        bytes_in = 0;
 162        bytes_out = 0;
 163
 164        /* Start reading from the device */
 165        usb_fill_bulk_urb(
 166                port->read_urb,
 167                serial->dev, 
 168                usb_rcvbulkpipe(serial->dev,
 169                        port->bulk_in_endpointAddress),
 170                port->read_urb->transfer_buffer,
 171                port->read_urb->transfer_buffer_length,
 172                empeg_read_bulk_callback,
 173                port);
 174
 175        result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 176
 177        if (result)
 178                dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, result);
 179
 180        return result;
 181}
 182
 183
 184static void empeg_close (struct usb_serial_port *port, struct file * filp)
 185{
 186        dbg("%s - port %d", __FUNCTION__, 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 usb_serial_port *port, const unsigned char *buf, int count)
 196{
 197        struct usb_serial *serial = port->serial;
 198        struct urb *urb;
 199        const unsigned char *current_position = buf;
 200        unsigned long flags;
 201        int status;
 202        int i;
 203        int bytes_sent = 0;
 204        int transfer_size;
 205
 206        dbg("%s - port %d", __FUNCTION__, port->number);
 207
 208        while (count > 0) {
 209
 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", __FUNCTION__);
 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, "%s no more kernel memory...\n", __FUNCTION__);
 233                                goto exit;
 234                        }
 235                }
 236
 237                transfer_size = min (count, URB_TRANSFER_BUFFER_SIZE);
 238
 239                memcpy (urb->transfer_buffer, current_position, transfer_size);
 240
 241                usb_serial_debug_data(debug, &port->dev, __FUNCTION__, transfer_size, urb->transfer_buffer);
 242
 243                /* build up our urb */
 244                usb_fill_bulk_urb (
 245                        urb,
 246                        serial->dev,
 247                        usb_sndbulkpipe(serial->dev,
 248                                port->bulk_out_endpointAddress), 
 249                        urb->transfer_buffer,
 250                        transfer_size,
 251                        empeg_write_bulk_callback,
 252                        port);
 253
 254                /* send it down the pipe */
 255                status = usb_submit_urb(urb, GFP_ATOMIC);
 256                if (status) {
 257                        dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n", __FUNCTION__, status);
 258                        bytes_sent = status;
 259                        break;
 260                }
 261
 262                current_position += transfer_size;
 263                bytes_sent += transfer_size;
 264                count -= transfer_size;
 265                bytes_out += transfer_size;
 266
 267        }
 268
 269exit:
 270        return bytes_sent;
 271
 272} 
 273
 274
 275static int empeg_write_room (struct usb_serial_port *port)
 276{
 277        unsigned long flags;
 278        int i;
 279        int room = 0;
 280
 281        dbg("%s - port %d", __FUNCTION__, port->number);
 282
 283        spin_lock_irqsave (&write_urb_pool_lock, flags);
 284
 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        } 
 291
 292        spin_unlock_irqrestore (&write_urb_pool_lock, flags);
 293
 294        dbg("%s - returns %d", __FUNCTION__, room);
 295
 296        return (room);
 297
 298}
 299
 300
 301static int empeg_chars_in_buffer (struct usb_serial_port *port)
 302{
 303        unsigned long flags;
 304        int i;
 305        int chars = 0;
 306
 307        dbg("%s - port %d", __FUNCTION__, port->number);
 308
 309        spin_lock_irqsave (&write_urb_pool_lock, flags);
 310
 311        /* tally up the number of bytes waiting */
 312        for (i = 0; i < NUM_URBS; ++i) {
 313                if (write_urb_pool[i]->status == -EINPROGRESS) {
 314                        chars += URB_TRANSFER_BUFFER_SIZE;
 315                }
 316        }
 317
 318        spin_unlock_irqrestore (&write_urb_pool_lock, flags);
 319
 320        dbg("%s - returns %d", __FUNCTION__, chars);
 321
 322        return (chars);
 323
 324}
 325
 326
 327static void empeg_write_bulk_callback (struct urb *urb)
 328{
 329        struct usb_serial_port *port = urb->context;
 330        int status = urb->status;
 331
 332        dbg("%s - port %d", __FUNCTION__, port->number);
 333
 334        if (status) {
 335                dbg("%s - nonzero write bulk status received: %d",
 336                    __FUNCTION__, status);
 337                return;
 338        }
 339
 340        usb_serial_port_softint(port);
 341}
 342
 343
 344static void empeg_read_bulk_callback (struct urb *urb)
 345{
 346        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 347        struct tty_struct *tty;
 348        unsigned char *data = urb->transfer_buffer;
 349        int result;
 350        int status = urb->status;
 351
 352        dbg("%s - port %d", __FUNCTION__, port->number);
 353
 354        if (status) {
 355                dbg("%s - nonzero read bulk status received: %d",
 356                    __FUNCTION__, status);
 357                return;
 358        }
 359
 360        usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
 361
 362        tty = port->tty;
 363
 364        if (urb->actual_length) {
 365                tty_buffer_request_room(tty, urb->actual_length);
 366                tty_insert_flip_string(tty, data, urb->actual_length);
 367                tty_flip_buffer_push(tty);
 368                bytes_in += urb->actual_length;
 369        }
 370
 371        /* Continue trying to always read  */
 372        usb_fill_bulk_urb(
 373                port->read_urb,
 374                port->serial->dev, 
 375                usb_rcvbulkpipe(port->serial->dev,
 376                        port->bulk_in_endpointAddress),
 377                port->read_urb->transfer_buffer,
 378                port->read_urb->transfer_buffer_length,
 379                empeg_read_bulk_callback,
 380                port);
 381
 382        result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
 383
 384        if (result)
 385                dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
 386
 387        return;
 388
 389}
 390
 391
 392static void empeg_throttle (struct usb_serial_port *port)
 393{
 394        dbg("%s - port %d", __FUNCTION__, port->number);
 395        usb_kill_urb(port->read_urb);
 396}
 397
 398
 399static void empeg_unthrottle (struct usb_serial_port *port)
 400{
 401        int result;
 402
 403        dbg("%s - port %d", __FUNCTION__, port->number);
 404
 405        port->read_urb->dev = port->serial->dev;
 406
 407        result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
 408
 409        if (result)
 410                dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, result);
 411
 412        return;
 413}
 414
 415
 416static int  empeg_startup (struct usb_serial *serial)
 417{
 418        int r;
 419
 420        dbg("%s", __FUNCTION__);
 421
 422        if (serial->dev->actconfig->desc.bConfigurationValue != 1) {
 423                err("active config #%d != 1 ??",
 424                        serial->dev->actconfig->desc.bConfigurationValue);
 425                return -ENODEV;
 426        }
 427        dbg("%s - reset config", __FUNCTION__);
 428        r = usb_reset_configuration (serial->dev);
 429
 430        /* continue on with initialization */
 431        return r;
 432
 433}
 434
 435
 436static void empeg_shutdown (struct usb_serial *serial)
 437{
 438        dbg ("%s", __FUNCTION__);
 439}
 440
 441
 442static int empeg_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
 443{
 444        dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd);
 445
 446        return -ENOIOCTLCMD;
 447}
 448
 449
 450static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
 451{
 452        struct ktermios *termios = port->tty->termios;
 453        dbg("%s - port %d", __FUNCTION__, port->number);
 454
 455        /*
 456         * The empeg-car player wants these particular tty settings.
 457         * You could, for example, change the baud rate, however the
 458         * player only supports 115200 (currently), so there is really
 459         * no point in support for changes to the tty settings.
 460         * (at least for now)
 461         *
 462         * The default requirements for this device are:
 463         */
 464        termios->c_iflag
 465                &= ~(IGNBRK     /* disable ignore break */
 466                | BRKINT        /* disable break causes interrupt */
 467                | PARMRK        /* disable mark parity errors */
 468                | ISTRIP        /* disable clear high bit of input characters */
 469                | INLCR         /* disable translate NL to CR */
 470                | IGNCR         /* disable ignore CR */
 471                | ICRNL         /* disable translate CR to NL */
 472                | IXON);        /* disable enable XON/XOFF flow control */
 473
 474        termios->c_oflag
 475                &= ~OPOST;      /* disable postprocess output characters */
 476
 477        termios->c_lflag
 478                &= ~(ECHO       /* disable echo input characters */
 479                | ECHONL        /* disable echo new line */
 480                | ICANON        /* disable erase, kill, werase, and rprnt special characters */
 481                | ISIG          /* disable interrupt, quit, and suspend special characters */
 482                | IEXTEN);      /* disable non-POSIX special characters */
 483
 484        termios->c_cflag
 485                &= ~(CSIZE      /* no size */
 486                | PARENB        /* disable parity bit */
 487                | CBAUD);       /* clear current baud rate */
 488
 489        termios->c_cflag
 490                |= CS8;         /* character size 8 bits */
 491
 492        /*
 493         * Force low_latency on; otherwise the pushes are scheduled;
 494         * this is bad as it opens up the possibility of dropping bytes
 495         * on the floor.  We don't want to drop bytes on the floor. :)
 496         */
 497        port->tty->low_latency = 1;
 498        tty_encode_baud_rate(port->tty, 115200, 115200);
 499}
 500
 501
 502static int __init empeg_init (void)
 503{
 504        struct urb *urb;
 505        int i, retval;
 506
 507        /* create our write urb pool and transfer buffers */ 
 508        spin_lock_init (&write_urb_pool_lock);
 509        for (i = 0; i < NUM_URBS; ++i) {
 510                urb = usb_alloc_urb(0, GFP_KERNEL);
 511                write_urb_pool[i] = urb;
 512                if (urb == NULL) {
 513                        err("No more urbs???");
 514                        continue;
 515                }
 516
 517                urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
 518                if (!urb->transfer_buffer) {
 519                        err("%s - out of memory for urb buffers.", 
 520                            __FUNCTION__);
 521                        continue;
 522                }
 523        }
 524
 525        retval = usb_serial_register(&empeg_device);
 526        if (retval)
 527                goto failed_usb_serial_register;
 528        retval = usb_register(&empeg_driver);
 529        if (retval)
 530                goto failed_usb_register;
 531
 532        info(DRIVER_VERSION ":" DRIVER_DESC);
 533
 534        return 0;
 535failed_usb_register:
 536        usb_serial_deregister(&empeg_device);
 537failed_usb_serial_register:
 538        for (i = 0; i < NUM_URBS; ++i) {
 539                if (write_urb_pool[i]) {
 540                        kfree(write_urb_pool[i]->transfer_buffer);
 541                        usb_free_urb(write_urb_pool[i]);
 542                }
 543        }
 544        return retval;
 545}
 546
 547
 548static void __exit empeg_exit (void)
 549{
 550        int i;
 551        unsigned long flags;
 552
 553        usb_deregister(&empeg_driver);
 554        usb_serial_deregister (&empeg_device);
 555
 556        spin_lock_irqsave (&write_urb_pool_lock, flags);
 557
 558        for (i = 0; i < NUM_URBS; ++i) {
 559                if (write_urb_pool[i]) {
 560                        /* FIXME - uncomment the following usb_kill_urb call when
 561                         * the host controllers get fixed to set urb->dev = NULL after
 562                         * the urb is finished.  Otherwise this call oopses. */
 563                        /* usb_kill_urb(write_urb_pool[i]); */
 564                        kfree(write_urb_pool[i]->transfer_buffer);
 565                        usb_free_urb (write_urb_pool[i]);
 566                }
 567        }
 568
 569        spin_unlock_irqrestore (&write_urb_pool_lock, flags);
 570}
 571
 572
 573module_init(empeg_init);
 574module_exit(empeg_exit);
 575
 576MODULE_AUTHOR( DRIVER_AUTHOR );
 577MODULE_DESCRIPTION( DRIVER_DESC );
 578MODULE_LICENSE("GPL");
 579
 580module_param(debug, bool, S_IRUGO | S_IWUSR);
 581MODULE_PARM_DESC(debug, "Debug enabled or not");
 582