tty: The big operations rework
[linux-2.6-block.git] / drivers / usb / serial / whiteheat.c
index cc8b44c08712c67c1c41448c18b17ff23950228a..f07e8a4c1f3ddb3b3cfe12f4a3b22bef7e7c11a9 100644 (file)
@@ -164,9 +164,6 @@ static struct usb_serial_driver whiteheat_fake_device = {
        .description =          "Connect Tech - WhiteHEAT - (prerenumeration)",
        .usb_driver =           &whiteheat_driver,
        .id_table =             id_table_prerenumeration,
-       .num_interrupt_in =     NUM_DONT_CARE,
-       .num_bulk_in =          NUM_DONT_CARE,
-       .num_bulk_out =         NUM_DONT_CARE,
        .num_ports =            1,
        .probe =                whiteheat_firmware_download,
        .attach =               whiteheat_firmware_attach,
@@ -180,9 +177,6 @@ static struct usb_serial_driver whiteheat_device = {
        .description =          "Connect Tech - WhiteHEAT",
        .usb_driver =           &whiteheat_driver,
        .id_table =             id_table_std,
-       .num_interrupt_in =     NUM_DONT_CARE,
-       .num_bulk_in =          NUM_DONT_CARE,
-       .num_bulk_out =         NUM_DONT_CARE,
        .num_ports =            4,
        .attach =               whiteheat_attach,
        .shutdown =             whiteheat_shutdown,
@@ -225,7 +219,7 @@ struct whiteheat_urb_wrap {
 struct whiteheat_private {
        spinlock_t              lock;
        __u8                    flags;
-       __u8                    mcr;
+       __u8                    mcr;            /* FIXME: no locking on mcr */
        struct list_head        rx_urbs_free;
        struct list_head        rx_urbs_submitted;
        struct list_head        rx_urb_q;
@@ -288,7 +282,7 @@ static int whiteheat_firmware_download (struct usb_serial *serial, const struct
        int response;
        const struct whiteheat_hex_record *record;
        
-       dbg("%s", __FUNCTION__);
+       dbg("%s", __func__);
        
        response = ezusb_set_reset (serial, 1);
 
@@ -298,7 +292,7 @@ static int whiteheat_firmware_download (struct usb_serial *serial, const struct
                                (unsigned char *)record->data, record->data_size, 0xa0);
                if (response < 0) {
                        err("%s - ezusb_writememory failed for loader (%d %04X %p %d)",
-                               __FUNCTION__, response, record->address, record->data, record->data_size);
+                               __func__, response, record->address, record->data, record->data_size);
                        break;
                }
                ++record;
@@ -315,7 +309,7 @@ static int whiteheat_firmware_download (struct usb_serial *serial, const struct
                                (unsigned char *)record->data, record->data_size, 0xa3);
                if (response < 0) {
                        err("%s - ezusb_writememory failed for first firmware step (%d %04X %p %d)", 
-                               __FUNCTION__, response, record->address, record->data, record->data_size);
+                               __func__, response, record->address, record->data, record->data_size);
                        break;
                }
                ++record;
@@ -329,7 +323,7 @@ static int whiteheat_firmware_download (struct usb_serial *serial, const struct
                                (unsigned char *)record->data, record->data_size, 0xa0);
                if (response < 0) {
                        err("%s - ezusb_writememory failed for second firmware step (%d %04X %p %d)", 
-                               __FUNCTION__, response, record->address, record->data, record->data_size);
+                               __func__, response, record->address, record->data, record->data_size);
                        break;
                }
                ++record;
@@ -567,7 +561,7 @@ static void whiteheat_shutdown (struct usb_serial *serial)
        struct list_head *tmp2;
        int i;
 
-       dbg("%s", __FUNCTION__);
+       dbg("%s", __func__);
 
        /* free up our private data for our command port */
        command_port = serial->port[COMMAND_PORT];
@@ -604,14 +598,13 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
        int             retval = 0;
        struct ktermios old_term;
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __func__, port->number);
 
        retval = start_command_port(port->serial);
        if (retval)
                goto exit;
 
-       if (port->tty)
-               port->tty->low_latency = 1;
+       port->tty->low_latency = 1;
 
        /* send an open port command */
        retval = firm_open(port);
@@ -638,14 +631,14 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
        /* Start reading from the device */
        retval = start_port_read(port);
        if (retval) {
-               err("%s - failed submitting read urb, error %d", __FUNCTION__, retval);
+               err("%s - failed submitting read urb, error %d", __func__, retval);
                firm_close(port);
                stop_command_port(port->serial);
                goto exit;
        }
 
 exit:
-       dbg("%s - exit, retval = %d", __FUNCTION__, retval);
+       dbg("%s - exit, retval = %d", __func__, retval);
        return retval;
 }
 
