/*ARGSUSED*/ int memseg_list(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { struct memseg ms; if (!(flags & DCMD_ADDRSPEC)) { if (mdb_pwalk_dcmd("memseg", "memseg_list", 0, NULL, 0) == -1) { mdb_warn("can't walk memseg"); return (DCMD_ERR); } return (DCMD_OK); } if (DCMD_HDRSPEC(flags)) mdb_printf("%<u>%?s %?s %?s %?s %?s%</u>\n", "ADDR", "PAGES", "EPAGES", "BASE", "END"); if (mdb_vread(&ms, sizeof (struct memseg), addr) == -1) { mdb_warn("can't read memseg at %#lx", addr); return (DCMD_ERR); } mdb_printf("%0?lx %0?lx %0?lx %0?lx %0?lx\n", addr, ms.pages, ms.epages, ms.pages_base, ms.pages_end); return (DCMD_OK); }
/* ARGSUSED */ static int module_serd(uintptr_t addr, const void *data, void *wsp) { fmd_module_t *modp = (fmd_module_t *)data; if (modp->mod_serds.sh_count != 0) { modp = (fmd_module_t *)addr; (void) mdb_pwalk_dcmd("fmd_serd", "fmd_serd", 0, 0, (uintptr_t)&modp->mod_serds); } return (WALK_NEXT); }
int sysevent(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { if ((flags & DCMD_ADDRSPEC) == 0) return (DCMD_USAGE); if ((flags & DCMD_LOOP) == 0) { if (mdb_pwalk_dcmd("sysevent", "sysevent", argc, argv, addr) == -1) { mdb_warn("can't walk sysevent queue"); return (DCMD_ERR); } return (DCMD_OK); } return (sysevent_buf(addr, flags, 0)); }
/* * Display a sv_dev_t hash chain. * Requires an address. * Same options as sv_dev(). */ static int sv_hash(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { if (!(flags & DCMD_ADDRSPEC)) return (DCMD_USAGE); /* * paranoid mode on: qualify walker name with module name * using '`' syntax. */ if (mdb_pwalk_dcmd("sv`sv_hash", "sv`sv_dev", argc, argv, addr) == -1) { mdb_warn("failed to walk sv_dev hash chain"); return (DCMD_ERR); } return (DCMD_OK); }
/* * Look up the symbol name for the given sockparams list and walk * all the entries. */ static boolean_t sockparams_walk_list(const char *symname, int argc, const mdb_arg_t *argv) { GElf_Sym sym; if (mdb_lookup_by_name(symname, &sym)) { mdb_warn("can't find symbol %s", symname); return (B_FALSE); } if (mdb_pwalk_dcmd("list", "sockfs`sockparams", argc, argv, sym.st_value) != 0) { mdb_warn("can't walk %s", symname); return (B_FALSE); } return (B_TRUE); }
int sysevent_class_list(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { int class_name_sz; char class_name[CLASS_LIST_FIELD_MAX]; class_lst_t clist; if ((flags & DCMD_ADDRSPEC) == 0) return (DCMD_USAGE); if ((flags & DCMD_LOOP) == 0) { if (mdb_pwalk_dcmd("sysevent_class_list", "sysevent_class_list", argc, argv, addr) == -1) { mdb_warn("can't walk sysevent class list"); return (DCMD_ERR); } return (DCMD_OK); } if (DCMD_HDRSPEC(flags)) mdb_printf("%<u>%-?s %-24s %-?s%</u>\n", "ADDR", "NAME", "SUBCLASS LIST ADDR"); if (mdb_vread(&clist, sizeof (clist), (uintptr_t)addr) == -1) { mdb_warn("failed to read class clist at %p", addr); return (DCMD_ERR); } if ((class_name_sz = mdb_readstr(class_name, CLASS_LIST_FIELD_MAX, (uintptr_t)clist.cl_name)) == -1) { mdb_warn("failed to read class name at %p", clist.cl_name); return (DCMD_ERR); } if (class_name_sz >= CLASS_LIST_FIELD_MAX - 1) (void) strcpy(&class_name[CLASS_LIST_FIELD_MAX - 4], "..."); mdb_printf("%-?p %-24s %-?p\n", addr, class_name, clist.cl_subclass_list); return (DCMD_OK); }
int memlist(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { struct memlist ml; if (!(flags & DCMD_ADDRSPEC)) { uintptr_t ptr; uint_t list = 0; int i; static const char *lists[] = { "phys_install", "phys_avail", "virt_avail" }; if (mdb_getopts(argc, argv, 'i', MDB_OPT_SETBITS, (1 << 0), &list, 'a', MDB_OPT_SETBITS, (1 << 1), &list, 'v', MDB_OPT_SETBITS, (1 << 2), &list, NULL) != argc) return (DCMD_USAGE); if (!list) list = 1; for (i = 0; list; i++, list >>= 1) { if (!(list & 1)) continue; if ((mdb_readvar(&ptr, lists[i]) == -1) || (ptr == NULL)) { mdb_warn("%s not found or invalid", lists[i]); return (DCMD_ERR); } mdb_printf("%s:\n", lists[i]); if (mdb_pwalk_dcmd("memlist", "memlist", 0, NULL, ptr) == -1) { mdb_warn("can't walk memlist"); return (DCMD_ERR); } } return (DCMD_OK); }
/*ARGSUSED*/ static int python_stack(uintptr_t addr, const PyThreadState *ts, uint_t *verbose) { mdb_arg_t nargv; uint_t nargc = (verbose != NULL && *verbose) ? 1 : 0; /* * Pass the ThreadState to the frame walker. Have frame walker * call frame dcmd. */ mdb_printf("PyThreadState: %0?p\n", addr); nargv.a_type = MDB_TYPE_STRING; nargv.a_un.a_str = "-v"; if (mdb_pwalk_dcmd("pyframe", "pyframe", nargc, &nargv, addr) == -1) { mdb_warn("can't walk 'pyframe'"); return (WALK_ERR); } return (WALK_NEXT); }
static int fmd_ustat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { if (!(flags & DCMD_ADDRSPEC)) { struct fmd_cmd_data ud; ud.argc = argc; ud.argv = argv; if (mdb_walk("fmd_module", module_ustat, &ud) == -1) { mdb_warn("failed to walk 'fmd_module'"); return (DCMD_ERR); } return (DCMD_OK); } if (mdb_pwalk_dcmd("fmd_ustat", "fmd_stat", argc, argv, addr) != 0) { mdb_warn("failed to walk fmd_ustat at %p", addr); return (DCMD_ERR); } return (DCMD_OK); }
/*ARGSUSED*/ int print_nvlist(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { int verbose = B_FALSE; mdb_arg_t v; if (!(flags & DCMD_ADDRSPEC)) return (DCMD_USAGE); if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose, NULL) != argc) return (DCMD_USAGE); v.a_type = MDB_TYPE_STRING; if (verbose) v.a_un.a_str = "-r"; else v.a_un.a_str = "-rq"; return (mdb_pwalk_dcmd("nvpair", "nvpair", 1, &v, addr)); }
/*ARGSUSED*/ static int py_stack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { uint_t verbose = FALSE; if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose, NULL) != argc) return (DCMD_USAGE); if (flags & DCMD_PIPE_OUT) { mdb_warn("py_stack cannot output into a pipe\n"); return (DCMD_ERR); } if (flags & DCMD_ADDRSPEC) { mdb_arg_t nargv; uint_t nargc = verbose ? 1 : 0; nargv.a_type = MDB_TYPE_STRING; nargv.a_un.a_str = "-v"; if (mdb_pwalk_dcmd("pyframe", "pyframe", nargc, &nargv, addr) == -1) { mdb_warn("can't walk 'pyframe'"); return (DCMD_ERR); } return (DCMD_OK); } if (mdb_walk("pyinterp", (mdb_walk_cb_t)python_thread, &verbose) == -1) { mdb_warn("can't walk 'pyinterp'"); return (DCMD_ERR); } return (DCMD_OK); }
/* * Dump a UHCI QH (queue head). * -b walk/dump the chian of QHs starting with the one specified. * -d also dump the chain of TDs starting with the one specified. */ int uhci_qh(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { uint_t breadth_flag = FALSE, depth_flag = FALSE; uhci_state_t uhci_state, *uhcip = &uhci_state; queue_head_t qh; if (!(flags & DCMD_ADDRSPEC)) return (DCMD_USAGE); if (addr & ~QH_LINK_PTR_MASK) { mdb_warn("address must be on a 16-byte boundary.\n"); return (DCMD_ERR); } if (mdb_getopts(argc, argv, 'b', MDB_OPT_SETBITS, TRUE, &breadth_flag, 'd', MDB_OPT_SETBITS, TRUE, &depth_flag, NULL) != argc) { return (DCMD_USAGE); } if (breadth_flag) { uint_t new_argc = 0; mdb_arg_t new_argv[1]; if (depth_flag) { new_argc = 1; new_argv[0].a_type = MDB_TYPE_STRING; new_argv[0].a_un.a_str = "-d"; } if ((mdb_pwalk_dcmd("uhci_qh", "uhci_qh", new_argc, new_argv, addr)) != 0) { mdb_warn("failed to walk 'uhci_qh'"); return (DCMD_ERR); } return (DCMD_OK); } if (find_uhci_statep((void *)addr, UHCI_QH, uhcip) != 1) { mdb_warn("failed to find uhci_statep"); return (DCMD_ERR); } if (mdb_vread(&qh, sizeof (qh), addr) != sizeof (qh)) { mdb_warn("failed to read qh at vaddr %p", addr); return (DCMD_ERR); } mdb_printf("\n UHCI qh struct at (vaddr) %08x:\n", addr); if (!(qh.link_ptr & HC_END_OF_LIST) && qh.link_ptr != NULL) { mdb_printf(" link_ptr (paddr) : %08x " "(vaddr) : %p\n", qh.link_ptr, /* Note: uhcip needed by QH_VADDR macro */ QH_VADDR(qh.link_ptr & QH_LINK_PTR_MASK)); } else { mdb_printf( " link_ptr (paddr) : %08x\n", qh.link_ptr); } if (!(qh.element_ptr & HC_END_OF_LIST) && qh.element_ptr != NULL) { mdb_printf(" element_ptr (paddr) : %08x " "(vaddr) : %p\n", qh.element_ptr, /* Note: uhcip needed by TD_VADDR macro */ TD_VADDR(qh.element_ptr & QH_LINK_PTR_MASK)); } else { mdb_printf( " element_ptr (paddr) : %08x\n", qh.element_ptr); } mdb_printf(" node : %04x " "flag : %04x\n", qh.node, qh.qh_flag); mdb_printf(" prev_qh : %?p " "td_tailp : %?p\n", qh.prev_qh, qh.td_tailp); mdb_printf(" bulk_xfer_isoc_info : %?p\n", qh.bulk_xfer_info); if (qh.link_ptr == NULL) { mdb_printf(" --> Link pointer = NULL\n"); return (DCMD_ERR); } else { /* Inform user if next link is a TD or QH. */ if (qh.link_ptr & HC_END_OF_LIST) { mdb_printf(" " "--> Link pointer invalid (terminate bit set).\n"); } else { if ((qh.link_ptr & HC_QUEUE_HEAD) == HC_QUEUE_HEAD) { mdb_printf(" " "--> Link pointer points to a QH.\n"); } else { /* Should never happen. */ mdb_warn(" " "--> Link pointer points to a TD.\n"); return (DCMD_ERR); } } } if (qh.element_ptr == NULL) { mdb_printf(" element_ptr = NULL\n"); return (DCMD_ERR); } else { /* Inform user if next element is a TD or QH. */ if (qh.element_ptr & HC_END_OF_LIST) { mdb_printf(" " "-->Element pointer invalid (terminate bit set)." "\n"); return (DCMD_OK); } else { if ((qh.element_ptr & HC_QUEUE_HEAD) == HC_QUEUE_HEAD) { mdb_printf(" " "--> Element pointer points to a QH.\n"); /* Should never happen in UHCI implementation */ return (DCMD_ERR); } else { mdb_printf(" " "--> Element pointer points to a TD.\n"); } } } /* * If the user specified the -d (depth) option, * dump all TDs linked to this TD via the element_ptr. */ if (depth_flag) { /* Traverse and display all the TDs in the chain */ if (mdb_pwalk_dcmd("uhci_td", "uhci_td", argc, argv, (uintptr_t)(TD_VADDR(qh.element_ptr & QH_LINK_PTR_MASK))) == -1) { mdb_warn("failed to walk 'uhci_td'"); return (DCMD_ERR); } } return (DCMD_OK); }
/* * Dump a UHCI TD (transaction descriptor); * or (-d) the chain of TDs starting with the one specified. */ int uhci_td(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { uint_t depth_flag = FALSE; uhci_state_t uhci_state, *uhcip = &uhci_state; uhci_td_t td; if (!(flags & DCMD_ADDRSPEC)) return (DCMD_USAGE); if (addr & ~QH_LINK_PTR_MASK) { mdb_warn("address must be on a 16-byte boundary.\n"); return (DCMD_ERR); } if (mdb_getopts(argc, argv, 'd', MDB_OPT_SETBITS, TRUE, &depth_flag, NULL) != argc) { return (DCMD_USAGE); } if (depth_flag) { if (mdb_pwalk_dcmd("uhci_td", "uhci_td", 0, NULL, addr) == -1) { mdb_warn("failed to walk 'uhci_td'"); return (DCMD_ERR); } return (DCMD_OK); } if (find_uhci_statep((void *)addr, UHCI_TD, uhcip) != 1) { mdb_warn("failed to find uhci_statep"); return (DCMD_ERR); } if (mdb_vread(&td, sizeof (td), addr) != sizeof (td)) { mdb_warn("failed to read td at vaddr %p", addr); return (DCMD_ERR); } mdb_printf("\n UHCI td struct at (vaddr) %08x:\n", addr); if (!(td.link_ptr & HC_END_OF_LIST) && td.link_ptr != NULL) { mdb_printf(" link_ptr (paddr) : %-8x " "(vaddr) : %p\n", td.link_ptr, /* Note: uhcip needed by TD_VADDR macro */ TD_VADDR(td.link_ptr & QH_LINK_PTR_MASK)); } else { mdb_printf(" link_ptr (paddr) : %-8x\n", td.link_ptr); } mdb_printf(" td_dword2 : %08x\n", td.dw2); mdb_printf(" td_dword3 : %08x\n", td.dw3); mdb_printf(" buffer_address : %08x\n", td.buffer_address); mdb_printf(" qh_td_prev : %?p " "tw_td_next : %?p\n", td.qh_td_prev, td.tw_td_next); mdb_printf(" outst_td_prev : %?p " "outst_td_next : %?p\n", td.outst_td_prev, td.outst_td_next); mdb_printf(" tw : %?p " "flag : %02x\n", td.tw, td.flag); mdb_printf(" isoc_next : %?p " "isoc_prev : %0x\n", td.isoc_next, td.isoc_prev); mdb_printf(" isoc_pkt_index : %0x " "startingframe: %0x\n", td.isoc_pkt_index, td.starting_frame); if (td.link_ptr == NULL) { mdb_printf(" --> Link pointer = NULL\n"); return (DCMD_ERR); } else { /* Inform user if link is to a TD or QH. */ if (td.link_ptr & HC_END_OF_LIST) { mdb_printf(" " "--> Link pointer invalid (terminate bit set).\n"); } else { if ((td.link_ptr & HC_QUEUE_HEAD) == HC_QUEUE_HEAD) { mdb_printf(" " "--> Link pointer points to a QH.\n"); } else { mdb_printf(" " "--> Link pointer points to a TD.\n"); } } } return (DCMD_OK); }
/*ARGSUSED*/ int nvpair_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { nvpair_t nvpair_tmp, *nvpair; int32_t i, size, nelem, elem_size = 0; char *data = NULL, *data_end = NULL; char *type_name = NULL; data_type_t type = DATA_TYPE_UNKNOWN; int quiet = FALSE; int recurse = FALSE; if (!(flags & DCMD_ADDRSPEC)) return (DCMD_USAGE); if (mdb_getopts(argc, argv, 'r', MDB_OPT_SETBITS, TRUE, &recurse, 'q', MDB_OPT_SETBITS, TRUE, &quiet, NULL) != argc) return (DCMD_USAGE); /* read in the nvpair header so we can get the size */ if (mdb_vread(&nvpair_tmp, sizeof (nvpair), addr) == -1) { mdb_warn("failed to read nvpair at %p", addr); return (DCMD_ERR); } size = NVP_SIZE(&nvpair_tmp); if (size == 0) { mdb_warn("nvpair of size zero at %p", addr); return (DCMD_OK); } /* read in the entire nvpair */ nvpair = mdb_alloc(size, UM_SLEEP | UM_GC); if (mdb_vread(nvpair, size, addr) == -1) { mdb_warn("failed to read nvpair and data at %p", addr); return (DCMD_ERR); } /* lookup type decoding information for this nvpair */ type = NVP_TYPE(nvpair); nelem = NVP_NELEM(nvpair); for (i = 0; i < NELEM(nvpair_info); i++) { if (nvpair_info[i].type == type) { elem_size = nvpair_info[i].elem_size; type_name = nvpair_info[i].type_name; break; } } if (quiet) { mdb_printf("%s", NVP_NAME(nvpair)); } else { /* print out the first line of nvpair info */ mdb_printf("name='%s'", NVP_NAME(nvpair)); if (type_name != NULL) { mdb_printf(" type=%s", type_name); } else { /* * If the nvpair type is unknown we print the type * number */ mdb_printf(" type=0x%x", type); } mdb_printf(" items=%d\n", nelem); } /* if there is no data and the type is known then we're done */ if ((nelem == 0) && (type_name != NULL)) { if (quiet) mdb_printf("(unknown)\n"); return (DCMD_OK); } /* get pointers to the data to print out */ data = (char *)NVP_VALUE(nvpair); data_end = (char *)nvpair + NVP_SIZE(nvpair); /* * The value of the name-value pair for a single embedded * list is the nvlist_t structure for the embedded list. * So we print that address out (computed as an offset from * the nvpair address we received as addr). * * The value of the name-value pair for an array of embedded * lists is nelem pointers to nvlist_t structures followed * by the structures themselves. We display the list * of pointers as the pair's value. */ if (type == DATA_TYPE_NVLIST) { char *p = (char *)addr + (data - (char *)nvpair); if (recurse) { if (quiet) mdb_printf("\n"); mdb_inc_indent(NVPAIR_VALUE_INDENT); if (mdb_pwalk_dcmd("nvpair", "nvpair", argc, argv, (uintptr_t)p) != DCMD_OK) return (DCMD_ERR); mdb_dec_indent(NVPAIR_VALUE_INDENT); } else { if (!quiet) { mdb_inc_indent(NVPAIR_VALUE_INDENT); mdb_printf("value", p); } mdb_printf("=%p\n", p); if (!quiet) mdb_dec_indent(NVPAIR_VALUE_INDENT); } return (DCMD_OK); } else if (type == DATA_TYPE_NVLIST_ARRAY) { if (recurse) { for (i = 0; i < nelem; i++, data += sizeof (nvlist_t *)) { nvlist_t **nl = (nvlist_t **)(void *)data; if (quiet && i != 0) mdb_printf("%s", NVP_NAME(nvpair)); mdb_printf("[%d]\n", i); mdb_inc_indent(NVPAIR_VALUE_INDENT); if (mdb_pwalk_dcmd("nvpair", "nvpair", argc, argv, (uintptr_t)*nl) != DCMD_OK) return (DCMD_ERR); mdb_dec_indent(NVPAIR_VALUE_INDENT); } } else { if (!quiet) { mdb_inc_indent(NVPAIR_VALUE_INDENT); mdb_printf("value"); } mdb_printf("="); for (i = 0; i < nelem; i++, data += sizeof (nvlist_t *)) { nvlist_t **nl = (nvlist_t **)(void *)data; mdb_printf("%c%p", " "[i == 0], *nl); } mdb_printf("\n"); if (!quiet) mdb_dec_indent(NVPAIR_VALUE_INDENT); } return (DCMD_OK); } /* if it's a string array, skip the index pointers */ if (type == DATA_TYPE_STRING_ARRAY) data += (sizeof (int64_t) * nelem); /* if the type is unknown, treat the data as a byte array */ if (type_name == NULL) { elem_size = 1; nelem = data_end - data; } /* * if the type is of strings, make sure they are printable * otherwise print them out as byte arrays */ if (elem_size == 0) { int32_t count = 0; i = 0; while ((&data[i] < data_end) && (count < nelem)) { if (data[i] == '\0') count++; else if (!isprint(data[i])) break; i++; } if (count != nelem) { /* there is unprintable data, output as byte array */ elem_size = 1; nelem = data_end - data; } } if (!quiet) { mdb_inc_indent(NVPAIR_VALUE_INDENT); mdb_printf("value="); } else { mdb_printf("="); } nvpair_print_value(data, elem_size, nelem, type); if (!quiet) mdb_dec_indent(NVPAIR_VALUE_INDENT); return (DCMD_OK); }
/*ARGSUSED*/ int usba_device(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { int status; char pathname[MAXNAMELEN]; char dname[MODMAXNAMELEN + 1] = "<unatt>"; /* Driver name */ char drv_statep[MODMAXNAMELEN+ 10]; uint_t usb_flag = NULL; boolean_t no_driver_attached = FALSE; uintptr_t dip_addr; struct dev_info devinfo; if (!(flags & DCMD_ADDRSPEC)) { /* Global walk */ if (mdb_walk_dcmd("usba_device", "usba_device", argc, argv) == -1) { mdb_warn("failed to walk usba_device"); return (DCMD_ERR); } return (DCMD_OK); } if (mdb_getopts(argc, argv, 'p', MDB_OPT_SETBITS, USB_DUMP_ACTIVE_PIPES, &usb_flag, 'v', MDB_OPT_SETBITS, USB_DUMP_VERBOSE, &usb_flag, NULL) != argc) { return (DCMD_USAGE); } if (usb_flag && !(DCMD_HDRSPEC(flags))) { mdb_printf("\n"); } if (DCMD_HDRSPEC(flags)) { mdb_printf("%<u>%-15s %4s %-?s %-42s%</u>\n", "NAME", "INST", "DIP", "PATH "); } status = usba_device2dip(addr, &dip_addr); /* * -1 = error * 0 = no error, no match * 1 = no error, match */ if (status != 1) { if (status == -1) { mdb_warn("error looking for dip for usba_device %p", addr); } else { mdb_warn("failed to find dip for usba_device %p\n", addr); } mdb_warn("dip and statep unobtainable\n"); return (DCMD_ERR); } /* Figure out what driver (name) is attached to this node. */ (void) mdb_devinfo2driver(dip_addr, (char *)dname, sizeof (dname)); if (mdb_vread(&devinfo, sizeof (struct dev_info), dip_addr) == -1) { mdb_warn("failed to read devinfo"); return (DCMD_ERR); } if (!(DDI_CF2(&devinfo))) { no_driver_attached = TRUE; } (void) mdb_ddi_pathname(dip_addr, pathname, sizeof (pathname)); mdb_printf("%-15s %2d %-?p %s\n", dname, devinfo.devi_instance, dip_addr, pathname); if (usb_flag & USB_DUMP_VERBOSE) { int i; uintptr_t statep = NULL; char *string_descr; char **config_cloud, **conf_str_descr; usb_dev_descr_t usb_dev_descr; usba_device_t usba_device_struct; if (mdb_vread(&usba_device_struct, sizeof (usba_device_t), addr) == -1) { mdb_warn("failed to read usba_device struct"); return (DCMD_ERR); } mdb_printf(" usba_device: %-16p\n\n", (usba_device_t *)addr); if (mdb_vread(&usb_dev_descr, sizeof (usb_dev_descr), (uintptr_t)usba_device_struct.usb_dev_descr) == -1) { mdb_warn("failed to read usb_dev_descr_t struct"); return (DCMD_ERR); } mdb_printf("\n idVendor: 0x%04x idProduct: 0x%04x " "usb_addr: 0x%02x\n", usb_dev_descr.idVendor, usb_dev_descr.idProduct, usba_device_struct.usb_addr); /* Get the string descriptor string into local space. */ string_descr = (char *)mdb_alloc(USB_MAXSTRINGLEN, UM_GC); if (usba_device_struct.usb_mfg_str == NULL) { (void) strcpy(string_descr, "<No Manufacturer String>"); } else { if (mdb_readstr(string_descr, USB_MAXSTRINGLEN, (uintptr_t)usba_device_struct.usb_mfg_str) == -1) { mdb_warn("failed to read manufacturer " "string descriptor"); (void) strcpy(string_descr, "???"); } } mdb_printf("\n Manufacturer String:\t%s\n", string_descr); if (usba_device_struct.usb_product_str == NULL) { (void) strcpy(string_descr, "<No Product String>"); } else { if (mdb_readstr(string_descr, USB_MAXSTRINGLEN, (uintptr_t)usba_device_struct.usb_product_str) == -1) { mdb_warn("failed to read product string " "descriptor"); (void) strcpy(string_descr, "???"); } } mdb_printf(" Product String:\t\t%s\n", string_descr); if (usba_device_struct.usb_serialno_str == NULL) { (void) strcpy(string_descr, "<No SerialNumber String>"); } else { if (mdb_readstr(string_descr, USB_MAXSTRINGLEN, (uintptr_t)usba_device_struct.usb_serialno_str) == -1) { mdb_warn("failed to read serial number string " "descriptor"); (void) strcpy(string_descr, "???"); } } mdb_printf(" SerialNumber String:\t%s\n", string_descr); if (no_driver_attached) { mdb_printf("\n"); } else { mdb_printf(" state_p: "); /* * Given the dip, find the associated statep. The * convention to generate this soft state anchor is: * <driver_name>_statep */ (void) mdb_snprintf(drv_statep, sizeof (drv_statep), "%s_statep", dname); if (mdb_devinfo2statep(dip_addr, drv_statep, &statep) == -1) { mdb_warn("failed to find %s state struct for " "dip %p", drv_statep, dip_addr); return (DCMD_ERR); } mdb_printf("%-?p\n", statep); } config_cloud = (char **)mdb_alloc(sizeof (void *) * usba_device_struct.usb_n_cfgs, UM_GC); conf_str_descr = (char **)mdb_alloc(sizeof (void *) * usba_device_struct.usb_n_cfgs, UM_GC); if ((usba_device_struct.usb_cfg_array) && (usba_device_struct.usb_cfg_str_descr)) { if ((mdb_vread(config_cloud, sizeof (void *) * usba_device_struct.usb_n_cfgs, (uintptr_t)usba_device_struct.usb_cfg_array) == -1) || (mdb_vread(conf_str_descr, sizeof (void *) * usba_device_struct.usb_n_cfgs, (uintptr_t) usba_device_struct.usb_cfg_str_descr)) == -1) { mdb_warn("failed to read config cloud pointers"); } else { mdb_printf("\n Device Config Clouds:\n" " Index\tConfig\t\tConfiguration " "String\n" " -----\t------\t\t" "--------------------\n"); for (i = 0; i < usba_device_struct.usb_n_cfgs; i++) { if (mdb_readstr(string_descr, USB_MAXSTRINGLEN, (uintptr_t)conf_str_descr[i]) == -1) { (void) strcpy(string_descr, "<No Configuration " "String>"); } mdb_printf(" %4d\t0x%p\t%s\n", i, config_cloud[i], string_descr); } } } mdb_printf("\n Active configuration index: %d\n", usba_device_struct.usb_active_cfg_ndx); } if (usb_flag & USB_DUMP_ACTIVE_PIPES) { if (mdb_pwalk_dcmd("usb_pipe_handle", "usb_pipe_handle", 0, NULL, addr) == -1) { mdb_warn("failed to walk usb_pipe_handle"); return (DCMD_ERR); } } return (DCMD_OK); }
/* * Print out all project, task, and process rctls for a given process. * If a handle is specified, print only the rctl matching that handle * for the process. */ int rctl_list(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { proc_t proc; uintptr_t set; task_t task; kproject_t proj; zone_t zone; dict_data_t rdict; int i; rdict.dict_addr = NULL; if (!(flags & DCMD_ADDRSPEC)) return (DCMD_USAGE); if (argc == 0) rdict.hndl = 0; else if (argc == 1) { /* * User specified a handle. Go find the rctl_dict_entity_t * structure so we know what type of rctl to look for. */ const mdb_arg_t *argp = &argv[0]; if (argp->a_type == MDB_TYPE_IMMEDIATE) rdict.hndl = (rctl_hndl_t)argp->a_un.a_val; else rdict.hndl = (rctl_hndl_t)mdb_strtoull(argp->a_un.a_str); if (mdb_walk("rctl_dict_list", (mdb_walk_cb_t)hndl2dict, &rdict) == -1) { mdb_warn("failed to walk rctl_dict_list"); return (DCMD_ERR); } /* Couldn't find a rctl_dict_entry_t for this handle */ if (rdict.dict_addr == NULL) return (DCMD_ERR); } else return (DCMD_USAGE); if (mdb_vread(&proc, sizeof (proc_t), addr) == -1) { mdb_warn("failed to read proc at %p", addr); return (DCMD_ERR); } if (mdb_vread(&zone, sizeof (zone_t), (uintptr_t)proc.p_zone) == -1) { mdb_warn("failed to read zone at %p", proc.p_zone); return (DCMD_ERR); } if (mdb_vread(&task, sizeof (task_t), (uintptr_t)proc.p_task) == -1) { mdb_warn("failed to read task at %p", proc.p_task); return (DCMD_ERR); } if (mdb_vread(&proj, sizeof (kproject_t), (uintptr_t)task.tk_proj) == -1) { mdb_warn("failed to read proj at %p", task.tk_proj); return (DCMD_ERR); } for (i = 0; i <= RC_MAX_ENTITY; i++) { /* * If user didn't specify a handle, print rctls for all * types. Otherwise, we can walk the rctl_set for only the * entity specified by the handle. */ if (rdict.hndl != 0 && rdict.type != i) continue; switch (i) { case (RCENTITY_PROCESS): set = (uintptr_t)proc.p_rctls; break; case (RCENTITY_TASK): set = (uintptr_t)task.tk_rctls; break; case (RCENTITY_PROJECT): set = (uintptr_t)proj.kpj_rctls; break; case (RCENTITY_ZONE): set = (uintptr_t)zone.zone_rctls; break; default: mdb_warn("Unknown rctl type %d", i); return (DCMD_ERR); } if (mdb_pwalk_dcmd("rctl_set", "rctl", argc, argv, set) == -1) { mdb_warn("failed to walk rctls in set %p", set); return (DCMD_ERR); } } return (DCMD_OK); }