[PATCH] USB: convert a bunch of USB semaphores to mutexes
[platform/kernel/linux-starfive.git] / drivers / usb / class / cdc-acm.c
index 248279e..6dd339f 100644 (file)
@@ -60,6 +60,7 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/smp_lock.h>
+#include <linux/mutex.h>
 #include <asm/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb_cdc.h>
@@ -80,7 +81,7 @@ static struct usb_driver acm_driver;
 static struct tty_driver *acm_tty_driver;
 static struct acm *acm_table[ACM_TTY_MINORS];
 
-static DECLARE_MUTEX(open_sem);
+static DEFINE_MUTEX(open_mutex);
 
 #define ACM_READY(acm) (acm && acm->dev && acm->used)
 
@@ -335,14 +336,9 @@ next_buffer:
 
        dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d\n", buf, buf->size);
 
-       for (i = 0; i < buf->size && !acm->throttle; i++) {
-               /* if we insert more than TTY_FLIPBUF_SIZE characters,
-                  we drop them. */
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                       tty_flip_buffer_push(tty);
-               }
-               tty_insert_flip_char(tty, buf->base[i], 0);
-       }
+       tty_buffer_request_room(tty, buf->size);
+       if (!acm->throttle)
+               tty_insert_flip_string(tty, buf->base, buf->size);
        tty_flip_buffer_push(tty);
 
        spin_lock(&acm->throttle_lock);
@@ -436,8 +432,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
        int rv = -EINVAL;
        int i;
        dbg("Entering acm_tty_open.\n");
-       
-       down(&open_sem);
+
+       mutex_lock(&open_mutex);
 
        acm = acm_table[tty->index];
        if (!acm || !acm->dev)
@@ -479,14 +475,14 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
 
 done:
 err_out:
-       up(&open_sem);
+       mutex_unlock(&open_mutex);
        return rv;
 
 full_bailout:
        usb_kill_urb(acm->ctrlurb);
 bail_out:
        acm->used--;
-       up(&open_sem);
+       mutex_unlock(&open_mutex);
        return -EIO;
 }
 
@@ -512,7 +508,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
        if (!acm || !acm->used)
                return;
 
-       down(&open_sem);
+       mutex_lock(&open_mutex);
        if (!--acm->used) {
                if (acm->dev) {
                        acm_set_control(acm, acm->ctrlout = 0);
@@ -523,7 +519,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
                } else
                        acm_tty_unregister(acm);
        }
-       up(&open_sem);
+       mutex_unlock(&open_mutex);
 }
 
 static int acm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
@@ -1018,9 +1014,14 @@ static void acm_disconnect(struct usb_interface *intf)
                return;
        }
 
-       down(&open_sem);
+       mutex_lock(&open_mutex);
+       if (!usb_get_intfdata(intf)) {
+               mutex_unlock(&open_mutex);
+               return;
+       }
        acm->dev = NULL;
-       usb_set_intfdata (intf, NULL);
+       usb_set_intfdata(acm->control, NULL);
+       usb_set_intfdata(acm->data, NULL);
 
        tasklet_disable(&acm->urb_task);
 
@@ -1041,15 +1042,15 @@ static void acm_disconnect(struct usb_interface *intf)
        for (i = 0; i < ACM_NRB; i++)
                usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma);
 
-       usb_driver_release_interface(&acm_driver, acm->data);
+       usb_driver_release_interface(&acm_driver, intf == acm->control ? acm->data : intf);
 
        if (!acm->used) {
                acm_tty_unregister(acm);
-               up(&open_sem);
+               mutex_unlock(&open_mutex);
                return;
        }
 
-       up(&open_sem);
+       mutex_unlock(&open_mutex);
 
        if (acm->tty)
                tty_hangup(acm->tty);