@@ -658,12 +651,15 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
        struct list_head *tmp;
        struct list_head *tmp2;
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
-       
+       dbg("%s - port %d", __func__, port->number);
+
+       mutex_lock(&port->serial->disc_mutex);
        /* filp is NULL when called from usb_serial_disconnect */
-       if (filp && (tty_hung_up_p(filp))) {
+       if ((filp && (tty_hung_up_p(filp))) || port->serial->disconnected) {
+               mutex_unlock(&port->serial->disc_mutex);
                return;
        }
+       mutex_unlock(&port->serial->disc_mutex);
 
        port->tty->closing = 1;
 
@@ -677,15 +673,13 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
        }
 */
 
-       if (port->tty->driver->flush_buffer)
-               port->tty->driver->flush_buffer(port->tty);
+       tty_driver_flush_buffer(port->tty);
        tty_ldisc_flush(port->tty);
 
        firm_report_tx_done(port);
 
        firm_close(port);
 
-printk(KERN_ERR"Before processing rx_urbs_submitted.\n");
        /* shutdown our bulk reads and writes */
        mutex_lock(&info->deathwarrant);
        spin_lock_irq(&info->lock);
@@ -730,10 +724,10 @@ static int whiteheat_write(struct usb_serial_port *port, const unsigned char *bu
        unsigned long flags;
        struct list_head *tmp;
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __func__, port->number);
 
        if (count == 0) {
-               dbg("%s - write request of 0 bytes", __FUNCTION__);
+               dbg("%s - write request of 0 bytes", __func__);
                return (0);
        }
 
@@ -752,13 +746,13 @@ static int whiteheat_write(struct usb_serial_port *port, const unsigned char *bu
                bytes = (count > port->bulk_out_size) ? port->bulk_out_size : count;
                memcpy (urb->transfer_buffer, buf + sent, bytes);
 
-               usb_serial_debug_data(debug, &port->dev, __FUNCTION__, bytes, urb->transfer_buffer);
+               usb_serial_debug_data(debug, &port->dev, __func__, bytes, urb->transfer_buffer);
 
                urb->dev = serial->dev;
                urb->transfer_buffer_length = bytes;
                result = usb_submit_urb(urb, GFP_ATOMIC);
                if (result) {
-                       err("%s - failed submitting write urb, error %d", __FUNCTION__, result);
+                       err("%s - failed submitting write urb, error %d", __func__, result);
                        sent = result;
                        spin_lock_irqsave(&info->lock, flags);
                        list_add(tmp, &info->tx_urbs_free);
@@ -784,7 +778,7 @@ static int whiteheat_write_room(struct usb_serial_port *port)
        int room = 0;
        unsigned long flags;
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __func__, port->number);
        
        spin_lock_irqsave(&info->lock, flags);
        list_for_each(tmp, &info->tx_urbs_free)
@@ -792,7 +786,7 @@ static int whiteheat_write_room(struct usb_serial_port *port)
        spin_unlock_irqrestore(&info->lock, flags);
        room *= port->bulk_out_size;
 
-       dbg("%s - returns %d", __FUNCTION__, room);
+       dbg("%s - returns %d", __func__, room);
        return (room);
 }
 
@@ -802,7 +796,7 @@ static int whiteheat_tiocmget (struct usb_serial_port *port, struct file *file)
        struct whiteheat_private *info = usb_get_serial_port_data(port);
        unsigned int modem_signals = 0;
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __func__, port->number);
 
        firm_get_dtr_rts(port);
        if (info->mcr & UART_MCR_DTR)
