1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * Copyright 2013 Nexenta Systems, Inc. All rights reserved. 28 */ 29 30 #include <limits.h> 31 #include <sys/mdb_modapi.h> 32 #include <sys/sysinfo.h> 33 #include <sys/sunmdi.h> 34 #include <sys/scsi/scsi.h> 35 #include "mr_sas.h" 36 37 int 38 construct_path(uintptr_t addr, char *result) 39 { 40 struct dev_info d; 41 char devi_node[PATH_MAX]; 42 char devi_addr[PATH_MAX]; 43 44 if (mdb_vread(&d, sizeof (d), addr) == -1) { 45 mdb_warn("couldn't read dev_info"); 46 return (DCMD_ERR); 47 } 48 49 if (d.devi_parent) { 50 construct_path((uintptr_t)d.devi_parent, result); 51 mdb_readstr(devi_node, sizeof (devi_node), 52 (uintptr_t)d.devi_node_name); 53 mdb_readstr(devi_addr, sizeof (devi_addr), 54 (uintptr_t)d.devi_addr); 55 mdb_snprintf(result+strlen(result), 56 PATH_MAX-strlen(result), 57 "/%s%s%s", devi_node, (*devi_addr ? "@" : ""), 58 devi_addr); 59 } 60 return (DCMD_OK); 61 } 62 63 void 64 display_targets(struct mrsas_instance *m, int verbose) 65 { 66 int tgt; 67 struct mrsas_ld mr_ldp[MRDRV_MAX_LD]; 68 struct mrsas_tbolt_pd mr_pdp[MRSAS_TBOLT_PD_TGT_MAX]; 69 char device_path[PATH_MAX]; 70 71 if (verbose) { 72 *device_path = 0; 73 if (construct_path((uintptr_t)m->dip, device_path) != DCMD_OK) { 74 strcpy(device_path, "couldn't determine device path"); 75 } 76 } 77 78 mdb_printf("\n"); 79 if (verbose) 80 mdb_printf("%s\n", device_path); 81 mdb_printf("Physical/Logical Target\n"); 82 mdb_printf("-----------------------\n"); 83 84 if (mdb_vread(&mr_ldp, sizeof (mr_ldp), (uintptr_t)m->mr_ld_list) 85 == -1 || 86 mdb_vread(&mr_pdp, sizeof (mr_pdp), (uintptr_t)m->mr_tbolt_pd_list) 87 == -1) { 88 mdb_warn("can't read list of disks"); 89 return; 90 } 91 92 for (tgt = 0; tgt < MRDRV_MAX_LD; tgt++) { 93 if (mr_ldp[tgt].dip != NULL && 94 mr_ldp[tgt].lun_type == MRSAS_LD_LUN) { 95 mdb_printf("Logical sd %d\n", tgt); 96 } 97 } 98 for (tgt = 0; tgt < MRSAS_TBOLT_PD_TGT_MAX; tgt++) { 99 if (mr_pdp[tgt].dip != NULL && 100 mr_pdp[tgt].lun_type == MRSAS_TBOLT_PD_LUN) { 101 mdb_printf("Physical sd %d\n", tgt); 102 } 103 } 104 mdb_printf("\n"); 105 } 106 107 void 108 display_deviceinfo(struct mrsas_instance *m) 109 { 110 uint16_t vid, did, svid, sid; 111 112 vid = m->vendor_id; 113 did = m->device_id; 114 svid = m->subsysvid; 115 sid = m->subsysid; 116 117 mdb_printf("\n"); 118 mdb_printf("vendor_id device_id subsysvid subsysid"); 119 mdb_printf("\n"); 120 mdb_printf("--------------------------------------"); 121 mdb_printf("\n"); 122 mdb_printf(" 0x%x 0x%x 0x%x 0x%x", 123 vid, did, svid, sid); 124 mdb_printf("\n"); 125 } 126 127 static int 128 mr_sas_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 129 { 130 struct mrsas_instance m; 131 132 int instance; 133 uint16_t ncmds; 134 uint_t verbose = FALSE; 135 uint_t device_info = FALSE; 136 uint_t target_info = FALSE; 137 int rv = DCMD_OK; 138 void *mrsas_state; 139 140 if (!(flags & DCMD_ADDRSPEC)) { 141 mrsas_state = NULL; 142 if (mdb_readvar(&mrsas_state, "mrsas_state") == -1) { 143 mdb_warn("can't read mrsas_state"); 144 return (DCMD_ERR); 145 } 146 if (mdb_pwalk_dcmd("genunix`softstate", "mr_sas`mr_sas", 147 argc, argv, (uintptr_t)mrsas_state) == -1) { 148 mdb_warn("mdb_pwalk_dcmd failed"); 149 return (DCMD_ERR); 150 } 151 return (DCMD_OK); 152 } 153 154 if (mdb_getopts(argc, argv, 155 'd', MDB_OPT_SETBITS, TRUE, &device_info, 156 't', MDB_OPT_SETBITS, TRUE, &target_info, 157 'v', MDB_OPT_SETBITS, TRUE, &verbose, 158 NULL) != argc) 159 return (DCMD_USAGE); 160 161 if (mdb_vread(&m, sizeof (m), addr) == -1) { 162 mdb_warn("couldn't read mrsas_instance struct at 0x%p", addr); 163 return (DCMD_ERR); 164 } 165 instance = m.instance; 166 167 /* cmd slot info */ 168 ncmds = m.max_fw_cmds; 169 170 /* processing completed */ 171 if (((flags & DCMD_ADDRSPEC) && !(flags & DCMD_LOOP)) || 172 (flags & DCMD_LOOPFIRST)) { 173 if ((flags & DCMD_LOOP) && !(flags & DCMD_LOOPFIRST)) 174 mdb_printf("\n"); 175 mdb_printf(" mrsas_t inst max_fw_cmds intr_type"); 176 mdb_printf("\n"); 177 mdb_printf("==========================================="); 178 mdb_printf("\n"); 179 } 180 181 mdb_printf("%16p %4d %4d ", addr, instance, ncmds); 182 switch (m.intr_type) { 183 case DDI_INTR_TYPE_MSIX: 184 mdb_printf("MSI-X"); 185 break; 186 case DDI_INTR_TYPE_MSI: 187 mdb_printf("MSI"); 188 break; 189 case DDI_INTR_TYPE_FIXED: 190 mdb_printf("FIXED"); 191 break; 192 default: 193 mdb_printf("INVALD"); 194 } 195 mdb_printf("\n"); 196 197 if (target_info) 198 display_targets(&m, verbose); 199 200 if (device_info) 201 display_deviceinfo(&m); 202 203 return (rv); 204 } 205 206 void 207 mr_sas_help(void) 208 { 209 mdb_printf("Prints summary information about each mr_sas instance, " 210 "Without the address of a \"struct mrsas_instance\", prints every " 211 "instance.\n\n" 212 "Switches:\n" 213 " -t includes information about targets\n" 214 " -d includes information about the hardware\n" 215 " -v displays extra information for some options\n"); 216 } 217 218 static const mdb_dcmd_t dcmds[] = { 219 { "mr_sas", "?[-tdv]", "print mr_sas information", mr_sas_dcmd, 220 mr_sas_help }, 221 { NULL } 222 }; 223 224 static const mdb_modinfo_t modinfo = { 225 MDB_API_VERSION, dcmds, NULL 226 }; 227 228 const mdb_modinfo_t * 229 _mdb_init(void) 230 { 231 return (&modinfo); 232 } 233