staging: ozwpan: Added event logging support
authorChris Kelly <ckelly@ozmodevices.com>
Mon, 20 Feb 2012 21:12:27 +0000 (21:12 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 24 Feb 2012 17:26:52 +0000 (09:26 -0800)
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>
drivers/staging/ozwpan/ozevent.c [new file with mode: 0644]
drivers/staging/ozwpan/ozevent.h [new file with mode: 0644]
drivers/staging/ozwpan/ozeventdef.h [new file with mode: 0644]

diff --git a/drivers/staging/ozwpan/ozevent.c b/drivers/staging/ozwpan/ozevent.c
new file mode 100644 (file)
index 0000000..73703d3
--- /dev/null
@@ -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 */
+
diff --git a/drivers/staging/ozwpan/ozevent.h b/drivers/staging/ozwpan/ozevent.h
new file mode 100644 (file)
index 0000000..f033d01
--- /dev/null
@@ -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 */
diff --git a/drivers/staging/ozwpan/ozeventdef.h b/drivers/staging/ozwpan/ozeventdef.h
new file mode 100644 (file)
index 0000000..cfe4163
--- /dev/null
@@ -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 */