diff --git a/drivers/staging/ozwpan/ozalloc.c b/drivers/staging/ozwpan/ozalloc.c new file mode 100644 index 000000000000..fe3cd406e4fa --- /dev/null +++ b/drivers/staging/ozwpan/ozalloc.c @@ -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 +#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 index 000000000000..11a7a1642880 --- /dev/null +++ b/drivers/staging/ozwpan/ozalloc.h @@ -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 + +#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 index 000000000000..353ead24fd7d --- /dev/null +++ b/drivers/staging/ozwpan/oztrace.c @@ -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 index 000000000000..8293b24c5a77 --- /dev/null +++ b/drivers/staging/ozwpan/oztrace.h @@ -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 index 000000000000..55b9afbbe47b --- /dev/null +++ b/drivers/staging/ozwpan/ozurbparanoia.c @@ -0,0 +1,53 @@ +/* ----------------------------------------------------------------------------- + * Copyright (c) 2011 Ozmo Inc + * Released under the GNU General Public License Version 2 (GPLv2). + * ----------------------------------------------------------------------------- + */ +#include +#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 index 000000000000..00f5a3a81bc8 --- /dev/null +++ b/drivers/staging/ozwpan/ozurbparanoia.h @@ -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 */ +