]> err.no Git - linux-2.6/blobdiff - drivers/usb/serial/cypress_m8.c
[MIPS] Added missing cases for rdhwr emulation
[linux-2.6] / drivers / usb / serial / cypress_m8.c
index 6bc1f404e1869c18b32679da0dd93ab8ad9b3aab..779d07851a4d820a4e32c372ed2e745798c82a27 100644 (file)
@@ -94,6 +94,7 @@ static struct usb_device_id id_table_earthmate [] = {
 
 static struct usb_device_id id_table_cyphidcomrs232 [] = {
        { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
+       { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) },
        { }                                             /* Terminating entry */
 };
 
@@ -106,6 +107,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) },
        { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) },
        { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
+       { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) },
        { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) },
        { }                                             /* Terminating entry */
 };
@@ -193,6 +195,7 @@ static struct usb_serial_driver cypress_earthmate_device = {
                .name =                 "earthmate",
        },
        .description =                  "DeLorme Earthmate USB",
+       .usb_driver =                   &cypress_driver,
        .id_table =                     id_table_earthmate,
        .num_interrupt_in =             1,
        .num_interrupt_out =            1,
@@ -222,6 +225,7 @@ static struct usb_serial_driver cypress_hidcom_device = {
                .name =                 "cyphidcom",
        },
        .description =                  "HID->COM RS232 Adapter",
+       .usb_driver =                   &cypress_driver,
        .id_table =                     id_table_cyphidcomrs232,
        .num_interrupt_in =             1,
        .num_interrupt_out =            1,
@@ -251,6 +255,7 @@ static struct usb_serial_driver cypress_ca42v2_device = {
                 .name =                        "nokiaca42v2",
        },
        .description =                  "Nokia CA-42 V2 Adapter",
+       .usb_driver =                   &cypress_driver,
        .id_table =                     id_table_nokiaca42v2,
        .num_interrupt_in =             1,
        .num_interrupt_out =            1,
@@ -679,7 +684,6 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp)
 {
        struct cypress_private *priv = usb_get_serial_port_data(port);
        unsigned int c_cflag;
-       unsigned long flags;
        int bps;
        long timeout;
        wait_queue_t wait;
@@ -687,7 +691,7 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp)
        dbg("%s - port %d", __FUNCTION__, port->number);
 
        /* wait for data to drain from buffer */
-       spin_lock_irqsave(&priv->lock, flags);
+       spin_lock_irq(&priv->lock);
        timeout = CYPRESS_CLOSING_WAIT;
        init_waitqueue_entry(&wait, current);
        add_wait_queue(&port->tty->write_wait, &wait);
@@ -695,18 +699,25 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp)
                set_current_state(TASK_INTERRUPTIBLE);
                if (cypress_buf_data_avail(priv->buf) == 0
                || timeout == 0 || signal_pending(current)
-               || !usb_get_intfdata(port->serial->interface))
+               /* without mutex, allowed due to harmless failure mode */
+               || port->serial->disconnected)
                        break;
-               spin_unlock_irqrestore(&priv->lock, flags);
+               spin_unlock_irq(&priv->lock);
                timeout = schedule_timeout(timeout);
-               spin_lock_irqsave(&priv->lock, flags);
+               spin_lock_irq(&priv->lock);
        }
        set_current_state(TASK_RUNNING);
        remove_wait_queue(&port->tty->write_wait, &wait);
        /* clear out any remaining data in the buffer */
        cypress_buf_clear(priv->buf);
-       spin_unlock_irqrestore(&priv->lock, flags);
-       
+       spin_unlock_irq(&priv->lock);
+
+       /* writing is potentially harmful, lock must be taken */
+       mutex_lock(&port->serial->disc_mutex);
+       if (port->serial->disconnected) {
+               mutex_unlock(&port->serial->disc_mutex);
+               return;
+       }
        /* wait for characters to drain from device */
        bps = tty_get_baud_rate(port->tty);
        if (bps > 1200)
@@ -724,10 +735,10 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp)
                if (c_cflag & HUPCL) {
                        /* drop dtr and rts */
                        priv = usb_get_serial_port_data(port);
-                       spin_lock_irqsave(&priv->lock, flags);
+                       spin_lock_irq(&priv->lock);
                        priv->line_control = 0;
                        priv->cmd_ctrl = 1;
-                       spin_unlock_irqrestore(&priv->lock, flags);
+                       spin_unlock_irq(&priv->lock);
                        cypress_write(port, NULL, 0);
                }
        }
@@ -735,6 +746,7 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp)
        if (stats)
                dev_info (&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n",
                          priv->bytes_in, priv->bytes_out, priv->cmd_count);
+       mutex_unlock(&port->serial->disc_mutex);
 } /* cypress_close */
 
 
@@ -1272,10 +1284,11 @@ static void cypress_read_int_callback(struct urb *urb)
        int bytes = 0;
        int result;
        int i = 0;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       switch (urb->status) {
+       switch (status) {
        case 0: /* success */
                break;
        case -ECONNRESET:
@@ -1289,7 +1302,7 @@ static void cypress_read_int_callback(struct urb *urb)
        default:
                /* something ugly is going on... */
                dev_err(&urb->dev->dev,"%s - unexpected nonzero read status received: %d\n",
-                       __FUNCTION__,urb->status);
+                       __FUNCTION__, status);
                cypress_set_dead(port);
                return;
        }
@@ -1416,10 +1429,11 @@ static void cypress_write_int_callback(struct urb *urb)
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct cypress_private *priv = usb_get_serial_port_data(port);
        int result;
+       int status = urb->status;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
-       
-       switch (urb->status) {
+
+       switch (status) {
                case 0:
                        /* success */
                        break;
@@ -1427,7 +1441,8 @@ static void cypress_write_int_callback(struct urb *urb)
                case -ENOENT:
                case -ESHUTDOWN:
                        /* this urb is terminated, clean up */
-                       dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
+                       dbg("%s - urb shutting down with status: %d",
+                           __FUNCTION__, status);
                        priv->write_urb_in_use = 0;
                        return;
                case -EPIPE: /* no break needed; clear halt and resubmit */
@@ -1435,7 +1450,8 @@ static void cypress_write_int_callback(struct urb *urb)
                                break;
                        usb_clear_halt(port->serial->dev, 0x02);
                        /* error in the urb, so we have to resubmit it */
-                       dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
+                       dbg("%s - nonzero write bulk status received: %d",
+                           __FUNCTION__, status);
                        port->interrupt_out_urb->transfer_buffer_length = 1;
                        port->interrupt_out_urb->dev = port->serial->dev;
                        result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC);
@@ -1447,7 +1463,7 @@ static void cypress_write_int_callback(struct urb *urb)
                        break;
                default:
                        dev_err(&urb->dev->dev,"%s - unexpected nonzero write status received: %d\n",
-                               __FUNCTION__,urb->status);
+                               __FUNCTION__, status);
                        cypress_set_dead(port);
                        break;
        }