]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/serial/ir-usb.c
Merge branch 'for-2.6.26' of git://linux-nfs.org/~bfields/linux
[linux-2.6-omap-h63xx.git] / drivers / usb / serial / ir-usb.c
index 9d847f69291cacb69aac6816cca2c24a2078e4c0..004d57385a757fac1064311efdb4d53b3355f009 100644 (file)
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * 2007_Jun_21  Alan Cox <alan@redhat.com>
+ *     Minimal cleanups for some of the driver problens and tty layer abuse.
+ *     Still needs fixing to allow multiple dongles.
+ *
  * 2002_Mar_07 greg kh
  *     moved some needed structures and #define values from the
  *     net/irda/irda-usb.h file into our file, as we don't want to depend on
@@ -109,6 +113,7 @@ static void ir_write_bulk_callback (struct urb *urb);
 static void ir_read_bulk_callback (struct urb *urb);
 static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios);
 
+/* Not that this lot means you can only have one per system */
 static u8 ir_baud = 0;
 static u8 ir_xbof = 0;
 static u8 ir_add_bof = 0;
@@ -140,9 +145,6 @@ static struct usb_serial_driver ir_device = {
        .description =          "IR Dongle",
        .usb_driver =           &ir_driver,
        .id_table =             id_table,
-       .num_interrupt_in =     1,
-       .num_bulk_in =          1,
-       .num_bulk_out =         1,
        .num_ports =            1,
        .set_termios =          ir_set_termios,
        .attach =               ir_startup,
@@ -193,16 +195,16 @@ static struct irda_class_desc *irda_usb_find_class_desc(struct usb_device *dev,
                        USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
                        0, ifnum, desc, sizeof(*desc), 1000);
        
-       dbg("%s -  ret=%d", __FUNCTION__, ret);
+       dbg("%s -  ret=%d", __func__, ret);
        if (ret < sizeof(*desc)) {
                dbg("%s - class descriptor read %s (%d)",
-                               __FUNCTION__, 
+                               __func__,
                                (ret<0) ? "failed" : "too short",
                                ret);
                goto error;
        }
        if (desc->bDescriptorType != USB_DT_IRDA) {
-               dbg("%s - bad class descriptor type", __FUNCTION__);
+               dbg("%s - bad class descriptor type", __func__);
                goto error;
        }
        
@@ -246,7 +248,7 @@ static int ir_startup (struct usb_serial *serial)
        }
 
        dbg ("%s - Baud rates supported:%s%s%s%s%s%s%s%s%s",
-               __FUNCTION__,
+               __func__,
                (irda_desc->wBaudRate & 0x0001) ? " 2400"    : "",
                (irda_desc->wBaudRate & 0x0002) ? " 9600"    : "",
                (irda_desc->wBaudRate & 0x0004) ? " 19200"   : "",
@@ -279,13 +281,13 @@ static int ir_open (struct usb_serial_port *port, struct file *filp)
        char *buffer;
        int result = 0;
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __func__, port->number);
 
        if (buffer_size) {
                /* override the default buffer sizes */
                buffer = kmalloc (buffer_size, GFP_KERNEL);
                if (!buffer) {
-                       dev_err (&port->dev, "%s - out of memory.\n", __FUNCTION__);
+                       dev_err (&port->dev, "%s - out of memory.\n", __func__);
                        return -ENOMEM;
                }
                kfree (port->read_urb->transfer_buffer);
@@ -294,7 +296,7 @@ static int ir_open (struct usb_serial_port *port, struct file *filp)
 
                buffer = kmalloc (buffer_size, GFP_KERNEL);
                if (!buffer) {
-                       dev_err (&port->dev, "%s - out of memory.\n", __FUNCTION__);
+                       dev_err (&port->dev, "%s - out of memory.\n", __func__);
                        return -ENOMEM;
                }
                kfree (port->write_urb->transfer_buffer);
@@ -314,14 +316,14 @@ static int ir_open (struct usb_serial_port *port, struct file *filp)
                port);
        result = usb_submit_urb(port->read_urb, GFP_KERNEL);
        if (result)
-               dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, result);
+               dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result);
 
        return result;
 }
 
 static void ir_close (struct usb_serial_port *port, struct file * filp)
 {
-       dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __func__, port->number);
                         
        /* shutdown our bulk read */
        usb_kill_urb(port->read_urb);
