Linux 3.4.71
[linux/fpc-iii.git] / drivers / staging / ozwpan / ozevent.c
blob73703d3e96bd9b0ec5e5a198a18cfc29030043f1
1 /* -----------------------------------------------------------------------------
2 * Copyright (c) 2011 Ozmo Inc
3 * Released under the GNU General Public License Version 2 (GPLv2).
4 * -----------------------------------------------------------------------------
5 */
6 #include "ozconfig.h"
7 #ifdef WANT_EVENT_TRACE
8 #include <linux/jiffies.h>
9 #include <linux/uaccess.h>
10 #include "oztrace.h"
11 #include "ozevent.h"
12 /*------------------------------------------------------------------------------
14 unsigned long g_evt_mask = 0xffffffff;
15 /*------------------------------------------------------------------------------
17 #define OZ_MAX_EVTS 2048 /* Must be power of 2 */
18 DEFINE_SPINLOCK(g_eventlock);
19 static int g_evt_in;
20 static int g_evt_out;
21 static int g_missed_events;
22 static struct oz_event g_events[OZ_MAX_EVTS];
23 /*------------------------------------------------------------------------------
24 * Context: process
26 void oz_event_init(void)
28 oz_trace("Event tracing initialized\n");
29 g_evt_in = g_evt_out = 0;
30 g_missed_events = 0;
32 /*------------------------------------------------------------------------------
33 * Context: process
35 void oz_event_term(void)
37 oz_trace("Event tracing terminated\n");
39 /*------------------------------------------------------------------------------
40 * Context: any
42 void oz_event_log2(u8 evt, u8 ctx1, u16 ctx2, void *ctx3, unsigned ctx4)
44 unsigned long irqstate;
45 int ix;
46 spin_lock_irqsave(&g_eventlock, irqstate);
47 ix = (g_evt_in + 1) & (OZ_MAX_EVTS - 1);
48 if (ix != g_evt_out) {
49 struct oz_event *e = &g_events[g_evt_in];
50 e->jiffies = jiffies;
51 e->evt = evt;
52 e->ctx1 = ctx1;
53 e->ctx2 = ctx2;
54 e->ctx3 = ctx3;
55 e->ctx4 = ctx4;
56 g_evt_in = ix;
57 } else {
58 g_missed_events++;
60 spin_unlock_irqrestore(&g_eventlock, irqstate);
62 /*------------------------------------------------------------------------------
63 * Context: process
65 int oz_events_copy(struct oz_evtlist __user *lst)
67 int first;
68 int ix;
69 struct hdr {
70 int count;
71 int missed;
72 } hdr;
73 ix = g_evt_out;
74 hdr.count = g_evt_in - ix;
75 if (hdr.count < 0)
76 hdr.count += OZ_MAX_EVTS;
77 if (hdr.count > OZ_EVT_LIST_SZ)
78 hdr.count = OZ_EVT_LIST_SZ;
79 hdr.missed = g_missed_events;
80 g_missed_events = 0;
81 if (copy_to_user((void __user *)lst, &hdr, sizeof(hdr)))
82 return -EFAULT;
83 first = OZ_MAX_EVTS - ix;
84 if (first > hdr.count)
85 first = hdr.count;
86 if (first) {
87 int sz = first*sizeof(struct oz_event);
88 void __user *p = (void __user *)lst->evts;
89 if (copy_to_user(p, &g_events[ix], sz))
90 return -EFAULT;
91 if (hdr.count > first) {
92 p = (void __user *)&lst->evts[first];
93 sz = (hdr.count-first)*sizeof(struct oz_event);
94 if (copy_to_user(p, g_events, sz))
95 return -EFAULT;
98 ix += hdr.count;
99 if (ix >= OZ_MAX_EVTS)
100 ix -= OZ_MAX_EVTS;
101 g_evt_out = ix;
102 return 0;
104 /*------------------------------------------------------------------------------
105 * Context: process
107 void oz_events_clear(void)
109 unsigned long irqstate;
110 spin_lock_irqsave(&g_eventlock, irqstate);
111 g_evt_in = g_evt_out = 0;
112 g_missed_events = 0;
113 spin_unlock_irqrestore(&g_eventlock, irqstate);
115 #endif /* WANT_EVENT_TRACE */