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

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

code cleanup - debug messages
fixed defect in smart ioctl

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