source: trunk/src/os2ahci/trace.c@ 160

Last change on this file since 160 was 160, checked in by David Azarewicz, 12 years ago

fixed trap dump kernel exit, some work on suspend/resume routines

File size: 7.9 KB
Line 
1/******************************************************************************
2 * trace.c - code for our internal trace ring buffer
3 *
4 * Copyright (c) 2011 thi.guten Software Development
5 * Copyright (c) 2011 Mensys B.V.
6 *
7 * Authors: Christian Mueller, Markus Thielen
8 *
9 * Parts copied from/inspired by the Linux AHCI driver;
10 * those parts are (c) Linux AHCI/ATA maintainers
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27#include "os2ahci.h"
28
29/* -------------------------- macros and constants ------------------------- */
30
31/* ------------------------ typedefs and structures ------------------------ */
32
33/* -------------------------- function prototypes -------------------------- */
34
35/* ------------------------ global/static variables ------------------------ */
36
37struct {
38 u32 phys_addr; /* physical address of allocated buffer */
39 u8 _far *tbuf; /* mapped address of trace buffer */
40 u16 writep; /* current write offset in buffer */
41 u16 readp; /* current read offset in buffer */
42 u16 mask; /* The mask for wrapping the buffer pointers */
43} ahci_trace_buf;
44
45/* ----------------------------- start of code ----------------------------- */
46
47/******************************************************************************
48 * initialize AHCI circular trace buffer
49 *
50 * NOTE: this func must be called during INIT time since it allocates
51 * a GDT selector for the trace ring buffer
52 */
53void trace_init(u16 usBufSize)
54{
55 SEL sel = 0;
56
57 if (ahci_trace_buf.phys_addr) return;
58
59 /* initialize ring buffer logic */
60 ahci_trace_buf.writep = 0;
61 ahci_trace_buf.readp = 0;
62 ahci_trace_buf.mask = usBufSize - 1;
63
64 if (ahci_trace_buf.phys_addr == 0) {
65 /* allocate buffer */
66 if (DevHelp_AllocPhys((ULONG) usBufSize, MEMTYPE_ABOVE_1M,
67 &(ahci_trace_buf.phys_addr))) {
68 /* failed above 1MB, try below */
69 if (DevHelp_AllocPhys((ULONG) usBufSize, MEMTYPE_BELOW_1M,
70 &(ahci_trace_buf.phys_addr))) {
71 /* failed, too. Give up */
72 ahci_trace_buf.phys_addr = 0;
73 cprintf("%s warning: failed to allocate %dk trace buffer\n",
74 drv_name, usBufSize / 1024);
75 return;
76 }
77 }
78
79 /* allocate GDT selector and map our physical trace buffer to it */
80 if (DevHelp_AllocGDTSelector(&sel, 1) ||
81 DevHelp_PhysToGDTSelector(ahci_trace_buf.phys_addr,
82 usBufSize, sel)) {
83 /* failed; free GDT selector and physical memory we allocated before */
84 if (sel) {
85 DevHelp_FreeGDTSelector(sel);
86 sel = 0;
87 }
88 DevHelp_FreePhys(ahci_trace_buf.phys_addr);
89 ahci_trace_buf.phys_addr = 0;
90 return;
91 }
92
93 /* create ring buffer address */
94 ahci_trace_buf.tbuf = (u8 _far *) ((u32) sel << 16);
95
96 }
97}
98
99/******************************************************************************
100 * cleanup trace buffer
101 *
102 * NOTE: this function is here for completeness; the trace buffer should not
103 * be deallocated and then reallocated.
104 */
105void trace_exit(void)
106{
107 /* free physical address */
108 if (ahci_trace_buf.phys_addr) {
109 DevHelp_FreePhys(ahci_trace_buf.phys_addr);
110 ahci_trace_buf.phys_addr = 0;
111 }
112
113 /* free GDT selector */
114 if (ahci_trace_buf.tbuf) {
115 DevHelp_FreeGDTSelector((SEL) ((u32) (ahci_trace_buf.tbuf) >> 16));
116 ahci_trace_buf.tbuf = NULL;
117 }
118}
119
120
121/******************************************************************************
122 * write a string to the circular trace buffer
123 *
124 * Note: This func wraps the buffer if necessary, so the caller does not
125 * need to call repeatedly until everything is written.
126 *
127 */
128void trace_write(u8 _far *s, int len)
129{
130 //NOT USED USHORT awake_cnt;
131
132 if (ahci_trace_buf.phys_addr == 0) {
133 /* tracing not active */
134 return;
135 }
136
137 while (len) {
138 if ( !wrap_trace_buffer && (((ahci_trace_buf.writep+1) & ahci_trace_buf.mask) == ahci_trace_buf.readp) ) break; /* buffer is full */
139
140 ahci_trace_buf.tbuf[ahci_trace_buf.writep] = *s++;
141 ahci_trace_buf.writep++;
142 ahci_trace_buf.writep &= ahci_trace_buf.mask;
143
144 /* keep the latest full buffer of information */
145 if (ahci_trace_buf.writep == ahci_trace_buf.readp)
146 ahci_trace_buf.readp = (ahci_trace_buf.readp+1) & ahci_trace_buf.mask;
147
148 len--;
149 }
150
151 /* wake up processes waiting for data from trace buffer */
152 //NOT_USED DevHelp_ProcRun(ahci_trace_buf.phys_addr, &awake_cnt);
153
154}
155
156/******************************************************************************
157 * read data from circular trace buffer
158 * returns the number of bytes written to the caller's buffer
159 *
160 * NOTE: the caller is expected to call this func repeatedly
161 * (up to two times) until it returns 0
162 */
163u16 trace_read(u8 _far *buf, u16 cb_buf)
164{
165 u16 cb_read;
166
167 if (ahci_trace_buf.phys_addr == NULL) return 0;
168
169 for (cb_read = 0; cb_read < cb_buf && ( ahci_trace_buf.readp != ahci_trace_buf.writep ); cb_read++)
170 {
171 *buf++ = ahci_trace_buf.tbuf[ahci_trace_buf.readp];
172 ahci_trace_buf.readp++;
173 ahci_trace_buf.readp &= ahci_trace_buf.mask;
174 }
175
176 return cb_read;
177}
178
179/******************************************************************************
180 * copy trace buffer content to character device reader (request block buffer)
181 */
182u16 trace_char_dev(RP_RWV _far *rwrb)
183{
184 u8 _far *to_buf;
185 u16 cb_read = 0;
186 u16 cb;
187 USHORT mode = 0;
188
189 spin_lock(com_lock);
190 #ifdef NOT_USED
191 /* block process until data is available in the trace buffer. */
192 while (ahci_trace_buf.writep == ahci_trace_buf.readp ) { /* buffer is empty */
193 spin_lock(com_lock);
194 #ifndef OS2AHCI_SMP
195 com_lock = 0;
196 #endif
197 if (DevHelp_ProcBlock((ULONG) ahci_trace_buf.phys_addr,
198 (ULONG) -1, 0) == WAIT_INTERRUPTED) {
199 /* user pressed Ctrl+C or whatever */
200 rwrb->NumSectors = 0;
201 return STDON;
202 }
203 spin_lock(com_lock);
204 }
205 #endif
206
207 /* get pointer to caller's buffer */
208 if (DevHelp_PhysToVirt(rwrb->XferAddr, rwrb->NumSectors, &to_buf, &mode)) {
209 spin_unlock(com_lock);
210 return (STATUS_DONE | STERR);
211 }
212
213 /* loop until caller's buffer is full or no more data in trace buffer */
214 do {
215 cb = trace_read(to_buf + cb_read, rwrb->NumSectors - cb_read);
216 cb_read += cb;
217 } while (cb > 0 && cb_read < rwrb->NumSectors);
218
219 spin_unlock(com_lock);
220 rwrb->NumSectors = cb_read;
221
222 return(STDON);
223}
224
225/******************************************************************************
226 * Create adapter/port/device list for user output.
227 */
228void build_user_info(void)
229{
230 int a;
231 int p;
232 int d;
233
234 for (a = 0; a < ad_info_cnt; a++) {
235 AD_INFO *ai = ad_infos + a;
236
237 ntprintf("Adapter %d: %d:%d:%d irq=%d addr=0x%lx\n", a,
238 ai->bus, ai->dev_func>>3, ai->dev_func&7,
239 ai->irq, ai->mmio_phys);
240
241 for (p = 0; p <= ai->port_max; p++) {
242 P_INFO *pi = &ai->ports[p];
243
244 ntprintf(" Port %d:\n", p);
245
246 for (d = 0; d <= pi->dev_max; d++) {
247 if (!pi->devs[d].present) continue;
248 ntprintf(" Drive %d: atapi=%d, removable=%d\n", d, pi->devs[d].atapi, pi->devs[d].removable);
249 }
250 }
251 }
252}
253
Note: See TracBrowser for help on using the repository browser.