staging: ozwpan: Added debug support
authorChris Kelly <ckelly@ozmodevices.com>
Mon, 20 Feb 2012 21:12:35 +0000 (21:12 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 24 Feb 2012 17:26:52 +0000 (09:26 -0800)
Added tracing facilities and also memory allocation and URB tracking.
This is for debugging purposes and is all optional and can be switched
out at compile time.

Signed-off-by: Chris Kelly <ckelly@ozmodevices.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/ozwpan/ozalloc.c [new file with mode: 0644]
drivers/staging/ozwpan/ozalloc.h [new file with mode: 0644]
drivers/staging/ozwpan/oztrace.c [new file with mode: 0644]
drivers/staging/ozwpan/oztrace.h [new file with mode: 0644]
drivers/staging/ozwpan/ozurbparanoia.c [new file with mode: 0644]
drivers/staging/ozwpan/ozurbparanoia.h [new file with mode: 0644]

diff --git a/drivers/staging/ozwpan/ozalloc.c b/drivers/staging/ozwpan/ozalloc.c
new file mode 100644 (file)
index 0000000..fe3cd40
--- /dev/null
@@ -0,0 +1,107 @@
+/* -----------------------------------------------------------------------------
+ * Copyright (c) 2011 Ozmo Inc
+ * Released under the GNU General Public License Version 2 (GPLv2).
+ * This file contains debug allocation and free functions. These are turned on
+ * by the configuration switch WANT_DEBUG_KMALLOC. This flags should be turned
+ * off in the release version but facilitate memory leak and corruption during
+ * development.
+ * -----------------------------------------------------------------------------
+ */
+#include <linux/module.h>
+#include "ozconfig.h"
+#include "ozalloc.h"
+#include "oztrace.h"
+#ifdef WANT_DEBUG_KMALLOC
+/*------------------------------------------------------------------------------
+ */
+#define MAGIC_1        0x12848796
+#define MAGIC_2        0x87465920
+#define MAGIC_3        0x80288264
+/*------------------------------------------------------------------------------
+ */
+struct oz_alloc_hdr {
+       int size;
+       int line;
+       unsigned magic;
+       struct list_head link;
+};
+/*------------------------------------------------------------------------------
+ */
+static unsigned long g_total_alloc_size;
+static int g_alloc_count;
+static DEFINE_SPINLOCK(g_alloc_lock);
+static LIST_HEAD(g_alloc_list);
+/*------------------------------------------------------------------------------
+ * Context: any
+ */
+void *oz_alloc_debug(size_t size, gfp_t flags, int line)
+{
+       struct oz_alloc_hdr *hdr = (struct oz_alloc_hdr *)
+               kmalloc(size + sizeof(struct oz_alloc_hdr) +
+                       sizeof(unsigned), flags);
+       if (hdr) {
+               unsigned long irq_state;
+               hdr->size = size;
+               hdr->line = line;
+               hdr->magic = MAGIC_1;
+               *(unsigned *)(((u8 *)(hdr + 1)) + size) = MAGIC_2;
+               spin_lock_irqsave(&g_alloc_lock, irq_state);
+               g_total_alloc_size += size;
+               g_alloc_count++;
+               list_add_tail(&hdr->link, &g_alloc_list);
+               spin_unlock_irqrestore(&g_alloc_lock, irq_state);
+               return hdr + 1;
+       }
+       return 0;
+}
+/*------------------------------------------------------------------------------
+ * Context: any
+ */
+void oz_free_debug(void *p)
+{
+       if (p) {
+               struct oz_alloc_hdr *hdr = (struct oz_alloc_hdr *)
+                       (((unsigned char *)p) - sizeof(struct oz_alloc_hdr));
+               if (hdr->magic == MAGIC_1) {
+                       unsigned long irq_state;
+                       if (*(unsigned *)(((u8 *)(hdr + 1)) + hdr->size)
+                               != MAGIC_2) {
+                               oz_trace("oz_free_debug: Corrupted beyond"
+                                       " %p size %d\n", hdr+1, hdr->size);
+                               return;
+                       }
+                       spin_lock_irqsave(&g_alloc_lock, irq_state);
+                       g_total_alloc_size -= hdr->size;
+                       g_alloc_count--;
+                       list_del(&hdr->link);
+                       spin_unlock_irqrestore(&g_alloc_lock, irq_state);
+                       hdr->magic = MAGIC_3;
+                       kfree(hdr);
+               } else {
+                       oz_trace("oz_free_debug: Invalid magic number %u\n",
+                               hdr->magic);
+               }
+       }
+}
+/*------------------------------------------------------------------------------
+ * Context: process
+ */
+void oz_trace_leaks(void)
+{
+#ifdef WANT_TRACE
+       struct list_head *e;
+       oz_trace("Total alloc size:%ld  Alloc count:%d\n",
+                       g_total_alloc_size, g_alloc_count);
+       if (g_alloc_count)
+               oz_trace("Trace of leaks.\n");
+       else
+               oz_trace("No memory leaks.\n");
+       list_for_each(e, &g_alloc_list) {
+               struct oz_alloc_hdr *hdr =
+                       container_of(e, struct oz_alloc_hdr, link);
+               oz_trace("LEAK size %d line %d\n", hdr->size, hdr->line);
+       }
+#endif /* #ifdef WANT_TRACE */
+}
+#endif /* #ifdef WANT_DEBUG_KMALLOC */
+
diff --git a/drivers/staging/ozwpan/ozalloc.h b/drivers/staging/ozwpan/ozalloc.h
new file mode 100644 (file)
index 0000000..11a7a16
--- /dev/null
@@ -0,0 +1,28 @@
+/* -----------------------------------------------------------------------------
+ * Copyright (c) 2011 Ozmo Inc
+ * Released under the GNU General Public License Version 2 (GPLv2).
+ * -----------------------------------------------------------------------------
+ */
+#ifndef _OZALLOC_H
+#define _OZALLOC_H
+
+#include <linux/slab.h>
+
+#ifdef WANT_DEBUG_KMALLOC
+
+void *oz_alloc_debug(size_t size, gfp_t flags, int line);
+void oz_free_debug(void *p);
+void oz_trace_leaks(void);
+#define oz_alloc(__s, __f)     oz_alloc_debug(__s, __f, __LINE__)
+#define oz_free                        oz_free_debug
+
+#else
+
+
+#define oz_alloc       kmalloc
+#define oz_free                kfree
+#define oz_trace_leaks()
+
+#endif /* #ifdef WANT_DEBUG_KMALLOC */
+
+#endif /* _OZALLOC_H */
diff --git a/drivers/staging/ozwpan/oztrace.c b/drivers/staging/ozwpan/oztrace.c
new file mode 100644 (file)
index 0000000..353ead2
--- /dev/null
@@ -0,0 +1,36 @@
+/* -----------------------------------------------------------------------------
+ * Copyright (c) 2011 Ozmo Inc
+ * Released under the GNU General Public License Version 2 (GPLv2).
+ * -----------------------------------------------------------------------------
+ */
+#include "ozconfig.h"
+#include "oztrace.h"
+
+#ifdef WANT_VERBOSE_TRACE
+unsigned long trace_flags =
+       0
+#ifdef WANT_TRACE_STREAM
+       | OZ_TRACE_STREAM
+#endif /* WANT_TRACE_STREAM */
+#ifdef WANT_TRACE_URB
+       | OZ_TRACE_URB
+#endif /* WANT_TRACE_URB */
+
+#ifdef WANT_TRACE_CTRL_DETAIL
+       | OZ_TRACE_CTRL_DETAIL
+#endif /* WANT_TRACE_CTRL_DETAIL */
+
+#ifdef WANT_TRACE_HUB
+       | OZ_TRACE_HUB
+#endif /* WANT_TRACE_HUB */
+
+#ifdef WANT_TRACE_RX_FRAMES
+       | OZ_TRACE_RX_FRAMES
+#endif /* WANT_TRACE_RX_FRAMES */
+
+#ifdef WANT_TRACE_TX_FRAMES
+       | OZ_TRACE_TX_FRAMES
+#endif /* WANT_TRACE_TX_FRAMES */
+       ;
+#endif /* WANT_VERBOSE_TRACE */
+
diff --git a/drivers/staging/ozwpan/oztrace.h b/drivers/staging/ozwpan/oztrace.h
new file mode 100644 (file)
index 0000000..8293b24
--- /dev/null
@@ -0,0 +1,35 @@
+/* -----------------------------------------------------------------------------
+ * Copyright (c) 2011 Ozmo Inc
+ * Released under the GNU General Public License Version 2 (GPLv2).
+ * -----------------------------------------------------------------------------
+ */
+#ifndef _OZTRACE_H_
+#define _OZTRACE_H_
+#include "ozconfig.h"
+
+#define TRACE_PREFIX   KERN_ALERT "OZWPAN: "
+
+#ifdef WANT_TRACE
+#define oz_trace(...) printk(TRACE_PREFIX __VA_ARGS__)
+#ifdef WANT_VERBOSE_TRACE
+extern unsigned long trace_flags;
+#define oz_trace2(_flag, ...) \
+       do { if (trace_flags & _flag) printk(TRACE_PREFIX __VA_ARGS__); \
+       } while (0)
+#else
+#define oz_trace2(...)
+#endif /* #ifdef WANT_VERBOSE_TRACE */
+#else
+#define oz_trace(...)
+#define oz_trace2(...)
+#endif /* #ifdef WANT_TRACE */
+
+#define OZ_TRACE_STREAM                0x1
+#define OZ_TRACE_URB           0x2
+#define OZ_TRACE_CTRL_DETAIL   0x4
+#define OZ_TRACE_HUB           0x8
+#define OZ_TRACE_RX_FRAMES     0x10
+#define OZ_TRACE_TX_FRAMES     0x20
+
+#endif /* Sentry */
+
diff --git a/drivers/staging/ozwpan/ozurbparanoia.c b/drivers/staging/ozwpan/ozurbparanoia.c
new file mode 100644 (file)
index 0000000..55b9afb
--- /dev/null
@@ -0,0 +1,53 @@
+/* -----------------------------------------------------------------------------
+ * Copyright (c) 2011 Ozmo Inc
+ * Released under the GNU General Public License Version 2 (GPLv2).
+ * -----------------------------------------------------------------------------
+ */
+#include <linux/usb.h>
+#include "ozconfig.h"
+#ifdef WANT_URB_PARANOIA
+#include "ozurbparanoia.h"
+#include "oztrace.h"
+/*-----------------------------------------------------------------------------
+ */
+#define OZ_MAX_URBS    1000
+struct urb *g_urb_memory[OZ_MAX_URBS];
+int g_nb_urbs;
+DEFINE_SPINLOCK(g_urb_mem_lock);
+/*-----------------------------------------------------------------------------
+ */
+void oz_remember_urb(struct urb *urb)
+{
+       unsigned long irq_state;
+       spin_lock_irqsave(&g_urb_mem_lock, irq_state);
+       if (g_nb_urbs < OZ_MAX_URBS) {
+               g_urb_memory[g_nb_urbs++] = urb;
+               oz_trace("%lu: urb up = %d %p\n", jiffies, g_nb_urbs, urb);
+       } else {
+               oz_trace("ERROR urb buffer full\n");
+       }
+       spin_unlock_irqrestore(&g_urb_mem_lock, irq_state);
+}
+/*------------------------------------------------------------------------------
+ */
+int oz_forget_urb(struct urb *urb)
+{
+       unsigned long irq_state;
+       int i;
+       int rc = -1;
+       spin_lock_irqsave(&g_urb_mem_lock, irq_state);
+       for (i = 0; i < g_nb_urbs; i++) {
+               if (g_urb_memory[i] == urb) {
+                       rc = 0;
+                       if (--g_nb_urbs > i)
+                               memcpy(&g_urb_memory[i], &g_urb_memory[i+1],
+                                       (g_nb_urbs - i) * sizeof(struct urb *));
+                       oz_trace("%lu: urb down = %d %p\n",
+                               jiffies, g_nb_urbs, urb);
+               }
+       }
+       spin_unlock_irqrestore(&g_urb_mem_lock, irq_state);
+       return rc;
+}
+#endif /* #ifdef WANT_URB_PARANOIA */
+
diff --git a/drivers/staging/ozwpan/ozurbparanoia.h b/drivers/staging/ozwpan/ozurbparanoia.h
new file mode 100644 (file)
index 0000000..00f5a3a
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef _OZURBPARANOIA_H
+#define _OZURBPARANOIA_H
+/* -----------------------------------------------------------------------------
+ * Released under the GNU General Public License Version 2 (GPLv2).
+ * Copyright (c) 2011 Ozmo Inc
+ * -----------------------------------------------------------------------------
+ */
+
+#ifdef WANT_URB_PARANOIA
+void oz_remember_urb(struct urb *urb);
+int oz_forget_urb(struct urb *urb);
+#else
+#define oz_remember_urb(__x)
+#define oz_forget_urb(__x)     0
+#endif /* WANT_URB_PARANOIA */
+
+
+#endif /* _OZURBPARANOIA_H */
+