Merge branch 'master' into 83xx
[powerpc.git] / drivers / usb / mon / mon_text.c
index f961a77..d38a127 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/usb.h>
 #include <linux/time.h>
 #include <linux/mutex.h>
+#include <linux/debugfs.h>
 #include <asm/uaccess.h>
 
 #include "usb_mon.h"
@@ -50,7 +51,7 @@ struct mon_event_text {
 
 #define SLAB_NAME_SZ  30
 struct mon_reader_text {
-       kmem_cache_t *e_slab;
+       struct kmem_cache *e_slab;
        int nevents;
        struct list_head e_list;
        struct mon_reader r;    /* In C, parent class can be placed anywhere */
@@ -63,7 +64,9 @@ struct mon_reader_text {
        char slab_name[SLAB_NAME_SZ];
 };
 
-static void mon_text_ctor(void *, kmem_cache_t *, unsigned long);
+static struct dentry *mon_dir;         /* Usually /sys/kernel/debug/usbmon */
+
+static void mon_text_ctor(void *, struct kmem_cache *, unsigned long);
 
 /*
  * mon_text_submit
@@ -75,13 +78,13 @@ static void mon_text_ctor(void *, kmem_cache_t *, unsigned long);
  */
 
 static inline char mon_text_get_setup(struct mon_event_text *ep,
-    struct urb *urb, char ev_type)
+    struct urb *urb, char ev_type, struct mon_bus *mbus)
 {
 
        if (!usb_pipecontrol(urb->pipe) || ev_type != 'S')
                return '-';
 
-       if (urb->transfer_flags & URB_NO_SETUP_DMA_MAP)
+       if (mbus->uses_dma && (urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
                return mon_dmapeek(ep->setup, urb->setup_dma, SETUP_MAX);
        if (urb->setup_packet == NULL)
                return 'Z';     /* '0' would be not as pretty. */
@@ -91,7 +94,7 @@ static inline char mon_text_get_setup(struct mon_event_text *ep,
 }
 
 static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
-    int len, char ev_type)
+    int len, char ev_type, struct mon_bus *mbus)
 {
        int pipe = urb->pipe;
 
@@ -117,7 +120,7 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
         * contain non-NULL garbage in case the upper level promised to
         * set DMA for the HCD.
         */
-       if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
+       if (mbus->uses_dma && (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))
                return mon_dmapeek(ep->data, urb->transfer_dma, len);
 
        if (urb->transfer_buffer == NULL)
@@ -147,7 +150,7 @@ static void mon_text_event(struct mon_reader_text *rp, struct urb *urb,
        stamp = mon_get_timestamp();
 
        if (rp->nevents >= EVENT_MAX ||
-           (ep = kmem_cache_alloc(rp->e_slab, SLAB_ATOMIC)) == NULL) {
+           (ep = kmem_cache_alloc(rp->e_slab, GFP_ATOMIC)) == NULL) {
                rp->r.m_bus->cnt_text_lost++;
                return;
        }
@@ -161,8 +164,9 @@ static void mon_text_event(struct mon_reader_text *rp, struct urb *urb,
        /* Collecting status makes debugging sense for submits, too */
        ep->status = urb->status;
 
-       ep->setup_flag = mon_text_get_setup(ep, urb, ev_type);
-       ep->data_flag = mon_text_get_data(ep, urb, ep->length, ev_type);
+       ep->setup_flag = mon_text_get_setup(ep, urb, ev_type, rp->r.m_bus);
+       ep->data_flag = mon_text_get_data(ep, urb, ep->length, ev_type,
+                       rp->r.m_bus);
 
        rp->nevents++;
        list_add_tail(&ep->e_link, &rp->e_list);
@@ -187,7 +191,7 @@ static void mon_text_error(void *data, struct urb *urb, int error)
        struct mon_event_text *ep;
 
        if (rp->nevents >= EVENT_MAX ||
-           (ep = kmem_cache_alloc(rp->e_slab, SLAB_ATOMIC)) == NULL) {
+           (ep = kmem_cache_alloc(rp->e_slab, GFP_ATOMIC)) == NULL) {
                rp->r.m_bus->cnt_text_lost++;
                return;
        }
@@ -238,7 +242,7 @@ static int mon_text_open(struct inode *inode, struct file *file)
        int rc;
 
        mutex_lock(&mon_lock);
-       mbus = inode->u.generic_ip;
+       mbus = inode->i_private;
        ubus = mbus->u_bus;
 
        rp = kzalloc(sizeof(struct mon_reader_text), GFP_KERNEL);
@@ -401,7 +405,7 @@ static int mon_text_release(struct inode *inode, struct file *file)
        struct mon_event_text *ep;
 
        mutex_lock(&mon_lock);
-       mbus = inode->u.generic_ip;
+       mbus = inode->i_private;
 
        if (mbus->nreaders <= 0) {
                printk(KERN_ERR TAG ": consistency error on close\n");
@@ -435,7 +439,7 @@ static int mon_text_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-struct file_operations mon_fops_text = {
+static const struct file_operations mon_fops_text = {
        .owner =        THIS_MODULE,
        .open =         mon_text_open,
        .llseek =       no_llseek,
@@ -446,10 +450,51 @@ struct file_operations mon_fops_text = {
        .release =      mon_text_release,
 };
 
+int mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus)
+{
+       struct dentry *d;
+       enum { NAMESZ = 10 };
+       char name[NAMESZ];
+       int rc;
+
+       rc = snprintf(name, NAMESZ, "%dt", ubus->busnum);
+       if (rc <= 0 || rc >= NAMESZ)
+               goto err_print_t;
+       d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text);
+       if (d == NULL)
+               goto err_create_t;
+       mbus->dent_t = d;
+
+       /* XXX The stats do not belong to here (text API), but oh well... */
+       rc = snprintf(name, NAMESZ, "%ds", ubus->busnum);
+       if (rc <= 0 || rc >= NAMESZ)
+               goto err_print_s;
+       d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_stat);
+       if (d == NULL)
+               goto err_create_s;
+       mbus->dent_s = d;
+
+       return 1;
+
+err_create_s:
+err_print_s:
+       debugfs_remove(mbus->dent_t);
+       mbus->dent_t = NULL;
+err_create_t:
+err_print_t:
+       return 0;
+}
+
+void mon_text_del(struct mon_bus *mbus)
+{
+       debugfs_remove(mbus->dent_t);
+       debugfs_remove(mbus->dent_s);
+}
+
 /*
  * Slab interface: constructor.
  */
-static void mon_text_ctor(void *mem, kmem_cache_t *slab, unsigned long sflags)
+static void mon_text_ctor(void *mem, struct kmem_cache *slab, unsigned long sflags)
 {
        /*
         * Nothing to initialize. No, really!
@@ -458,3 +503,24 @@ static void mon_text_ctor(void *mem, kmem_cache_t *slab, unsigned long sflags)
        memset(mem, 0xe5, sizeof(struct mon_event_text));
 }
 
+int __init mon_text_init(void)
+{
+       struct dentry *mondir;
+
+       mondir = debugfs_create_dir("usbmon", NULL);
+       if (IS_ERR(mondir)) {
+               printk(KERN_NOTICE TAG ": debugfs is not available\n");
+               return -ENODEV;
+       }
+       if (mondir == NULL) {
+               printk(KERN_NOTICE TAG ": unable to create usbmon directory\n");
+               return -ENODEV;
+       }
+       mon_dir = mondir;
+       return 0;
+}
+
+void __exit mon_text_exit(void)
+{
+       debugfs_remove(mon_dir);
+}