USB: ehci-dbg: increase debug buffer size for periodic file
authorMing Lei <tom.leiming@gmail.com>
Thu, 18 Sep 2008 15:06:21 +0000 (23:06 +0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 17 Oct 2008 21:40:57 +0000 (14:40 -0700)
This patch is based on the following ideas:

1. Some usb devices (such as usb video class) have endpoints of high
   interval attribute, so reading "periodic" file need more debug buffer
   to accommodate the qh or itd schedule information.  For example, 4KB
   buffer is not enough for a single interrupt qh of 2ms period.

2. print a %p need 16 byte buffer on 64-bits arch, but 8 byte on 32-bits
   arch. Add a extra bonus for 64-bits arch.

Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/host/ehci-dbg.c
drivers/usb/host/ehci-hcd.c

index b0f8ed5..9534ff3 100644 (file)
@@ -358,7 +358,8 @@ struct debug_buffer {
        struct usb_bus *bus;
        struct mutex mutex;     /* protect filling of buffer */
        size_t count;           /* number of characters filled into buffer */
-       char *page;
+       char *output_buf;
+       size_t alloc_size;
 };
 
 #define speed_char(info1) ({ char tmp; \
@@ -488,8 +489,8 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
 
        hcd = bus_to_hcd(buf->bus);
        ehci = hcd_to_ehci (hcd);
-       next = buf->page;
-       size = PAGE_SIZE;
+       next = buf->output_buf;
+       size = buf->alloc_size;
 
        *next = 0;
 
@@ -510,7 +511,7 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
        }
        spin_unlock_irqrestore (&ehci->lock, flags);
 
-       return strlen(buf->page);
+       return strlen(buf->output_buf);
 }
 
 #define DBG_SCHED_LIMIT 64
@@ -531,8 +532,8 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 
        hcd = bus_to_hcd(buf->bus);
        ehci = hcd_to_ehci (hcd);
-       next = buf->page;
-       size = PAGE_SIZE;
+       next = buf->output_buf;
+       size = buf->alloc_size;
 
        temp = scnprintf (next, size, "size = %d\n", ehci->periodic_size);
        size -= temp;
@@ -649,7 +650,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
        spin_unlock_irqrestore (&ehci->lock, flags);
        kfree (seen);
 
-       return PAGE_SIZE - size;
+       return buf->alloc_size - size;
 }
 #undef DBG_SCHED_LIMIT
 
@@ -665,8 +666,8 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 
        hcd = bus_to_hcd(buf->bus);
        ehci = hcd_to_ehci (hcd);
-       next = buf->page;
-       size = PAGE_SIZE;
+       next = buf->output_buf;
+       size = buf->alloc_size;
 
        spin_lock_irqsave (&ehci->lock, flags);
 
@@ -808,7 +809,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 done:
        spin_unlock_irqrestore (&ehci->lock, flags);
 
-       return PAGE_SIZE - size;
+       return buf->alloc_size - size;
 }
 
 static struct debug_buffer *alloc_buffer(struct usb_bus *bus,
@@ -822,6 +823,7 @@ static struct debug_buffer *alloc_buffer(struct usb_bus *bus,
                buf->bus = bus;
                buf->fill_func = fill_func;
                mutex_init(&buf->mutex);
+               buf->alloc_size = PAGE_SIZE;
        }
 
        return buf;
@@ -831,10 +833,10 @@ static int fill_buffer(struct debug_buffer *buf)
 {
        int ret = 0;
 
-       if (!buf->page)
-               buf->page = (char *)get_zeroed_page(GFP_KERNEL);
+       if (!buf->output_buf)
+               buf->output_buf = (char *)vmalloc(buf->alloc_size);
 
-       if (!buf->page) {
+       if (!buf->output_buf) {
                ret = -ENOMEM;
                goto out;
        }
@@ -867,7 +869,7 @@ static ssize_t debug_output(struct file *file, char __user *user_buf,
        mutex_unlock(&buf->mutex);
 
        ret = simple_read_from_buffer(user_buf, len, offset,
-                                     buf->page, buf->count);
+                                     buf->output_buf, buf->count);
 
 out:
        return ret;
@@ -879,8 +881,8 @@ static int debug_close(struct inode *inode, struct file *file)
        struct debug_buffer *buf = file->private_data;
 
        if (buf) {
-               if (buf->page)
-                       free_page((unsigned long)buf->page);
+               if (buf->output_buf)
+                       vfree(buf->output_buf);
                kfree(buf);
        }
 
@@ -895,10 +897,14 @@ static int debug_async_open(struct inode *inode, struct file *file)
 
 static int debug_periodic_open(struct inode *inode, struct file *file)
 {
-       file->private_data = alloc_buffer(inode->i_private,
-                                         fill_periodic_buffer);
+       struct debug_buffer *buf;
+       buf = alloc_buffer(inode->i_private, fill_periodic_buffer);
+       if (!buf)
+               return -ENOMEM;
 
-       return file->private_data ? 0 : -ENOMEM;
+       buf->alloc_size = (sizeof(void *) == 4 ? 6 : 8)*PAGE_SIZE;
+       file->private_data = buf;
+       return 0;
 }
 
 static int debug_registers_open(struct inode *inode, struct file *file)
index 8409e07..7378aa1 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/ioport.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/timer.h>