@@ -819,7 +813,7 @@ static int whiteheat_tiocmset (struct usb_serial_port *port, struct file *file,
 {
        struct whiteheat_private *info = usb_get_serial_port_data(port);
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __func__, port->number);
 
        if (set & TIOCM_RTS)
                info->mcr |= UART_MCR_RTS;
@@ -842,7 +836,7 @@ static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, un
        struct serial_struct serstruct;
        void __user *user_arg = (void __user *)arg;
 
-       dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd);
+       dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);
 
        switch (cmd) {
                case TIOCGSERIAL:
@@ -884,17 +878,8 @@ static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, un
 
 static void whiteheat_set_termios(struct usb_serial_port *port, struct ktermios *old_termios)
 {
-       dbg("%s -port %d", __FUNCTION__, port->number);
-
-       if ((!port->tty) || (!port->tty->termios)) {
-               dbg("%s - no tty structures", __FUNCTION__);
-               goto exit;
-       }
-       
+       dbg("%s -port %d", __func__, port->number);
        firm_setup_port(port);
-
-exit:
-       return;
 }
 
 
@@ -911,7 +896,7 @@ static int whiteheat_chars_in_buffer(struct usb_serial_port *port)
        int chars = 0;
        unsigned long flags;
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __func__, port->number);
 
        spin_lock_irqsave(&info->lock, flags);
        list_for_each(tmp, &info->tx_urbs_submitted) {
@@ -920,7 +905,7 @@ static int whiteheat_chars_in_buffer(struct usb_serial_port *port)
        }
        spin_unlock_irqrestore(&info->lock, flags);
 
-       dbg ("%s - returns %d", __FUNCTION__, chars);
+       dbg ("%s - returns %d", __func__, chars);
        return chars;
 }
 
@@ -930,7 +915,7 @@ static void whiteheat_throttle (struct usb_serial_port *port)
        struct whiteheat_private *info = usb_get_serial_port_data(port);
        unsigned long flags;
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __func__, port->number);
 
        spin_lock_irqsave(&info->lock, flags);
        info->flags |= THROTTLED;
@@ -946,7 +931,7 @@ static void whiteheat_unthrottle (struct usb_serial_port *port)
        int actually_throttled;
        unsigned long flags;
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __func__, port->number);
 
        spin_lock_irqsave(&info->lock, flags);
        actually_throttled = info->flags & ACTUALLY_THROTTLED;
