staging: ozwpan: Added event logging support

The event logging subsystem allows internal events in the driver to
be logged. This facilitates testing the correct operation of the
driver. This subsystem is 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>
This commit is contained in:
Chris Kelly 2012-02-20 21:12:27 +00:00 committed by Greg Kroah-Hartman
parent 23af8c2a08
commit 56ff32fe1c
3 changed files with 194 additions and 0 deletions

View file

@ -0,0 +1,116 @@
/* -----------------------------------------------------------------------------
* Copyright (c) 2011 Ozmo Inc
* Released under the GNU General Public License Version 2 (GPLv2).
* -----------------------------------------------------------------------------
*/
#include "ozconfig.h"
#ifdef WANT_EVENT_TRACE
#include <linux/jiffies.h>
#include <linux/uaccess.h>
#include "oztrace.h"
#include "ozevent.h"
/*------------------------------------------------------------------------------
*/
unsigned long g_evt_mask = 0xffffffff;
/*------------------------------------------------------------------------------
*/
#define OZ_MAX_EVTS 2048 /* Must be power of 2 */
DEFINE_SPINLOCK(g_eventlock);
static int g_evt_in;
static int g_evt_out;
static int g_missed_events;
static struct oz_event g_events[OZ_MAX_EVTS];
/*------------------------------------------------------------------------------
* Context: process
*/
void oz_event_init(void)
{
oz_trace("Event tracing initialized\n");
g_evt_in = g_evt_out = 0;
g_missed_events = 0;
}
/*------------------------------------------------------------------------------
* Context: process
*/
void oz_event_term(void)
{
oz_trace("Event tracing terminated\n");
}
/*------------------------------------------------------------------------------
* Context: any
*/
void oz_event_log2(u8 evt, u8 ctx1, u16 ctx2, void *ctx3, unsigned ctx4)
{
unsigned long irqstate;
int ix;
spin_lock_irqsave(&g_eventlock, irqstate);
ix = (g_evt_in + 1) & (OZ_MAX_EVTS - 1);
if (ix != g_evt_out) {
struct oz_event *e = &g_events[g_evt_in];
e->jiffies = jiffies;
e->evt = evt;
e->ctx1 = ctx1;
e->ctx2 = ctx2;
e->ctx3 = ctx3;
e->ctx4 = ctx4;
g_evt_in = ix;
} else {
g_missed_events++;
}
spin_unlock_irqrestore(&g_eventlock, irqstate);
}
/*------------------------------------------------------------------------------
* Context: process
*/
int oz_events_copy(struct oz_evtlist __user *lst)
{
int first;
int ix;
struct hdr {
int count;
int missed;
} hdr;
ix = g_evt_out;
hdr.count = g_evt_in - ix;
if (hdr.count < 0)
hdr.count += OZ_MAX_EVTS;
if (hdr.count > OZ_EVT_LIST_SZ)
hdr.count = OZ_EVT_LIST_SZ;
hdr.missed = g_missed_events;
g_missed_events = 0;
if (copy_to_user((void __user *)lst, &hdr, sizeof(hdr)))
return -EFAULT;
first = OZ_MAX_EVTS - ix;
if (first > hdr.count)
first = hdr.count;
if (first) {
int sz = first*sizeof(struct oz_event);
void __user *p = (void __user *)lst->evts;
if (copy_to_user(p, &g_events[ix], sz))
return -EFAULT;
if (hdr.count > first) {
p = (void __user *)&lst->evts[first];
sz = (hdr.count-first)*sizeof(struct oz_event);
if (copy_to_user(p, g_events, sz))
return -EFAULT;
}
}
ix += hdr.count;
if (ix >= OZ_MAX_EVTS)
ix -= OZ_MAX_EVTS;
g_evt_out = ix;
return 0;
}
/*------------------------------------------------------------------------------
* Context: process
*/
void oz_events_clear(void)
{
unsigned long irqstate;
spin_lock_irqsave(&g_eventlock, irqstate);
g_evt_in = g_evt_out = 0;
g_missed_events = 0;
spin_unlock_irqrestore(&g_eventlock, irqstate);
}
#endif /* WANT_EVENT_TRACE */

View file

@ -0,0 +1,31 @@
/* -----------------------------------------------------------------------------
* Copyright (c) 2011 Ozmo Inc
* Released under the GNU General Public License Version 2 (GPLv2).
* -----------------------------------------------------------------------------
*/
#ifndef _OZEVENT_H
#define _OZEVENT_H
#include "ozconfig.h"
#include "ozeventdef.h"
#ifdef WANT_EVENT_TRACE
extern unsigned long g_evt_mask;
void oz_event_init(void);
void oz_event_term(void);
void oz_event_log2(u8 evt, u8 ctx1, u16 ctx2, void *ctx3, unsigned ctx4);
#define oz_event_log(__evt, __ctx1, __ctx2, __ctx3, __ctx4) \
do { \
if ((1<<(__evt)) & g_evt_mask) \
oz_event_log2(__evt, __ctx1, __ctx2, __ctx3, __ctx4); \
} while (0)
int oz_events_copy(struct oz_evtlist __user *lst);
void oz_events_clear(void);
#else
#define oz_event_init()
#define oz_event_term()
#define oz_event_log(__evt, __ctx1, __ctx2, __ctx3, __ctx4)
#define oz_events_copy(__lst)
#define oz_events_clear()
#endif /* WANT_EVENT_TRACE */
#endif /* _OZEVENT_H */

View file

@ -0,0 +1,47 @@
/* -----------------------------------------------------------------------------
* Copyright (c) 2011 Ozmo Inc
* Released under the GNU General Public License Version 2 (GPLv2).
* -----------------------------------------------------------------------------
*/
#ifndef _OZEVENTDEF_H
#define _OZEVENTDEF_H
#define OZ_EVT_RX_FRAME 0
#define OZ_EVT_RX_PROCESS 1
#define OZ_EVT_TX_FRAME 2
#define OZ_EVT_TX_ISOC 3
#define OZ_EVT_URB_SUBMIT 4
#define OZ_EVT_URB_DONE 5
#define OZ_EVT_URB_CANCEL 6
#define OZ_EVT_CTRL_REQ 7
#define OZ_EVT_CTRL_CNF 8
#define OZ_EVT_CTRL_LOCAL 9
#define OZ_EVT_CONNECT_REQ 10
#define OZ_EVT_CONNECT_RSP 11
#define OZ_EVT_EP_CREDIT 12
#define OZ_EVT_EP_BUFFERING 13
#define OZ_EVT_TX_ISOC_DONE 14
#define OZ_EVT_TX_ISOC_DROP 15
#define OZ_EVT_TIMER_CTRL 16
#define OZ_EVT_TIMER 17
#define OZ_EVT_PD_STATE 18
#define OZ_EVT_SERVICE 19
#define OZ_EVT_DEBUG 20
struct oz_event {
unsigned long jiffies;
unsigned char evt;
unsigned char ctx1;
unsigned short ctx2;
void *ctx3;
unsigned ctx4;
};
#define OZ_EVT_LIST_SZ 256
struct oz_evtlist {
int count;
int missed;
struct oz_event evts[OZ_EVT_LIST_SZ];
};
#endif /* _OZEVENTDEF_H */