USB: cdc-acm: clean up open error handling
[firefly-linux-kernel-4.4.55.git] / drivers / usb / class / cdc-acm.c
index 3c0d4b913a898d2a7abe5a0f3ac5a2202e33967e..f239e3bd6423f89fd262298ab7f6d3642bb08658 100644 (file)
  *
  * Sponsored by SuSE
  *
- * ChangeLog:
- *     v0.9  - thorough cleaning, URBification, almost a rewrite
- *     v0.10 - some more cleanups
- *     v0.11 - fixed flow control, read error doesn't stop reads
- *     v0.12 - added TIOCM ioctls, added break handling, made struct acm
- *             kmalloced
- *     v0.13 - added termios, added hangup
- *     v0.14 - sized down struct acm
- *     v0.15 - fixed flow control again - characters could be lost
- *     v0.16 - added code for modems with swapped data and control interfaces
- *     v0.17 - added new style probing
- *     v0.18 - fixed new style probing for devices with more configurations
- *     v0.19 - fixed CLOCAL handling (thanks to Richard Shih-Ping Chan)
- *     v0.20 - switched to probing on interface (rather than device) class
- *     v0.21 - revert to probing on device for devices with multiple configs
- *     v0.22 - probe only the control interface. if usbcore doesn't choose the
- *             config we want, sysadmin changes bConfigurationValue in sysfs.
- *     v0.23 - use softirq for rx processing, as needed by tty layer
- *     v0.24 - change probe method to evaluate CDC union descriptor
- *     v0.25 - downstream tasks paralelized to maximize throughput
- *     v0.26 - multiple write urbs, writesize increased
- */
-
-/*
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
 #include "cdc-acm.h"
 
 
-#define ACM_CLOSE_TIMEOUT      15      /* seconds to let writes drain */
-
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v0.26"
 #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek"
 #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters"
 
@@ -534,8 +504,6 @@ static void acm_write_bulk(struct urb *urb)
        spin_unlock_irqrestore(&acm->write_lock, flags);
        if (ACM_READY(acm))
                schedule_work(&acm->work);
-       else
-               wake_up_interruptible(&acm->drain_wait);
 }
 
 static void acm_softint(struct work_struct *work)
@@ -600,7 +568,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
 
        if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS) &&
            (acm->ctrl_caps & USB_CDC_CAP_LINE))
-               goto full_bailout;
+               goto bail_out;
 
        usb_autopm_put_interface(acm->control);
 
@@ -624,8 +592,6 @@ out:
        mutex_unlock(&open_mutex);
        return rv;
 
-full_bailout:
-       usb_kill_urb(acm->ctrlurb);
 bail_out:
        acm->port.count--;
        mutex_unlock(&acm->mutex);
@@ -638,26 +604,24 @@ early_bail:
 
 static void acm_tty_unregister(struct acm *acm)
 {
-       int i, nr;
+       int i;
 
-       nr = acm->rx_buflimit;
        tty_unregister_device(acm_tty_driver, acm->minor);
        usb_put_intf(acm->control);
        acm_table[acm->minor] = NULL;
        usb_free_urb(acm->ctrlurb);
        for (i = 0; i < ACM_NW; i++)
                usb_free_urb(acm->wb[i].urb);
-       for (i = 0; i < nr; i++)
+       for (i = 0; i < acm->rx_buflimit; i++)
                usb_free_urb(acm->ru[i].urb);
        kfree(acm->country_codes);
        kfree(acm);
 }
 
-static int acm_tty_chars_in_buffer(struct tty_struct *tty);
-
 static void acm_port_down(struct acm *acm)
 {
-       int i, nr = acm->rx_buflimit;
+       int i;
+
        mutex_lock(&open_mutex);
        if (acm->dev) {
                usb_autopm_get_interface(acm->control);
@@ -666,7 +630,7 @@ static void acm_port_down(struct acm *acm)
                for (i = 0; i < ACM_NW; i++)
                        usb_kill_urb(acm->wb[i].urb);
                tasklet_disable(&acm->urb_task);
-               for (i = 0; i < nr; i++)
+               for (i = 0; i < acm->rx_buflimit; i++)
                        usb_kill_urb(acm->ru[i].urb);
                tasklet_enable(&acm->urb_task);
                acm->control->needs_remote_wakeup = 0;
@@ -916,9 +880,9 @@ static void acm_write_buffers_free(struct acm *acm)
 static void acm_read_buffers_free(struct acm *acm)
 {
        struct usb_device *usb_dev = interface_to_usbdev(acm->control);
-       int i, n = acm->rx_buflimit;
+       int i;
 
-       for (i = 0; i < n; i++)
+       for (i = 0; i < acm->rx_buflimit; i++)
                usb_free_coherent(usb_dev, acm->readsize,
                                  acm->rb[i].base, acm->rb[i].dma);
 }
@@ -1184,7 +1148,6 @@ made_compressed_probe:
        acm->urb_task.func = acm_rx_tasklet;
        acm->urb_task.data = (unsigned long) acm;
        INIT_WORK(&acm->work, acm_softint);
-       init_waitqueue_head(&acm->drain_wait);
        spin_lock_init(&acm->throttle_lock);
        spin_lock_init(&acm->write_lock);
        spin_lock_init(&acm->read_lock);
@@ -1736,8 +1699,7 @@ static int __init acm_init(void)
                return retval;
        }
 
-       printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
-              DRIVER_DESC "\n");
+       printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
 
        return 0;
 }