Merge branch 'linus' into cont_syslog
[safe/jmp/linux-2.6] / drivers / usb / mon / mon_text.c
index ebb04ac..a545d65 100644 (file)
@@ -7,9 +7,11 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/usb.h>
+#include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/mutex.h>
 #include <linux/debugfs.h>
+#include <linux/scatterlist.h>
 #include <asm/uaccess.h>
 
 #include "usb_mon.h"
@@ -87,7 +89,7 @@ struct mon_reader_text {
 
 static struct dentry *mon_dir;         /* Usually /sys/kernel/debug/usbmon */
 
-static void mon_text_ctor(void *, struct kmem_cache *, unsigned long);
+static void mon_text_ctor(void *);
 
 struct mon_text_ptr {
        int cnt, limit;
@@ -137,6 +139,8 @@ 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, struct mon_bus *mbus)
 {
+       void *src;
+
        if (len <= 0)
                return 'L';
        if (len >= DATA_MAX)
@@ -150,24 +154,22 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
                        return '>';
        }
 
-       /*
-        * The check to see if it's safe to poke at data has an enormous
-        * number of corner cases, but it seems that the following is
-        * more or less safe.
-        *
-        * We do not even try to look at transfer_buffer, because it can
-        * contain non-NULL garbage in case the upper level promised to
-        * set DMA for the HCD.
-        */
-       if (urb->dev->bus->uses_dma &&
-           (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) {
-               return mon_dmapeek(ep->data, urb->transfer_dma, len);
-       }
+       if (urb->num_sgs == 0) {
+               src = urb->transfer_buffer;
+               if (src == NULL)
+                       return 'Z';     /* '0' would be not as pretty. */
+       } else {
+               struct scatterlist *sg = urb->sg;
 
-       if (urb->transfer_buffer == NULL)
-               return 'Z';     /* '0' would be not as pretty. */
+               if (PageHighMem(sg_page(sg)))
+                       return 'D';
+
+               /* For the text interface we copy only the first sg buffer */
+               len = min_t(int, sg->length, len);
+               src = sg_virt(sg);
+       }
 
-       memcpy(ep->data, urb->transfer_buffer, len);
+       memcpy(ep->data, src, len);
        return 0;
 }
 
@@ -177,7 +179,7 @@ static inline unsigned int mon_get_timestamp(void)
        unsigned int stamp;
 
        do_gettimeofday(&tval);
-       stamp = tval.tv_sec & 0xFFFF;   /* 2^32 = 4294967296. Limit to 4096s. */
+       stamp = tval.tv_sec & 0xFFF   /* 2^32 = 4294967296. Limit to 4096s. */
        stamp = stamp * 1000000 + tval.tv_usec;
        return stamp;
 }
@@ -270,12 +272,12 @@ static void mon_text_error(void *data, struct urb *urb, int error)
 
        ep->type = 'E';
        ep->id = (unsigned long) urb;
-       ep->busnum = 0;
+       ep->busnum = urb->dev->bus->busnum;
        ep->devnum = urb->dev->devnum;
        ep->epnum = usb_endpoint_num(&urb->ep->desc);
        ep->xfertype = usb_endpoint_type(&urb->ep->desc);
        ep->is_in = usb_urb_dir_in(urb);
-       ep->tstamp = 0;
+       ep->tstamp = mon_get_timestamp();
        ep->length = 0;
        ep->status = error;
 
@@ -720,7 +722,7 @@ void mon_text_del(struct mon_bus *mbus)
 /*
  * Slab interface: constructor.
  */
-static void mon_text_ctor(void *mem, struct kmem_cache *slab, unsigned long sflags)
+static void mon_text_ctor(void *mem)
 {
        /*
         * Nothing to initialize. No, really!
@@ -733,7 +735,7 @@ int __init mon_text_init(void)
 {
        struct dentry *mondir;
 
-       mondir = debugfs_create_dir("usbmon", NULL);
+       mondir = debugfs_create_dir("usbmon", usb_debug_root);
        if (IS_ERR(mondir)) {
                printk(KERN_NOTICE TAG ": debugfs is not available\n");
                return -ENODEV;