1*fcf3ce44SJohn Forte /* 2*fcf3ce44SJohn Forte * CDDL HEADER START 3*fcf3ce44SJohn Forte * 4*fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5*fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6*fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7*fcf3ce44SJohn Forte * 8*fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10*fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11*fcf3ce44SJohn Forte * and limitations under the License. 12*fcf3ce44SJohn Forte * 13*fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14*fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16*fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17*fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18*fcf3ce44SJohn Forte * 19*fcf3ce44SJohn Forte * CDDL HEADER END 20*fcf3ce44SJohn Forte */ 21*fcf3ce44SJohn Forte /* 22*fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*fcf3ce44SJohn Forte * Use is subject to license terms. 24*fcf3ce44SJohn Forte * 25*fcf3ce44SJohn Forte * FCP mdb module 26*fcf3ce44SJohn Forte */ 27*fcf3ce44SJohn Forte 28*fcf3ce44SJohn Forte 29*fcf3ce44SJohn Forte #include <sys/mdb_modapi.h> 30*fcf3ce44SJohn Forte #include <sys/mutex.h> 31*fcf3ce44SJohn Forte #include <sys/modctl.h> 32*fcf3ce44SJohn Forte #include <sys/scsi/scsi.h> 33*fcf3ce44SJohn Forte #include <sys/sunndi.h> 34*fcf3ce44SJohn Forte #include <sys/fibre-channel/fc.h> 35*fcf3ce44SJohn Forte #include <sys/fibre-channel/ulp/fcpvar.h> 36*fcf3ce44SJohn Forte 37*fcf3ce44SJohn Forte static struct fcp_port port; 38*fcf3ce44SJohn Forte static struct fcp_tgt tgt; 39*fcf3ce44SJohn Forte static struct fcp_lun lun; 40*fcf3ce44SJohn Forte static uint32_t tgt_hash_index; 41*fcf3ce44SJohn Forte 42*fcf3ce44SJohn Forte 43*fcf3ce44SJohn Forte /* 44*fcf3ce44SJohn Forte * Leadville fcp walker/dcmd code 45*fcf3ce44SJohn Forte */ 46*fcf3ce44SJohn Forte 47*fcf3ce44SJohn Forte static int 48*fcf3ce44SJohn Forte fcp_walk_i(mdb_walk_state_t *wsp) 49*fcf3ce44SJohn Forte { 50*fcf3ce44SJohn Forte if (wsp->walk_addr == NULL && 51*fcf3ce44SJohn Forte mdb_readvar(&wsp->walk_addr, "fcp_port_head") == -1) { 52*fcf3ce44SJohn Forte mdb_warn("failed to read 'fcp_port_head'"); 53*fcf3ce44SJohn Forte return (WALK_ERR); 54*fcf3ce44SJohn Forte } 55*fcf3ce44SJohn Forte 56*fcf3ce44SJohn Forte wsp->walk_data = mdb_alloc(sizeof (struct fcp_port), UM_SLEEP); 57*fcf3ce44SJohn Forte return (WALK_NEXT); 58*fcf3ce44SJohn Forte } 59*fcf3ce44SJohn Forte 60*fcf3ce44SJohn Forte static int 61*fcf3ce44SJohn Forte fcp_walk_s(mdb_walk_state_t *wsp) 62*fcf3ce44SJohn Forte { 63*fcf3ce44SJohn Forte int status; 64*fcf3ce44SJohn Forte 65*fcf3ce44SJohn Forte if (wsp->walk_addr == NULL) 66*fcf3ce44SJohn Forte return (WALK_DONE); 67*fcf3ce44SJohn Forte 68*fcf3ce44SJohn Forte if (mdb_vread(wsp->walk_data, sizeof (struct fcp_port), 69*fcf3ce44SJohn Forte wsp->walk_addr) == -1) { 70*fcf3ce44SJohn Forte mdb_warn("failed to read fcp_port at %p", wsp->walk_addr); 71*fcf3ce44SJohn Forte return (WALK_DONE); 72*fcf3ce44SJohn Forte } 73*fcf3ce44SJohn Forte 74*fcf3ce44SJohn Forte status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 75*fcf3ce44SJohn Forte wsp->walk_cbdata); 76*fcf3ce44SJohn Forte 77*fcf3ce44SJohn Forte wsp->walk_addr = 78*fcf3ce44SJohn Forte (uintptr_t)(((struct fcp_port *)wsp->walk_data)->port_next); 79*fcf3ce44SJohn Forte 80*fcf3ce44SJohn Forte return (status); 81*fcf3ce44SJohn Forte } 82*fcf3ce44SJohn Forte 83*fcf3ce44SJohn Forte /* 84*fcf3ce44SJohn Forte * The walker's fini function is invoked at the end of each walk. 85*fcf3ce44SJohn Forte */ 86*fcf3ce44SJohn Forte static void 87*fcf3ce44SJohn Forte fcp_walk_f(mdb_walk_state_t *wsp) 88*fcf3ce44SJohn Forte { 89*fcf3ce44SJohn Forte mdb_free(wsp->walk_data, sizeof (struct fcp_port)); 90*fcf3ce44SJohn Forte } 91*fcf3ce44SJohn Forte 92*fcf3ce44SJohn Forte 93*fcf3ce44SJohn Forte static int 94*fcf3ce44SJohn Forte fcp(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 95*fcf3ce44SJohn Forte { 96*fcf3ce44SJohn Forte struct fcp_port pinfo; 97*fcf3ce44SJohn Forte 98*fcf3ce44SJohn Forte if (argc != 0) { 99*fcf3ce44SJohn Forte return (DCMD_USAGE); 100*fcf3ce44SJohn Forte } 101*fcf3ce44SJohn Forte 102*fcf3ce44SJohn Forte if (!(flags & DCMD_ADDRSPEC)) { 103*fcf3ce44SJohn Forte if (mdb_walk_dcmd("fcp", "fcp", 104*fcf3ce44SJohn Forte argc, argv) == -1) { 105*fcf3ce44SJohn Forte mdb_warn("failed to walk 'fcp_port_head'"); 106*fcf3ce44SJohn Forte return (DCMD_ERR); 107*fcf3ce44SJohn Forte } 108*fcf3ce44SJohn Forte return (DCMD_OK); 109*fcf3ce44SJohn Forte } 110*fcf3ce44SJohn Forte 111*fcf3ce44SJohn Forte mdb_printf("FCP structure at %p\n", addr); 112*fcf3ce44SJohn Forte 113*fcf3ce44SJohn Forte /* 114*fcf3ce44SJohn Forte * For each port, we just need to read the fc_fca_port_t struct, read 115*fcf3ce44SJohn Forte * the port_handle 116*fcf3ce44SJohn Forte */ 117*fcf3ce44SJohn Forte if (mdb_vread(&pinfo, sizeof (struct fcp_port), addr) != 118*fcf3ce44SJohn Forte sizeof (struct fcp_port)) { 119*fcf3ce44SJohn Forte mdb_warn("failed to read fcp_port at %p", addr); 120*fcf3ce44SJohn Forte return (DCMD_OK); 121*fcf3ce44SJohn Forte } 122*fcf3ce44SJohn Forte 123*fcf3ce44SJohn Forte mdb_printf(" mutex : 0x%-08x\n", pinfo.port_mutex); 124*fcf3ce44SJohn Forte mdb_printf(" ipkt_list : 0x%p\n", pinfo.port_ipkt_list); 125*fcf3ce44SJohn Forte mdb_printf(" state : 0x%-08x\n", pinfo.port_state); 126*fcf3ce44SJohn Forte mdb_printf(" phys_state : 0x%-08x\n", pinfo.port_phys_state); 127*fcf3ce44SJohn Forte mdb_printf(" top : %u\n", pinfo.port_topology); 128*fcf3ce44SJohn Forte mdb_printf(" sid : 0x%-06x\n", pinfo.port_id); 129*fcf3ce44SJohn Forte mdb_printf(" reset_list : 0x%p\n", pinfo.port_reset_list); 130*fcf3ce44SJohn Forte mdb_printf(" link_cnt : %u\n", pinfo.port_link_cnt); 131*fcf3ce44SJohn Forte mdb_printf(" deadline : %d\n", pinfo.port_deadline); 132*fcf3ce44SJohn Forte mdb_printf(" port wwn : " 133*fcf3ce44SJohn Forte "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", 134*fcf3ce44SJohn Forte pinfo.port_pwwn.raw_wwn[0], pinfo.port_pwwn.raw_wwn[1], 135*fcf3ce44SJohn Forte pinfo.port_pwwn.raw_wwn[2], pinfo.port_pwwn.raw_wwn[3], 136*fcf3ce44SJohn Forte pinfo.port_pwwn.raw_wwn[4], pinfo.port_pwwn.raw_wwn[5], 137*fcf3ce44SJohn Forte pinfo.port_pwwn.raw_wwn[6], pinfo.port_pwwn.raw_wwn[7]); 138*fcf3ce44SJohn Forte mdb_printf(" node wwn : " 139*fcf3ce44SJohn Forte "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", 140*fcf3ce44SJohn Forte pinfo.port_nwwn.raw_wwn[0], pinfo.port_nwwn.raw_wwn[1], 141*fcf3ce44SJohn Forte pinfo.port_nwwn.raw_wwn[2], pinfo.port_nwwn.raw_wwn[3], 142*fcf3ce44SJohn Forte pinfo.port_nwwn.raw_wwn[4], pinfo.port_nwwn.raw_wwn[5], 143*fcf3ce44SJohn Forte pinfo.port_nwwn.raw_wwn[6], pinfo.port_nwwn.raw_wwn[7]); 144*fcf3ce44SJohn Forte mdb_printf(" handle : 0x%p\n", pinfo.port_fp_handle); 145*fcf3ce44SJohn Forte mdb_printf(" cmd_mutex : 0x%-08x\n", pinfo.port_pkt_mutex); 146*fcf3ce44SJohn Forte mdb_printf(" ncmds : %u\n", pinfo.port_npkts); 147*fcf3ce44SJohn Forte mdb_printf(" pkt_head : 0x%p\n", pinfo.port_pkt_head); 148*fcf3ce44SJohn Forte mdb_printf(" pkt_tail : 0x%p\n", pinfo.port_pkt_tail); 149*fcf3ce44SJohn Forte mdb_printf(" ipkt_cnt : %d\n", pinfo.port_ipkt_cnt); 150*fcf3ce44SJohn Forte mdb_printf(" instance : %u\n", pinfo.port_instance); 151*fcf3ce44SJohn Forte mdb_printf(" max_exch : %u\n", pinfo.port_max_exch); 152*fcf3ce44SJohn Forte mdb_printf(" cmds_aborted : 0x%-08x\n", 153*fcf3ce44SJohn Forte pinfo.port_reset_action); 154*fcf3ce44SJohn Forte mdb_printf(" cmds_dma_flags : 0x%-08x\n", 155*fcf3ce44SJohn Forte pinfo.port_cmds_dma_flags); 156*fcf3ce44SJohn Forte mdb_printf(" fcp_dma : 0x%-08x\n", pinfo.port_fcp_dma); 157*fcf3ce44SJohn Forte mdb_printf(" priv_pkt_len : %u\n", pinfo.port_priv_pkt_len); 158*fcf3ce44SJohn Forte mdb_printf(" data_dma_attr : 0x%-08x\n", 159*fcf3ce44SJohn Forte pinfo.port_data_dma_attr); 160*fcf3ce44SJohn Forte mdb_printf(" cmd_dma_attr : 0x%-08x\n", 161*fcf3ce44SJohn Forte pinfo.port_cmd_dma_attr); 162*fcf3ce44SJohn Forte mdb_printf(" resp_dma_attr : 0x%-08x\n", 163*fcf3ce44SJohn Forte pinfo.port_resp_dma_attr); 164*fcf3ce44SJohn Forte mdb_printf(" dma_acc_attr : 0x%-08x\n", 165*fcf3ce44SJohn Forte pinfo.port_dma_acc_attr); 166*fcf3ce44SJohn Forte mdb_printf(" tran : 0x%p\n", pinfo.port_tran); 167*fcf3ce44SJohn Forte mdb_printf(" dip : 0x%p\n", pinfo.port_dip); 168*fcf3ce44SJohn Forte mdb_printf(" reset_notify_listf: 0x%p\n", 169*fcf3ce44SJohn Forte pinfo.port_reset_notify_listf); 170*fcf3ce44SJohn Forte mdb_printf(" event_defs : 0x%p\n", pinfo.port_ndi_event_defs); 171*fcf3ce44SJohn Forte mdb_printf(" event_hdl : 0x%p\n", pinfo.port_ndi_event_hdl); 172*fcf3ce44SJohn Forte mdb_printf(" events : 0x%p\n", pinfo.port_ndi_events); 173*fcf3ce44SJohn Forte mdb_printf(" tgt_hash_table : 0x%p\n", pinfo.port_tgt_hash_table); 174*fcf3ce44SJohn Forte mdb_printf(" mpxio : %d\n", pinfo.port_mpxio); 175*fcf3ce44SJohn Forte 176*fcf3ce44SJohn Forte mdb_printf("\n"); 177*fcf3ce44SJohn Forte 178*fcf3ce44SJohn Forte return (DCMD_OK); 179*fcf3ce44SJohn Forte } 180*fcf3ce44SJohn Forte 181*fcf3ce44SJohn Forte 182*fcf3ce44SJohn Forte /* 183*fcf3ce44SJohn Forte * Leadville cmds walker/dcmd code 184*fcf3ce44SJohn Forte */ 185*fcf3ce44SJohn Forte 186*fcf3ce44SJohn Forte static int 187*fcf3ce44SJohn Forte cmds_walk_i(mdb_walk_state_t *wsp) 188*fcf3ce44SJohn Forte { 189*fcf3ce44SJohn Forte if (wsp->walk_addr == NULL) { 190*fcf3ce44SJohn Forte mdb_warn("Can not perform global walk"); 191*fcf3ce44SJohn Forte return (WALK_ERR); 192*fcf3ce44SJohn Forte } 193*fcf3ce44SJohn Forte 194*fcf3ce44SJohn Forte /* 195*fcf3ce44SJohn Forte * Input should be a fcp_lun, so read it to get the fcp_pkt 196*fcf3ce44SJohn Forte * lists's head 197*fcf3ce44SJohn Forte */ 198*fcf3ce44SJohn Forte 199*fcf3ce44SJohn Forte if (mdb_vread(&lun, sizeof (struct fcp_lun), wsp->walk_addr) != 200*fcf3ce44SJohn Forte sizeof (struct fcp_lun)) { 201*fcf3ce44SJohn Forte mdb_warn("Unable to read in the fcp_lun structure address\n"); 202*fcf3ce44SJohn Forte return (WALK_ERR); 203*fcf3ce44SJohn Forte } 204*fcf3ce44SJohn Forte 205*fcf3ce44SJohn Forte wsp->walk_addr = (uintptr_t)(lun.lun_pkt_head); 206*fcf3ce44SJohn Forte wsp->walk_data = mdb_alloc(sizeof (struct fcp_pkt), UM_SLEEP); 207*fcf3ce44SJohn Forte 208*fcf3ce44SJohn Forte return (WALK_NEXT); 209*fcf3ce44SJohn Forte } 210*fcf3ce44SJohn Forte 211*fcf3ce44SJohn Forte static int 212*fcf3ce44SJohn Forte cmds_walk_s(mdb_walk_state_t *wsp) 213*fcf3ce44SJohn Forte { 214*fcf3ce44SJohn Forte int status; 215*fcf3ce44SJohn Forte 216*fcf3ce44SJohn Forte if (wsp->walk_addr == NULL) 217*fcf3ce44SJohn Forte return (WALK_DONE); 218*fcf3ce44SJohn Forte 219*fcf3ce44SJohn Forte if (mdb_vread(wsp->walk_data, sizeof (struct fcp_pkt), 220*fcf3ce44SJohn Forte wsp->walk_addr) == -1) { 221*fcf3ce44SJohn Forte mdb_warn("failed to read fcp_pkt at %p", wsp->walk_addr); 222*fcf3ce44SJohn Forte return (WALK_DONE); 223*fcf3ce44SJohn Forte } 224*fcf3ce44SJohn Forte 225*fcf3ce44SJohn Forte status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 226*fcf3ce44SJohn Forte wsp->walk_cbdata); 227*fcf3ce44SJohn Forte 228*fcf3ce44SJohn Forte wsp->walk_addr = 229*fcf3ce44SJohn Forte (uintptr_t)(((struct fcp_pkt *)wsp->walk_data)->cmd_forw); 230*fcf3ce44SJohn Forte 231*fcf3ce44SJohn Forte return (status); 232*fcf3ce44SJohn Forte } 233*fcf3ce44SJohn Forte 234*fcf3ce44SJohn Forte /* 235*fcf3ce44SJohn Forte * The walker's fini function is invoked at the end of each walk. 236*fcf3ce44SJohn Forte */ 237*fcf3ce44SJohn Forte static void 238*fcf3ce44SJohn Forte cmds_walk_f(mdb_walk_state_t *wsp) 239*fcf3ce44SJohn Forte { 240*fcf3ce44SJohn Forte mdb_free(wsp->walk_data, sizeof (struct fcp_pkt)); 241*fcf3ce44SJohn Forte } 242*fcf3ce44SJohn Forte 243*fcf3ce44SJohn Forte 244*fcf3ce44SJohn Forte /* 245*fcf3ce44SJohn Forte * Leadville luns walker/dcmd code 246*fcf3ce44SJohn Forte */ 247*fcf3ce44SJohn Forte 248*fcf3ce44SJohn Forte static int 249*fcf3ce44SJohn Forte luns_walk_i(mdb_walk_state_t *wsp) 250*fcf3ce44SJohn Forte { 251*fcf3ce44SJohn Forte if (wsp->walk_addr == NULL) { 252*fcf3ce44SJohn Forte mdb_warn("Can not perform global walk"); 253*fcf3ce44SJohn Forte return (WALK_ERR); 254*fcf3ce44SJohn Forte } 255*fcf3ce44SJohn Forte 256*fcf3ce44SJohn Forte /* 257*fcf3ce44SJohn Forte * Input should be a fcp_tgt, so read it to get the fcp_lun 258*fcf3ce44SJohn Forte * lists's head 259*fcf3ce44SJohn Forte */ 260*fcf3ce44SJohn Forte 261*fcf3ce44SJohn Forte if (mdb_vread(&tgt, sizeof (struct fcp_tgt), wsp->walk_addr) != 262*fcf3ce44SJohn Forte sizeof (struct fcp_tgt)) { 263*fcf3ce44SJohn Forte mdb_warn("Unable to read in the fcp_tgt structure address\n"); 264*fcf3ce44SJohn Forte return (WALK_ERR); 265*fcf3ce44SJohn Forte } 266*fcf3ce44SJohn Forte 267*fcf3ce44SJohn Forte wsp->walk_addr = (uintptr_t)(tgt.tgt_lun); 268*fcf3ce44SJohn Forte wsp->walk_data = mdb_alloc(sizeof (struct fcp_lun), UM_SLEEP); 269*fcf3ce44SJohn Forte 270*fcf3ce44SJohn Forte return (WALK_NEXT); 271*fcf3ce44SJohn Forte } 272*fcf3ce44SJohn Forte 273*fcf3ce44SJohn Forte static int 274*fcf3ce44SJohn Forte luns_walk_s(mdb_walk_state_t *wsp) 275*fcf3ce44SJohn Forte { 276*fcf3ce44SJohn Forte int status; 277*fcf3ce44SJohn Forte 278*fcf3ce44SJohn Forte if (wsp->walk_addr == NULL) 279*fcf3ce44SJohn Forte return (WALK_DONE); 280*fcf3ce44SJohn Forte 281*fcf3ce44SJohn Forte if (mdb_vread(wsp->walk_data, sizeof (struct fcp_lun), 282*fcf3ce44SJohn Forte wsp->walk_addr) == -1) { 283*fcf3ce44SJohn Forte mdb_warn("failed to read fcp_pkt at %p", wsp->walk_addr); 284*fcf3ce44SJohn Forte return (WALK_DONE); 285*fcf3ce44SJohn Forte } 286*fcf3ce44SJohn Forte 287*fcf3ce44SJohn Forte status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 288*fcf3ce44SJohn Forte wsp->walk_cbdata); 289*fcf3ce44SJohn Forte 290*fcf3ce44SJohn Forte wsp->walk_addr = 291*fcf3ce44SJohn Forte (uintptr_t)(((struct fcp_lun *)wsp->walk_data)->lun_next); 292*fcf3ce44SJohn Forte 293*fcf3ce44SJohn Forte return (status); 294*fcf3ce44SJohn Forte } 295*fcf3ce44SJohn Forte 296*fcf3ce44SJohn Forte /* 297*fcf3ce44SJohn Forte * The walker's fini function is invoked at the end of each walk. 298*fcf3ce44SJohn Forte */ 299*fcf3ce44SJohn Forte static void 300*fcf3ce44SJohn Forte luns_walk_f(mdb_walk_state_t *wsp) 301*fcf3ce44SJohn Forte { 302*fcf3ce44SJohn Forte mdb_free(wsp->walk_data, sizeof (struct fcp_lun)); 303*fcf3ce44SJohn Forte } 304*fcf3ce44SJohn Forte 305*fcf3ce44SJohn Forte 306*fcf3ce44SJohn Forte /* 307*fcf3ce44SJohn Forte * Leadville targets walker/dcmd code 308*fcf3ce44SJohn Forte */ 309*fcf3ce44SJohn Forte 310*fcf3ce44SJohn Forte static int 311*fcf3ce44SJohn Forte targets_walk_i(mdb_walk_state_t *wsp) 312*fcf3ce44SJohn Forte { 313*fcf3ce44SJohn Forte if (wsp->walk_addr == NULL) { 314*fcf3ce44SJohn Forte mdb_warn("Can not perform global walk\n"); 315*fcf3ce44SJohn Forte return (WALK_ERR); 316*fcf3ce44SJohn Forte } 317*fcf3ce44SJohn Forte 318*fcf3ce44SJohn Forte /* 319*fcf3ce44SJohn Forte * Input should be a fcp_port, so read it to get the port_tgt 320*fcf3ce44SJohn Forte * table's head 321*fcf3ce44SJohn Forte */ 322*fcf3ce44SJohn Forte 323*fcf3ce44SJohn Forte if (mdb_vread(&port, sizeof (struct fcp_port), wsp->walk_addr) != 324*fcf3ce44SJohn Forte sizeof (struct fcp_port)) { 325*fcf3ce44SJohn Forte mdb_warn("Unable to read in the port structure address\n"); 326*fcf3ce44SJohn Forte return (WALK_ERR); 327*fcf3ce44SJohn Forte } 328*fcf3ce44SJohn Forte 329*fcf3ce44SJohn Forte tgt_hash_index = 0; 330*fcf3ce44SJohn Forte 331*fcf3ce44SJohn Forte while ((port.port_tgt_hash_table[tgt_hash_index] == NULL) && 332*fcf3ce44SJohn Forte (tgt_hash_index < FCP_NUM_HASH)) { 333*fcf3ce44SJohn Forte tgt_hash_index++; 334*fcf3ce44SJohn Forte } 335*fcf3ce44SJohn Forte 336*fcf3ce44SJohn Forte wsp->walk_addr = (uintptr_t)(port.port_tgt_hash_table[tgt_hash_index]); 337*fcf3ce44SJohn Forte 338*fcf3ce44SJohn Forte wsp->walk_data = mdb_alloc(sizeof (struct fcp_tgt), UM_SLEEP); 339*fcf3ce44SJohn Forte 340*fcf3ce44SJohn Forte return (WALK_NEXT); 341*fcf3ce44SJohn Forte } 342*fcf3ce44SJohn Forte 343*fcf3ce44SJohn Forte static int 344*fcf3ce44SJohn Forte targets_walk_s(mdb_walk_state_t *wsp) 345*fcf3ce44SJohn Forte { 346*fcf3ce44SJohn Forte int status; 347*fcf3ce44SJohn Forte 348*fcf3ce44SJohn Forte if ((wsp->walk_addr == NULL) && 349*fcf3ce44SJohn Forte (tgt_hash_index >= (FCP_NUM_HASH - 1))) { 350*fcf3ce44SJohn Forte return (WALK_DONE); 351*fcf3ce44SJohn Forte } 352*fcf3ce44SJohn Forte 353*fcf3ce44SJohn Forte if (mdb_vread(wsp->walk_data, sizeof (struct fcp_tgt), 354*fcf3ce44SJohn Forte wsp->walk_addr) == -1) { 355*fcf3ce44SJohn Forte mdb_warn("failed to read fcp_tgt at %p", wsp->walk_addr); 356*fcf3ce44SJohn Forte return (WALK_DONE); 357*fcf3ce44SJohn Forte } 358*fcf3ce44SJohn Forte 359*fcf3ce44SJohn Forte status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 360*fcf3ce44SJohn Forte wsp->walk_cbdata); 361*fcf3ce44SJohn Forte 362*fcf3ce44SJohn Forte wsp->walk_addr = 363*fcf3ce44SJohn Forte (uintptr_t)(((struct fcp_tgt *)wsp->walk_data)->tgt_next); 364*fcf3ce44SJohn Forte 365*fcf3ce44SJohn Forte if (wsp->walk_addr == NULL) { 366*fcf3ce44SJohn Forte /* 367*fcf3ce44SJohn Forte * locate the next hash list 368*fcf3ce44SJohn Forte */ 369*fcf3ce44SJohn Forte 370*fcf3ce44SJohn Forte tgt_hash_index++; 371*fcf3ce44SJohn Forte 372*fcf3ce44SJohn Forte while ((port.port_tgt_hash_table[tgt_hash_index] == NULL) && 373*fcf3ce44SJohn Forte (tgt_hash_index < FCP_NUM_HASH)) { 374*fcf3ce44SJohn Forte tgt_hash_index++; 375*fcf3ce44SJohn Forte } 376*fcf3ce44SJohn Forte 377*fcf3ce44SJohn Forte if (tgt_hash_index == FCP_NUM_HASH) { 378*fcf3ce44SJohn Forte /* You're done */ 379*fcf3ce44SJohn Forte return (status); 380*fcf3ce44SJohn Forte } 381*fcf3ce44SJohn Forte 382*fcf3ce44SJohn Forte wsp->walk_addr = 383*fcf3ce44SJohn Forte (uintptr_t)(port.port_tgt_hash_table[tgt_hash_index]); 384*fcf3ce44SJohn Forte } 385*fcf3ce44SJohn Forte 386*fcf3ce44SJohn Forte return (status); 387*fcf3ce44SJohn Forte } 388*fcf3ce44SJohn Forte 389*fcf3ce44SJohn Forte /* 390*fcf3ce44SJohn Forte * The walker's fini function is invoked at the end of each walk. 391*fcf3ce44SJohn Forte */ 392*fcf3ce44SJohn Forte static void 393*fcf3ce44SJohn Forte targets_walk_f(mdb_walk_state_t *wsp) 394*fcf3ce44SJohn Forte { 395*fcf3ce44SJohn Forte mdb_free(wsp->walk_data, sizeof (struct fcp_tgt)); 396*fcf3ce44SJohn Forte } 397*fcf3ce44SJohn Forte 398*fcf3ce44SJohn Forte 399*fcf3ce44SJohn Forte /* 400*fcf3ce44SJohn Forte * Leadville fcp_ipkt walker/dcmd code 401*fcf3ce44SJohn Forte */ 402*fcf3ce44SJohn Forte 403*fcf3ce44SJohn Forte static int 404*fcf3ce44SJohn Forte ipkt_walk_i(mdb_walk_state_t *wsp) 405*fcf3ce44SJohn Forte { 406*fcf3ce44SJohn Forte if (wsp->walk_addr == NULL) { 407*fcf3ce44SJohn Forte mdb_warn("The address of a fcp_port" 408*fcf3ce44SJohn Forte " structure must be given\n"); 409*fcf3ce44SJohn Forte return (WALK_ERR); 410*fcf3ce44SJohn Forte } 411*fcf3ce44SJohn Forte 412*fcf3ce44SJohn Forte /* 413*fcf3ce44SJohn Forte * Input should be a fcp_port, so read it to get the ipkt 414*fcf3ce44SJohn Forte * list's head 415*fcf3ce44SJohn Forte */ 416*fcf3ce44SJohn Forte 417*fcf3ce44SJohn Forte if (mdb_vread(&port, sizeof (struct fcp_port), wsp->walk_addr) != 418*fcf3ce44SJohn Forte sizeof (struct fcp_port)) { 419*fcf3ce44SJohn Forte mdb_warn("Failed to read in the fcp_port" 420*fcf3ce44SJohn Forte " at 0x%p\n", wsp->walk_addr); 421*fcf3ce44SJohn Forte return (WALK_ERR); 422*fcf3ce44SJohn Forte } 423*fcf3ce44SJohn Forte 424*fcf3ce44SJohn Forte wsp->walk_addr = (uintptr_t)(port.port_ipkt_list); 425*fcf3ce44SJohn Forte wsp->walk_data = mdb_alloc(sizeof (struct fcp_ipkt), UM_SLEEP); 426*fcf3ce44SJohn Forte 427*fcf3ce44SJohn Forte return (WALK_NEXT); 428*fcf3ce44SJohn Forte } 429*fcf3ce44SJohn Forte 430*fcf3ce44SJohn Forte static int 431*fcf3ce44SJohn Forte ipkt_walk_s(mdb_walk_state_t *wsp) 432*fcf3ce44SJohn Forte { 433*fcf3ce44SJohn Forte int status; 434*fcf3ce44SJohn Forte 435*fcf3ce44SJohn Forte if (wsp->walk_addr == NULL) 436*fcf3ce44SJohn Forte return (WALK_DONE); 437*fcf3ce44SJohn Forte 438*fcf3ce44SJohn Forte if (mdb_vread(wsp->walk_data, sizeof (struct fcp_ipkt), 439*fcf3ce44SJohn Forte wsp->walk_addr) == -1) { 440*fcf3ce44SJohn Forte mdb_warn("Failed to read in the fcp_ipkt" 441*fcf3ce44SJohn Forte " at 0x%p\n", wsp->walk_addr); 442*fcf3ce44SJohn Forte return (WALK_DONE); 443*fcf3ce44SJohn Forte } 444*fcf3ce44SJohn Forte 445*fcf3ce44SJohn Forte status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 446*fcf3ce44SJohn Forte wsp->walk_cbdata); 447*fcf3ce44SJohn Forte 448*fcf3ce44SJohn Forte wsp->walk_addr = 449*fcf3ce44SJohn Forte (uintptr_t)(((struct fcp_ipkt *)wsp->walk_data)->ipkt_next); 450*fcf3ce44SJohn Forte 451*fcf3ce44SJohn Forte return (status); 452*fcf3ce44SJohn Forte } 453*fcf3ce44SJohn Forte 454*fcf3ce44SJohn Forte /* 455*fcf3ce44SJohn Forte * The walker's fini function is invoked at the end of each walk. 456*fcf3ce44SJohn Forte */ 457*fcf3ce44SJohn Forte static void 458*fcf3ce44SJohn Forte ipkt_walk_f(mdb_walk_state_t *wsp) 459*fcf3ce44SJohn Forte { 460*fcf3ce44SJohn Forte mdb_free(wsp->walk_data, sizeof (struct fcp_ipkt)); 461*fcf3ce44SJohn Forte } 462*fcf3ce44SJohn Forte 463*fcf3ce44SJohn Forte /* 464*fcf3ce44SJohn Forte * Leadville fcp_pkt walker/dcmd code 465*fcf3ce44SJohn Forte */ 466*fcf3ce44SJohn Forte 467*fcf3ce44SJohn Forte static int 468*fcf3ce44SJohn Forte pkt_walk_i(mdb_walk_state_t *wsp) 469*fcf3ce44SJohn Forte { 470*fcf3ce44SJohn Forte if (wsp->walk_addr == NULL) { 471*fcf3ce44SJohn Forte mdb_warn("The address of a fcp_port" 472*fcf3ce44SJohn Forte " structure must be given\n"); 473*fcf3ce44SJohn Forte return (WALK_ERR); 474*fcf3ce44SJohn Forte } 475*fcf3ce44SJohn Forte 476*fcf3ce44SJohn Forte /* 477*fcf3ce44SJohn Forte * Input should be an fcp_port, so read it to get the pkt 478*fcf3ce44SJohn Forte * list's head 479*fcf3ce44SJohn Forte */ 480*fcf3ce44SJohn Forte 481*fcf3ce44SJohn Forte if (mdb_vread(&port, sizeof (struct fcp_port), wsp->walk_addr) != 482*fcf3ce44SJohn Forte sizeof (struct fcp_port)) { 483*fcf3ce44SJohn Forte mdb_warn("Failed to read in the fcp_port" 484*fcf3ce44SJohn Forte " at 0x%p\n", wsp->walk_addr); 485*fcf3ce44SJohn Forte return (WALK_ERR); 486*fcf3ce44SJohn Forte } 487*fcf3ce44SJohn Forte 488*fcf3ce44SJohn Forte wsp->walk_addr = (uintptr_t)(port.port_pkt_head); 489*fcf3ce44SJohn Forte wsp->walk_data = mdb_alloc(sizeof (struct fcp_pkt), UM_SLEEP); 490*fcf3ce44SJohn Forte 491*fcf3ce44SJohn Forte return (WALK_NEXT); 492*fcf3ce44SJohn Forte } 493*fcf3ce44SJohn Forte 494*fcf3ce44SJohn Forte static int 495*fcf3ce44SJohn Forte pkt_walk_s(mdb_walk_state_t *wsp) 496*fcf3ce44SJohn Forte { 497*fcf3ce44SJohn Forte int status; 498*fcf3ce44SJohn Forte 499*fcf3ce44SJohn Forte if (wsp->walk_addr == NULL) 500*fcf3ce44SJohn Forte return (WALK_DONE); 501*fcf3ce44SJohn Forte 502*fcf3ce44SJohn Forte if (mdb_vread(wsp->walk_data, sizeof (struct fcp_pkt), 503*fcf3ce44SJohn Forte wsp->walk_addr) == -1) { 504*fcf3ce44SJohn Forte mdb_warn("Failed to read in the fcp_pkt" 505*fcf3ce44SJohn Forte " at 0x%p\n", wsp->walk_addr); 506*fcf3ce44SJohn Forte return (WALK_DONE); 507*fcf3ce44SJohn Forte } 508*fcf3ce44SJohn Forte 509*fcf3ce44SJohn Forte status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 510*fcf3ce44SJohn Forte wsp->walk_cbdata); 511*fcf3ce44SJohn Forte 512*fcf3ce44SJohn Forte wsp->walk_addr = 513*fcf3ce44SJohn Forte (uintptr_t)(((struct fcp_pkt *)wsp->walk_data)->cmd_next); 514*fcf3ce44SJohn Forte 515*fcf3ce44SJohn Forte return (status); 516*fcf3ce44SJohn Forte } 517*fcf3ce44SJohn Forte 518*fcf3ce44SJohn Forte /* 519*fcf3ce44SJohn Forte * The walker's fini function is invoked at the end of each walk. 520*fcf3ce44SJohn Forte */ 521*fcf3ce44SJohn Forte static void 522*fcf3ce44SJohn Forte pkt_walk_f(mdb_walk_state_t *wsp) 523*fcf3ce44SJohn Forte { 524*fcf3ce44SJohn Forte mdb_free(wsp->walk_data, sizeof (struct fcp_pkt)); 525*fcf3ce44SJohn Forte } 526*fcf3ce44SJohn Forte 527*fcf3ce44SJohn Forte /* 528*fcf3ce44SJohn Forte * MDB module linkage information: 529*fcf3ce44SJohn Forte * 530*fcf3ce44SJohn Forte * We declare a list of structures describing our dcmds, a list of structures 531*fcf3ce44SJohn Forte * describing our walkers, and a function named _mdb_init to return a pointer 532*fcf3ce44SJohn Forte * to our module information. 533*fcf3ce44SJohn Forte */ 534*fcf3ce44SJohn Forte 535*fcf3ce44SJohn Forte static const mdb_dcmd_t dcmds[] = { 536*fcf3ce44SJohn Forte { "fcp", NULL, "Leadville fcp instances", fcp }, 537*fcf3ce44SJohn Forte { NULL } 538*fcf3ce44SJohn Forte }; 539*fcf3ce44SJohn Forte 540*fcf3ce44SJohn Forte static const mdb_walker_t walkers[] = { 541*fcf3ce44SJohn Forte { "fcp", "Walk list of Leadville fcp instances", 542*fcf3ce44SJohn Forte fcp_walk_i, fcp_walk_s, fcp_walk_f }, 543*fcf3ce44SJohn Forte { "cmds", "Walk list of SCSI commands in fcp's per-lun queue", 544*fcf3ce44SJohn Forte cmds_walk_i, cmds_walk_s, cmds_walk_f }, 545*fcf3ce44SJohn Forte { "luns", "Walk list of LUNs in an fcp target", 546*fcf3ce44SJohn Forte luns_walk_i, luns_walk_s, luns_walk_f }, 547*fcf3ce44SJohn Forte { "targets", "Walk list of fcp targets attached to the local port", 548*fcf3ce44SJohn Forte targets_walk_i, targets_walk_s, targets_walk_f }, 549*fcf3ce44SJohn Forte { "fcp_ipkt", "Walk list of internal packets queued on a local port", 550*fcf3ce44SJohn Forte ipkt_walk_i, ipkt_walk_s, ipkt_walk_f}, 551*fcf3ce44SJohn Forte { "fcp_pkt", "Walk list of packets queued on a local port", 552*fcf3ce44SJohn Forte pkt_walk_i, pkt_walk_s, pkt_walk_f}, 553*fcf3ce44SJohn Forte { NULL } 554*fcf3ce44SJohn Forte }; 555*fcf3ce44SJohn Forte 556*fcf3ce44SJohn Forte static const mdb_modinfo_t modinfo = { 557*fcf3ce44SJohn Forte MDB_API_VERSION, dcmds, walkers 558*fcf3ce44SJohn Forte }; 559*fcf3ce44SJohn Forte 560*fcf3ce44SJohn Forte const mdb_modinfo_t * 561*fcf3ce44SJohn Forte _mdb_init(void) 562*fcf3ce44SJohn Forte { 563*fcf3ce44SJohn Forte return (&modinfo); 564*fcf3ce44SJohn Forte } 565