@@ -333,10 +335,10 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int
        int result;
        int transfer_size;
 
-       dbg("%s - port = %d, count = %d", __FUNCTION__, port->number, count);
+       dbg("%s - port = %d, count = %d", __func__, port->number, count);
 
        if (!port->tty) {
-               dev_err (&port->dev, "%s - no tty???\n", __FUNCTION__);
+               dev_err (&port->dev, "%s - no tty???\n", __func__);
                return 0;
        }
 
@@ -346,7 +348,7 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int
        spin_lock_bh(&port->lock);
        if (port->write_urb_busy) {
                spin_unlock_bh(&port->lock);
-               dbg("%s - already writing", __FUNCTION__);
+               dbg("%s - already writing", __func__);
                return 0;
        }
        port->write_urb_busy = 1;
@@ -382,7 +384,7 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int
        result = usb_submit_urb (port->write_urb, GFP_ATOMIC);
        if (result) {
                port->write_urb_busy = 0;
-               dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
+               dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__, result);
        } else
                result = transfer_size;
 
@@ -391,20 +393,22 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int
 
 static void ir_write_bulk_callback (struct urb *urb)
 {
-       struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       struct usb_serial_port *port = urb->context;
+       int status = urb->status;
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __func__, port->number);
 
        port->write_urb_busy = 0;
-       if (urb->status) {
-               dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero write bulk status received: %d",
+                   __func__, status);
                return;
        }
 
        usb_serial_debug_data (
                debug,
                &port->dev,
-               __FUNCTION__,
+               __func__,
                urb->actual_length,
                urb->transfer_buffer);
 
@@ -413,20 +417,20 @@ static void ir_write_bulk_callback (struct urb *urb)
 
 static void ir_read_bulk_callback (struct urb *urb)
 {
-       struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       struct usb_serial_port *port = urb->context;
        struct tty_struct *tty;
        unsigned char *data = urb->transfer_buffer;
        int result;
+       int status = urb->status;
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __func__, port->number);
 
        if (!port->open_count) {
-               dbg("%s - port closed.", __FUNCTION__);
+               dbg("%s - port closed.", __func__);
                return;
        }
 
