Print this page
6639 uhci_qh walker contains whacky boolean logic
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/mdb/common/modules/uhci/uhci.c
+++ new/usr/src/cmd/mdb/common/modules/uhci/uhci.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License, Version 1.0 only
6 6 * (the "License"). You may not use this file except in compliance
7 7 * with the License.
8 8 *
9 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 * or http://www.opensolaris.org/os/licensing.
11 11 * See the License for the specific language governing permissions
12 12 * and limitations under the License.
13 13 *
14 14 * When distributing Covered Code, include this CDDL HEADER in each
15 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 * If applicable, add the following below this CDDL HEADER, with the
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
17 17 * fields enclosed by brackets "[]" replaced with your own identifying
18 18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 19 *
20 20 * CDDL HEADER END
21 21 */
22 22 /*
23 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 -#pragma ident "%Z%%M% %I% %E% SMI"
28 -
29 27 #include <gelf.h>
30 28
31 29 #include <sys/mdb_modapi.h>
32 30 #include <mdb/mdb_ks.h>
33 31
34 32 #include <sys/usb/usba.h>
35 33 #include <sys/usb/usba/usba_types.h>
36 34
37 35 #include <sys/usb/hcd/uhci/uhci.h>
38 36 #include <sys/usb/hcd/uhci/uhcid.h>
39 37 #include <sys/usb/hcd/uhci/uhciutil.h>
40 38
41 39
42 40 #define UHCI_TD 0
43 41 #define UHCI_QH 1
44 42
45 43
46 44 /* Prototypes */
47 45
48 46 int uhci_td(uintptr_t, uint_t, int, const mdb_arg_t *);
49 47 int uhci_qh(uintptr_t, uint_t, int, const mdb_arg_t *);
50 48 int uhci_td_walk_init(mdb_walk_state_t *);
51 49 int uhci_td_walk_step(mdb_walk_state_t *);
52 50 int uhci_qh_walk_init(mdb_walk_state_t *);
53 51 int uhci_qh_walk_step(mdb_walk_state_t *);
54 52
55 53
56 54 /*
57 55 * Callback for find_uhci_statep (called back from walk "softstate" in
58 56 * find_uhci_statep).
59 57 *
60 58 * - uhci_instancep is the value of the current pointer in the array of soft
61 59 * state instance pointers (see i_ddi_soft_state in ddi_impldefs.h)
62 60 * - local_ss is a pointer to the copy of the i_ddi_soft_state in local space
63 61 * - cb_arg is a pointer to the cb arg (an instance of state_find_data).
64 62 *
65 63 * For the current uchi_state_t*, see if the td address is in its pool.
66 64 *
67 65 * Returns WALK_NEXT on success (match not found yet), WALK_ERR on errors.
68 66 *
69 67 * WALK_DONE is returned, cb_data.found is set to TRUE, and
70 68 * *cb_data.fic_uhci_statep is filled in with the contents of the state
71 69 * struct in core. This forces the walk to terminate.
72 70 */
73 71 typedef struct find_instance_struct {
74 72 void *fic_td_qh; /* td/qh we want uhci instance for */
75 73 boolean_t fic_td_or_qh; /* which one td_qh points to */
76 74 boolean_t fic_found;
77 75 uhci_state_t *fic_uhci_statep; /* buffer uhci_state's written into */
78 76 } find_instance_cb_t;
79 77
80 78 /*ARGSUSED*/
81 79 static int
82 80 find_uhci_instance(uintptr_t uhci_instancep, const void *local_ss, void *cb_arg)
83 81 {
84 82 int td_pool_size, qh_pool_size;
85 83 find_instance_cb_t *cb_data = (find_instance_cb_t *)cb_arg;
86 84 uhci_state_t *uhcip = cb_data->fic_uhci_statep;
87 85
88 86
89 87 if (mdb_vread(cb_data->fic_uhci_statep, sizeof (uhci_state_t),
90 88 uhci_instancep) == -1) {
91 89 mdb_warn("failed to read uhci_state at %p", uhci_instancep);
92 90 return (-1);
93 91 }
94 92
95 93 if (mdb_readsym(&td_pool_size, sizeof (int), "uhci_td_pool_size") ==
96 94 -1) {
97 95 mdb_warn("failed to read uhci_td_pool_size");
98 96 return (-1);
99 97 }
100 98
101 99 if (mdb_readsym(&qh_pool_size, sizeof (int), "uhci_qh_pool_size") ==
102 100 -1) {
103 101 mdb_warn("failed to read uhci_td_pool_size");
104 102 return (-1);
105 103 }
106 104
107 105 /*
108 106 * See if the addr is within the appropriate pool for this instance.
109 107 */
110 108 if ((cb_data->fic_td_or_qh == UHCI_TD &&
111 109
112 110 ((uhci_td_t *)cb_data->fic_td_qh >= uhcip->uhci_td_pool_addr &&
113 111 (uhci_td_t *)cb_data->fic_td_qh <= (uhcip->uhci_td_pool_addr +
114 112 td_pool_size - sizeof (uhci_td_t)))) ||
115 113
116 114 (cb_data->fic_td_or_qh == UHCI_QH &&
117 115
118 116 ((queue_head_t *)cb_data->fic_td_qh >= uhcip->uhci_qh_pool_addr &&
119 117 (queue_head_t *)cb_data->fic_td_qh <= (uhcip->uhci_qh_pool_addr +
120 118 qh_pool_size - sizeof (queue_head_t))))) {
121 119
122 120 /* td/qh address is within pool for this instance of uhci. */
123 121 cb_data->fic_found = TRUE;
124 122 return (WALK_DONE);
125 123 }
126 124
127 125 return (WALK_NEXT);
128 126 }
129 127
130 128 /*
131 129 * Figure out which instance of uhci owns a td/qh.
132 130 *
133 131 * - td_qh: a pointer to a uhci td or qh
134 132 * - td_or_qh: a flag indicating which it is (td/qh),
135 133 * - uhci_statep, pointer to a uhci_state_t, to be filled in with data from
136 134 * the found instance of uhci_state_t.
137 135 *
138 136 * Only works for Cntl/Interrupt tds/qhs; others are dynamically allocated
139 137 * and so cannot be found with this method.
140 138 *
141 139 * Returns 0 on success (no match found), 1 on success (match found),
142 140 * -1 on errors.
143 141 */
144 142 static int
145 143 find_uhci_statep(void *td_qh, boolean_t td_or_qh, uhci_state_t *uhci_statep)
146 144 {
147 145 find_instance_cb_t cb_data;
148 146 uintptr_t uhci_ss;
149 147
150 148
151 149 if (uhci_statep == NULL) {
152 150 mdb_warn("failed to find uhci statep: "
153 151 "NULL uhci_statep param\n");
154 152 return (-1);
155 153 }
156 154
157 155 cb_data.fic_td_qh = td_qh;
158 156 cb_data.fic_td_or_qh = td_or_qh;
159 157 cb_data.fic_found = FALSE;
160 158 cb_data.fic_uhci_statep = uhci_statep;
161 159
162 160
163 161 if (mdb_readsym(&uhci_ss, sizeof (uhci_statep),
164 162 "uhci_statep") == -1) {
165 163 mdb_warn("failed to read uhci_statep");
166 164 return (-1);
167 165 }
168 166
169 167
170 168 /*
171 169 * Walk all instances of uhci.
172 170 * The callback func checks if td_qh belongs to a given instance
173 171 * of uhci.
174 172 */
175 173 if (mdb_pwalk("softstate", find_uhci_instance, &cb_data,
176 174 uhci_ss) != 0) {
177 175 mdb_warn("failed to walk softstate");
178 176 return (-1);
179 177 }
180 178
181 179 if (cb_data.fic_found == TRUE) {
182 180 return (1);
183 181 }
184 182
185 183 return (0);
186 184 }
187 185
188 186 /*
189 187 * Dump a UHCI TD (transaction descriptor);
190 188 * or (-d) the chain of TDs starting with the one specified.
191 189 */
192 190 int
193 191 uhci_td(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
194 192 {
195 193 uint_t depth_flag = FALSE;
196 194 uhci_state_t uhci_state, *uhcip = &uhci_state;
197 195 uhci_td_t td;
198 196
199 197
200 198 if (!(flags & DCMD_ADDRSPEC))
201 199 return (DCMD_USAGE);
202 200
203 201 if (addr & ~QH_LINK_PTR_MASK) {
204 202 mdb_warn("address must be on a 16-byte boundary.\n");
205 203 return (DCMD_ERR);
206 204 }
207 205
208 206 if (mdb_getopts(argc, argv,
209 207 'd', MDB_OPT_SETBITS, TRUE, &depth_flag,
210 208 NULL) != argc) {
211 209 return (DCMD_USAGE);
212 210 }
213 211
214 212
215 213 if (depth_flag) {
216 214 if (mdb_pwalk_dcmd("uhci_td", "uhci_td", 0, NULL, addr) == -1) {
217 215 mdb_warn("failed to walk 'uhci_td'");
218 216 return (DCMD_ERR);
219 217 }
220 218 return (DCMD_OK);
221 219 }
222 220
223 221
224 222 if (find_uhci_statep((void *)addr, UHCI_TD, uhcip) != 1) {
225 223 mdb_warn("failed to find uhci_statep");
226 224 return (DCMD_ERR);
227 225 }
228 226
229 227 if (mdb_vread(&td, sizeof (td), addr) != sizeof (td)) {
230 228 mdb_warn("failed to read td at vaddr %p", addr);
231 229 return (DCMD_ERR);
232 230 }
233 231
234 232 mdb_printf("\n UHCI td struct at (vaddr) %08x:\n", addr);
235 233
236 234 if (!(td.link_ptr & HC_END_OF_LIST) && td.link_ptr != NULL) {
237 235 mdb_printf(" link_ptr (paddr) : %-8x "
238 236 "(vaddr) : %p\n",
239 237 td.link_ptr,
240 238 /* Note: uhcip needed by TD_VADDR macro */
241 239 TD_VADDR(td.link_ptr & QH_LINK_PTR_MASK));
242 240 } else {
243 241 mdb_printf(" link_ptr (paddr) : %-8x\n",
244 242 td.link_ptr);
245 243 }
246 244 mdb_printf(" td_dword2 : %08x\n", td.dw2);
247 245 mdb_printf(" td_dword3 : %08x\n", td.dw3);
248 246 mdb_printf(" buffer_address : %08x\n", td.buffer_address);
249 247 mdb_printf(" qh_td_prev : %?p "
250 248 "tw_td_next : %?p\n",
251 249 td.qh_td_prev, td.tw_td_next);
252 250 mdb_printf(" outst_td_prev : %?p "
253 251 "outst_td_next : %?p\n",
254 252 td.outst_td_prev, td.outst_td_next);
255 253 mdb_printf(" tw : %?p "
256 254 "flag : %02x\n", td.tw, td.flag);
257 255 mdb_printf(" isoc_next : %?p "
258 256 "isoc_prev : %0x\n", td.isoc_next, td.isoc_prev);
259 257 mdb_printf(" isoc_pkt_index : %0x "
260 258 "startingframe: %0x\n", td.isoc_pkt_index, td.starting_frame);
261 259
262 260
263 261 if (td.link_ptr == NULL) {
264 262 mdb_printf(" --> Link pointer = NULL\n");
265 263 return (DCMD_ERR);
266 264 } else {
267 265
268 266 /* Inform user if link is to a TD or QH. */
269 267 if (td.link_ptr & HC_END_OF_LIST) {
270 268 mdb_printf(" "
271 269 "--> Link pointer invalid (terminate bit set).\n");
272 270 } else {
273 271 if ((td.link_ptr & HC_QUEUE_HEAD) == HC_QUEUE_HEAD) {
274 272 mdb_printf(" "
275 273 "--> Link pointer points to a QH.\n");
276 274 } else {
277 275 mdb_printf(" "
278 276 "--> Link pointer points to a TD.\n");
279 277 }
280 278 }
281 279 }
282 280
283 281 return (DCMD_OK);
284 282 }
285 283
286 284 /*
287 285 * Dump a UHCI QH (queue head).
288 286 * -b walk/dump the chian of QHs starting with the one specified.
289 287 * -d also dump the chain of TDs starting with the one specified.
290 288 */
291 289 int
292 290 uhci_qh(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
293 291 {
294 292 uint_t breadth_flag = FALSE, depth_flag = FALSE;
295 293 uhci_state_t uhci_state, *uhcip = &uhci_state;
296 294 queue_head_t qh;
297 295
298 296
299 297 if (!(flags & DCMD_ADDRSPEC))
300 298 return (DCMD_USAGE);
301 299
302 300 if (addr & ~QH_LINK_PTR_MASK) {
303 301 mdb_warn("address must be on a 16-byte boundary.\n");
304 302 return (DCMD_ERR);
305 303 }
306 304
307 305 if (mdb_getopts(argc, argv,
308 306 'b', MDB_OPT_SETBITS, TRUE, &breadth_flag,
309 307 'd', MDB_OPT_SETBITS, TRUE, &depth_flag,
310 308 NULL) != argc) {
311 309 return (DCMD_USAGE);
312 310 }
313 311
314 312
315 313 if (breadth_flag) {
316 314 uint_t new_argc = 0;
317 315 mdb_arg_t new_argv[1];
318 316
319 317
320 318 if (depth_flag) {
321 319 new_argc = 1;
322 320 new_argv[0].a_type = MDB_TYPE_STRING;
323 321 new_argv[0].a_un.a_str = "-d";
324 322 }
325 323
326 324 if ((mdb_pwalk_dcmd("uhci_qh", "uhci_qh", new_argc, new_argv,
327 325 addr)) != 0) {
328 326 mdb_warn("failed to walk 'uhci_qh'");
329 327 return (DCMD_ERR);
330 328 }
331 329 return (DCMD_OK);
332 330 }
333 331
334 332
335 333 if (find_uhci_statep((void *)addr, UHCI_QH, uhcip) != 1) {
336 334 mdb_warn("failed to find uhci_statep");
337 335 return (DCMD_ERR);
338 336 }
339 337
340 338
341 339 if (mdb_vread(&qh, sizeof (qh), addr) != sizeof (qh)) {
342 340 mdb_warn("failed to read qh at vaddr %p", addr);
343 341 return (DCMD_ERR);
344 342 }
345 343
346 344 mdb_printf("\n UHCI qh struct at (vaddr) %08x:\n", addr);
347 345
348 346 if (!(qh.link_ptr & HC_END_OF_LIST) && qh.link_ptr != NULL) {
349 347 mdb_printf(" link_ptr (paddr) : %08x "
350 348 "(vaddr) : %p\n",
351 349 qh.link_ptr,
352 350 /* Note: uhcip needed by QH_VADDR macro */
353 351 QH_VADDR(qh.link_ptr & QH_LINK_PTR_MASK));
354 352 } else {
355 353 mdb_printf(
356 354 " link_ptr (paddr) : %08x\n",
357 355 qh.link_ptr);
358 356 }
359 357
360 358 if (!(qh.element_ptr & HC_END_OF_LIST) && qh.element_ptr != NULL) {
361 359 mdb_printf(" element_ptr (paddr) : %08x "
362 360 "(vaddr) : %p\n",
363 361 qh.element_ptr,
364 362 /* Note: uhcip needed by TD_VADDR macro */
365 363 TD_VADDR(qh.element_ptr & QH_LINK_PTR_MASK));
366 364 } else {
367 365 mdb_printf(
368 366 " element_ptr (paddr) : %08x\n", qh.element_ptr);
369 367 }
370 368
371 369 mdb_printf(" node : %04x "
372 370 "flag : %04x\n",
373 371 qh.node, qh.qh_flag);
374 372 mdb_printf(" prev_qh : %?p "
375 373 "td_tailp : %?p\n",
376 374 qh.prev_qh, qh.td_tailp);
377 375 mdb_printf(" bulk_xfer_isoc_info : %?p\n", qh.bulk_xfer_info);
378 376
379 377
380 378 if (qh.link_ptr == NULL) {
381 379 mdb_printf(" --> Link pointer = NULL\n");
382 380 return (DCMD_ERR);
383 381 } else {
384 382
385 383 /* Inform user if next link is a TD or QH. */
386 384 if (qh.link_ptr & HC_END_OF_LIST) {
387 385 mdb_printf(" "
388 386 "--> Link pointer invalid (terminate bit set).\n");
389 387 } else {
390 388 if ((qh.link_ptr & HC_QUEUE_HEAD) == HC_QUEUE_HEAD) {
391 389 mdb_printf(" "
392 390 "--> Link pointer points to a QH.\n");
393 391 } else {
394 392 /* Should never happen. */
395 393 mdb_warn(" "
396 394 "--> Link pointer points to a TD.\n");
397 395 return (DCMD_ERR);
398 396 }
399 397 }
400 398 }
401 399
402 400
403 401 if (qh.element_ptr == NULL) {
404 402 mdb_printf(" element_ptr = NULL\n");
405 403 return (DCMD_ERR);
406 404 } else {
407 405
408 406 /* Inform user if next element is a TD or QH. */
409 407 if (qh.element_ptr & HC_END_OF_LIST) {
410 408 mdb_printf(" "
411 409 "-->Element pointer invalid (terminate bit set)."
412 410 "\n");
413 411 return (DCMD_OK);
414 412 } else {
415 413 if ((qh.element_ptr & HC_QUEUE_HEAD) == HC_QUEUE_HEAD) {
416 414 mdb_printf(" "
417 415 "--> Element pointer points to a QH.\n");
418 416 /* Should never happen in UHCI implementation */
419 417 return (DCMD_ERR);
420 418 } else {
421 419 mdb_printf(" "
422 420 "--> Element pointer points to a TD.\n");
423 421 }
424 422 }
425 423 }
426 424
427 425 /*
428 426 * If the user specified the -d (depth) option,
429 427 * dump all TDs linked to this TD via the element_ptr.
430 428 */
431 429 if (depth_flag) {
432 430
433 431 /* Traverse and display all the TDs in the chain */
434 432 if (mdb_pwalk_dcmd("uhci_td", "uhci_td", argc, argv,
435 433 (uintptr_t)(TD_VADDR(qh.element_ptr &
436 434 QH_LINK_PTR_MASK))) == -1) {
437 435 mdb_warn("failed to walk 'uhci_td'");
438 436 return (DCMD_ERR);
439 437 }
440 438 }
441 439
442 440 return (DCMD_OK);
443 441 }
444 442
445 443 /*
446 444 * Walk a list of UHCI Transaction Descriptors (td's).
447 445 * Stop at the end of the list, or if the next element in the list is a
448 446 * queue head (qh).
449 447 * User must specify the address of the first td to look at.
450 448 */
451 449 int
452 450 uhci_td_walk_init(mdb_walk_state_t *wsp)
453 451 {
454 452 if (wsp->walk_addr == NULL) {
455 453 return (DCMD_USAGE);
456 454 }
457 455
458 456 wsp->walk_data = mdb_alloc(sizeof (uhci_td_t), UM_SLEEP | UM_GC);
459 457 wsp->walk_arg = mdb_alloc(sizeof (uhci_state_t), UM_SLEEP | UM_GC);
460 458
461 459
462 460 /*
463 461 * Read the uhci_state_t for the instance of uhci
464 462 * using this td address into buf pointed to by walk_arg.
465 463 */
466 464 if (find_uhci_statep((void *)wsp->walk_addr, UHCI_TD,
467 465 wsp->walk_arg) != 1) {
468 466 mdb_warn("failed to find uhci_statep");
469 467 return (WALK_ERR);
470 468 }
471 469
472 470 return (WALK_NEXT);
473 471 }
474 472
475 473 /*
476 474 * At each step, read a TD into our private storage, and then invoke
477 475 * the callback function. We terminate when we reach a QH, or
↓ open down ↓ |
439 lines elided |
↑ open up ↑ |
478 476 * link_ptr is NULL.
479 477 */
480 478 int
481 479 uhci_td_walk_step(mdb_walk_state_t *wsp)
482 480 {
483 481 int status;
484 482 uhci_state_t *uhcip = (uhci_state_t *)wsp->walk_arg;
485 483
486 484
487 485 if (mdb_vread(wsp->walk_data, sizeof (uhci_td_t), wsp->walk_addr)
488 - == -1) {
486 + == -1) {
489 487 mdb_warn("failed to read td at %p", wsp->walk_addr);
490 488 return (WALK_DONE);
491 489 }
492 490
493 491 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
494 492 wsp->walk_cbdata);
495 493
496 494 /* Next td. */
497 495 wsp->walk_addr = ((uhci_td_t *)wsp->walk_data)->link_ptr;
498 496
499 497 /* Check if we're at the last element */
500 498 if (wsp->walk_addr == NULL || wsp->walk_addr & HC_END_OF_LIST)
501 499 return (WALK_DONE);
502 500
503 501 /* Make sure next element is a TD. If a QH, stop. */
504 502 if (((((uhci_td_t *)wsp->walk_data)->link_ptr) & HC_QUEUE_HEAD)
505 503 == HC_QUEUE_HEAD) {
506 504 return (WALK_DONE);
507 505 }
508 506
509 507 /* Strip terminate etc. bits. */
510 508 wsp->walk_addr &= QH_LINK_PTR_MASK; /* there is no TD_LINK_PTR_MASK */
511 509
512 510 if (wsp->walk_addr == NULL)
513 511 return (WALK_DONE);
514 512
515 513 /*
516 514 * Convert link_ptr paddr to vaddr
517 515 * Note: uhcip needed by TD_VADDR macro
518 516 */
519 517 wsp->walk_addr = (uintptr_t)TD_VADDR(wsp->walk_addr);
520 518
521 519 return (status);
522 520 }
523 521
524 522 /*
525 523 * Walk a list of UHCI Queue Heads (qh's).
526 524 * Stop at the end of the list, or if the next element in the list is a
527 525 * Transaction Descriptor (td).
528 526 * User must specify the address of the first qh to look at.
529 527 */
530 528 int
531 529 uhci_qh_walk_init(mdb_walk_state_t *wsp)
532 530 {
533 531 if (wsp->walk_addr == NULL)
534 532 return (DCMD_USAGE);
535 533
536 534 wsp->walk_data = mdb_alloc(sizeof (queue_head_t), UM_SLEEP | UM_GC);
537 535 wsp->walk_arg = mdb_alloc(sizeof (uhci_state_t), UM_SLEEP | UM_GC);
538 536
539 537
540 538 /*
541 539 * Read the uhci_state_t for the instance of uhci
542 540 * using this td address into buf pointed to by walk_arg.
543 541 */
544 542 if (find_uhci_statep((void *)wsp->walk_addr, UHCI_QH,
545 543 (uhci_state_t *)wsp->walk_arg) != 1) {
546 544 mdb_warn("failed to find uhci_statep");
547 545 return (WALK_ERR);
548 546 }
549 547
550 548 return (WALK_NEXT);
551 549 }
552 550
553 551 /*
554 552 * At each step, read a QH into our private storage, and then invoke
555 553 * the callback function. We terminate when we reach a QH, or
556 554 * link_ptr is NULL.
557 555 */
558 556 int
559 557 uhci_qh_walk_step(mdb_walk_state_t *wsp)
560 558 {
561 559 int status;
562 560 uhci_state_t *uhcip = (uhci_state_t *)wsp->walk_arg;
563 561
564 562
565 563 if (wsp->walk_addr == NULL) /* Should never occur */
566 564 return (WALK_DONE);
567 565
568 566 if (mdb_vread(wsp->walk_data, sizeof (queue_head_t), wsp->walk_addr)
569 567 == -1) {
570 568 mdb_warn("failure reading qh at %p", wsp->walk_addr);
571 569 return (WALK_DONE);
572 570 }
573 571
574 572 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
575 573 wsp->walk_cbdata);
576 574
↓ open down ↓ |
78 lines elided |
↑ open up ↑ |
577 575 /* Next QH. */
578 576 wsp->walk_addr = ((queue_head_t *)wsp->walk_data)->link_ptr;
579 577
580 578
581 579 /* Check if we're at the last element */
582 580 if (wsp->walk_addr == NULL || wsp->walk_addr & HC_END_OF_LIST) {
583 581 return (WALK_DONE);
584 582 }
585 583
586 584 /* Make sure next element is a QH. If a TD, stop. */
587 - if (! ((((queue_head_t *)wsp->walk_data)->link_ptr) & HC_QUEUE_HEAD)
588 - == HC_QUEUE_HEAD) {
585 + if (((((queue_head_t *)wsp->walk_data)->link_ptr) & HC_QUEUE_HEAD)
586 + != HC_QUEUE_HEAD) {
589 587 return (WALK_DONE);
590 588 }
591 589
592 590 /* Strip terminate etc. bits. */
593 591 wsp->walk_addr &= QH_LINK_PTR_MASK;
594 592
595 593 if (wsp->walk_addr == NULL)
596 594 return (WALK_DONE);
597 595
598 596 /*
599 597 * Convert link_ptr paddr to vaddr
600 598 * Note: uhcip needed by QH_VADDR macro
601 599 */
602 600 wsp->walk_addr = (uintptr_t)QH_VADDR(wsp->walk_addr);
603 601
604 602 return (status);
605 603 }
606 604
607 605 /*
608 606 * MDB module linkage information:
609 607 *
610 608 * We declare a list of structures describing our dcmds, and a function
611 609 * named _mdb_init to return a pointer to our module information.
612 610 */
613 611
614 612 static const mdb_dcmd_t dcmds[] = {
615 613 { "uhci_td", ": [-d]", "print UHCI TD", uhci_td, NULL },
616 614 { "uhci_qh", ": [-bd]", "print UHCI QH", uhci_qh, NULL},
617 615 { NULL }
618 616 };
619 617
620 618
621 619 static const mdb_walker_t walkers[] = {
622 620 { "uhci_td", "walk list of UHCI TD structures",
623 621 uhci_td_walk_init, uhci_td_walk_step, NULL,
624 622 NULL },
625 623 { "uhci_qh", "walk list of UHCI QH structures",
626 624 uhci_qh_walk_init, uhci_qh_walk_step, NULL,
627 625 NULL },
628 626 { NULL }
629 627 };
630 628
631 629 static const mdb_modinfo_t modinfo = {
632 630 MDB_API_VERSION, dcmds, walkers
633 631 };
634 632
635 633
636 634 const mdb_modinfo_t *
637 635 _mdb_init(void)
638 636 {
639 637 return (&modinfo);
640 638 }
↓ open down ↓ |
42 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX