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

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

driver info updates, misc cleanup, add comments
This is version 1.28

File size: 8.3 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
249 ntprintf(" Drive %d:");
250 if (pi->devs[d].atapi) ntprintf(" atapi");
251 if (pi->devs[d].removable) ntprintf(" removable");
252 if (pi->devs[d].dev_info.Method != NULL)
253 ntprintf(" %d cylinders, %d heads, %d sectors per track (%ldMB) (%s)",
254 pi->devs[d].dev_info.Cylinders, pi->devs[d].dev_info.HeadsPerCylinder, pi->devs[d].dev_info.SectorsPerTrack,
255 pi->devs[d].dev_info.TotalSectors/2048, pi->devs[d].dev_info.Method);
256 ntprintf("\n");
257 }
258 }
259 }
260}
261
Note: See TracBrowser for help on using the repository browser.