import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / usb / gadget / u_serial.c
index b369292d4b90cd0c5c66dd147434f5d8aadbd752..e464070e0fd8af7484ce5d94bc47ec8028a062ee 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "u_serial.h"
 
+#define ACM_LOG "USB_ACM"
 
 /*
  * This component encapsulates the TTY layer glue needed to provide basic
@@ -82,6 +83,7 @@
  */
 #define QUEUE_SIZE             16
 #define WRITE_BUF_SIZE         8192            /* TX only */
+#define REQ_BUF_SIZE           4096
 
 /* circular buffer */
 struct gs_buf {
@@ -365,6 +367,8 @@ __acquires(&port->port_lock)
        struct usb_ep           *in = port->port_usb->in;
        int                     status = 0;
        bool                    do_tty_wake = false;
+       static unsigned int     skip = 0;
+       static DEFINE_RATELIMIT_STATE(ratelimit, 1 * HZ, 10);
 
        while (!list_empty(pool)) {
                struct usb_request      *req;
@@ -374,7 +378,7 @@ __acquires(&port->port_lock)
                        break;
 
                req = list_entry(pool->next, struct usb_request, list);
-               len = gs_send_packet(port, req->buf, in->maxpacket);
+               len = gs_send_packet(port, req->buf, REQ_BUF_SIZE);
                if (len == 0) {
                        wake_up_interruptible(&port->drain_wait);
                        break;
@@ -389,6 +393,18 @@ __acquires(&port->port_lock)
                                port->port_num, len, *((u8 *)req->buf),
                                *((u8 *)req->buf+1), *((u8 *)req->buf+2));
 
+               if (__ratelimit(&ratelimit)) {
+                       printk( ACM_LOG \
+                               "%s: ttyGS%d: tx len=%d, 0x%02x 0x%02x 0x%02x ...\n", \
+                               __func__, port->port_num, len, *((u8 *)req->buf), \
+                               *((u8 *)req->buf+1), *((u8 *)req->buf+2));
+                       if (skip > 0) {
+                               printk( ACM_LOG "%s Too many data, skipped %d bytes", __func__, skip);
+                               skip = 0;
+                       }
+               } else
+                       skip += req->actual;
+
                /* Drop lock while we call out of driver; completions
                 * could be issued while we do so.  Disconnection may
                 * happen too; maybe immediately before we queue this!
@@ -487,6 +503,8 @@ static void gs_rx_push(unsigned long _port)
        struct list_head        *queue = &port->read_queue;
        bool                    disconnect = false;
        bool                    do_push = false;
+       static unsigned int     skip = 0;
+       static DEFINE_RATELIMIT_STATE(ratelimit, 1 * HZ, 10);
 
        /* hand any queued data to the tty */
        spin_lock_irq(&port->port_lock);
@@ -516,6 +534,18 @@ static void gs_rx_push(unsigned long _port)
                        break;
                }
 
+               if (__ratelimit(&ratelimit)) {
+                       printk( ACM_LOG \
+                               "%s: ttyGS%d: actual=%d, n_read=%d 0x%02x 0x%02x 0x%02x ...\n", \
+                               __func__, port->port_num, req->actual, port->n_read,
+                               *((u8 *)req->buf), *((u8 *)req->buf+1), *((u8 *)req->buf+2));
+                       if (skip > 0) {
+                               printk( ACM_LOG "%s Too many data, skipped %d bytes", __func__, skip);
+                               skip = 0;
+                       }
+               } else
+                       skip += req->actual;
+
                /* push data to (open) tty */
                if (req->actual) {
                        char            *packet = req->buf;
@@ -647,7 +677,7 @@ static int gs_alloc_requests(struct usb_ep *ep, struct list_head *head,
         * be as speedy as we might otherwise be.
         */
        for (i = 0; i < n; i++) {
-               req = gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC);
+               req = gs_alloc_req(ep, REQ_BUF_SIZE, GFP_ATOMIC);
                if (!req)
                        return list_empty(head) ? -ENOMEM : 0;
                req->complete = fn;
@@ -810,6 +840,9 @@ static int gs_open(struct tty_struct *tty, struct file *file)
 
        pr_debug("gs_open: ttyGS%d (%p,%p)\n", port->port_num, tty, file);
 
+       printk( ACM_LOG \
+               "gs_open: ttyGS%d (%p,%p)\n", port->port_num, tty, file);
+
        status = 0;
 
 exit_unlock_port:
@@ -846,6 +879,9 @@ static void gs_close(struct tty_struct *tty, struct file *file)
 
        pr_debug("gs_close: ttyGS%d (%p,%p) ...\n", port->port_num, tty, file);
 
+       printk( ACM_LOG \
+               "gs_close: ttyGS%d (%p,%p) ...\n", port->port_num, tty, file);
+
        /* mark port as closing but in use; we can drop port lock
         * and sleep if necessary
         */
@@ -895,6 +931,14 @@ static int gs_write(struct tty_struct *tty, const unsigned char *buf, int count)
        struct gs_port  *port = tty->driver_data;
        unsigned long   flags;
        int             status;
+       //ALPS00423739
+       if(!port)
+       {
+               printk("ERROR!!! port is closed!! %s, line %d: port = %p\n", __func__, __LINE__, port);
+               /*abort immediately after disconnect */
+               return -EINVAL;
+       }
+       //ALPS00423739
 
        pr_vdebug("gs_write: ttyGS%d (%p) writing %d bytes\n",
                        port->port_num, tty, count);
@@ -916,6 +960,15 @@ static int gs_put_char(struct tty_struct *tty, unsigned char ch)
        unsigned long   flags;
        int             status;
 
+       //ALPS00423739
+       if(!port)
+       {
+               printk("ERROR!!! port is closed!! %s, line %d: port = %p\n", __func__, __LINE__, port);
+               /*abort immediately after disconnect */
+               return -EINVAL;
+       }
+       //ALPS00423739
+
        pr_vdebug("gs_put_char: (%d,%p) char=0x%x, called from %pf\n",
                port->port_num, tty, ch, __builtin_return_address(0));
 
@@ -931,6 +984,15 @@ static void gs_flush_chars(struct tty_struct *tty)
        struct gs_port  *port = tty->driver_data;
        unsigned long   flags;
 
+       //ALPS00423739
+       if(!port)
+       {
+               printk("ERROR!!! port is closed!! %s, line %d: port = %p\n", __func__, __LINE__, port);
+               /*abort immediately after disconnect */
+               return;
+       }
+       //ALPS00423739
+
        pr_vdebug("gs_flush_chars: (%d,%p)\n", port->port_num, tty);
 
        spin_lock_irqsave(&port->port_lock, flags);
@@ -945,6 +1007,15 @@ static int gs_write_room(struct tty_struct *tty)
        unsigned long   flags;
        int             room = 0;
 
+       //ALPS00423739
+       if(!port)
+       {
+               printk("ERROR!!! port is closed!! %s, line %d: port = %p\n", __func__, __LINE__, port);
+               /*abort immediately after disconnect */
+               return -EINVAL;
+       }
+       //ALPS00423739
+
        spin_lock_irqsave(&port->port_lock, flags);
        if (port->port_usb)
                room = gs_buf_space_avail(&port->port_write_buf);
@@ -962,6 +1033,15 @@ static int gs_chars_in_buffer(struct tty_struct *tty)
        unsigned long   flags;
        int             chars = 0;
 
+       //ALPS00423739
+       if(!port)
+       {
+               printk("ERROR!!! port is closed!! %s, line %d: port = %p\n", __func__, __LINE__, port);
+               /*abort immediately after disconnect */
+               return -EINVAL;
+       }
+       //ALPS00423739
+
        spin_lock_irqsave(&port->port_lock, flags);
        chars = gs_buf_data_avail(&port->port_write_buf);
        spin_unlock_irqrestore(&port->port_lock, flags);
@@ -978,6 +1058,15 @@ static void gs_unthrottle(struct tty_struct *tty)
        struct gs_port          *port = tty->driver_data;
        unsigned long           flags;
 
+       //ALPS00423739
+       if(!port)
+       {
+               printk("ERROR!!! port is closed!! %s, line %d: port = %p\n", __func__, __LINE__, port);
+               /*abort immediately after disconnect */
+               return;
+       }
+       //ALPS00423739
+
        spin_lock_irqsave(&port->port_lock, flags);
        if (port->port_usb) {
                /* Kickstart read queue processing.  We don't do xon/xoff,
@@ -996,6 +1085,15 @@ static int gs_break_ctl(struct tty_struct *tty, int duration)
        int             status = 0;
        struct gserial  *gser;
 
+       //ALPS00423739
+       if(!port)
+       {
+               printk("ERROR!!! port is closed!! %s, line %d: port = %p\n", __func__, __LINE__, port);
+               /*abort immediately after disconnect */
+               return -EINVAL;
+       }
+       //ALPS00423739
+
        pr_vdebug("gs_break_ctl: ttyGS%d, send break (%d) \n",
                        port->port_num, duration);
 
@@ -1126,6 +1224,7 @@ int gserial_alloc_line(unsigned char *line_num)
 
        tty_dev = tty_port_register_device(&ports[port_num].port->port,
                        gs_tty_driver, port_num, NULL);
+
        if (IS_ERR(tty_dev)) {
                struct gs_port  *port;
                pr_err("%s: failed to register tty for port %d, err %ld\n",