17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate #include <gelf.h>
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate #include <sys/mdb_modapi.h>
307c478bd9Sstevel@tonic-gate #include <mdb/mdb_ks.h>
317c478bd9Sstevel@tonic-gate
327c478bd9Sstevel@tonic-gate #include <sys/usb/usba.h>
337c478bd9Sstevel@tonic-gate #include <sys/usb/usba/usba_types.h>
347c478bd9Sstevel@tonic-gate
357c478bd9Sstevel@tonic-gate #include <sys/usb/hcd/uhci/uhci.h>
367c478bd9Sstevel@tonic-gate #include <sys/usb/hcd/uhci/uhcid.h>
377c478bd9Sstevel@tonic-gate #include <sys/usb/hcd/uhci/uhciutil.h>
387c478bd9Sstevel@tonic-gate
397c478bd9Sstevel@tonic-gate
407c478bd9Sstevel@tonic-gate #define UHCI_TD 0
417c478bd9Sstevel@tonic-gate #define UHCI_QH 1
427c478bd9Sstevel@tonic-gate
437c478bd9Sstevel@tonic-gate
447c478bd9Sstevel@tonic-gate /* Prototypes */
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gate int uhci_td(uintptr_t, uint_t, int, const mdb_arg_t *);
477c478bd9Sstevel@tonic-gate int uhci_qh(uintptr_t, uint_t, int, const mdb_arg_t *);
487c478bd9Sstevel@tonic-gate int uhci_td_walk_init(mdb_walk_state_t *);
497c478bd9Sstevel@tonic-gate int uhci_td_walk_step(mdb_walk_state_t *);
507c478bd9Sstevel@tonic-gate int uhci_qh_walk_init(mdb_walk_state_t *);
517c478bd9Sstevel@tonic-gate int uhci_qh_walk_step(mdb_walk_state_t *);
527c478bd9Sstevel@tonic-gate
537c478bd9Sstevel@tonic-gate
547c478bd9Sstevel@tonic-gate /*
557c478bd9Sstevel@tonic-gate * Callback for find_uhci_statep (called back from walk "softstate" in
567c478bd9Sstevel@tonic-gate * find_uhci_statep).
577c478bd9Sstevel@tonic-gate *
587c478bd9Sstevel@tonic-gate * - uhci_instancep is the value of the current pointer in the array of soft
597c478bd9Sstevel@tonic-gate * state instance pointers (see i_ddi_soft_state in ddi_impldefs.h)
607c478bd9Sstevel@tonic-gate * - local_ss is a pointer to the copy of the i_ddi_soft_state in local space
617c478bd9Sstevel@tonic-gate * - cb_arg is a pointer to the cb arg (an instance of state_find_data).
627c478bd9Sstevel@tonic-gate *
637c478bd9Sstevel@tonic-gate * For the current uchi_state_t*, see if the td address is in its pool.
647c478bd9Sstevel@tonic-gate *
657c478bd9Sstevel@tonic-gate * Returns WALK_NEXT on success (match not found yet), WALK_ERR on errors.
667c478bd9Sstevel@tonic-gate *
677c478bd9Sstevel@tonic-gate * WALK_DONE is returned, cb_data.found is set to TRUE, and
687c478bd9Sstevel@tonic-gate * *cb_data.fic_uhci_statep is filled in with the contents of the state
697c478bd9Sstevel@tonic-gate * struct in core. This forces the walk to terminate.
707c478bd9Sstevel@tonic-gate */
717c478bd9Sstevel@tonic-gate typedef struct find_instance_struct {
727c478bd9Sstevel@tonic-gate void *fic_td_qh; /* td/qh we want uhci instance for */
737c478bd9Sstevel@tonic-gate boolean_t fic_td_or_qh; /* which one td_qh points to */
747c478bd9Sstevel@tonic-gate boolean_t fic_found;
757c478bd9Sstevel@tonic-gate uhci_state_t *fic_uhci_statep; /* buffer uhci_state's written into */
767c478bd9Sstevel@tonic-gate } find_instance_cb_t;
777c478bd9Sstevel@tonic-gate
787c478bd9Sstevel@tonic-gate /*ARGSUSED*/
797c478bd9Sstevel@tonic-gate static int
find_uhci_instance(uintptr_t uhci_instancep,const void * local_ss,void * cb_arg)807c478bd9Sstevel@tonic-gate find_uhci_instance(uintptr_t uhci_instancep, const void *local_ss, void *cb_arg)
817c478bd9Sstevel@tonic-gate {
827c478bd9Sstevel@tonic-gate int td_pool_size, qh_pool_size;
837c478bd9Sstevel@tonic-gate find_instance_cb_t *cb_data = (find_instance_cb_t *)cb_arg;
847c478bd9Sstevel@tonic-gate uhci_state_t *uhcip = cb_data->fic_uhci_statep;
857c478bd9Sstevel@tonic-gate
867c478bd9Sstevel@tonic-gate
877c478bd9Sstevel@tonic-gate if (mdb_vread(cb_data->fic_uhci_statep, sizeof (uhci_state_t),
887c478bd9Sstevel@tonic-gate uhci_instancep) == -1) {
897c478bd9Sstevel@tonic-gate mdb_warn("failed to read uhci_state at %p", uhci_instancep);
907c478bd9Sstevel@tonic-gate return (-1);
917c478bd9Sstevel@tonic-gate }
927c478bd9Sstevel@tonic-gate
937c478bd9Sstevel@tonic-gate if (mdb_readsym(&td_pool_size, sizeof (int), "uhci_td_pool_size") ==
947c478bd9Sstevel@tonic-gate -1) {
957c478bd9Sstevel@tonic-gate mdb_warn("failed to read uhci_td_pool_size");
967c478bd9Sstevel@tonic-gate return (-1);
977c478bd9Sstevel@tonic-gate }
987c478bd9Sstevel@tonic-gate
997c478bd9Sstevel@tonic-gate if (mdb_readsym(&qh_pool_size, sizeof (int), "uhci_qh_pool_size") ==
1007c478bd9Sstevel@tonic-gate -1) {
1017c478bd9Sstevel@tonic-gate mdb_warn("failed to read uhci_td_pool_size");
1027c478bd9Sstevel@tonic-gate return (-1);
1037c478bd9Sstevel@tonic-gate }
1047c478bd9Sstevel@tonic-gate
1057c478bd9Sstevel@tonic-gate /*
1067c478bd9Sstevel@tonic-gate * See if the addr is within the appropriate pool for this instance.
1077c478bd9Sstevel@tonic-gate */
1087c478bd9Sstevel@tonic-gate if ((cb_data->fic_td_or_qh == UHCI_TD &&
1097c478bd9Sstevel@tonic-gate
1107c478bd9Sstevel@tonic-gate ((uhci_td_t *)cb_data->fic_td_qh >= uhcip->uhci_td_pool_addr &&
1117c478bd9Sstevel@tonic-gate (uhci_td_t *)cb_data->fic_td_qh <= (uhcip->uhci_td_pool_addr +
1127c478bd9Sstevel@tonic-gate td_pool_size - sizeof (uhci_td_t)))) ||
1137c478bd9Sstevel@tonic-gate
1147c478bd9Sstevel@tonic-gate (cb_data->fic_td_or_qh == UHCI_QH &&
1157c478bd9Sstevel@tonic-gate
1167c478bd9Sstevel@tonic-gate ((queue_head_t *)cb_data->fic_td_qh >= uhcip->uhci_qh_pool_addr &&
1177c478bd9Sstevel@tonic-gate (queue_head_t *)cb_data->fic_td_qh <= (uhcip->uhci_qh_pool_addr +
1187c478bd9Sstevel@tonic-gate qh_pool_size - sizeof (queue_head_t))))) {
1197c478bd9Sstevel@tonic-gate
1207c478bd9Sstevel@tonic-gate /* td/qh address is within pool for this instance of uhci. */
1217c478bd9Sstevel@tonic-gate cb_data->fic_found = TRUE;
1227c478bd9Sstevel@tonic-gate return (WALK_DONE);
1237c478bd9Sstevel@tonic-gate }
1247c478bd9Sstevel@tonic-gate
1257c478bd9Sstevel@tonic-gate return (WALK_NEXT);
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate
1287c478bd9Sstevel@tonic-gate /*
1297c478bd9Sstevel@tonic-gate * Figure out which instance of uhci owns a td/qh.
1307c478bd9Sstevel@tonic-gate *
1317c478bd9Sstevel@tonic-gate * - td_qh: a pointer to a uhci td or qh
1327c478bd9Sstevel@tonic-gate * - td_or_qh: a flag indicating which it is (td/qh),
1337c478bd9Sstevel@tonic-gate * - uhci_statep, pointer to a uhci_state_t, to be filled in with data from
1347c478bd9Sstevel@tonic-gate * the found instance of uhci_state_t.
1357c478bd9Sstevel@tonic-gate *
1367c478bd9Sstevel@tonic-gate * Only works for Cntl/Interrupt tds/qhs; others are dynamically allocated
1377c478bd9Sstevel@tonic-gate * and so cannot be found with this method.
1387c478bd9Sstevel@tonic-gate *
1397c478bd9Sstevel@tonic-gate * Returns 0 on success (no match found), 1 on success (match found),
1407c478bd9Sstevel@tonic-gate * -1 on errors.
1417c478bd9Sstevel@tonic-gate */
1427c478bd9Sstevel@tonic-gate static int
find_uhci_statep(void * td_qh,boolean_t td_or_qh,uhci_state_t * uhci_statep)1437c478bd9Sstevel@tonic-gate find_uhci_statep(void *td_qh, boolean_t td_or_qh, uhci_state_t *uhci_statep)
1447c478bd9Sstevel@tonic-gate {
1457c478bd9Sstevel@tonic-gate find_instance_cb_t cb_data;
1467c478bd9Sstevel@tonic-gate uintptr_t uhci_ss;
1477c478bd9Sstevel@tonic-gate
1487c478bd9Sstevel@tonic-gate
1497c478bd9Sstevel@tonic-gate if (uhci_statep == NULL) {
1507c478bd9Sstevel@tonic-gate mdb_warn("failed to find uhci statep: "
1517c478bd9Sstevel@tonic-gate "NULL uhci_statep param\n");
1527c478bd9Sstevel@tonic-gate return (-1);
1537c478bd9Sstevel@tonic-gate }
1547c478bd9Sstevel@tonic-gate
1557c478bd9Sstevel@tonic-gate cb_data.fic_td_qh = td_qh;
1567c478bd9Sstevel@tonic-gate cb_data.fic_td_or_qh = td_or_qh;
1577c478bd9Sstevel@tonic-gate cb_data.fic_found = FALSE;
1587c478bd9Sstevel@tonic-gate cb_data.fic_uhci_statep = uhci_statep;
1597c478bd9Sstevel@tonic-gate
1607c478bd9Sstevel@tonic-gate
1617c478bd9Sstevel@tonic-gate if (mdb_readsym(&uhci_ss, sizeof (uhci_statep),
1627c478bd9Sstevel@tonic-gate "uhci_statep") == -1) {
1637c478bd9Sstevel@tonic-gate mdb_warn("failed to read uhci_statep");
1647c478bd9Sstevel@tonic-gate return (-1);
1657c478bd9Sstevel@tonic-gate }
1667c478bd9Sstevel@tonic-gate
1677c478bd9Sstevel@tonic-gate
1687c478bd9Sstevel@tonic-gate /*
1697c478bd9Sstevel@tonic-gate * Walk all instances of uhci.
1707c478bd9Sstevel@tonic-gate * The callback func checks if td_qh belongs to a given instance
1717c478bd9Sstevel@tonic-gate * of uhci.
1727c478bd9Sstevel@tonic-gate */
1737c478bd9Sstevel@tonic-gate if (mdb_pwalk("softstate", find_uhci_instance, &cb_data,
1747c478bd9Sstevel@tonic-gate uhci_ss) != 0) {
1757c478bd9Sstevel@tonic-gate mdb_warn("failed to walk softstate");
1767c478bd9Sstevel@tonic-gate return (-1);
1777c478bd9Sstevel@tonic-gate }
1787c478bd9Sstevel@tonic-gate
1797c478bd9Sstevel@tonic-gate if (cb_data.fic_found == TRUE) {
1807c478bd9Sstevel@tonic-gate return (1);
1817c478bd9Sstevel@tonic-gate }
1827c478bd9Sstevel@tonic-gate
1837c478bd9Sstevel@tonic-gate return (0);
1847c478bd9Sstevel@tonic-gate }
1857c478bd9Sstevel@tonic-gate
1867c478bd9Sstevel@tonic-gate /*
1877c478bd9Sstevel@tonic-gate * Dump a UHCI TD (transaction descriptor);
1887c478bd9Sstevel@tonic-gate * or (-d) the chain of TDs starting with the one specified.
1897c478bd9Sstevel@tonic-gate */
1907c478bd9Sstevel@tonic-gate int
uhci_td(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1917c478bd9Sstevel@tonic-gate uhci_td(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1927c478bd9Sstevel@tonic-gate {
1937c478bd9Sstevel@tonic-gate uint_t depth_flag = FALSE;
1947c478bd9Sstevel@tonic-gate uhci_state_t uhci_state, *uhcip = &uhci_state;
1957c478bd9Sstevel@tonic-gate uhci_td_t td;
1967c478bd9Sstevel@tonic-gate
1977c478bd9Sstevel@tonic-gate
1987c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC))
1997c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
2007c478bd9Sstevel@tonic-gate
2017c478bd9Sstevel@tonic-gate if (addr & ~QH_LINK_PTR_MASK) {
2027c478bd9Sstevel@tonic-gate mdb_warn("address must be on a 16-byte boundary.\n");
2037c478bd9Sstevel@tonic-gate return (DCMD_ERR);
2047c478bd9Sstevel@tonic-gate }
2057c478bd9Sstevel@tonic-gate
2067c478bd9Sstevel@tonic-gate if (mdb_getopts(argc, argv,
2077c478bd9Sstevel@tonic-gate 'd', MDB_OPT_SETBITS, TRUE, &depth_flag,
2087c478bd9Sstevel@tonic-gate NULL) != argc) {
2097c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
2107c478bd9Sstevel@tonic-gate }
2117c478bd9Sstevel@tonic-gate
2127c478bd9Sstevel@tonic-gate
2137c478bd9Sstevel@tonic-gate if (depth_flag) {
2147c478bd9Sstevel@tonic-gate if (mdb_pwalk_dcmd("uhci_td", "uhci_td", 0, NULL, addr) == -1) {
2157c478bd9Sstevel@tonic-gate mdb_warn("failed to walk 'uhci_td'");
2167c478bd9Sstevel@tonic-gate return (DCMD_ERR);
2177c478bd9Sstevel@tonic-gate }
2187c478bd9Sstevel@tonic-gate return (DCMD_OK);
2197c478bd9Sstevel@tonic-gate }
2207c478bd9Sstevel@tonic-gate
2217c478bd9Sstevel@tonic-gate
2227c478bd9Sstevel@tonic-gate if (find_uhci_statep((void *)addr, UHCI_TD, uhcip) != 1) {
2237c478bd9Sstevel@tonic-gate mdb_warn("failed to find uhci_statep");
2247c478bd9Sstevel@tonic-gate return (DCMD_ERR);
2257c478bd9Sstevel@tonic-gate }
2267c478bd9Sstevel@tonic-gate
2277c478bd9Sstevel@tonic-gate if (mdb_vread(&td, sizeof (td), addr) != sizeof (td)) {
2287c478bd9Sstevel@tonic-gate mdb_warn("failed to read td at vaddr %p", addr);
2297c478bd9Sstevel@tonic-gate return (DCMD_ERR);
2307c478bd9Sstevel@tonic-gate }
2317c478bd9Sstevel@tonic-gate
2327c478bd9Sstevel@tonic-gate mdb_printf("\n UHCI td struct at (vaddr) %08x:\n", addr);
2337c478bd9Sstevel@tonic-gate
2347c478bd9Sstevel@tonic-gate if (!(td.link_ptr & HC_END_OF_LIST) && td.link_ptr != NULL) {
2357c478bd9Sstevel@tonic-gate mdb_printf(" link_ptr (paddr) : %-8x "
2367c478bd9Sstevel@tonic-gate "(vaddr) : %p\n",
2377c478bd9Sstevel@tonic-gate td.link_ptr,
2387c478bd9Sstevel@tonic-gate /* Note: uhcip needed by TD_VADDR macro */
2397c478bd9Sstevel@tonic-gate TD_VADDR(td.link_ptr & QH_LINK_PTR_MASK));
2407c478bd9Sstevel@tonic-gate } else {
2417c478bd9Sstevel@tonic-gate mdb_printf(" link_ptr (paddr) : %-8x\n",
2427c478bd9Sstevel@tonic-gate td.link_ptr);
2437c478bd9Sstevel@tonic-gate }
2447c478bd9Sstevel@tonic-gate mdb_printf(" td_dword2 : %08x\n", td.dw2);
2457c478bd9Sstevel@tonic-gate mdb_printf(" td_dword3 : %08x\n", td.dw3);
2467c478bd9Sstevel@tonic-gate mdb_printf(" buffer_address : %08x\n", td.buffer_address);
2477c478bd9Sstevel@tonic-gate mdb_printf(" qh_td_prev : %?p "
2487c478bd9Sstevel@tonic-gate "tw_td_next : %?p\n",
2497c478bd9Sstevel@tonic-gate td.qh_td_prev, td.tw_td_next);
2507c478bd9Sstevel@tonic-gate mdb_printf(" outst_td_prev : %?p "
2517c478bd9Sstevel@tonic-gate "outst_td_next : %?p\n",
2527c478bd9Sstevel@tonic-gate td.outst_td_prev, td.outst_td_next);
2537c478bd9Sstevel@tonic-gate mdb_printf(" tw : %?p "
2547c478bd9Sstevel@tonic-gate "flag : %02x\n", td.tw, td.flag);
2557c478bd9Sstevel@tonic-gate mdb_printf(" isoc_next : %?p "
2567c478bd9Sstevel@tonic-gate "isoc_prev : %0x\n", td.isoc_next, td.isoc_prev);
2577c478bd9Sstevel@tonic-gate mdb_printf(" isoc_pkt_index : %0x "
2587c478bd9Sstevel@tonic-gate "startingframe: %0x\n", td.isoc_pkt_index, td.starting_frame);
2597c478bd9Sstevel@tonic-gate
2607c478bd9Sstevel@tonic-gate
2617c478bd9Sstevel@tonic-gate if (td.link_ptr == NULL) {
2627c478bd9Sstevel@tonic-gate mdb_printf(" --> Link pointer = NULL\n");
2637c478bd9Sstevel@tonic-gate return (DCMD_ERR);
2647c478bd9Sstevel@tonic-gate } else {
2657c478bd9Sstevel@tonic-gate
2667c478bd9Sstevel@tonic-gate /* Inform user if link is to a TD or QH. */
2677c478bd9Sstevel@tonic-gate if (td.link_ptr & HC_END_OF_LIST) {
2687c478bd9Sstevel@tonic-gate mdb_printf(" "
2697c478bd9Sstevel@tonic-gate "--> Link pointer invalid (terminate bit set).\n");
2707c478bd9Sstevel@tonic-gate } else {
2717c478bd9Sstevel@tonic-gate if ((td.link_ptr & HC_QUEUE_HEAD) == HC_QUEUE_HEAD) {
2727c478bd9Sstevel@tonic-gate mdb_printf(" "
2737c478bd9Sstevel@tonic-gate "--> Link pointer points to a QH.\n");
2747c478bd9Sstevel@tonic-gate } else {
2757c478bd9Sstevel@tonic-gate mdb_printf(" "
2767c478bd9Sstevel@tonic-gate "--> Link pointer points to a TD.\n");
2777c478bd9Sstevel@tonic-gate }
2787c478bd9Sstevel@tonic-gate }
2797c478bd9Sstevel@tonic-gate }
2807c478bd9Sstevel@tonic-gate
2817c478bd9Sstevel@tonic-gate return (DCMD_OK);
2827c478bd9Sstevel@tonic-gate }
2837c478bd9Sstevel@tonic-gate
2847c478bd9Sstevel@tonic-gate /*
2857c478bd9Sstevel@tonic-gate * Dump a UHCI QH (queue head).
2867c478bd9Sstevel@tonic-gate * -b walk/dump the chian of QHs starting with the one specified.
2877c478bd9Sstevel@tonic-gate * -d also dump the chain of TDs starting with the one specified.
2887c478bd9Sstevel@tonic-gate */
2897c478bd9Sstevel@tonic-gate int
uhci_qh(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)2907c478bd9Sstevel@tonic-gate uhci_qh(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2917c478bd9Sstevel@tonic-gate {
2927c478bd9Sstevel@tonic-gate uint_t breadth_flag = FALSE, depth_flag = FALSE;
2937c478bd9Sstevel@tonic-gate uhci_state_t uhci_state, *uhcip = &uhci_state;
2947c478bd9Sstevel@tonic-gate queue_head_t qh;
2957c478bd9Sstevel@tonic-gate
2967c478bd9Sstevel@tonic-gate
2977c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC))
2987c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
2997c478bd9Sstevel@tonic-gate
3007c478bd9Sstevel@tonic-gate if (addr & ~QH_LINK_PTR_MASK) {
3017c478bd9Sstevel@tonic-gate mdb_warn("address must be on a 16-byte boundary.\n");
3027c478bd9Sstevel@tonic-gate return (DCMD_ERR);
3037c478bd9Sstevel@tonic-gate }
3047c478bd9Sstevel@tonic-gate
3057c478bd9Sstevel@tonic-gate if (mdb_getopts(argc, argv,
3067c478bd9Sstevel@tonic-gate 'b', MDB_OPT_SETBITS, TRUE, &breadth_flag,
3077c478bd9Sstevel@tonic-gate 'd', MDB_OPT_SETBITS, TRUE, &depth_flag,
3087c478bd9Sstevel@tonic-gate NULL) != argc) {
3097c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
3107c478bd9Sstevel@tonic-gate }
3117c478bd9Sstevel@tonic-gate
3127c478bd9Sstevel@tonic-gate
3137c478bd9Sstevel@tonic-gate if (breadth_flag) {
3147c478bd9Sstevel@tonic-gate uint_t new_argc = 0;
3157c478bd9Sstevel@tonic-gate mdb_arg_t new_argv[1];
3167c478bd9Sstevel@tonic-gate
3177c478bd9Sstevel@tonic-gate
3187c478bd9Sstevel@tonic-gate if (depth_flag) {
3197c478bd9Sstevel@tonic-gate new_argc = 1;
3207c478bd9Sstevel@tonic-gate new_argv[0].a_type = MDB_TYPE_STRING;
3217c478bd9Sstevel@tonic-gate new_argv[0].a_un.a_str = "-d";
3227c478bd9Sstevel@tonic-gate }
3237c478bd9Sstevel@tonic-gate
3247c478bd9Sstevel@tonic-gate if ((mdb_pwalk_dcmd("uhci_qh", "uhci_qh", new_argc, new_argv,
3257c478bd9Sstevel@tonic-gate addr)) != 0) {
3267c478bd9Sstevel@tonic-gate mdb_warn("failed to walk 'uhci_qh'");
3277c478bd9Sstevel@tonic-gate return (DCMD_ERR);
3287c478bd9Sstevel@tonic-gate }
3297c478bd9Sstevel@tonic-gate return (DCMD_OK);
3307c478bd9Sstevel@tonic-gate }
3317c478bd9Sstevel@tonic-gate
3327c478bd9Sstevel@tonic-gate
3337c478bd9Sstevel@tonic-gate if (find_uhci_statep((void *)addr, UHCI_QH, uhcip) != 1) {
3347c478bd9Sstevel@tonic-gate mdb_warn("failed to find uhci_statep");
3357c478bd9Sstevel@tonic-gate return (DCMD_ERR);
3367c478bd9Sstevel@tonic-gate }
3377c478bd9Sstevel@tonic-gate
3387c478bd9Sstevel@tonic-gate
3397c478bd9Sstevel@tonic-gate if (mdb_vread(&qh, sizeof (qh), addr) != sizeof (qh)) {
3407c478bd9Sstevel@tonic-gate mdb_warn("failed to read qh at vaddr %p", addr);
3417c478bd9Sstevel@tonic-gate return (DCMD_ERR);
3427c478bd9Sstevel@tonic-gate }
3437c478bd9Sstevel@tonic-gate
3447c478bd9Sstevel@tonic-gate mdb_printf("\n UHCI qh struct at (vaddr) %08x:\n", addr);
3457c478bd9Sstevel@tonic-gate
3467c478bd9Sstevel@tonic-gate if (!(qh.link_ptr & HC_END_OF_LIST) && qh.link_ptr != NULL) {
3477c478bd9Sstevel@tonic-gate mdb_printf(" link_ptr (paddr) : %08x "
3487c478bd9Sstevel@tonic-gate "(vaddr) : %p\n",
3497c478bd9Sstevel@tonic-gate qh.link_ptr,
3507c478bd9Sstevel@tonic-gate /* Note: uhcip needed by QH_VADDR macro */
3517c478bd9Sstevel@tonic-gate QH_VADDR(qh.link_ptr & QH_LINK_PTR_MASK));
3527c478bd9Sstevel@tonic-gate } else {
3537c478bd9Sstevel@tonic-gate mdb_printf(
3547c478bd9Sstevel@tonic-gate " link_ptr (paddr) : %08x\n",
3557c478bd9Sstevel@tonic-gate qh.link_ptr);
3567c478bd9Sstevel@tonic-gate }
3577c478bd9Sstevel@tonic-gate
3587c478bd9Sstevel@tonic-gate if (!(qh.element_ptr & HC_END_OF_LIST) && qh.element_ptr != NULL) {
3597c478bd9Sstevel@tonic-gate mdb_printf(" element_ptr (paddr) : %08x "
3607c478bd9Sstevel@tonic-gate "(vaddr) : %p\n",
3617c478bd9Sstevel@tonic-gate qh.element_ptr,
3627c478bd9Sstevel@tonic-gate /* Note: uhcip needed by TD_VADDR macro */
3637c478bd9Sstevel@tonic-gate TD_VADDR(qh.element_ptr & QH_LINK_PTR_MASK));
3647c478bd9Sstevel@tonic-gate } else {
3657c478bd9Sstevel@tonic-gate mdb_printf(
3667c478bd9Sstevel@tonic-gate " element_ptr (paddr) : %08x\n", qh.element_ptr);
3677c478bd9Sstevel@tonic-gate }
3687c478bd9Sstevel@tonic-gate
3697c478bd9Sstevel@tonic-gate mdb_printf(" node : %04x "
3707c478bd9Sstevel@tonic-gate "flag : %04x\n",
3717c478bd9Sstevel@tonic-gate qh.node, qh.qh_flag);
3727c478bd9Sstevel@tonic-gate mdb_printf(" prev_qh : %?p "
3737c478bd9Sstevel@tonic-gate "td_tailp : %?p\n",
3747c478bd9Sstevel@tonic-gate qh.prev_qh, qh.td_tailp);
3757c478bd9Sstevel@tonic-gate mdb_printf(" bulk_xfer_isoc_info : %?p\n", qh.bulk_xfer_info);
3767c478bd9Sstevel@tonic-gate
3777c478bd9Sstevel@tonic-gate
3787c478bd9Sstevel@tonic-gate if (qh.link_ptr == NULL) {
3797c478bd9Sstevel@tonic-gate mdb_printf(" --> Link pointer = NULL\n");
3807c478bd9Sstevel@tonic-gate return (DCMD_ERR);
3817c478bd9Sstevel@tonic-gate } else {
3827c478bd9Sstevel@tonic-gate
3837c478bd9Sstevel@tonic-gate /* Inform user if next link is a TD or QH. */
3847c478bd9Sstevel@tonic-gate if (qh.link_ptr & HC_END_OF_LIST) {
3857c478bd9Sstevel@tonic-gate mdb_printf(" "
3867c478bd9Sstevel@tonic-gate "--> Link pointer invalid (terminate bit set).\n");
3877c478bd9Sstevel@tonic-gate } else {
3887c478bd9Sstevel@tonic-gate if ((qh.link_ptr & HC_QUEUE_HEAD) == HC_QUEUE_HEAD) {
3897c478bd9Sstevel@tonic-gate mdb_printf(" "
3907c478bd9Sstevel@tonic-gate "--> Link pointer points to a QH.\n");
3917c478bd9Sstevel@tonic-gate } else {
3927c478bd9Sstevel@tonic-gate /* Should never happen. */
3937c478bd9Sstevel@tonic-gate mdb_warn(" "
3947c478bd9Sstevel@tonic-gate "--> Link pointer points to a TD.\n");
3957c478bd9Sstevel@tonic-gate return (DCMD_ERR);
3967c478bd9Sstevel@tonic-gate }
3977c478bd9Sstevel@tonic-gate }
3987c478bd9Sstevel@tonic-gate }
3997c478bd9Sstevel@tonic-gate
4007c478bd9Sstevel@tonic-gate
4017c478bd9Sstevel@tonic-gate if (qh.element_ptr == NULL) {
4027c478bd9Sstevel@tonic-gate mdb_printf(" element_ptr = NULL\n");
4037c478bd9Sstevel@tonic-gate return (DCMD_ERR);
4047c478bd9Sstevel@tonic-gate } else {
4057c478bd9Sstevel@tonic-gate
4067c478bd9Sstevel@tonic-gate /* Inform user if next element is a TD or QH. */
4077c478bd9Sstevel@tonic-gate if (qh.element_ptr & HC_END_OF_LIST) {
4087c478bd9Sstevel@tonic-gate mdb_printf(" "
4097c478bd9Sstevel@tonic-gate "-->Element pointer invalid (terminate bit set)."
4107c478bd9Sstevel@tonic-gate "\n");
4117c478bd9Sstevel@tonic-gate return (DCMD_OK);
4127c478bd9Sstevel@tonic-gate } else {
4137c478bd9Sstevel@tonic-gate if ((qh.element_ptr & HC_QUEUE_HEAD) == HC_QUEUE_HEAD) {
4147c478bd9Sstevel@tonic-gate mdb_printf(" "
4157c478bd9Sstevel@tonic-gate "--> Element pointer points to a QH.\n");
4167c478bd9Sstevel@tonic-gate /* Should never happen in UHCI implementation */
4177c478bd9Sstevel@tonic-gate return (DCMD_ERR);
4187c478bd9Sstevel@tonic-gate } else {
4197c478bd9Sstevel@tonic-gate mdb_printf(" "
4207c478bd9Sstevel@tonic-gate "--> Element pointer points to a TD.\n");
4217c478bd9Sstevel@tonic-gate }
4227c478bd9Sstevel@tonic-gate }
4237c478bd9Sstevel@tonic-gate }
4247c478bd9Sstevel@tonic-gate
4257c478bd9Sstevel@tonic-gate /*
4267c478bd9Sstevel@tonic-gate * If the user specified the -d (depth) option,
4277c478bd9Sstevel@tonic-gate * dump all TDs linked to this TD via the element_ptr.
4287c478bd9Sstevel@tonic-gate */
4297c478bd9Sstevel@tonic-gate if (depth_flag) {
4307c478bd9Sstevel@tonic-gate
4317c478bd9Sstevel@tonic-gate /* Traverse and display all the TDs in the chain */
4327c478bd9Sstevel@tonic-gate if (mdb_pwalk_dcmd("uhci_td", "uhci_td", argc, argv,
4337c478bd9Sstevel@tonic-gate (uintptr_t)(TD_VADDR(qh.element_ptr &
4347c478bd9Sstevel@tonic-gate QH_LINK_PTR_MASK))) == -1) {
4357c478bd9Sstevel@tonic-gate mdb_warn("failed to walk 'uhci_td'");
4367c478bd9Sstevel@tonic-gate return (DCMD_ERR);
4377c478bd9Sstevel@tonic-gate }
4387c478bd9Sstevel@tonic-gate }
4397c478bd9Sstevel@tonic-gate
4407c478bd9Sstevel@tonic-gate return (DCMD_OK);
4417c478bd9Sstevel@tonic-gate }
4427c478bd9Sstevel@tonic-gate
4437c478bd9Sstevel@tonic-gate /*
4447c478bd9Sstevel@tonic-gate * Walk a list of UHCI Transaction Descriptors (td's).
4457c478bd9Sstevel@tonic-gate * Stop at the end of the list, or if the next element in the list is a
4467c478bd9Sstevel@tonic-gate * queue head (qh).
4477c478bd9Sstevel@tonic-gate * User must specify the address of the first td to look at.
4487c478bd9Sstevel@tonic-gate */
4497c478bd9Sstevel@tonic-gate int
uhci_td_walk_init(mdb_walk_state_t * wsp)4507c478bd9Sstevel@tonic-gate uhci_td_walk_init(mdb_walk_state_t *wsp)
4517c478bd9Sstevel@tonic-gate {
4527c478bd9Sstevel@tonic-gate if (wsp->walk_addr == NULL) {
4537c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
4547c478bd9Sstevel@tonic-gate }
4557c478bd9Sstevel@tonic-gate
4567c478bd9Sstevel@tonic-gate wsp->walk_data = mdb_alloc(sizeof (uhci_td_t), UM_SLEEP | UM_GC);
4577c478bd9Sstevel@tonic-gate wsp->walk_arg = mdb_alloc(sizeof (uhci_state_t), UM_SLEEP | UM_GC);
4587c478bd9Sstevel@tonic-gate
4597c478bd9Sstevel@tonic-gate
4607c478bd9Sstevel@tonic-gate /*
4617c478bd9Sstevel@tonic-gate * Read the uhci_state_t for the instance of uhci
4627c478bd9Sstevel@tonic-gate * using this td address into buf pointed to by walk_arg.
4637c478bd9Sstevel@tonic-gate */
4647c478bd9Sstevel@tonic-gate if (find_uhci_statep((void *)wsp->walk_addr, UHCI_TD,
4657c478bd9Sstevel@tonic-gate wsp->walk_arg) != 1) {
4667c478bd9Sstevel@tonic-gate mdb_warn("failed to find uhci_statep");
4677c478bd9Sstevel@tonic-gate return (WALK_ERR);
4687c478bd9Sstevel@tonic-gate }
4697c478bd9Sstevel@tonic-gate
4707c478bd9Sstevel@tonic-gate return (WALK_NEXT);
4717c478bd9Sstevel@tonic-gate }
4727c478bd9Sstevel@tonic-gate
4737c478bd9Sstevel@tonic-gate /*
4747c478bd9Sstevel@tonic-gate * At each step, read a TD into our private storage, and then invoke
4757c478bd9Sstevel@tonic-gate * the callback function. We terminate when we reach a QH, or
4767c478bd9Sstevel@tonic-gate * link_ptr is NULL.
4777c478bd9Sstevel@tonic-gate */
4787c478bd9Sstevel@tonic-gate int
uhci_td_walk_step(mdb_walk_state_t * wsp)4797c478bd9Sstevel@tonic-gate uhci_td_walk_step(mdb_walk_state_t *wsp)
4807c478bd9Sstevel@tonic-gate {
4817c478bd9Sstevel@tonic-gate int status;
4827c478bd9Sstevel@tonic-gate uhci_state_t *uhcip = (uhci_state_t *)wsp->walk_arg;
4837c478bd9Sstevel@tonic-gate
4847c478bd9Sstevel@tonic-gate
4857c478bd9Sstevel@tonic-gate if (mdb_vread(wsp->walk_data, sizeof (uhci_td_t), wsp->walk_addr)
4867c478bd9Sstevel@tonic-gate == -1) {
4877c478bd9Sstevel@tonic-gate mdb_warn("failed to read td at %p", wsp->walk_addr);
4887c478bd9Sstevel@tonic-gate return (WALK_DONE);
4897c478bd9Sstevel@tonic-gate }
4907c478bd9Sstevel@tonic-gate
4917c478bd9Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
4927c478bd9Sstevel@tonic-gate wsp->walk_cbdata);
4937c478bd9Sstevel@tonic-gate
4947c478bd9Sstevel@tonic-gate /* Next td. */
4957c478bd9Sstevel@tonic-gate wsp->walk_addr = ((uhci_td_t *)wsp->walk_data)->link_ptr;
4967c478bd9Sstevel@tonic-gate
4977c478bd9Sstevel@tonic-gate /* Check if we're at the last element */
4987c478bd9Sstevel@tonic-gate if (wsp->walk_addr == NULL || wsp->walk_addr & HC_END_OF_LIST)
4997c478bd9Sstevel@tonic-gate return (WALK_DONE);
5007c478bd9Sstevel@tonic-gate
5017c478bd9Sstevel@tonic-gate /* Make sure next element is a TD. If a QH, stop. */
5027c478bd9Sstevel@tonic-gate if (((((uhci_td_t *)wsp->walk_data)->link_ptr) & HC_QUEUE_HEAD)
5037c478bd9Sstevel@tonic-gate == HC_QUEUE_HEAD) {
5047c478bd9Sstevel@tonic-gate return (WALK_DONE);
5057c478bd9Sstevel@tonic-gate }
5067c478bd9Sstevel@tonic-gate
5077c478bd9Sstevel@tonic-gate /* Strip terminate etc. bits. */
5087c478bd9Sstevel@tonic-gate wsp->walk_addr &= QH_LINK_PTR_MASK; /* there is no TD_LINK_PTR_MASK */
5097c478bd9Sstevel@tonic-gate
5107c478bd9Sstevel@tonic-gate if (wsp->walk_addr == NULL)
5117c478bd9Sstevel@tonic-gate return (WALK_DONE);
5127c478bd9Sstevel@tonic-gate
5137c478bd9Sstevel@tonic-gate /*
5147c478bd9Sstevel@tonic-gate * Convert link_ptr paddr to vaddr
5157c478bd9Sstevel@tonic-gate * Note: uhcip needed by TD_VADDR macro
5167c478bd9Sstevel@tonic-gate */
5177c478bd9Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)TD_VADDR(wsp->walk_addr);
5187c478bd9Sstevel@tonic-gate
5197c478bd9Sstevel@tonic-gate return (status);
5207c478bd9Sstevel@tonic-gate }
5217c478bd9Sstevel@tonic-gate
5227c478bd9Sstevel@tonic-gate /*
5237c478bd9Sstevel@tonic-gate * Walk a list of UHCI Queue Heads (qh's).
5247c478bd9Sstevel@tonic-gate * Stop at the end of the list, or if the next element in the list is a
5257c478bd9Sstevel@tonic-gate * Transaction Descriptor (td).
5267c478bd9Sstevel@tonic-gate * User must specify the address of the first qh to look at.
5277c478bd9Sstevel@tonic-gate */
5287c478bd9Sstevel@tonic-gate int
uhci_qh_walk_init(mdb_walk_state_t * wsp)5297c478bd9Sstevel@tonic-gate uhci_qh_walk_init(mdb_walk_state_t *wsp)
5307c478bd9Sstevel@tonic-gate {
5317c478bd9Sstevel@tonic-gate if (wsp->walk_addr == NULL)
5327c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
5337c478bd9Sstevel@tonic-gate
5347c478bd9Sstevel@tonic-gate wsp->walk_data = mdb_alloc(sizeof (queue_head_t), UM_SLEEP | UM_GC);
5357c478bd9Sstevel@tonic-gate wsp->walk_arg = mdb_alloc(sizeof (uhci_state_t), UM_SLEEP | UM_GC);
5367c478bd9Sstevel@tonic-gate
5377c478bd9Sstevel@tonic-gate
5387c478bd9Sstevel@tonic-gate /*
5397c478bd9Sstevel@tonic-gate * Read the uhci_state_t for the instance of uhci
5407c478bd9Sstevel@tonic-gate * using this td address into buf pointed to by walk_arg.
5417c478bd9Sstevel@tonic-gate */
5427c478bd9Sstevel@tonic-gate if (find_uhci_statep((void *)wsp->walk_addr, UHCI_QH,
5437c478bd9Sstevel@tonic-gate (uhci_state_t *)wsp->walk_arg) != 1) {
5447c478bd9Sstevel@tonic-gate mdb_warn("failed to find uhci_statep");
5457c478bd9Sstevel@tonic-gate return (WALK_ERR);
5467c478bd9Sstevel@tonic-gate }
5477c478bd9Sstevel@tonic-gate
5487c478bd9Sstevel@tonic-gate return (WALK_NEXT);
5497c478bd9Sstevel@tonic-gate }
5507c478bd9Sstevel@tonic-gate
5517c478bd9Sstevel@tonic-gate /*
5527c478bd9Sstevel@tonic-gate * At each step, read a QH into our private storage, and then invoke
5537c478bd9Sstevel@tonic-gate * the callback function. We terminate when we reach a QH, or
5547c478bd9Sstevel@tonic-gate * link_ptr is NULL.
5557c478bd9Sstevel@tonic-gate */
5567c478bd9Sstevel@tonic-gate int
uhci_qh_walk_step(mdb_walk_state_t * wsp)5577c478bd9Sstevel@tonic-gate uhci_qh_walk_step(mdb_walk_state_t *wsp)
5587c478bd9Sstevel@tonic-gate {
5597c478bd9Sstevel@tonic-gate int status;
5607c478bd9Sstevel@tonic-gate uhci_state_t *uhcip = (uhci_state_t *)wsp->walk_arg;
5617c478bd9Sstevel@tonic-gate
5627c478bd9Sstevel@tonic-gate
5637c478bd9Sstevel@tonic-gate if (wsp->walk_addr == NULL) /* Should never occur */
5647c478bd9Sstevel@tonic-gate return (WALK_DONE);
5657c478bd9Sstevel@tonic-gate
5667c478bd9Sstevel@tonic-gate if (mdb_vread(wsp->walk_data, sizeof (queue_head_t), wsp->walk_addr)
5677c478bd9Sstevel@tonic-gate == -1) {
5687c478bd9Sstevel@tonic-gate mdb_warn("failure reading qh at %p", wsp->walk_addr);
5697c478bd9Sstevel@tonic-gate return (WALK_DONE);
5707c478bd9Sstevel@tonic-gate }
5717c478bd9Sstevel@tonic-gate
5727c478bd9Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
5737c478bd9Sstevel@tonic-gate wsp->walk_cbdata);
5747c478bd9Sstevel@tonic-gate
5757c478bd9Sstevel@tonic-gate /* Next QH. */
5767c478bd9Sstevel@tonic-gate wsp->walk_addr = ((queue_head_t *)wsp->walk_data)->link_ptr;
5777c478bd9Sstevel@tonic-gate
5787c478bd9Sstevel@tonic-gate
5797c478bd9Sstevel@tonic-gate /* Check if we're at the last element */
5807c478bd9Sstevel@tonic-gate if (wsp->walk_addr == NULL || wsp->walk_addr & HC_END_OF_LIST) {
5817c478bd9Sstevel@tonic-gate return (WALK_DONE);
5827c478bd9Sstevel@tonic-gate }
5837c478bd9Sstevel@tonic-gate
5847c478bd9Sstevel@tonic-gate /* Make sure next element is a QH. If a TD, stop. */
585*a7317cebSRichard Lowe if (((((queue_head_t *)wsp->walk_data)->link_ptr) & HC_QUEUE_HEAD)
586*a7317cebSRichard Lowe != HC_QUEUE_HEAD) {
5877c478bd9Sstevel@tonic-gate return (WALK_DONE);
5887c478bd9Sstevel@tonic-gate }
5897c478bd9Sstevel@tonic-gate
5907c478bd9Sstevel@tonic-gate /* Strip terminate etc. bits. */
5917c478bd9Sstevel@tonic-gate wsp->walk_addr &= QH_LINK_PTR_MASK;
5927c478bd9Sstevel@tonic-gate
5937c478bd9Sstevel@tonic-gate if (wsp->walk_addr == NULL)
5947c478bd9Sstevel@tonic-gate return (WALK_DONE);
5957c478bd9Sstevel@tonic-gate
5967c478bd9Sstevel@tonic-gate /*
5977c478bd9Sstevel@tonic-gate * Convert link_ptr paddr to vaddr
5987c478bd9Sstevel@tonic-gate * Note: uhcip needed by QH_VADDR macro
5997c478bd9Sstevel@tonic-gate */
6007c478bd9Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)QH_VADDR(wsp->walk_addr);
6017c478bd9Sstevel@tonic-gate
6027c478bd9Sstevel@tonic-gate return (status);
6037c478bd9Sstevel@tonic-gate }
6047c478bd9Sstevel@tonic-gate
6057c478bd9Sstevel@tonic-gate /*
6067c478bd9Sstevel@tonic-gate * MDB module linkage information:
6077c478bd9Sstevel@tonic-gate *
6087c478bd9Sstevel@tonic-gate * We declare a list of structures describing our dcmds, and a function
6097c478bd9Sstevel@tonic-gate * named _mdb_init to return a pointer to our module information.
6107c478bd9Sstevel@tonic-gate */
6117c478bd9Sstevel@tonic-gate
6127c478bd9Sstevel@tonic-gate static const mdb_dcmd_t dcmds[] = {
6137c478bd9Sstevel@tonic-gate { "uhci_td", ": [-d]", "print UHCI TD", uhci_td, NULL },
6147c478bd9Sstevel@tonic-gate { "uhci_qh", ": [-bd]", "print UHCI QH", uhci_qh, NULL},
6157c478bd9Sstevel@tonic-gate { NULL }
6167c478bd9Sstevel@tonic-gate };
6177c478bd9Sstevel@tonic-gate
6187c478bd9Sstevel@tonic-gate
6197c478bd9Sstevel@tonic-gate static const mdb_walker_t walkers[] = {
6207c478bd9Sstevel@tonic-gate { "uhci_td", "walk list of UHCI TD structures",
6217c478bd9Sstevel@tonic-gate uhci_td_walk_init, uhci_td_walk_step, NULL,
6227c478bd9Sstevel@tonic-gate NULL },
6237c478bd9Sstevel@tonic-gate { "uhci_qh", "walk list of UHCI QH structures",
6247c478bd9Sstevel@tonic-gate uhci_qh_walk_init, uhci_qh_walk_step, NULL,
6257c478bd9Sstevel@tonic-gate NULL },
6267c478bd9Sstevel@tonic-gate { NULL }
6277c478bd9Sstevel@tonic-gate };
6287c478bd9Sstevel@tonic-gate
6297c478bd9Sstevel@tonic-gate static const mdb_modinfo_t modinfo = {
6307c478bd9Sstevel@tonic-gate MDB_API_VERSION, dcmds, walkers
6317c478bd9Sstevel@tonic-gate };
6327c478bd9Sstevel@tonic-gate
6337c478bd9Sstevel@tonic-gate
6347c478bd9Sstevel@tonic-gate const mdb_modinfo_t *
_mdb_init(void)6357c478bd9Sstevel@tonic-gate _mdb_init(void)
6367c478bd9Sstevel@tonic-gate {
6377c478bd9Sstevel@tonic-gate return (&modinfo);
6387c478bd9Sstevel@tonic-gate }
639