-       switch (urb->status) {
-
+       switch (status) {
                case 0: /* Successful */
 
                        /*
@@ -440,26 +444,16 @@ static void ir_read_bulk_callback (struct urb *urb)
                        usb_serial_debug_data (
                                debug,
                                &port->dev,
-                               __FUNCTION__,
+                               __func__,
                                urb->actual_length,
                                data);
 
-                       /*
-                        * Bypass flip-buffers, and feed the ldisc directly
-                        * due to our potentially large buffer size.  Since we
-                        * used to set low_latency, this is exactly what the
-                        * tty layer did anyway :)
-                        */
                        tty = port->tty;
 
-                       /*
-                        *      FIXME: must not do this in IRQ context
-                        */
-                       tty->ldisc.receive_buf(
-                               tty,
-                               data+1,
-                               NULL,
-                               urb->actual_length-1);
+                       if (tty_buffer_request_room(tty, urb->actual_length - 1)) {
+                               tty_insert_flip_string(tty, data+1, urb->actual_length - 1);
+                               tty_flip_buffer_push(tty);
+                       }
 
                        /*
                         * No break here.
@@ -483,14 +477,14 @@ static void ir_read_bulk_callback (struct urb *urb)
                        result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
                        if (result)
                                dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n",
-                                       __FUNCTION__, result);
+                                       __func__, result);
 
                        break ;
 
                default:
                        dbg("%s - nonzero read bulk status received: %d",
-                               __FUNCTION__, 
-                               urb->status);
+                               __func__,
+                               status);
                        break ;
 
        }
@@ -501,87 +495,67 @@ static void ir_read_bulk_callback (struct urb *urb)
 static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
 {
        unsigned char *transfer_buffer;
-       unsigned int cflag;
        int result;
+       speed_t baud;
+       int ir_baud;
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __func__, port->number);
 
-       if ((!port->tty) || (!port->tty->termios)) {
-               dbg("%s - no tty structures", __FUNCTION__);
-               return;
-       }
+       baud = tty_get_baud_rate(port->tty);
 
-       cflag = port->tty->termios->c_cflag;
-       /* check that they really want us to change something */
-       if (old_termios) {
-               if ((cflag == old_termios->c_cflag) &&
-                   (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
-                       dbg("%s - nothing to change...", __FUNCTION__);
-                       return;
-               }
+       /*
+        * FIXME, we should compare the baud request against the
+        * capability stated in the IR header that we got in the
+        * startup function.
+        */
+
+       switch (baud) {
+               case 2400:      ir_baud = SPEED_2400; break;
+               case 9600:      ir_baud = SPEED_9600; break;
+               case 19200:     ir_baud = SPEED_19200; break;
+               case 38400:     ir_baud = SPEED_38400; break;
+               case 57600:     ir_baud = SPEED_57600; break;
+               case 115200:    ir_baud = SPEED_115200; break;
+               case 576000:    ir_baud = SPEED_576000; break;
+               case 1152000:   ir_baud = SPEED_1152000; break;
+               case 4000000:   ir_baud = SPEED_4000000; break;
+                       break;
+               default:
+                       ir_baud = SPEED_9600;
+                       baud = 9600;
        }
 
-       /* All we can change is the baud rate */
-       if (cflag & CBAUD) {
-
-               dbg ("%s - asking for baud %d",
-                       __FUNCTION__,
-                       tty_get_baud_rate(port->tty));
-
-               /* 
-                * FIXME, we should compare the baud request against the
-                * capability stated in the IR header that we got in the
-                * startup function.
-                */
-               switch (cflag & CBAUD) {
-                       case B2400:    ir_baud = SPEED_2400;    break;
-                       default:
-                       case B9600:    ir_baud = SPEED_9600;    break;
-                       case B19200:   ir_baud = SPEED_19200;   break;
-                       case B38400:   ir_baud = SPEED_38400;   break;
-                       case B57600:   ir_baud = SPEED_57600;   break;
-                       case B115200:  ir_baud = SPEED_115200;  break;
-                       case B576000:  ir_baud = SPEED_576000;  break;
-                       case B1152000: ir_baud = SPEED_1152000; break;
-#ifdef B4000000
-                       case B4000000: ir_baud = SPEED_4000000; break;
-#endif
-               }
+       if (xbof == -1)
+               ir_xbof = ir_xbof_change(ir_add_bof);
+       else
+               ir_xbof = ir_xbof_change(xbof) ;
 
-               if (xbof == -1) {
-                       ir_xbof = ir_xbof_change(ir_add_bof);
-               } else {
-                       ir_xbof = ir_xbof_change(xbof) ;
-               }
+       /* FIXME need to check to see if our write urb is busy right
+        * now, or use a urb pool.
+        *
+        * send the baud change out on an "empty" data packet
+        */
+       transfer_buffer = port->write_urb->transfer_buffer;
+       *transfer_buffer = ir_xbof | ir_baud;
 
-               /* Notify the tty driver that the termios have changed. */
-               port->tty->ldisc.set_termios(port->tty, NULL);
-
-               /* FIXME need to check to see if our write urb is busy right
-                * now, or use a urb pool.
-                *
-                * send the baud change out on an "empty" data packet
-                */
-               transfer_buffer = port->write_urb->transfer_buffer;
-               *transfer_buffer = ir_xbof | ir_baud;
-
-               usb_fill_bulk_urb (
-                       port->write_urb,
-                       port->serial->dev,
-                       usb_sndbulkpipe(port->serial->dev,
-                               port->bulk_out_endpointAddress),
-                       port->write_urb->transfer_buffer,
-                       1,
-                       ir_write_bulk_callback,
-                       port);
-
-               port->write_urb->transfer_flags = URB_ZERO_PACKET;
-
-               result = usb_submit_urb (port->write_urb, GFP_KERNEL);
-               if (result)
-                       dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
-       }
-       return;
+       usb_fill_bulk_urb (
+               port->write_urb,
+               port->serial->dev,
+               usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress),
+               port->write_urb->transfer_buffer,
+               1,
+               ir_write_bulk_callback,
+               port);
+
+       port->write_urb->transfer_flags = URB_ZERO_PACKET;
+
+       result = usb_submit_urb (port->write_urb, GFP_KERNEL);
+       if (result)
+               dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__, result);
+
+       /* Only speed changes are supported */
+       tty_termios_copy_hw(port->tty->termios, old_termios);
+       tty_encode_baud_rate(port->tty, baud, baud);
 }