USB: sierra: add support for Sierra Wireless MC7710
[linux-flexiantxendom0.git] / drivers / usb / serial / sierra.c
index 66437f1..7c3ec9e 100644 (file)
@@ -289,6 +289,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */
        { USB_DEVICE(0x1199, 0x6859) }, /* Sierra Wireless AirCard 885 E */
        { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */
+       { USB_DEVICE(0x1199, 0x68A2) }, /* Sierra Wireless MC7710 */
        /* Sierra Wireless C885 */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)},
        /* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */
@@ -301,6 +302,9 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x1199, 0x68A3),   /* Sierra Wireless Direct IP modems */
          .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
        },
+       { USB_DEVICE(0x0f3d, 0x68A3),   /* Airprime/Sierra Wireless Direct IP modems */
+         .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
+       },
        { USB_DEVICE(0x413C, 0x08133) }, /* Dell Computer Corp. Wireless 5720 VZW Mobile Broadband (EVDO Rev-A) Minicard GPS Port */
 
        { }
@@ -373,7 +377,10 @@ static int sierra_send_setup(struct usb_serial_port *port)
        if (!do_send)
                return 0;
 
-       usb_autopm_get_interface(serial->interface);
+       retval = usb_autopm_get_interface(serial->interface);
+       if (retval < 0)
+               return retval;
+
        retval = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
                0x22, 0x21, val, interface, NULL, 0, USB_CTRL_SET_TIMEOUT);
        usb_autopm_put_interface(serial->interface);
@@ -408,7 +415,7 @@ static int sierra_tiocmget(struct tty_struct *tty)
        return value;
 }
 
-static int sierra_tiocmset(struct tty_struct *tty, struct file *file,
+static int sierra_tiocmset(struct tty_struct *tty,
                        unsigned int set, unsigned int clear)
 {
        struct usb_serial_port *port = tty->driver_data;
@@ -808,8 +815,12 @@ static void sierra_close(struct usb_serial_port *port)
                mutex_lock(&serial->disc_mutex);
                if (!serial->disconnected) {
                        serial->interface->needs_remote_wakeup = 0;
-                       usb_autopm_get_interface(serial->interface);
-                       sierra_send_setup(port);
+                       /* odd error handling due to pm counters */
+                       if (!usb_autopm_get_interface(serial->interface))
+                               sierra_send_setup(port);
+                       else
+                               usb_autopm_get_interface_no_resume(serial->interface);
+                               
                }
                mutex_unlock(&serial->disc_mutex);
                spin_lock_irq(&intfdata->susp_lock);
@@ -862,7 +873,8 @@ static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port)
                /* get rid of everything as in close */
                sierra_close(port);
                /* restore balance for autopm */
-               usb_autopm_put_interface(serial->interface);
+               if (!serial->disconnected)
+                       usb_autopm_put_interface(serial->interface);
                return err;
        }
        sierra_send_setup(port);
@@ -998,7 +1010,7 @@ static int sierra_suspend(struct usb_serial *serial, pm_message_t message)
        struct sierra_intf_private *intfdata;
        int b;
 
-       if (message.event & PM_EVENT_AUTO) {
+       if (PMSG_IS_AUTO(message)) {
                intfdata = serial->private;
                spin_lock_irq(&intfdata->susp_lock);
                b = intfdata->in_flight;