@@ -967,7 +952,7 @@ static void command_port_write_callback(struct urb *urb)
 {
        int status = urb->status;
 
-       dbg("%s", __FUNCTION__);
+       dbg("%s", __func__);
 
        if (status) {
                dbg("nonzero urb status: %d", status);
@@ -978,28 +963,28 @@ static void command_port_write_callback(struct urb *urb)
 
 static void command_port_read_callback(struct urb *urb)
 {
-       struct usb_serial_port *command_port = (struct usb_serial_port *)urb->context;
+       struct usb_serial_port *command_port = urb->context;
        struct whiteheat_command_private *command_info;
        int status = urb->status;
        unsigned char *data = urb->transfer_buffer;
        int result;
 
-       dbg("%s", __FUNCTION__);
+       dbg("%s", __func__);
 
        command_info = usb_get_serial_port_data(command_port);
        if (!command_info) {
-               dbg ("%s - command_info is NULL, exiting.", __FUNCTION__);
+               dbg ("%s - command_info is NULL, exiting.", __func__);
                return;
        }
        if (status) {
-               dbg("%s - nonzero urb status: %d", __FUNCTION__, status);
+               dbg("%s - nonzero urb status: %d", __func__, status);
                if (status != -ENOENT)
                        command_info->command_finished = WHITEHEAT_CMD_FAILURE;
                wake_up(&command_info->wait_command);
                return;
        }
 
-       usb_serial_debug_data(debug, &command_port->dev, __FUNCTION__, urb->actual_length, data);
+       usb_serial_debug_data(debug, &command_port->dev, __func__, urb->actual_length, data);
 
        if (data[0] == WHITEHEAT_CMD_COMPLETE) {
                command_info->command_finished = WHITEHEAT_CMD_COMPLETE;
@@ -1009,38 +994,38 @@ static void command_port_read_callback(struct urb *urb)
                wake_up(&command_info->wait_command);
        } else if (data[0] == WHITEHEAT_EVENT) {
                /* These are unsolicited reports from the firmware, hence no waiting command to wakeup */
-               dbg("%s - event received", __FUNCTION__);
+               dbg("%s - event received", __func__);
        } else if (data[0] == WHITEHEAT_GET_DTR_RTS) {
                memcpy(command_info->result_buffer, &data[1], urb->actual_length - 1);
                command_info->command_finished = WHITEHEAT_CMD_COMPLETE;
                wake_up(&command_info->wait_command);
        } else {
-               dbg("%s - bad reply from firmware", __FUNCTION__);
+               dbg("%s - bad reply from firmware", __func__);
        }
        
        /* Continue trying to always read */
        command_port->read_urb->dev = command_port->serial->dev;
        result = usb_submit_urb(command_port->read_urb, GFP_ATOMIC);
        if (result)
-               dbg("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);
+               dbg("%s - failed resubmitting read urb, error %d", __func__, result);
 }
 
 
 static void whiteheat_read_callback(struct urb *urb)
 {
-       struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       struct usb_serial_port *port = urb->context;
        struct whiteheat_urb_wrap *wrap;
        unsigned char *data = urb->transfer_buffer;
        struct whiteheat_private *info = usb_get_serial_port_data(port);
        int status = urb->status;
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __func__, port->number);
 
        spin_lock(&info->lock);
        wrap = urb_to_wrap(urb, &info->rx_urbs_submitted);
        if (!wrap) {
                spin_unlock(&info->lock);
-               err("%s - Not my urb!", __FUNCTION__);
+               err("%s - Not my urb!", __func__);
                return;
        }
        list_del(&wrap->list);
@@ -1048,14 +1033,14 @@ static void whiteheat_read_callback(struct urb *urb)
 
        if (status) {
                dbg("%s - nonzero read bulk status received: %d",
-                   __FUNCTION__, status);
+                   __func__, status);
                spin_lock(&info->lock);
                list_add(&wrap->list, &info->rx_urbs_free);
                spin_unlock(&info->lock);
                return;
        }
 
-       usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
+       usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
 
        spin_lock(&info->lock);
        list_add_tail(&wrap->list, &info->rx_urb_q);
@@ -1072,18 +1057,18 @@ static void whiteheat_read_callback(struct urb *urb)
 
 static void whiteheat_write_callback(struct urb *urb)
 {
-       struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       struct usb_serial_port *port = urb->context;
        struct whiteheat_private *info = usb_get_serial_port_data(port);
        struct whiteheat_urb_wrap *wrap;
        int status = urb->status;
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __func__, port->number);
 
        spin_lock(&info->lock);
        wrap = urb_to_wrap(urb, &info->tx_urbs_submitted);
        if (!wrap) {
                spin_unlock(&info->lock);
-               err("%s - Not my urb!", __FUNCTION__);
+               err("%s - Not my urb!", __func__);
                return;
        }
        list_move(&wrap->list, &info->tx_urbs_free);
@@ -1091,7 +1076,7 @@ static void whiteheat_write_callback(struct urb *urb)
 
        if (status) {
                dbg("%s - nonzero write bulk status received: %d",
-                   __FUNCTION__, status);
+                   __func__, status);
                return;
        }
 
@@ -1111,7 +1096,7 @@ static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *d
        int retval = 0;
        int t;
 
-       dbg("%s - command %d", __FUNCTION__, command);
+       dbg("%s - command %d", __func__, command);
 
        command_port = port->serial->port[COMMAND_PORT];
        command_info = usb_get_serial_port_data(command_port);
@@ -1125,7 +1110,7 @@ static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *d
        command_port->write_urb->dev = port->serial->dev;
        retval = usb_submit_urb (command_port->write_urb, GFP_NOIO);
        if (retval) {
-               dbg("%s - submit urb failed", __FUNCTION__);
+               dbg("%s - submit urb failed", __func__);
                goto exit;
        }
 
@@ -1136,19 +1121,19 @@ static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *d
                usb_kill_urb(command_port->write_urb);
 
        if (command_info->command_finished == false) {
-               dbg("%s - command timed out.", __FUNCTION__);
+               dbg("%s - command timed out.", __func__);
                retval = -ETIMEDOUT;
                goto exit;
        }
 
        if (command_info->command_finished == WHITEHEAT_CMD_FAILURE) {
-               dbg("%s - command failed.", __FUNCTION__);
+               dbg("%s - command failed.", __func__);
                retval = -EIO;
                goto exit;
        }
 
        if (command_info->command_finished == WHITEHEAT_CMD_COMPLETE) {
-               dbg("%s - command completed.", __FUNCTION__);
+               dbg("%s - command completed.", __func__);
                switch (command) {
                        case WHITEHEAT_GET_DTR_RTS:
                                info = usb_get_serial_port_data(port);
@@ -1193,7 +1178,7 @@ static int firm_setup_port(struct usb_serial_port *port) {
                default:
                case CS8:       port_settings.bits = 8;   break;
        }
-       dbg("%s - data bits = %d", __FUNCTION__, port_settings.bits);
+       dbg("%s - data bits = %d", __func__, port_settings.bits);
        
        /* determine the parity */
        if (cflag & PARENB)
@@ -1209,21 +1194,21 @@ static int firm_setup_port(struct usb_serial_port *port) {
                                port_settings.parity = WHITEHEAT_PAR_EVEN;
        else
                port_settings.parity = WHITEHEAT_PAR_NONE;
-       dbg("%s - parity = %c", __FUNCTION__, port_settings.parity);
+       dbg("%s - parity = %c", __func__, port_settings.parity);
 
        /* figure out the stop bits requested */
        if (cflag & CSTOPB)
                port_settings.stop = 2;
        else
                port_settings.stop = 1;
-       dbg("%s - stop bits = %d", __FUNCTION__, port_settings.stop);
+       dbg("%s - stop bits = %d", __func__, port_settings.stop);
 
        /* figure out the flow control settings */
        if (cflag & CRTSCTS)
                port_settings.hflow = (WHITEHEAT_HFLOW_CTS | WHITEHEAT_HFLOW_RTS);
        else
                port_settings.hflow = WHITEHEAT_HFLOW_NONE;
-       dbg("%s - hardware flow control = %s %s %s %s", __FUNCTION__,
+       dbg("%s - hardware flow control = %s %s %s %s", __func__,
            (port_settings.hflow & WHITEHEAT_HFLOW_CTS) ? "CTS" : "",
            (port_settings.hflow & WHITEHEAT_HFLOW_RTS) ? "RTS" : "",
            (port_settings.hflow & WHITEHEAT_HFLOW_DSR) ? "DSR" : "",
@@ -1234,16 +1219,18 @@ static int firm_setup_port(struct usb_serial_port *port) {
                port_settings.sflow = WHITEHEAT_SFLOW_RXTX;
        else
                port_settings.sflow = WHITEHEAT_SFLOW_NONE;
-       dbg("%s - software flow control = %c", __FUNCTION__, port_settings.sflow);
+       dbg("%s - software flow control = %c", __func__, port_settings.sflow);
        
        port_settings.xon = START_CHAR(port->tty);
        port_settings.xoff = STOP_CHAR(port->tty);
-       dbg("%s - XON = %2x, XOFF = %2x", __FUNCTION__, port_settings.xon, port_settings.xoff);
+       dbg("%s - XON = %2x, XOFF = %2x", __func__, port_settings.xon, port_settings.xoff);
 
        /* get the baud rate wanted */
        port_settings.baud = tty_get_baud_rate(port->tty);
-       dbg("%s - baud rate = %d", __FUNCTION__, port_settings.baud);
+       dbg("%s - baud rate = %d", __func__, port_settings.baud);
 
+       /* fixme: should set validated settings */
+       tty_encode_baud_rate(port->tty, port_settings.baud, port_settings.baud);
        /* handle any settings that aren't specified in the tty structure */
        port_settings.lloop = 0;
        
@@ -1323,7 +1310,7 @@ static int start_command_port(struct usb_serial *serial)
                command_port->read_urb->dev = serial->dev;
                retval = usb_submit_urb(command_port->read_urb, GFP_KERNEL);
                if (retval) {
-                       err("%s - failed submitting read urb, error %d", __FUNCTION__, retval);
+                       err("%s - failed submitting read urb, error %d", __func__, retval);
                        goto exit;
                }
        }
@@ -1459,7 +1446,7 @@ static void rx_data_softint(struct work_struct *work)
                urb->dev = port->serial->dev;
                result = usb_submit_urb(urb, GFP_ATOMIC);
                if (result) {
-                       err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);
+                       err("%s - failed resubmitting read urb, error %d", __func__, result);
                        spin_lock_irqsave(&info->lock, flags);
                        list_add(tmp, &info->rx_urbs_free);
                        continue;