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 /* 23*fcf3ce44SJohn Forte * Copyright 2008 Emulex. All rights reserved. 24*fcf3ce44SJohn Forte * Use is subject to License terms. 25*fcf3ce44SJohn Forte */ 26*fcf3ce44SJohn Forte 27*fcf3ce44SJohn Forte 28*fcf3ce44SJohn Forte #include "emlxs.h" 29*fcf3ce44SJohn Forte 30*fcf3ce44SJohn Forte #define PRIV_LILP_POSIT(port_dev) port_dev->dev_did.priv_lilp_posit 31*fcf3ce44SJohn Forte #define HARD_ADDR(port_dev) port_dev->dev_hard_addr.hard_addr 32*fcf3ce44SJohn Forte #define HBA_10GBIT HBA_PORTSPEED_10GBIT 33*fcf3ce44SJohn Forte 34*fcf3ce44SJohn Forte #ifdef DFC_SUPPORT 35*fcf3ce44SJohn Forte 36*fcf3ce44SJohn Forte /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 37*fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_DFC_C); 38*fcf3ce44SJohn Forte 39*fcf3ce44SJohn Forte static int32_t emlxs_dfc_get_rev(emlxs_hba_t *hba, 40*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 41*fcf3ce44SJohn Forte static int32_t emlxs_dfc_get_hbainfo(emlxs_hba_t *hba, 42*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 43*fcf3ce44SJohn Forte static int32_t emlxs_dfc_get_hbastats(emlxs_hba_t *hba, 44*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 45*fcf3ce44SJohn Forte static int32_t emlxs_dfc_get_drvstats(emlxs_hba_t *hba, 46*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 47*fcf3ce44SJohn Forte static int32_t emlxs_dfc_set_diag(emlxs_hba_t *hba, 48*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 49*fcf3ce44SJohn Forte static int32_t emlxs_dfc_send_mbox(emlxs_hba_t *hba, 50*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 51*fcf3ce44SJohn Forte static int32_t emlxs_dfc_read_pci(emlxs_hba_t *hba, 52*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 53*fcf3ce44SJohn Forte static int32_t emlxs_dfc_write_pci(emlxs_hba_t *hba, 54*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 55*fcf3ce44SJohn Forte static int32_t emlxs_dfc_get_cfg(emlxs_hba_t *hba, 56*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 57*fcf3ce44SJohn Forte static int32_t emlxs_dfc_set_cfg(emlxs_hba_t *hba, 58*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 59*fcf3ce44SJohn Forte static int32_t emlxs_dfc_send_menlo(emlxs_hba_t *hba, 60*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 61*fcf3ce44SJohn Forte static int32_t emlxs_dfc_send_ct(emlxs_hba_t *hba, 62*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 63*fcf3ce44SJohn Forte static int32_t emlxs_dfc_send_ct_rsp(emlxs_hba_t *hba, 64*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 65*fcf3ce44SJohn Forte static int32_t emlxs_dfc_write_flash(emlxs_hba_t *hba, 66*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 67*fcf3ce44SJohn Forte static int32_t emlxs_dfc_read_flash(emlxs_hba_t *hba, 68*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 69*fcf3ce44SJohn Forte static int32_t emlxs_dfc_send_els(emlxs_hba_t *hba, 70*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 71*fcf3ce44SJohn Forte static int32_t emlxs_dfc_loopback_test(emlxs_hba_t *hba, 72*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 73*fcf3ce44SJohn Forte static int32_t emlxs_dfc_get_dump_region(emlxs_hba_t *hba, 74*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 75*fcf3ce44SJohn Forte static int32_t emlxs_dfc_loopback_mode(emlxs_hba_t *hba, 76*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 77*fcf3ce44SJohn Forte static int32_t emlxs_dfc_get_ioinfo(emlxs_hba_t *hba, 78*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 79*fcf3ce44SJohn Forte static int32_t emlxs_dfc_get_linkinfo(emlxs_hba_t *hba, 80*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 81*fcf3ce44SJohn Forte static int32_t emlxs_dfc_read_mem(emlxs_hba_t *hba, 82*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 83*fcf3ce44SJohn Forte static int32_t emlxs_dfc_write_mem(emlxs_hba_t *hba, 84*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 85*fcf3ce44SJohn Forte static int32_t emlxs_dfc_write_ctlreg(emlxs_hba_t *hba, 86*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 87*fcf3ce44SJohn Forte static int32_t emlxs_dfc_read_ctlreg(emlxs_hba_t *hba, 88*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 89*fcf3ce44SJohn Forte static int32_t emlxs_dfc_get_event(emlxs_hba_t *hba, 90*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 91*fcf3ce44SJohn Forte static int32_t emlxs_dfc_set_event(emlxs_hba_t *hba, 92*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 93*fcf3ce44SJohn Forte static int32_t emlxs_dfc_get_eventinfo(emlxs_hba_t *hba, 94*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 95*fcf3ce44SJohn Forte static int32_t emlxs_dfc_get_nodeinfo(emlxs_hba_t *hba, 96*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 97*fcf3ce44SJohn Forte 98*fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT 99*fcf3ce44SJohn Forte static int32_t emlxs_dfc_get_fctstat(emlxs_hba_t *hba, 100*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 101*fcf3ce44SJohn Forte #endif /* SFCT_SUPPORT */ 102*fcf3ce44SJohn Forte #ifdef NPIV_SUPPORT 103*fcf3ce44SJohn Forte static int32_t emlxs_dfc_create_vport(emlxs_hba_t *hba, 104*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 105*fcf3ce44SJohn Forte static int32_t emlxs_dfc_destroy_vport(emlxs_hba_t *hba, 106*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 107*fcf3ce44SJohn Forte static int32_t emlxs_dfc_get_vportinfo(emlxs_hba_t *hba, 108*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 109*fcf3ce44SJohn Forte static int32_t emlxs_dfc_npiv_resource(emlxs_hba_t *hba, 110*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 111*fcf3ce44SJohn Forte static int32_t emlxs_dfc_npiv_test(emlxs_hba_t *hba, 112*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 113*fcf3ce44SJohn Forte static emlxs_port_t *emlxs_vport_find_wwpn(emlxs_hba_t *hba, 114*fcf3ce44SJohn Forte uint8_t *wwpn); 115*fcf3ce44SJohn Forte #endif /* NPIV_SUPPORT */ 116*fcf3ce44SJohn Forte 117*fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 118*fcf3ce44SJohn Forte static int32_t emlxs_dfc_init_auth(emlxs_hba_t *hba, 119*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 120*fcf3ce44SJohn Forte static int32_t emlxs_dfc_get_auth_cfg(emlxs_hba_t *hba, 121*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 122*fcf3ce44SJohn Forte static int32_t emlxs_dfc_set_auth_cfg(emlxs_hba_t *hba, 123*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 124*fcf3ce44SJohn Forte static int32_t emlxs_dfc_get_auth_pwd(emlxs_hba_t *hba, 125*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 126*fcf3ce44SJohn Forte static int32_t emlxs_dfc_set_auth_pwd(emlxs_hba_t *hba, 127*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 128*fcf3ce44SJohn Forte static int32_t emlxs_dfc_get_auth_status(emlxs_hba_t *hba, 129*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 130*fcf3ce44SJohn Forte static int32_t emlxs_dfc_get_auth_cfg_table(emlxs_hba_t *hba, 131*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 132*fcf3ce44SJohn Forte static int32_t emlxs_dfc_get_auth_key_table(emlxs_hba_t *hba, 133*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 134*fcf3ce44SJohn Forte #endif /* DHCHAP_SUPPORT */ 135*fcf3ce44SJohn Forte 136*fcf3ce44SJohn Forte static int32_t emlxs_dfc_send_scsi_fcp(emlxs_hba_t *hba, 137*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 138*fcf3ce44SJohn Forte #ifdef FCIO_SUPPORT 139*fcf3ce44SJohn Forte static int32_t emlxs_fcio_manage(emlxs_hba_t *hba, 140*fcf3ce44SJohn Forte dfc_t *dfc, int32_t mode); 141*fcf3ce44SJohn Forte #endif /* FCIO_SUPPORT */ 142*fcf3ce44SJohn Forte 143*fcf3ce44SJohn Forte 144*fcf3ce44SJohn Forte uint32_t emlxs_loopback_tmo = 60; 145*fcf3ce44SJohn Forte 146*fcf3ce44SJohn Forte emlxs_table_t emlxs_dfc_table[] = 147*fcf3ce44SJohn Forte { 148*fcf3ce44SJohn Forte {EMLXS_GET_HBAINFO, "GET_HBAINFO"}, 149*fcf3ce44SJohn Forte {EMLXS_GET_REV, "GET_REV"}, 150*fcf3ce44SJohn Forte {EMLXS_SET_DIAG, "SET_DIAG"}, 151*fcf3ce44SJohn Forte {EMLXS_SEND_MBOX, "SEND_MBOX"}, 152*fcf3ce44SJohn Forte {EMLXS_READ_PCI, "READ_PCI"}, 153*fcf3ce44SJohn Forte {EMLXS_WRITE_PCI, "WRITE_PCI"}, 154*fcf3ce44SJohn Forte {EMLXS_GET_CFG, "GET_CFG"}, 155*fcf3ce44SJohn Forte {EMLXS_SET_CFG, "SET_CFG"}, 156*fcf3ce44SJohn Forte {EMLXS_SEND_CT, "SEND_CT"}, 157*fcf3ce44SJohn Forte {EMLXS_SEND_CT_RSP, "SEND_CT_RSP"}, 158*fcf3ce44SJohn Forte {EMLXS_SEND_MENLO, "SEND_MENLO"}, 159*fcf3ce44SJohn Forte {EMLXS_WRITE_FLASH, "WRITE_FLASH"}, 160*fcf3ce44SJohn Forte {EMLXS_READ_FLASH, "READ_FLASH"}, 161*fcf3ce44SJohn Forte {EMLXS_SEND_ELS, "SEND_ELS"}, 162*fcf3ce44SJohn Forte {EMLXS_LOOPBACK_TEST, "LOOPBACK_TEST"}, 163*fcf3ce44SJohn Forte {EMLXS_GET_DUMPREGION, "GET_DUMPREGION"}, 164*fcf3ce44SJohn Forte {EMLXS_LOOPBACK_MODE, "LOOPBACK_MODE"}, 165*fcf3ce44SJohn Forte {EMLXS_GET_IOINFO, "GET_IOINFO"}, 166*fcf3ce44SJohn Forte {EMLXS_GET_LINKINFO, "GET_LINKINFO"}, 167*fcf3ce44SJohn Forte {EMLXS_GET_NODEINFO, "GET_NODEINFO"}, 168*fcf3ce44SJohn Forte {EMLXS_READ_MEM, "READ_MEM"}, 169*fcf3ce44SJohn Forte {EMLXS_WRITE_MEM, "WRITE_MEM"}, 170*fcf3ce44SJohn Forte {EMLXS_WRITE_CTLREG, "WRITE_CTLREG"}, 171*fcf3ce44SJohn Forte {EMLXS_READ_CTLREG, "READ_CTLREG"}, 172*fcf3ce44SJohn Forte {EMLXS_SEND_SCSI, "SEND_SCSI"}, 173*fcf3ce44SJohn Forte {EMLXS_GET_EVENT, "GET_EVENT"}, 174*fcf3ce44SJohn Forte {EMLXS_SET_EVENT, "SET_EVENT"}, 175*fcf3ce44SJohn Forte {EMLXS_GET_EVENTINFO, "GET_EVENTINFO"}, 176*fcf3ce44SJohn Forte {EMLXS_GET_HBASTATS, "GET_HBASTATS"}, 177*fcf3ce44SJohn Forte {EMLXS_GET_DRVSTATS, "GET_DRVSTATS"}, 178*fcf3ce44SJohn Forte {EMLXS_CREATE_VPORT, "CREATE_VPORT"}, 179*fcf3ce44SJohn Forte {EMLXS_DESTROY_VPORT, "DESTROY_VPORT"}, 180*fcf3ce44SJohn Forte {EMLXS_GET_VPORTINFO, "GET_VPORTINFO"}, 181*fcf3ce44SJohn Forte {EMLXS_NPIV_RESOURCE, "NPIV_RESOURCE"}, 182*fcf3ce44SJohn Forte {EMLXS_NPIV_TEST, "NPIV_TEST"}, 183*fcf3ce44SJohn Forte {EMLXS_INIT_AUTH, "INIT_AUTH"}, 184*fcf3ce44SJohn Forte {EMLXS_GET_AUTH_CFG, "GET_AUTH_CFG"}, 185*fcf3ce44SJohn Forte {EMLXS_SET_AUTH_CFG, "SET_AUTH_CFG"}, 186*fcf3ce44SJohn Forte {EMLXS_GET_AUTH_PASSWORD, "GET_AUTH_PASSWORD"}, 187*fcf3ce44SJohn Forte {EMLXS_SET_AUTH_PASSWORD, "SET_AUTH_PASSWORD"}, 188*fcf3ce44SJohn Forte {EMLXS_GET_AUTH_STATUS, "GET_AUTH_STATUS"}, 189*fcf3ce44SJohn Forte {EMLXS_GET_AUTH_CFG_TABLE, "GET_AUTH_CFG_TABLE"}, 190*fcf3ce44SJohn Forte {EMLXS_GET_AUTH_KEY_TABLE, "GET_AUTH_KEY_TABLE"}, 191*fcf3ce44SJohn Forte {EMLXS_FCIO_CMD, "FCIO_CMD"}, 192*fcf3ce44SJohn Forte {EMLXS_GET_FCTSTAT, "GET_FCTSTAT"}, 193*fcf3ce44SJohn Forte 194*fcf3ce44SJohn Forte }; /* emlxs_dfc_table */ 195*fcf3ce44SJohn Forte 196*fcf3ce44SJohn Forte 197*fcf3ce44SJohn Forte emlxs_table_t emlxs_dfc_event_table[] = 198*fcf3ce44SJohn Forte { 199*fcf3ce44SJohn Forte {FC_REG_LINK_EVENT, "LINK_EVENT"}, 200*fcf3ce44SJohn Forte {FC_REG_RSCN_EVENT, "RSCN_EVENT"}, 201*fcf3ce44SJohn Forte {FC_REG_CT_EVENT, "CT_EVENT"}, 202*fcf3ce44SJohn Forte {FC_REG_DUMP_EVENT, "DUMP_EVENT"}, 203*fcf3ce44SJohn Forte {FC_REG_TEMP_EVENT, "TEMP_EVENT"}, 204*fcf3ce44SJohn Forte {FC_REG_FCOE_EVENT, "FCOE_EVENT"}, 205*fcf3ce44SJohn Forte 206*fcf3ce44SJohn Forte }; /* emlxs_dfc_event_table */ 207*fcf3ce44SJohn Forte 208*fcf3ce44SJohn Forte 209*fcf3ce44SJohn Forte extern char * 210*fcf3ce44SJohn Forte emlxs_dfc_xlate(uint16_t cmd) 211*fcf3ce44SJohn Forte { 212*fcf3ce44SJohn Forte static char buffer[32]; 213*fcf3ce44SJohn Forte uint32_t i; 214*fcf3ce44SJohn Forte uint32_t count; 215*fcf3ce44SJohn Forte 216*fcf3ce44SJohn Forte count = sizeof (emlxs_dfc_table) / sizeof (emlxs_table_t); 217*fcf3ce44SJohn Forte for (i = 0; i < count; i++) { 218*fcf3ce44SJohn Forte if (cmd == emlxs_dfc_table[i].code) { 219*fcf3ce44SJohn Forte return (emlxs_dfc_table[i].string); 220*fcf3ce44SJohn Forte } 221*fcf3ce44SJohn Forte } 222*fcf3ce44SJohn Forte 223*fcf3ce44SJohn Forte (void) sprintf(buffer, "Cmd=0x%x", cmd); 224*fcf3ce44SJohn Forte return (buffer); 225*fcf3ce44SJohn Forte 226*fcf3ce44SJohn Forte } /* emlxs_dfc_xlate() */ 227*fcf3ce44SJohn Forte 228*fcf3ce44SJohn Forte 229*fcf3ce44SJohn Forte extern char * 230*fcf3ce44SJohn Forte emlxs_dfc_event_xlate(uint32_t event) 231*fcf3ce44SJohn Forte { 232*fcf3ce44SJohn Forte static char buffer[32]; 233*fcf3ce44SJohn Forte uint32_t i; 234*fcf3ce44SJohn Forte uint32_t count; 235*fcf3ce44SJohn Forte 236*fcf3ce44SJohn Forte count = sizeof (emlxs_dfc_event_table) / sizeof (emlxs_table_t); 237*fcf3ce44SJohn Forte for (i = 0; i < count; i++) { 238*fcf3ce44SJohn Forte if (event == emlxs_dfc_event_table[i].code) { 239*fcf3ce44SJohn Forte return (emlxs_dfc_event_table[i].string); 240*fcf3ce44SJohn Forte } 241*fcf3ce44SJohn Forte } 242*fcf3ce44SJohn Forte 243*fcf3ce44SJohn Forte (void) sprintf(buffer, "Event=0x%x", event); 244*fcf3ce44SJohn Forte return (buffer); 245*fcf3ce44SJohn Forte 246*fcf3ce44SJohn Forte } /* emlxs_dfc_event_xlate() */ 247*fcf3ce44SJohn Forte 248*fcf3ce44SJohn Forte 249*fcf3ce44SJohn Forte 250*fcf3ce44SJohn Forte extern int32_t 251*fcf3ce44SJohn Forte emlxs_dfc_manage(emlxs_hba_t *hba, void *arg, int32_t mode) 252*fcf3ce44SJohn Forte { 253*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 254*fcf3ce44SJohn Forte int rval = 0; 255*fcf3ce44SJohn Forte dfc_t *dfc; 256*fcf3ce44SJohn Forte 257*fcf3ce44SJohn Forte if (!(dfc = (dfc_t *)kmem_zalloc(sizeof (dfc_t), KM_SLEEP))) { 258*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 259*fcf3ce44SJohn Forte "%s: Unable to allocate dfc buffer.", 260*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 261*fcf3ce44SJohn Forte 262*fcf3ce44SJohn Forte return (DFC_SYSRES_ERROR); 263*fcf3ce44SJohn Forte } 264*fcf3ce44SJohn Forte #ifdef _MULTI_DATAMODEL 265*fcf3ce44SJohn Forte switch (ddi_model_convert_from(mode & FMODELS)) { 266*fcf3ce44SJohn Forte case DDI_MODEL_ILP32: 267*fcf3ce44SJohn Forte { 268*fcf3ce44SJohn Forte dfc32_t dfc32; 269*fcf3ce44SJohn Forte 270*fcf3ce44SJohn Forte if (ddi_copyin((void *)arg, (void *)&dfc32, 271*fcf3ce44SJohn Forte sizeof (dfc32_t), mode)) { 272*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 273*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 274*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 275*fcf3ce44SJohn Forte 276*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 277*fcf3ce44SJohn Forte break; 278*fcf3ce44SJohn Forte } 279*fcf3ce44SJohn Forte dfc->cmd = dfc32.cmd; 280*fcf3ce44SJohn Forte dfc->flag = dfc32.flag; 281*fcf3ce44SJohn Forte dfc->buf1 = (void *)(unsigned long)dfc32.buf1; 282*fcf3ce44SJohn Forte dfc->buf1_size = dfc32.buf1_size; 283*fcf3ce44SJohn Forte dfc->data1 = dfc32.data1; 284*fcf3ce44SJohn Forte dfc->buf2 = (void *)(unsigned long)dfc32.buf2; 285*fcf3ce44SJohn Forte dfc->buf2_size = dfc32.buf2_size; 286*fcf3ce44SJohn Forte dfc->data2 = dfc32.data2; 287*fcf3ce44SJohn Forte dfc->buf3 = (void *)(unsigned long)dfc32.buf3; 288*fcf3ce44SJohn Forte dfc->buf3_size = dfc32.buf3_size; 289*fcf3ce44SJohn Forte dfc->data3 = dfc32.data3; 290*fcf3ce44SJohn Forte dfc->buf4 = (void *)(unsigned long)dfc32.buf4; 291*fcf3ce44SJohn Forte dfc->buf4_size = dfc32.buf4_size; 292*fcf3ce44SJohn Forte dfc->data4 = dfc32.data4; 293*fcf3ce44SJohn Forte 294*fcf3ce44SJohn Forte break; 295*fcf3ce44SJohn Forte } 296*fcf3ce44SJohn Forte 297*fcf3ce44SJohn Forte case DDI_MODEL_NONE: 298*fcf3ce44SJohn Forte if (ddi_copyin((void *)arg, (void *)dfc, 299*fcf3ce44SJohn Forte sizeof (dfc_t), mode)) { 300*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 301*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 302*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 303*fcf3ce44SJohn Forte 304*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 305*fcf3ce44SJohn Forte } 306*fcf3ce44SJohn Forte break; 307*fcf3ce44SJohn Forte } 308*fcf3ce44SJohn Forte #else /* _MULTI_DATAMODEL */ 309*fcf3ce44SJohn Forte if (ddi_copyin((void *) arg, (void *) dfc, sizeof (dfc_t), mode)) { 310*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 311*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 312*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 313*fcf3ce44SJohn Forte 314*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 315*fcf3ce44SJohn Forte } 316*fcf3ce44SJohn Forte #endif /* _MULTI_DATAMODEL */ 317*fcf3ce44SJohn Forte 318*fcf3ce44SJohn Forte 319*fcf3ce44SJohn Forte switch (dfc->cmd) { 320*fcf3ce44SJohn Forte case EMLXS_GET_HBAINFO: 321*fcf3ce44SJohn Forte { 322*fcf3ce44SJohn Forte 323*fcf3ce44SJohn Forte rval = emlxs_dfc_get_hbainfo(hba, dfc, mode); 324*fcf3ce44SJohn Forte 325*fcf3ce44SJohn Forte break; 326*fcf3ce44SJohn Forte } 327*fcf3ce44SJohn Forte 328*fcf3ce44SJohn Forte case EMLXS_GET_HBASTATS: 329*fcf3ce44SJohn Forte { 330*fcf3ce44SJohn Forte 331*fcf3ce44SJohn Forte rval = emlxs_dfc_get_hbastats(hba, dfc, mode); 332*fcf3ce44SJohn Forte 333*fcf3ce44SJohn Forte break; 334*fcf3ce44SJohn Forte } 335*fcf3ce44SJohn Forte 336*fcf3ce44SJohn Forte case EMLXS_GET_DRVSTATS: 337*fcf3ce44SJohn Forte { 338*fcf3ce44SJohn Forte 339*fcf3ce44SJohn Forte rval = emlxs_dfc_get_drvstats(hba, dfc, mode); 340*fcf3ce44SJohn Forte 341*fcf3ce44SJohn Forte break; 342*fcf3ce44SJohn Forte } 343*fcf3ce44SJohn Forte 344*fcf3ce44SJohn Forte case EMLXS_GET_NODEINFO: 345*fcf3ce44SJohn Forte { 346*fcf3ce44SJohn Forte 347*fcf3ce44SJohn Forte rval = emlxs_dfc_get_nodeinfo(hba, dfc, mode); 348*fcf3ce44SJohn Forte 349*fcf3ce44SJohn Forte break; 350*fcf3ce44SJohn Forte } 351*fcf3ce44SJohn Forte 352*fcf3ce44SJohn Forte case EMLXS_SET_DIAG: 353*fcf3ce44SJohn Forte { 354*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 355*fcf3ce44SJohn Forte "%s requested.", 356*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 357*fcf3ce44SJohn Forte 358*fcf3ce44SJohn Forte rval = emlxs_dfc_set_diag(hba, dfc, mode); 359*fcf3ce44SJohn Forte 360*fcf3ce44SJohn Forte break; 361*fcf3ce44SJohn Forte } 362*fcf3ce44SJohn Forte 363*fcf3ce44SJohn Forte case EMLXS_SEND_MBOX: 364*fcf3ce44SJohn Forte { 365*fcf3ce44SJohn Forte rval = emlxs_dfc_send_mbox(hba, dfc, mode); 366*fcf3ce44SJohn Forte 367*fcf3ce44SJohn Forte break; 368*fcf3ce44SJohn Forte } 369*fcf3ce44SJohn Forte 370*fcf3ce44SJohn Forte case EMLXS_READ_PCI: 371*fcf3ce44SJohn Forte { 372*fcf3ce44SJohn Forte rval = emlxs_dfc_read_pci(hba, dfc, mode); 373*fcf3ce44SJohn Forte 374*fcf3ce44SJohn Forte break; 375*fcf3ce44SJohn Forte } 376*fcf3ce44SJohn Forte 377*fcf3ce44SJohn Forte case EMLXS_WRITE_PCI: 378*fcf3ce44SJohn Forte { 379*fcf3ce44SJohn Forte rval = emlxs_dfc_write_pci(hba, dfc, mode); 380*fcf3ce44SJohn Forte 381*fcf3ce44SJohn Forte break; 382*fcf3ce44SJohn Forte } 383*fcf3ce44SJohn Forte 384*fcf3ce44SJohn Forte case EMLXS_GET_CFG: 385*fcf3ce44SJohn Forte { 386*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 387*fcf3ce44SJohn Forte "%s requested.", 388*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 389*fcf3ce44SJohn Forte 390*fcf3ce44SJohn Forte rval = emlxs_dfc_get_cfg(hba, dfc, mode); 391*fcf3ce44SJohn Forte 392*fcf3ce44SJohn Forte break; 393*fcf3ce44SJohn Forte } 394*fcf3ce44SJohn Forte 395*fcf3ce44SJohn Forte case EMLXS_SET_CFG: 396*fcf3ce44SJohn Forte { 397*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 398*fcf3ce44SJohn Forte "%s requested.", 399*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 400*fcf3ce44SJohn Forte 401*fcf3ce44SJohn Forte rval = emlxs_dfc_set_cfg(hba, dfc, mode); 402*fcf3ce44SJohn Forte 403*fcf3ce44SJohn Forte break; 404*fcf3ce44SJohn Forte } 405*fcf3ce44SJohn Forte 406*fcf3ce44SJohn Forte case EMLXS_SEND_CT: 407*fcf3ce44SJohn Forte { 408*fcf3ce44SJohn Forte rval = emlxs_dfc_send_ct(hba, dfc, mode); 409*fcf3ce44SJohn Forte 410*fcf3ce44SJohn Forte break; 411*fcf3ce44SJohn Forte } 412*fcf3ce44SJohn Forte 413*fcf3ce44SJohn Forte case EMLXS_SEND_CT_RSP: 414*fcf3ce44SJohn Forte { 415*fcf3ce44SJohn Forte rval = emlxs_dfc_send_ct_rsp(hba, dfc, mode); 416*fcf3ce44SJohn Forte 417*fcf3ce44SJohn Forte break; 418*fcf3ce44SJohn Forte } 419*fcf3ce44SJohn Forte 420*fcf3ce44SJohn Forte #ifdef MENLO_SUPPORT 421*fcf3ce44SJohn Forte case EMLXS_SEND_MENLO: 422*fcf3ce44SJohn Forte { 423*fcf3ce44SJohn Forte rval = emlxs_dfc_send_menlo(hba, dfc, mode); 424*fcf3ce44SJohn Forte 425*fcf3ce44SJohn Forte break; 426*fcf3ce44SJohn Forte } 427*fcf3ce44SJohn Forte #endif /* MENLO_SUPPORT */ 428*fcf3ce44SJohn Forte 429*fcf3ce44SJohn Forte case EMLXS_WRITE_FLASH: 430*fcf3ce44SJohn Forte { 431*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 432*fcf3ce44SJohn Forte "%s requested.", 433*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 434*fcf3ce44SJohn Forte 435*fcf3ce44SJohn Forte rval = emlxs_dfc_write_flash(hba, dfc, mode); 436*fcf3ce44SJohn Forte 437*fcf3ce44SJohn Forte break; 438*fcf3ce44SJohn Forte } 439*fcf3ce44SJohn Forte 440*fcf3ce44SJohn Forte case EMLXS_READ_FLASH: 441*fcf3ce44SJohn Forte { 442*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 443*fcf3ce44SJohn Forte "%s requested.", 444*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 445*fcf3ce44SJohn Forte 446*fcf3ce44SJohn Forte rval = emlxs_dfc_read_flash(hba, dfc, mode); 447*fcf3ce44SJohn Forte 448*fcf3ce44SJohn Forte break; 449*fcf3ce44SJohn Forte } 450*fcf3ce44SJohn Forte 451*fcf3ce44SJohn Forte case EMLXS_SEND_ELS: 452*fcf3ce44SJohn Forte { 453*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 454*fcf3ce44SJohn Forte "%s requested.", 455*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 456*fcf3ce44SJohn Forte 457*fcf3ce44SJohn Forte rval = emlxs_dfc_send_els(hba, dfc, mode); 458*fcf3ce44SJohn Forte 459*fcf3ce44SJohn Forte break; 460*fcf3ce44SJohn Forte } 461*fcf3ce44SJohn Forte 462*fcf3ce44SJohn Forte case EMLXS_LOOPBACK_TEST: 463*fcf3ce44SJohn Forte { 464*fcf3ce44SJohn Forte rval = emlxs_dfc_loopback_test(hba, dfc, mode); 465*fcf3ce44SJohn Forte 466*fcf3ce44SJohn Forte break; 467*fcf3ce44SJohn Forte } 468*fcf3ce44SJohn Forte 469*fcf3ce44SJohn Forte case EMLXS_GET_DUMPREGION: 470*fcf3ce44SJohn Forte { 471*fcf3ce44SJohn Forte 472*fcf3ce44SJohn Forte rval = emlxs_dfc_get_dump_region(hba, dfc, mode); 473*fcf3ce44SJohn Forte 474*fcf3ce44SJohn Forte break; 475*fcf3ce44SJohn Forte } 476*fcf3ce44SJohn Forte 477*fcf3ce44SJohn Forte case EMLXS_LOOPBACK_MODE: 478*fcf3ce44SJohn Forte { 479*fcf3ce44SJohn Forte rval = emlxs_dfc_loopback_mode(hba, dfc, mode); 480*fcf3ce44SJohn Forte 481*fcf3ce44SJohn Forte break; 482*fcf3ce44SJohn Forte } 483*fcf3ce44SJohn Forte 484*fcf3ce44SJohn Forte case EMLXS_GET_IOINFO: 485*fcf3ce44SJohn Forte { 486*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 487*fcf3ce44SJohn Forte "%s requested.", 488*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 489*fcf3ce44SJohn Forte 490*fcf3ce44SJohn Forte rval = emlxs_dfc_get_ioinfo(hba, dfc, mode); 491*fcf3ce44SJohn Forte 492*fcf3ce44SJohn Forte break; 493*fcf3ce44SJohn Forte } 494*fcf3ce44SJohn Forte 495*fcf3ce44SJohn Forte case EMLXS_GET_LINKINFO: 496*fcf3ce44SJohn Forte { 497*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 498*fcf3ce44SJohn Forte "%s requested.", 499*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 500*fcf3ce44SJohn Forte 501*fcf3ce44SJohn Forte rval = emlxs_dfc_get_linkinfo(hba, dfc, mode); 502*fcf3ce44SJohn Forte 503*fcf3ce44SJohn Forte break; 504*fcf3ce44SJohn Forte } 505*fcf3ce44SJohn Forte 506*fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT 507*fcf3ce44SJohn Forte case EMLXS_GET_FCTSTAT: 508*fcf3ce44SJohn Forte { 509*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 510*fcf3ce44SJohn Forte "%s requested.", 511*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 512*fcf3ce44SJohn Forte 513*fcf3ce44SJohn Forte rval = emlxs_dfc_get_fctstat(hba, dfc, mode); 514*fcf3ce44SJohn Forte 515*fcf3ce44SJohn Forte break; 516*fcf3ce44SJohn Forte } 517*fcf3ce44SJohn Forte #endif /* SFCT_SUPPORT */ 518*fcf3ce44SJohn Forte 519*fcf3ce44SJohn Forte case EMLXS_READ_MEM: 520*fcf3ce44SJohn Forte { 521*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 522*fcf3ce44SJohn Forte "%s requested.", 523*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 524*fcf3ce44SJohn Forte 525*fcf3ce44SJohn Forte rval = emlxs_dfc_read_mem(hba, dfc, mode); 526*fcf3ce44SJohn Forte 527*fcf3ce44SJohn Forte break; 528*fcf3ce44SJohn Forte } 529*fcf3ce44SJohn Forte 530*fcf3ce44SJohn Forte case EMLXS_WRITE_MEM: 531*fcf3ce44SJohn Forte { 532*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 533*fcf3ce44SJohn Forte "%s requested.", 534*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 535*fcf3ce44SJohn Forte 536*fcf3ce44SJohn Forte rval = emlxs_dfc_write_mem(hba, dfc, mode); 537*fcf3ce44SJohn Forte 538*fcf3ce44SJohn Forte break; 539*fcf3ce44SJohn Forte } 540*fcf3ce44SJohn Forte 541*fcf3ce44SJohn Forte case EMLXS_WRITE_CTLREG: 542*fcf3ce44SJohn Forte { 543*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 544*fcf3ce44SJohn Forte "%s requested.", 545*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 546*fcf3ce44SJohn Forte 547*fcf3ce44SJohn Forte rval = emlxs_dfc_write_ctlreg(hba, dfc, mode); 548*fcf3ce44SJohn Forte 549*fcf3ce44SJohn Forte break; 550*fcf3ce44SJohn Forte } 551*fcf3ce44SJohn Forte 552*fcf3ce44SJohn Forte case EMLXS_READ_CTLREG: 553*fcf3ce44SJohn Forte { 554*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 555*fcf3ce44SJohn Forte "%s requested.", 556*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 557*fcf3ce44SJohn Forte 558*fcf3ce44SJohn Forte rval = emlxs_dfc_read_ctlreg(hba, dfc, mode); 559*fcf3ce44SJohn Forte 560*fcf3ce44SJohn Forte break; 561*fcf3ce44SJohn Forte } 562*fcf3ce44SJohn Forte 563*fcf3ce44SJohn Forte 564*fcf3ce44SJohn Forte case EMLXS_GET_EVENTINFO: 565*fcf3ce44SJohn Forte { 566*fcf3ce44SJohn Forte rval = emlxs_dfc_get_eventinfo(hba, dfc, mode); 567*fcf3ce44SJohn Forte 568*fcf3ce44SJohn Forte break; 569*fcf3ce44SJohn Forte } 570*fcf3ce44SJohn Forte 571*fcf3ce44SJohn Forte case EMLXS_GET_EVENT: 572*fcf3ce44SJohn Forte { 573*fcf3ce44SJohn Forte rval = emlxs_dfc_get_event(hba, dfc, mode); 574*fcf3ce44SJohn Forte 575*fcf3ce44SJohn Forte break; 576*fcf3ce44SJohn Forte } 577*fcf3ce44SJohn Forte 578*fcf3ce44SJohn Forte case EMLXS_SET_EVENT: 579*fcf3ce44SJohn Forte { 580*fcf3ce44SJohn Forte rval = emlxs_dfc_set_event(hba, dfc, mode); 581*fcf3ce44SJohn Forte 582*fcf3ce44SJohn Forte break; 583*fcf3ce44SJohn Forte } 584*fcf3ce44SJohn Forte 585*fcf3ce44SJohn Forte case EMLXS_GET_REV: 586*fcf3ce44SJohn Forte { 587*fcf3ce44SJohn Forte rval = emlxs_dfc_get_rev(hba, dfc, mode); 588*fcf3ce44SJohn Forte 589*fcf3ce44SJohn Forte break; 590*fcf3ce44SJohn Forte } 591*fcf3ce44SJohn Forte 592*fcf3ce44SJohn Forte case EMLXS_SEND_SCSI: 593*fcf3ce44SJohn Forte { 594*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 595*fcf3ce44SJohn Forte "%s requested.", 596*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 597*fcf3ce44SJohn Forte 598*fcf3ce44SJohn Forte rval = emlxs_dfc_send_scsi_fcp(hba, dfc, mode); 599*fcf3ce44SJohn Forte break; 600*fcf3ce44SJohn Forte } 601*fcf3ce44SJohn Forte 602*fcf3ce44SJohn Forte #ifdef NPIV_SUPPORT 603*fcf3ce44SJohn Forte case EMLXS_CREATE_VPORT: 604*fcf3ce44SJohn Forte { 605*fcf3ce44SJohn Forte 606*fcf3ce44SJohn Forte rval = emlxs_dfc_create_vport(hba, dfc, mode); 607*fcf3ce44SJohn Forte 608*fcf3ce44SJohn Forte break; 609*fcf3ce44SJohn Forte } 610*fcf3ce44SJohn Forte 611*fcf3ce44SJohn Forte case EMLXS_DESTROY_VPORT: 612*fcf3ce44SJohn Forte { 613*fcf3ce44SJohn Forte 614*fcf3ce44SJohn Forte rval = emlxs_dfc_destroy_vport(hba, dfc, mode); 615*fcf3ce44SJohn Forte 616*fcf3ce44SJohn Forte break; 617*fcf3ce44SJohn Forte } 618*fcf3ce44SJohn Forte 619*fcf3ce44SJohn Forte case EMLXS_GET_VPORTINFO: 620*fcf3ce44SJohn Forte { 621*fcf3ce44SJohn Forte 622*fcf3ce44SJohn Forte rval = emlxs_dfc_get_vportinfo(hba, dfc, mode); 623*fcf3ce44SJohn Forte 624*fcf3ce44SJohn Forte break; 625*fcf3ce44SJohn Forte } 626*fcf3ce44SJohn Forte 627*fcf3ce44SJohn Forte case EMLXS_NPIV_RESOURCE: 628*fcf3ce44SJohn Forte { 629*fcf3ce44SJohn Forte rval = emlxs_dfc_npiv_resource(hba, dfc, mode); 630*fcf3ce44SJohn Forte 631*fcf3ce44SJohn Forte break; 632*fcf3ce44SJohn Forte } 633*fcf3ce44SJohn Forte 634*fcf3ce44SJohn Forte case EMLXS_NPIV_TEST: 635*fcf3ce44SJohn Forte { 636*fcf3ce44SJohn Forte rval = emlxs_dfc_npiv_test(hba, dfc, mode); 637*fcf3ce44SJohn Forte 638*fcf3ce44SJohn Forte break; 639*fcf3ce44SJohn Forte } 640*fcf3ce44SJohn Forte #endif /* NPIV_SUPPORT */ 641*fcf3ce44SJohn Forte 642*fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 643*fcf3ce44SJohn Forte case EMLXS_INIT_AUTH: 644*fcf3ce44SJohn Forte { 645*fcf3ce44SJohn Forte rval = emlxs_dfc_init_auth(hba, dfc, mode); 646*fcf3ce44SJohn Forte 647*fcf3ce44SJohn Forte break; 648*fcf3ce44SJohn Forte } 649*fcf3ce44SJohn Forte 650*fcf3ce44SJohn Forte case EMLXS_GET_AUTH_CFG: 651*fcf3ce44SJohn Forte { 652*fcf3ce44SJohn Forte rval = emlxs_dfc_get_auth_cfg(hba, dfc, mode); 653*fcf3ce44SJohn Forte 654*fcf3ce44SJohn Forte break; 655*fcf3ce44SJohn Forte } 656*fcf3ce44SJohn Forte 657*fcf3ce44SJohn Forte case EMLXS_SET_AUTH_CFG: 658*fcf3ce44SJohn Forte { 659*fcf3ce44SJohn Forte rval = emlxs_dfc_set_auth_cfg(hba, dfc, mode); 660*fcf3ce44SJohn Forte 661*fcf3ce44SJohn Forte break; 662*fcf3ce44SJohn Forte } 663*fcf3ce44SJohn Forte 664*fcf3ce44SJohn Forte case EMLXS_GET_AUTH_PASSWORD: 665*fcf3ce44SJohn Forte { 666*fcf3ce44SJohn Forte rval = emlxs_dfc_get_auth_pwd(hba, dfc, mode); 667*fcf3ce44SJohn Forte 668*fcf3ce44SJohn Forte break; 669*fcf3ce44SJohn Forte } 670*fcf3ce44SJohn Forte 671*fcf3ce44SJohn Forte case EMLXS_SET_AUTH_PASSWORD: 672*fcf3ce44SJohn Forte { 673*fcf3ce44SJohn Forte rval = emlxs_dfc_set_auth_pwd(hba, dfc, mode); 674*fcf3ce44SJohn Forte 675*fcf3ce44SJohn Forte break; 676*fcf3ce44SJohn Forte } 677*fcf3ce44SJohn Forte 678*fcf3ce44SJohn Forte case EMLXS_GET_AUTH_STATUS: 679*fcf3ce44SJohn Forte { 680*fcf3ce44SJohn Forte rval = emlxs_dfc_get_auth_status(hba, dfc, mode); 681*fcf3ce44SJohn Forte 682*fcf3ce44SJohn Forte break; 683*fcf3ce44SJohn Forte } 684*fcf3ce44SJohn Forte 685*fcf3ce44SJohn Forte case EMLXS_GET_AUTH_CFG_TABLE: 686*fcf3ce44SJohn Forte { 687*fcf3ce44SJohn Forte rval = emlxs_dfc_get_auth_cfg_table(hba, dfc, mode); 688*fcf3ce44SJohn Forte break; 689*fcf3ce44SJohn Forte } 690*fcf3ce44SJohn Forte 691*fcf3ce44SJohn Forte case EMLXS_GET_AUTH_KEY_TABLE: 692*fcf3ce44SJohn Forte { 693*fcf3ce44SJohn Forte rval = emlxs_dfc_get_auth_key_table(hba, dfc, mode); 694*fcf3ce44SJohn Forte break; 695*fcf3ce44SJohn Forte } 696*fcf3ce44SJohn Forte 697*fcf3ce44SJohn Forte #endif /* DHCHAP_SUPPORT */ 698*fcf3ce44SJohn Forte 699*fcf3ce44SJohn Forte #ifdef FCIO_SUPPORT 700*fcf3ce44SJohn Forte case EMLXS_FCIO_CMD: 701*fcf3ce44SJohn Forte rval = emlxs_fcio_manage(hba, dfc, mode); 702*fcf3ce44SJohn Forte break; 703*fcf3ce44SJohn Forte #endif /* FCIO_SUPPORT */ 704*fcf3ce44SJohn Forte 705*fcf3ce44SJohn Forte default: 706*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 707*fcf3ce44SJohn Forte "Unknown command received. (0x%x)", 708*fcf3ce44SJohn Forte dfc->cmd); 709*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 710*fcf3ce44SJohn Forte 711*fcf3ce44SJohn Forte } /* switch() */ 712*fcf3ce44SJohn Forte 713*fcf3ce44SJohn Forte kmem_free(dfc, sizeof (dfc_t)); 714*fcf3ce44SJohn Forte return (rval); 715*fcf3ce44SJohn Forte 716*fcf3ce44SJohn Forte } /* emlxs_dfc_manage() */ 717*fcf3ce44SJohn Forte 718*fcf3ce44SJohn Forte 719*fcf3ce44SJohn Forte #ifdef FCIO_SUPPORT 720*fcf3ce44SJohn Forte 721*fcf3ce44SJohn Forte emlxs_table_t emlxs_fcio_table[] = 722*fcf3ce44SJohn Forte { 723*fcf3ce44SJohn Forte {FCIO_GET_NUM_DEVS, "GET_NUM_DEVS"}, 724*fcf3ce44SJohn Forte {FCIO_GET_DEV_LIST, "GET_DEV_LIST"}, 725*fcf3ce44SJohn Forte {FCIO_GET_SYM_PNAME, "GET_SYM_PNAME"}, 726*fcf3ce44SJohn Forte {FCIO_GET_SYM_NNAME, "GET_SYM_NNAME"}, 727*fcf3ce44SJohn Forte {FCIO_SET_SYM_PNAME, "SET_SYM_PNAME"}, 728*fcf3ce44SJohn Forte {FCIO_SET_SYM_NNAME, "SET_SYM_NNAME"}, 729*fcf3ce44SJohn Forte {FCIO_GET_LOGI_PARAMS, "GET_LOGI_PARAMS"}, 730*fcf3ce44SJohn Forte {FCIO_DEV_LOGIN, "DEV_LOGIN"}, 731*fcf3ce44SJohn Forte {FCIO_DEV_LOGOUT, "DEV_LOGOUT"}, 732*fcf3ce44SJohn Forte {FCIO_GET_STATE, "GET_STATE"}, 733*fcf3ce44SJohn Forte {FCIO_DEV_REMOVE, "DEV_REMOVE"}, 734*fcf3ce44SJohn Forte {FCIO_GET_FCODE_REV, "GET_FCODE_REV"}, 735*fcf3ce44SJohn Forte {FCIO_GET_FW_REV, "GET_FW_REV"}, 736*fcf3ce44SJohn Forte {FCIO_GET_DUMP_SIZE, "GET_DUMP_SIZE"}, 737*fcf3ce44SJohn Forte {FCIO_FORCE_DUMP, "FORCE_DUMP"}, 738*fcf3ce44SJohn Forte {FCIO_GET_DUMP, "GET_DUMP"}, 739*fcf3ce44SJohn Forte {FCIO_GET_TOPOLOGY, "GET_TOPOLOGY"}, 740*fcf3ce44SJohn Forte {FCIO_RESET_LINK, "RESET_LINK"}, 741*fcf3ce44SJohn Forte {FCIO_RESET_HARD, "RESET_HARD"}, 742*fcf3ce44SJohn Forte {FCIO_RESET_HARD_CORE, "RESET_HARD_CORE"}, 743*fcf3ce44SJohn Forte {FCIO_DIAG, "DIAG"}, 744*fcf3ce44SJohn Forte {FCIO_NS, "NS"}, 745*fcf3ce44SJohn Forte {FCIO_DOWNLOAD_FW, "DOWNLOAD_FW"}, 746*fcf3ce44SJohn Forte {FCIO_GET_HOST_PARAMS, "GET_HOST_PARAMS"}, 747*fcf3ce44SJohn Forte {FCIO_LINK_STATUS, "LINK_STATUS"}, 748*fcf3ce44SJohn Forte {FCIO_DOWNLOAD_FCODE, "DOWNLOAD_FCODE"}, 749*fcf3ce44SJohn Forte {FCIO_GET_NODE_ID, "GET_NODE_ID"}, 750*fcf3ce44SJohn Forte {FCIO_SET_NODE_ID, "SET_NODE_ID"}, 751*fcf3ce44SJohn Forte {FCIO_SEND_NODE_ID, "SEND_NODE_ID"}, 752*fcf3ce44SJohn Forte {FCIO_GET_ADAPTER_ATTRIBUTES, "GET_ADAPTER_ATTRIBUTES"}, 753*fcf3ce44SJohn Forte {FCIO_GET_OTHER_ADAPTER_PORTS, "GET_OTHER_ADAPTER_PORTS"}, 754*fcf3ce44SJohn Forte {FCIO_GET_ADAPTER_PORT_ATTRIBUTES, "GET_ADAPTER_PORT_ATTRIBUTES"}, 755*fcf3ce44SJohn Forte {FCIO_GET_DISCOVERED_PORT_ATTRIBUTES, "GET_DISCOVERED_PORT_ATTRIBUTES"}, 756*fcf3ce44SJohn Forte {FCIO_GET_PORT_ATTRIBUTES, "GET_PORT_ATTRIBUTES"}, 757*fcf3ce44SJohn Forte {FCIO_GET_ADAPTER_PORT_STATS, "GET_ADAPTER_PORT_STATS"}, 758*fcf3ce44SJohn Forte 759*fcf3ce44SJohn Forte }; /* emlxs_fcio_table */ 760*fcf3ce44SJohn Forte 761*fcf3ce44SJohn Forte 762*fcf3ce44SJohn Forte extern char * 763*fcf3ce44SJohn Forte emlxs_fcio_xlate(uint16_t cmd) 764*fcf3ce44SJohn Forte { 765*fcf3ce44SJohn Forte static char buffer[32]; 766*fcf3ce44SJohn Forte uint32_t i; 767*fcf3ce44SJohn Forte uint32_t count; 768*fcf3ce44SJohn Forte 769*fcf3ce44SJohn Forte count = sizeof (emlxs_fcio_table) / sizeof (emlxs_table_t); 770*fcf3ce44SJohn Forte for (i = 0; i < count; i++) { 771*fcf3ce44SJohn Forte if (cmd == emlxs_fcio_table[i].code) { 772*fcf3ce44SJohn Forte return (emlxs_fcio_table[i].string); 773*fcf3ce44SJohn Forte } 774*fcf3ce44SJohn Forte } 775*fcf3ce44SJohn Forte 776*fcf3ce44SJohn Forte (void) sprintf(buffer, "Cmd=0x%x", cmd); 777*fcf3ce44SJohn Forte return (buffer); 778*fcf3ce44SJohn Forte 779*fcf3ce44SJohn Forte } /* emlxs_fcio_xlate() */ 780*fcf3ce44SJohn Forte 781*fcf3ce44SJohn Forte 782*fcf3ce44SJohn Forte static int32_t 783*fcf3ce44SJohn Forte emlxs_fcio_manage(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 784*fcf3ce44SJohn Forte { 785*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 786*fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 787*fcf3ce44SJohn Forte int rval = 0; 788*fcf3ce44SJohn Forte fcio_t local_fcio; 789*fcf3ce44SJohn Forte fcio_t *fcio = &local_fcio; 790*fcf3ce44SJohn Forte emlxs_vpd_t *vpd = &VPD; 791*fcf3ce44SJohn Forte fc_hba_port_attributes_t *port_attrs; 792*fcf3ce44SJohn Forte emlxs_node_t *ndlp; 793*fcf3ce44SJohn Forte uint8_t *wwpn; 794*fcf3ce44SJohn Forte 795*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 796*fcf3ce44SJohn Forte "%s: %s: requested.", 797*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), emlxs_fcio_xlate(dfc->data1)); 798*fcf3ce44SJohn Forte 799*fcf3ce44SJohn Forte if (!dfc->buf4 || !dfc->buf4_size) { 800*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 801*fcf3ce44SJohn Forte "%s: %s: Null buffer4 found.", 802*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 803*fcf3ce44SJohn Forte emlxs_fcio_xlate(dfc->data1)); 804*fcf3ce44SJohn Forte 805*fcf3ce44SJohn Forte return (EFAULT); 806*fcf3ce44SJohn Forte } 807*fcf3ce44SJohn Forte if (dfc->buf4_size < sizeof (uint32_t)) { 808*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 809*fcf3ce44SJohn Forte "%s: %s: Buffer4 too small. (size=%d)", 810*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), emlxs_fcio_xlate(dfc->data1), 811*fcf3ce44SJohn Forte dfc->buf4_size); 812*fcf3ce44SJohn Forte 813*fcf3ce44SJohn Forte return (EFAULT); 814*fcf3ce44SJohn Forte } 815*fcf3ce44SJohn Forte /* Map DFC to FCIO */ 816*fcf3ce44SJohn Forte bzero(fcio, sizeof (fcio_t)); 817*fcf3ce44SJohn Forte fcio->fcio_flags = dfc->flag; 818*fcf3ce44SJohn Forte fcio->fcio_cmd = dfc->data1; 819*fcf3ce44SJohn Forte fcio->fcio_cmd_flags = dfc->data2; 820*fcf3ce44SJohn Forte fcio->fcio_xfer = dfc->data3; 821*fcf3ce44SJohn Forte fcio->fcio_errno = FC_FAILURE; /* dfc->buf4 on return */ 822*fcf3ce44SJohn Forte 823*fcf3ce44SJohn Forte if (dfc->buf1_size && dfc->buf1) { 824*fcf3ce44SJohn Forte fcio->fcio_ilen = dfc->buf1_size; 825*fcf3ce44SJohn Forte fcio->fcio_ibuf = kmem_zalloc(dfc->buf1_size, KM_SLEEP); 826*fcf3ce44SJohn Forte 827*fcf3ce44SJohn Forte if (!fcio->fcio_ibuf) { 828*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 829*fcf3ce44SJohn Forte "%s: %s: Unable to allocate ibuf. (size=%d)", 830*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 831*fcf3ce44SJohn Forte emlxs_fcio_xlate(dfc->data1), 832*fcf3ce44SJohn Forte fcio->fcio_ilen); 833*fcf3ce44SJohn Forte 834*fcf3ce44SJohn Forte rval = EFAULT; 835*fcf3ce44SJohn Forte goto done; 836*fcf3ce44SJohn Forte } 837*fcf3ce44SJohn Forte if (ddi_copyin(dfc->buf1, fcio->fcio_ibuf, 838*fcf3ce44SJohn Forte fcio->fcio_ilen, mode)) { 839*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 840*fcf3ce44SJohn Forte "%s: %s: ddi_copyin failed. (size=%d)", 841*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 842*fcf3ce44SJohn Forte emlxs_fcio_xlate(dfc->data1), 843*fcf3ce44SJohn Forte fcio->fcio_ilen); 844*fcf3ce44SJohn Forte 845*fcf3ce44SJohn Forte rval = EFAULT; 846*fcf3ce44SJohn Forte goto done; 847*fcf3ce44SJohn Forte } 848*fcf3ce44SJohn Forte } 849*fcf3ce44SJohn Forte if (dfc->buf2_size && dfc->buf2) { 850*fcf3ce44SJohn Forte fcio->fcio_olen = dfc->buf2_size; 851*fcf3ce44SJohn Forte fcio->fcio_obuf = kmem_zalloc(dfc->buf2_size, KM_SLEEP); 852*fcf3ce44SJohn Forte 853*fcf3ce44SJohn Forte if (!fcio->fcio_obuf) { 854*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 855*fcf3ce44SJohn Forte "%s: %s: Unable to allocate obuf. (size=%d)", 856*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 857*fcf3ce44SJohn Forte emlxs_fcio_xlate(dfc->data1), 858*fcf3ce44SJohn Forte fcio->fcio_olen); 859*fcf3ce44SJohn Forte 860*fcf3ce44SJohn Forte rval = EFAULT; 861*fcf3ce44SJohn Forte goto done; 862*fcf3ce44SJohn Forte } 863*fcf3ce44SJohn Forte if (ddi_copyin(dfc->buf2, fcio->fcio_obuf, 864*fcf3ce44SJohn Forte fcio->fcio_olen, mode)) { 865*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 866*fcf3ce44SJohn Forte "%s: %s: ddi_copyin failed. (size=%d)", 867*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 868*fcf3ce44SJohn Forte emlxs_fcio_xlate(dfc->data1), 869*fcf3ce44SJohn Forte fcio->fcio_olen); 870*fcf3ce44SJohn Forte 871*fcf3ce44SJohn Forte rval = EFAULT; 872*fcf3ce44SJohn Forte goto done; 873*fcf3ce44SJohn Forte } 874*fcf3ce44SJohn Forte } 875*fcf3ce44SJohn Forte if (dfc->buf3_size && dfc->buf3) { 876*fcf3ce44SJohn Forte fcio->fcio_alen = dfc->buf3_size; 877*fcf3ce44SJohn Forte fcio->fcio_abuf = kmem_zalloc(dfc->buf3_size, KM_SLEEP); 878*fcf3ce44SJohn Forte 879*fcf3ce44SJohn Forte if (!fcio->fcio_abuf) { 880*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 881*fcf3ce44SJohn Forte "%s: %s: Unable to allocate abuf. (size=%d)", 882*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 883*fcf3ce44SJohn Forte emlxs_fcio_xlate(dfc->data1), 884*fcf3ce44SJohn Forte fcio->fcio_alen); 885*fcf3ce44SJohn Forte 886*fcf3ce44SJohn Forte rval = EFAULT; 887*fcf3ce44SJohn Forte goto done; 888*fcf3ce44SJohn Forte } 889*fcf3ce44SJohn Forte if (ddi_copyin(dfc->buf3, fcio->fcio_abuf, 890*fcf3ce44SJohn Forte fcio->fcio_alen, mode)) { 891*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 892*fcf3ce44SJohn Forte "%s: %s: ddi_copyin failed. (size=%d)", 893*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 894*fcf3ce44SJohn Forte emlxs_fcio_xlate(dfc->data1), 895*fcf3ce44SJohn Forte fcio->fcio_alen); 896*fcf3ce44SJohn Forte 897*fcf3ce44SJohn Forte rval = EFAULT; 898*fcf3ce44SJohn Forte goto done; 899*fcf3ce44SJohn Forte } 900*fcf3ce44SJohn Forte } 901*fcf3ce44SJohn Forte /* FCIO command */ 902*fcf3ce44SJohn Forte switch (fcio->fcio_cmd) { 903*fcf3ce44SJohn Forte case FCIO_DIAG: 904*fcf3ce44SJohn Forte { 905*fcf3ce44SJohn Forte fc_fca_pm_t pm; 906*fcf3ce44SJohn Forte /* uint32_t ret; */ 907*fcf3ce44SJohn Forte 908*fcf3ce44SJohn Forte bzero((caddr_t)&pm, sizeof (fc_fca_pm_t)); 909*fcf3ce44SJohn Forte 910*fcf3ce44SJohn Forte pm.pm_cmd_len = fcio->fcio_ilen; 911*fcf3ce44SJohn Forte pm.pm_cmd_buf = fcio->fcio_ibuf; 912*fcf3ce44SJohn Forte pm.pm_data_len = fcio->fcio_alen; 913*fcf3ce44SJohn Forte pm.pm_data_buf = fcio->fcio_abuf; 914*fcf3ce44SJohn Forte pm.pm_stat_len = fcio->fcio_olen; 915*fcf3ce44SJohn Forte pm.pm_stat_buf = fcio->fcio_obuf; 916*fcf3ce44SJohn Forte pm.pm_cmd_code = FC_PORT_DIAG; 917*fcf3ce44SJohn Forte pm.pm_cmd_flags = fcio->fcio_cmd_flags; 918*fcf3ce44SJohn Forte 919*fcf3ce44SJohn Forte rval = emlxs_port_manage(port, &pm); 920*fcf3ce44SJohn Forte 921*fcf3ce44SJohn Forte if (rval != FC_SUCCESS) { 922*fcf3ce44SJohn Forte fcio->fcio_errno = rval; 923*fcf3ce44SJohn Forte 924*fcf3ce44SJohn Forte if (rval == FC_INVALID_REQUEST) { 925*fcf3ce44SJohn Forte rval = ENOTTY; 926*fcf3ce44SJohn Forte } else { 927*fcf3ce44SJohn Forte rval = EIO; 928*fcf3ce44SJohn Forte } 929*fcf3ce44SJohn Forte } 930*fcf3ce44SJohn Forte break; 931*fcf3ce44SJohn Forte } 932*fcf3ce44SJohn Forte 933*fcf3ce44SJohn Forte case FCIO_GET_HOST_PARAMS: 934*fcf3ce44SJohn Forte { 935*fcf3ce44SJohn Forte fc_port_dev_t *port_dev; 936*fcf3ce44SJohn Forte uint32_t i; 937*fcf3ce44SJohn Forte 938*fcf3ce44SJohn Forte if (fcio->fcio_xfer != FCIO_XFER_READ || 939*fcf3ce44SJohn Forte fcio->fcio_olen != sizeof (fc_port_dev_t)) { 940*fcf3ce44SJohn Forte rval = EINVAL; 941*fcf3ce44SJohn Forte break; 942*fcf3ce44SJohn Forte } 943*fcf3ce44SJohn Forte port_dev = (fc_port_dev_t *)fcio->fcio_obuf; 944*fcf3ce44SJohn Forte port_dev->dev_did.port_id = port->did; 945*fcf3ce44SJohn Forte port_dev->dev_hard_addr.hard_addr = 946*fcf3ce44SJohn Forte cfg[CFG_ASSIGN_ALPA].current; 947*fcf3ce44SJohn Forte port_dev->dev_state = port->ulp_statec; 948*fcf3ce44SJohn Forte bcopy((caddr_t)&port->wwpn, 949*fcf3ce44SJohn Forte (caddr_t)&port_dev->dev_pwwn, 8); 950*fcf3ce44SJohn Forte bcopy((caddr_t)&port->wwnn, 951*fcf3ce44SJohn Forte (caddr_t)&port_dev->dev_nwwn, 8); 952*fcf3ce44SJohn Forte 953*fcf3ce44SJohn Forte if (hba->topology == TOPOLOGY_LOOP) { 954*fcf3ce44SJohn Forte for (i = 0; i < port->alpa_map[0]; i++) { 955*fcf3ce44SJohn Forte if (port->alpa_map[i+1] == port->did) { 956*fcf3ce44SJohn Forte PRIV_LILP_POSIT(port_dev) = 957*fcf3ce44SJohn Forte (uint8_t)(i & 0xff); 958*fcf3ce44SJohn Forte break; 959*fcf3ce44SJohn Forte } 960*fcf3ce44SJohn Forte } 961*fcf3ce44SJohn Forte } 962*fcf3ce44SJohn Forte port_dev->dev_type[0] = SWAP_DATA32(0x00000120); 963*fcf3ce44SJohn Forte port_dev->dev_type[1] = SWAP_DATA32(0x00000001); 964*fcf3ce44SJohn Forte 965*fcf3ce44SJohn Forte break; 966*fcf3ce44SJohn Forte } 967*fcf3ce44SJohn Forte 968*fcf3ce44SJohn Forte case FCIO_RESET_LINK: 969*fcf3ce44SJohn Forte { 970*fcf3ce44SJohn Forte uint8_t null_wwn[8]; 971*fcf3ce44SJohn Forte 972*fcf3ce44SJohn Forte if (fcio->fcio_xfer != FCIO_XFER_WRITE || 973*fcf3ce44SJohn Forte fcio->fcio_ilen != 8) { 974*fcf3ce44SJohn Forte rval = EINVAL; 975*fcf3ce44SJohn Forte break; 976*fcf3ce44SJohn Forte } 977*fcf3ce44SJohn Forte bzero(null_wwn, 8); 978*fcf3ce44SJohn Forte 979*fcf3ce44SJohn Forte if (bcmp((uint8_t *)fcio->fcio_ibuf, 980*fcf3ce44SJohn Forte null_wwn, 8) == 0) { 981*fcf3ce44SJohn Forte rval = emlxs_reset(port, FC_FCA_LINK_RESET); 982*fcf3ce44SJohn Forte 983*fcf3ce44SJohn Forte if (rval != FC_SUCCESS) { 984*fcf3ce44SJohn Forte fcio->fcio_errno = rval; 985*fcf3ce44SJohn Forte rval = EIO; 986*fcf3ce44SJohn Forte } 987*fcf3ce44SJohn Forte } else { 988*fcf3ce44SJohn Forte rval = ENOTSUP; 989*fcf3ce44SJohn Forte } 990*fcf3ce44SJohn Forte break; 991*fcf3ce44SJohn Forte } 992*fcf3ce44SJohn Forte 993*fcf3ce44SJohn Forte case FCIO_RESET_HARD: 994*fcf3ce44SJohn Forte case FCIO_RESET_HARD_CORE: 995*fcf3ce44SJohn Forte { 996*fcf3ce44SJohn Forte rval = emlxs_reset(port, FC_FCA_RESET); 997*fcf3ce44SJohn Forte 998*fcf3ce44SJohn Forte if (rval != FC_SUCCESS) { 999*fcf3ce44SJohn Forte fcio->fcio_errno = rval; 1000*fcf3ce44SJohn Forte rval = EIO; 1001*fcf3ce44SJohn Forte } 1002*fcf3ce44SJohn Forte break; 1003*fcf3ce44SJohn Forte } 1004*fcf3ce44SJohn Forte 1005*fcf3ce44SJohn Forte case FCIO_DOWNLOAD_FW: 1006*fcf3ce44SJohn Forte { 1007*fcf3ce44SJohn Forte fc_fca_pm_t pm; 1008*fcf3ce44SJohn Forte 1009*fcf3ce44SJohn Forte if (fcio->fcio_xfer != FCIO_XFER_WRITE || 1010*fcf3ce44SJohn Forte fcio->fcio_ilen <= 0) { 1011*fcf3ce44SJohn Forte rval = EINVAL; 1012*fcf3ce44SJohn Forte break; 1013*fcf3ce44SJohn Forte } 1014*fcf3ce44SJohn Forte bzero((caddr_t)&pm, sizeof (pm)); 1015*fcf3ce44SJohn Forte 1016*fcf3ce44SJohn Forte pm.pm_cmd_flags = FC_FCA_PM_WRITE; 1017*fcf3ce44SJohn Forte pm.pm_cmd_code = FC_PORT_DOWNLOAD_FW; 1018*fcf3ce44SJohn Forte pm.pm_data_len = fcio->fcio_ilen; 1019*fcf3ce44SJohn Forte pm.pm_data_buf = fcio->fcio_ibuf; 1020*fcf3ce44SJohn Forte 1021*fcf3ce44SJohn Forte rval = emlxs_port_manage(port, &pm); 1022*fcf3ce44SJohn Forte 1023*fcf3ce44SJohn Forte if (rval != FC_SUCCESS) { 1024*fcf3ce44SJohn Forte fcio->fcio_errno = rval; 1025*fcf3ce44SJohn Forte rval = EIO; 1026*fcf3ce44SJohn Forte } 1027*fcf3ce44SJohn Forte break; 1028*fcf3ce44SJohn Forte } 1029*fcf3ce44SJohn Forte 1030*fcf3ce44SJohn Forte case FCIO_GET_FW_REV: 1031*fcf3ce44SJohn Forte { 1032*fcf3ce44SJohn Forte fc_fca_pm_t pm; 1033*fcf3ce44SJohn Forte 1034*fcf3ce44SJohn Forte if (fcio->fcio_xfer != FCIO_XFER_READ || 1035*fcf3ce44SJohn Forte fcio->fcio_olen < FC_FW_REV_SIZE) { 1036*fcf3ce44SJohn Forte rval = EINVAL; 1037*fcf3ce44SJohn Forte break; 1038*fcf3ce44SJohn Forte } 1039*fcf3ce44SJohn Forte bzero((caddr_t)&pm, sizeof (pm)); 1040*fcf3ce44SJohn Forte 1041*fcf3ce44SJohn Forte pm.pm_cmd_flags = FC_FCA_PM_READ; 1042*fcf3ce44SJohn Forte pm.pm_cmd_code = FC_PORT_GET_FW_REV; 1043*fcf3ce44SJohn Forte pm.pm_data_len = fcio->fcio_olen; 1044*fcf3ce44SJohn Forte pm.pm_data_buf = fcio->fcio_obuf; 1045*fcf3ce44SJohn Forte 1046*fcf3ce44SJohn Forte rval = emlxs_port_manage(port, &pm); 1047*fcf3ce44SJohn Forte 1048*fcf3ce44SJohn Forte if (rval != FC_SUCCESS) { 1049*fcf3ce44SJohn Forte fcio->fcio_errno = rval; 1050*fcf3ce44SJohn Forte rval = EIO; 1051*fcf3ce44SJohn Forte } 1052*fcf3ce44SJohn Forte break; 1053*fcf3ce44SJohn Forte } 1054*fcf3ce44SJohn Forte 1055*fcf3ce44SJohn Forte case FCIO_GET_FCODE_REV: 1056*fcf3ce44SJohn Forte { 1057*fcf3ce44SJohn Forte fc_fca_pm_t pm; 1058*fcf3ce44SJohn Forte 1059*fcf3ce44SJohn Forte if (fcio->fcio_xfer != FCIO_XFER_READ || 1060*fcf3ce44SJohn Forte fcio->fcio_olen < FC_FCODE_REV_SIZE) { 1061*fcf3ce44SJohn Forte rval = EINVAL; 1062*fcf3ce44SJohn Forte break; 1063*fcf3ce44SJohn Forte } 1064*fcf3ce44SJohn Forte bzero((caddr_t)&pm, sizeof (pm)); 1065*fcf3ce44SJohn Forte 1066*fcf3ce44SJohn Forte pm.pm_cmd_flags = FC_FCA_PM_READ; 1067*fcf3ce44SJohn Forte pm.pm_cmd_code = FC_PORT_GET_FCODE_REV; 1068*fcf3ce44SJohn Forte pm.pm_data_len = fcio->fcio_olen; 1069*fcf3ce44SJohn Forte pm.pm_data_buf = fcio->fcio_obuf; 1070*fcf3ce44SJohn Forte 1071*fcf3ce44SJohn Forte rval = emlxs_port_manage(port, &pm); 1072*fcf3ce44SJohn Forte 1073*fcf3ce44SJohn Forte if (rval != FC_SUCCESS) { 1074*fcf3ce44SJohn Forte fcio->fcio_errno = rval; 1075*fcf3ce44SJohn Forte rval = EIO; 1076*fcf3ce44SJohn Forte } 1077*fcf3ce44SJohn Forte break; 1078*fcf3ce44SJohn Forte } 1079*fcf3ce44SJohn Forte 1080*fcf3ce44SJohn Forte case FCIO_DOWNLOAD_FCODE: 1081*fcf3ce44SJohn Forte { 1082*fcf3ce44SJohn Forte fc_fca_pm_t pm; 1083*fcf3ce44SJohn Forte 1084*fcf3ce44SJohn Forte if (fcio->fcio_xfer != FCIO_XFER_WRITE || 1085*fcf3ce44SJohn Forte fcio->fcio_ilen <= 0) { 1086*fcf3ce44SJohn Forte rval = EINVAL; 1087*fcf3ce44SJohn Forte break; 1088*fcf3ce44SJohn Forte } 1089*fcf3ce44SJohn Forte bzero((caddr_t)&pm, sizeof (pm)); 1090*fcf3ce44SJohn Forte 1091*fcf3ce44SJohn Forte pm.pm_cmd_flags = FC_FCA_PM_WRITE; 1092*fcf3ce44SJohn Forte pm.pm_cmd_code = FC_PORT_DOWNLOAD_FCODE; 1093*fcf3ce44SJohn Forte pm.pm_data_len = fcio->fcio_ilen; 1094*fcf3ce44SJohn Forte pm.pm_data_buf = fcio->fcio_ibuf; 1095*fcf3ce44SJohn Forte 1096*fcf3ce44SJohn Forte rval = emlxs_port_manage(port, &pm); 1097*fcf3ce44SJohn Forte 1098*fcf3ce44SJohn Forte if (rval != FC_SUCCESS) { 1099*fcf3ce44SJohn Forte fcio->fcio_errno = rval; 1100*fcf3ce44SJohn Forte rval = EIO; 1101*fcf3ce44SJohn Forte } 1102*fcf3ce44SJohn Forte break; 1103*fcf3ce44SJohn Forte } 1104*fcf3ce44SJohn Forte 1105*fcf3ce44SJohn Forte case FCIO_GET_ADAPTER_ATTRIBUTES: 1106*fcf3ce44SJohn Forte { 1107*fcf3ce44SJohn Forte fc_hba_adapter_attributes_t *hba_attrs; 1108*fcf3ce44SJohn Forte 1109*fcf3ce44SJohn Forte if (fcio->fcio_xfer != FCIO_XFER_READ || 1110*fcf3ce44SJohn Forte fcio->fcio_olen < 1111*fcf3ce44SJohn Forte sizeof (fc_hba_adapter_attributes_t)) { 1112*fcf3ce44SJohn Forte rval = EINVAL; 1113*fcf3ce44SJohn Forte break; 1114*fcf3ce44SJohn Forte } 1115*fcf3ce44SJohn Forte hba_attrs = 1116*fcf3ce44SJohn Forte (fc_hba_adapter_attributes_t *)fcio->fcio_obuf; 1117*fcf3ce44SJohn Forte 1118*fcf3ce44SJohn Forte hba_attrs->version = FC_HBA_ADAPTER_ATTRIBUTES_VERSION; 1119*fcf3ce44SJohn Forte (void) strncpy(hba_attrs->Manufacturer, 1120*fcf3ce44SJohn Forte "Emulex", sizeof (hba_attrs->Manufacturer)); 1121*fcf3ce44SJohn Forte (void) strncpy(hba_attrs->SerialNumber, vpd->serial_num, 1122*fcf3ce44SJohn Forte sizeof (hba_attrs->SerialNumber)); 1123*fcf3ce44SJohn Forte (void) strncpy(hba_attrs->Model, hba->model_info.model, 1124*fcf3ce44SJohn Forte sizeof (hba_attrs->Model)); 1125*fcf3ce44SJohn Forte (void) strncpy(hba_attrs->ModelDescription, 1126*fcf3ce44SJohn Forte hba->model_info.model_desc, 1127*fcf3ce44SJohn Forte sizeof (hba_attrs->ModelDescription)); 1128*fcf3ce44SJohn Forte bcopy((caddr_t)&port->wwnn, 1129*fcf3ce44SJohn Forte (caddr_t)&hba_attrs->NodeWWN, 8); 1130*fcf3ce44SJohn Forte (void) strncpy((caddr_t)hba_attrs->NodeSymbolicName, 1131*fcf3ce44SJohn Forte (caddr_t)port->snn, 1132*fcf3ce44SJohn Forte sizeof (hba_attrs->NodeSymbolicName)); 1133*fcf3ce44SJohn Forte (void) sprintf(hba_attrs->HardwareVersion, "%x", 1134*fcf3ce44SJohn Forte vpd->biuRev); 1135*fcf3ce44SJohn Forte (void) sprintf(hba_attrs->DriverVersion, "%s (%s)", 1136*fcf3ce44SJohn Forte emlxs_version, emlxs_revision); 1137*fcf3ce44SJohn Forte (void) strncpy(hba_attrs->OptionROMVersion, 1138*fcf3ce44SJohn Forte vpd->fcode_version, 1139*fcf3ce44SJohn Forte sizeof (hba_attrs->OptionROMVersion)); 1140*fcf3ce44SJohn Forte (void) sprintf(hba_attrs->FirmwareVersion, "%s (%s)", 1141*fcf3ce44SJohn Forte vpd->fw_version, vpd->fw_label); 1142*fcf3ce44SJohn Forte (void) strncpy(hba_attrs->DriverName, DRIVER_NAME, 1143*fcf3ce44SJohn Forte sizeof (hba_attrs->DriverName)); 1144*fcf3ce44SJohn Forte hba_attrs->VendorSpecificID = 1145*fcf3ce44SJohn Forte ((hba->model_info.device_id << 16) | 1146*fcf3ce44SJohn Forte PCI_VENDOR_ID_EMULEX); 1147*fcf3ce44SJohn Forte hba_attrs->NumberOfPorts = hba->num_of_ports; 1148*fcf3ce44SJohn Forte 1149*fcf3ce44SJohn Forte break; 1150*fcf3ce44SJohn Forte } 1151*fcf3ce44SJohn Forte 1152*fcf3ce44SJohn Forte case FCIO_GET_ADAPTER_PORT_ATTRIBUTES: 1153*fcf3ce44SJohn Forte { 1154*fcf3ce44SJohn Forte fc_hba_port_attributes_t *port_attrs; 1155*fcf3ce44SJohn Forte uint32_t value1; 1156*fcf3ce44SJohn Forte uint32_t value2; 1157*fcf3ce44SJohn Forte 1158*fcf3ce44SJohn Forte if (fcio->fcio_xfer != FCIO_XFER_READ || 1159*fcf3ce44SJohn Forte fcio->fcio_olen < 1160*fcf3ce44SJohn Forte sizeof (fc_hba_port_attributes_t)) { 1161*fcf3ce44SJohn Forte rval = EINVAL; 1162*fcf3ce44SJohn Forte break; 1163*fcf3ce44SJohn Forte } 1164*fcf3ce44SJohn Forte port_attrs = 1165*fcf3ce44SJohn Forte (fc_hba_port_attributes_t *)fcio->fcio_obuf; 1166*fcf3ce44SJohn Forte 1167*fcf3ce44SJohn Forte port_attrs->version = FC_HBA_PORT_ATTRIBUTES_VERSION; 1168*fcf3ce44SJohn Forte port_attrs->lastChange = 0; 1169*fcf3ce44SJohn Forte port_attrs->fp_minor = 0; 1170*fcf3ce44SJohn Forte bcopy((caddr_t)&port->wwnn, 1171*fcf3ce44SJohn Forte (caddr_t)&port_attrs->NodeWWN, 8); 1172*fcf3ce44SJohn Forte bcopy((caddr_t)&port->wwpn, 1173*fcf3ce44SJohn Forte (caddr_t)&port_attrs->PortWWN, 8); 1174*fcf3ce44SJohn Forte 1175*fcf3ce44SJohn Forte if (hba->state <= FC_LINK_DOWN) { 1176*fcf3ce44SJohn Forte /* port_attrs->PortFcId */ 1177*fcf3ce44SJohn Forte /* port_attrs->PortType */ 1178*fcf3ce44SJohn Forte /* port_attrs->PortSpeed */ 1179*fcf3ce44SJohn Forte /* port_attrs->FabricName */ 1180*fcf3ce44SJohn Forte port_attrs->PortState = 1181*fcf3ce44SJohn Forte FC_HBA_PORTSTATE_OFFLINE; 1182*fcf3ce44SJohn Forte } else { 1183*fcf3ce44SJohn Forte port_attrs->PortFcId = port->did; 1184*fcf3ce44SJohn Forte port_attrs->PortState = 1185*fcf3ce44SJohn Forte FC_HBA_PORTSTATE_ONLINE; 1186*fcf3ce44SJohn Forte 1187*fcf3ce44SJohn Forte if (hba->topology == TOPOLOGY_LOOP) { 1188*fcf3ce44SJohn Forte port_attrs->PortType = 1189*fcf3ce44SJohn Forte FC_HBA_PORTTYPE_LPORT; 1190*fcf3ce44SJohn Forte } else { 1191*fcf3ce44SJohn Forte port_attrs->PortType = 1192*fcf3ce44SJohn Forte FC_HBA_PORTTYPE_NPORT; 1193*fcf3ce44SJohn Forte } 1194*fcf3ce44SJohn Forte 1195*fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, Fabric_DID); 1196*fcf3ce44SJohn Forte 1197*fcf3ce44SJohn Forte if (ndlp) { 1198*fcf3ce44SJohn Forte bcopy(&ndlp->nlp_portname, (caddr_t) 1199*fcf3ce44SJohn Forte &port_attrs->FabricName, 1200*fcf3ce44SJohn Forte sizeof (port_attrs->FabricName)); 1201*fcf3ce44SJohn Forte } 1202*fcf3ce44SJohn Forte switch (hba->linkspeed) { 1203*fcf3ce44SJohn Forte case 0: 1204*fcf3ce44SJohn Forte port_attrs->PortSpeed = 1205*fcf3ce44SJohn Forte HBA_PORTSPEED_1GBIT; 1206*fcf3ce44SJohn Forte break; 1207*fcf3ce44SJohn Forte case LA_1GHZ_LINK: 1208*fcf3ce44SJohn Forte port_attrs->PortSpeed = 1209*fcf3ce44SJohn Forte HBA_PORTSPEED_1GBIT; 1210*fcf3ce44SJohn Forte break; 1211*fcf3ce44SJohn Forte case LA_2GHZ_LINK: 1212*fcf3ce44SJohn Forte port_attrs->PortSpeed = 1213*fcf3ce44SJohn Forte HBA_PORTSPEED_2GBIT; 1214*fcf3ce44SJohn Forte break; 1215*fcf3ce44SJohn Forte case LA_4GHZ_LINK: 1216*fcf3ce44SJohn Forte port_attrs->PortSpeed = 1217*fcf3ce44SJohn Forte HBA_PORTSPEED_4GBIT; 1218*fcf3ce44SJohn Forte break; 1219*fcf3ce44SJohn Forte case LA_8GHZ_LINK: 1220*fcf3ce44SJohn Forte port_attrs->PortSpeed = 1221*fcf3ce44SJohn Forte HBA_PORTSPEED_8GBIT; 1222*fcf3ce44SJohn Forte break; 1223*fcf3ce44SJohn Forte case LA_10GHZ_LINK: 1224*fcf3ce44SJohn Forte port_attrs->PortSpeed = 1225*fcf3ce44SJohn Forte HBA_PORTSPEED_10GBIT; 1226*fcf3ce44SJohn Forte break; 1227*fcf3ce44SJohn Forte default: 1228*fcf3ce44SJohn Forte port_attrs->PortSpeed = 1229*fcf3ce44SJohn Forte HBA_PORTSPEED_UNKNOWN; 1230*fcf3ce44SJohn Forte 1231*fcf3ce44SJohn Forte } 1232*fcf3ce44SJohn Forte } 1233*fcf3ce44SJohn Forte 1234*fcf3ce44SJohn Forte port_attrs->PortSupportedClassofService = 1235*fcf3ce44SJohn Forte SWAP_DATA32(FC_NS_CLASS3); 1236*fcf3ce44SJohn Forte (void) strncpy((caddr_t)port_attrs->PortSymbolicName, 1237*fcf3ce44SJohn Forte (caddr_t)port->spn, 1238*fcf3ce44SJohn Forte sizeof (port_attrs->PortSymbolicName)); 1239*fcf3ce44SJohn Forte 1240*fcf3ce44SJohn Forte /* Set the hba speed limit */ 1241*fcf3ce44SJohn Forte if (vpd->link_speed & LMT_10GB_CAPABLE) { 1242*fcf3ce44SJohn Forte port_attrs->PortSupportedSpeed |= 1243*fcf3ce44SJohn Forte FC_HBA_PORTSPEED_10GBIT; 1244*fcf3ce44SJohn Forte } 1245*fcf3ce44SJohn Forte if (vpd->link_speed & LMT_8GB_CAPABLE) { 1246*fcf3ce44SJohn Forte port_attrs->PortSupportedSpeed |= 1247*fcf3ce44SJohn Forte FC_HBA_PORTSPEED_8GBIT; 1248*fcf3ce44SJohn Forte } 1249*fcf3ce44SJohn Forte if (vpd->link_speed & LMT_4GB_CAPABLE) { 1250*fcf3ce44SJohn Forte port_attrs->PortSupportedSpeed |= 1251*fcf3ce44SJohn Forte FC_HBA_PORTSPEED_4GBIT; 1252*fcf3ce44SJohn Forte } 1253*fcf3ce44SJohn Forte if (vpd->link_speed & LMT_2GB_CAPABLE) { 1254*fcf3ce44SJohn Forte port_attrs->PortSupportedSpeed |= 1255*fcf3ce44SJohn Forte FC_HBA_PORTSPEED_2GBIT; 1256*fcf3ce44SJohn Forte } 1257*fcf3ce44SJohn Forte if (vpd->link_speed & LMT_1GB_CAPABLE) { 1258*fcf3ce44SJohn Forte port_attrs->PortSupportedSpeed |= 1259*fcf3ce44SJohn Forte FC_HBA_PORTSPEED_1GBIT; 1260*fcf3ce44SJohn Forte } 1261*fcf3ce44SJohn Forte value1 = 0x00000120; 1262*fcf3ce44SJohn Forte value2 = 0x00000001; 1263*fcf3ce44SJohn Forte 1264*fcf3ce44SJohn Forte bcopy((caddr_t)&value1, 1265*fcf3ce44SJohn Forte (caddr_t)&port_attrs->PortSupportedFc4Types[0], 1266*fcf3ce44SJohn Forte 4); 1267*fcf3ce44SJohn Forte bcopy((caddr_t)&value2, 1268*fcf3ce44SJohn Forte (caddr_t)&port_attrs->PortSupportedFc4Types[4], 1269*fcf3ce44SJohn Forte 4); 1270*fcf3ce44SJohn Forte 1271*fcf3ce44SJohn Forte bcopy((caddr_t)&value1, 1272*fcf3ce44SJohn Forte (caddr_t)&port_attrs->PortActiveFc4Types[0], 4); 1273*fcf3ce44SJohn Forte bcopy((caddr_t)&value2, 1274*fcf3ce44SJohn Forte (caddr_t)&port_attrs->PortActiveFc4Types[4], 4); 1275*fcf3ce44SJohn Forte 1276*fcf3ce44SJohn Forte port_attrs->PortMaxFrameSize = FF_FRAME_SIZE; 1277*fcf3ce44SJohn Forte port_attrs->NumberofDiscoveredPorts = 1278*fcf3ce44SJohn Forte emlxs_nport_count(port); 1279*fcf3ce44SJohn Forte 1280*fcf3ce44SJohn Forte break; 1281*fcf3ce44SJohn Forte } 1282*fcf3ce44SJohn Forte 1283*fcf3ce44SJohn Forte case FCIO_GET_NODE_ID: 1284*fcf3ce44SJohn Forte { 1285*fcf3ce44SJohn Forte fc_fca_pm_t pm; 1286*fcf3ce44SJohn Forte 1287*fcf3ce44SJohn Forte if (fcio->fcio_xfer != FCIO_XFER_READ || 1288*fcf3ce44SJohn Forte fcio->fcio_olen < sizeof (fc_rnid_t)) { 1289*fcf3ce44SJohn Forte rval = EINVAL; 1290*fcf3ce44SJohn Forte break; 1291*fcf3ce44SJohn Forte } 1292*fcf3ce44SJohn Forte bzero((caddr_t)&pm, sizeof (pm)); 1293*fcf3ce44SJohn Forte 1294*fcf3ce44SJohn Forte pm.pm_cmd_flags = FC_FCA_PM_READ; 1295*fcf3ce44SJohn Forte pm.pm_cmd_code = FC_PORT_GET_NODE_ID; 1296*fcf3ce44SJohn Forte pm.pm_data_len = fcio->fcio_olen; 1297*fcf3ce44SJohn Forte pm.pm_data_buf = fcio->fcio_obuf; 1298*fcf3ce44SJohn Forte 1299*fcf3ce44SJohn Forte rval = emlxs_port_manage(port, &pm); 1300*fcf3ce44SJohn Forte 1301*fcf3ce44SJohn Forte if (rval != FC_SUCCESS) { 1302*fcf3ce44SJohn Forte fcio->fcio_errno = rval; 1303*fcf3ce44SJohn Forte rval = EIO; 1304*fcf3ce44SJohn Forte } 1305*fcf3ce44SJohn Forte break; 1306*fcf3ce44SJohn Forte } 1307*fcf3ce44SJohn Forte 1308*fcf3ce44SJohn Forte case FCIO_SET_NODE_ID: 1309*fcf3ce44SJohn Forte { 1310*fcf3ce44SJohn Forte fc_fca_pm_t pm; 1311*fcf3ce44SJohn Forte 1312*fcf3ce44SJohn Forte if (fcio->fcio_xfer != FCIO_XFER_WRITE || 1313*fcf3ce44SJohn Forte fcio->fcio_ilen < sizeof (fc_rnid_t)) { 1314*fcf3ce44SJohn Forte rval = EINVAL; 1315*fcf3ce44SJohn Forte break; 1316*fcf3ce44SJohn Forte } 1317*fcf3ce44SJohn Forte bzero((caddr_t)&pm, sizeof (pm)); 1318*fcf3ce44SJohn Forte 1319*fcf3ce44SJohn Forte pm.pm_cmd_flags = FC_FCA_PM_READ; 1320*fcf3ce44SJohn Forte pm.pm_cmd_code = FC_PORT_SET_NODE_ID; 1321*fcf3ce44SJohn Forte pm.pm_data_len = fcio->fcio_ilen; 1322*fcf3ce44SJohn Forte pm.pm_data_buf = fcio->fcio_ibuf; 1323*fcf3ce44SJohn Forte 1324*fcf3ce44SJohn Forte rval = emlxs_port_manage(port, &pm); 1325*fcf3ce44SJohn Forte 1326*fcf3ce44SJohn Forte if (rval != FC_SUCCESS) { 1327*fcf3ce44SJohn Forte fcio->fcio_errno = rval; 1328*fcf3ce44SJohn Forte rval = EIO; 1329*fcf3ce44SJohn Forte } 1330*fcf3ce44SJohn Forte break; 1331*fcf3ce44SJohn Forte } 1332*fcf3ce44SJohn Forte 1333*fcf3ce44SJohn Forte case FCIO_GET_NUM_DEVS: 1334*fcf3ce44SJohn Forte { 1335*fcf3ce44SJohn Forte if (fcio->fcio_xfer != FCIO_XFER_READ || 1336*fcf3ce44SJohn Forte fcio->fcio_olen < sizeof (uint32_t)) { 1337*fcf3ce44SJohn Forte rval = EINVAL; 1338*fcf3ce44SJohn Forte break; 1339*fcf3ce44SJohn Forte } 1340*fcf3ce44SJohn Forte *(uint32_t *)fcio->fcio_obuf = emlxs_nport_count(port); 1341*fcf3ce44SJohn Forte 1342*fcf3ce44SJohn Forte break; 1343*fcf3ce44SJohn Forte } 1344*fcf3ce44SJohn Forte 1345*fcf3ce44SJohn Forte case FCIO_GET_DEV_LIST: 1346*fcf3ce44SJohn Forte { 1347*fcf3ce44SJohn Forte fc_port_dev_t *port_dev; 1348*fcf3ce44SJohn Forte uint32_t max_count; 1349*fcf3ce44SJohn Forte uint32_t i; 1350*fcf3ce44SJohn Forte uint32_t j; 1351*fcf3ce44SJohn Forte emlxs_node_t *nlp; 1352*fcf3ce44SJohn Forte uint32_t nport_count; 1353*fcf3ce44SJohn Forte caddr_t np; 1354*fcf3ce44SJohn Forte caddr_t wp; 1355*fcf3ce44SJohn Forte 1356*fcf3ce44SJohn Forte if (fcio->fcio_xfer != FCIO_XFER_READ || 1357*fcf3ce44SJohn Forte fcio->fcio_alen < sizeof (uint32_t)) { 1358*fcf3ce44SJohn Forte rval = EINVAL; 1359*fcf3ce44SJohn Forte break; 1360*fcf3ce44SJohn Forte } 1361*fcf3ce44SJohn Forte port_dev = (fc_port_dev_t *)fcio->fcio_obuf; 1362*fcf3ce44SJohn Forte max_count = fcio->fcio_olen / sizeof (fc_port_dev_t); 1363*fcf3ce44SJohn Forte 1364*fcf3ce44SJohn Forte rw_enter(&port->node_rwlock, RW_READER); 1365*fcf3ce44SJohn Forte 1366*fcf3ce44SJohn Forte nport_count = emlxs_nport_count(port); 1367*fcf3ce44SJohn Forte *(uint32_t *)fcio->fcio_abuf = nport_count; 1368*fcf3ce44SJohn Forte 1369*fcf3ce44SJohn Forte if (nport_count == 0) { 1370*fcf3ce44SJohn Forte rw_exit(&port->node_rwlock); 1371*fcf3ce44SJohn Forte 1372*fcf3ce44SJohn Forte fcio->fcio_errno = FC_NO_MAP; 1373*fcf3ce44SJohn Forte rval = EIO; 1374*fcf3ce44SJohn Forte break; 1375*fcf3ce44SJohn Forte } 1376*fcf3ce44SJohn Forte if (nport_count > max_count) { 1377*fcf3ce44SJohn Forte rw_exit(&port->node_rwlock); 1378*fcf3ce44SJohn Forte 1379*fcf3ce44SJohn Forte fcio->fcio_errno = FC_TOOMANY; 1380*fcf3ce44SJohn Forte rval = EIO; 1381*fcf3ce44SJohn Forte break; 1382*fcf3ce44SJohn Forte } 1383*fcf3ce44SJohn Forte 1384*fcf3ce44SJohn Forte #define TOP_LOOP() for (j = 1; j < port->alpa_map[0]; j++) { \ 1385*fcf3ce44SJohn Forte if (nlp->nlp_DID == port->alpa_map[j]) { \ 1386*fcf3ce44SJohn Forte PRIV_LILP_POSIT(port_dev) = j - 1; \ 1387*fcf3ce44SJohn Forte break; \ 1388*fcf3ce44SJohn Forte } \ 1389*fcf3ce44SJohn Forte } 1390*fcf3ce44SJohn Forte 1391*fcf3ce44SJohn Forte 1392*fcf3ce44SJohn Forte for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) { 1393*fcf3ce44SJohn Forte nlp = port->node_table[i]; 1394*fcf3ce44SJohn Forte while (nlp != NULL) { 1395*fcf3ce44SJohn Forte if ((nlp->nlp_DID & 0xFFF000) != 1396*fcf3ce44SJohn Forte 0xFFF000) { 1397*fcf3ce44SJohn Forte port_dev->dev_dtype = 0; 1398*fcf3ce44SJohn Forte port_dev->dev_type[0] = 1399*fcf3ce44SJohn Forte SWAP_LONG(0x00000100); 1400*fcf3ce44SJohn Forte port_dev->dev_state = 1401*fcf3ce44SJohn Forte PORT_DEVICE_LOGGED_IN; 1402*fcf3ce44SJohn Forte port_dev->dev_did.port_id = 1403*fcf3ce44SJohn Forte nlp->nlp_DID; 1404*fcf3ce44SJohn Forte PRIV_LILP_POSIT(port_dev) = 0; 1405*fcf3ce44SJohn Forte HARD_ADDR(port_dev) = 0; 1406*fcf3ce44SJohn Forte 1407*fcf3ce44SJohn Forte if (hba->topology == 1408*fcf3ce44SJohn Forte TOPOLOGY_LOOP) { 1409*fcf3ce44SJohn Forte 1410*fcf3ce44SJohn Forte for (j = 1; j < port->alpa_map[0]; j++) { 1411*fcf3ce44SJohn Forte if (nlp->nlp_DID == port->alpa_map[j]) { 1412*fcf3ce44SJohn Forte PRIV_LILP_POSIT(port_dev) = j - 1; 1413*fcf3ce44SJohn Forte break; 1414*fcf3ce44SJohn Forte } 1415*fcf3ce44SJohn Forte } 1416*fcf3ce44SJohn Forte HARD_ADDR(port_dev) = 1417*fcf3ce44SJohn Forte nlp->nlp_DID; 1418*fcf3ce44SJohn Forte 1419*fcf3ce44SJohn Forte } 1420*fcf3ce44SJohn Forte 1421*fcf3ce44SJohn Forte np = (caddr_t) 1422*fcf3ce44SJohn Forte &nlp->nlp_portname; 1423*fcf3ce44SJohn Forte wp = (caddr_t) 1424*fcf3ce44SJohn Forte &port_dev->dev_pwwn; 1425*fcf3ce44SJohn Forte bcopy(np, wp, 8); 1426*fcf3ce44SJohn Forte 1427*fcf3ce44SJohn Forte np = (caddr_t) 1428*fcf3ce44SJohn Forte &nlp->nlp_nodename; 1429*fcf3ce44SJohn Forte wp = (caddr_t) 1430*fcf3ce44SJohn Forte &port_dev->dev_nwwn; 1431*fcf3ce44SJohn Forte bcopy(np, wp, 8); 1432*fcf3ce44SJohn Forte port_dev++; 1433*fcf3ce44SJohn Forte } 1434*fcf3ce44SJohn Forte nlp = (NODELIST *) nlp->nlp_list_next; 1435*fcf3ce44SJohn Forte } 1436*fcf3ce44SJohn Forte } 1437*fcf3ce44SJohn Forte rw_exit(&port->node_rwlock); 1438*fcf3ce44SJohn Forte 1439*fcf3ce44SJohn Forte break; 1440*fcf3ce44SJohn Forte } 1441*fcf3ce44SJohn Forte 1442*fcf3ce44SJohn Forte case FCIO_GET_LOGI_PARAMS: 1443*fcf3ce44SJohn Forte { 1444*fcf3ce44SJohn Forte uint8_t null_wwn[8]; 1445*fcf3ce44SJohn Forte 1446*fcf3ce44SJohn Forte if (fcio->fcio_ilen != sizeof (la_wwn_t) || 1447*fcf3ce44SJohn Forte (fcio->fcio_xfer & FCIO_XFER_READ) == 0 || 1448*fcf3ce44SJohn Forte (fcio->fcio_xfer & FCIO_XFER_WRITE) == 0) { 1449*fcf3ce44SJohn Forte rval = EINVAL; 1450*fcf3ce44SJohn Forte break; 1451*fcf3ce44SJohn Forte } 1452*fcf3ce44SJohn Forte bzero(null_wwn, 8); 1453*fcf3ce44SJohn Forte wwpn = (uint8_t *)fcio->fcio_ibuf; 1454*fcf3ce44SJohn Forte 1455*fcf3ce44SJohn Forte if ((bcmp((caddr_t)wwpn, (caddr_t)null_wwn, 8) == 0) || 1456*fcf3ce44SJohn Forte (bcmp((caddr_t)wwpn, 1457*fcf3ce44SJohn Forte (caddr_t)&port->wwpn, 8) == 0)) { 1458*fcf3ce44SJohn Forte bcopy((caddr_t)&port->sparam, 1459*fcf3ce44SJohn Forte (caddr_t)fcio->fcio_obuf, fcio->fcio_olen); 1460*fcf3ce44SJohn Forte } else { 1461*fcf3ce44SJohn Forte ndlp = emlxs_node_find_wwpn(port, wwpn); 1462*fcf3ce44SJohn Forte 1463*fcf3ce44SJohn Forte if (ndlp) { 1464*fcf3ce44SJohn Forte bcopy((caddr_t)&ndlp->sparm, 1465*fcf3ce44SJohn Forte (caddr_t)fcio->fcio_obuf, 1466*fcf3ce44SJohn Forte fcio->fcio_olen); 1467*fcf3ce44SJohn Forte } else { 1468*fcf3ce44SJohn Forte rval = ENXIO; 1469*fcf3ce44SJohn Forte } 1470*fcf3ce44SJohn Forte } 1471*fcf3ce44SJohn Forte 1472*fcf3ce44SJohn Forte break; 1473*fcf3ce44SJohn Forte } 1474*fcf3ce44SJohn Forte 1475*fcf3ce44SJohn Forte case FCIO_GET_STATE: 1476*fcf3ce44SJohn Forte { 1477*fcf3ce44SJohn Forte uint8_t null_wwn[8]; 1478*fcf3ce44SJohn Forte uint32_t *statep; 1479*fcf3ce44SJohn Forte 1480*fcf3ce44SJohn Forte if (fcio->fcio_ilen != 8 || 1481*fcf3ce44SJohn Forte fcio->fcio_olen != 4 || 1482*fcf3ce44SJohn Forte (fcio->fcio_xfer & FCIO_XFER_WRITE) == 0 || 1483*fcf3ce44SJohn Forte (fcio->fcio_xfer & FCIO_XFER_READ) == 0) { 1484*fcf3ce44SJohn Forte rval = EINVAL; 1485*fcf3ce44SJohn Forte break; 1486*fcf3ce44SJohn Forte } 1487*fcf3ce44SJohn Forte bzero(null_wwn, 8); 1488*fcf3ce44SJohn Forte wwpn = (uint8_t *)fcio->fcio_ibuf; 1489*fcf3ce44SJohn Forte statep = (uint32_t *)fcio->fcio_obuf; 1490*fcf3ce44SJohn Forte 1491*fcf3ce44SJohn Forte if ((bcmp((caddr_t)wwpn, (caddr_t)null_wwn, 8) == 0) || 1492*fcf3ce44SJohn Forte (bcmp((caddr_t)wwpn, 1493*fcf3ce44SJohn Forte (caddr_t)&port->wwpn, 8) == 0)) { 1494*fcf3ce44SJohn Forte *statep = PORT_DEVICE_VALID; 1495*fcf3ce44SJohn Forte } else { 1496*fcf3ce44SJohn Forte ndlp = emlxs_node_find_wwpn(port, wwpn); 1497*fcf3ce44SJohn Forte 1498*fcf3ce44SJohn Forte if (ndlp) { 1499*fcf3ce44SJohn Forte *statep = PORT_DEVICE_VALID; 1500*fcf3ce44SJohn Forte } else { 1501*fcf3ce44SJohn Forte *statep = PORT_DEVICE_INVALID; 1502*fcf3ce44SJohn Forte } 1503*fcf3ce44SJohn Forte } 1504*fcf3ce44SJohn Forte 1505*fcf3ce44SJohn Forte break; 1506*fcf3ce44SJohn Forte } 1507*fcf3ce44SJohn Forte 1508*fcf3ce44SJohn Forte case FCIO_GET_TOPOLOGY: 1509*fcf3ce44SJohn Forte { 1510*fcf3ce44SJohn Forte uint32_t *tp; 1511*fcf3ce44SJohn Forte 1512*fcf3ce44SJohn Forte if (fcio->fcio_olen != 4 || 1513*fcf3ce44SJohn Forte (fcio->fcio_xfer & FCIO_XFER_READ) == 0) { 1514*fcf3ce44SJohn Forte rval = EINVAL; 1515*fcf3ce44SJohn Forte break; 1516*fcf3ce44SJohn Forte } 1517*fcf3ce44SJohn Forte tp = (uint32_t *)fcio->fcio_obuf; 1518*fcf3ce44SJohn Forte 1519*fcf3ce44SJohn Forte if (hba->state <= FC_LINK_DOWN) { 1520*fcf3ce44SJohn Forte *tp = FC_TOP_UNKNOWN; 1521*fcf3ce44SJohn Forte } else { 1522*fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, Fabric_DID); 1523*fcf3ce44SJohn Forte 1524*fcf3ce44SJohn Forte if (hba->topology == TOPOLOGY_LOOP) { 1525*fcf3ce44SJohn Forte if (ndlp) { 1526*fcf3ce44SJohn Forte *tp = FC_TOP_PUBLIC_LOOP; 1527*fcf3ce44SJohn Forte } else { 1528*fcf3ce44SJohn Forte *tp = FC_TOP_PRIVATE_LOOP; 1529*fcf3ce44SJohn Forte } 1530*fcf3ce44SJohn Forte } else { 1531*fcf3ce44SJohn Forte if (ndlp) { 1532*fcf3ce44SJohn Forte *tp = FC_TOP_FABRIC; 1533*fcf3ce44SJohn Forte } else { 1534*fcf3ce44SJohn Forte *tp = FC_TOP_PT_PT; 1535*fcf3ce44SJohn Forte } 1536*fcf3ce44SJohn Forte } 1537*fcf3ce44SJohn Forte } 1538*fcf3ce44SJohn Forte 1539*fcf3ce44SJohn Forte break; 1540*fcf3ce44SJohn Forte } 1541*fcf3ce44SJohn Forte 1542*fcf3ce44SJohn Forte case FCIO_LINK_STATUS: 1543*fcf3ce44SJohn Forte { 1544*fcf3ce44SJohn Forte fc_portid_t *portid; 1545*fcf3ce44SJohn Forte fc_rls_acc_t *rls; 1546*fcf3ce44SJohn Forte fc_fca_pm_t pm; 1547*fcf3ce44SJohn Forte 1548*fcf3ce44SJohn Forte if (fcio->fcio_ilen != sizeof (fc_portid_t) || 1549*fcf3ce44SJohn Forte fcio->fcio_olen != sizeof (fc_rls_acc_t) || 1550*fcf3ce44SJohn Forte fcio->fcio_xfer != FCIO_XFER_RW) { 1551*fcf3ce44SJohn Forte rval = EINVAL; 1552*fcf3ce44SJohn Forte break; 1553*fcf3ce44SJohn Forte } 1554*fcf3ce44SJohn Forte if ((fcio->fcio_cmd_flags != 1555*fcf3ce44SJohn Forte FCIO_CFLAGS_RLS_DEST_FPORT) && 1556*fcf3ce44SJohn Forte (fcio->fcio_cmd_flags != 1557*fcf3ce44SJohn Forte FCIO_CFLAGS_RLS_DEST_NPORT)) { 1558*fcf3ce44SJohn Forte rval = EINVAL; 1559*fcf3ce44SJohn Forte break; 1560*fcf3ce44SJohn Forte } 1561*fcf3ce44SJohn Forte portid = (fc_portid_t *)fcio->fcio_ibuf; 1562*fcf3ce44SJohn Forte rls = (fc_rls_acc_t *)fcio->fcio_obuf; 1563*fcf3ce44SJohn Forte 1564*fcf3ce44SJohn Forte if (portid->port_id == 0 || 1565*fcf3ce44SJohn Forte portid->port_id == port->did) { 1566*fcf3ce44SJohn Forte bzero((caddr_t)&pm, sizeof (pm)); 1567*fcf3ce44SJohn Forte 1568*fcf3ce44SJohn Forte pm.pm_cmd_flags = FC_FCA_PM_READ; 1569*fcf3ce44SJohn Forte pm.pm_cmd_code = FC_PORT_RLS; 1570*fcf3ce44SJohn Forte pm.pm_data_len = sizeof (fc_rls_acc_t); 1571*fcf3ce44SJohn Forte pm.pm_data_buf = (caddr_t)rls; 1572*fcf3ce44SJohn Forte 1573*fcf3ce44SJohn Forte rval = emlxs_port_manage(port, &pm); 1574*fcf3ce44SJohn Forte 1575*fcf3ce44SJohn Forte if (rval != FC_SUCCESS) { 1576*fcf3ce44SJohn Forte fcio->fcio_errno = rval; 1577*fcf3ce44SJohn Forte rval = EIO; 1578*fcf3ce44SJohn Forte } 1579*fcf3ce44SJohn Forte } else { 1580*fcf3ce44SJohn Forte rval = ENOTSUP; 1581*fcf3ce44SJohn Forte } 1582*fcf3ce44SJohn Forte break; 1583*fcf3ce44SJohn Forte } 1584*fcf3ce44SJohn Forte 1585*fcf3ce44SJohn Forte case FCIO_GET_OTHER_ADAPTER_PORTS: 1586*fcf3ce44SJohn Forte { 1587*fcf3ce44SJohn Forte uint32_t index; 1588*fcf3ce44SJohn Forte char *path; 1589*fcf3ce44SJohn Forte 1590*fcf3ce44SJohn Forte if (fcio->fcio_olen < MAXPATHLEN || 1591*fcf3ce44SJohn Forte fcio->fcio_ilen != sizeof (uint32_t)) { 1592*fcf3ce44SJohn Forte rval = EINVAL; 1593*fcf3ce44SJohn Forte break; 1594*fcf3ce44SJohn Forte } 1595*fcf3ce44SJohn Forte index = *(uint32_t *)fcio->fcio_ibuf; 1596*fcf3ce44SJohn Forte path = (char *)fcio->fcio_obuf; 1597*fcf3ce44SJohn Forte 1598*fcf3ce44SJohn Forte if (index > hba->vpi_max - 1) { 1599*fcf3ce44SJohn Forte fcio->fcio_errno = FC_BADPORT; 1600*fcf3ce44SJohn Forte rval = EFAULT; 1601*fcf3ce44SJohn Forte break; 1602*fcf3ce44SJohn Forte } 1603*fcf3ce44SJohn Forte (void) ddi_pathname(hba->dip, path); 1604*fcf3ce44SJohn Forte 1605*fcf3ce44SJohn Forte break; 1606*fcf3ce44SJohn Forte } 1607*fcf3ce44SJohn Forte 1608*fcf3ce44SJohn Forte case FCIO_GET_DISCOVERED_PORT_ATTRIBUTES: 1609*fcf3ce44SJohn Forte { 1610*fcf3ce44SJohn Forte uint32_t index; 1611*fcf3ce44SJohn Forte 1612*fcf3ce44SJohn Forte if (fcio->fcio_xfer != FCIO_XFER_READ || 1613*fcf3ce44SJohn Forte fcio->fcio_ilen < sizeof (uint32_t) || 1614*fcf3ce44SJohn Forte fcio->fcio_olen < 1615*fcf3ce44SJohn Forte sizeof (fc_hba_port_attributes_t)) { 1616*fcf3ce44SJohn Forte rval = EINVAL; 1617*fcf3ce44SJohn Forte break; 1618*fcf3ce44SJohn Forte } 1619*fcf3ce44SJohn Forte index = *(uint32_t *)fcio->fcio_ibuf; 1620*fcf3ce44SJohn Forte ndlp = emlxs_node_find_index(port, index, 1); 1621*fcf3ce44SJohn Forte 1622*fcf3ce44SJohn Forte if (!ndlp) { 1623*fcf3ce44SJohn Forte fcio->fcio_errno = FC_OUTOFBOUNDS; 1624*fcf3ce44SJohn Forte rval = EINVAL; 1625*fcf3ce44SJohn Forte break; 1626*fcf3ce44SJohn Forte } 1627*fcf3ce44SJohn Forte goto get_node_attrs; 1628*fcf3ce44SJohn Forte } 1629*fcf3ce44SJohn Forte 1630*fcf3ce44SJohn Forte /* Same as FCIO_GET_DISCOVERED_PORT_ATTRIBUTES */ 1631*fcf3ce44SJohn Forte /* except WWPN is used instead of index */ 1632*fcf3ce44SJohn Forte case FCIO_GET_PORT_ATTRIBUTES: 1633*fcf3ce44SJohn Forte { 1634*fcf3ce44SJohn Forte emlxs_node_t *ndlp2; 1635*fcf3ce44SJohn Forte /* uint32_t value1; */ 1636*fcf3ce44SJohn Forte 1637*fcf3ce44SJohn Forte if (fcio->fcio_xfer != FCIO_XFER_READ || 1638*fcf3ce44SJohn Forte fcio->fcio_ilen < 8 || 1639*fcf3ce44SJohn Forte fcio->fcio_olen < 1640*fcf3ce44SJohn Forte sizeof (fc_hba_port_attributes_t)) { 1641*fcf3ce44SJohn Forte rval = EINVAL; 1642*fcf3ce44SJohn Forte break; 1643*fcf3ce44SJohn Forte } 1644*fcf3ce44SJohn Forte wwpn = (uint8_t *)fcio->fcio_ibuf; 1645*fcf3ce44SJohn Forte ndlp = emlxs_node_find_wwpn(port, wwpn); 1646*fcf3ce44SJohn Forte 1647*fcf3ce44SJohn Forte if (!ndlp) { 1648*fcf3ce44SJohn Forte fcio->fcio_errno = FC_NOMAP; 1649*fcf3ce44SJohn Forte rval = EINVAL; 1650*fcf3ce44SJohn Forte break; 1651*fcf3ce44SJohn Forte } 1652*fcf3ce44SJohn Forte /* Filter fabric ports */ 1653*fcf3ce44SJohn Forte if ((ndlp->nlp_DID & 0xFFF000) == 0xFFF000) { 1654*fcf3ce44SJohn Forte fcio->fcio_errno = FC_NOMAP; 1655*fcf3ce44SJohn Forte rval = EINVAL; 1656*fcf3ce44SJohn Forte break; 1657*fcf3ce44SJohn Forte } 1658*fcf3ce44SJohn Forte get_node_attrs: 1659*fcf3ce44SJohn Forte 1660*fcf3ce44SJohn Forte port_attrs = 1661*fcf3ce44SJohn Forte (fc_hba_port_attributes_t *)fcio->fcio_obuf; 1662*fcf3ce44SJohn Forte 1663*fcf3ce44SJohn Forte port_attrs->version = FC_HBA_PORT_ATTRIBUTES_VERSION; 1664*fcf3ce44SJohn Forte /* port_attrs->lastChange */ 1665*fcf3ce44SJohn Forte /* port_attrs->fp_minor */ 1666*fcf3ce44SJohn Forte bcopy((caddr_t)&ndlp->nlp_nodename, 1667*fcf3ce44SJohn Forte (caddr_t)&port_attrs->NodeWWN, 8); 1668*fcf3ce44SJohn Forte bcopy((caddr_t)&ndlp->nlp_portname, 1669*fcf3ce44SJohn Forte (caddr_t)&port_attrs->PortWWN, 8); 1670*fcf3ce44SJohn Forte 1671*fcf3ce44SJohn Forte port_attrs->PortSpeed = HBA_PORTSPEED_UNKNOWN; 1672*fcf3ce44SJohn Forte port_attrs->PortType = FC_HBA_PORTTYPE_UNKNOWN; 1673*fcf3ce44SJohn Forte port_attrs->PortState = FC_HBA_PORTSTATE_OFFLINE; 1674*fcf3ce44SJohn Forte 1675*fcf3ce44SJohn Forte if (hba->state > FC_LINK_UP) { 1676*fcf3ce44SJohn Forte ndlp2 = emlxs_node_find_did(port, Fabric_DID); 1677*fcf3ce44SJohn Forte 1678*fcf3ce44SJohn Forte port_attrs->PortFcId = ndlp->nlp_DID; 1679*fcf3ce44SJohn Forte port_attrs->PortState = FC_HBA_PORTSTATE_ONLINE; 1680*fcf3ce44SJohn Forte 1681*fcf3ce44SJohn Forte /* no switch */ 1682*fcf3ce44SJohn Forte if (!ndlp2) { 1683*fcf3ce44SJohn Forte if (hba->topology == TOPOLOGY_LOOP) { 1684*fcf3ce44SJohn Forte port_attrs->PortType = 1685*fcf3ce44SJohn Forte FC_HBA_PORTTYPE_LPORT; 1686*fcf3ce44SJohn Forte } else { 1687*fcf3ce44SJohn Forte port_attrs->PortType = 1688*fcf3ce44SJohn Forte FC_HBA_PORTTYPE_PTP; 1689*fcf3ce44SJohn Forte } 1690*fcf3ce44SJohn Forte 1691*fcf3ce44SJohn Forte /* We share a common speed */ 1692*fcf3ce44SJohn Forte switch (hba->linkspeed) { 1693*fcf3ce44SJohn Forte case 0: 1694*fcf3ce44SJohn Forte port_attrs->PortSpeed = 1695*fcf3ce44SJohn Forte HBA_PORTSPEED_1GBIT; 1696*fcf3ce44SJohn Forte break; 1697*fcf3ce44SJohn Forte case LA_1GHZ_LINK: 1698*fcf3ce44SJohn Forte port_attrs->PortSpeed = 1699*fcf3ce44SJohn Forte HBA_PORTSPEED_1GBIT; 1700*fcf3ce44SJohn Forte break; 1701*fcf3ce44SJohn Forte case LA_2GHZ_LINK: 1702*fcf3ce44SJohn Forte port_attrs->PortSpeed = 1703*fcf3ce44SJohn Forte HBA_PORTSPEED_2GBIT; 1704*fcf3ce44SJohn Forte break; 1705*fcf3ce44SJohn Forte case LA_4GHZ_LINK: 1706*fcf3ce44SJohn Forte port_attrs->PortSpeed = 1707*fcf3ce44SJohn Forte HBA_PORTSPEED_4GBIT; 1708*fcf3ce44SJohn Forte break; 1709*fcf3ce44SJohn Forte case LA_8GHZ_LINK: 1710*fcf3ce44SJohn Forte port_attrs->PortSpeed = 1711*fcf3ce44SJohn Forte HBA_PORTSPEED_8GBIT; 1712*fcf3ce44SJohn Forte break; 1713*fcf3ce44SJohn Forte case LA_10GHZ_LINK: 1714*fcf3ce44SJohn Forte port_attrs->PortSpeed = 1715*fcf3ce44SJohn Forte HBA_PORTSPEED_10GBIT; 1716*fcf3ce44SJohn Forte break; 1717*fcf3ce44SJohn Forte } 1718*fcf3ce44SJohn Forte } 1719*fcf3ce44SJohn Forte /* public loop */ 1720*fcf3ce44SJohn Forte else if (hba->topology == TOPOLOGY_LOOP) { 1721*fcf3ce44SJohn Forte /* Check for common area and domain */ 1722*fcf3ce44SJohn Forte if ((ndlp->nlp_DID & 0xFFFF00) == 1723*fcf3ce44SJohn Forte (port->did & 0xFFFF00)) { 1724*fcf3ce44SJohn Forte port_attrs->PortType = 1725*fcf3ce44SJohn Forte FC_HBA_PORTTYPE_NLPORT; 1726*fcf3ce44SJohn Forte 1727*fcf3ce44SJohn Forte /* We share a common speed */ 1728*fcf3ce44SJohn Forte switch (hba->linkspeed) { 1729*fcf3ce44SJohn Forte case 0: 1730*fcf3ce44SJohn Forte port_attrs->PortSpeed = 1731*fcf3ce44SJohn Forte HBA_PORTSPEED_1GBIT; 1732*fcf3ce44SJohn Forte break; 1733*fcf3ce44SJohn Forte case LA_1GHZ_LINK: 1734*fcf3ce44SJohn Forte port_attrs->PortSpeed = 1735*fcf3ce44SJohn Forte HBA_PORTSPEED_1GBIT; 1736*fcf3ce44SJohn Forte break; 1737*fcf3ce44SJohn Forte case LA_2GHZ_LINK: 1738*fcf3ce44SJohn Forte port_attrs->PortSpeed = 1739*fcf3ce44SJohn Forte HBA_PORTSPEED_2GBIT; 1740*fcf3ce44SJohn Forte break; 1741*fcf3ce44SJohn Forte case LA_4GHZ_LINK: 1742*fcf3ce44SJohn Forte port_attrs->PortSpeed = 1743*fcf3ce44SJohn Forte HBA_PORTSPEED_4GBIT; 1744*fcf3ce44SJohn Forte break; 1745*fcf3ce44SJohn Forte case LA_8GHZ_LINK: 1746*fcf3ce44SJohn Forte port_attrs->PortSpeed = 1747*fcf3ce44SJohn Forte HBA_PORTSPEED_8GBIT; 1748*fcf3ce44SJohn Forte break; 1749*fcf3ce44SJohn Forte case LA_10GHZ_LINK: 1750*fcf3ce44SJohn Forte port_attrs->PortSpeed = 1751*fcf3ce44SJohn Forte HBA_10GBIT; 1752*fcf3ce44SJohn Forte break; 1753*fcf3ce44SJohn Forte } 1754*fcf3ce44SJohn Forte } 1755*fcf3ce44SJohn Forte } 1756*fcf3ce44SJohn Forte } 1757*fcf3ce44SJohn Forte port_attrs->PortSupportedClassofService = 1758*fcf3ce44SJohn Forte SWAP_DATA32(FC_NS_CLASS3); 1759*fcf3ce44SJohn Forte /* port_attrs->PortSymbolicName */ 1760*fcf3ce44SJohn Forte /* port_attrs->PortSupportedSpeed */ 1761*fcf3ce44SJohn Forte /* port_attrs->PortSupportedFc4Types */ 1762*fcf3ce44SJohn Forte /* port_attrs->PortActiveFc4Types */ 1763*fcf3ce44SJohn Forte /* port_attrs->PortMaxFrameSize */ 1764*fcf3ce44SJohn Forte /* port_attrs->NumberofDiscoveredPorts */ 1765*fcf3ce44SJohn Forte 1766*fcf3ce44SJohn Forte break; 1767*fcf3ce44SJohn Forte } 1768*fcf3ce44SJohn Forte 1769*fcf3ce44SJohn Forte case FCIO_GET_SYM_PNAME: 1770*fcf3ce44SJohn Forte { 1771*fcf3ce44SJohn Forte if (fcio->fcio_olen < (strlen(port->spn) + 1) || 1772*fcf3ce44SJohn Forte (fcio->fcio_xfer & FCIO_XFER_READ) == 0) { 1773*fcf3ce44SJohn Forte rval = EINVAL; 1774*fcf3ce44SJohn Forte break; 1775*fcf3ce44SJohn Forte } 1776*fcf3ce44SJohn Forte (void) strcpy((caddr_t)fcio->fcio_obuf, 1777*fcf3ce44SJohn Forte (caddr_t)port->spn); 1778*fcf3ce44SJohn Forte 1779*fcf3ce44SJohn Forte break; 1780*fcf3ce44SJohn Forte } 1781*fcf3ce44SJohn Forte 1782*fcf3ce44SJohn Forte case FCIO_GET_SYM_NNAME: 1783*fcf3ce44SJohn Forte { 1784*fcf3ce44SJohn Forte if (fcio->fcio_olen < (strlen(port->snn) + 1) || 1785*fcf3ce44SJohn Forte (fcio->fcio_xfer & FCIO_XFER_READ) == 0) { 1786*fcf3ce44SJohn Forte rval = EINVAL; 1787*fcf3ce44SJohn Forte break; 1788*fcf3ce44SJohn Forte } 1789*fcf3ce44SJohn Forte (void) strcpy((caddr_t)fcio->fcio_obuf, 1790*fcf3ce44SJohn Forte (caddr_t)port->snn); 1791*fcf3ce44SJohn Forte 1792*fcf3ce44SJohn Forte break; 1793*fcf3ce44SJohn Forte } 1794*fcf3ce44SJohn Forte 1795*fcf3ce44SJohn Forte case FCIO_SET_SYM_PNAME: 1796*fcf3ce44SJohn Forte case FCIO_SET_SYM_NNAME: 1797*fcf3ce44SJohn Forte case FCIO_DEV_LOGIN: 1798*fcf3ce44SJohn Forte case FCIO_DEV_LOGOUT: 1799*fcf3ce44SJohn Forte case FCIO_DEV_REMOVE: 1800*fcf3ce44SJohn Forte case FCIO_GET_DUMP_SIZE: 1801*fcf3ce44SJohn Forte case FCIO_FORCE_DUMP: 1802*fcf3ce44SJohn Forte case FCIO_GET_DUMP: 1803*fcf3ce44SJohn Forte case FCIO_NS: 1804*fcf3ce44SJohn Forte case FCIO_SEND_NODE_ID: 1805*fcf3ce44SJohn Forte case FCIO_GET_ADAPTER_PORT_STATS: 1806*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 1807*fcf3ce44SJohn Forte "%s: Unsupported FCIO command.", 1808*fcf3ce44SJohn Forte emlxs_fcio_xlate(fcio->fcio_cmd)); 1809*fcf3ce44SJohn Forte rval = ENOTSUP; 1810*fcf3ce44SJohn Forte break; 1811*fcf3ce44SJohn Forte 1812*fcf3ce44SJohn Forte default: 1813*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 1814*fcf3ce44SJohn Forte "Unknown FCIO command. (0x%x)", 1815*fcf3ce44SJohn Forte fcio->fcio_cmd); 1816*fcf3ce44SJohn Forte rval = EFAULT; 1817*fcf3ce44SJohn Forte 1818*fcf3ce44SJohn Forte } /* switch() */ 1819*fcf3ce44SJohn Forte 1820*fcf3ce44SJohn Forte done: 1821*fcf3ce44SJohn Forte 1822*fcf3ce44SJohn Forte if (rval == 0) { 1823*fcf3ce44SJohn Forte fcio->fcio_errno = 0; 1824*fcf3ce44SJohn Forte } 1825*fcf3ce44SJohn Forte if (fcio->fcio_ibuf) { 1826*fcf3ce44SJohn Forte if (ddi_copyout(fcio->fcio_ibuf, dfc->buf1, 1827*fcf3ce44SJohn Forte fcio->fcio_ilen, mode)) { 1828*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 1829*fcf3ce44SJohn Forte "%s: %s: ddi_copyout failed. (size=%d)", 1830*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 1831*fcf3ce44SJohn Forte emlxs_fcio_xlate(dfc->data1), 1832*fcf3ce44SJohn Forte fcio->fcio_ilen); 1833*fcf3ce44SJohn Forte 1834*fcf3ce44SJohn Forte rval = EFAULT; 1835*fcf3ce44SJohn Forte } 1836*fcf3ce44SJohn Forte kmem_free(fcio->fcio_ibuf, fcio->fcio_ilen); 1837*fcf3ce44SJohn Forte } 1838*fcf3ce44SJohn Forte if (fcio->fcio_obuf) { 1839*fcf3ce44SJohn Forte if (ddi_copyout(fcio->fcio_obuf, dfc->buf2, 1840*fcf3ce44SJohn Forte fcio->fcio_olen, mode)) { 1841*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 1842*fcf3ce44SJohn Forte "%s: %s: ddi_copyout failed. (size=%d)", 1843*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 1844*fcf3ce44SJohn Forte emlxs_fcio_xlate(dfc->data1), 1845*fcf3ce44SJohn Forte fcio->fcio_olen); 1846*fcf3ce44SJohn Forte 1847*fcf3ce44SJohn Forte rval = EFAULT; 1848*fcf3ce44SJohn Forte } 1849*fcf3ce44SJohn Forte kmem_free(fcio->fcio_obuf, fcio->fcio_olen); 1850*fcf3ce44SJohn Forte } 1851*fcf3ce44SJohn Forte if (fcio->fcio_abuf) { 1852*fcf3ce44SJohn Forte if (ddi_copyout(fcio->fcio_abuf, dfc->buf3, 1853*fcf3ce44SJohn Forte fcio->fcio_alen, mode)) { 1854*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 1855*fcf3ce44SJohn Forte "%s: %s: ddi_copyout failed. (size=%d)", 1856*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 1857*fcf3ce44SJohn Forte emlxs_fcio_xlate(dfc->data1), 1858*fcf3ce44SJohn Forte fcio->fcio_alen); 1859*fcf3ce44SJohn Forte 1860*fcf3ce44SJohn Forte rval = EFAULT; 1861*fcf3ce44SJohn Forte } 1862*fcf3ce44SJohn Forte kmem_free(fcio->fcio_abuf, fcio->fcio_alen); 1863*fcf3ce44SJohn Forte } 1864*fcf3ce44SJohn Forte if (ddi_copyout((void *)&fcio->fcio_errno, (void *)dfc->buf4, 1865*fcf3ce44SJohn Forte dfc->buf4_size, mode) != 0) { 1866*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 1867*fcf3ce44SJohn Forte "%s: %s: ddi_copyout failed. (size=%d)", 1868*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 1869*fcf3ce44SJohn Forte emlxs_fcio_xlate(dfc->data1), 1870*fcf3ce44SJohn Forte dfc->buf4_size); 1871*fcf3ce44SJohn Forte 1872*fcf3ce44SJohn Forte rval = EFAULT; 1873*fcf3ce44SJohn Forte } 1874*fcf3ce44SJohn Forte return (rval); 1875*fcf3ce44SJohn Forte 1876*fcf3ce44SJohn Forte } /* emlxs_fcio_manage() */ 1877*fcf3ce44SJohn Forte 1878*fcf3ce44SJohn Forte #endif /* FCIO_SUPPORT */ 1879*fcf3ce44SJohn Forte 1880*fcf3ce44SJohn Forte 1881*fcf3ce44SJohn Forte 1882*fcf3ce44SJohn Forte #ifdef NPIV_SUPPORT 1883*fcf3ce44SJohn Forte 1884*fcf3ce44SJohn Forte static int32_t 1885*fcf3ce44SJohn Forte emlxs_dfc_create_vport(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 1886*fcf3ce44SJohn Forte { 1887*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1888*fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 1889*fcf3ce44SJohn Forte emlxs_port_t *vport; 1890*fcf3ce44SJohn Forte dfc_vportinfo_t dfc_vport; 1891*fcf3ce44SJohn Forte uint32_t vpi; 1892*fcf3ce44SJohn Forte uint32_t options; 1893*fcf3ce44SJohn Forte char name[256]; 1894*fcf3ce44SJohn Forte uint8_t wwn[8]; 1895*fcf3ce44SJohn Forte 1896*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 1897*fcf3ce44SJohn Forte "%s requested.", 1898*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 1899*fcf3ce44SJohn Forte 1900*fcf3ce44SJohn Forte options = dfc->data1; 1901*fcf3ce44SJohn Forte 1902*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 1903*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 1904*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 1905*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 1906*fcf3ce44SJohn Forte 1907*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 1908*fcf3ce44SJohn Forte } 1909*fcf3ce44SJohn Forte if (dfc->buf1_size < sizeof (dfc_vportinfo_t)) { 1910*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 1911*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 1912*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 1913*fcf3ce44SJohn Forte 1914*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 1915*fcf3ce44SJohn Forte } 1916*fcf3ce44SJohn Forte /* Read the dfc_vport object */ 1917*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf1, (void *)&dfc_vport, 1918*fcf3ce44SJohn Forte sizeof (dfc_vportinfo_t), mode) != 0) { 1919*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 1920*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 1921*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 1922*fcf3ce44SJohn Forte 1923*fcf3ce44SJohn Forte return (DFC_COPYIN_ERROR); 1924*fcf3ce44SJohn Forte } 1925*fcf3ce44SJohn Forte if (!(options & VPORT_OPT_AUTORETRY)) { 1926*fcf3ce44SJohn Forte if (!(hba->flag & FC_NPIV_ENABLED)) { 1927*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 1928*fcf3ce44SJohn Forte "%s: NPIV currently not enabled.", 1929*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 1930*fcf3ce44SJohn Forte 1931*fcf3ce44SJohn Forte return (DFC_NPIV_DISABLED); 1932*fcf3ce44SJohn Forte } 1933*fcf3ce44SJohn Forte if (!(hba->flag & FC_NPIV_SUPPORTED)) { 1934*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 1935*fcf3ce44SJohn Forte "%s: NPIV currently not supported.", 1936*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 1937*fcf3ce44SJohn Forte 1938*fcf3ce44SJohn Forte return (DFC_NPIV_UNSUPPORTED); 1939*fcf3ce44SJohn Forte } 1940*fcf3ce44SJohn Forte } 1941*fcf3ce44SJohn Forte /* 1942*fcf3ce44SJohn Forte * Only the same WWNN and WWPN can be re-created 1943*fcf3ce44SJohn Forte */ 1944*fcf3ce44SJohn Forte bzero(wwn, 8); 1945*fcf3ce44SJohn Forte if (bcmp(wwn, dfc_vport.wwpn, 8) || bcmp(wwn, dfc_vport.wwnn, 0)) { 1946*fcf3ce44SJohn Forte for (vpi = 1; vpi <= hba->vpi_max; vpi++) { 1947*fcf3ce44SJohn Forte vport = &VPORT(vpi); 1948*fcf3ce44SJohn Forte 1949*fcf3ce44SJohn Forte if ((bcmp((caddr_t)&vport->wwnn, 1950*fcf3ce44SJohn Forte (caddr_t)dfc_vport.wwnn, 8) == 0) && 1951*fcf3ce44SJohn Forte (bcmp((caddr_t)&vport->wwpn, 1952*fcf3ce44SJohn Forte (caddr_t)dfc_vport.wwpn, 8) == 0)) { 1953*fcf3ce44SJohn Forte if (!(vport->flag & EMLXS_PORT_CONFIG) && 1954*fcf3ce44SJohn Forte (vport->flag & EMLXS_PORT_BOUND)) { 1955*fcf3ce44SJohn Forte dfc_vport.vpi = vpi; 1956*fcf3ce44SJohn Forte break; 1957*fcf3ce44SJohn Forte } else { 1958*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 1959*fcf3ce44SJohn Forte &emlxs_dfc_error_msg, 1960*fcf3ce44SJohn Forte "%s: VPI already in use.", 1961*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 1962*fcf3ce44SJohn Forte 1963*fcf3ce44SJohn Forte return (DFC_ARG_INVALID); 1964*fcf3ce44SJohn Forte } 1965*fcf3ce44SJohn Forte } 1966*fcf3ce44SJohn Forte } 1967*fcf3ce44SJohn Forte } /* else auto assign */ 1968*fcf3ce44SJohn Forte /* Acquire a VPI */ 1969*fcf3ce44SJohn Forte if (dfc_vport.vpi == 0) { 1970*fcf3ce44SJohn Forte /* Auto Assign VPI */ 1971*fcf3ce44SJohn Forte for (vpi = 1; vpi <= hba->vpi_max; vpi++) { 1972*fcf3ce44SJohn Forte vport = &VPORT(vpi); 1973*fcf3ce44SJohn Forte 1974*fcf3ce44SJohn Forte if (!(vport->flag & EMLXS_PORT_CONFIG)) { 1975*fcf3ce44SJohn Forte break; 1976*fcf3ce44SJohn Forte } 1977*fcf3ce44SJohn Forte } 1978*fcf3ce44SJohn Forte 1979*fcf3ce44SJohn Forte if (vpi > hba->vpi_max) { 1980*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 1981*fcf3ce44SJohn Forte "%s: Out of resources.", 1982*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 1983*fcf3ce44SJohn Forte 1984*fcf3ce44SJohn Forte return (DFC_DRVRES_ERROR); 1985*fcf3ce44SJohn Forte } 1986*fcf3ce44SJohn Forte dfc_vport.vpi = vpi; 1987*fcf3ce44SJohn Forte } 1988*fcf3ce44SJohn Forte /* Establish a WWPN */ 1989*fcf3ce44SJohn Forte bzero(wwn, 8); 1990*fcf3ce44SJohn Forte if (bcmp(wwn, dfc_vport.wwpn, 8) == 0) { 1991*fcf3ce44SJohn Forte /* Generate new WWPN */ 1992*fcf3ce44SJohn Forte bcopy((caddr_t)&hba->wwpn, (caddr_t)dfc_vport.wwpn, 8); 1993*fcf3ce44SJohn Forte dfc_vport.wwpn[0] = 0x20; 1994*fcf3ce44SJohn Forte dfc_vport.wwpn[1] = vpi; 1995*fcf3ce44SJohn Forte } else { /* use one provided */ 1996*fcf3ce44SJohn Forte /* Make sure WWPN is unique */ 1997*fcf3ce44SJohn Forte if (emlxs_vport_find_wwpn(hba, dfc_vport.wwpn)) { 1998*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 1999*fcf3ce44SJohn Forte "%s: WWPN already exists. vpi=%d", 2000*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), vpi); 2001*fcf3ce44SJohn Forte 2002*fcf3ce44SJohn Forte return (DFC_ARG_INVALID); 2003*fcf3ce44SJohn Forte } 2004*fcf3ce44SJohn Forte } 2005*fcf3ce44SJohn Forte 2006*fcf3ce44SJohn Forte /* Establish a WWNN */ 2007*fcf3ce44SJohn Forte bzero(wwn, 8); 2008*fcf3ce44SJohn Forte if (bcmp(wwn, dfc_vport.wwnn, 8) == 0) { 2009*fcf3ce44SJohn Forte /* Generate new WWNN */ 2010*fcf3ce44SJohn Forte bcopy((caddr_t)&hba->wwnn, (caddr_t)dfc_vport.wwnn, 8); 2011*fcf3ce44SJohn Forte dfc_vport.wwnn[0] = 0x28; 2012*fcf3ce44SJohn Forte dfc_vport.wwnn[1] = vpi; 2013*fcf3ce44SJohn Forte } 2014*fcf3ce44SJohn Forte /* else use WWNN provided */ 2015*fcf3ce44SJohn Forte 2016*fcf3ce44SJohn Forte /* Generate the symbolic node name */ 2017*fcf3ce44SJohn Forte if (dfc_vport.snn[0]) { 2018*fcf3ce44SJohn Forte (void) strcpy(name, dfc_vport.snn); 2019*fcf3ce44SJohn Forte (void) sprintf(dfc_vport.snn, "%s %s", hba->snn, name); 2020*fcf3ce44SJohn Forte } else { 2021*fcf3ce44SJohn Forte (void) strcpy(dfc_vport.snn, hba->snn); 2022*fcf3ce44SJohn Forte } 2023*fcf3ce44SJohn Forte 2024*fcf3ce44SJohn Forte /* Generate the symbolic port name */ 2025*fcf3ce44SJohn Forte if (dfc_vport.spn[0]) { 2026*fcf3ce44SJohn Forte (void) strcpy(name, dfc_vport.spn); 2027*fcf3ce44SJohn Forte (void) sprintf(dfc_vport.spn, "%s VPort-%d VName-%s", 2028*fcf3ce44SJohn Forte hba->spn, vpi, name); 2029*fcf3ce44SJohn Forte } else { 2030*fcf3ce44SJohn Forte (void) sprintf(dfc_vport.spn, "%s VPort-%d", hba->spn, vpi); 2031*fcf3ce44SJohn Forte } 2032*fcf3ce44SJohn Forte 2033*fcf3ce44SJohn Forte dfc_vport.port_id = 0; 2034*fcf3ce44SJohn Forte dfc_vport.ulp_statec = FC_STATE_OFFLINE; 2035*fcf3ce44SJohn Forte dfc_vport.flags = VPORT_CONFIG; 2036*fcf3ce44SJohn Forte 2037*fcf3ce44SJohn Forte /* Set the highest configured vpi */ 2038*fcf3ce44SJohn Forte if (dfc_vport.vpi >= hba->vpi_high) { 2039*fcf3ce44SJohn Forte hba->vpi_high = dfc_vport.vpi; 2040*fcf3ce44SJohn Forte } 2041*fcf3ce44SJohn Forte /* Configure the port object */ 2042*fcf3ce44SJohn Forte bcopy((caddr_t)dfc_vport.wwnn, (caddr_t)&vport->wwnn, 8); 2043*fcf3ce44SJohn Forte bcopy((caddr_t)dfc_vport.wwpn, (caddr_t)&vport->wwpn, 8); 2044*fcf3ce44SJohn Forte (void) strncpy((caddr_t)vport->snn, (caddr_t)dfc_vport.snn, 256); 2045*fcf3ce44SJohn Forte (void) strncpy((caddr_t)vport->spn, (caddr_t)dfc_vport.spn, 256); 2046*fcf3ce44SJohn Forte vport->flag |= (EMLXS_PORT_CONFIG | EMLXS_PORT_ENABLE); 2047*fcf3ce44SJohn Forte 2048*fcf3ce44SJohn Forte /* Adjust restricted flags */ 2049*fcf3ce44SJohn Forte vport->options &= ~EMLXS_OPT_RESTRICT_MASK; 2050*fcf3ce44SJohn Forte vport->flag &= ~EMLXS_PORT_RESTRICTED; 2051*fcf3ce44SJohn Forte if (options & VPORT_OPT_RESTRICT) { 2052*fcf3ce44SJohn Forte vport->options |= EMLXS_OPT_RESTRICT; 2053*fcf3ce44SJohn Forte vport->flag |= EMLXS_PORT_RESTRICTED; 2054*fcf3ce44SJohn Forte dfc_vport.flags |= VPORT_RESTRICTED; 2055*fcf3ce44SJohn Forte } else if (options & VPORT_OPT_UNRESTRICT) { 2056*fcf3ce44SJohn Forte vport->options |= EMLXS_OPT_UNRESTRICT; 2057*fcf3ce44SJohn Forte } else if (cfg[CFG_VPORT_RESTRICTED].current) { 2058*fcf3ce44SJohn Forte vport->flag |= EMLXS_PORT_RESTRICTED; 2059*fcf3ce44SJohn Forte dfc_vport.flags |= VPORT_RESTRICTED; 2060*fcf3ce44SJohn Forte } 2061*fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT 2062*fcf3ce44SJohn Forte if (vport->tgt_mode) { 2063*fcf3ce44SJohn Forte emlxs_fct_bind_port(vport); 2064*fcf3ce44SJohn Forte } 2065*fcf3ce44SJohn Forte #endif /* SFCT_SUPPORT */ 2066*fcf3ce44SJohn Forte 2067*fcf3ce44SJohn Forte if (ddi_copyout((void *)&dfc_vport, (void *)dfc->buf1, 2068*fcf3ce44SJohn Forte sizeof (dfc_vportinfo_t), mode) != 0) { 2069*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2070*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 2071*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2072*fcf3ce44SJohn Forte 2073*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 2074*fcf3ce44SJohn Forte } 2075*fcf3ce44SJohn Forte if (vport->flag & EMLXS_PORT_BOUND) { 2076*fcf3ce44SJohn Forte /* 2077*fcf3ce44SJohn Forte * The same WWNN, WWPN and VPI has been re-created. Bring up 2078*fcf3ce44SJohn Forte * the vport now! 2079*fcf3ce44SJohn Forte */ 2080*fcf3ce44SJohn Forte emlxs_port_online(vport); 2081*fcf3ce44SJohn Forte } 2082*fcf3ce44SJohn Forte return (0); 2083*fcf3ce44SJohn Forte 2084*fcf3ce44SJohn Forte } /* emlxs_dfc_create_vport() */ 2085*fcf3ce44SJohn Forte 2086*fcf3ce44SJohn Forte 2087*fcf3ce44SJohn Forte static int32_t 2088*fcf3ce44SJohn Forte emlxs_dfc_destroy_vport(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 2089*fcf3ce44SJohn Forte { 2090*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2091*fcf3ce44SJohn Forte emlxs_port_t *vport; 2092*fcf3ce44SJohn Forte uint8_t wwpn[8]; 2093*fcf3ce44SJohn Forte fc_packet_t *pkt = NULL; 2094*fcf3ce44SJohn Forte uint32_t rval = 0; 2095*fcf3ce44SJohn Forte ELS_PKT *els; 2096*fcf3ce44SJohn Forte char buffer[256]; 2097*fcf3ce44SJohn Forte 2098*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 2099*fcf3ce44SJohn Forte "%s requested.", 2100*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2101*fcf3ce44SJohn Forte 2102*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 2103*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2104*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 2105*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2106*fcf3ce44SJohn Forte 2107*fcf3ce44SJohn Forte rval = DFC_ARG_NULL; 2108*fcf3ce44SJohn Forte goto done; 2109*fcf3ce44SJohn Forte } 2110*fcf3ce44SJohn Forte if (dfc->buf1_size < 8) { 2111*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2112*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 2113*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 2114*fcf3ce44SJohn Forte 2115*fcf3ce44SJohn Forte rval = DFC_ARG_TOOSMALL; 2116*fcf3ce44SJohn Forte goto done; 2117*fcf3ce44SJohn Forte } 2118*fcf3ce44SJohn Forte /* Read the wwn object */ 2119*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf1, (void *)wwpn, 8, mode) != 0) { 2120*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2121*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 2122*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2123*fcf3ce44SJohn Forte 2124*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 2125*fcf3ce44SJohn Forte goto done; 2126*fcf3ce44SJohn Forte } 2127*fcf3ce44SJohn Forte /* Make sure WWPN is unique */ 2128*fcf3ce44SJohn Forte vport = emlxs_vport_find_wwpn(hba, wwpn); 2129*fcf3ce44SJohn Forte 2130*fcf3ce44SJohn Forte if (!vport) { 2131*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2132*fcf3ce44SJohn Forte "%s: WWPN does not exists. %s", 2133*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 2134*fcf3ce44SJohn Forte emlxs_wwn_xlate(buffer, wwpn)); 2135*fcf3ce44SJohn Forte 2136*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 2137*fcf3ce44SJohn Forte goto done; 2138*fcf3ce44SJohn Forte } 2139*fcf3ce44SJohn Forte if (vport->did) { 2140*fcf3ce44SJohn Forte /* Fabric Logout */ 2141*fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(vport, 2142*fcf3ce44SJohn Forte sizeof (uint32_t) + sizeof (LOGO), 2143*fcf3ce44SJohn Forte sizeof (FCP_RSP), 0, KM_NOSLEEP))) { 2144*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2145*fcf3ce44SJohn Forte "%s: Unable to allocate packet.", 2146*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2147*fcf3ce44SJohn Forte 2148*fcf3ce44SJohn Forte rval = DFC_SYSRES_ERROR; 2149*fcf3ce44SJohn Forte goto done; 2150*fcf3ce44SJohn Forte } 2151*fcf3ce44SJohn Forte /* Make this a polled IO */ 2152*fcf3ce44SJohn Forte pkt->pkt_tran_flags &= ~FC_TRAN_INTR; 2153*fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_NO_INTR; 2154*fcf3ce44SJohn Forte pkt->pkt_comp = NULL; 2155*fcf3ce44SJohn Forte 2156*fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE; 2157*fcf3ce44SJohn Forte pkt->pkt_timeout = 60; 2158*fcf3ce44SJohn Forte 2159*fcf3ce44SJohn Forte /* Build the fc header */ 2160*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(Fabric_DID); 2161*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_ELS_REQ; 2162*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.s_id = SWAP_DATA24_LO(vport->did); 2163*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 2164*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = F_CTL_FIRST_SEQ | F_CTL_END_SEQ | 2165*fcf3ce44SJohn Forte F_CTL_SEQ_INITIATIVE; 2166*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 2167*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 2168*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 2169*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xFFFF; 2170*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xFFFF; 2171*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 2172*fcf3ce44SJohn Forte 2173*fcf3ce44SJohn Forte /* Build the command */ 2174*fcf3ce44SJohn Forte els = (ELS_PKT *) pkt->pkt_cmd; 2175*fcf3ce44SJohn Forte els->elsCode = 0x05; /* LOGO */ 2176*fcf3ce44SJohn Forte els->un.logo.un.nPortId32 = SWAP_DATA32(vport->did); 2177*fcf3ce44SJohn Forte bcopy(&vport->wwpn, &els->un.logo.portName, 8); 2178*fcf3ce44SJohn Forte 2179*fcf3ce44SJohn Forte /* 2180*fcf3ce44SJohn Forte * Just send LOGO. Don't worry about result. This is just a 2181*fcf3ce44SJohn Forte * courtesy anyway. 2182*fcf3ce44SJohn Forte */ 2183*fcf3ce44SJohn Forte (void) emlxs_pkt_send(pkt, 1); 2184*fcf3ce44SJohn Forte 2185*fcf3ce44SJohn Forte 2186*fcf3ce44SJohn Forte /* Take the port offline */ 2187*fcf3ce44SJohn Forte (void) emlxs_port_offline(vport, 0xffffffff); 2188*fcf3ce44SJohn Forte } 2189*fcf3ce44SJohn Forte vport->flag &= ~(EMLXS_PORT_CONFIG | EMLXS_PORT_ENABLE); 2190*fcf3ce44SJohn Forte 2191*fcf3ce44SJohn Forte rval = 0; 2192*fcf3ce44SJohn Forte 2193*fcf3ce44SJohn Forte done: 2194*fcf3ce44SJohn Forte 2195*fcf3ce44SJohn Forte if (pkt) { 2196*fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 2197*fcf3ce44SJohn Forte } 2198*fcf3ce44SJohn Forte return (rval); 2199*fcf3ce44SJohn Forte 2200*fcf3ce44SJohn Forte } /* emlxs_dfc_destroy_vport() */ 2201*fcf3ce44SJohn Forte 2202*fcf3ce44SJohn Forte 2203*fcf3ce44SJohn Forte static int32_t 2204*fcf3ce44SJohn Forte emlxs_dfc_get_vportinfo(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 2205*fcf3ce44SJohn Forte { 2206*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2207*fcf3ce44SJohn Forte emlxs_port_t *vport; 2208*fcf3ce44SJohn Forte dfc_vportinfo_t *dfc_vport; 2209*fcf3ce44SJohn Forte dfc_vportinfo_t *dfc_vport_list = NULL; 2210*fcf3ce44SJohn Forte uint32_t i; 2211*fcf3ce44SJohn Forte /* uint32_t j; */ 2212*fcf3ce44SJohn Forte uint32_t size; 2213*fcf3ce44SJohn Forte uint32_t max_count; 2214*fcf3ce44SJohn Forte uint32_t rval = DFC_SUCCESS; 2215*fcf3ce44SJohn Forte 2216*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 2217*fcf3ce44SJohn Forte "%s requested.", 2218*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2219*fcf3ce44SJohn Forte 2220*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 2221*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2222*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 2223*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2224*fcf3ce44SJohn Forte 2225*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 2226*fcf3ce44SJohn Forte } 2227*fcf3ce44SJohn Forte size = (sizeof (dfc_vportinfo_t) * MAX_VPORTS); 2228*fcf3ce44SJohn Forte 2229*fcf3ce44SJohn Forte if (!(dfc_vport_list = (dfc_vportinfo_t *) 2230*fcf3ce44SJohn Forte kmem_zalloc(size, KM_NOSLEEP))) { 2231*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2232*fcf3ce44SJohn Forte "%s: Unable to allocate memory.", 2233*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2234*fcf3ce44SJohn Forte 2235*fcf3ce44SJohn Forte return (DFC_SYSRES_ERROR); 2236*fcf3ce44SJohn Forte } 2237*fcf3ce44SJohn Forte max_count = 0; 2238*fcf3ce44SJohn Forte for (i = 0; i <= hba->vpi_max; i++) { 2239*fcf3ce44SJohn Forte vport = &VPORT(i); 2240*fcf3ce44SJohn Forte dfc_vport = &dfc_vport_list[i]; 2241*fcf3ce44SJohn Forte 2242*fcf3ce44SJohn Forte if (!(vport->flag & EMLXS_PORT_CONFIG)) { 2243*fcf3ce44SJohn Forte continue; 2244*fcf3ce44SJohn Forte } 2245*fcf3ce44SJohn Forte bcopy(vport->snn, dfc_vport->snn, 256); 2246*fcf3ce44SJohn Forte bcopy(vport->spn, dfc_vport->spn, 256); 2247*fcf3ce44SJohn Forte bcopy(&vport->wwpn, dfc_vport->wwpn, 8); 2248*fcf3ce44SJohn Forte bcopy(&vport->wwnn, dfc_vport->wwnn, 8); 2249*fcf3ce44SJohn Forte dfc_vport->port_id = vport->did; 2250*fcf3ce44SJohn Forte dfc_vport->vpi = vport->vpi; 2251*fcf3ce44SJohn Forte dfc_vport->ulp_statec = vport->ulp_statec; 2252*fcf3ce44SJohn Forte dfc_vport->flags = VPORT_CONFIG; 2253*fcf3ce44SJohn Forte 2254*fcf3ce44SJohn Forte if (vport->flag & EMLXS_PORT_ENABLE) { 2255*fcf3ce44SJohn Forte dfc_vport->flags |= VPORT_ENABLED; 2256*fcf3ce44SJohn Forte } 2257*fcf3ce44SJohn Forte if (vport->flag & EMLXS_PORT_BOUND) { 2258*fcf3ce44SJohn Forte dfc_vport->flags |= VPORT_BOUND; 2259*fcf3ce44SJohn Forte } 2260*fcf3ce44SJohn Forte if (vport->flag & EMLXS_PORT_IP_UP) { 2261*fcf3ce44SJohn Forte dfc_vport->flags |= VPORT_IP; 2262*fcf3ce44SJohn Forte } 2263*fcf3ce44SJohn Forte if (vport->flag & EMLXS_PORT_RESTRICTED) { 2264*fcf3ce44SJohn Forte dfc_vport->flags |= VPORT_RESTRICTED; 2265*fcf3ce44SJohn Forte } 2266*fcf3ce44SJohn Forte max_count++; 2267*fcf3ce44SJohn Forte } 2268*fcf3ce44SJohn Forte 2269*fcf3ce44SJohn Forte max_count *= sizeof (dfc_vportinfo_t); 2270*fcf3ce44SJohn Forte 2271*fcf3ce44SJohn Forte if (max_count > dfc->buf1_size) { 2272*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2273*fcf3ce44SJohn Forte "%s: Buffer1 too small. (%d > %d)", 2274*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), max_count, 2275*fcf3ce44SJohn Forte dfc->buf1_size); 2276*fcf3ce44SJohn Forte 2277*fcf3ce44SJohn Forte rval = DFC_ARG_TOOSMALL; 2278*fcf3ce44SJohn Forte goto done; 2279*fcf3ce44SJohn Forte } 2280*fcf3ce44SJohn Forte if (ddi_copyout((void *)dfc_vport_list, (void *)dfc->buf1, 2281*fcf3ce44SJohn Forte dfc->buf1_size, mode) != 0) { 2282*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2283*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 2284*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2285*fcf3ce44SJohn Forte 2286*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 2287*fcf3ce44SJohn Forte goto done; 2288*fcf3ce44SJohn Forte } 2289*fcf3ce44SJohn Forte done: 2290*fcf3ce44SJohn Forte 2291*fcf3ce44SJohn Forte if (dfc_vport_list) { 2292*fcf3ce44SJohn Forte kmem_free(dfc_vport_list, size); 2293*fcf3ce44SJohn Forte } 2294*fcf3ce44SJohn Forte return (rval); 2295*fcf3ce44SJohn Forte 2296*fcf3ce44SJohn Forte } /* emlxs_dfc_get_vportinfo() */ 2297*fcf3ce44SJohn Forte 2298*fcf3ce44SJohn Forte 2299*fcf3ce44SJohn Forte static emlxs_port_t * 2300*fcf3ce44SJohn Forte emlxs_vport_find_wwpn(emlxs_hba_t *hba, uint8_t *wwpn) 2301*fcf3ce44SJohn Forte { 2302*fcf3ce44SJohn Forte emlxs_port_t *port; 2303*fcf3ce44SJohn Forte NODELIST *nlp; 2304*fcf3ce44SJohn Forte int i, j; 2305*fcf3ce44SJohn Forte 2306*fcf3ce44SJohn Forte for (i = 0; i <= hba->vpi_max; i++) { 2307*fcf3ce44SJohn Forte port = &VPORT(i); 2308*fcf3ce44SJohn Forte 2309*fcf3ce44SJohn Forte if (!(port->flag & EMLXS_PORT_CONFIG)) { 2310*fcf3ce44SJohn Forte continue; 2311*fcf3ce44SJohn Forte } 2312*fcf3ce44SJohn Forte /* Check Local N-port */ 2313*fcf3ce44SJohn Forte if (bcmp(&port->wwpn, wwpn, 8) == 0) { 2314*fcf3ce44SJohn Forte return (port); 2315*fcf3ce44SJohn Forte } 2316*fcf3ce44SJohn Forte /* Check Remote N-port */ 2317*fcf3ce44SJohn Forte rw_enter(&port->node_rwlock, RW_READER); 2318*fcf3ce44SJohn Forte for (j = 0; j < EMLXS_NUM_HASH_QUES; j++) { 2319*fcf3ce44SJohn Forte nlp = port->node_table[j]; 2320*fcf3ce44SJohn Forte while (nlp != NULL) { 2321*fcf3ce44SJohn Forte /* Check Local N-port */ 2322*fcf3ce44SJohn Forte if (bcmp(&nlp->nlp_portname, wwpn, 8) == 0) { 2323*fcf3ce44SJohn Forte rw_exit(&port->node_rwlock); 2324*fcf3ce44SJohn Forte return (port); 2325*fcf3ce44SJohn Forte } 2326*fcf3ce44SJohn Forte nlp = nlp->nlp_list_next; 2327*fcf3ce44SJohn Forte } 2328*fcf3ce44SJohn Forte } 2329*fcf3ce44SJohn Forte 2330*fcf3ce44SJohn Forte rw_exit(&port->node_rwlock); 2331*fcf3ce44SJohn Forte } 2332*fcf3ce44SJohn Forte 2333*fcf3ce44SJohn Forte return (0); 2334*fcf3ce44SJohn Forte 2335*fcf3ce44SJohn Forte } /* emlxs_vport_find_wwpn() */ 2336*fcf3ce44SJohn Forte 2337*fcf3ce44SJohn Forte 2338*fcf3ce44SJohn Forte static int32_t 2339*fcf3ce44SJohn Forte emlxs_dfc_npiv_resource(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 2340*fcf3ce44SJohn Forte { 2341*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2342*fcf3ce44SJohn Forte dfc_vport_resource_t vres; 2343*fcf3ce44SJohn Forte MAILBOXQ *mbq = NULL; 2344*fcf3ce44SJohn Forte MAILBOX *mb; 2345*fcf3ce44SJohn Forte uint32_t rval = DFC_SUCCESS; 2346*fcf3ce44SJohn Forte 2347*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 2348*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2349*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 2350*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2351*fcf3ce44SJohn Forte 2352*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 2353*fcf3ce44SJohn Forte } 2354*fcf3ce44SJohn Forte if (dfc->buf1_size < sizeof (dfc_vport_resource_t)) { 2355*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2356*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 2357*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 2358*fcf3ce44SJohn Forte 2359*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 2360*fcf3ce44SJohn Forte } 2361*fcf3ce44SJohn Forte if ((mbq = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_SLEEP)) == 0) { 2362*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2363*fcf3ce44SJohn Forte "%s: Unable to allocate mailbox buffer.", 2364*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2365*fcf3ce44SJohn Forte 2366*fcf3ce44SJohn Forte return (DFC_SYSRES_ERROR); 2367*fcf3ce44SJohn Forte } 2368*fcf3ce44SJohn Forte mb = (MAILBOX *)mbq; 2369*fcf3ce44SJohn Forte 2370*fcf3ce44SJohn Forte emlxs_mb_read_config(hba, mb); 2371*fcf3ce44SJohn Forte 2372*fcf3ce44SJohn Forte rval = emlxs_mb_issue_cmd(hba, mb, MBX_WAIT, 0); 2373*fcf3ce44SJohn Forte 2374*fcf3ce44SJohn Forte if (rval == MBX_TIMEOUT) { 2375*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2376*fcf3ce44SJohn Forte "%s: Mailbox timed out. cmd=%x", 2377*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 2378*fcf3ce44SJohn Forte 2379*fcf3ce44SJohn Forte rval = DFC_TIMEOUT; 2380*fcf3ce44SJohn Forte goto done; 2381*fcf3ce44SJohn Forte } 2382*fcf3ce44SJohn Forte if (rval) { 2383*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2384*fcf3ce44SJohn Forte "%s: %s failed. status=%x", 2385*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 2386*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), rval); 2387*fcf3ce44SJohn Forte 2388*fcf3ce44SJohn Forte rval = DFC_IO_ERROR; 2389*fcf3ce44SJohn Forte goto done; 2390*fcf3ce44SJohn Forte } 2391*fcf3ce44SJohn Forte bzero(&vres, sizeof (dfc_vport_resource_t)); 2392*fcf3ce44SJohn Forte vres.vpi_max = mb->un.varRdConfig.max_vpi; 2393*fcf3ce44SJohn Forte vres.vpi_inuse = (mb->un.varRdConfig.max_vpi <= 2394*fcf3ce44SJohn Forte mb->un.varRdConfig.avail_vpi) ? 0 : 2395*fcf3ce44SJohn Forte mb->un.varRdConfig.max_vpi - 2396*fcf3ce44SJohn Forte mb->un.varRdConfig.avail_vpi; 2397*fcf3ce44SJohn Forte 2398*fcf3ce44SJohn Forte vres.rpi_max = mb->un.varRdConfig.max_rpi; 2399*fcf3ce44SJohn Forte vres.rpi_inuse = (mb->un.varRdConfig.max_rpi <= 2400*fcf3ce44SJohn Forte mb->un.varRdConfig.avail_rpi) ? 0 : 2401*fcf3ce44SJohn Forte mb->un.varRdConfig.max_rpi - 2402*fcf3ce44SJohn Forte mb->un.varRdConfig.avail_rpi; 2403*fcf3ce44SJohn Forte 2404*fcf3ce44SJohn Forte if (ddi_copyout((void *)&vres, (void *)dfc->buf1, 2405*fcf3ce44SJohn Forte sizeof (dfc_vport_resource_t), mode) != 0) { 2406*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2407*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 2408*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2409*fcf3ce44SJohn Forte 2410*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 2411*fcf3ce44SJohn Forte } 2412*fcf3ce44SJohn Forte done: 2413*fcf3ce44SJohn Forte 2414*fcf3ce44SJohn Forte /* Free allocated mbox memory */ 2415*fcf3ce44SJohn Forte if (mbq) { 2416*fcf3ce44SJohn Forte kmem_free(mbq, sizeof (MAILBOXQ)); 2417*fcf3ce44SJohn Forte } 2418*fcf3ce44SJohn Forte return (rval); 2419*fcf3ce44SJohn Forte 2420*fcf3ce44SJohn Forte } /* emlxs_dfc_npiv_resource() */ 2421*fcf3ce44SJohn Forte 2422*fcf3ce44SJohn Forte 2423*fcf3ce44SJohn Forte static int32_t 2424*fcf3ce44SJohn Forte emlxs_dfc_npiv_test(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 2425*fcf3ce44SJohn Forte { 2426*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2427*fcf3ce44SJohn Forte emlxs_port_t *vport = &VPORT(hba->vpi_max); 2428*fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 2429*fcf3ce44SJohn Forte fc_packet_t *pkt = NULL; 2430*fcf3ce44SJohn Forte fc_packet_t *pkt1 = NULL; 2431*fcf3ce44SJohn Forte ELS_PKT *els; 2432*fcf3ce44SJohn Forte /* SERV_PARM *sp; */ 2433*fcf3ce44SJohn Forte LS_RJT *lsrjt; 2434*fcf3ce44SJohn Forte uint32_t checklist = 0; 2435*fcf3ce44SJohn Forte uint32_t rval = DFC_SUCCESS; 2436*fcf3ce44SJohn Forte uint8_t wwn[8]; 2437*fcf3ce44SJohn Forte emlxs_vpd_t *vpd = &VPD; 2438*fcf3ce44SJohn Forte int i; 2439*fcf3ce44SJohn Forte 2440*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 2441*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2442*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 2443*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2444*fcf3ce44SJohn Forte 2445*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 2446*fcf3ce44SJohn Forte } 2447*fcf3ce44SJohn Forte if (dfc->buf1_size < sizeof (uint32_t)) { 2448*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2449*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 2450*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 2451*fcf3ce44SJohn Forte 2452*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 2453*fcf3ce44SJohn Forte } 2454*fcf3ce44SJohn Forte if (cfg[CFG_NPIV_ENABLE].current) { 2455*fcf3ce44SJohn Forte checklist |= CL_NPIV_PARM_ENABLE; 2456*fcf3ce44SJohn Forte } 2457*fcf3ce44SJohn Forte if (hba->sli_mode >= 3) { 2458*fcf3ce44SJohn Forte checklist |= CL_SLI3_ENABLE; 2459*fcf3ce44SJohn Forte } 2460*fcf3ce44SJohn Forte if (vpd->feaLevelHigh >= 0x09) { 2461*fcf3ce44SJohn Forte checklist |= CL_HBA_SUPPORT_NPIV; 2462*fcf3ce44SJohn Forte } 2463*fcf3ce44SJohn Forte if (hba->num_of_ports <= hba->vpi_max) { 2464*fcf3ce44SJohn Forte checklist |= CL_HBA_HAS_RESOURCES; 2465*fcf3ce44SJohn Forte } 2466*fcf3ce44SJohn Forte if (hba->state < FC_LINK_UP) { 2467*fcf3ce44SJohn Forte goto done; 2468*fcf3ce44SJohn Forte } 2469*fcf3ce44SJohn Forte checklist |= CL_HBA_LINKUP; 2470*fcf3ce44SJohn Forte 2471*fcf3ce44SJohn Forte if (hba->topology == TOPOLOGY_LOOP) { 2472*fcf3ce44SJohn Forte goto done; 2473*fcf3ce44SJohn Forte } 2474*fcf3ce44SJohn Forte if (!(hba->flag & FC_FABRIC_ATTACHED)) { 2475*fcf3ce44SJohn Forte goto done; 2476*fcf3ce44SJohn Forte } 2477*fcf3ce44SJohn Forte checklist |= CL_P2P_TOPOLOGY; 2478*fcf3ce44SJohn Forte 2479*fcf3ce44SJohn Forte if (!(hba->flag & FC_NPIV_SUPPORTED)) { 2480*fcf3ce44SJohn Forte goto done; 2481*fcf3ce44SJohn Forte } 2482*fcf3ce44SJohn Forte checklist |= CL_FABRIC_SUPPORTS_NPIV; 2483*fcf3ce44SJohn Forte 2484*fcf3ce44SJohn Forte /* Does fabric have resources? */ 2485*fcf3ce44SJohn Forte 2486*fcf3ce44SJohn Forte /* Check if we have resources */ 2487*fcf3ce44SJohn Forte if (!(checklist & CL_HBA_HAS_RESOURCES)) { 2488*fcf3ce44SJohn Forte /* 2489*fcf3ce44SJohn Forte * If we're out of resources then it doesn't matter if fabric 2490*fcf3ce44SJohn Forte * has resources 2491*fcf3ce44SJohn Forte */ 2492*fcf3ce44SJohn Forte goto done; 2493*fcf3ce44SJohn Forte } else { 2494*fcf3ce44SJohn Forte /* Now check if fabric have resources */ 2495*fcf3ce44SJohn Forte for (i = 1; i <= hba->vpi_max; i++) { 2496*fcf3ce44SJohn Forte vport = &VPORT(i); 2497*fcf3ce44SJohn Forte if (vport->did) { 2498*fcf3ce44SJohn Forte checklist |= CL_FABRIC_HAS_RESOURCES; 2499*fcf3ce44SJohn Forte goto done; 2500*fcf3ce44SJohn Forte } 2501*fcf3ce44SJohn Forte } 2502*fcf3ce44SJohn Forte } 2503*fcf3ce44SJohn Forte 2504*fcf3ce44SJohn Forte vport->vpi = hba->vpi_max; 2505*fcf3ce44SJohn Forte vport->hba = hba; 2506*fcf3ce44SJohn Forte 2507*fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(vport, 2508*fcf3ce44SJohn Forte sizeof (uint32_t) + sizeof (SERV_PARM), 2509*fcf3ce44SJohn Forte sizeof (FCP_RSP), 0, KM_NOSLEEP))) { 2510*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2511*fcf3ce44SJohn Forte "Unable to allocate packet."); 2512*fcf3ce44SJohn Forte goto done; 2513*fcf3ce44SJohn Forte } 2514*fcf3ce44SJohn Forte /* Build (FDISC) the fc header */ 2515*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(Fabric_DID); 2516*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_EXTENDED_SVC | R_CTL_UNSOL_CONTROL; 2517*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.s_id = 0; 2518*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 2519*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = F_CTL_FIRST_SEQ | F_CTL_SEQ_INITIATIVE; 2520*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 2521*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 2522*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 2523*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xffff; 2524*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xffff; 2525*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 2526*fcf3ce44SJohn Forte 2527*fcf3ce44SJohn Forte /* Build the command (FDISC) */ 2528*fcf3ce44SJohn Forte els = (ELS_PKT *)pkt->pkt_cmd; 2529*fcf3ce44SJohn Forte els->elsCode = 0x04; /* FLOGI - This will be changed automatically */ 2530*fcf3ce44SJohn Forte /* by the drive (See emlxs_send_els()) */ 2531*fcf3ce44SJohn Forte 2532*fcf3ce44SJohn Forte els->un.logi.cmn.fcphHigh = 0x09; 2533*fcf3ce44SJohn Forte els->un.logi.cmn.fcphLow = 0x08; 2534*fcf3ce44SJohn Forte els->un.logi.cmn.bbCreditMsb = 0xff; 2535*fcf3ce44SJohn Forte els->un.logi.cmn.bbCreditlsb = 0xff; 2536*fcf3ce44SJohn Forte els->un.logi.cmn.reqMultipleNPort = 1; 2537*fcf3ce44SJohn Forte els->un.logi.cmn.bbRcvSizeMsb = 0x08; 2538*fcf3ce44SJohn Forte els->un.logi.cmn.bbRcvSizeLsb = 0x00; 2539*fcf3ce44SJohn Forte els->un.logi.cmn.w2.nPort.totalConcurrSeq = 0xff; 2540*fcf3ce44SJohn Forte els->un.logi.cmn.w2.nPort.roByCategoryMsb = 0xff; 2541*fcf3ce44SJohn Forte els->un.logi.cmn.w2.nPort.roByCategoryLsb = 0xff; 2542*fcf3ce44SJohn Forte els->un.logi.cmn.e_d_tov = 0x7d0; 2543*fcf3ce44SJohn Forte 2544*fcf3ce44SJohn Forte bcopy((caddr_t)&hba->wwnn, (caddr_t)wwn, 8); 2545*fcf3ce44SJohn Forte wwn[0] = 0x28; 2546*fcf3ce44SJohn Forte wwn[1] = hba->vpi_max; 2547*fcf3ce44SJohn Forte bcopy((caddr_t)wwn, (caddr_t)&els->un.logi.nodeName, 8); 2548*fcf3ce44SJohn Forte 2549*fcf3ce44SJohn Forte bcopy((caddr_t)&hba->wwpn, (caddr_t)wwn, 8); 2550*fcf3ce44SJohn Forte wwn[0] = 0x20; 2551*fcf3ce44SJohn Forte wwn[1] = hba->vpi_max; 2552*fcf3ce44SJohn Forte bcopy((caddr_t)wwn, (caddr_t)&els->un.logi.portName, 8); 2553*fcf3ce44SJohn Forte 2554*fcf3ce44SJohn Forte els->un.logi.cls1.openSeqPerXchgMsb = 0x00; 2555*fcf3ce44SJohn Forte els->un.logi.cls1.openSeqPerXchgLsb = 0x01; 2556*fcf3ce44SJohn Forte 2557*fcf3ce44SJohn Forte els->un.logi.cls2.classValid = 1; 2558*fcf3ce44SJohn Forte els->un.logi.cls2.rcvDataSizeMsb = 0x08; 2559*fcf3ce44SJohn Forte els->un.logi.cls2.rcvDataSizeLsb = 0x00; 2560*fcf3ce44SJohn Forte els->un.logi.cls2.concurrentSeqMsb = 0x00; 2561*fcf3ce44SJohn Forte els->un.logi.cls2.concurrentSeqLsb = 0xff; 2562*fcf3ce44SJohn Forte els->un.logi.cls2.EeCreditSeqMsb = 0x00; 2563*fcf3ce44SJohn Forte els->un.logi.cls2.EeCreditSeqLsb = 0x0c; 2564*fcf3ce44SJohn Forte els->un.logi.cls2.openSeqPerXchgMsb = 0x00; 2565*fcf3ce44SJohn Forte els->un.logi.cls2.openSeqPerXchgLsb = 0x01; 2566*fcf3ce44SJohn Forte 2567*fcf3ce44SJohn Forte els->un.logi.cls3.classValid = 1; 2568*fcf3ce44SJohn Forte els->un.logi.cls3.rcvDataSizeMsb = 0x08; 2569*fcf3ce44SJohn Forte els->un.logi.cls3.rcvDataSizeLsb = 0x00; 2570*fcf3ce44SJohn Forte els->un.logi.cls3.concurrentSeqMsb = 0x00; 2571*fcf3ce44SJohn Forte els->un.logi.cls3.concurrentSeqLsb = 0xff; 2572*fcf3ce44SJohn Forte els->un.logi.cls3.openSeqPerXchgMsb = 0x00; 2573*fcf3ce44SJohn Forte els->un.logi.cls3.openSeqPerXchgLsb = 0x01; 2574*fcf3ce44SJohn Forte 2575*fcf3ce44SJohn Forte bcopy((void *)&els->un.logi, (void *)&vport->sparam, 2576*fcf3ce44SJohn Forte sizeof (SERV_PARM)); 2577*fcf3ce44SJohn Forte 2578*fcf3ce44SJohn Forte /* Make this a polled IO */ 2579*fcf3ce44SJohn Forte pkt->pkt_tran_flags &= ~FC_TRAN_INTR; 2580*fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_NO_INTR; 2581*fcf3ce44SJohn Forte pkt->pkt_comp = NULL; 2582*fcf3ce44SJohn Forte 2583*fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE; 2584*fcf3ce44SJohn Forte pkt->pkt_timeout = 60; 2585*fcf3ce44SJohn Forte 2586*fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 2587*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2588*fcf3ce44SJohn Forte "%s: Unable to send packet.", 2589*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2590*fcf3ce44SJohn Forte 2591*fcf3ce44SJohn Forte goto done; 2592*fcf3ce44SJohn Forte } 2593*fcf3ce44SJohn Forte if (pkt->pkt_state == FC_PKT_SUCCESS) { 2594*fcf3ce44SJohn Forte if (!(pkt1 = emlxs_pkt_alloc(vport, 2595*fcf3ce44SJohn Forte sizeof (uint32_t) + sizeof (LOGO), 2596*fcf3ce44SJohn Forte sizeof (FCP_RSP), 0, KM_NOSLEEP))) { 2597*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2598*fcf3ce44SJohn Forte "Unable to allocate LOGO packet."); 2599*fcf3ce44SJohn Forte goto free_resc; 2600*fcf3ce44SJohn Forte } 2601*fcf3ce44SJohn Forte /* Make this a polled IO */ 2602*fcf3ce44SJohn Forte pkt1->pkt_tran_flags &= ~FC_TRAN_INTR; 2603*fcf3ce44SJohn Forte pkt1->pkt_tran_flags |= FC_TRAN_NO_INTR; 2604*fcf3ce44SJohn Forte pkt1->pkt_comp = NULL; 2605*fcf3ce44SJohn Forte 2606*fcf3ce44SJohn Forte pkt1->pkt_tran_type = FC_PKT_EXCHANGE; 2607*fcf3ce44SJohn Forte pkt1->pkt_timeout = 60; 2608*fcf3ce44SJohn Forte 2609*fcf3ce44SJohn Forte /* Build (LOGO) the fc header */ 2610*fcf3ce44SJohn Forte pkt1->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(Fabric_DID); 2611*fcf3ce44SJohn Forte pkt1->pkt_cmd_fhdr.r_ctl = R_CTL_ELS_REQ; 2612*fcf3ce44SJohn Forte pkt1->pkt_cmd_fhdr.s_id = 2613*fcf3ce44SJohn Forte SWAP_DATA24_LO(pkt->pkt_resp_fhdr.d_id); 2614*fcf3ce44SJohn Forte pkt1->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 2615*fcf3ce44SJohn Forte pkt1->pkt_cmd_fhdr.f_ctl = F_CTL_FIRST_SEQ | F_CTL_END_SEQ | 2616*fcf3ce44SJohn Forte F_CTL_SEQ_INITIATIVE; 2617*fcf3ce44SJohn Forte pkt1->pkt_cmd_fhdr.seq_id = 0; 2618*fcf3ce44SJohn Forte pkt1->pkt_cmd_fhdr.df_ctl = 0; 2619*fcf3ce44SJohn Forte pkt1->pkt_cmd_fhdr.seq_cnt = 0; 2620*fcf3ce44SJohn Forte pkt1->pkt_cmd_fhdr.ox_id = 0xFFFF; 2621*fcf3ce44SJohn Forte pkt1->pkt_cmd_fhdr.rx_id = 0xFFFF; 2622*fcf3ce44SJohn Forte pkt1->pkt_cmd_fhdr.ro = 0; 2623*fcf3ce44SJohn Forte 2624*fcf3ce44SJohn Forte /* Build the command (LOGO) */ 2625*fcf3ce44SJohn Forte els = (ELS_PKT *)pkt1->pkt_cmd; 2626*fcf3ce44SJohn Forte els->elsCode = 0x05; /* LOGO */ 2627*fcf3ce44SJohn Forte els->un.logo.un.nPortId32 = 2628*fcf3ce44SJohn Forte SWAP_DATA32(pkt->pkt_resp_fhdr.d_id); 2629*fcf3ce44SJohn Forte bcopy((caddr_t)&hba->wwpn, (caddr_t)wwn, 8); 2630*fcf3ce44SJohn Forte wwn[0] = 0x20; 2631*fcf3ce44SJohn Forte wwn[1] = hba->vpi_max; 2632*fcf3ce44SJohn Forte bcopy(wwn, &els->un.logo.portName, 8); 2633*fcf3ce44SJohn Forte 2634*fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt1, 1) != FC_SUCCESS) { 2635*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2636*fcf3ce44SJohn Forte "%s: Unable to send packet.", 2637*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2638*fcf3ce44SJohn Forte 2639*fcf3ce44SJohn Forte goto free_resc; 2640*fcf3ce44SJohn Forte } 2641*fcf3ce44SJohn Forte if (pkt1->pkt_state != FC_PKT_SUCCESS) { 2642*fcf3ce44SJohn Forte if (pkt1->pkt_state == FC_PKT_TIMEOUT) { 2643*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2644*fcf3ce44SJohn Forte "%s: Pkt Transport error. Pkt Timeout.", 2645*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2646*fcf3ce44SJohn Forte } else { 2647*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2648*fcf3ce44SJohn Forte "%s: Pkt Transport error. state=%x", 2649*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 2650*fcf3ce44SJohn Forte pkt1->pkt_state); 2651*fcf3ce44SJohn Forte } 2652*fcf3ce44SJohn Forte goto free_resc; 2653*fcf3ce44SJohn Forte } 2654*fcf3ce44SJohn Forte checklist |= CL_FABRIC_HAS_RESOURCES; 2655*fcf3ce44SJohn Forte } else if (pkt->pkt_state == FC_PKT_LS_RJT) { 2656*fcf3ce44SJohn Forte lsrjt = (LS_RJT *) pkt->pkt_resp; 2657*fcf3ce44SJohn Forte if (lsrjt->un.b.lsRjtRsnCodeExp != LSEXP_OUT_OF_RESOURCE) { 2658*fcf3ce44SJohn Forte checklist |= CL_FABRIC_HAS_RESOURCES; 2659*fcf3ce44SJohn Forte } 2660*fcf3ce44SJohn Forte } 2661*fcf3ce44SJohn Forte /* 2662*fcf3ce44SJohn Forte * Free up default RPIs and VPI 2663*fcf3ce44SJohn Forte */ 2664*fcf3ce44SJohn Forte free_resc: 2665*fcf3ce44SJohn Forte (void) emlxs_mb_unreg_rpi(vport, 0xffff, 0, 0, 0); 2666*fcf3ce44SJohn Forte (void) emlxs_mb_unreg_vpi(vport); 2667*fcf3ce44SJohn Forte 2668*fcf3ce44SJohn Forte done: 2669*fcf3ce44SJohn Forte if (ddi_copyout((void *)&checklist, (void *)dfc->buf1, 2670*fcf3ce44SJohn Forte sizeof (uint32_t), mode) != 0) { 2671*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2672*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 2673*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2674*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 2675*fcf3ce44SJohn Forte } 2676*fcf3ce44SJohn Forte if (pkt) { 2677*fcf3ce44SJohn Forte /* Free the pkt */ 2678*fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 2679*fcf3ce44SJohn Forte } 2680*fcf3ce44SJohn Forte if (pkt1) { 2681*fcf3ce44SJohn Forte /* Free the pkt */ 2682*fcf3ce44SJohn Forte emlxs_pkt_free(pkt1); 2683*fcf3ce44SJohn Forte } 2684*fcf3ce44SJohn Forte return (rval); 2685*fcf3ce44SJohn Forte 2686*fcf3ce44SJohn Forte } /* emlxs_dfc_npiv_test() */ 2687*fcf3ce44SJohn Forte 2688*fcf3ce44SJohn Forte #endif /* NPIV_SUPPORT */ 2689*fcf3ce44SJohn Forte 2690*fcf3ce44SJohn Forte 2691*fcf3ce44SJohn Forte 2692*fcf3ce44SJohn Forte static int32_t 2693*fcf3ce44SJohn Forte emlxs_dfc_get_rev(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 2694*fcf3ce44SJohn Forte { 2695*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2696*fcf3ce44SJohn Forte uint32_t rev; 2697*fcf3ce44SJohn Forte 2698*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 2699*fcf3ce44SJohn Forte "%s requested.", 2700*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2701*fcf3ce44SJohn Forte 2702*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 2703*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2704*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 2705*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2706*fcf3ce44SJohn Forte 2707*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 2708*fcf3ce44SJohn Forte } 2709*fcf3ce44SJohn Forte if (dfc->buf1_size < sizeof (uint32_t)) { 2710*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2711*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 2712*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 2713*fcf3ce44SJohn Forte 2714*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 2715*fcf3ce44SJohn Forte } 2716*fcf3ce44SJohn Forte rev = DFC_REV; 2717*fcf3ce44SJohn Forte 2718*fcf3ce44SJohn Forte if (ddi_copyout((void *)&rev, (void *)dfc->buf1, 2719*fcf3ce44SJohn Forte sizeof (uint32_t), mode) != 0) { 2720*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2721*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 2722*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2723*fcf3ce44SJohn Forte 2724*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 2725*fcf3ce44SJohn Forte } 2726*fcf3ce44SJohn Forte return (0); 2727*fcf3ce44SJohn Forte 2728*fcf3ce44SJohn Forte } /* emlxs_dfc_get_rev() */ 2729*fcf3ce44SJohn Forte 2730*fcf3ce44SJohn Forte 2731*fcf3ce44SJohn Forte static int32_t 2732*fcf3ce44SJohn Forte emlxs_dfc_get_hbainfo(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 2733*fcf3ce44SJohn Forte { 2734*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2735*fcf3ce44SJohn Forte emlxs_vpd_t *vpd = &VPD; 2736*fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 2737*fcf3ce44SJohn Forte dfc_hbainfo_t hbainfo; 2738*fcf3ce44SJohn Forte NODELIST *ndlp; 2739*fcf3ce44SJohn Forte char pathname[256]; 2740*fcf3ce44SJohn Forte 2741*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 2742*fcf3ce44SJohn Forte "%s requested.", 2743*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2744*fcf3ce44SJohn Forte 2745*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 2746*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2747*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 2748*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2749*fcf3ce44SJohn Forte 2750*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 2751*fcf3ce44SJohn Forte } 2752*fcf3ce44SJohn Forte if (dfc->buf1_size < sizeof (dfc_hbainfo_t)) { 2753*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2754*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size = %d)", 2755*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 2756*fcf3ce44SJohn Forte 2757*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 2758*fcf3ce44SJohn Forte } 2759*fcf3ce44SJohn Forte bzero((void *)&hbainfo, sizeof (dfc_hbainfo_t)); 2760*fcf3ce44SJohn Forte 2761*fcf3ce44SJohn Forte (void) strncpy(hbainfo.vpd_serial_num, vpd->serial_num, 2762*fcf3ce44SJohn Forte sizeof (hbainfo.vpd_serial_num)); 2763*fcf3ce44SJohn Forte (void) strncpy(hbainfo.vpd_part_num, vpd->part_num, 2764*fcf3ce44SJohn Forte sizeof (hbainfo.vpd_part_num)); 2765*fcf3ce44SJohn Forte (void) strncpy(hbainfo.vpd_port_num, vpd->port_num, 2766*fcf3ce44SJohn Forte sizeof (hbainfo.vpd_port_num)); 2767*fcf3ce44SJohn Forte (void) strncpy(hbainfo.vpd_eng_change, vpd->eng_change, 2768*fcf3ce44SJohn Forte sizeof (hbainfo.vpd_eng_change)); 2769*fcf3ce44SJohn Forte (void) strncpy(hbainfo.vpd_manufacturer, vpd->manufacturer, 2770*fcf3ce44SJohn Forte sizeof (hbainfo.vpd_manufacturer)); 2771*fcf3ce44SJohn Forte (void) strncpy(hbainfo.vpd_model, vpd->model, 2772*fcf3ce44SJohn Forte sizeof (hbainfo.vpd_model)); 2773*fcf3ce44SJohn Forte (void) strncpy(hbainfo.vpd_model_desc, vpd->model_desc, 2774*fcf3ce44SJohn Forte sizeof (hbainfo.vpd_model_desc)); 2775*fcf3ce44SJohn Forte (void) strncpy(hbainfo.vpd_prog_types, vpd->prog_types, 2776*fcf3ce44SJohn Forte sizeof (hbainfo.vpd_prog_types)); 2777*fcf3ce44SJohn Forte (void) strncpy(hbainfo.vpd_id, vpd->id, sizeof (hbainfo.vpd_id)); 2778*fcf3ce44SJohn Forte 2779*fcf3ce44SJohn Forte hbainfo.device_id = hba->model_info.device_id; 2780*fcf3ce44SJohn Forte hbainfo.vendor_id = ddi_get32(hba->pci_acc_handle, 2781*fcf3ce44SJohn Forte (uint32_t *)(hba->pci_addr + PCI_VENDOR_ID_REGISTER)) & 0xffff; 2782*fcf3ce44SJohn Forte 2783*fcf3ce44SJohn Forte hbainfo.ports = hba->num_of_ports; 2784*fcf3ce44SJohn Forte hbainfo.port_index = vpd->port_index; 2785*fcf3ce44SJohn Forte 2786*fcf3ce44SJohn Forte bcopy(&hba->wwnn, hbainfo.wwnn, sizeof (hbainfo.wwnn)); 2787*fcf3ce44SJohn Forte (void) strncpy(hbainfo.snn, port->snn, sizeof (hbainfo.snn)); 2788*fcf3ce44SJohn Forte 2789*fcf3ce44SJohn Forte bcopy(&hba->wwpn, hbainfo.wwpn, sizeof (hbainfo.wwpn)); 2790*fcf3ce44SJohn Forte (void) strncpy(hbainfo.spn, port->spn, sizeof (hbainfo.spn)); 2791*fcf3ce44SJohn Forte 2792*fcf3ce44SJohn Forte hbainfo.biuRev = vpd->biuRev; 2793*fcf3ce44SJohn Forte hbainfo.smRev = vpd->smRev; 2794*fcf3ce44SJohn Forte hbainfo.smFwRev = vpd->smFwRev; 2795*fcf3ce44SJohn Forte hbainfo.endecRev = vpd->endecRev; 2796*fcf3ce44SJohn Forte hbainfo.rBit = vpd->rBit; 2797*fcf3ce44SJohn Forte hbainfo.fcphHigh = vpd->fcphHigh; 2798*fcf3ce44SJohn Forte hbainfo.fcphLow = vpd->fcphLow; 2799*fcf3ce44SJohn Forte hbainfo.feaLevelHigh = vpd->feaLevelHigh; 2800*fcf3ce44SJohn Forte hbainfo.feaLevelLow = vpd->feaLevelLow; 2801*fcf3ce44SJohn Forte 2802*fcf3ce44SJohn Forte hbainfo.kern_rev = vpd->postKernRev; 2803*fcf3ce44SJohn Forte (void) strncpy(hbainfo.kern_name, vpd->postKernName, 2804*fcf3ce44SJohn Forte sizeof (hbainfo.kern_name)); 2805*fcf3ce44SJohn Forte 2806*fcf3ce44SJohn Forte hbainfo.stub_rev = vpd->opFwRev; 2807*fcf3ce44SJohn Forte (void) strncpy(hbainfo.stub_name, vpd->opFwName, 2808*fcf3ce44SJohn Forte sizeof (hbainfo.stub_name)); 2809*fcf3ce44SJohn Forte 2810*fcf3ce44SJohn Forte hbainfo.sli1_rev = vpd->sli1FwRev; 2811*fcf3ce44SJohn Forte (void) strncpy(hbainfo.sli1_name, vpd->sli1FwName, 2812*fcf3ce44SJohn Forte sizeof (hbainfo.sli1_name)); 2813*fcf3ce44SJohn Forte 2814*fcf3ce44SJohn Forte hbainfo.sli2_rev = vpd->sli2FwRev; 2815*fcf3ce44SJohn Forte (void) strncpy(hbainfo.sli2_name, vpd->sli2FwName, 2816*fcf3ce44SJohn Forte sizeof (hbainfo.sli2_name)); 2817*fcf3ce44SJohn Forte 2818*fcf3ce44SJohn Forte hbainfo.sli3_rev = vpd->sli3FwRev; 2819*fcf3ce44SJohn Forte (void) strncpy(hbainfo.sli3_name, vpd->sli3FwName, 2820*fcf3ce44SJohn Forte sizeof (hbainfo.sli3_name)); 2821*fcf3ce44SJohn Forte 2822*fcf3ce44SJohn Forte hbainfo.sli4_rev = vpd->sli4FwRev; 2823*fcf3ce44SJohn Forte (void) strncpy(hbainfo.sli4_name, vpd->sli4FwName, 2824*fcf3ce44SJohn Forte sizeof (hbainfo.sli4_name)); 2825*fcf3ce44SJohn Forte 2826*fcf3ce44SJohn Forte hbainfo.sli_mode = hba->sli_mode; 2827*fcf3ce44SJohn Forte hbainfo.vpi_max = hba->vpi_max; 2828*fcf3ce44SJohn Forte hbainfo.vpi_high = hba->vpi_high; 2829*fcf3ce44SJohn Forte hbainfo.flags = 0; 2830*fcf3ce44SJohn Forte 2831*fcf3ce44SJohn Forte /* Set support flags */ 2832*fcf3ce44SJohn Forte hbainfo.flags = HBA_FLAG_DYN_WWN; 2833*fcf3ce44SJohn Forte 2834*fcf3ce44SJohn Forte #ifdef NPIV_SUPPORT 2835*fcf3ce44SJohn Forte hbainfo.flags |= HBA_FLAG_NPIV; 2836*fcf3ce44SJohn Forte #endif /* NPIV_SUPPORT */ 2837*fcf3ce44SJohn Forte 2838*fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 2839*fcf3ce44SJohn Forte hbainfo.flags |= HBA_FLAG_DHCHAP; 2840*fcf3ce44SJohn Forte 2841*fcf3ce44SJohn Forte if (cfg[CFG_AUTH_E2E].current) { 2842*fcf3ce44SJohn Forte hbainfo.flags |= HBA_FLAG_E2E_AUTH; 2843*fcf3ce44SJohn Forte } 2844*fcf3ce44SJohn Forte #endif /* DHCHAP_SUPPORT */ 2845*fcf3ce44SJohn Forte 2846*fcf3ce44SJohn Forte (void) strncpy(hbainfo.fcode_version, vpd->fcode_version, 2847*fcf3ce44SJohn Forte sizeof (hbainfo.fcode_version)); 2848*fcf3ce44SJohn Forte (void) strncpy(hbainfo.boot_version, vpd->boot_version, 2849*fcf3ce44SJohn Forte sizeof (hbainfo.boot_version)); 2850*fcf3ce44SJohn Forte (void) strncpy(hbainfo.fw_version, vpd->fw_version, 2851*fcf3ce44SJohn Forte sizeof (hbainfo.fw_version)); 2852*fcf3ce44SJohn Forte (void) strncpy(hbainfo.drv_label, emlxs_label, 2853*fcf3ce44SJohn Forte sizeof (hbainfo.drv_label)); 2854*fcf3ce44SJohn Forte (void) strncpy(hbainfo.drv_module, emlxs_name, 2855*fcf3ce44SJohn Forte sizeof (hbainfo.drv_module)); 2856*fcf3ce44SJohn Forte (void) strncpy(hbainfo.drv_name, DRIVER_NAME, 2857*fcf3ce44SJohn Forte sizeof (hbainfo.drv_name)); 2858*fcf3ce44SJohn Forte (void) strncpy(hbainfo.drv_version, emlxs_version, 2859*fcf3ce44SJohn Forte sizeof (hbainfo.drv_version)); 2860*fcf3ce44SJohn Forte (void) strncpy(hbainfo.drv_revision, emlxs_revision, 2861*fcf3ce44SJohn Forte sizeof (hbainfo.drv_revision)); 2862*fcf3ce44SJohn Forte (void) strncpy(hbainfo.hostname, (char *)utsname.nodename, 2863*fcf3ce44SJohn Forte sizeof (hbainfo.hostname)); 2864*fcf3ce44SJohn Forte 2865*fcf3ce44SJohn Forte (void) ddi_pathname(hba->dip, pathname); 2866*fcf3ce44SJohn Forte (void) sprintf(hbainfo.os_devname, "/devices%s", pathname); 2867*fcf3ce44SJohn Forte 2868*fcf3ce44SJohn Forte if (hba->flag & (FC_OFFLINE_MODE | FC_OFFLINING_MODE)) { 2869*fcf3ce44SJohn Forte hbainfo.flags |= HBA_FLAG_OFFLINE; 2870*fcf3ce44SJohn Forte } 2871*fcf3ce44SJohn Forte hbainfo.drv_instance = hba->ddiinst; 2872*fcf3ce44SJohn Forte hbainfo.port_id = port->did; 2873*fcf3ce44SJohn Forte hbainfo.port_type = HBA_PORTTYPE_UNKNOWN; 2874*fcf3ce44SJohn Forte 2875*fcf3ce44SJohn Forte #ifdef MENLO_SUPPORT 2876*fcf3ce44SJohn Forte if (hba->flag & FC_MENLO_MODE) { 2877*fcf3ce44SJohn Forte hbainfo.topology = LNK_MENLO_MAINTENANCE; 2878*fcf3ce44SJohn Forte } else 2879*fcf3ce44SJohn Forte #endif /* MENLO_SUPPORT */ 2880*fcf3ce44SJohn Forte 2881*fcf3ce44SJohn Forte if (hba->state >= FC_LINK_UP) { 2882*fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, Fabric_DID); 2883*fcf3ce44SJohn Forte 2884*fcf3ce44SJohn Forte if (hba->topology == TOPOLOGY_LOOP) { 2885*fcf3ce44SJohn Forte if (ndlp) { 2886*fcf3ce44SJohn Forte hbainfo.port_type = HBA_PORTTYPE_NLPORT; 2887*fcf3ce44SJohn Forte hbainfo.topology = LNK_PUBLIC_LOOP; 2888*fcf3ce44SJohn Forte } else { 2889*fcf3ce44SJohn Forte hbainfo.port_type = HBA_PORTTYPE_LPORT; 2890*fcf3ce44SJohn Forte hbainfo.topology = LNK_LOOP; 2891*fcf3ce44SJohn Forte } 2892*fcf3ce44SJohn Forte 2893*fcf3ce44SJohn Forte hbainfo.alpa_count = port->alpa_map[0]; 2894*fcf3ce44SJohn Forte bcopy((void *)&port->alpa_map[1], hbainfo.alpa_map, 2895*fcf3ce44SJohn Forte hbainfo.alpa_count); 2896*fcf3ce44SJohn Forte } else { 2897*fcf3ce44SJohn Forte if (ndlp) { 2898*fcf3ce44SJohn Forte hbainfo.port_type = HBA_PORTTYPE_NPORT; 2899*fcf3ce44SJohn Forte hbainfo.topology = LNK_FABRIC; 2900*fcf3ce44SJohn Forte } else { 2901*fcf3ce44SJohn Forte hbainfo.port_type = HBA_PORTTYPE_PTP; 2902*fcf3ce44SJohn Forte hbainfo.topology = LNK_PT2PT; 2903*fcf3ce44SJohn Forte } 2904*fcf3ce44SJohn Forte } 2905*fcf3ce44SJohn Forte 2906*fcf3ce44SJohn Forte if (ndlp) { 2907*fcf3ce44SJohn Forte bcopy(&ndlp->nlp_nodename, hbainfo.fabric_wwnn, 2908*fcf3ce44SJohn Forte sizeof (hbainfo.fabric_wwnn)); 2909*fcf3ce44SJohn Forte bcopy(&ndlp->nlp_portname, hbainfo.fabric_wwpn, 2910*fcf3ce44SJohn Forte sizeof (hbainfo.fabric_wwpn)); 2911*fcf3ce44SJohn Forte } 2912*fcf3ce44SJohn Forte if (hba->linkspeed == LA_2GHZ_LINK) { 2913*fcf3ce44SJohn Forte hbainfo.port_speed = HBA_PORTSPEED_2GBIT; 2914*fcf3ce44SJohn Forte } else if (hba->linkspeed == LA_4GHZ_LINK) { 2915*fcf3ce44SJohn Forte hbainfo.port_speed = HBA_PORTSPEED_4GBIT; 2916*fcf3ce44SJohn Forte } else if (hba->linkspeed == LA_8GHZ_LINK) { 2917*fcf3ce44SJohn Forte hbainfo.port_speed = HBA_PORTSPEED_8GBIT; 2918*fcf3ce44SJohn Forte } else if (hba->linkspeed == LA_10GHZ_LINK) { 2919*fcf3ce44SJohn Forte hbainfo.port_speed = HBA_PORTSPEED_10GBIT; 2920*fcf3ce44SJohn Forte } else { 2921*fcf3ce44SJohn Forte hbainfo.port_speed = HBA_PORTSPEED_1GBIT; 2922*fcf3ce44SJohn Forte } 2923*fcf3ce44SJohn Forte 2924*fcf3ce44SJohn Forte hbainfo.node_count = port->node_count; 2925*fcf3ce44SJohn Forte } 2926*fcf3ce44SJohn Forte hbainfo.hard_alpa = cfg[CFG_ASSIGN_ALPA].current; 2927*fcf3ce44SJohn Forte hbainfo.supported_cos = SWAP_DATA32((FC_NS_CLASS3 | FC_NS_CLASS2)); 2928*fcf3ce44SJohn Forte 2929*fcf3ce44SJohn Forte hbainfo.supported_types[0] = SWAP_DATA32(0x00000120); 2930*fcf3ce44SJohn Forte hbainfo.supported_types[1] = SWAP_DATA32(0x00000001); 2931*fcf3ce44SJohn Forte 2932*fcf3ce44SJohn Forte hbainfo.active_types[0] = SWAP_DATA32(0x00000120); 2933*fcf3ce44SJohn Forte hbainfo.active_types[1] = SWAP_DATA32(0x00000001); 2934*fcf3ce44SJohn Forte 2935*fcf3ce44SJohn Forte if (!cfg[CFG_NETWORK_ON].current) { 2936*fcf3ce44SJohn Forte hbainfo.active_types[0] &= ~(SWAP_DATA32(0x00000020)); 2937*fcf3ce44SJohn Forte } 2938*fcf3ce44SJohn Forte if (vpd->link_speed & LMT_10GB_CAPABLE) { 2939*fcf3ce44SJohn Forte hbainfo.supported_speeds |= FC_HBA_PORTSPEED_10GBIT; 2940*fcf3ce44SJohn Forte } 2941*fcf3ce44SJohn Forte if (vpd->link_speed & LMT_8GB_CAPABLE) { 2942*fcf3ce44SJohn Forte hbainfo.supported_speeds |= FC_HBA_PORTSPEED_8GBIT; 2943*fcf3ce44SJohn Forte } 2944*fcf3ce44SJohn Forte if (vpd->link_speed & LMT_4GB_CAPABLE) { 2945*fcf3ce44SJohn Forte hbainfo.supported_speeds |= FC_HBA_PORTSPEED_4GBIT; 2946*fcf3ce44SJohn Forte } 2947*fcf3ce44SJohn Forte if (vpd->link_speed & LMT_2GB_CAPABLE) { 2948*fcf3ce44SJohn Forte hbainfo.supported_speeds |= FC_HBA_PORTSPEED_2GBIT; 2949*fcf3ce44SJohn Forte } 2950*fcf3ce44SJohn Forte if (vpd->link_speed & LMT_1GB_CAPABLE) { 2951*fcf3ce44SJohn Forte hbainfo.supported_speeds |= FC_HBA_PORTSPEED_1GBIT; 2952*fcf3ce44SJohn Forte } 2953*fcf3ce44SJohn Forte hbainfo.max_frame_size = FF_FRAME_SIZE; 2954*fcf3ce44SJohn Forte 2955*fcf3ce44SJohn Forte if (hba->bus_type == SBUS_FC) { 2956*fcf3ce44SJohn Forte hbainfo.flags |= HBA_FLAG_SBUS; 2957*fcf3ce44SJohn Forte } 2958*fcf3ce44SJohn Forte if (hba->flag & (FC_ONLINING_MODE | FC_OFFLINING_MODE)) { 2959*fcf3ce44SJohn Forte hbainfo.flags |= HBA_FLAG_OFFLINE; 2960*fcf3ce44SJohn Forte hbainfo.port_state = HBA_PORTSTATE_UNKNOWN; 2961*fcf3ce44SJohn Forte } else if (hba->flag & FC_ONLINE_MODE) { 2962*fcf3ce44SJohn Forte if (hba->flag & FC_LOOPBACK_MODE) { 2963*fcf3ce44SJohn Forte hbainfo.port_state = HBA_PORTSTATE_LOOPBACK; 2964*fcf3ce44SJohn Forte } else if (hba->state <= FC_LINK_DOWN) { 2965*fcf3ce44SJohn Forte hbainfo.port_state = HBA_PORTSTATE_LINKDOWN; 2966*fcf3ce44SJohn Forte } 2967*fcf3ce44SJohn Forte #ifdef MENLO_SUPPORT 2968*fcf3ce44SJohn Forte else if (hba->flag & FC_MENLO_MODE) { 2969*fcf3ce44SJohn Forte hbainfo.port_state = HBA_PORTSTATE_LINKDOWN; 2970*fcf3ce44SJohn Forte } 2971*fcf3ce44SJohn Forte #endif /* MENLO_SUPPORT */ 2972*fcf3ce44SJohn Forte else { 2973*fcf3ce44SJohn Forte hbainfo.port_state = HBA_PORTSTATE_ONLINE; 2974*fcf3ce44SJohn Forte } 2975*fcf3ce44SJohn Forte } else { 2976*fcf3ce44SJohn Forte hbainfo.flags |= HBA_FLAG_OFFLINE; 2977*fcf3ce44SJohn Forte 2978*fcf3ce44SJohn Forte if (hba->state == FC_ERROR) { 2979*fcf3ce44SJohn Forte hbainfo.port_state = HBA_PORTSTATE_ERROR; 2980*fcf3ce44SJohn Forte } else { 2981*fcf3ce44SJohn Forte hbainfo.port_state = HBA_PORTSTATE_OFFLINE; 2982*fcf3ce44SJohn Forte } 2983*fcf3ce44SJohn Forte } 2984*fcf3ce44SJohn Forte 2985*fcf3ce44SJohn Forte if (ddi_copyout((void *)&hbainfo, (void *)dfc->buf1, 2986*fcf3ce44SJohn Forte sizeof (dfc_hbainfo_t), mode) != 0) { 2987*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 2988*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 2989*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 2990*fcf3ce44SJohn Forte 2991*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 2992*fcf3ce44SJohn Forte } 2993*fcf3ce44SJohn Forte return (0); 2994*fcf3ce44SJohn Forte 2995*fcf3ce44SJohn Forte } /* emlxs_dfc_get_hbainfo() */ 2996*fcf3ce44SJohn Forte 2997*fcf3ce44SJohn Forte 2998*fcf3ce44SJohn Forte 2999*fcf3ce44SJohn Forte static int32_t 3000*fcf3ce44SJohn Forte emlxs_dfc_get_hbastats(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 3001*fcf3ce44SJohn Forte { 3002*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3003*fcf3ce44SJohn Forte dfc_hbastats_t stats; 3004*fcf3ce44SJohn Forte MAILBOX *mb = NULL; 3005*fcf3ce44SJohn Forte MAILBOXQ *mbq = NULL; 3006*fcf3ce44SJohn Forte uint32_t rval = 0; 3007*fcf3ce44SJohn Forte 3008*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 3009*fcf3ce44SJohn Forte "%s requested.", 3010*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 3011*fcf3ce44SJohn Forte 3012*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 3013*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3014*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 3015*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 3016*fcf3ce44SJohn Forte 3017*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 3018*fcf3ce44SJohn Forte } 3019*fcf3ce44SJohn Forte if (dfc->buf1_size < sizeof (dfc_hbastats_t)) { 3020*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3021*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 3022*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 3023*fcf3ce44SJohn Forte 3024*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 3025*fcf3ce44SJohn Forte } 3026*fcf3ce44SJohn Forte if ((mbq = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_SLEEP)) == 0) { 3027*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3028*fcf3ce44SJohn Forte "%s: Unable to allocate mailbox buffer.", 3029*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 3030*fcf3ce44SJohn Forte 3031*fcf3ce44SJohn Forte return (DFC_SYSRES_ERROR); 3032*fcf3ce44SJohn Forte } 3033*fcf3ce44SJohn Forte mb = (MAILBOX *) mbq; 3034*fcf3ce44SJohn Forte 3035*fcf3ce44SJohn Forte emlxs_mb_read_status(hba, mb); 3036*fcf3ce44SJohn Forte 3037*fcf3ce44SJohn Forte rval = emlxs_mb_issue_cmd(hba, mb, MBX_WAIT, 0); 3038*fcf3ce44SJohn Forte 3039*fcf3ce44SJohn Forte if (rval == MBX_TIMEOUT) { 3040*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3041*fcf3ce44SJohn Forte "%s: Mailbox timed out. cmd=%x", 3042*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3043*fcf3ce44SJohn Forte 3044*fcf3ce44SJohn Forte rval = DFC_TIMEOUT; 3045*fcf3ce44SJohn Forte goto done; 3046*fcf3ce44SJohn Forte } 3047*fcf3ce44SJohn Forte if (rval) { 3048*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3049*fcf3ce44SJohn Forte "%s: %s failed. status=%x", 3050*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 3051*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), 3052*fcf3ce44SJohn Forte rval); 3053*fcf3ce44SJohn Forte 3054*fcf3ce44SJohn Forte rval = DFC_IO_ERROR; 3055*fcf3ce44SJohn Forte goto done; 3056*fcf3ce44SJohn Forte } 3057*fcf3ce44SJohn Forte bzero((void *)&stats, sizeof (dfc_hbastats_t)); 3058*fcf3ce44SJohn Forte 3059*fcf3ce44SJohn Forte stats.tx_frame_cnt = mb->un.varRdStatus.xmitFrameCnt; 3060*fcf3ce44SJohn Forte stats.rx_frame_cnt = mb->un.varRdStatus.rcvFrameCnt; 3061*fcf3ce44SJohn Forte stats.tx_kbyte_cnt = mb->un.varRdStatus.xmitByteCnt; 3062*fcf3ce44SJohn Forte stats.rx_kbyte_cnt = mb->un.varRdStatus.rcvByteCnt; 3063*fcf3ce44SJohn Forte stats.tx_seq_cnt = mb->un.varRdStatus.xmitSeqCnt; 3064*fcf3ce44SJohn Forte stats.rx_seq_cnt = mb->un.varRdStatus.rcvSeqCnt; 3065*fcf3ce44SJohn Forte stats.orig_exch_cnt = mb->un.varRdStatus.totalOrigExchanges; 3066*fcf3ce44SJohn Forte stats.resp_exch_cnt = mb->un.varRdStatus.totalRespExchanges; 3067*fcf3ce44SJohn Forte stats.pbsy_cnt = mb->un.varRdStatus.rcvPbsyCnt; 3068*fcf3ce44SJohn Forte stats.fbsy_cnt = mb->un.varRdStatus.rcvFbsyCnt; 3069*fcf3ce44SJohn Forte 3070*fcf3ce44SJohn Forte emlxs_mb_read_lnk_stat(hba, mb); 3071*fcf3ce44SJohn Forte 3072*fcf3ce44SJohn Forte rval = emlxs_mb_issue_cmd(hba, mb, MBX_WAIT, 0); 3073*fcf3ce44SJohn Forte 3074*fcf3ce44SJohn Forte if (rval == MBX_TIMEOUT) { 3075*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3076*fcf3ce44SJohn Forte "%s: Mailbox timed out. cmd=%x", 3077*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3078*fcf3ce44SJohn Forte 3079*fcf3ce44SJohn Forte rval = DFC_TIMEOUT; 3080*fcf3ce44SJohn Forte goto done; 3081*fcf3ce44SJohn Forte } 3082*fcf3ce44SJohn Forte if (rval) { 3083*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3084*fcf3ce44SJohn Forte "%s: %s failed. status=%x", 3085*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 3086*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), 3087*fcf3ce44SJohn Forte rval); 3088*fcf3ce44SJohn Forte 3089*fcf3ce44SJohn Forte rval = DFC_IO_ERROR; 3090*fcf3ce44SJohn Forte goto done; 3091*fcf3ce44SJohn Forte } 3092*fcf3ce44SJohn Forte stats.link_failure_cnt = mb->un.varRdLnk.linkFailureCnt; 3093*fcf3ce44SJohn Forte stats.loss_sync_cnt = mb->un.varRdLnk.lossSyncCnt; 3094*fcf3ce44SJohn Forte stats.loss_signal_cnt = mb->un.varRdLnk.lossSignalCnt; 3095*fcf3ce44SJohn Forte stats.seq_error_cnt = mb->un.varRdLnk.primSeqErrCnt; 3096*fcf3ce44SJohn Forte stats.inval_tx_word_cnt = mb->un.varRdLnk.invalidXmitWord; 3097*fcf3ce44SJohn Forte stats.crc_error_cnt = mb->un.varRdLnk.crcCnt; 3098*fcf3ce44SJohn Forte stats.seq_timeout_cnt = mb->un.varRdLnk.primSeqTimeout; 3099*fcf3ce44SJohn Forte stats.elastic_overrun_cnt = mb->un.varRdLnk.elasticOverrun; 3100*fcf3ce44SJohn Forte stats.arb_timeout_cnt = mb->un.varRdLnk.arbTimeout; 3101*fcf3ce44SJohn Forte stats.rx_buf_credit = mb->un.varRdLnk.rxBufCredit; 3102*fcf3ce44SJohn Forte stats.rx_buf_cnt = mb->un.varRdLnk.rxBufCreditCur; 3103*fcf3ce44SJohn Forte stats.tx_buf_credit = mb->un.varRdLnk.txBufCredit; 3104*fcf3ce44SJohn Forte stats.tx_buf_cnt = mb->un.varRdLnk.txBufCreditCur; 3105*fcf3ce44SJohn Forte stats.EOFa_cnt = mb->un.varRdLnk.EOFaCnt; 3106*fcf3ce44SJohn Forte stats.EOFdti_cnt = mb->un.varRdLnk.EOFdtiCnt; 3107*fcf3ce44SJohn Forte stats.EOFni_cnt = mb->un.varRdLnk.EOFniCnt; 3108*fcf3ce44SJohn Forte stats.SOFf_cnt = mb->un.varRdLnk.SOFfCnt; 3109*fcf3ce44SJohn Forte stats.link_event_tag = hba->link_event_tag; 3110*fcf3ce44SJohn Forte stats.last_reset_time = hba->timer_tics - hba->stats.ResetTime; 3111*fcf3ce44SJohn Forte stats.port_type = HBA_PORTTYPE_UNKNOWN; 3112*fcf3ce44SJohn Forte 3113*fcf3ce44SJohn Forte #ifdef MENLO_SUPPORT 3114*fcf3ce44SJohn Forte if (hba->flag & FC_MENLO_MODE) { 3115*fcf3ce44SJohn Forte stats.topology = LNK_MENLO_MAINTENANCE; 3116*fcf3ce44SJohn Forte } else 3117*fcf3ce44SJohn Forte #endif /* MENLO_SUPPORT */ 3118*fcf3ce44SJohn Forte 3119*fcf3ce44SJohn Forte if (hba->state >= FC_LINK_UP) { 3120*fcf3ce44SJohn Forte if (hba->topology == TOPOLOGY_LOOP) { 3121*fcf3ce44SJohn Forte if (hba->flag & FC_FABRIC_ATTACHED) { 3122*fcf3ce44SJohn Forte stats.port_type = HBA_PORTTYPE_NLPORT; 3123*fcf3ce44SJohn Forte stats.topology = LNK_PUBLIC_LOOP; 3124*fcf3ce44SJohn Forte } else { 3125*fcf3ce44SJohn Forte stats.port_type = HBA_PORTTYPE_LPORT; 3126*fcf3ce44SJohn Forte stats.topology = LNK_LOOP; 3127*fcf3ce44SJohn Forte } 3128*fcf3ce44SJohn Forte } else { 3129*fcf3ce44SJohn Forte if (hba->flag & FC_FABRIC_ATTACHED) { 3130*fcf3ce44SJohn Forte stats.port_type = HBA_PORTTYPE_NPORT; 3131*fcf3ce44SJohn Forte stats.topology = LNK_FABRIC; 3132*fcf3ce44SJohn Forte } else { 3133*fcf3ce44SJohn Forte stats.port_type = HBA_PORTTYPE_PTP; 3134*fcf3ce44SJohn Forte stats.topology = LNK_PT2PT; 3135*fcf3ce44SJohn Forte } 3136*fcf3ce44SJohn Forte } 3137*fcf3ce44SJohn Forte 3138*fcf3ce44SJohn Forte if (hba->linkspeed == LA_2GHZ_LINK) { 3139*fcf3ce44SJohn Forte stats.link_speed = HBA_PORTSPEED_2GBIT; 3140*fcf3ce44SJohn Forte } else if (hba->linkspeed == LA_4GHZ_LINK) { 3141*fcf3ce44SJohn Forte stats.link_speed = HBA_PORTSPEED_4GBIT; 3142*fcf3ce44SJohn Forte } else if (hba->linkspeed == LA_8GHZ_LINK) { 3143*fcf3ce44SJohn Forte stats.link_speed = HBA_PORTSPEED_8GBIT; 3144*fcf3ce44SJohn Forte } else if (hba->linkspeed == LA_10GHZ_LINK) { 3145*fcf3ce44SJohn Forte stats.link_speed = HBA_PORTSPEED_10GBIT; 3146*fcf3ce44SJohn Forte } else { 3147*fcf3ce44SJohn Forte stats.link_speed = HBA_PORTSPEED_1GBIT; 3148*fcf3ce44SJohn Forte } 3149*fcf3ce44SJohn Forte } 3150*fcf3ce44SJohn Forte if (ddi_copyout((void *)&stats, (void *)dfc->buf1, 3151*fcf3ce44SJohn Forte sizeof (dfc_hbastats_t), mode) != 0) { 3152*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3153*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 3154*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 3155*fcf3ce44SJohn Forte 3156*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 3157*fcf3ce44SJohn Forte } 3158*fcf3ce44SJohn Forte done: 3159*fcf3ce44SJohn Forte 3160*fcf3ce44SJohn Forte /* Free allocated mbox memory */ 3161*fcf3ce44SJohn Forte if (mbq) { 3162*fcf3ce44SJohn Forte kmem_free(mbq, sizeof (MAILBOXQ)); 3163*fcf3ce44SJohn Forte } 3164*fcf3ce44SJohn Forte return (rval); 3165*fcf3ce44SJohn Forte 3166*fcf3ce44SJohn Forte } /* emlxs_dfc_get_hbastats() */ 3167*fcf3ce44SJohn Forte 3168*fcf3ce44SJohn Forte 3169*fcf3ce44SJohn Forte 3170*fcf3ce44SJohn Forte static int32_t 3171*fcf3ce44SJohn Forte emlxs_dfc_get_drvstats(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 3172*fcf3ce44SJohn Forte { 3173*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3174*fcf3ce44SJohn Forte dfc_drvstats_t stats; 3175*fcf3ce44SJohn Forte uint32_t rval = 0; 3176*fcf3ce44SJohn Forte 3177*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 3178*fcf3ce44SJohn Forte "%s requested.", 3179*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 3180*fcf3ce44SJohn Forte 3181*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 3182*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3183*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 3184*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 3185*fcf3ce44SJohn Forte 3186*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 3187*fcf3ce44SJohn Forte } 3188*fcf3ce44SJohn Forte bzero((void *)&stats, sizeof (dfc_drvstats_t)); 3189*fcf3ce44SJohn Forte 3190*fcf3ce44SJohn Forte stats.LinkUp = hba->stats.LinkUp; 3191*fcf3ce44SJohn Forte stats.LinkDown = hba->stats.LinkDown; 3192*fcf3ce44SJohn Forte stats.LinkEvent = hba->stats.LinkEvent; 3193*fcf3ce44SJohn Forte stats.LinkMultiEvent = hba->stats.LinkMultiEvent; 3194*fcf3ce44SJohn Forte 3195*fcf3ce44SJohn Forte stats.MboxIssued = hba->stats.MboxIssued; 3196*fcf3ce44SJohn Forte stats.MboxCompleted = hba->stats.MboxCompleted; 3197*fcf3ce44SJohn Forte stats.MboxGood = hba->stats.MboxGood; 3198*fcf3ce44SJohn Forte stats.MboxError = hba->stats.MboxError; 3199*fcf3ce44SJohn Forte stats.MboxBusy = hba->stats.MboxBusy; 3200*fcf3ce44SJohn Forte stats.MboxInvalid = hba->stats.MboxInvalid; 3201*fcf3ce44SJohn Forte 3202*fcf3ce44SJohn Forte stats.IocbIssued[0] = hba->stats.IocbIssued[0]; 3203*fcf3ce44SJohn Forte stats.IocbIssued[1] = hba->stats.IocbIssued[1]; 3204*fcf3ce44SJohn Forte stats.IocbIssued[2] = hba->stats.IocbIssued[2]; 3205*fcf3ce44SJohn Forte stats.IocbIssued[3] = hba->stats.IocbIssued[3]; 3206*fcf3ce44SJohn Forte stats.IocbReceived[0] = hba->stats.IocbReceived[0]; 3207*fcf3ce44SJohn Forte stats.IocbReceived[1] = hba->stats.IocbReceived[1]; 3208*fcf3ce44SJohn Forte stats.IocbReceived[2] = hba->stats.IocbReceived[2]; 3209*fcf3ce44SJohn Forte stats.IocbReceived[3] = hba->stats.IocbReceived[3]; 3210*fcf3ce44SJohn Forte stats.IocbTxPut[0] = hba->stats.IocbTxPut[0]; 3211*fcf3ce44SJohn Forte stats.IocbTxPut[1] = hba->stats.IocbTxPut[1]; 3212*fcf3ce44SJohn Forte stats.IocbTxPut[2] = hba->stats.IocbTxPut[2]; 3213*fcf3ce44SJohn Forte stats.IocbTxPut[3] = hba->stats.IocbTxPut[3]; 3214*fcf3ce44SJohn Forte stats.IocbTxGet[0] = hba->stats.IocbTxGet[0]; 3215*fcf3ce44SJohn Forte stats.IocbTxGet[1] = hba->stats.IocbTxGet[1]; 3216*fcf3ce44SJohn Forte stats.IocbTxGet[2] = hba->stats.IocbTxGet[2]; 3217*fcf3ce44SJohn Forte stats.IocbTxGet[3] = hba->stats.IocbTxGet[3]; 3218*fcf3ce44SJohn Forte stats.IocbRingFull[0] = hba->stats.IocbRingFull[0]; 3219*fcf3ce44SJohn Forte stats.IocbRingFull[1] = hba->stats.IocbRingFull[1]; 3220*fcf3ce44SJohn Forte stats.IocbRingFull[2] = hba->stats.IocbRingFull[2]; 3221*fcf3ce44SJohn Forte stats.IocbRingFull[3] = hba->stats.IocbRingFull[3]; 3222*fcf3ce44SJohn Forte 3223*fcf3ce44SJohn Forte stats.IntrEvent[0] = hba->stats.IntrEvent[0]; 3224*fcf3ce44SJohn Forte stats.IntrEvent[1] = hba->stats.IntrEvent[1]; 3225*fcf3ce44SJohn Forte stats.IntrEvent[2] = hba->stats.IntrEvent[2]; 3226*fcf3ce44SJohn Forte stats.IntrEvent[3] = hba->stats.IntrEvent[3]; 3227*fcf3ce44SJohn Forte stats.IntrEvent[4] = hba->stats.IntrEvent[4]; 3228*fcf3ce44SJohn Forte stats.IntrEvent[5] = hba->stats.IntrEvent[5]; 3229*fcf3ce44SJohn Forte stats.IntrEvent[6] = hba->stats.IntrEvent[6]; 3230*fcf3ce44SJohn Forte stats.IntrEvent[7] = hba->stats.IntrEvent[7]; 3231*fcf3ce44SJohn Forte 3232*fcf3ce44SJohn Forte stats.FcpIssued = hba->stats.FcpIssued; 3233*fcf3ce44SJohn Forte stats.FcpCompleted = hba->stats.FcpCompleted; 3234*fcf3ce44SJohn Forte stats.FcpGood = hba->stats.FcpGood; 3235*fcf3ce44SJohn Forte stats.FcpError = hba->stats.FcpError; 3236*fcf3ce44SJohn Forte 3237*fcf3ce44SJohn Forte stats.FcpEvent = hba->stats.FcpEvent; 3238*fcf3ce44SJohn Forte stats.FcpStray = hba->stats.FcpStray; 3239*fcf3ce44SJohn Forte 3240*fcf3ce44SJohn Forte stats.ElsEvent = hba->stats.ElsEvent; 3241*fcf3ce44SJohn Forte stats.ElsStray = hba->stats.ElsStray; 3242*fcf3ce44SJohn Forte 3243*fcf3ce44SJohn Forte stats.ElsCmdIssued = hba->stats.ElsCmdIssued; 3244*fcf3ce44SJohn Forte stats.ElsCmdCompleted = hba->stats.ElsCmdCompleted; 3245*fcf3ce44SJohn Forte stats.ElsCmdGood = hba->stats.ElsCmdGood; 3246*fcf3ce44SJohn Forte stats.ElsCmdError = hba->stats.ElsCmdError; 3247*fcf3ce44SJohn Forte 3248*fcf3ce44SJohn Forte stats.ElsRspIssued = hba->stats.ElsRspIssued; 3249*fcf3ce44SJohn Forte stats.ElsRspCompleted = hba->stats.ElsRspCompleted; 3250*fcf3ce44SJohn Forte 3251*fcf3ce44SJohn Forte stats.ElsRcvEvent = hba->stats.ElsRcvEvent; 3252*fcf3ce44SJohn Forte stats.ElsRcvError = hba->stats.ElsRcvError; 3253*fcf3ce44SJohn Forte stats.ElsRcvDropped = hba->stats.ElsRcvDropped; 3254*fcf3ce44SJohn Forte stats.ElsCmdReceived = hba->stats.ElsCmdReceived; 3255*fcf3ce44SJohn Forte stats.ElsRscnReceived = hba->stats.ElsRscnReceived; 3256*fcf3ce44SJohn Forte stats.ElsPlogiReceived = hba->stats.ElsPlogiReceived; 3257*fcf3ce44SJohn Forte stats.ElsPrliReceived = hba->stats.ElsPrliReceived; 3258*fcf3ce44SJohn Forte stats.ElsPrloReceived = hba->stats.ElsPrloReceived; 3259*fcf3ce44SJohn Forte stats.ElsLogoReceived = hba->stats.ElsLogoReceived; 3260*fcf3ce44SJohn Forte stats.ElsAdiscReceived = hba->stats.ElsAdiscReceived; 3261*fcf3ce44SJohn Forte stats.ElsGenReceived = hba->stats.ElsGenReceived; 3262*fcf3ce44SJohn Forte 3263*fcf3ce44SJohn Forte stats.CtEvent = hba->stats.CtEvent; 3264*fcf3ce44SJohn Forte stats.CtStray = hba->stats.CtStray; 3265*fcf3ce44SJohn Forte 3266*fcf3ce44SJohn Forte stats.CtCmdIssued = hba->stats.CtCmdIssued; 3267*fcf3ce44SJohn Forte stats.CtCmdCompleted = hba->stats.CtCmdCompleted; 3268*fcf3ce44SJohn Forte stats.CtCmdGood = hba->stats.CtCmdGood; 3269*fcf3ce44SJohn Forte stats.CtCmdError = hba->stats.CtCmdError; 3270*fcf3ce44SJohn Forte 3271*fcf3ce44SJohn Forte stats.CtRspIssued = hba->stats.CtRspIssued; 3272*fcf3ce44SJohn Forte stats.CtRspCompleted = hba->stats.CtRspCompleted; 3273*fcf3ce44SJohn Forte 3274*fcf3ce44SJohn Forte stats.CtRcvEvent = hba->stats.CtRcvEvent; 3275*fcf3ce44SJohn Forte stats.CtRcvError = hba->stats.CtRcvError; 3276*fcf3ce44SJohn Forte stats.CtRcvDropped = hba->stats.CtRcvDropped; 3277*fcf3ce44SJohn Forte stats.CtCmdReceived = hba->stats.CtCmdReceived; 3278*fcf3ce44SJohn Forte 3279*fcf3ce44SJohn Forte stats.IpEvent = hba->stats.IpEvent; 3280*fcf3ce44SJohn Forte stats.IpStray = hba->stats.IpStray; 3281*fcf3ce44SJohn Forte 3282*fcf3ce44SJohn Forte stats.IpSeqIssued = hba->stats.IpSeqIssued; 3283*fcf3ce44SJohn Forte stats.IpSeqCompleted = hba->stats.IpSeqCompleted; 3284*fcf3ce44SJohn Forte stats.IpSeqGood = hba->stats.IpSeqGood; 3285*fcf3ce44SJohn Forte stats.IpSeqError = hba->stats.IpSeqError; 3286*fcf3ce44SJohn Forte 3287*fcf3ce44SJohn Forte stats.IpBcastIssued = hba->stats.IpBcastIssued; 3288*fcf3ce44SJohn Forte stats.IpBcastCompleted = hba->stats.IpBcastCompleted; 3289*fcf3ce44SJohn Forte stats.IpBcastGood = hba->stats.IpBcastGood; 3290*fcf3ce44SJohn Forte stats.IpBcastError = hba->stats.IpBcastError; 3291*fcf3ce44SJohn Forte 3292*fcf3ce44SJohn Forte stats.IpRcvEvent = hba->stats.IpRcvEvent; 3293*fcf3ce44SJohn Forte stats.IpDropped = hba->stats.IpDropped; 3294*fcf3ce44SJohn Forte stats.IpSeqReceived = hba->stats.IpSeqReceived; 3295*fcf3ce44SJohn Forte stats.IpBcastReceived = hba->stats.IpBcastReceived; 3296*fcf3ce44SJohn Forte 3297*fcf3ce44SJohn Forte stats.IpUbPosted = hba->stats.IpUbPosted; 3298*fcf3ce44SJohn Forte stats.ElsUbPosted = hba->stats.ElsUbPosted; 3299*fcf3ce44SJohn Forte stats.CtUbPosted = hba->stats.CtUbPosted; 3300*fcf3ce44SJohn Forte 3301*fcf3ce44SJohn Forte #if (DFC_REV >= 2) 3302*fcf3ce44SJohn Forte stats.IocbThrottled = hba->stats.IocbThrottled; 3303*fcf3ce44SJohn Forte stats.ElsAuthReceived = hba->stats.ElsAuthReceived; 3304*fcf3ce44SJohn Forte #endif 3305*fcf3ce44SJohn Forte 3306*fcf3ce44SJohn Forte if (ddi_copyout((void *)&stats, (void *)dfc->buf1, 3307*fcf3ce44SJohn Forte dfc->buf1_size, mode) != 0) { 3308*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3309*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 3310*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 3311*fcf3ce44SJohn Forte 3312*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 3313*fcf3ce44SJohn Forte } 3314*fcf3ce44SJohn Forte return (rval); 3315*fcf3ce44SJohn Forte 3316*fcf3ce44SJohn Forte } /* emlxs_dfc_get_drvstats() */ 3317*fcf3ce44SJohn Forte 3318*fcf3ce44SJohn Forte 3319*fcf3ce44SJohn Forte static int32_t 3320*fcf3ce44SJohn Forte emlxs_dfc_set_diag(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 3321*fcf3ce44SJohn Forte { 3322*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3323*fcf3ce44SJohn Forte int32_t rval = 0; 3324*fcf3ce44SJohn Forte uint32_t flag; 3325*fcf3ce44SJohn Forte uint32_t i; 3326*fcf3ce44SJohn Forte 3327*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 3328*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3329*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 3330*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 3331*fcf3ce44SJohn Forte 3332*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 3333*fcf3ce44SJohn Forte } 3334*fcf3ce44SJohn Forte if (dfc->buf1_size < sizeof (uint32_t)) { 3335*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3336*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 3337*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 3338*fcf3ce44SJohn Forte 3339*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 3340*fcf3ce44SJohn Forte } 3341*fcf3ce44SJohn Forte flag = (uint32_t)dfc->flag; 3342*fcf3ce44SJohn Forte 3343*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 3344*fcf3ce44SJohn Forte 3345*fcf3ce44SJohn Forte /* Wait if adapter is in transition */ 3346*fcf3ce44SJohn Forte i = 0; 3347*fcf3ce44SJohn Forte while ((hba->flag & (FC_ONLINING_MODE | FC_OFFLINING_MODE))) { 3348*fcf3ce44SJohn Forte if (i++ > 30) { 3349*fcf3ce44SJohn Forte break; 3350*fcf3ce44SJohn Forte } 3351*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 3352*fcf3ce44SJohn Forte delay(drv_usectohz(1000000)); 3353*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 3354*fcf3ce44SJohn Forte } 3355*fcf3ce44SJohn Forte 3356*fcf3ce44SJohn Forte switch (flag) { 3357*fcf3ce44SJohn Forte case DDI_SHOW: 3358*fcf3ce44SJohn Forte break; 3359*fcf3ce44SJohn Forte 3360*fcf3ce44SJohn Forte case DDI_ONDI: 3361*fcf3ce44SJohn Forte if (hba->flag & FC_OFFLINE_MODE) { 3362*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 3363*fcf3ce44SJohn Forte (void) emlxs_online(hba); 3364*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 3365*fcf3ce44SJohn Forte } 3366*fcf3ce44SJohn Forte break; 3367*fcf3ce44SJohn Forte 3368*fcf3ce44SJohn Forte 3369*fcf3ce44SJohn Forte /* Killed + Restart state */ 3370*fcf3ce44SJohn Forte case DDI_OFFDI: 3371*fcf3ce44SJohn Forte if (hba->flag & FC_ONLINE_MODE) { 3372*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 3373*fcf3ce44SJohn Forte 3374*fcf3ce44SJohn Forte (void) emlxs_offline(hba); 3375*fcf3ce44SJohn Forte 3376*fcf3ce44SJohn Forte /* Reset with restart */ 3377*fcf3ce44SJohn Forte (void) emlxs_hba_reset(hba, 1, 1); 3378*fcf3ce44SJohn Forte 3379*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 3380*fcf3ce44SJohn Forte } else if (hba->state < FC_INIT_START) { 3381*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 3382*fcf3ce44SJohn Forte 3383*fcf3ce44SJohn Forte /* Reset with restart */ 3384*fcf3ce44SJohn Forte (void) emlxs_hba_reset(hba, 1, 1); 3385*fcf3ce44SJohn Forte 3386*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 3387*fcf3ce44SJohn Forte } 3388*fcf3ce44SJohn Forte break; 3389*fcf3ce44SJohn Forte 3390*fcf3ce44SJohn Forte /* Killed + Reset state */ 3391*fcf3ce44SJohn Forte case DDI_WARMDI: 3392*fcf3ce44SJohn Forte if (hba->flag & FC_ONLINE_MODE) { 3393*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 3394*fcf3ce44SJohn Forte 3395*fcf3ce44SJohn Forte (void) emlxs_offline(hba); 3396*fcf3ce44SJohn Forte 3397*fcf3ce44SJohn Forte /* Reset with no restart */ 3398*fcf3ce44SJohn Forte (void) emlxs_hba_reset(hba, 0, 0); 3399*fcf3ce44SJohn Forte 3400*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 3401*fcf3ce44SJohn Forte } else if (hba->state != FC_WARM_START) { 3402*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 3403*fcf3ce44SJohn Forte 3404*fcf3ce44SJohn Forte /* Reset with no restart */ 3405*fcf3ce44SJohn Forte (void) emlxs_hba_reset(hba, 0, 0); 3406*fcf3ce44SJohn Forte 3407*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 3408*fcf3ce44SJohn Forte } 3409*fcf3ce44SJohn Forte break; 3410*fcf3ce44SJohn Forte 3411*fcf3ce44SJohn Forte /* Killed */ 3412*fcf3ce44SJohn Forte case DDI_DIAGDI: 3413*fcf3ce44SJohn Forte if (hba->flag & FC_ONLINE_MODE) { 3414*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 3415*fcf3ce44SJohn Forte 3416*fcf3ce44SJohn Forte (void) emlxs_offline(hba); 3417*fcf3ce44SJohn Forte 3418*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 3419*fcf3ce44SJohn Forte } else if (hba->state != FC_KILLED) { 3420*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 3421*fcf3ce44SJohn Forte 3422*fcf3ce44SJohn Forte (void) emlxs_interlock(hba); 3423*fcf3ce44SJohn Forte 3424*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 3425*fcf3ce44SJohn Forte } 3426*fcf3ce44SJohn Forte break; 3427*fcf3ce44SJohn Forte 3428*fcf3ce44SJohn Forte default: 3429*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3430*fcf3ce44SJohn Forte "%s: Invalid flag. flag=%x", 3431*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), flag); 3432*fcf3ce44SJohn Forte 3433*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 3434*fcf3ce44SJohn Forte } 3435*fcf3ce44SJohn Forte 3436*fcf3ce44SJohn Forte /* Wait if adapter is in transition */ 3437*fcf3ce44SJohn Forte i = 0; 3438*fcf3ce44SJohn Forte while ((hba->flag & (FC_ONLINING_MODE | FC_OFFLINING_MODE))) { 3439*fcf3ce44SJohn Forte if (i++ > 30) { 3440*fcf3ce44SJohn Forte break; 3441*fcf3ce44SJohn Forte } 3442*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 3443*fcf3ce44SJohn Forte delay(drv_usectohz(1000000)); 3444*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 3445*fcf3ce44SJohn Forte } 3446*fcf3ce44SJohn Forte 3447*fcf3ce44SJohn Forte /* Return current state */ 3448*fcf3ce44SJohn Forte if (hba->flag & FC_ONLINE_MODE) { 3449*fcf3ce44SJohn Forte flag = DDI_ONDI; 3450*fcf3ce44SJohn Forte } else if (hba->state == FC_KILLED) { 3451*fcf3ce44SJohn Forte flag = DDI_DIAGDI; 3452*fcf3ce44SJohn Forte } else if (hba->state == FC_WARM_START) { 3453*fcf3ce44SJohn Forte flag = DDI_WARMDI; 3454*fcf3ce44SJohn Forte } else { 3455*fcf3ce44SJohn Forte flag = DDI_OFFDI; 3456*fcf3ce44SJohn Forte } 3457*fcf3ce44SJohn Forte 3458*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 3459*fcf3ce44SJohn Forte 3460*fcf3ce44SJohn Forte if (ddi_copyout((void *)&flag, (void *)dfc->buf1, 3461*fcf3ce44SJohn Forte sizeof (uint32_t), mode) != 0) { 3462*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3463*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 3464*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 3465*fcf3ce44SJohn Forte 3466*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 3467*fcf3ce44SJohn Forte } 3468*fcf3ce44SJohn Forte return (rval); 3469*fcf3ce44SJohn Forte 3470*fcf3ce44SJohn Forte } /* emlxs_dfc_set_diag() */ 3471*fcf3ce44SJohn Forte 3472*fcf3ce44SJohn Forte 3473*fcf3ce44SJohn Forte 3474*fcf3ce44SJohn Forte static int32_t 3475*fcf3ce44SJohn Forte emlxs_dfc_send_mbox(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 3476*fcf3ce44SJohn Forte { 3477*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 3478*fcf3ce44SJohn Forte MAILBOX *mb = NULL; 3479*fcf3ce44SJohn Forte MAILBOXQ *mbq = NULL; 3480*fcf3ce44SJohn Forte uint32_t size = 0; 3481*fcf3ce44SJohn Forte MATCHMAP *rx_mp = NULL; 3482*fcf3ce44SJohn Forte MATCHMAP *tx_mp = NULL; 3483*fcf3ce44SJohn Forte uintptr_t lptr; 3484*fcf3ce44SJohn Forte int32_t rval = 0; 3485*fcf3ce44SJohn Forte int32_t mbxstatus = 0; 3486*fcf3ce44SJohn Forte NODELIST *ndlp; 3487*fcf3ce44SJohn Forte uint32_t did; 3488*fcf3ce44SJohn Forte uint32_t extsize = 0; 3489*fcf3ce44SJohn Forte uint8_t *extbuf = NULL; 3490*fcf3ce44SJohn Forte 3491*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 3492*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3493*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 3494*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 3495*fcf3ce44SJohn Forte 3496*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 3497*fcf3ce44SJohn Forte } 3498*fcf3ce44SJohn Forte if (!dfc->buf2 || !dfc->buf2_size) { 3499*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3500*fcf3ce44SJohn Forte "%s: Null buffer2 found.", 3501*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 3502*fcf3ce44SJohn Forte 3503*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 3504*fcf3ce44SJohn Forte } 3505*fcf3ce44SJohn Forte if (dfc->buf1_size > MAILBOX_CMD_BSIZE) { 3506*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3507*fcf3ce44SJohn Forte "%s: Buffer1 too large. (size=%d)", 3508*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 3509*fcf3ce44SJohn Forte 3510*fcf3ce44SJohn Forte return (DFC_ARG_TOOBIG); 3511*fcf3ce44SJohn Forte } 3512*fcf3ce44SJohn Forte #ifdef MBOX_EXT_SUPPORT 3513*fcf3ce44SJohn Forte if (dfc->buf3_size || dfc->buf4_size) { 3514*fcf3ce44SJohn Forte if (dfc->buf3_size && !dfc->buf3) { 3515*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3516*fcf3ce44SJohn Forte "%s: Null buffer3 found.", 3517*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 3518*fcf3ce44SJohn Forte 3519*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 3520*fcf3ce44SJohn Forte } 3521*fcf3ce44SJohn Forte if (dfc->buf3_size > MBOX_EXTENSION_SIZE) { 3522*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3523*fcf3ce44SJohn Forte "%s: buffer3 too large. (size=%d)", 3524*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf3_size); 3525*fcf3ce44SJohn Forte 3526*fcf3ce44SJohn Forte return (DFC_ARG_TOOBIG); 3527*fcf3ce44SJohn Forte } 3528*fcf3ce44SJohn Forte if (dfc->buf4_size && !dfc->buf4) { 3529*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3530*fcf3ce44SJohn Forte "%s: Null buffer4 found.", 3531*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 3532*fcf3ce44SJohn Forte 3533*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 3534*fcf3ce44SJohn Forte } 3535*fcf3ce44SJohn Forte if (dfc->buf4_size > MBOX_EXTENSION_SIZE) { 3536*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3537*fcf3ce44SJohn Forte "%s: buffer4 too large. (size=%d)", 3538*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf3_size); 3539*fcf3ce44SJohn Forte 3540*fcf3ce44SJohn Forte return (DFC_ARG_TOOBIG); 3541*fcf3ce44SJohn Forte } 3542*fcf3ce44SJohn Forte extsize = (dfc->buf3_size > dfc->buf4_size) 3543*fcf3ce44SJohn Forte ? dfc->buf3_size : dfc->buf4_size; 3544*fcf3ce44SJohn Forte if ((extbuf = (uint8_t *) 3545*fcf3ce44SJohn Forte kmem_zalloc(extsize, KM_SLEEP)) == 0) { 3546*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3547*fcf3ce44SJohn Forte "%s: Unable to allocate mailbox" 3548*fcf3ce44SJohn Forte " extension buffer.", 3549*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 3550*fcf3ce44SJohn Forte 3551*fcf3ce44SJohn Forte return (DFC_SYSRES_ERROR); 3552*fcf3ce44SJohn Forte } 3553*fcf3ce44SJohn Forte if (dfc->buf3_size) { 3554*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf3, (void *)extbuf, 3555*fcf3ce44SJohn Forte dfc->buf3_size, mode) != 0) { 3556*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3557*fcf3ce44SJohn Forte "%s: ddi_copyin mbox extension" 3558*fcf3ce44SJohn Forte " data failed.", 3559*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 3560*fcf3ce44SJohn Forte 3561*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 3562*fcf3ce44SJohn Forte goto done; 3563*fcf3ce44SJohn Forte } 3564*fcf3ce44SJohn Forte } 3565*fcf3ce44SJohn Forte } 3566*fcf3ce44SJohn Forte #endif /* MBOX_EXT_SUPPORT */ 3567*fcf3ce44SJohn Forte 3568*fcf3ce44SJohn Forte if ((mbq = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_SLEEP)) == 0) { 3569*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3570*fcf3ce44SJohn Forte "%s: Unable to allocate mailbox buffer.", 3571*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 3572*fcf3ce44SJohn Forte 3573*fcf3ce44SJohn Forte rval = DFC_SYSRES_ERROR; 3574*fcf3ce44SJohn Forte goto done; 3575*fcf3ce44SJohn Forte } 3576*fcf3ce44SJohn Forte mb = (MAILBOX *) mbq; 3577*fcf3ce44SJohn Forte 3578*fcf3ce44SJohn Forte bzero((void *) mb, MAILBOX_CMD_BSIZE); 3579*fcf3ce44SJohn Forte 3580*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf1, (void *)mb, 3581*fcf3ce44SJohn Forte dfc->buf1_size, mode) != 0) { 3582*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3583*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 3584*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 3585*fcf3ce44SJohn Forte 3586*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 3587*fcf3ce44SJohn Forte goto done; 3588*fcf3ce44SJohn Forte } 3589*fcf3ce44SJohn Forte #ifdef _LP64 3590*fcf3ce44SJohn Forte if ((mb->mbxCommand == MBX_READ_SPARM) || 3591*fcf3ce44SJohn Forte (mb->mbxCommand == MBX_READ_RPI) || 3592*fcf3ce44SJohn Forte (mb->mbxCommand == MBX_REG_LOGIN) || 3593*fcf3ce44SJohn Forte (mb->mbxCommand == MBX_READ_LA) || 3594*fcf3ce44SJohn Forte (mb->mbxCommand == MBX_RUN_BIU_DIAG)) { 3595*fcf3ce44SJohn Forte 3596*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3597*fcf3ce44SJohn Forte "%s: Invalid mailbox command." 3598*fcf3ce44SJohn Forte " Must use 64bit version. cmd = %x", 3599*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3600*fcf3ce44SJohn Forte 3601*fcf3ce44SJohn Forte /* Must use 64 bit versions of these mbox cmds */ 3602*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 3603*fcf3ce44SJohn Forte goto done; 3604*fcf3ce44SJohn Forte } 3605*fcf3ce44SJohn Forte #endif 3606*fcf3ce44SJohn Forte 3607*fcf3ce44SJohn Forte lptr = 0; 3608*fcf3ce44SJohn Forte size = 0; 3609*fcf3ce44SJohn Forte switch (mb->mbxCommand) { 3610*fcf3ce44SJohn Forte /* Offline only */ 3611*fcf3ce44SJohn Forte case MBX_CONFIG_LINK: /* 0x07 */ 3612*fcf3ce44SJohn Forte case MBX_PART_SLIM: /* 0x08 */ 3613*fcf3ce44SJohn Forte case MBX_CONFIG_RING: /* 0x09 */ 3614*fcf3ce44SJohn Forte case MBX_DUMP_CONTEXT: /* 0x18 */ 3615*fcf3ce44SJohn Forte case MBX_RUN_DIAGS: /* 0x19 */ 3616*fcf3ce44SJohn Forte case MBX_RESTART: /* 0x1A */ 3617*fcf3ce44SJohn Forte case MBX_SET_MASK: /* 0x20 */ 3618*fcf3ce44SJohn Forte case MBX_FLASH_WR_ULA: /* 0x98 */ 3619*fcf3ce44SJohn Forte if (!(hba->flag & FC_OFFLINE_MODE)) { 3620*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3621*fcf3ce44SJohn Forte "%s: Adapter not offline. cmd=%x", 3622*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3623*fcf3ce44SJohn Forte 3624*fcf3ce44SJohn Forte rval = DFC_ONLINE_ERROR; 3625*fcf3ce44SJohn Forte goto done; 3626*fcf3ce44SJohn Forte } 3627*fcf3ce44SJohn Forte break; 3628*fcf3ce44SJohn Forte 3629*fcf3ce44SJohn Forte /* Online / Offline */ 3630*fcf3ce44SJohn Forte case MBX_UNREG_LOGIN: /* 0x14 */ 3631*fcf3ce44SJohn Forte ndlp = emlxs_node_find_rpi(port, mb->un.varUnregLogin.rpi); 3632*fcf3ce44SJohn Forte 3633*fcf3ce44SJohn Forte if (ndlp) { 3634*fcf3ce44SJohn Forte did = ndlp->nlp_DID; 3635*fcf3ce44SJohn Forte 3636*fcf3ce44SJohn Forte /* remove it */ 3637*fcf3ce44SJohn Forte emlxs_node_rm(port, ndlp); 3638*fcf3ce44SJohn Forte 3639*fcf3ce44SJohn Forte /* 3640*fcf3ce44SJohn Forte * If we just unregistered the host node then clear 3641*fcf3ce44SJohn Forte * the host DID 3642*fcf3ce44SJohn Forte */ 3643*fcf3ce44SJohn Forte if (did == port->did) { 3644*fcf3ce44SJohn Forte port->did = 0; 3645*fcf3ce44SJohn Forte } 3646*fcf3ce44SJohn Forte } else { 3647*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3648*fcf3ce44SJohn Forte "%s: Node not found. cmd=%x rpi=%x", 3649*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand, 3650*fcf3ce44SJohn Forte mb->un.varUnregLogin.rpi); 3651*fcf3ce44SJohn Forte 3652*fcf3ce44SJohn Forte /* Node does not exist */ 3653*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 3654*fcf3ce44SJohn Forte goto done; 3655*fcf3ce44SJohn Forte } 3656*fcf3ce44SJohn Forte 3657*fcf3ce44SJohn Forte /* Send it */ 3658*fcf3ce44SJohn Forte break; 3659*fcf3ce44SJohn Forte 3660*fcf3ce44SJohn Forte case MBX_UNREG_D_ID: /* 0x23 */ 3661*fcf3ce44SJohn Forte 3662*fcf3ce44SJohn Forte did = mb->un.varRegLogin.did; 3663*fcf3ce44SJohn Forte 3664*fcf3ce44SJohn Forte if (did == 0) { 3665*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3666*fcf3ce44SJohn Forte "%s: Node not found. cmd=%x did=%x", 3667*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand, did); 3668*fcf3ce44SJohn Forte 3669*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 3670*fcf3ce44SJohn Forte goto done; 3671*fcf3ce44SJohn Forte } 3672*fcf3ce44SJohn Forte if (did == 0xffffffff) { 3673*fcf3ce44SJohn Forte emlxs_node_destroy_all(port); 3674*fcf3ce44SJohn Forte break; 3675*fcf3ce44SJohn Forte } 3676*fcf3ce44SJohn Forte /* Check for base node */ 3677*fcf3ce44SJohn Forte if (did == Bcast_DID) { 3678*fcf3ce44SJohn Forte /* just flush base node */ 3679*fcf3ce44SJohn Forte (void) emlxs_tx_node_flush(port, &port->node_base, 3680*fcf3ce44SJohn Forte 0, 0, 0); 3681*fcf3ce44SJohn Forte (void) emlxs_chipq_node_flush(port, 0, &port->node_base, 3682*fcf3ce44SJohn Forte 0); 3683*fcf3ce44SJohn Forte 3684*fcf3ce44SJohn Forte /* Return now */ 3685*fcf3ce44SJohn Forte rval = 0; 3686*fcf3ce44SJohn Forte goto done; 3687*fcf3ce44SJohn Forte } 3688*fcf3ce44SJohn Forte /* Make sure the node does already exist */ 3689*fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, did); 3690*fcf3ce44SJohn Forte 3691*fcf3ce44SJohn Forte if (ndlp) { 3692*fcf3ce44SJohn Forte /* remove it */ 3693*fcf3ce44SJohn Forte emlxs_node_rm(port, ndlp); 3694*fcf3ce44SJohn Forte 3695*fcf3ce44SJohn Forte /* 3696*fcf3ce44SJohn Forte * If we just unregistered the host node then clear 3697*fcf3ce44SJohn Forte * the host DID 3698*fcf3ce44SJohn Forte */ 3699*fcf3ce44SJohn Forte if (did == port->did) { 3700*fcf3ce44SJohn Forte port->did = 0; 3701*fcf3ce44SJohn Forte } 3702*fcf3ce44SJohn Forte } else { 3703*fcf3ce44SJohn Forte 3704*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3705*fcf3ce44SJohn Forte "%s: Node not found. cmd=%x did=%x", 3706*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand, did); 3707*fcf3ce44SJohn Forte 3708*fcf3ce44SJohn Forte /* Node does not exist */ 3709*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 3710*fcf3ce44SJohn Forte goto done; 3711*fcf3ce44SJohn Forte } 3712*fcf3ce44SJohn Forte 3713*fcf3ce44SJohn Forte /* Send it */ 3714*fcf3ce44SJohn Forte break; 3715*fcf3ce44SJohn Forte 3716*fcf3ce44SJohn Forte /* Online / Offline - with DMA */ 3717*fcf3ce44SJohn Forte case MBX_READ_EVENT_LOG: /* 0x38 */ 3718*fcf3ce44SJohn Forte lptr = (uintptr_t)getPaddr(mb->un.varRdEvtLog.un.sp64.addrHigh, 3719*fcf3ce44SJohn Forte mb->un.varRdEvtLog.un.sp64.addrLow); 3720*fcf3ce44SJohn Forte size = (int)mb->un.varRdEvtLog.un.sp64.tus.f.bdeSize; 3721*fcf3ce44SJohn Forte 3722*fcf3ce44SJohn Forte if (!lptr || !size || (size > MEM_BUF_SIZE)) { 3723*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3724*fcf3ce44SJohn Forte "%s: Invalid BDE. cmd=%x", 3725*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3726*fcf3ce44SJohn Forte 3727*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 3728*fcf3ce44SJohn Forte goto done; 3729*fcf3ce44SJohn Forte } 3730*fcf3ce44SJohn Forte /* Allocate receive buffer */ 3731*fcf3ce44SJohn Forte if ((rx_mp = (MATCHMAP *)emlxs_mem_buf_alloc(hba)) == 0) { 3732*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3733*fcf3ce44SJohn Forte "%s: Unable to allocate receive buffer. cmd=%x", 3734*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3735*fcf3ce44SJohn Forte 3736*fcf3ce44SJohn Forte rval = DFC_DRVRES_ERROR; 3737*fcf3ce44SJohn Forte goto done; 3738*fcf3ce44SJohn Forte } 3739*fcf3ce44SJohn Forte mb->un.varRdEvtLog.un.sp64.addrHigh = 3740*fcf3ce44SJohn Forte (uint32_t)putPaddrHigh(rx_mp->phys); 3741*fcf3ce44SJohn Forte mb->un.varRdEvtLog.un.sp64.addrLow = 3742*fcf3ce44SJohn Forte (uint32_t)putPaddrLow(rx_mp->phys); 3743*fcf3ce44SJohn Forte mb->un.varRdEvtLog.un.sp64.tus.f.bdeFlags = 0; 3744*fcf3ce44SJohn Forte 3745*fcf3ce44SJohn Forte break; 3746*fcf3ce44SJohn Forte 3747*fcf3ce44SJohn Forte case MBX_READ_SPARM: /* 0x0D */ 3748*fcf3ce44SJohn Forte case MBX_READ_SPARM64: /* 0x8D */ 3749*fcf3ce44SJohn Forte lptr = (uintptr_t)getPaddr(mb->un.varRdSparm.un.sp64.addrHigh, 3750*fcf3ce44SJohn Forte mb->un.varRdSparm.un.sp64.addrLow); 3751*fcf3ce44SJohn Forte size = (int)mb->un.varRdSparm.un.sp64.tus.f.bdeSize; 3752*fcf3ce44SJohn Forte 3753*fcf3ce44SJohn Forte if (!lptr || !size || (size > MEM_BUF_SIZE)) { 3754*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3755*fcf3ce44SJohn Forte "%s: Invalid BDE. cmd=%x", 3756*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3757*fcf3ce44SJohn Forte 3758*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 3759*fcf3ce44SJohn Forte goto done; 3760*fcf3ce44SJohn Forte } 3761*fcf3ce44SJohn Forte /* Allocate receive buffer */ 3762*fcf3ce44SJohn Forte if ((rx_mp = (MATCHMAP *)emlxs_mem_buf_alloc(hba)) == 0) { 3763*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3764*fcf3ce44SJohn Forte "%s: Unable to allocate receive buffer. cmd=%x", 3765*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3766*fcf3ce44SJohn Forte 3767*fcf3ce44SJohn Forte rval = DFC_DRVRES_ERROR; 3768*fcf3ce44SJohn Forte goto done; 3769*fcf3ce44SJohn Forte } 3770*fcf3ce44SJohn Forte mb->un.varRdSparm.un.sp64.addrHigh = 3771*fcf3ce44SJohn Forte (uint32_t)putPaddrHigh(rx_mp->phys); 3772*fcf3ce44SJohn Forte mb->un.varRdSparm.un.sp64.addrLow = 3773*fcf3ce44SJohn Forte (uint32_t)putPaddrLow(rx_mp->phys); 3774*fcf3ce44SJohn Forte mb->un.varRdSparm.un.sp64.tus.f.bdeFlags = 0; 3775*fcf3ce44SJohn Forte 3776*fcf3ce44SJohn Forte break; 3777*fcf3ce44SJohn Forte 3778*fcf3ce44SJohn Forte case MBX_READ_RPI: /* 0x0F */ 3779*fcf3ce44SJohn Forte case MBX_READ_RPI64: /* 0x8F */ 3780*fcf3ce44SJohn Forte lptr = (uintptr_t)getPaddr(mb->un.varRdRPI.un.sp64.addrHigh, 3781*fcf3ce44SJohn Forte mb->un.varRdRPI.un.sp64.addrLow); 3782*fcf3ce44SJohn Forte size = (int)mb->un.varRdRPI.un.sp64.tus.f.bdeSize; 3783*fcf3ce44SJohn Forte 3784*fcf3ce44SJohn Forte if (!lptr || !size || (size > MEM_BUF_SIZE)) { 3785*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3786*fcf3ce44SJohn Forte "%s: Invalid BDE. cmd=%x", 3787*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3788*fcf3ce44SJohn Forte 3789*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 3790*fcf3ce44SJohn Forte goto done; 3791*fcf3ce44SJohn Forte } 3792*fcf3ce44SJohn Forte /* Allocate receive buffer */ 3793*fcf3ce44SJohn Forte if ((rx_mp = (MATCHMAP *)emlxs_mem_buf_alloc(hba)) == 0) { 3794*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3795*fcf3ce44SJohn Forte "%s: Unable to allocate receive buffer. cmd=%x", 3796*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3797*fcf3ce44SJohn Forte 3798*fcf3ce44SJohn Forte rval = DFC_DRVRES_ERROR; 3799*fcf3ce44SJohn Forte goto done; 3800*fcf3ce44SJohn Forte } 3801*fcf3ce44SJohn Forte mb->un.varRdRPI.un.sp64.addrHigh = 3802*fcf3ce44SJohn Forte (uint32_t)putPaddrHigh(rx_mp->phys); 3803*fcf3ce44SJohn Forte mb->un.varRdRPI.un.sp64.addrLow = 3804*fcf3ce44SJohn Forte (uint32_t)putPaddrLow(rx_mp->phys); 3805*fcf3ce44SJohn Forte mb->un.varRdRPI.un.sp64.tus.f.bdeFlags = 0; 3806*fcf3ce44SJohn Forte 3807*fcf3ce44SJohn Forte break; 3808*fcf3ce44SJohn Forte 3809*fcf3ce44SJohn Forte case MBX_RUN_BIU_DIAG: /* 0x04 */ 3810*fcf3ce44SJohn Forte case MBX_RUN_BIU_DIAG64: /* 0x84 */ 3811*fcf3ce44SJohn Forte lptr = (uintptr_t) 3812*fcf3ce44SJohn Forte getPaddr(mb->un.varBIUdiag.un.s2.xmit_bde64.addrHigh, 3813*fcf3ce44SJohn Forte mb->un.varBIUdiag.un.s2.xmit_bde64.addrLow); 3814*fcf3ce44SJohn Forte size = (int)mb->un.varBIUdiag.un.s2.xmit_bde64.tus.f.bdeSize; 3815*fcf3ce44SJohn Forte 3816*fcf3ce44SJohn Forte if (!lptr || !size || (size > MEM_BUF_SIZE)) { 3817*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3818*fcf3ce44SJohn Forte "%s: Invalid xmit BDE. cmd=%x", 3819*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3820*fcf3ce44SJohn Forte 3821*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 3822*fcf3ce44SJohn Forte goto done; 3823*fcf3ce44SJohn Forte } 3824*fcf3ce44SJohn Forte /* Allocate xmit buffer */ 3825*fcf3ce44SJohn Forte if ((tx_mp = (MATCHMAP *)emlxs_mem_buf_alloc(hba)) == 0) { 3826*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3827*fcf3ce44SJohn Forte "%s: Unable to allocate xmit buffer. cmd=%x", 3828*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3829*fcf3ce44SJohn Forte 3830*fcf3ce44SJohn Forte rval = DFC_DRVRES_ERROR; 3831*fcf3ce44SJohn Forte goto done; 3832*fcf3ce44SJohn Forte } 3833*fcf3ce44SJohn Forte /* Initialize the xmit buffer */ 3834*fcf3ce44SJohn Forte if (ddi_copyin((void *)lptr, (void *)tx_mp->virt, 3835*fcf3ce44SJohn Forte size, mode) != 0) { 3836*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3837*fcf3ce44SJohn Forte "%s: ddi_copyin failed. cmd=%x", 3838*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3839*fcf3ce44SJohn Forte 3840*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 3841*fcf3ce44SJohn Forte goto done; 3842*fcf3ce44SJohn Forte } 3843*fcf3ce44SJohn Forte emlxs_mpdata_sync(tx_mp->dma_handle, 0, 3844*fcf3ce44SJohn Forte size, DDI_DMA_SYNC_FORDEV); 3845*fcf3ce44SJohn Forte 3846*fcf3ce44SJohn Forte mb->un.varBIUdiag.un.s2.xmit_bde64.addrHigh = 3847*fcf3ce44SJohn Forte (uint32_t)putPaddrHigh(tx_mp->phys); 3848*fcf3ce44SJohn Forte mb->un.varBIUdiag.un.s2.xmit_bde64.addrLow = 3849*fcf3ce44SJohn Forte (uint32_t)putPaddrLow(tx_mp->phys); 3850*fcf3ce44SJohn Forte mb->un.varBIUdiag.un.s2.xmit_bde64.tus.f.bdeFlags = 0; 3851*fcf3ce44SJohn Forte 3852*fcf3ce44SJohn Forte /* Initialize the receive buffer */ 3853*fcf3ce44SJohn Forte lptr = (uintptr_t) 3854*fcf3ce44SJohn Forte getPaddr(mb->un.varBIUdiag.un.s2.rcv_bde64.addrHigh, 3855*fcf3ce44SJohn Forte mb->un.varBIUdiag.un.s2.rcv_bde64.addrLow); 3856*fcf3ce44SJohn Forte size = (int)mb->un.varBIUdiag.un.s2.rcv_bde64.tus.f.bdeSize; 3857*fcf3ce44SJohn Forte 3858*fcf3ce44SJohn Forte if (!lptr || !size || (size > MEM_BUF_SIZE)) { 3859*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3860*fcf3ce44SJohn Forte "%s: Invalid rcv BDE. cmd=%x", 3861*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3862*fcf3ce44SJohn Forte 3863*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 3864*fcf3ce44SJohn Forte goto done; 3865*fcf3ce44SJohn Forte } 3866*fcf3ce44SJohn Forte /* Allocate receive buffer */ 3867*fcf3ce44SJohn Forte if ((rx_mp = (MATCHMAP *)emlxs_mem_buf_alloc(hba)) == 0) { 3868*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3869*fcf3ce44SJohn Forte "%s: Unable to allocate receive buffer. cmd=%x", 3870*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3871*fcf3ce44SJohn Forte 3872*fcf3ce44SJohn Forte rval = DFC_DRVRES_ERROR; 3873*fcf3ce44SJohn Forte goto done; 3874*fcf3ce44SJohn Forte } 3875*fcf3ce44SJohn Forte mb->un.varBIUdiag.un.s2.rcv_bde64.addrHigh = 3876*fcf3ce44SJohn Forte (uint32_t)putPaddrHigh(rx_mp->phys); 3877*fcf3ce44SJohn Forte mb->un.varBIUdiag.un.s2.rcv_bde64.addrLow = 3878*fcf3ce44SJohn Forte (uint32_t)putPaddrLow(rx_mp->phys); 3879*fcf3ce44SJohn Forte mb->un.varBIUdiag.un.s2.rcv_bde64.tus.f.bdeFlags = 0; 3880*fcf3ce44SJohn Forte 3881*fcf3ce44SJohn Forte break; 3882*fcf3ce44SJohn Forte 3883*fcf3ce44SJohn Forte case MBX_REG_LOGIN: /* 0x13 */ 3884*fcf3ce44SJohn Forte case MBX_REG_LOGIN64: /* 0x93 */ 3885*fcf3ce44SJohn Forte 3886*fcf3ce44SJohn Forte did = mb->un.varRegLogin.did; 3887*fcf3ce44SJohn Forte 3888*fcf3ce44SJohn Forte /* Check for invalid node ids to register */ 3889*fcf3ce44SJohn Forte if (did == 0 || (did & 0xff000000)) { 3890*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3891*fcf3ce44SJohn Forte "%s: Invalid node id. cmd=%x did=%x", 3892*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand, did); 3893*fcf3ce44SJohn Forte 3894*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 3895*fcf3ce44SJohn Forte goto done; 3896*fcf3ce44SJohn Forte } 3897*fcf3ce44SJohn Forte /* Check if the node limit has been reached */ 3898*fcf3ce44SJohn Forte if (port->node_count >= hba->max_nodes) { 3899*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3900*fcf3ce44SJohn Forte "%s: Too many nodes. cmd=%x", 3901*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3902*fcf3ce44SJohn Forte 3903*fcf3ce44SJohn Forte rval = DFC_HBARES_ERROR; 3904*fcf3ce44SJohn Forte goto done; 3905*fcf3ce44SJohn Forte } 3906*fcf3ce44SJohn Forte lptr = (uintptr_t)getPaddr(mb->un.varRegLogin.un.sp64.addrHigh, 3907*fcf3ce44SJohn Forte mb->un.varRegLogin.un.sp64.addrLow); 3908*fcf3ce44SJohn Forte size = (int)mb->un.varRegLogin.un.sp64.tus.f.bdeSize; 3909*fcf3ce44SJohn Forte 3910*fcf3ce44SJohn Forte if (!lptr || (size > MEM_BUF_SIZE)) { 3911*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3912*fcf3ce44SJohn Forte "%s: Invalid BDE. cmd=%x", 3913*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3914*fcf3ce44SJohn Forte 3915*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 3916*fcf3ce44SJohn Forte goto done; 3917*fcf3ce44SJohn Forte } 3918*fcf3ce44SJohn Forte /* Allocate xmit buffer */ 3919*fcf3ce44SJohn Forte if ((tx_mp = (MATCHMAP *)emlxs_mem_buf_alloc(hba)) == 0) { 3920*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3921*fcf3ce44SJohn Forte "%s: Unable to allocate xmit buffer. cmd=%x", 3922*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3923*fcf3ce44SJohn Forte 3924*fcf3ce44SJohn Forte rval = DFC_DRVRES_ERROR; 3925*fcf3ce44SJohn Forte goto done; 3926*fcf3ce44SJohn Forte } 3927*fcf3ce44SJohn Forte /* Initialize the xmit buffer */ 3928*fcf3ce44SJohn Forte if (ddi_copyin((void *)lptr, (void *)tx_mp->virt, 3929*fcf3ce44SJohn Forte size, mode) != 0) { 3930*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3931*fcf3ce44SJohn Forte "%s: Unable to allocate xmit buffer. cmd=%x", 3932*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3933*fcf3ce44SJohn Forte 3934*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 3935*fcf3ce44SJohn Forte goto done; 3936*fcf3ce44SJohn Forte } 3937*fcf3ce44SJohn Forte emlxs_mpdata_sync(tx_mp->dma_handle, 0, 3938*fcf3ce44SJohn Forte size, DDI_DMA_SYNC_FORDEV); 3939*fcf3ce44SJohn Forte 3940*fcf3ce44SJohn Forte mb->un.varRegLogin.un.sp64.addrHigh = 3941*fcf3ce44SJohn Forte (uint32_t)putPaddrHigh(tx_mp->phys); 3942*fcf3ce44SJohn Forte mb->un.varRegLogin.un.sp64.addrLow = 3943*fcf3ce44SJohn Forte (uint32_t)putPaddrLow(tx_mp->phys); 3944*fcf3ce44SJohn Forte mb->un.varRegLogin.un.sp64.tus.f.bdeFlags = 0; 3945*fcf3ce44SJohn Forte 3946*fcf3ce44SJohn Forte break; 3947*fcf3ce44SJohn Forte 3948*fcf3ce44SJohn Forte case MBX_READ_LA: /* 0x15 */ 3949*fcf3ce44SJohn Forte case MBX_READ_LA64: /* 0x95 */ 3950*fcf3ce44SJohn Forte lptr = (uintptr_t) 3951*fcf3ce44SJohn Forte getPaddr(mb->un.varReadLA.un.lilpBde64.addrHigh, 3952*fcf3ce44SJohn Forte mb->un.varReadLA.un.lilpBde64.addrLow); 3953*fcf3ce44SJohn Forte size = (int)mb->un.varReadLA.un.lilpBde64.tus.f.bdeSize; 3954*fcf3ce44SJohn Forte 3955*fcf3ce44SJohn Forte if (!lptr || !size || (size > MEM_BUF_SIZE)) { 3956*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3957*fcf3ce44SJohn Forte "%s: Invalid BDE. cmd=%x", 3958*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3959*fcf3ce44SJohn Forte 3960*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 3961*fcf3ce44SJohn Forte goto done; 3962*fcf3ce44SJohn Forte } 3963*fcf3ce44SJohn Forte /* Allocate receive buffer */ 3964*fcf3ce44SJohn Forte if ((rx_mp = (MATCHMAP *)emlxs_mem_buf_alloc(hba)) == 0) { 3965*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3966*fcf3ce44SJohn Forte "%s: Unable to allocate receive buffer. cmd=%x", 3967*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3968*fcf3ce44SJohn Forte 3969*fcf3ce44SJohn Forte rval = DFC_DRVRES_ERROR; 3970*fcf3ce44SJohn Forte goto done; 3971*fcf3ce44SJohn Forte } 3972*fcf3ce44SJohn Forte mb->un.varReadLA.un.lilpBde64.addrHigh = 3973*fcf3ce44SJohn Forte (uint32_t)putPaddrHigh(rx_mp->phys); 3974*fcf3ce44SJohn Forte mb->un.varReadLA.un.lilpBde64.addrLow = 3975*fcf3ce44SJohn Forte (uint32_t)putPaddrLow(rx_mp->phys); 3976*fcf3ce44SJohn Forte mb->un.varReadLA.un.lilpBde64.tus.f.bdeFlags = 0; 3977*fcf3ce44SJohn Forte 3978*fcf3ce44SJohn Forte break; 3979*fcf3ce44SJohn Forte 3980*fcf3ce44SJohn Forte 3981*fcf3ce44SJohn Forte /* Do not allow these commands */ 3982*fcf3ce44SJohn Forte case MBX_CONFIG_PORT: /* 0x88 */ 3983*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 3984*fcf3ce44SJohn Forte "%s: Command not allowed. cmd=%x", 3985*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 3986*fcf3ce44SJohn Forte 3987*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 3988*fcf3ce44SJohn Forte goto done; 3989*fcf3ce44SJohn Forte 3990*fcf3ce44SJohn Forte 3991*fcf3ce44SJohn Forte /* Online / Offline */ 3992*fcf3ce44SJohn Forte default: 3993*fcf3ce44SJohn Forte break; 3994*fcf3ce44SJohn Forte 3995*fcf3ce44SJohn Forte } /* switch() */ 3996*fcf3ce44SJohn Forte 3997*fcf3ce44SJohn Forte mb->mbxOwner = OWN_HOST; 3998*fcf3ce44SJohn Forte 3999*fcf3ce44SJohn Forte /* Set or don't set the PASSTHRU bit. */ 4000*fcf3ce44SJohn Forte /* Setting will prevent the driver from processing it as its own */ 4001*fcf3ce44SJohn Forte switch (mb->mbxCommand) { 4002*fcf3ce44SJohn Forte case MBX_REG_LOGIN: /* 0x13 */ 4003*fcf3ce44SJohn Forte case MBX_REG_LOGIN64: /* 0x93 */ 4004*fcf3ce44SJohn Forte break; 4005*fcf3ce44SJohn Forte 4006*fcf3ce44SJohn Forte default: 4007*fcf3ce44SJohn Forte mbq->flag |= MBQ_PASSTHRU; 4008*fcf3ce44SJohn Forte } 4009*fcf3ce44SJohn Forte 4010*fcf3ce44SJohn Forte #ifdef MBOX_EXT_SUPPORT 4011*fcf3ce44SJohn Forte if (extbuf) { 4012*fcf3ce44SJohn Forte mbq->extbuf = extbuf; 4013*fcf3ce44SJohn Forte mbq->extsize = extsize; 4014*fcf3ce44SJohn Forte } 4015*fcf3ce44SJohn Forte #endif /* MBOX_EXT_SUPPORT */ 4016*fcf3ce44SJohn Forte 4017*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 4018*fcf3ce44SJohn Forte "%s: %s sent. (%x %x %x %x)", 4019*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 4020*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), 4021*fcf3ce44SJohn Forte mb->un.varWords[0], 4022*fcf3ce44SJohn Forte mb->un.varWords[1], 4023*fcf3ce44SJohn Forte mb->un.varWords[2], 4024*fcf3ce44SJohn Forte mb->un.varWords[3]); 4025*fcf3ce44SJohn Forte 4026*fcf3ce44SJohn Forte /* issue the mbox cmd to the sli */ 4027*fcf3ce44SJohn Forte mbxstatus = emlxs_mb_issue_cmd(hba, mb, MBX_WAIT, 0); 4028*fcf3ce44SJohn Forte 4029*fcf3ce44SJohn Forte if (mbxstatus) { 4030*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4031*fcf3ce44SJohn Forte "%s: %s failed. mbxstatus=0x%x", 4032*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 4033*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), 4034*fcf3ce44SJohn Forte mbxstatus); 4035*fcf3ce44SJohn Forte 4036*fcf3ce44SJohn Forte } 4037*fcf3ce44SJohn Forte if (ddi_copyout((void *)mb, (void *)dfc->buf2, 4038*fcf3ce44SJohn Forte dfc->buf2_size, mode) != 0) { 4039*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4040*fcf3ce44SJohn Forte "%s: ddi_copyout failed. cmd=%x", 4041*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 4042*fcf3ce44SJohn Forte 4043*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 4044*fcf3ce44SJohn Forte goto done; 4045*fcf3ce44SJohn Forte } 4046*fcf3ce44SJohn Forte if (rx_mp) { 4047*fcf3ce44SJohn Forte emlxs_mpdata_sync(rx_mp->dma_handle, 0, size, 4048*fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL); 4049*fcf3ce44SJohn Forte 4050*fcf3ce44SJohn Forte if (ddi_copyout((void *)rx_mp->virt, (void *)lptr, 4051*fcf3ce44SJohn Forte size, mode) != 0) { 4052*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4053*fcf3ce44SJohn Forte "%s: ddi_copyout failed for receive buffer." 4054*fcf3ce44SJohn Forte " cmd = %x", 4055*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 4056*fcf3ce44SJohn Forte mb->mbxCommand); 4057*fcf3ce44SJohn Forte 4058*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 4059*fcf3ce44SJohn Forte goto done; 4060*fcf3ce44SJohn Forte } 4061*fcf3ce44SJohn Forte } 4062*fcf3ce44SJohn Forte #ifdef MBOX_EXT_SUPPORT 4063*fcf3ce44SJohn Forte /* Any data needs to copy to mbox extension area */ 4064*fcf3ce44SJohn Forte if (dfc->buf4_size) { 4065*fcf3ce44SJohn Forte if (ddi_copyout((void *)extbuf, (void *)dfc->buf4, 4066*fcf3ce44SJohn Forte dfc->buf4_size, mode) != 0) { 4067*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4068*fcf3ce44SJohn Forte "%s: ddi_copyout failed for mbox" 4069*fcf3ce44SJohn Forte " extension data.", 4070*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4071*fcf3ce44SJohn Forte 4072*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 4073*fcf3ce44SJohn Forte goto done; 4074*fcf3ce44SJohn Forte } 4075*fcf3ce44SJohn Forte } 4076*fcf3ce44SJohn Forte #endif /* MBOX_EXT_SUPPORT */ 4077*fcf3ce44SJohn Forte 4078*fcf3ce44SJohn Forte rval = 0; 4079*fcf3ce44SJohn Forte 4080*fcf3ce44SJohn Forte done: 4081*fcf3ce44SJohn Forte 4082*fcf3ce44SJohn Forte /* Free allocated mbox memory */ 4083*fcf3ce44SJohn Forte if (extbuf) { 4084*fcf3ce44SJohn Forte kmem_free(extbuf, extsize); 4085*fcf3ce44SJohn Forte } 4086*fcf3ce44SJohn Forte /* Free allocated mbox memory */ 4087*fcf3ce44SJohn Forte if (mbq) { 4088*fcf3ce44SJohn Forte kmem_free(mbq, sizeof (MAILBOXQ)); 4089*fcf3ce44SJohn Forte } 4090*fcf3ce44SJohn Forte /* Free allocated mbuf memory */ 4091*fcf3ce44SJohn Forte if (rx_mp) { 4092*fcf3ce44SJohn Forte (void) emlxs_mem_buf_free(hba, (uint8_t *)rx_mp); 4093*fcf3ce44SJohn Forte } 4094*fcf3ce44SJohn Forte if (tx_mp) { 4095*fcf3ce44SJohn Forte (void) emlxs_mem_buf_free(hba, (uint8_t *)tx_mp); 4096*fcf3ce44SJohn Forte } 4097*fcf3ce44SJohn Forte return (rval); 4098*fcf3ce44SJohn Forte 4099*fcf3ce44SJohn Forte } /* emlxs_dfc_send_mbox() */ 4100*fcf3ce44SJohn Forte 4101*fcf3ce44SJohn Forte 4102*fcf3ce44SJohn Forte static int32_t 4103*fcf3ce44SJohn Forte emlxs_dfc_read_pci(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 4104*fcf3ce44SJohn Forte { 4105*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 4106*fcf3ce44SJohn Forte uint32_t offset; 4107*fcf3ce44SJohn Forte uint32_t cnt; 4108*fcf3ce44SJohn Forte uint32_t outsz; 4109*fcf3ce44SJohn Forte uint32_t i; 4110*fcf3ce44SJohn Forte uint32_t *buffer; 4111*fcf3ce44SJohn Forte uint32_t *bptr; 4112*fcf3ce44SJohn Forte uint32_t value; 4113*fcf3ce44SJohn Forte uint32_t size; 4114*fcf3ce44SJohn Forte uint32_t max = 4096; 4115*fcf3ce44SJohn Forte 4116*fcf3ce44SJohn Forte offset = dfc->data1; 4117*fcf3ce44SJohn Forte cnt = dfc->data2; 4118*fcf3ce44SJohn Forte outsz = dfc->buf1_size; 4119*fcf3ce44SJohn Forte 4120*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 4121*fcf3ce44SJohn Forte "%s: offset=%x count=%d", 4122*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), offset, cnt); 4123*fcf3ce44SJohn Forte 4124*fcf3ce44SJohn Forte if (!dfc->buf1_size || !dfc->buf1) { 4125*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4126*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 4127*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4128*fcf3ce44SJohn Forte 4129*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 4130*fcf3ce44SJohn Forte } 4131*fcf3ce44SJohn Forte if (offset & 0x3) { 4132*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4133*fcf3ce44SJohn Forte "%s: Offset misaligned. (offset=%d)", 4134*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), offset); 4135*fcf3ce44SJohn Forte 4136*fcf3ce44SJohn Forte return (DFC_ARG_MISALIGNED); 4137*fcf3ce44SJohn Forte } 4138*fcf3ce44SJohn Forte if (cnt & 0x3) { 4139*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4140*fcf3ce44SJohn Forte "%s: Count misaligned. (count=%d)", 4141*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), cnt); 4142*fcf3ce44SJohn Forte 4143*fcf3ce44SJohn Forte return (DFC_ARG_MISALIGNED); 4144*fcf3ce44SJohn Forte } 4145*fcf3ce44SJohn Forte if (outsz & 0x3) { 4146*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4147*fcf3ce44SJohn Forte "%s: Output size misaligned. (size=%d)", 4148*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), outsz); 4149*fcf3ce44SJohn Forte 4150*fcf3ce44SJohn Forte return (DFC_ARG_MISALIGNED); 4151*fcf3ce44SJohn Forte } 4152*fcf3ce44SJohn Forte /* Get max PCI config range */ 4153*fcf3ce44SJohn Forte if (hba->model_info.chip <= EMLXS_HELIOS_CHIP) { 4154*fcf3ce44SJohn Forte max = 256; 4155*fcf3ce44SJohn Forte } else { 4156*fcf3ce44SJohn Forte max = 4096; 4157*fcf3ce44SJohn Forte } 4158*fcf3ce44SJohn Forte 4159*fcf3ce44SJohn Forte if ((cnt + offset) > max) { 4160*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4161*fcf3ce44SJohn Forte "%s: Offset+Count too large." 4162*fcf3ce44SJohn Forte " (offset=%d count=%d max=%d)", 4163*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), offset, 4164*fcf3ce44SJohn Forte cnt, max); 4165*fcf3ce44SJohn Forte 4166*fcf3ce44SJohn Forte return (DFC_ARG_TOOBIG); 4167*fcf3ce44SJohn Forte } 4168*fcf3ce44SJohn Forte if (outsz > max) { 4169*fcf3ce44SJohn Forte outsz = max; 4170*fcf3ce44SJohn Forte } 4171*fcf3ce44SJohn Forte if (cnt > outsz) { 4172*fcf3ce44SJohn Forte cnt = outsz; 4173*fcf3ce44SJohn Forte } 4174*fcf3ce44SJohn Forte size = cnt; 4175*fcf3ce44SJohn Forte 4176*fcf3ce44SJohn Forte if (!(buffer = (uint32_t *)kmem_zalloc(size, KM_NOSLEEP))) { 4177*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4178*fcf3ce44SJohn Forte "%s: Unable to allocate buffer.", 4179*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4180*fcf3ce44SJohn Forte 4181*fcf3ce44SJohn Forte return (DFC_SYSRES_ERROR); 4182*fcf3ce44SJohn Forte } 4183*fcf3ce44SJohn Forte bptr = buffer; 4184*fcf3ce44SJohn Forte for (i = offset; i < (offset + cnt); i += 4) { 4185*fcf3ce44SJohn Forte value = ddi_get32(hba->pci_acc_handle, 4186*fcf3ce44SJohn Forte (uint32_t *)(hba->pci_addr + i)); 4187*fcf3ce44SJohn Forte *bptr++ = PCIMEM_LONG(value); 4188*fcf3ce44SJohn Forte } 4189*fcf3ce44SJohn Forte 4190*fcf3ce44SJohn Forte if (ddi_copyout((void *)buffer, (void *)dfc->buf1, 4191*fcf3ce44SJohn Forte outsz, mode) != 0) { 4192*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4193*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 4194*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4195*fcf3ce44SJohn Forte 4196*fcf3ce44SJohn Forte kmem_free(buffer, size); 4197*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 4198*fcf3ce44SJohn Forte } 4199*fcf3ce44SJohn Forte kmem_free(buffer, size); 4200*fcf3ce44SJohn Forte return (0); 4201*fcf3ce44SJohn Forte 4202*fcf3ce44SJohn Forte } /* emlxs_dfc_read_pci() */ 4203*fcf3ce44SJohn Forte 4204*fcf3ce44SJohn Forte 4205*fcf3ce44SJohn Forte static int32_t 4206*fcf3ce44SJohn Forte emlxs_dfc_write_pci(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 4207*fcf3ce44SJohn Forte { 4208*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 4209*fcf3ce44SJohn Forte uint32_t offset; 4210*fcf3ce44SJohn Forte uint32_t cnt; 4211*fcf3ce44SJohn Forte /* uint32_t outsz; */ 4212*fcf3ce44SJohn Forte uint32_t value; 4213*fcf3ce44SJohn Forte uint32_t i; 4214*fcf3ce44SJohn Forte uint32_t max; 4215*fcf3ce44SJohn Forte uint8_t buffer[256]; 4216*fcf3ce44SJohn Forte uint32_t *bptr; 4217*fcf3ce44SJohn Forte uint16_t word0; 4218*fcf3ce44SJohn Forte uint16_t word1; 4219*fcf3ce44SJohn Forte 4220*fcf3ce44SJohn Forte offset = dfc->data1; 4221*fcf3ce44SJohn Forte cnt = dfc->data2; 4222*fcf3ce44SJohn Forte 4223*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 4224*fcf3ce44SJohn Forte "%s: offset = %x count = %d", 4225*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), offset, cnt); 4226*fcf3ce44SJohn Forte 4227*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 4228*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4229*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 4230*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4231*fcf3ce44SJohn Forte 4232*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 4233*fcf3ce44SJohn Forte } 4234*fcf3ce44SJohn Forte if (offset & 0x3) { 4235*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4236*fcf3ce44SJohn Forte "%s: Offset misaligned. (offset = %d)", 4237*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), offset); 4238*fcf3ce44SJohn Forte 4239*fcf3ce44SJohn Forte return (DFC_ARG_MISALIGNED); 4240*fcf3ce44SJohn Forte } 4241*fcf3ce44SJohn Forte if (cnt > dfc->buf1_size) { 4242*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4243*fcf3ce44SJohn Forte "%s: Count too large. (count=%d)", 4244*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), cnt); 4245*fcf3ce44SJohn Forte 4246*fcf3ce44SJohn Forte return (DFC_ARG_TOOBIG); 4247*fcf3ce44SJohn Forte } 4248*fcf3ce44SJohn Forte if (cnt & 0x3) { 4249*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4250*fcf3ce44SJohn Forte "%s: Count misaligned. (count = %d)", 4251*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), cnt); 4252*fcf3ce44SJohn Forte 4253*fcf3ce44SJohn Forte return (DFC_ARG_MISALIGNED); 4254*fcf3ce44SJohn Forte } 4255*fcf3ce44SJohn Forte /* Get max PCI config range */ 4256*fcf3ce44SJohn Forte if (hba->model_info.chip <= EMLXS_HELIOS_CHIP) { 4257*fcf3ce44SJohn Forte max = 256; 4258*fcf3ce44SJohn Forte } else { 4259*fcf3ce44SJohn Forte max = 4096; 4260*fcf3ce44SJohn Forte } 4261*fcf3ce44SJohn Forte 4262*fcf3ce44SJohn Forte if ((cnt + offset) > max) { 4263*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4264*fcf3ce44SJohn Forte "%s: Count+Offset too large." 4265*fcf3ce44SJohn Forte " (offset = %d count = %d max = %d)", 4266*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), offset, cnt, max); 4267*fcf3ce44SJohn Forte 4268*fcf3ce44SJohn Forte return (DFC_ARG_TOOBIG); 4269*fcf3ce44SJohn Forte } 4270*fcf3ce44SJohn Forte bzero(buffer, sizeof (buffer)); 4271*fcf3ce44SJohn Forte 4272*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf1, (void *)buffer, cnt, mode) != 0) { 4273*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4274*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 4275*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4276*fcf3ce44SJohn Forte 4277*fcf3ce44SJohn Forte return (DFC_COPYIN_ERROR); 4278*fcf3ce44SJohn Forte } 4279*fcf3ce44SJohn Forte bptr = (uint32_t *)buffer; 4280*fcf3ce44SJohn Forte for (i = offset; i < (offset + cnt); i += 4) { 4281*fcf3ce44SJohn Forte value = *bptr++; 4282*fcf3ce44SJohn Forte value = PCIMEM_LONG(value); 4283*fcf3ce44SJohn Forte 4284*fcf3ce44SJohn Forte word0 = value & 0xFFFF; 4285*fcf3ce44SJohn Forte word1 = value >> 16; 4286*fcf3ce44SJohn Forte 4287*fcf3ce44SJohn Forte /* 4288*fcf3ce44SJohn Forte * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_debug_msg, "%s: 4289*fcf3ce44SJohn Forte * Writing. offset=%x cnt=%d value=%08x %04x %04x", 4290*fcf3ce44SJohn Forte * emlxs_dfc_xlate(dfc->cmd), i, value, word0, word1); 4291*fcf3ce44SJohn Forte */ 4292*fcf3ce44SJohn Forte 4293*fcf3ce44SJohn Forte /* word0 = PCIMEM_SHORT(word0); */ 4294*fcf3ce44SJohn Forte (void) ddi_put16(hba->pci_acc_handle, 4295*fcf3ce44SJohn Forte (uint16_t *)(hba->pci_addr + i), 4296*fcf3ce44SJohn Forte (uint16_t)word0); 4297*fcf3ce44SJohn Forte 4298*fcf3ce44SJohn Forte /* word1 = PCIMEM_SHORT(word1); */ 4299*fcf3ce44SJohn Forte (void) ddi_put16(hba->pci_acc_handle, 4300*fcf3ce44SJohn Forte (uint16_t *)(hba->pci_addr + i + 2), (uint16_t)word1); 4301*fcf3ce44SJohn Forte } 4302*fcf3ce44SJohn Forte 4303*fcf3ce44SJohn Forte return (0); 4304*fcf3ce44SJohn Forte 4305*fcf3ce44SJohn Forte } /* emlxs_dfc_write_pci() */ 4306*fcf3ce44SJohn Forte 4307*fcf3ce44SJohn Forte 4308*fcf3ce44SJohn Forte static int32_t 4309*fcf3ce44SJohn Forte emlxs_dfc_get_cfg(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 4310*fcf3ce44SJohn Forte { 4311*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 4312*fcf3ce44SJohn Forte dfc_cfgparam_t *cfgparam; 4313*fcf3ce44SJohn Forte uint32_t size; 4314*fcf3ce44SJohn Forte uint32_t count; 4315*fcf3ce44SJohn Forte uint32_t i; 4316*fcf3ce44SJohn Forte int32_t rval = 0; 4317*fcf3ce44SJohn Forte emlxs_config_t *cfg; 4318*fcf3ce44SJohn Forte 4319*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 4320*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4321*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 4322*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4323*fcf3ce44SJohn Forte 4324*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 4325*fcf3ce44SJohn Forte } 4326*fcf3ce44SJohn Forte count = dfc->buf1_size / sizeof (dfc_cfgparam_t); 4327*fcf3ce44SJohn Forte 4328*fcf3ce44SJohn Forte if (count > MAX_CFG_PARAM) { 4329*fcf3ce44SJohn Forte count = MAX_CFG_PARAM; 4330*fcf3ce44SJohn Forte } 4331*fcf3ce44SJohn Forte if (count > NUM_CFG_PARAM) { 4332*fcf3ce44SJohn Forte count = NUM_CFG_PARAM; 4333*fcf3ce44SJohn Forte } 4334*fcf3ce44SJohn Forte size = count * sizeof (dfc_cfgparam_t); 4335*fcf3ce44SJohn Forte 4336*fcf3ce44SJohn Forte if (!(cfgparam = (dfc_cfgparam_t *)kmem_zalloc(size, KM_NOSLEEP))) { 4337*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4338*fcf3ce44SJohn Forte "%s: Unable to allocate cfgparm buffer.", 4339*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4340*fcf3ce44SJohn Forte 4341*fcf3ce44SJohn Forte return (DFC_SYSRES_ERROR); 4342*fcf3ce44SJohn Forte } 4343*fcf3ce44SJohn Forte cfg = &CFG; 4344*fcf3ce44SJohn Forte for (i = 0; i < count; i++) { 4345*fcf3ce44SJohn Forte (void) strncpy(cfgparam[i].a_string, cfg[i].string, 4346*fcf3ce44SJohn Forte sizeof (cfgparam[i].a_string)); 4347*fcf3ce44SJohn Forte cfgparam[i].a_low = cfg[i].low; 4348*fcf3ce44SJohn Forte cfgparam[i].a_hi = cfg[i].hi; 4349*fcf3ce44SJohn Forte cfgparam[i].a_default = cfg[i].def; 4350*fcf3ce44SJohn Forte cfgparam[i].a_current = cfg[i].current; 4351*fcf3ce44SJohn Forte 4352*fcf3ce44SJohn Forte if (!(cfg[i].flags & PARM_HIDDEN)) { 4353*fcf3ce44SJohn Forte cfgparam[i].a_flag |= CFG_EXPORT; 4354*fcf3ce44SJohn Forte } 4355*fcf3ce44SJohn Forte if ((cfg[i].flags & PARM_DYNAMIC)) { 4356*fcf3ce44SJohn Forte if ((cfg[i].flags & PARM_DYNAMIC_RESET) == 4357*fcf3ce44SJohn Forte PARM_DYNAMIC_RESET) { 4358*fcf3ce44SJohn Forte cfgparam[i].a_changestate = CFG_RESTART; 4359*fcf3ce44SJohn Forte } else { 4360*fcf3ce44SJohn Forte cfgparam[i].a_changestate = CFG_DYMANIC; 4361*fcf3ce44SJohn Forte } 4362*fcf3ce44SJohn Forte } else { 4363*fcf3ce44SJohn Forte cfgparam[i].a_changestate = CFG_REBOOT; 4364*fcf3ce44SJohn Forte } 4365*fcf3ce44SJohn Forte 4366*fcf3ce44SJohn Forte (void) strncpy(cfgparam[i].a_help, cfg[i].help, 4367*fcf3ce44SJohn Forte sizeof (cfgparam[i].a_help)); 4368*fcf3ce44SJohn Forte } 4369*fcf3ce44SJohn Forte 4370*fcf3ce44SJohn Forte if (ddi_copyout((void *)cfgparam, (void *)dfc->buf1, 4371*fcf3ce44SJohn Forte size, mode) != 0) { 4372*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4373*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 4374*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4375*fcf3ce44SJohn Forte 4376*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 4377*fcf3ce44SJohn Forte } 4378*fcf3ce44SJohn Forte rval = 0; 4379*fcf3ce44SJohn Forte 4380*fcf3ce44SJohn Forte kmem_free(cfgparam, size); 4381*fcf3ce44SJohn Forte 4382*fcf3ce44SJohn Forte return (rval); 4383*fcf3ce44SJohn Forte 4384*fcf3ce44SJohn Forte } /* emlxs_dfc_get_cfg() */ 4385*fcf3ce44SJohn Forte 4386*fcf3ce44SJohn Forte 4387*fcf3ce44SJohn Forte /*ARGSUSED*/ 4388*fcf3ce44SJohn Forte static int32_t 4389*fcf3ce44SJohn Forte emlxs_dfc_set_cfg(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 4390*fcf3ce44SJohn Forte { 4391*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 4392*fcf3ce44SJohn Forte uint32_t index; 4393*fcf3ce44SJohn Forte uint32_t new_value; 4394*fcf3ce44SJohn Forte uint32_t rc; 4395*fcf3ce44SJohn Forte 4396*fcf3ce44SJohn Forte index = dfc->data1; 4397*fcf3ce44SJohn Forte new_value = dfc->data2; 4398*fcf3ce44SJohn Forte 4399*fcf3ce44SJohn Forte rc = emlxs_set_parm(hba, index, new_value); 4400*fcf3ce44SJohn Forte 4401*fcf3ce44SJohn Forte if (rc) { 4402*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4403*fcf3ce44SJohn Forte "%s: Unable to set parameter. code=%d", 4404*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), rc); 4405*fcf3ce44SJohn Forte 4406*fcf3ce44SJohn Forte switch (rc) { 4407*fcf3ce44SJohn Forte case 2: 4408*fcf3ce44SJohn Forte return (DFC_NPIV_ACTIVE); 4409*fcf3ce44SJohn Forte 4410*fcf3ce44SJohn Forte default: 4411*fcf3ce44SJohn Forte return (DFC_ARG_INVALID); 4412*fcf3ce44SJohn Forte } 4413*fcf3ce44SJohn Forte } 4414*fcf3ce44SJohn Forte return (0); 4415*fcf3ce44SJohn Forte 4416*fcf3ce44SJohn Forte } /* emlxs_dfc_set_cfg() */ 4417*fcf3ce44SJohn Forte 4418*fcf3ce44SJohn Forte 4419*fcf3ce44SJohn Forte static int32_t 4420*fcf3ce44SJohn Forte emlxs_dfc_send_ct(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 4421*fcf3ce44SJohn Forte { 4422*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 4423*fcf3ce44SJohn Forte uint8_t *rsp_buf; 4424*fcf3ce44SJohn Forte uint8_t *cmd_buf; 4425*fcf3ce44SJohn Forte uint32_t did; 4426*fcf3ce44SJohn Forte uint32_t rsp_size; 4427*fcf3ce44SJohn Forte uint32_t cmd_size; 4428*fcf3ce44SJohn Forte uint32_t timeout; 4429*fcf3ce44SJohn Forte fc_packet_t *pkt = NULL; 4430*fcf3ce44SJohn Forte uint32_t rval = 0; 4431*fcf3ce44SJohn Forte dfc_destid_t destid; 4432*fcf3ce44SJohn Forte NODELIST *nlp; 4433*fcf3ce44SJohn Forte char buffer[128]; 4434*fcf3ce44SJohn Forte 4435*fcf3ce44SJohn Forte cmd_buf = dfc->buf1; 4436*fcf3ce44SJohn Forte cmd_size = dfc->buf1_size; 4437*fcf3ce44SJohn Forte rsp_buf = dfc->buf2; 4438*fcf3ce44SJohn Forte rsp_size = dfc->buf2_size; 4439*fcf3ce44SJohn Forte timeout = dfc->data1; 4440*fcf3ce44SJohn Forte 4441*fcf3ce44SJohn Forte if (timeout < (2 * hba->fc_ratov)) { 4442*fcf3ce44SJohn Forte timeout = 2 * hba->fc_ratov; 4443*fcf3ce44SJohn Forte } 4444*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 4445*fcf3ce44SJohn Forte "%s: csize=%d rsize=%d", 4446*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), cmd_size, rsp_size); 4447*fcf3ce44SJohn Forte 4448*fcf3ce44SJohn Forte 4449*fcf3ce44SJohn Forte if (!cmd_size || !cmd_buf) { 4450*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4451*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 4452*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4453*fcf3ce44SJohn Forte 4454*fcf3ce44SJohn Forte rval = DFC_ARG_NULL; 4455*fcf3ce44SJohn Forte goto done; 4456*fcf3ce44SJohn Forte } 4457*fcf3ce44SJohn Forte if (!rsp_size || !rsp_buf) { 4458*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4459*fcf3ce44SJohn Forte "%s: Null buffer2 found.", 4460*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4461*fcf3ce44SJohn Forte 4462*fcf3ce44SJohn Forte rval = DFC_ARG_NULL; 4463*fcf3ce44SJohn Forte goto done; 4464*fcf3ce44SJohn Forte } 4465*fcf3ce44SJohn Forte if (!dfc->buf3 || !dfc->buf3_size) { 4466*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4467*fcf3ce44SJohn Forte "%s: Null buffer3 found.", 4468*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4469*fcf3ce44SJohn Forte 4470*fcf3ce44SJohn Forte rval = DFC_ARG_NULL; 4471*fcf3ce44SJohn Forte goto done; 4472*fcf3ce44SJohn Forte } 4473*fcf3ce44SJohn Forte if (!dfc->buf4 || !dfc->buf4_size) { 4474*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4475*fcf3ce44SJohn Forte "%s: Null buffer4 found.", 4476*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4477*fcf3ce44SJohn Forte 4478*fcf3ce44SJohn Forte rval = DFC_ARG_NULL; 4479*fcf3ce44SJohn Forte goto done; 4480*fcf3ce44SJohn Forte } 4481*fcf3ce44SJohn Forte if (rsp_size > MAX_CT_PAYLOAD) { 4482*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4483*fcf3ce44SJohn Forte "%s: Buffer2 too large. size=%d", 4484*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), rsp_size); 4485*fcf3ce44SJohn Forte 4486*fcf3ce44SJohn Forte rval = DFC_ARG_TOOBIG; 4487*fcf3ce44SJohn Forte goto done; 4488*fcf3ce44SJohn Forte } 4489*fcf3ce44SJohn Forte if (cmd_size > MAX_CT_PAYLOAD) { 4490*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4491*fcf3ce44SJohn Forte "%s: Buffer1 too large. size=%d", 4492*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), cmd_size); 4493*fcf3ce44SJohn Forte 4494*fcf3ce44SJohn Forte rval = DFC_ARG_TOOBIG; 4495*fcf3ce44SJohn Forte goto done; 4496*fcf3ce44SJohn Forte } 4497*fcf3ce44SJohn Forte if (dfc->buf3_size < sizeof (dfc_destid_t)) { 4498*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4499*fcf3ce44SJohn Forte "%s: Buffer3 too small. (size=%d)", 4500*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf3_size); 4501*fcf3ce44SJohn Forte 4502*fcf3ce44SJohn Forte rval = DFC_ARG_TOOSMALL; 4503*fcf3ce44SJohn Forte goto done; 4504*fcf3ce44SJohn Forte } 4505*fcf3ce44SJohn Forte if (dfc->buf4_size < sizeof (uint32_t)) { 4506*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4507*fcf3ce44SJohn Forte "%s: Buffer4 too small. (size=%d)", 4508*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf4_size); 4509*fcf3ce44SJohn Forte 4510*fcf3ce44SJohn Forte rval = DFC_ARG_TOOSMALL; 4511*fcf3ce44SJohn Forte goto done; 4512*fcf3ce44SJohn Forte } 4513*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf3, (void *)&destid, 4514*fcf3ce44SJohn Forte sizeof (dfc_destid_t), mode) != 0) { 4515*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4516*fcf3ce44SJohn Forte "%s: Unable to read destination id.", 4517*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4518*fcf3ce44SJohn Forte 4519*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 4520*fcf3ce44SJohn Forte goto done; 4521*fcf3ce44SJohn Forte } 4522*fcf3ce44SJohn Forte if (destid.idType == 0) { 4523*fcf3ce44SJohn Forte if ((nlp = emlxs_node_find_wwpn(port, destid.wwpn)) == NULL) { 4524*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4525*fcf3ce44SJohn Forte "%s: WWPN does not exists. %s", 4526*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 4527*fcf3ce44SJohn Forte emlxs_wwn_xlate(buffer, destid.wwpn)); 4528*fcf3ce44SJohn Forte 4529*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 4530*fcf3ce44SJohn Forte goto done; 4531*fcf3ce44SJohn Forte } 4532*fcf3ce44SJohn Forte did = nlp->nlp_DID; 4533*fcf3ce44SJohn Forte } else { 4534*fcf3ce44SJohn Forte if (emlxs_node_find_did(port, destid.d_id) == NULL) { 4535*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4536*fcf3ce44SJohn Forte "%s: DID does not exist. did=%x", 4537*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), destid.d_id); 4538*fcf3ce44SJohn Forte 4539*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 4540*fcf3ce44SJohn Forte goto done; 4541*fcf3ce44SJohn Forte } 4542*fcf3ce44SJohn Forte did = destid.d_id; 4543*fcf3ce44SJohn Forte } 4544*fcf3ce44SJohn Forte 4545*fcf3ce44SJohn Forte if (did == 0) { 4546*fcf3ce44SJohn Forte did = port->did; 4547*fcf3ce44SJohn Forte } 4548*fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, cmd_size, rsp_size, 0, KM_NOSLEEP))) { 4549*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4550*fcf3ce44SJohn Forte "%s: Unable to allocate packet.", 4551*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4552*fcf3ce44SJohn Forte 4553*fcf3ce44SJohn Forte rval = DFC_SYSRES_ERROR; 4554*fcf3ce44SJohn Forte goto done; 4555*fcf3ce44SJohn Forte } 4556*fcf3ce44SJohn Forte /* Make this a polled IO */ 4557*fcf3ce44SJohn Forte pkt->pkt_tran_flags &= ~FC_TRAN_INTR; 4558*fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_NO_INTR; 4559*fcf3ce44SJohn Forte pkt->pkt_comp = NULL; 4560*fcf3ce44SJohn Forte 4561*fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE; 4562*fcf3ce44SJohn Forte pkt->pkt_timeout = (timeout) ? timeout : 30; 4563*fcf3ce44SJohn Forte 4564*fcf3ce44SJohn Forte /* Build the fc header */ 4565*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(did); 4566*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_UNSOL_CONTROL; 4567*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.s_id = SWAP_DATA24_LO(port->did); 4568*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_FC_SERVICES; 4569*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = F_CTL_FIRST_SEQ | F_CTL_END_SEQ | 4570*fcf3ce44SJohn Forte F_CTL_SEQ_INITIATIVE; 4571*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 4572*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 4573*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 4574*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xFFFF; 4575*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xFFFF; 4576*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 4577*fcf3ce44SJohn Forte 4578*fcf3ce44SJohn Forte /* Copy in the command buffer */ 4579*fcf3ce44SJohn Forte if (ddi_copyin((void *)cmd_buf, (void *)pkt->pkt_cmd, 4580*fcf3ce44SJohn Forte cmd_size, mode) != 0) { 4581*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4582*fcf3ce44SJohn Forte "%s: Unable to read command buffer.", 4583*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4584*fcf3ce44SJohn Forte 4585*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 4586*fcf3ce44SJohn Forte goto done; 4587*fcf3ce44SJohn Forte } 4588*fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 4589*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4590*fcf3ce44SJohn Forte "%s: Unable to send packet.", 4591*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4592*fcf3ce44SJohn Forte 4593*fcf3ce44SJohn Forte rval = DFC_IO_ERROR; 4594*fcf3ce44SJohn Forte goto done; 4595*fcf3ce44SJohn Forte } 4596*fcf3ce44SJohn Forte if ((pkt->pkt_state != FC_PKT_SUCCESS) && 4597*fcf3ce44SJohn Forte (pkt->pkt_state != FC_PKT_FS_RJT)) { 4598*fcf3ce44SJohn Forte if (pkt->pkt_state == FC_PKT_TIMEOUT) { 4599*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4600*fcf3ce44SJohn Forte "Pkt Transport error. Pkt Timeout."); 4601*fcf3ce44SJohn Forte rval = DFC_TIMEOUT; 4602*fcf3ce44SJohn Forte } else { 4603*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4604*fcf3ce44SJohn Forte "Pkt Transport error. state=%x", 4605*fcf3ce44SJohn Forte pkt->pkt_state); 4606*fcf3ce44SJohn Forte rval = DFC_IO_ERROR; 4607*fcf3ce44SJohn Forte } 4608*fcf3ce44SJohn Forte goto done; 4609*fcf3ce44SJohn Forte } 4610*fcf3ce44SJohn Forte if (ddi_copyout((void *)pkt->pkt_resp, (void *)rsp_buf, 4611*fcf3ce44SJohn Forte rsp_size, mode) != 0) { 4612*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4613*fcf3ce44SJohn Forte "%s: Unable to read response.", 4614*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4615*fcf3ce44SJohn Forte 4616*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 4617*fcf3ce44SJohn Forte goto done; 4618*fcf3ce44SJohn Forte } 4619*fcf3ce44SJohn Forte rsp_size -= pkt->pkt_resp_resid; 4620*fcf3ce44SJohn Forte if (ddi_copyout((void *)&rsp_size, (void *)dfc->buf4, 4621*fcf3ce44SJohn Forte dfc->buf4_size, mode) != 0) { 4622*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4623*fcf3ce44SJohn Forte "%s: Unable to write response.", 4624*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4625*fcf3ce44SJohn Forte 4626*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 4627*fcf3ce44SJohn Forte goto done; 4628*fcf3ce44SJohn Forte } 4629*fcf3ce44SJohn Forte rval = 0; 4630*fcf3ce44SJohn Forte 4631*fcf3ce44SJohn Forte done: 4632*fcf3ce44SJohn Forte 4633*fcf3ce44SJohn Forte if (pkt) { 4634*fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 4635*fcf3ce44SJohn Forte } 4636*fcf3ce44SJohn Forte return (rval); 4637*fcf3ce44SJohn Forte 4638*fcf3ce44SJohn Forte } /* emlxs_dfc_send_ct() */ 4639*fcf3ce44SJohn Forte 4640*fcf3ce44SJohn Forte 4641*fcf3ce44SJohn Forte static int32_t 4642*fcf3ce44SJohn Forte emlxs_dfc_send_ct_rsp(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 4643*fcf3ce44SJohn Forte { 4644*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 4645*fcf3ce44SJohn Forte uint8_t *cmd_buf; 4646*fcf3ce44SJohn Forte uint32_t rx_id; 4647*fcf3ce44SJohn Forte uint32_t cmd_size; 4648*fcf3ce44SJohn Forte uint32_t timeout; 4649*fcf3ce44SJohn Forte fc_packet_t *pkt = NULL; 4650*fcf3ce44SJohn Forte uint32_t rval = 0; 4651*fcf3ce44SJohn Forte /* dfc_destid_t destid; */ 4652*fcf3ce44SJohn Forte 4653*fcf3ce44SJohn Forte cmd_buf = dfc->buf1; 4654*fcf3ce44SJohn Forte cmd_size = dfc->buf1_size; 4655*fcf3ce44SJohn Forte rx_id = dfc->flag; 4656*fcf3ce44SJohn Forte timeout = 2 * hba->fc_ratov; 4657*fcf3ce44SJohn Forte 4658*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 4659*fcf3ce44SJohn Forte "%s: csize=%d", 4660*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), cmd_size); 4661*fcf3ce44SJohn Forte 4662*fcf3ce44SJohn Forte if (!cmd_size || !cmd_buf) { 4663*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4664*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 4665*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4666*fcf3ce44SJohn Forte 4667*fcf3ce44SJohn Forte rval = DFC_ARG_NULL; 4668*fcf3ce44SJohn Forte goto done; 4669*fcf3ce44SJohn Forte } 4670*fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, cmd_size, 0, 0, KM_NOSLEEP))) { 4671*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4672*fcf3ce44SJohn Forte "%s: Unable to allocate packet.", 4673*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4674*fcf3ce44SJohn Forte 4675*fcf3ce44SJohn Forte rval = DFC_SYSRES_ERROR; 4676*fcf3ce44SJohn Forte goto done; 4677*fcf3ce44SJohn Forte } 4678*fcf3ce44SJohn Forte /* Make this a polled IO */ 4679*fcf3ce44SJohn Forte pkt->pkt_tran_flags &= ~FC_TRAN_INTR; 4680*fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_NO_INTR; 4681*fcf3ce44SJohn Forte pkt->pkt_comp = NULL; 4682*fcf3ce44SJohn Forte 4683*fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND; 4684*fcf3ce44SJohn Forte pkt->pkt_timeout = (timeout) ? timeout : 30; 4685*fcf3ce44SJohn Forte 4686*fcf3ce44SJohn Forte /* Build the fc header */ 4687*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(0); 4688*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_SOLICITED_CONTROL; 4689*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.s_id = SWAP_DATA24_LO(port->did); 4690*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_FC_SERVICES; 4691*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = F_CTL_LAST_SEQ | F_CTL_END_SEQ | 4692*fcf3ce44SJohn Forte F_CTL_XCHG_CONTEXT; 4693*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 4694*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 4695*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 4696*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xffff; 4697*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = rx_id; 4698*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 4699*fcf3ce44SJohn Forte 4700*fcf3ce44SJohn Forte /* Copy in the command buffer */ 4701*fcf3ce44SJohn Forte if (ddi_copyin((void *)cmd_buf, (void *)pkt->pkt_cmd, 4702*fcf3ce44SJohn Forte cmd_size, mode) != 0) { 4703*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4704*fcf3ce44SJohn Forte "%s: Unable to read command buffer.", 4705*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4706*fcf3ce44SJohn Forte 4707*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 4708*fcf3ce44SJohn Forte goto done; 4709*fcf3ce44SJohn Forte } 4710*fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 4711*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4712*fcf3ce44SJohn Forte "%s: Unable to send packet.", 4713*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4714*fcf3ce44SJohn Forte 4715*fcf3ce44SJohn Forte rval = DFC_IO_ERROR; 4716*fcf3ce44SJohn Forte goto done; 4717*fcf3ce44SJohn Forte } 4718*fcf3ce44SJohn Forte if (pkt->pkt_state != FC_PKT_SUCCESS) { 4719*fcf3ce44SJohn Forte if (pkt->pkt_state == FC_PKT_TIMEOUT) { 4720*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4721*fcf3ce44SJohn Forte "Pkt Transport error. Pkt Timeout."); 4722*fcf3ce44SJohn Forte rval = DFC_TIMEOUT; 4723*fcf3ce44SJohn Forte } else { 4724*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4725*fcf3ce44SJohn Forte "Pkt Transport error. state=%x", 4726*fcf3ce44SJohn Forte pkt->pkt_state); 4727*fcf3ce44SJohn Forte rval = DFC_IO_ERROR; 4728*fcf3ce44SJohn Forte } 4729*fcf3ce44SJohn Forte goto done; 4730*fcf3ce44SJohn Forte } 4731*fcf3ce44SJohn Forte rval = 0; 4732*fcf3ce44SJohn Forte 4733*fcf3ce44SJohn Forte done: 4734*fcf3ce44SJohn Forte 4735*fcf3ce44SJohn Forte if (pkt) { 4736*fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 4737*fcf3ce44SJohn Forte } 4738*fcf3ce44SJohn Forte return (rval); 4739*fcf3ce44SJohn Forte 4740*fcf3ce44SJohn Forte } /* emlxs_dfc_send_ct_rsp() */ 4741*fcf3ce44SJohn Forte 4742*fcf3ce44SJohn Forte 4743*fcf3ce44SJohn Forte #ifdef MENLO_SUPPORT 4744*fcf3ce44SJohn Forte 4745*fcf3ce44SJohn Forte static int32_t 4746*fcf3ce44SJohn Forte emlxs_dfc_send_menlo(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 4747*fcf3ce44SJohn Forte { 4748*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 4749*fcf3ce44SJohn Forte uint8_t *rsp_buf; 4750*fcf3ce44SJohn Forte uint8_t *cmd_buf; 4751*fcf3ce44SJohn Forte uint8_t *data_buf; 4752*fcf3ce44SJohn Forte /* uint32_t did; */ 4753*fcf3ce44SJohn Forte uint32_t rsp_size; 4754*fcf3ce44SJohn Forte uint32_t cmd_size; 4755*fcf3ce44SJohn Forte uint32_t data_size; 4756*fcf3ce44SJohn Forte fc_packet_t *pkt = NULL; 4757*fcf3ce44SJohn Forte uint32_t rval = 0; 4758*fcf3ce44SJohn Forte /* char buffer[128]; */ 4759*fcf3ce44SJohn Forte menlo_set_cmd_t set_cmd; 4760*fcf3ce44SJohn Forte menlo_reset_cmd_t reset_cmd; 4761*fcf3ce44SJohn Forte uint32_t rsp_code; 4762*fcf3ce44SJohn Forte uint32_t mm_mode; 4763*fcf3ce44SJohn Forte uint32_t cmd_code; 4764*fcf3ce44SJohn Forte clock_t timeout; 4765*fcf3ce44SJohn Forte MAILBOXQ *mbq = NULL; 4766*fcf3ce44SJohn Forte MAILBOX *mb; 4767*fcf3ce44SJohn Forte uint32_t addr; 4768*fcf3ce44SJohn Forte uint32_t value; 4769*fcf3ce44SJohn Forte uint32_t mbxstatus; 4770*fcf3ce44SJohn Forte 4771*fcf3ce44SJohn Forte cmd_buf = dfc->buf1; 4772*fcf3ce44SJohn Forte cmd_size = dfc->buf1_size; 4773*fcf3ce44SJohn Forte rsp_buf = dfc->buf2; 4774*fcf3ce44SJohn Forte rsp_size = dfc->buf2_size; 4775*fcf3ce44SJohn Forte data_buf = NULL; 4776*fcf3ce44SJohn Forte data_size = 0; 4777*fcf3ce44SJohn Forte mm_mode = 0; 4778*fcf3ce44SJohn Forte 4779*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 4780*fcf3ce44SJohn Forte "%s: csize=%d rsize=%d", 4781*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), cmd_size, rsp_size); 4782*fcf3ce44SJohn Forte 4783*fcf3ce44SJohn Forte if (hba->model_info.device_id != PCI_DEVICE_ID_LP21000_M) { 4784*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4785*fcf3ce44SJohn Forte "%s: Menlo device not present. device=%x,%x", 4786*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), hba->model_info.device_id, 4787*fcf3ce44SJohn Forte hba->model_info.ssdid); 4788*fcf3ce44SJohn Forte 4789*fcf3ce44SJohn Forte rval = DFC_INVALID_ADAPTER; 4790*fcf3ce44SJohn Forte goto done; 4791*fcf3ce44SJohn Forte } 4792*fcf3ce44SJohn Forte if (!cmd_size || !cmd_buf) { 4793*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4794*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 4795*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4796*fcf3ce44SJohn Forte 4797*fcf3ce44SJohn Forte rval = DFC_ARG_NULL; 4798*fcf3ce44SJohn Forte goto done; 4799*fcf3ce44SJohn Forte } 4800*fcf3ce44SJohn Forte if (!rsp_size || !rsp_buf) { 4801*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4802*fcf3ce44SJohn Forte "%s: Null buffer2 found.", 4803*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4804*fcf3ce44SJohn Forte 4805*fcf3ce44SJohn Forte rval = DFC_ARG_NULL; 4806*fcf3ce44SJohn Forte goto done; 4807*fcf3ce44SJohn Forte } 4808*fcf3ce44SJohn Forte if (!dfc->buf3 || !dfc->buf3_size) { 4809*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4810*fcf3ce44SJohn Forte "%s: Null buffer3 found.", 4811*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4812*fcf3ce44SJohn Forte 4813*fcf3ce44SJohn Forte rval = DFC_ARG_NULL; 4814*fcf3ce44SJohn Forte goto done; 4815*fcf3ce44SJohn Forte } 4816*fcf3ce44SJohn Forte if (dfc->buf3_size < sizeof (uint32_t)) { 4817*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4818*fcf3ce44SJohn Forte "%s: Buffer3 too small. %d < %d", 4819*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf3_size, 4820*fcf3ce44SJohn Forte sizeof (uint32_t)); 4821*fcf3ce44SJohn Forte 4822*fcf3ce44SJohn Forte rval = DFC_ARG_TOOSMALL; 4823*fcf3ce44SJohn Forte goto done; 4824*fcf3ce44SJohn Forte } 4825*fcf3ce44SJohn Forte /* Read the command code first */ 4826*fcf3ce44SJohn Forte if (ddi_copyin((void *)cmd_buf, (void *)&cmd_code, 4827*fcf3ce44SJohn Forte sizeof (uint32_t), mode) != 0) { 4828*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4829*fcf3ce44SJohn Forte "%s: Unable to read command code.", 4830*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4831*fcf3ce44SJohn Forte 4832*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 4833*fcf3ce44SJohn Forte goto done; 4834*fcf3ce44SJohn Forte } 4835*fcf3ce44SJohn Forte cmd_code = SWAP_LONG(cmd_code); 4836*fcf3ce44SJohn Forte 4837*fcf3ce44SJohn Forte /* Look for Zephyr specific commands */ 4838*fcf3ce44SJohn Forte if (cmd_code & 0x80000000) { 4839*fcf3ce44SJohn Forte bzero((uint8_t *)&reset_cmd, sizeof (menlo_reset_cmd_t)); 4840*fcf3ce44SJohn Forte bzero((uint8_t *)&set_cmd, sizeof (menlo_set_cmd_t)); 4841*fcf3ce44SJohn Forte bzero((uint8_t *)&rsp_code, sizeof (uint32_t)); 4842*fcf3ce44SJohn Forte 4843*fcf3ce44SJohn Forte /* Validate response buffer */ 4844*fcf3ce44SJohn Forte if (rsp_size < sizeof (uint32_t)) { 4845*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4846*fcf3ce44SJohn Forte "%s: Response overrun.", 4847*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4848*fcf3ce44SJohn Forte rval = DFC_RSP_BUF_OVERRUN; 4849*fcf3ce44SJohn Forte goto done; 4850*fcf3ce44SJohn Forte } 4851*fcf3ce44SJohn Forte /* All of these responses will be 4 bytes only */ 4852*fcf3ce44SJohn Forte rsp_size = sizeof (uint32_t); 4853*fcf3ce44SJohn Forte rsp_code = 0; 4854*fcf3ce44SJohn Forte 4855*fcf3ce44SJohn Forte /* Validate command buffer */ 4856*fcf3ce44SJohn Forte switch (cmd_code) { 4857*fcf3ce44SJohn Forte case MENLO_CMD_RESET: 4858*fcf3ce44SJohn Forte if (cmd_size < sizeof (menlo_reset_cmd_t)) { 4859*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4860*fcf3ce44SJohn Forte "%s: Invalid command size. %d < %d", 4861*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), cmd_size, 4862*fcf3ce44SJohn Forte sizeof (menlo_reset_cmd_t)); 4863*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 4864*fcf3ce44SJohn Forte goto done; 4865*fcf3ce44SJohn Forte } 4866*fcf3ce44SJohn Forte cmd_size = sizeof (menlo_reset_cmd_t); 4867*fcf3ce44SJohn Forte 4868*fcf3ce44SJohn Forte /* Read the command buffer */ 4869*fcf3ce44SJohn Forte if (ddi_copyin((void *)cmd_buf, (void *)&reset_cmd, 4870*fcf3ce44SJohn Forte cmd_size, mode) != 0) { 4871*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4872*fcf3ce44SJohn Forte "%s: Unable to read command buffer.", 4873*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4874*fcf3ce44SJohn Forte 4875*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 4876*fcf3ce44SJohn Forte goto done; 4877*fcf3ce44SJohn Forte } 4878*fcf3ce44SJohn Forte if (reset_cmd.firmware) { 4879*fcf3ce44SJohn Forte /* MENLO_FW_GOLDEN */ 4880*fcf3ce44SJohn Forte value = 1; 4881*fcf3ce44SJohn Forte 4882*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 4883*fcf3ce44SJohn Forte "%s: Reset with Golden" 4884*fcf3ce44SJohn Forte " firmware requested.", 4885*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4886*fcf3ce44SJohn Forte 4887*fcf3ce44SJohn Forte } else { 4888*fcf3ce44SJohn Forte /* MENLO_FW_OPERATIONAL */ 4889*fcf3ce44SJohn Forte value = 0; 4890*fcf3ce44SJohn Forte 4891*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 4892*fcf3ce44SJohn Forte "%s: Reset with Operational" 4893*fcf3ce44SJohn Forte " firmware requested.", 4894*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4895*fcf3ce44SJohn Forte } 4896*fcf3ce44SJohn Forte 4897*fcf3ce44SJohn Forte addr = 0x103007; 4898*fcf3ce44SJohn Forte 4899*fcf3ce44SJohn Forte break; 4900*fcf3ce44SJohn Forte 4901*fcf3ce44SJohn Forte case MENLO_CMD_SET_MODE: 4902*fcf3ce44SJohn Forte if (cmd_size < sizeof (menlo_set_cmd_t)) { 4903*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4904*fcf3ce44SJohn Forte "%s: Invalid command size. %d < %d", 4905*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), cmd_size, 4906*fcf3ce44SJohn Forte sizeof (menlo_set_cmd_t)); 4907*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 4908*fcf3ce44SJohn Forte goto done; 4909*fcf3ce44SJohn Forte } 4910*fcf3ce44SJohn Forte cmd_size = sizeof (menlo_set_cmd_t); 4911*fcf3ce44SJohn Forte 4912*fcf3ce44SJohn Forte /* Read the command buffer */ 4913*fcf3ce44SJohn Forte if (ddi_copyin((void *)cmd_buf, (void *)&set_cmd, 4914*fcf3ce44SJohn Forte cmd_size, mode) != 0) { 4915*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4916*fcf3ce44SJohn Forte "%s: Unable to read command buffer.", 4917*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4918*fcf3ce44SJohn Forte 4919*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 4920*fcf3ce44SJohn Forte goto done; 4921*fcf3ce44SJohn Forte } 4922*fcf3ce44SJohn Forte if (set_cmd.value1) { 4923*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 4924*fcf3ce44SJohn Forte "%s: Maintenance mode" 4925*fcf3ce44SJohn Forte " enable requested.", 4926*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4927*fcf3ce44SJohn Forte 4928*fcf3ce44SJohn Forte /* Make sure the mode flag is cleared */ 4929*fcf3ce44SJohn Forte if (hba->flag & FC_MENLO_MODE) { 4930*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 4931*fcf3ce44SJohn Forte hba->flag &= ~FC_MENLO_MODE; 4932*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 4933*fcf3ce44SJohn Forte } 4934*fcf3ce44SJohn Forte mm_mode = 1; 4935*fcf3ce44SJohn Forte } else { 4936*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 4937*fcf3ce44SJohn Forte "%s: Maintenance mode" 4938*fcf3ce44SJohn Forte " disable requested.", 4939*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4940*fcf3ce44SJohn Forte } 4941*fcf3ce44SJohn Forte 4942*fcf3ce44SJohn Forte addr = 0x103107; 4943*fcf3ce44SJohn Forte value = mm_mode; 4944*fcf3ce44SJohn Forte 4945*fcf3ce44SJohn Forte break; 4946*fcf3ce44SJohn Forte 4947*fcf3ce44SJohn Forte default: 4948*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4949*fcf3ce44SJohn Forte "%s: Invalid command. cmd=%x", 4950*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), cmd_code); 4951*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 4952*fcf3ce44SJohn Forte goto done; 4953*fcf3ce44SJohn Forte } 4954*fcf3ce44SJohn Forte 4955*fcf3ce44SJohn Forte if ((mbq = (MAILBOXQ *) 4956*fcf3ce44SJohn Forte kmem_zalloc(sizeof (MAILBOXQ), KM_SLEEP)) == 0) { 4957*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4958*fcf3ce44SJohn Forte "%s: Unable to allocate mailbox buffer.", 4959*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4960*fcf3ce44SJohn Forte 4961*fcf3ce44SJohn Forte rval = DFC_SYSRES_ERROR; 4962*fcf3ce44SJohn Forte goto done; 4963*fcf3ce44SJohn Forte } 4964*fcf3ce44SJohn Forte mb = (MAILBOX *)mbq; 4965*fcf3ce44SJohn Forte 4966*fcf3ce44SJohn Forte /* Create the set_variable mailbox request */ 4967*fcf3ce44SJohn Forte emlxs_mb_set_var(hba, mb, addr, value); 4968*fcf3ce44SJohn Forte 4969*fcf3ce44SJohn Forte mbq->flag |= MBQ_PASSTHRU; 4970*fcf3ce44SJohn Forte 4971*fcf3ce44SJohn Forte /* issue the mbox cmd to the sli */ 4972*fcf3ce44SJohn Forte mbxstatus = emlxs_mb_issue_cmd(hba, mb, MBX_WAIT, 0); 4973*fcf3ce44SJohn Forte 4974*fcf3ce44SJohn Forte if (mbxstatus) { 4975*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4976*fcf3ce44SJohn Forte "%s: %s failed. mbxstatus=0x%x", 4977*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 4978*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), 4979*fcf3ce44SJohn Forte mbxstatus); 4980*fcf3ce44SJohn Forte 4981*fcf3ce44SJohn Forte if (mbxstatus == MBX_TIMEOUT) { 4982*fcf3ce44SJohn Forte rval = DFC_TIMEOUT; 4983*fcf3ce44SJohn Forte } else { 4984*fcf3ce44SJohn Forte rval = DFC_IO_ERROR; 4985*fcf3ce44SJohn Forte } 4986*fcf3ce44SJohn Forte goto done; 4987*fcf3ce44SJohn Forte } 4988*fcf3ce44SJohn Forte if (ddi_copyout((void *)&rsp_code, (void *)rsp_buf, 4989*fcf3ce44SJohn Forte rsp_size, mode) != 0) { 4990*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 4991*fcf3ce44SJohn Forte "%s: Unable to write response.", 4992*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 4993*fcf3ce44SJohn Forte 4994*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 4995*fcf3ce44SJohn Forte goto done; 4996*fcf3ce44SJohn Forte } 4997*fcf3ce44SJohn Forte if (ddi_copyout((void *)&rsp_size, (void *)dfc->buf3, 4998*fcf3ce44SJohn Forte dfc->buf3_size, mode) != 0) { 4999*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5000*fcf3ce44SJohn Forte "%s: Unable to write response size.", 5001*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5002*fcf3ce44SJohn Forte 5003*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 5004*fcf3ce44SJohn Forte goto done; 5005*fcf3ce44SJohn Forte } 5006*fcf3ce44SJohn Forte /* Check if we need to wait for maintenance mode */ 5007*fcf3ce44SJohn Forte if (mm_mode && !(hba->flag & FC_MENLO_MODE)) { 5008*fcf3ce44SJohn Forte /* Wait for link to come up in maintenance mode */ 5009*fcf3ce44SJohn Forte mutex_enter(&EMLXS_LINKUP_LOCK); 5010*fcf3ce44SJohn Forte 5011*fcf3ce44SJohn Forte timeout = emlxs_timeout(hba, 30); 5012*fcf3ce44SJohn Forte 5013*fcf3ce44SJohn Forte rval = 0; 5014*fcf3ce44SJohn Forte while ((rval != -1) && !(hba->flag & FC_MENLO_MODE)) { 5015*fcf3ce44SJohn Forte rval = cv_timedwait(&EMLXS_LINKUP_CV, 5016*fcf3ce44SJohn Forte &EMLXS_LINKUP_LOCK, timeout); 5017*fcf3ce44SJohn Forte } 5018*fcf3ce44SJohn Forte 5019*fcf3ce44SJohn Forte mutex_exit(&EMLXS_LINKUP_LOCK); 5020*fcf3ce44SJohn Forte 5021*fcf3ce44SJohn Forte if (rval == -1) { 5022*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5023*fcf3ce44SJohn Forte "%s: Menlo maintenance mode" 5024*fcf3ce44SJohn Forte " error. Timeout.", 5025*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5026*fcf3ce44SJohn Forte 5027*fcf3ce44SJohn Forte rval = DFC_TIMEOUT; 5028*fcf3ce44SJohn Forte goto done; 5029*fcf3ce44SJohn Forte } 5030*fcf3ce44SJohn Forte } 5031*fcf3ce44SJohn Forte } else { /* Standard commands */ 5032*fcf3ce44SJohn Forte if (hba->state <= FC_LINK_DOWN) { 5033*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5034*fcf3ce44SJohn Forte "%s: Adapter link down.", 5035*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5036*fcf3ce44SJohn Forte 5037*fcf3ce44SJohn Forte rval = DFC_LINKDOWN_ERROR; 5038*fcf3ce44SJohn Forte goto done; 5039*fcf3ce44SJohn Forte } 5040*fcf3ce44SJohn Forte if (cmd_code == MENLO_CMD_FW_DOWNLOAD) { 5041*fcf3ce44SJohn Forte /* Check cmd size */ 5042*fcf3ce44SJohn Forte /* 5043*fcf3ce44SJohn Forte * Must be at least 12 bytes of command plus 4 bytes 5044*fcf3ce44SJohn Forte * of data 5045*fcf3ce44SJohn Forte */ 5046*fcf3ce44SJohn Forte if (cmd_size < (12 + 4)) { 5047*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5048*fcf3ce44SJohn Forte "%s: Invalid command size. %d < %d", 5049*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), cmd_size, 5050*fcf3ce44SJohn Forte (12 + 4)); 5051*fcf3ce44SJohn Forte 5052*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 5053*fcf3ce44SJohn Forte goto done; 5054*fcf3ce44SJohn Forte } 5055*fcf3ce44SJohn Forte /* Extract data buffer from command buffer */ 5056*fcf3ce44SJohn Forte data_buf = cmd_buf + 12; 5057*fcf3ce44SJohn Forte data_size = cmd_size - 12; 5058*fcf3ce44SJohn Forte cmd_size = 12; 5059*fcf3ce44SJohn Forte } 5060*fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, cmd_size, 5061*fcf3ce44SJohn Forte rsp_size, 0, KM_NOSLEEP))) { 5062*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5063*fcf3ce44SJohn Forte "%s: Unable to allocate packet.", 5064*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5065*fcf3ce44SJohn Forte 5066*fcf3ce44SJohn Forte rval = DFC_SYSRES_ERROR; 5067*fcf3ce44SJohn Forte goto done; 5068*fcf3ce44SJohn Forte } 5069*fcf3ce44SJohn Forte /* Make this a polled IO */ 5070*fcf3ce44SJohn Forte pkt->pkt_tran_flags &= ~FC_TRAN_INTR; 5071*fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_NO_INTR; 5072*fcf3ce44SJohn Forte pkt->pkt_comp = NULL; 5073*fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE; 5074*fcf3ce44SJohn Forte pkt->pkt_timeout = 30; 5075*fcf3ce44SJohn Forte 5076*fcf3ce44SJohn Forte /* Build the fc header */ 5077*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(EMLXS_MENLO_DID); 5078*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_COMMAND; 5079*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.s_id = SWAP_DATA24_LO(port->did); 5080*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = EMLXS_MENLO_TYPE; 5081*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = F_CTL_FIRST_SEQ | F_CTL_END_SEQ | 5082*fcf3ce44SJohn Forte F_CTL_SEQ_INITIATIVE; 5083*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 5084*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 5085*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 5086*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xFFFF; 5087*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xFFFF; 5088*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 5089*fcf3ce44SJohn Forte 5090*fcf3ce44SJohn Forte /* Copy in the command buffer */ 5091*fcf3ce44SJohn Forte if (ddi_copyin((void *)cmd_buf, (void *)pkt->pkt_cmd, 5092*fcf3ce44SJohn Forte cmd_size, mode) != 0) { 5093*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5094*fcf3ce44SJohn Forte "%s: Unable to read command buffer.", 5095*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5096*fcf3ce44SJohn Forte 5097*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 5098*fcf3ce44SJohn Forte goto done; 5099*fcf3ce44SJohn Forte } 5100*fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 5101*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5102*fcf3ce44SJohn Forte "%s: Unable to send packet.", 5103*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5104*fcf3ce44SJohn Forte 5105*fcf3ce44SJohn Forte rval = DFC_IO_ERROR; 5106*fcf3ce44SJohn Forte goto done; 5107*fcf3ce44SJohn Forte } 5108*fcf3ce44SJohn Forte if (pkt->pkt_state != FC_PKT_SUCCESS) { 5109*fcf3ce44SJohn Forte if (pkt->pkt_state == FC_PKT_TIMEOUT) { 5110*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5111*fcf3ce44SJohn Forte "%s: Pkt Transport error. Pkt Timeout.", 5112*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5113*fcf3ce44SJohn Forte rval = DFC_TIMEOUT; 5114*fcf3ce44SJohn Forte } else if ((pkt->pkt_state == FC_PKT_LOCAL_RJT) && 5115*fcf3ce44SJohn Forte (pkt->pkt_reason == FC_REASON_OVERRUN)) { 5116*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5117*fcf3ce44SJohn Forte "%s: Pkt Transport error." 5118*fcf3ce44SJohn Forte " Response overrun.", 5119*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5120*fcf3ce44SJohn Forte rval = DFC_RSP_BUF_OVERRUN; 5121*fcf3ce44SJohn Forte } else { 5122*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5123*fcf3ce44SJohn Forte "%s: Pkt Transport error. state=%x", 5124*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 5125*fcf3ce44SJohn Forte pkt->pkt_state); 5126*fcf3ce44SJohn Forte rval = DFC_IO_ERROR; 5127*fcf3ce44SJohn Forte } 5128*fcf3ce44SJohn Forte goto done; 5129*fcf3ce44SJohn Forte } 5130*fcf3ce44SJohn Forte if (cmd_code == MENLO_CMD_FW_DOWNLOAD) { 5131*fcf3ce44SJohn Forte uint32_t *rsp; 5132*fcf3ce44SJohn Forte 5133*fcf3ce44SJohn Forte /* Check response code */ 5134*fcf3ce44SJohn Forte rsp = (uint32_t *)pkt->pkt_resp; 5135*fcf3ce44SJohn Forte rsp_code = *rsp; 5136*fcf3ce44SJohn Forte rsp_code = SWAP_LONG(rsp_code); 5137*fcf3ce44SJohn Forte 5138*fcf3ce44SJohn Forte if (rsp_code == MENLO_RSP_SUCCESS) { 5139*fcf3ce44SJohn Forte /* Now transmit the data phase */ 5140*fcf3ce44SJohn Forte 5141*fcf3ce44SJohn Forte /* Save last rx_id */ 5142*fcf3ce44SJohn Forte uint32_t rx_id = pkt->pkt_cmd_fhdr.rx_id; 5143*fcf3ce44SJohn Forte 5144*fcf3ce44SJohn Forte /* Free old pkt */ 5145*fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 5146*fcf3ce44SJohn Forte 5147*fcf3ce44SJohn Forte /* Allocate data pkt */ 5148*fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, data_size, 5149*fcf3ce44SJohn Forte rsp_size, 0, KM_NOSLEEP))) { 5150*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 5151*fcf3ce44SJohn Forte &emlxs_dfc_error_msg, 5152*fcf3ce44SJohn Forte "%s: Unable to allocate" 5153*fcf3ce44SJohn Forte " data packet.", 5154*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5155*fcf3ce44SJohn Forte 5156*fcf3ce44SJohn Forte rval = DFC_SYSRES_ERROR; 5157*fcf3ce44SJohn Forte goto done; 5158*fcf3ce44SJohn Forte } 5159*fcf3ce44SJohn Forte /* Make this a polled IO */ 5160*fcf3ce44SJohn Forte pkt->pkt_tran_flags &= ~FC_TRAN_INTR; 5161*fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_NO_INTR; 5162*fcf3ce44SJohn Forte pkt->pkt_comp = NULL; 5163*fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND; 5164*fcf3ce44SJohn Forte pkt->pkt_timeout = 30; 5165*fcf3ce44SJohn Forte 5166*fcf3ce44SJohn Forte /* Build the fc header */ 5167*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = 5168*fcf3ce44SJohn Forte SWAP_DATA24_LO(EMLXS_MENLO_DID); 5169*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_COMMAND; 5170*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.s_id = 5171*fcf3ce44SJohn Forte SWAP_DATA24_LO(port->did); 5172*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = EMLXS_MENLO_TYPE; 5173*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = F_CTL_FIRST_SEQ | 5174*fcf3ce44SJohn Forte F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE; 5175*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 5176*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 5177*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 5178*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xFFFF; 5179*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = rx_id; 5180*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 5181*fcf3ce44SJohn Forte 5182*fcf3ce44SJohn Forte /* Copy in the data buffer */ 5183*fcf3ce44SJohn Forte if (ddi_copyin((void *)data_buf, 5184*fcf3ce44SJohn Forte (void *)pkt->pkt_cmd, data_size, 5185*fcf3ce44SJohn Forte mode) != 0) { 5186*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 5187*fcf3ce44SJohn Forte &emlxs_dfc_error_msg, 5188*fcf3ce44SJohn Forte "%s: Unable to read data buffer.", 5189*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5190*fcf3ce44SJohn Forte 5191*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 5192*fcf3ce44SJohn Forte goto done; 5193*fcf3ce44SJohn Forte } 5194*fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 5195*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 5196*fcf3ce44SJohn Forte &emlxs_dfc_error_msg, 5197*fcf3ce44SJohn Forte "%s: Unable to send data packet.", 5198*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5199*fcf3ce44SJohn Forte 5200*fcf3ce44SJohn Forte rval = DFC_IO_ERROR; 5201*fcf3ce44SJohn Forte goto done; 5202*fcf3ce44SJohn Forte } 5203*fcf3ce44SJohn Forte if (pkt->pkt_state != FC_PKT_SUCCESS) { 5204*fcf3ce44SJohn Forte if (pkt->pkt_state == FC_PKT_TIMEOUT) { 5205*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 5206*fcf3ce44SJohn Forte &emlxs_dfc_error_msg, 5207*fcf3ce44SJohn Forte "%s: Data Pkt Transport" 5208*fcf3ce44SJohn Forte " error. Pkt Timeout.", 5209*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5210*fcf3ce44SJohn Forte rval = DFC_TIMEOUT; 5211*fcf3ce44SJohn Forte } else if ((pkt->pkt_state == 5212*fcf3ce44SJohn Forte FC_PKT_LOCAL_RJT) && 5213*fcf3ce44SJohn Forte (pkt->pkt_reason == 5214*fcf3ce44SJohn Forte FC_REASON_OVERRUN)) { 5215*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 5216*fcf3ce44SJohn Forte &emlxs_dfc_error_msg, 5217*fcf3ce44SJohn Forte "%s: Data Pkt Transport " 5218*fcf3ce44SJohn Forte "error. Response overrun.", 5219*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5220*fcf3ce44SJohn Forte rval = DFC_RSP_BUF_OVERRUN; 5221*fcf3ce44SJohn Forte } else { 5222*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 5223*fcf3ce44SJohn Forte &emlxs_dfc_error_msg, 5224*fcf3ce44SJohn Forte "%s: Data Pkt Transport " 5225*fcf3ce44SJohn Forte "error. state=%x", 5226*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 5227*fcf3ce44SJohn Forte pkt->pkt_state); 5228*fcf3ce44SJohn Forte rval = DFC_IO_ERROR; 5229*fcf3ce44SJohn Forte } 5230*fcf3ce44SJohn Forte goto done; 5231*fcf3ce44SJohn Forte } 5232*fcf3ce44SJohn Forte } 5233*fcf3ce44SJohn Forte } 5234*fcf3ce44SJohn Forte if (ddi_copyout((void *)pkt->pkt_resp, (void *)rsp_buf, 5235*fcf3ce44SJohn Forte rsp_size, mode) != 0) { 5236*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5237*fcf3ce44SJohn Forte "%s: Unable to write response.", 5238*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5239*fcf3ce44SJohn Forte 5240*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 5241*fcf3ce44SJohn Forte goto done; 5242*fcf3ce44SJohn Forte } 5243*fcf3ce44SJohn Forte rsp_size -= pkt->pkt_resp_resid; 5244*fcf3ce44SJohn Forte if (ddi_copyout((void *)&rsp_size, (void *)dfc->buf3, 5245*fcf3ce44SJohn Forte dfc->buf3_size, mode) != 0) { 5246*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5247*fcf3ce44SJohn Forte "%s: Unable to write response size.", 5248*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5249*fcf3ce44SJohn Forte 5250*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 5251*fcf3ce44SJohn Forte goto done; 5252*fcf3ce44SJohn Forte } 5253*fcf3ce44SJohn Forte } 5254*fcf3ce44SJohn Forte 5255*fcf3ce44SJohn Forte rval = 0; 5256*fcf3ce44SJohn Forte 5257*fcf3ce44SJohn Forte done: 5258*fcf3ce44SJohn Forte 5259*fcf3ce44SJohn Forte if (pkt) { 5260*fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 5261*fcf3ce44SJohn Forte } 5262*fcf3ce44SJohn Forte if (mbq) { 5263*fcf3ce44SJohn Forte kmem_free(mbq, sizeof (MAILBOXQ)); 5264*fcf3ce44SJohn Forte } 5265*fcf3ce44SJohn Forte return (rval); 5266*fcf3ce44SJohn Forte 5267*fcf3ce44SJohn Forte } /* emlxs_dfc_send_menlo() */ 5268*fcf3ce44SJohn Forte 5269*fcf3ce44SJohn Forte 5270*fcf3ce44SJohn Forte 5271*fcf3ce44SJohn Forte extern void 5272*fcf3ce44SJohn Forte emlxs_fcoe_attention_thread(void *arg) 5273*fcf3ce44SJohn Forte { 5274*fcf3ce44SJohn Forte emlxs_hba_t *hba = (emlxs_hba_t *)arg; 5275*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 5276*fcf3ce44SJohn Forte menlo_init_rsp_t *rsp; 5277*fcf3ce44SJohn Forte menlo_get_cmd_t *cmd; 5278*fcf3ce44SJohn Forte fc_packet_t *pkt = NULL; 5279*fcf3ce44SJohn Forte 5280*fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, sizeof (menlo_get_cmd_t), 5281*fcf3ce44SJohn Forte sizeof (menlo_init_rsp_t), 0, KM_NOSLEEP))) { 5282*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5283*fcf3ce44SJohn Forte "FCoE attention: Unable to allocate packet."); 5284*fcf3ce44SJohn Forte 5285*fcf3ce44SJohn Forte return; 5286*fcf3ce44SJohn Forte } 5287*fcf3ce44SJohn Forte /* Make this a polled IO */ 5288*fcf3ce44SJohn Forte pkt->pkt_tran_flags &= ~FC_TRAN_INTR; 5289*fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_NO_INTR; 5290*fcf3ce44SJohn Forte pkt->pkt_comp = NULL; 5291*fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE; 5292*fcf3ce44SJohn Forte pkt->pkt_timeout = 30; 5293*fcf3ce44SJohn Forte 5294*fcf3ce44SJohn Forte /* Build the fc header */ 5295*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(EMLXS_MENLO_DID); 5296*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_COMMAND; 5297*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.s_id = SWAP_DATA24_LO(port->did); 5298*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = EMLXS_MENLO_TYPE; 5299*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = F_CTL_FIRST_SEQ | F_CTL_END_SEQ | 5300*fcf3ce44SJohn Forte F_CTL_SEQ_INITIATIVE; 5301*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 5302*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 5303*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 5304*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xFFFF; 5305*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xFFFF; 5306*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 5307*fcf3ce44SJohn Forte 5308*fcf3ce44SJohn Forte cmd = (menlo_get_cmd_t *)pkt->pkt_cmd; 5309*fcf3ce44SJohn Forte cmd->code = MENLO_CMD_GET_INIT; 5310*fcf3ce44SJohn Forte cmd->context = 0; 5311*fcf3ce44SJohn Forte cmd->length = sizeof (menlo_init_rsp_t); 5312*fcf3ce44SJohn Forte 5313*fcf3ce44SJohn Forte /* Little Endian Swap */ 5314*fcf3ce44SJohn Forte cmd->code = SWAP_LONG(cmd->code); 5315*fcf3ce44SJohn Forte cmd->length = SWAP_LONG(cmd->length); 5316*fcf3ce44SJohn Forte 5317*fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 5318*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5319*fcf3ce44SJohn Forte "FCoE attention: Unable to send packet."); 5320*fcf3ce44SJohn Forte 5321*fcf3ce44SJohn Forte goto done; 5322*fcf3ce44SJohn Forte } 5323*fcf3ce44SJohn Forte if (pkt->pkt_state != FC_PKT_SUCCESS) { 5324*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5325*fcf3ce44SJohn Forte "FCoE attention: Pkt Transport error. state=%x", 5326*fcf3ce44SJohn Forte pkt->pkt_state); 5327*fcf3ce44SJohn Forte 5328*fcf3ce44SJohn Forte goto done; 5329*fcf3ce44SJohn Forte } 5330*fcf3ce44SJohn Forte /* Check response code */ 5331*fcf3ce44SJohn Forte rsp = (menlo_init_rsp_t *)pkt->pkt_resp; 5332*fcf3ce44SJohn Forte rsp->code = SWAP_LONG(rsp->code); 5333*fcf3ce44SJohn Forte 5334*fcf3ce44SJohn Forte if (rsp->code != MENLO_RSP_SUCCESS) { 5335*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5336*fcf3ce44SJohn Forte "FCoE attention: FCOE Response error =%x", 5337*fcf3ce44SJohn Forte rsp->code); 5338*fcf3ce44SJohn Forte 5339*fcf3ce44SJohn Forte goto done; 5340*fcf3ce44SJohn Forte } 5341*fcf3ce44SJohn Forte /* Little Endian Swap */ 5342*fcf3ce44SJohn Forte rsp->bb_credit = SWAP_LONG(rsp->bb_credit); 5343*fcf3ce44SJohn Forte rsp->frame_size = SWAP_LONG(rsp->frame_size); 5344*fcf3ce44SJohn Forte rsp->fw_version = SWAP_LONG(rsp->fw_version); 5345*fcf3ce44SJohn Forte rsp->reset_status = SWAP_LONG(rsp->reset_status); 5346*fcf3ce44SJohn Forte rsp->maint_status = SWAP_LONG(rsp->maint_status); 5347*fcf3ce44SJohn Forte rsp->fw_type = SWAP_LONG(rsp->fw_type); 5348*fcf3ce44SJohn Forte rsp->fru_data_valid = SWAP_LONG(rsp->fru_data_valid); 5349*fcf3ce44SJohn Forte 5350*fcf3ce44SJohn Forte /* Log the event */ 5351*fcf3ce44SJohn Forte emlxs_log_fcoe_event(port, rsp); 5352*fcf3ce44SJohn Forte 5353*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 5354*fcf3ce44SJohn Forte "MENLO_INIT: bb_credit = 0x%x", rsp->bb_credit); 5355*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 5356*fcf3ce44SJohn Forte "MENLO_INIT: frame_size = 0x%x", rsp->frame_size); 5357*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 5358*fcf3ce44SJohn Forte "MENLO_INIT: fw_version = 0x%x", rsp->fw_version); 5359*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 5360*fcf3ce44SJohn Forte "MENLO_INIT: reset_status = 0x%x", rsp->reset_status); 5361*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 5362*fcf3ce44SJohn Forte "MENLO_INIT: maint_status = 0x%x", rsp->maint_status); 5363*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 5364*fcf3ce44SJohn Forte "MENLO_INIT: fw_type = 0x%x", rsp->fw_type); 5365*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 5366*fcf3ce44SJohn Forte "MENLO_INIT: fru_data_valid = 0x%x", rsp->fru_data_valid); 5367*fcf3ce44SJohn Forte 5368*fcf3ce44SJohn Forte /* Perform attention checks */ 5369*fcf3ce44SJohn Forte if (rsp->fru_data_valid == 0) { 5370*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_adapter_error_msg, 5371*fcf3ce44SJohn Forte "Invalid FRU data found on adapter." 5372*fcf3ce44SJohn Forte " Return adapter to Emulex for repair."); 5373*fcf3ce44SJohn Forte } 5374*fcf3ce44SJohn Forte switch (rsp->fw_type) { 5375*fcf3ce44SJohn Forte case MENLO_FW_TYPE_GOLDEN: 5376*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_adapter_warning_msg, 5377*fcf3ce44SJohn Forte "FCoE chip is running Golden firmware." 5378*fcf3ce44SJohn Forte " Update FCoE firmware immediately."); 5379*fcf3ce44SJohn Forte break; 5380*fcf3ce44SJohn Forte 5381*fcf3ce44SJohn Forte case MENLO_FW_TYPE_DIAG: 5382*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_adapter_notice_msg, 5383*fcf3ce44SJohn Forte "FCoE chip is running Diagnostic firmware." 5384*fcf3ce44SJohn Forte " Operational use of the adapter is suspended."); 5385*fcf3ce44SJohn Forte break; 5386*fcf3ce44SJohn Forte } 5387*fcf3ce44SJohn Forte 5388*fcf3ce44SJohn Forte done: 5389*fcf3ce44SJohn Forte 5390*fcf3ce44SJohn Forte if (pkt) { 5391*fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 5392*fcf3ce44SJohn Forte } 5393*fcf3ce44SJohn Forte return; 5394*fcf3ce44SJohn Forte 5395*fcf3ce44SJohn Forte } /* emlxs_fcoe_attention_thread() */ 5396*fcf3ce44SJohn Forte 5397*fcf3ce44SJohn Forte #endif /* MENLO_SUPPORT */ 5398*fcf3ce44SJohn Forte 5399*fcf3ce44SJohn Forte 5400*fcf3ce44SJohn Forte static int32_t 5401*fcf3ce44SJohn Forte emlxs_dfc_write_flash(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 5402*fcf3ce44SJohn Forte { 5403*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 5404*fcf3ce44SJohn Forte uint32_t offset; 5405*fcf3ce44SJohn Forte uint32_t cnt; 5406*fcf3ce44SJohn Forte uint8_t *buffer; 5407*fcf3ce44SJohn Forte uint8_t *bptr; 5408*fcf3ce44SJohn Forte uint32_t i; 5409*fcf3ce44SJohn Forte 5410*fcf3ce44SJohn Forte if (hba->bus_type != SBUS_FC) { 5411*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5412*fcf3ce44SJohn Forte "%s: Invalid bus_type. (bus_type=%x)", 5413*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), hba->bus_type); 5414*fcf3ce44SJohn Forte 5415*fcf3ce44SJohn Forte return (DFC_ARG_INVALID); 5416*fcf3ce44SJohn Forte } 5417*fcf3ce44SJohn Forte if (!(hba->flag & FC_OFFLINE_MODE)) { 5418*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5419*fcf3ce44SJohn Forte "%s: Adapter not offline.", 5420*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5421*fcf3ce44SJohn Forte 5422*fcf3ce44SJohn Forte return (DFC_ONLINE_ERROR); 5423*fcf3ce44SJohn Forte } 5424*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 5425*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5426*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 5427*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5428*fcf3ce44SJohn Forte 5429*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 5430*fcf3ce44SJohn Forte } 5431*fcf3ce44SJohn Forte offset = dfc->data1; 5432*fcf3ce44SJohn Forte cnt = dfc->data2; 5433*fcf3ce44SJohn Forte 5434*fcf3ce44SJohn Forte if (offset > (64 * 1024)) { 5435*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5436*fcf3ce44SJohn Forte "%s: Offset too large. (offset=%d)", 5437*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), offset); 5438*fcf3ce44SJohn Forte 5439*fcf3ce44SJohn Forte return (DFC_ARG_TOOBIG); 5440*fcf3ce44SJohn Forte } 5441*fcf3ce44SJohn Forte if (cnt > dfc->buf1_size) { 5442*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5443*fcf3ce44SJohn Forte "%s: Count too large. (count=%d)", 5444*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), cnt); 5445*fcf3ce44SJohn Forte 5446*fcf3ce44SJohn Forte return (DFC_ARG_TOOBIG); 5447*fcf3ce44SJohn Forte } 5448*fcf3ce44SJohn Forte if ((cnt + offset) > (64 * 1024)) { 5449*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5450*fcf3ce44SJohn Forte "%s: Count+Offset too large. (count=%d offset=%d)", 5451*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), cnt, offset); 5452*fcf3ce44SJohn Forte 5453*fcf3ce44SJohn Forte return (DFC_ARG_TOOBIG); 5454*fcf3ce44SJohn Forte } 5455*fcf3ce44SJohn Forte if (cnt == 0) { 5456*fcf3ce44SJohn Forte return (0); 5457*fcf3ce44SJohn Forte } 5458*fcf3ce44SJohn Forte if ((buffer = (uint8_t *)kmem_zalloc(cnt, KM_NOSLEEP)) == NULL) { 5459*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5460*fcf3ce44SJohn Forte "%s: Unable to allocate buffer.", 5461*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5462*fcf3ce44SJohn Forte 5463*fcf3ce44SJohn Forte return (DFC_SYSRES_ERROR); 5464*fcf3ce44SJohn Forte } 5465*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf1, (void *)buffer, 5466*fcf3ce44SJohn Forte cnt, mode) != 0) { 5467*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5468*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 5469*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5470*fcf3ce44SJohn Forte 5471*fcf3ce44SJohn Forte kmem_free(buffer, cnt); 5472*fcf3ce44SJohn Forte return (DFC_COPYIN_ERROR); 5473*fcf3ce44SJohn Forte } 5474*fcf3ce44SJohn Forte bptr = buffer; 5475*fcf3ce44SJohn Forte for (i = 0; i < cnt; i++) { 5476*fcf3ce44SJohn Forte SBUS_WRITE_FLASH_COPY(hba, offset++, (unsigned long)bptr++); 5477*fcf3ce44SJohn Forte } 5478*fcf3ce44SJohn Forte 5479*fcf3ce44SJohn Forte kmem_free(buffer, cnt); 5480*fcf3ce44SJohn Forte 5481*fcf3ce44SJohn Forte return (0); 5482*fcf3ce44SJohn Forte 5483*fcf3ce44SJohn Forte } /* emlxs_dfc_write_flash() */ 5484*fcf3ce44SJohn Forte 5485*fcf3ce44SJohn Forte 5486*fcf3ce44SJohn Forte static int32_t 5487*fcf3ce44SJohn Forte emlxs_dfc_read_flash(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 5488*fcf3ce44SJohn Forte { 5489*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 5490*fcf3ce44SJohn Forte uint32_t offset; 5491*fcf3ce44SJohn Forte uint32_t count; 5492*fcf3ce44SJohn Forte uint32_t outsz; 5493*fcf3ce44SJohn Forte uint8_t *buffer; 5494*fcf3ce44SJohn Forte uint8_t *bptr; 5495*fcf3ce44SJohn Forte uint32_t i; 5496*fcf3ce44SJohn Forte 5497*fcf3ce44SJohn Forte if (hba->bus_type != SBUS_FC) { 5498*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5499*fcf3ce44SJohn Forte "%s: Invalid bus_type. (bus_type=%x)", 5500*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), hba->bus_type); 5501*fcf3ce44SJohn Forte 5502*fcf3ce44SJohn Forte return (DFC_ARG_INVALID); 5503*fcf3ce44SJohn Forte } 5504*fcf3ce44SJohn Forte if (!(hba->flag & FC_OFFLINE_MODE)) { 5505*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5506*fcf3ce44SJohn Forte "%s: Adapter not offline.", 5507*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5508*fcf3ce44SJohn Forte 5509*fcf3ce44SJohn Forte return (DFC_ONLINE_ERROR); 5510*fcf3ce44SJohn Forte } 5511*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 5512*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5513*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 5514*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5515*fcf3ce44SJohn Forte 5516*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 5517*fcf3ce44SJohn Forte } 5518*fcf3ce44SJohn Forte offset = dfc->data1; 5519*fcf3ce44SJohn Forte count = dfc->data2; 5520*fcf3ce44SJohn Forte outsz = dfc->buf1_size; 5521*fcf3ce44SJohn Forte 5522*fcf3ce44SJohn Forte if (offset > (64 * 1024)) { 5523*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5524*fcf3ce44SJohn Forte "%s: Offset too large. (offset=%d)", 5525*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), offset); 5526*fcf3ce44SJohn Forte 5527*fcf3ce44SJohn Forte return (DFC_ARG_TOOBIG); 5528*fcf3ce44SJohn Forte } 5529*fcf3ce44SJohn Forte if ((count + offset) > (64 * 1024)) { 5530*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5531*fcf3ce44SJohn Forte "%s: Count+Offset too large. (count = %d offset = %d)", 5532*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), count, offset); 5533*fcf3ce44SJohn Forte 5534*fcf3ce44SJohn Forte return (DFC_ARG_TOOBIG); 5535*fcf3ce44SJohn Forte } 5536*fcf3ce44SJohn Forte if (count < outsz) { 5537*fcf3ce44SJohn Forte outsz = count; 5538*fcf3ce44SJohn Forte } 5539*fcf3ce44SJohn Forte if ((buffer = (uint8_t *)kmem_zalloc(outsz, KM_NOSLEEP)) == NULL) { 5540*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5541*fcf3ce44SJohn Forte "%s: Unable to allocate buffer.", 5542*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5543*fcf3ce44SJohn Forte 5544*fcf3ce44SJohn Forte return (DFC_SYSRES_ERROR); 5545*fcf3ce44SJohn Forte } 5546*fcf3ce44SJohn Forte bptr = buffer; 5547*fcf3ce44SJohn Forte for (i = 0; i < outsz; i++) { 5548*fcf3ce44SJohn Forte *bptr++ = SBUS_READ_FLASH_COPY(hba, offset++); 5549*fcf3ce44SJohn Forte } 5550*fcf3ce44SJohn Forte 5551*fcf3ce44SJohn Forte if (ddi_copyout((void *)buffer, (void *)dfc->buf1, 5552*fcf3ce44SJohn Forte outsz, mode) != 0) { 5553*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5554*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 5555*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5556*fcf3ce44SJohn Forte 5557*fcf3ce44SJohn Forte kmem_free(buffer, outsz); 5558*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 5559*fcf3ce44SJohn Forte } 5560*fcf3ce44SJohn Forte kmem_free(buffer, outsz); 5561*fcf3ce44SJohn Forte 5562*fcf3ce44SJohn Forte return (0); 5563*fcf3ce44SJohn Forte 5564*fcf3ce44SJohn Forte } /* emlxs_dfc_read_flash() */ 5565*fcf3ce44SJohn Forte 5566*fcf3ce44SJohn Forte 5567*fcf3ce44SJohn Forte static int32_t 5568*fcf3ce44SJohn Forte emlxs_dfc_send_els(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 5569*fcf3ce44SJohn Forte { 5570*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 5571*fcf3ce44SJohn Forte uint8_t *rsp_buf; 5572*fcf3ce44SJohn Forte uint8_t *cmd_buf; 5573*fcf3ce44SJohn Forte dfc_destid_t destid; 5574*fcf3ce44SJohn Forte uint32_t rsp_size; 5575*fcf3ce44SJohn Forte uint32_t cmd_size; 5576*fcf3ce44SJohn Forte uint32_t timeout; 5577*fcf3ce44SJohn Forte fc_packet_t *pkt = NULL; 5578*fcf3ce44SJohn Forte NODELIST *ndlp; 5579*fcf3ce44SJohn Forte uint32_t did; 5580*fcf3ce44SJohn Forte uint32_t rval = 0; 5581*fcf3ce44SJohn Forte char buffer[128]; 5582*fcf3ce44SJohn Forte 5583*fcf3ce44SJohn Forte cmd_buf = dfc->buf1; 5584*fcf3ce44SJohn Forte cmd_size = dfc->buf1_size; 5585*fcf3ce44SJohn Forte rsp_buf = dfc->buf2; 5586*fcf3ce44SJohn Forte rsp_size = dfc->buf2_size; 5587*fcf3ce44SJohn Forte 5588*fcf3ce44SJohn Forte timeout = 2 * hba->fc_ratov; 5589*fcf3ce44SJohn Forte 5590*fcf3ce44SJohn Forte if (!cmd_size || !cmd_buf) { 5591*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5592*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 5593*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5594*fcf3ce44SJohn Forte 5595*fcf3ce44SJohn Forte rval = DFC_ARG_NULL; 5596*fcf3ce44SJohn Forte goto done; 5597*fcf3ce44SJohn Forte } 5598*fcf3ce44SJohn Forte if (!rsp_buf || !rsp_size) { 5599*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5600*fcf3ce44SJohn Forte "%s: Null buffer2 found.", 5601*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5602*fcf3ce44SJohn Forte 5603*fcf3ce44SJohn Forte rval = DFC_ARG_NULL; 5604*fcf3ce44SJohn Forte goto done; 5605*fcf3ce44SJohn Forte } 5606*fcf3ce44SJohn Forte if (!dfc->buf3 || !dfc->buf3_size) { 5607*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5608*fcf3ce44SJohn Forte "%s: Null buffer3 found.", 5609*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5610*fcf3ce44SJohn Forte 5611*fcf3ce44SJohn Forte rval = DFC_ARG_NULL; 5612*fcf3ce44SJohn Forte goto done; 5613*fcf3ce44SJohn Forte } 5614*fcf3ce44SJohn Forte if (dfc->buf3_size < sizeof (dfc_destid_t)) { 5615*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5616*fcf3ce44SJohn Forte "%s: Buffer3 too small. (size=%d)", 5617*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf3_size); 5618*fcf3ce44SJohn Forte 5619*fcf3ce44SJohn Forte rval = DFC_ARG_TOOSMALL; 5620*fcf3ce44SJohn Forte goto done; 5621*fcf3ce44SJohn Forte } 5622*fcf3ce44SJohn Forte if (!dfc->buf4 || !dfc->buf4_size) { 5623*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5624*fcf3ce44SJohn Forte "%s: Null buffer4 found.", 5625*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5626*fcf3ce44SJohn Forte 5627*fcf3ce44SJohn Forte rval = DFC_ARG_NULL; 5628*fcf3ce44SJohn Forte goto done; 5629*fcf3ce44SJohn Forte } 5630*fcf3ce44SJohn Forte if (dfc->buf4_size < sizeof (uint32_t)) { 5631*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5632*fcf3ce44SJohn Forte "%s: Buffer4 too small. (size=%d)", 5633*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf4_size); 5634*fcf3ce44SJohn Forte 5635*fcf3ce44SJohn Forte rval = DFC_ARG_TOOSMALL; 5636*fcf3ce44SJohn Forte goto done; 5637*fcf3ce44SJohn Forte } 5638*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf3, (void *)&destid, 5639*fcf3ce44SJohn Forte sizeof (dfc_destid_t), mode) != 0) { 5640*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5641*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 5642*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5643*fcf3ce44SJohn Forte 5644*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 5645*fcf3ce44SJohn Forte goto done; 5646*fcf3ce44SJohn Forte } 5647*fcf3ce44SJohn Forte if (destid.idType == 0) { 5648*fcf3ce44SJohn Forte if ((ndlp = emlxs_node_find_wwpn(port, destid.wwpn)) == NULL) { 5649*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5650*fcf3ce44SJohn Forte "%s: WWPN does not exists. %s", 5651*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 5652*fcf3ce44SJohn Forte emlxs_wwn_xlate(buffer, destid.wwpn)); 5653*fcf3ce44SJohn Forte 5654*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 5655*fcf3ce44SJohn Forte goto done; 5656*fcf3ce44SJohn Forte } 5657*fcf3ce44SJohn Forte did = ndlp->nlp_DID; 5658*fcf3ce44SJohn Forte } else { 5659*fcf3ce44SJohn Forte if (emlxs_node_find_did(port, destid.d_id) == NULL) { 5660*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5661*fcf3ce44SJohn Forte "%s: DID does not exist. did=%x", 5662*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), destid.d_id); 5663*fcf3ce44SJohn Forte 5664*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 5665*fcf3ce44SJohn Forte goto done; 5666*fcf3ce44SJohn Forte } 5667*fcf3ce44SJohn Forte did = destid.d_id; 5668*fcf3ce44SJohn Forte } 5669*fcf3ce44SJohn Forte 5670*fcf3ce44SJohn Forte if (did == 0) { 5671*fcf3ce44SJohn Forte did = port->did; 5672*fcf3ce44SJohn Forte } 5673*fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, cmd_size, rsp_size, 0, KM_NOSLEEP))) { 5674*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5675*fcf3ce44SJohn Forte "%s: Unable to allocate packet.", 5676*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5677*fcf3ce44SJohn Forte 5678*fcf3ce44SJohn Forte rval = DFC_SYSRES_ERROR; 5679*fcf3ce44SJohn Forte goto done; 5680*fcf3ce44SJohn Forte } 5681*fcf3ce44SJohn Forte /* Make this a polled IO */ 5682*fcf3ce44SJohn Forte pkt->pkt_tran_flags &= ~FC_TRAN_INTR; 5683*fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_NO_INTR; 5684*fcf3ce44SJohn Forte pkt->pkt_comp = NULL; 5685*fcf3ce44SJohn Forte 5686*fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE; 5687*fcf3ce44SJohn Forte pkt->pkt_timeout = (timeout) ? timeout : 30; 5688*fcf3ce44SJohn Forte 5689*fcf3ce44SJohn Forte /* Build the fc header */ 5690*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(did); 5691*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_ELS_REQ; 5692*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.s_id = SWAP_DATA24_LO(port->did); 5693*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 5694*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = F_CTL_FIRST_SEQ | F_CTL_END_SEQ | 5695*fcf3ce44SJohn Forte F_CTL_SEQ_INITIATIVE; 5696*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 5697*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 5698*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 5699*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xFFFF; 5700*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xFFFF; 5701*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 5702*fcf3ce44SJohn Forte 5703*fcf3ce44SJohn Forte /* Copy in the command buffer */ 5704*fcf3ce44SJohn Forte if (ddi_copyin((void *)cmd_buf, (void *)pkt->pkt_cmd, 5705*fcf3ce44SJohn Forte cmd_size, mode) != 0) { 5706*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5707*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 5708*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5709*fcf3ce44SJohn Forte 5710*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 5711*fcf3ce44SJohn Forte goto done; 5712*fcf3ce44SJohn Forte } 5713*fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 5714*fcf3ce44SJohn Forte rval = DFC_IO_ERROR; 5715*fcf3ce44SJohn Forte goto done; 5716*fcf3ce44SJohn Forte } 5717*fcf3ce44SJohn Forte if (pkt->pkt_state != FC_PKT_SUCCESS) { 5718*fcf3ce44SJohn Forte if (pkt->pkt_state == FC_PKT_TIMEOUT) { 5719*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5720*fcf3ce44SJohn Forte "Pkt Transport error. Pkt Timeout."); 5721*fcf3ce44SJohn Forte rval = DFC_TIMEOUT; 5722*fcf3ce44SJohn Forte } else { 5723*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5724*fcf3ce44SJohn Forte "Pkt Transport error. state=%x", 5725*fcf3ce44SJohn Forte pkt->pkt_state); 5726*fcf3ce44SJohn Forte rval = DFC_IO_ERROR; 5727*fcf3ce44SJohn Forte } 5728*fcf3ce44SJohn Forte goto done; 5729*fcf3ce44SJohn Forte } 5730*fcf3ce44SJohn Forte rsp_size -= pkt->pkt_resp_resid; 5731*fcf3ce44SJohn Forte if (ddi_copyout((void *)pkt->pkt_resp, (void *)rsp_buf, 5732*fcf3ce44SJohn Forte rsp_size, mode) != 0) { 5733*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5734*fcf3ce44SJohn Forte "%s: rsp_buf ddi_copyout failed.", 5735*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5736*fcf3ce44SJohn Forte 5737*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 5738*fcf3ce44SJohn Forte goto done; 5739*fcf3ce44SJohn Forte } 5740*fcf3ce44SJohn Forte if (ddi_copyout((void *)&rsp_size, (void *)dfc->buf4, 5741*fcf3ce44SJohn Forte sizeof (uint32_t), mode) != 0) { 5742*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5743*fcf3ce44SJohn Forte "%s: rsp_size ddi_copyout failed.", 5744*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5745*fcf3ce44SJohn Forte 5746*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 5747*fcf3ce44SJohn Forte goto done; 5748*fcf3ce44SJohn Forte } 5749*fcf3ce44SJohn Forte rval = 0; 5750*fcf3ce44SJohn Forte 5751*fcf3ce44SJohn Forte done: 5752*fcf3ce44SJohn Forte if (pkt) { 5753*fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 5754*fcf3ce44SJohn Forte } 5755*fcf3ce44SJohn Forte return (rval); 5756*fcf3ce44SJohn Forte 5757*fcf3ce44SJohn Forte } /* emlxs_dfc_send_els() */ 5758*fcf3ce44SJohn Forte 5759*fcf3ce44SJohn Forte 5760*fcf3ce44SJohn Forte static int32_t 5761*fcf3ce44SJohn Forte emlxs_dfc_get_ioinfo(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 5762*fcf3ce44SJohn Forte { 5763*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 5764*fcf3ce44SJohn Forte dfc_ioinfo_t ioinfo; 5765*fcf3ce44SJohn Forte uint32_t i; 5766*fcf3ce44SJohn Forte 5767*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 5768*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5769*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 5770*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5771*fcf3ce44SJohn Forte 5772*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 5773*fcf3ce44SJohn Forte } 5774*fcf3ce44SJohn Forte if (dfc->buf1_size < sizeof (dfc_ioinfo_t)) { 5775*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5776*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 5777*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 5778*fcf3ce44SJohn Forte 5779*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 5780*fcf3ce44SJohn Forte } 5781*fcf3ce44SJohn Forte bzero(&ioinfo, sizeof (dfc_ioinfo_t)); 5782*fcf3ce44SJohn Forte 5783*fcf3ce44SJohn Forte ioinfo.a_mboxCmd = HBASTATS.MboxIssued; 5784*fcf3ce44SJohn Forte ioinfo.a_mboxCmpl = HBASTATS.MboxCompleted; 5785*fcf3ce44SJohn Forte ioinfo.a_mboxErr = HBASTATS.MboxError; 5786*fcf3ce44SJohn Forte 5787*fcf3ce44SJohn Forte for (i = 0; i < MAX_RINGS; i++) { 5788*fcf3ce44SJohn Forte ioinfo.a_iocbCmd += HBASTATS.IocbIssued[i]; 5789*fcf3ce44SJohn Forte ioinfo.a_iocbRsp += HBASTATS.IocbReceived[i]; 5790*fcf3ce44SJohn Forte } 5791*fcf3ce44SJohn Forte 5792*fcf3ce44SJohn Forte ioinfo.a_adapterIntr = 5793*fcf3ce44SJohn Forte HBASTATS.IntrEvent[0] + HBASTATS.IntrEvent[1] + 5794*fcf3ce44SJohn Forte HBASTATS.IntrEvent[2] + HBASTATS.IntrEvent[3] + 5795*fcf3ce44SJohn Forte HBASTATS.IntrEvent[4] + HBASTATS.IntrEvent[5] + 5796*fcf3ce44SJohn Forte HBASTATS.IntrEvent[6] + HBASTATS.IntrEvent[7]; 5797*fcf3ce44SJohn Forte 5798*fcf3ce44SJohn Forte ioinfo.a_fcpCmd = HBASTATS.FcpIssued; 5799*fcf3ce44SJohn Forte ioinfo.a_fcpCmpl = HBASTATS.FcpCompleted; 5800*fcf3ce44SJohn Forte ioinfo.a_fcpErr = 5801*fcf3ce44SJohn Forte HBASTATS.FcpCompleted - HBASTATS.FcpGood; 5802*fcf3ce44SJohn Forte 5803*fcf3ce44SJohn Forte ioinfo.a_seqXmit = HBASTATS.IpSeqIssued; 5804*fcf3ce44SJohn Forte ioinfo.a_seqRcv = HBASTATS.IpSeqReceived; 5805*fcf3ce44SJohn Forte ioinfo.a_seqXmitErr = 5806*fcf3ce44SJohn Forte HBASTATS.IpSeqCompleted - HBASTATS.IpSeqGood; 5807*fcf3ce44SJohn Forte 5808*fcf3ce44SJohn Forte ioinfo.a_bcastXmit = HBASTATS.IpBcastIssued; 5809*fcf3ce44SJohn Forte ioinfo.a_bcastRcv = HBASTATS.IpBcastReceived; 5810*fcf3ce44SJohn Forte 5811*fcf3ce44SJohn Forte ioinfo.a_elsXmit = HBASTATS.ElsCmdIssued; 5812*fcf3ce44SJohn Forte ioinfo.a_elsRcv = HBASTATS.ElsCmdReceived; 5813*fcf3ce44SJohn Forte ioinfo.a_elsXmitErr = 5814*fcf3ce44SJohn Forte HBASTATS.ElsCmdCompleted - HBASTATS.ElsCmdGood; 5815*fcf3ce44SJohn Forte 5816*fcf3ce44SJohn Forte ioinfo.a_RSCNRcv = HBASTATS.ElsRscnReceived; 5817*fcf3ce44SJohn Forte 5818*fcf3ce44SJohn Forte ioinfo.a_elsBufPost = HBASTATS.ElsUbPosted; 5819*fcf3ce44SJohn Forte ioinfo.a_ipBufPost = HBASTATS.IpUbPosted; 5820*fcf3ce44SJohn Forte 5821*fcf3ce44SJohn Forte ioinfo.a_cnt1 = 0; 5822*fcf3ce44SJohn Forte ioinfo.a_cnt2 = 0; 5823*fcf3ce44SJohn Forte ioinfo.a_cnt3 = 0; 5824*fcf3ce44SJohn Forte ioinfo.a_cnt4 = 0; 5825*fcf3ce44SJohn Forte 5826*fcf3ce44SJohn Forte if (ddi_copyout((void *)&ioinfo, (void *)dfc->buf1, 5827*fcf3ce44SJohn Forte sizeof (dfc_ioinfo_t), mode) != 0) { 5828*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5829*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 5830*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5831*fcf3ce44SJohn Forte 5832*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 5833*fcf3ce44SJohn Forte } 5834*fcf3ce44SJohn Forte return (0); 5835*fcf3ce44SJohn Forte 5836*fcf3ce44SJohn Forte } /* emlxs_dfc_get_ioinfo() */ 5837*fcf3ce44SJohn Forte 5838*fcf3ce44SJohn Forte 5839*fcf3ce44SJohn Forte static int32_t 5840*fcf3ce44SJohn Forte emlxs_dfc_get_linkinfo(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 5841*fcf3ce44SJohn Forte { 5842*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 5843*fcf3ce44SJohn Forte dfc_linkinfo_t linkinfo; 5844*fcf3ce44SJohn Forte 5845*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 5846*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5847*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 5848*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5849*fcf3ce44SJohn Forte 5850*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 5851*fcf3ce44SJohn Forte } 5852*fcf3ce44SJohn Forte if (dfc->buf1_size < sizeof (dfc_linkinfo_t)) { 5853*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5854*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 5855*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 5856*fcf3ce44SJohn Forte 5857*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 5858*fcf3ce44SJohn Forte } 5859*fcf3ce44SJohn Forte bzero(&linkinfo, sizeof (dfc_linkinfo_t)); 5860*fcf3ce44SJohn Forte 5861*fcf3ce44SJohn Forte linkinfo.a_linkEventTag = hba->link_event_tag; 5862*fcf3ce44SJohn Forte linkinfo.a_linkUp = HBASTATS.LinkUp; 5863*fcf3ce44SJohn Forte linkinfo.a_linkDown = HBASTATS.LinkDown; 5864*fcf3ce44SJohn Forte linkinfo.a_linkMulti = HBASTATS.LinkMultiEvent; 5865*fcf3ce44SJohn Forte linkinfo.a_DID = port->did; 5866*fcf3ce44SJohn Forte linkinfo.a_topology = 0; 5867*fcf3ce44SJohn Forte 5868*fcf3ce44SJohn Forte if (hba->state <= FC_LINK_DOWN) { 5869*fcf3ce44SJohn Forte linkinfo.a_linkState = LNK_DOWN; 5870*fcf3ce44SJohn Forte } 5871*fcf3ce44SJohn Forte #ifdef MENLO_SUPPORT 5872*fcf3ce44SJohn Forte else if (hba->flag & FC_MENLO_MODE) { 5873*fcf3ce44SJohn Forte linkinfo.a_linkState = LNK_DOWN; 5874*fcf3ce44SJohn Forte linkinfo.a_topology = LNK_MENLO_MAINTENANCE; 5875*fcf3ce44SJohn Forte 5876*fcf3ce44SJohn Forte } 5877*fcf3ce44SJohn Forte #endif /* MENLO_SUPPORT */ 5878*fcf3ce44SJohn Forte else if (hba->state < FC_READY) { 5879*fcf3ce44SJohn Forte linkinfo.a_linkState = LNK_DISCOVERY; 5880*fcf3ce44SJohn Forte } else { 5881*fcf3ce44SJohn Forte linkinfo.a_linkState = LNK_READY; 5882*fcf3ce44SJohn Forte } 5883*fcf3ce44SJohn Forte 5884*fcf3ce44SJohn Forte if (linkinfo.a_linkState != LNK_DOWN) { 5885*fcf3ce44SJohn Forte if (hba->topology == TOPOLOGY_LOOP) { 5886*fcf3ce44SJohn Forte if (hba->flag & FC_FABRIC_ATTACHED) { 5887*fcf3ce44SJohn Forte linkinfo.a_topology = LNK_PUBLIC_LOOP; 5888*fcf3ce44SJohn Forte } else { 5889*fcf3ce44SJohn Forte linkinfo.a_topology = LNK_LOOP; 5890*fcf3ce44SJohn Forte } 5891*fcf3ce44SJohn Forte 5892*fcf3ce44SJohn Forte linkinfo.a_alpa = port->did & 0xff; 5893*fcf3ce44SJohn Forte linkinfo.a_alpaCnt = port->alpa_map[0]; 5894*fcf3ce44SJohn Forte 5895*fcf3ce44SJohn Forte if (linkinfo.a_alpaCnt > 127) { 5896*fcf3ce44SJohn Forte linkinfo.a_alpaCnt = 127; 5897*fcf3ce44SJohn Forte } 5898*fcf3ce44SJohn Forte bcopy((void *)&port->alpa_map[1], linkinfo.a_alpaMap, 5899*fcf3ce44SJohn Forte linkinfo.a_alpaCnt); 5900*fcf3ce44SJohn Forte } else { 5901*fcf3ce44SJohn Forte if (hba->flag & FC_FABRIC_ATTACHED) { 5902*fcf3ce44SJohn Forte linkinfo.a_topology = LNK_FABRIC; 5903*fcf3ce44SJohn Forte } else { 5904*fcf3ce44SJohn Forte linkinfo.a_topology = LNK_PT2PT; 5905*fcf3ce44SJohn Forte } 5906*fcf3ce44SJohn Forte } 5907*fcf3ce44SJohn Forte } 5908*fcf3ce44SJohn Forte bcopy(&hba->wwpn, linkinfo.a_wwpName, 8); 5909*fcf3ce44SJohn Forte bcopy(&hba->wwnn, linkinfo.a_wwnName, 8); 5910*fcf3ce44SJohn Forte 5911*fcf3ce44SJohn Forte if (ddi_copyout((void *)&linkinfo, (void *)dfc->buf1, 5912*fcf3ce44SJohn Forte sizeof (dfc_linkinfo_t), mode) != 0) { 5913*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5914*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 5915*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5916*fcf3ce44SJohn Forte 5917*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 5918*fcf3ce44SJohn Forte } 5919*fcf3ce44SJohn Forte return (0); 5920*fcf3ce44SJohn Forte 5921*fcf3ce44SJohn Forte } /* emlxs_dfc_get_linkinfo() */ 5922*fcf3ce44SJohn Forte 5923*fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT 5924*fcf3ce44SJohn Forte static int32_t 5925*fcf3ce44SJohn Forte emlxs_dfc_get_fctstat(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 5926*fcf3ce44SJohn Forte { 5927*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 5928*fcf3ce44SJohn Forte emlxs_tgtport_stat_t *statp = &TGTPORTSTAT; 5929*fcf3ce44SJohn Forte dfc_tgtport_stat_t dfcstat; 5930*fcf3ce44SJohn Forte 5931*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 5932*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5933*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 5934*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 5935*fcf3ce44SJohn Forte 5936*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 5937*fcf3ce44SJohn Forte } 5938*fcf3ce44SJohn Forte if (dfc->buf1_size < sizeof (emlxs_tgtport_stat_t)) { 5939*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 5940*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 5941*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 5942*fcf3ce44SJohn Forte 5943*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 5944*fcf3ce44SJohn Forte } 5945*fcf3ce44SJohn Forte bzero(&dfcstat, sizeof (dfcstat)); 5946*fcf3ce44SJohn Forte 5947*fcf3ce44SJohn Forte dfcstat.FctRcvDropped = statp->FctRcvDropped; 5948*fcf3ce44SJohn Forte dfcstat.FctOverQDepth = statp->FctOverQDepth; 5949*fcf3ce44SJohn Forte dfcstat.FctOutstandingIO = statp->FctOutstandingIO; 5950*fcf3ce44SJohn Forte dfcstat.FctFailedPortRegister = 5951*fcf3ce44SJohn Forte statp->FctFailedPortRegister; 5952*fcf3ce44SJohn Forte dfcstat.FctPortRegister = statp->FctPortRegister; 5953*fcf3ce44SJohn Forte dfcstat.FctPortDeregister = statp->FctPortDeregister; 5954*fcf3ce44SJohn Forte 5955*fcf3ce44SJohn Forte dfcstat.FctAbortSent = statp->FctAbortSent; 5956*fcf3ce44SJohn Forte dfcstat.FctNoBuffer = statp->FctNoBuffer; 5957*fcf3ce44SJohn Forte dfcstat.FctScsiStatusErr = statp->FctScsiStatusErr; 5958*fcf3ce44SJohn Forte dfcstat.FctScsiQfullErr = statp->FctScsiQfullErr; 5959*fcf3ce44SJohn Forte dfcstat.FctScsiResidOver = statp->FctScsiResidOver; 5960*fcf3ce44SJohn Forte dfcstat.FctScsiResidUnder = statp->FctScsiResidUnder; 5961*fcf3ce44SJohn Forte dfcstat.FctScsiSenseErr = statp->FctScsiSenseErr; 5962*fcf3ce44SJohn Forte 5963*fcf3ce44SJohn Forte dfcstat.FctEvent = statp->FctEvent; 5964*fcf3ce44SJohn Forte dfcstat.FctCompleted = statp->FctCompleted; 5965*fcf3ce44SJohn Forte dfcstat.FctCmplGood = statp->FctCmplGood; 5966*fcf3ce44SJohn Forte dfcstat.FctCmplError = statp->FctCmplError; 5967*fcf3ce44SJohn Forte dfcstat.FctStray = statp->FctStray; 5968*fcf3ce44SJohn Forte 5969*fcf3ce44SJohn Forte bcopy(&statp->FctP2IOWcnt[0], &dfcstat.FctP2IOWcnt[0], 5970*fcf3ce44SJohn Forte (sizeof (uint64_t) * MAX_TGTPORT_IOCNT)); 5971*fcf3ce44SJohn Forte bcopy(&statp->FctP2IORcnt[0], &dfcstat.FctP2IORcnt[0], 5972*fcf3ce44SJohn Forte (sizeof (uint64_t) * MAX_TGTPORT_IOCNT)); 5973*fcf3ce44SJohn Forte dfcstat.FctIOCmdCnt = statp->FctIOCmdCnt; 5974*fcf3ce44SJohn Forte dfcstat.FctReadBytes = statp->FctReadBytes; 5975*fcf3ce44SJohn Forte dfcstat.FctWriteBytes = statp->FctWriteBytes; 5976*fcf3ce44SJohn Forte dfcstat.FctCmdReceived = statp->FctCmdReceived; 5977*fcf3ce44SJohn Forte 5978*fcf3ce44SJohn Forte if (dfc->flag) { /* Clear counters after read */ 5979*fcf3ce44SJohn Forte bzero(&statp->FctP2IOWcnt[0], 5980*fcf3ce44SJohn Forte (sizeof (uint64_t) * MAX_TGTPORT_IOCNT)); 5981*fcf3ce44SJohn Forte bzero(&statp->FctP2IORcnt[0], 5982*fcf3ce44SJohn Forte (sizeof (uint64_t) * MAX_TGTPORT_IOCNT)); 5983*fcf3ce44SJohn Forte statp->FctIOCmdCnt = 0; 5984*fcf3ce44SJohn Forte statp->FctReadBytes = 0; 5985*fcf3ce44SJohn Forte statp->FctWriteBytes = 0; 5986*fcf3ce44SJohn Forte statp->FctCmdReceived = 0; 5987*fcf3ce44SJohn Forte } 5988*fcf3ce44SJohn Forte if (hba->state <= FC_LINK_DOWN) { 5989*fcf3ce44SJohn Forte dfcstat.FctLinkState = LNK_DOWN; 5990*fcf3ce44SJohn Forte } 5991*fcf3ce44SJohn Forte #ifdef MENLO_SUPPORT 5992*fcf3ce44SJohn Forte else if (hba->flag & FC_MENLO_MODE) { 5993*fcf3ce44SJohn Forte dfcstat.FctLinkState = LNK_DOWN; 5994*fcf3ce44SJohn Forte } 5995*fcf3ce44SJohn Forte #endif /* MENLO_SUPPORT */ 5996*fcf3ce44SJohn Forte else if (hba->state < FC_READY) { 5997*fcf3ce44SJohn Forte dfcstat.FctLinkState = LNK_DISCOVERY; 5998*fcf3ce44SJohn Forte } else { 5999*fcf3ce44SJohn Forte dfcstat.FctLinkState = LNK_READY; 6000*fcf3ce44SJohn Forte } 6001*fcf3ce44SJohn Forte 6002*fcf3ce44SJohn Forte if (ddi_copyout((void *)&dfcstat, (void *)dfc->buf1, 6003*fcf3ce44SJohn Forte sizeof (dfc_tgtport_stat_t), mode) != 0) { 6004*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6005*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 6006*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6007*fcf3ce44SJohn Forte 6008*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 6009*fcf3ce44SJohn Forte } 6010*fcf3ce44SJohn Forte return (0); 6011*fcf3ce44SJohn Forte 6012*fcf3ce44SJohn Forte } /* emlxs_dfc_get_fctstat() */ 6013*fcf3ce44SJohn Forte #endif /* SFCT_SUPPORT */ 6014*fcf3ce44SJohn Forte 6015*fcf3ce44SJohn Forte static int32_t 6016*fcf3ce44SJohn Forte emlxs_dfc_get_nodeinfo(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 6017*fcf3ce44SJohn Forte { 6018*fcf3ce44SJohn Forte emlxs_port_t *port; 6019*fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 6020*fcf3ce44SJohn Forte dfc_node_t *dfc_node; 6021*fcf3ce44SJohn Forte dfc_node_t *dnp; 6022*fcf3ce44SJohn Forte uint32_t node_count; 6023*fcf3ce44SJohn Forte NODELIST *nlp; 6024*fcf3ce44SJohn Forte uint32_t size; 6025*fcf3ce44SJohn Forte uint32_t i; 6026*fcf3ce44SJohn Forte 6027*fcf3ce44SJohn Forte port = &VPORT(dfc->data1); 6028*fcf3ce44SJohn Forte 6029*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 6030*fcf3ce44SJohn Forte "%s requested.", 6031*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6032*fcf3ce44SJohn Forte 6033*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 6034*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6035*fcf3ce44SJohn Forte "%s: NULL buffer1 found.", 6036*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6037*fcf3ce44SJohn Forte 6038*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 6039*fcf3ce44SJohn Forte } 6040*fcf3ce44SJohn Forte if (dfc->buf1_size < (sizeof (dfc_node_t) * MAX_NODES)) { 6041*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6042*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 6043*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 6044*fcf3ce44SJohn Forte 6045*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 6046*fcf3ce44SJohn Forte } 6047*fcf3ce44SJohn Forte if (!dfc->buf2 || !dfc->buf2_size) { 6048*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6049*fcf3ce44SJohn Forte "%s: NULL buffer2 found.", 6050*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6051*fcf3ce44SJohn Forte 6052*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 6053*fcf3ce44SJohn Forte } 6054*fcf3ce44SJohn Forte if (dfc->buf2_size < sizeof (uint32_t)) { 6055*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6056*fcf3ce44SJohn Forte "%s: Buffer2 too small. (size=%d)", 6057*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf2_size); 6058*fcf3ce44SJohn Forte 6059*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 6060*fcf3ce44SJohn Forte } 6061*fcf3ce44SJohn Forte node_count = port->node_count; 6062*fcf3ce44SJohn Forte 6063*fcf3ce44SJohn Forte if (node_count == 0) { 6064*fcf3ce44SJohn Forte return (0); 6065*fcf3ce44SJohn Forte } 6066*fcf3ce44SJohn Forte if (node_count > MAX_NODES) { 6067*fcf3ce44SJohn Forte node_count = MAX_NODES; 6068*fcf3ce44SJohn Forte } 6069*fcf3ce44SJohn Forte size = node_count * sizeof (dfc_node_t); 6070*fcf3ce44SJohn Forte 6071*fcf3ce44SJohn Forte if (!(dfc_node = (dfc_node_t *)kmem_zalloc(size, KM_NOSLEEP))) { 6072*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6073*fcf3ce44SJohn Forte "%s: Unable to allocate dfc_node.", 6074*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6075*fcf3ce44SJohn Forte 6076*fcf3ce44SJohn Forte return (DFC_SYSRES_ERROR); 6077*fcf3ce44SJohn Forte } 6078*fcf3ce44SJohn Forte dnp = dfc_node; 6079*fcf3ce44SJohn Forte 6080*fcf3ce44SJohn Forte rw_enter(&port->node_rwlock, RW_READER); 6081*fcf3ce44SJohn Forte for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) { 6082*fcf3ce44SJohn Forte nlp = port->node_table[i]; 6083*fcf3ce44SJohn Forte while (nlp != NULL) { 6084*fcf3ce44SJohn Forte dnp->port_id = nlp->nlp_DID; 6085*fcf3ce44SJohn Forte dnp->rpi = nlp->nlp_Rpi; 6086*fcf3ce44SJohn Forte dnp->xri = nlp->nlp_Xri; 6087*fcf3ce44SJohn Forte 6088*fcf3ce44SJohn Forte bcopy((char *)&nlp->sparm, (char *)&dnp->sparm, 6089*fcf3ce44SJohn Forte sizeof (dnp->sparm)); 6090*fcf3ce44SJohn Forte 6091*fcf3ce44SJohn Forte if (nlp->nlp_fcp_info & NLP_FCP_TGT_DEVICE) { 6092*fcf3ce44SJohn Forte dnp->flags |= PORT_FLAG_FCP_TARGET; 6093*fcf3ce44SJohn Forte } 6094*fcf3ce44SJohn Forte if (nlp->nlp_fcp_info & NLP_FCP_INI_DEVICE) { 6095*fcf3ce44SJohn Forte dnp->flags |= PORT_FLAG_FCP_INI; 6096*fcf3ce44SJohn Forte 6097*fcf3ce44SJohn Forte } 6098*fcf3ce44SJohn Forte if (nlp->nlp_fcp_info & NLP_FCP_2_DEVICE) { 6099*fcf3ce44SJohn Forte dnp->flags |= PORT_FLAG_FCP2; 6100*fcf3ce44SJohn Forte } 6101*fcf3ce44SJohn Forte if (cfg[CFG_NETWORK_ON].current && nlp->nlp_Xri) { 6102*fcf3ce44SJohn Forte dnp->flags |= PORT_FLAG_IP; 6103*fcf3ce44SJohn Forte } 6104*fcf3ce44SJohn Forte dnp++; 6105*fcf3ce44SJohn Forte nlp = (NODELIST *) nlp->nlp_list_next; 6106*fcf3ce44SJohn Forte } 6107*fcf3ce44SJohn Forte } 6108*fcf3ce44SJohn Forte rw_exit(&port->node_rwlock); 6109*fcf3ce44SJohn Forte 6110*fcf3ce44SJohn Forte if (ddi_copyout((void *)dfc_node, (void *)dfc->buf1, 6111*fcf3ce44SJohn Forte size, mode) != 0) { 6112*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6113*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 6114*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6115*fcf3ce44SJohn Forte 6116*fcf3ce44SJohn Forte kmem_free(dfc_node, size); 6117*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 6118*fcf3ce44SJohn Forte } 6119*fcf3ce44SJohn Forte if (ddi_copyout((void *)&node_count, (void *)dfc->buf2, 6120*fcf3ce44SJohn Forte sizeof (uint32_t), mode) != 0) { 6121*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6122*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 6123*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6124*fcf3ce44SJohn Forte 6125*fcf3ce44SJohn Forte kmem_free(dfc_node, size); 6126*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 6127*fcf3ce44SJohn Forte } 6128*fcf3ce44SJohn Forte kmem_free(dfc_node, size); 6129*fcf3ce44SJohn Forte 6130*fcf3ce44SJohn Forte return (0); 6131*fcf3ce44SJohn Forte 6132*fcf3ce44SJohn Forte } /* emlxs_dfc_get_nodeinfo() */ 6133*fcf3ce44SJohn Forte 6134*fcf3ce44SJohn Forte 6135*fcf3ce44SJohn Forte static int32_t 6136*fcf3ce44SJohn Forte emlxs_dfc_read_mem(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 6137*fcf3ce44SJohn Forte { 6138*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 6139*fcf3ce44SJohn Forte uint32_t offset; 6140*fcf3ce44SJohn Forte uint32_t size; 6141*fcf3ce44SJohn Forte uint32_t max_size; 6142*fcf3ce44SJohn Forte uint8_t *buffer; 6143*fcf3ce44SJohn Forte uint8_t *slim; 6144*fcf3ce44SJohn Forte 6145*fcf3ce44SJohn Forte offset = dfc->data1; 6146*fcf3ce44SJohn Forte size = dfc->data2; 6147*fcf3ce44SJohn Forte 6148*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 6149*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6150*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 6151*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6152*fcf3ce44SJohn Forte 6153*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 6154*fcf3ce44SJohn Forte } 6155*fcf3ce44SJohn Forte if (size > dfc->buf1_size) { 6156*fcf3ce44SJohn Forte size = dfc->buf1_size; 6157*fcf3ce44SJohn Forte } 6158*fcf3ce44SJohn Forte if (offset % 4) { 6159*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6160*fcf3ce44SJohn Forte "%s: Offset misaligned. (offset=%d)", 6161*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), offset); 6162*fcf3ce44SJohn Forte 6163*fcf3ce44SJohn Forte return (DFC_ARG_MISALIGNED); 6164*fcf3ce44SJohn Forte } 6165*fcf3ce44SJohn Forte if (size % 4) { 6166*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6167*fcf3ce44SJohn Forte "%s: Size misaligned. (size=%d)", 6168*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), size); 6169*fcf3ce44SJohn Forte 6170*fcf3ce44SJohn Forte return (DFC_ARG_MISALIGNED); 6171*fcf3ce44SJohn Forte } 6172*fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 6173*fcf3ce44SJohn Forte max_size = SLI2_SLIM2_SIZE; 6174*fcf3ce44SJohn Forte } else { 6175*fcf3ce44SJohn Forte max_size = 4096; 6176*fcf3ce44SJohn Forte } 6177*fcf3ce44SJohn Forte 6178*fcf3ce44SJohn Forte if (offset >= max_size) { 6179*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6180*fcf3ce44SJohn Forte "%s: Offset too large. (offset=%d)", 6181*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), offset); 6182*fcf3ce44SJohn Forte 6183*fcf3ce44SJohn Forte return (DFC_ARG_TOOBIG); 6184*fcf3ce44SJohn Forte } 6185*fcf3ce44SJohn Forte if ((size + offset) > max_size) { 6186*fcf3ce44SJohn Forte size = (max_size - offset); 6187*fcf3ce44SJohn Forte } 6188*fcf3ce44SJohn Forte if (!(buffer = (uint8_t *)kmem_zalloc(size, KM_NOSLEEP))) { 6189*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6190*fcf3ce44SJohn Forte "%s: Unable to allocate buffer.", 6191*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6192*fcf3ce44SJohn Forte 6193*fcf3ce44SJohn Forte return (DFC_SYSRES_ERROR); 6194*fcf3ce44SJohn Forte } 6195*fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 6196*fcf3ce44SJohn Forte slim = (uint8_t *)hba->slim2.virt + offset; 6197*fcf3ce44SJohn Forte emlxs_pcimem_bcopy((uint32_t *)slim, (uint32_t *)buffer, 6198*fcf3ce44SJohn Forte size); 6199*fcf3ce44SJohn Forte } else { 6200*fcf3ce44SJohn Forte slim = (uint8_t *)hba->slim_addr + offset; 6201*fcf3ce44SJohn Forte READ_SLIM_COPY(hba, (uint32_t *)buffer, 6202*fcf3ce44SJohn Forte (uint32_t *)slim, (size / 4)); 6203*fcf3ce44SJohn Forte } 6204*fcf3ce44SJohn Forte 6205*fcf3ce44SJohn Forte if (ddi_copyout((void *)buffer, (void *)dfc->buf1, 6206*fcf3ce44SJohn Forte size, mode) != 0) { 6207*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6208*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 6209*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6210*fcf3ce44SJohn Forte 6211*fcf3ce44SJohn Forte kmem_free(buffer, size); 6212*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 6213*fcf3ce44SJohn Forte } 6214*fcf3ce44SJohn Forte kmem_free(buffer, size); 6215*fcf3ce44SJohn Forte 6216*fcf3ce44SJohn Forte return (0); 6217*fcf3ce44SJohn Forte 6218*fcf3ce44SJohn Forte } /* emlxs_dfc_read_mem() */ 6219*fcf3ce44SJohn Forte 6220*fcf3ce44SJohn Forte 6221*fcf3ce44SJohn Forte static int32_t 6222*fcf3ce44SJohn Forte emlxs_dfc_write_mem(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 6223*fcf3ce44SJohn Forte { 6224*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 6225*fcf3ce44SJohn Forte uint32_t offset; 6226*fcf3ce44SJohn Forte uint32_t size; 6227*fcf3ce44SJohn Forte uint32_t max_size; 6228*fcf3ce44SJohn Forte uint8_t *buffer; 6229*fcf3ce44SJohn Forte uint8_t *slim; 6230*fcf3ce44SJohn Forte 6231*fcf3ce44SJohn Forte offset = dfc->data1; 6232*fcf3ce44SJohn Forte size = dfc->data2; 6233*fcf3ce44SJohn Forte 6234*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 6235*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6236*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 6237*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6238*fcf3ce44SJohn Forte 6239*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 6240*fcf3ce44SJohn Forte } 6241*fcf3ce44SJohn Forte if (size > dfc->buf1_size) { 6242*fcf3ce44SJohn Forte size = dfc->buf1_size; 6243*fcf3ce44SJohn Forte } 6244*fcf3ce44SJohn Forte if (offset % 4) { 6245*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6246*fcf3ce44SJohn Forte "%s: Offset misaligned. (offset=%d)", 6247*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), offset); 6248*fcf3ce44SJohn Forte 6249*fcf3ce44SJohn Forte return (DFC_ARG_MISALIGNED); 6250*fcf3ce44SJohn Forte } 6251*fcf3ce44SJohn Forte if (size % 4) { 6252*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6253*fcf3ce44SJohn Forte "%s: Size misaligned. (szie=%d)", 6254*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), size); 6255*fcf3ce44SJohn Forte 6256*fcf3ce44SJohn Forte return (DFC_ARG_MISALIGNED); 6257*fcf3ce44SJohn Forte } 6258*fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 6259*fcf3ce44SJohn Forte max_size = SLI2_SLIM2_SIZE; 6260*fcf3ce44SJohn Forte } else { 6261*fcf3ce44SJohn Forte max_size = 4096; 6262*fcf3ce44SJohn Forte } 6263*fcf3ce44SJohn Forte 6264*fcf3ce44SJohn Forte if (offset >= max_size) { 6265*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6266*fcf3ce44SJohn Forte "%s: Offset too large. (offset=%d)", 6267*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), offset); 6268*fcf3ce44SJohn Forte 6269*fcf3ce44SJohn Forte return (DFC_ARG_TOOBIG); 6270*fcf3ce44SJohn Forte } 6271*fcf3ce44SJohn Forte if ((size + offset) > max_size) { 6272*fcf3ce44SJohn Forte size = (max_size - offset); 6273*fcf3ce44SJohn Forte } 6274*fcf3ce44SJohn Forte if (!(buffer = (uint8_t *)kmem_zalloc(size, KM_NOSLEEP))) { 6275*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6276*fcf3ce44SJohn Forte "%s: Unable to allocate buffer.", 6277*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6278*fcf3ce44SJohn Forte 6279*fcf3ce44SJohn Forte return (DFC_SYSRES_ERROR); 6280*fcf3ce44SJohn Forte } 6281*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf1, (void *)buffer, 6282*fcf3ce44SJohn Forte size, mode) != 0) { 6283*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6284*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 6285*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6286*fcf3ce44SJohn Forte 6287*fcf3ce44SJohn Forte kmem_free(buffer, size); 6288*fcf3ce44SJohn Forte return (DFC_COPYIN_ERROR); 6289*fcf3ce44SJohn Forte } 6290*fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 6291*fcf3ce44SJohn Forte slim = (uint8_t *)hba->slim2.virt + offset; 6292*fcf3ce44SJohn Forte emlxs_pcimem_bcopy((uint32_t *)buffer, (uint32_t *)slim, 6293*fcf3ce44SJohn Forte size); 6294*fcf3ce44SJohn Forte } else { 6295*fcf3ce44SJohn Forte slim = (uint8_t *)hba->slim_addr + offset; 6296*fcf3ce44SJohn Forte WRITE_SLIM_COPY(hba, (uint32_t *)buffer, (uint32_t *)slim, 6297*fcf3ce44SJohn Forte (size / 4)); 6298*fcf3ce44SJohn Forte } 6299*fcf3ce44SJohn Forte 6300*fcf3ce44SJohn Forte kmem_free(buffer, size); 6301*fcf3ce44SJohn Forte 6302*fcf3ce44SJohn Forte return (0); 6303*fcf3ce44SJohn Forte 6304*fcf3ce44SJohn Forte } /* emlxs_dfc_write_mem() */ 6305*fcf3ce44SJohn Forte 6306*fcf3ce44SJohn Forte 6307*fcf3ce44SJohn Forte /*ARGSUSED*/ 6308*fcf3ce44SJohn Forte static int32_t 6309*fcf3ce44SJohn Forte emlxs_dfc_write_ctlreg(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 6310*fcf3ce44SJohn Forte { 6311*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 6312*fcf3ce44SJohn Forte uint32_t offset; 6313*fcf3ce44SJohn Forte uint32_t value; 6314*fcf3ce44SJohn Forte 6315*fcf3ce44SJohn Forte offset = dfc->data1; 6316*fcf3ce44SJohn Forte value = dfc->data2; 6317*fcf3ce44SJohn Forte 6318*fcf3ce44SJohn Forte if (!(hba->flag & FC_OFFLINE_MODE)) { 6319*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6320*fcf3ce44SJohn Forte "%s: Adapter not offline.", 6321*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6322*fcf3ce44SJohn Forte 6323*fcf3ce44SJohn Forte return (DFC_ONLINE_ERROR); 6324*fcf3ce44SJohn Forte } 6325*fcf3ce44SJohn Forte if (offset % 4) { 6326*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6327*fcf3ce44SJohn Forte "%s: Offset misaligned. (offset=%d)", 6328*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), offset); 6329*fcf3ce44SJohn Forte 6330*fcf3ce44SJohn Forte return (DFC_ARG_MISALIGNED); 6331*fcf3ce44SJohn Forte } 6332*fcf3ce44SJohn Forte if (offset > 255) { 6333*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6334*fcf3ce44SJohn Forte "%s: Offset too large. (offset=%d)", 6335*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), offset); 6336*fcf3ce44SJohn Forte 6337*fcf3ce44SJohn Forte return (DFC_ARG_TOOBIG); 6338*fcf3ce44SJohn Forte } 6339*fcf3ce44SJohn Forte WRITE_CSR_REG(hba, (hba->csr_addr + offset), value); 6340*fcf3ce44SJohn Forte 6341*fcf3ce44SJohn Forte return (0); 6342*fcf3ce44SJohn Forte 6343*fcf3ce44SJohn Forte } /* emlxs_dfc_write_ctlreg() */ 6344*fcf3ce44SJohn Forte 6345*fcf3ce44SJohn Forte 6346*fcf3ce44SJohn Forte static int32_t 6347*fcf3ce44SJohn Forte emlxs_dfc_read_ctlreg(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 6348*fcf3ce44SJohn Forte { 6349*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 6350*fcf3ce44SJohn Forte uint32_t offset; 6351*fcf3ce44SJohn Forte uint32_t value; 6352*fcf3ce44SJohn Forte 6353*fcf3ce44SJohn Forte offset = dfc->data1; 6354*fcf3ce44SJohn Forte 6355*fcf3ce44SJohn Forte if (offset % 4) { 6356*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6357*fcf3ce44SJohn Forte "%s: Offset misaligned. (offset=%d)", 6358*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), offset); 6359*fcf3ce44SJohn Forte 6360*fcf3ce44SJohn Forte return (DFC_ARG_MISALIGNED); 6361*fcf3ce44SJohn Forte } 6362*fcf3ce44SJohn Forte if (offset > 255) { 6363*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6364*fcf3ce44SJohn Forte "%s: Offset too large. (offset=%d)", 6365*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), offset); 6366*fcf3ce44SJohn Forte 6367*fcf3ce44SJohn Forte return (DFC_ARG_TOOBIG); 6368*fcf3ce44SJohn Forte } 6369*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 6370*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6371*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 6372*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6373*fcf3ce44SJohn Forte 6374*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 6375*fcf3ce44SJohn Forte } 6376*fcf3ce44SJohn Forte if (dfc->buf1_size < sizeof (uint32_t)) { 6377*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6378*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 6379*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 6380*fcf3ce44SJohn Forte 6381*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 6382*fcf3ce44SJohn Forte } 6383*fcf3ce44SJohn Forte value = READ_CSR_REG(hba, (hba->csr_addr + offset)); 6384*fcf3ce44SJohn Forte 6385*fcf3ce44SJohn Forte if (ddi_copyout((void *)&value, (void *)dfc->buf1, 6386*fcf3ce44SJohn Forte sizeof (uint32_t), mode) != 0) { 6387*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6388*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 6389*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6390*fcf3ce44SJohn Forte 6391*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 6392*fcf3ce44SJohn Forte } 6393*fcf3ce44SJohn Forte return (0); 6394*fcf3ce44SJohn Forte 6395*fcf3ce44SJohn Forte } /* emlxs_dfc_read_ctlreg() */ 6396*fcf3ce44SJohn Forte 6397*fcf3ce44SJohn Forte 6398*fcf3ce44SJohn Forte static int32_t 6399*fcf3ce44SJohn Forte emlxs_dfc_set_event(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 6400*fcf3ce44SJohn Forte { 6401*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 6402*fcf3ce44SJohn Forte uint32_t event; 6403*fcf3ce44SJohn Forte uint32_t enable; 6404*fcf3ce44SJohn Forte uint32_t pid; 6405*fcf3ce44SJohn Forte uint32_t count; 6406*fcf3ce44SJohn Forte uint32_t i; 6407*fcf3ce44SJohn Forte emlxs_dfc_event_t *dfc_event; 6408*fcf3ce44SJohn Forte 6409*fcf3ce44SJohn Forte event = dfc->data1; 6410*fcf3ce44SJohn Forte pid = dfc->data2; 6411*fcf3ce44SJohn Forte enable = dfc->flag; 6412*fcf3ce44SJohn Forte 6413*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 6414*fcf3ce44SJohn Forte "%s: %s. pid=%d enable=%d", 6415*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 6416*fcf3ce44SJohn Forte emlxs_dfc_event_xlate(event), pid, enable); 6417*fcf3ce44SJohn Forte 6418*fcf3ce44SJohn Forte switch (event) { 6419*fcf3ce44SJohn Forte case FC_REG_LINK_EVENT: 6420*fcf3ce44SJohn Forte case FC_REG_RSCN_EVENT: 6421*fcf3ce44SJohn Forte case FC_REG_CT_EVENT: 6422*fcf3ce44SJohn Forte case FC_REG_DUMP_EVENT: 6423*fcf3ce44SJohn Forte case FC_REG_TEMP_EVENT: 6424*fcf3ce44SJohn Forte case FC_REG_FCOE_EVENT: 6425*fcf3ce44SJohn Forte break; 6426*fcf3ce44SJohn Forte 6427*fcf3ce44SJohn Forte case FC_REG_MULTIPULSE_EVENT: 6428*fcf3ce44SJohn Forte default: 6429*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6430*fcf3ce44SJohn Forte "%s: %s. Invalid event. pid=%d enable=%d", 6431*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 6432*fcf3ce44SJohn Forte emlxs_dfc_event_xlate(event), pid, enable); 6433*fcf3ce44SJohn Forte 6434*fcf3ce44SJohn Forte return (DFC_ARG_INVALID); 6435*fcf3ce44SJohn Forte } 6436*fcf3ce44SJohn Forte 6437*fcf3ce44SJohn Forte if (enable) { 6438*fcf3ce44SJohn Forte if (dfc->buf1_size < sizeof (uint32_t)) { 6439*fcf3ce44SJohn Forte dfc->buf1 = NULL; 6440*fcf3ce44SJohn Forte } else if (!dfc->buf1) { 6441*fcf3ce44SJohn Forte dfc->buf1_size = 0; 6442*fcf3ce44SJohn Forte } 6443*fcf3ce44SJohn Forte /* Make sure this pid/event is not already registered */ 6444*fcf3ce44SJohn Forte dfc_event = NULL; 6445*fcf3ce44SJohn Forte for (i = 0; i < MAX_DFC_EVENTS; i++) { 6446*fcf3ce44SJohn Forte dfc_event = &hba->dfc_event[i]; 6447*fcf3ce44SJohn Forte 6448*fcf3ce44SJohn Forte if (dfc_event->pid == pid && 6449*fcf3ce44SJohn Forte dfc_event->event == event) { 6450*fcf3ce44SJohn Forte break; 6451*fcf3ce44SJohn Forte } 6452*fcf3ce44SJohn Forte } 6453*fcf3ce44SJohn Forte 6454*fcf3ce44SJohn Forte if (i == MAX_DFC_EVENTS) { 6455*fcf3ce44SJohn Forte /* Find next available event object */ 6456*fcf3ce44SJohn Forte for (i = 0; i < MAX_DFC_EVENTS; i++) { 6457*fcf3ce44SJohn Forte dfc_event = &hba->dfc_event[i]; 6458*fcf3ce44SJohn Forte 6459*fcf3ce44SJohn Forte if (!dfc_event->pid && !dfc_event->event) { 6460*fcf3ce44SJohn Forte break; 6461*fcf3ce44SJohn Forte } 6462*fcf3ce44SJohn Forte } 6463*fcf3ce44SJohn Forte 6464*fcf3ce44SJohn Forte /* Return if all event objects are busy */ 6465*fcf3ce44SJohn Forte if (i == MAX_DFC_EVENTS) { 6466*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6467*fcf3ce44SJohn Forte "%s: %s. Too many events registered." 6468*fcf3ce44SJohn Forte " pid=%d enable=%d", 6469*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 6470*fcf3ce44SJohn Forte emlxs_dfc_event_xlate(event), 6471*fcf3ce44SJohn Forte pid, enable); 6472*fcf3ce44SJohn Forte 6473*fcf3ce44SJohn Forte return (DFC_DRVRES_ERROR); 6474*fcf3ce44SJohn Forte } 6475*fcf3ce44SJohn Forte } 6476*fcf3ce44SJohn Forte /* Initialize */ 6477*fcf3ce44SJohn Forte dfc_event->pid = pid; 6478*fcf3ce44SJohn Forte dfc_event->event = event; 6479*fcf3ce44SJohn Forte dfc_event->last_id = (uint32_t)-1; 6480*fcf3ce44SJohn Forte dfc_event->dataout = NULL; 6481*fcf3ce44SJohn Forte dfc_event->size = 0; 6482*fcf3ce44SJohn Forte dfc_event->mode = 0; 6483*fcf3ce44SJohn Forte 6484*fcf3ce44SJohn Forte (void) emlxs_get_dfc_event(port, dfc_event, 0); 6485*fcf3ce44SJohn Forte 6486*fcf3ce44SJohn Forte if (dfc->buf1) { 6487*fcf3ce44SJohn Forte if (ddi_copyout((void *)&dfc_event->last_id, dfc->buf1, 6488*fcf3ce44SJohn Forte sizeof (uint32_t), mode) != 0) { 6489*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6490*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 6491*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6492*fcf3ce44SJohn Forte 6493*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 6494*fcf3ce44SJohn Forte } 6495*fcf3ce44SJohn Forte } 6496*fcf3ce44SJohn Forte /* 6497*fcf3ce44SJohn Forte * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_debug_msg, "%s: %s. 6498*fcf3ce44SJohn Forte * Enabled. pid=%d id=%d", emlxs_dfc_xlate(dfc->cmd), 6499*fcf3ce44SJohn Forte * emlxs_dfc_event_xlate(event), pid, dfc_event->last_id); 6500*fcf3ce44SJohn Forte */ 6501*fcf3ce44SJohn Forte 6502*fcf3ce44SJohn Forte hba->log_events |= event; 6503*fcf3ce44SJohn Forte } else { /* Disable */ 6504*fcf3ce44SJohn Forte /* Find the event entry */ 6505*fcf3ce44SJohn Forte dfc_event = NULL; 6506*fcf3ce44SJohn Forte for (i = 0; i < MAX_DFC_EVENTS; i++) { 6507*fcf3ce44SJohn Forte dfc_event = &hba->dfc_event[i]; 6508*fcf3ce44SJohn Forte 6509*fcf3ce44SJohn Forte if (dfc_event->pid == pid && 6510*fcf3ce44SJohn Forte dfc_event->event == event) { 6511*fcf3ce44SJohn Forte break; 6512*fcf3ce44SJohn Forte } 6513*fcf3ce44SJohn Forte } 6514*fcf3ce44SJohn Forte 6515*fcf3ce44SJohn Forte if (i == MAX_DFC_EVENTS) { 6516*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6517*fcf3ce44SJohn Forte "%s: %s. Event not registered." 6518*fcf3ce44SJohn Forte " pid=%d enable=%d", 6519*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 6520*fcf3ce44SJohn Forte emlxs_dfc_event_xlate(event), 6521*fcf3ce44SJohn Forte pid, enable); 6522*fcf3ce44SJohn Forte 6523*fcf3ce44SJohn Forte return (DFC_ARG_INVALID); 6524*fcf3ce44SJohn Forte } 6525*fcf3ce44SJohn Forte /* Kill the event thread if it is sleeping */ 6526*fcf3ce44SJohn Forte (void) emlxs_kill_dfc_event(port, dfc_event); 6527*fcf3ce44SJohn Forte 6528*fcf3ce44SJohn Forte /* Count the number of pids still registered for this event */ 6529*fcf3ce44SJohn Forte count = 0; 6530*fcf3ce44SJohn Forte for (i = 0; i < MAX_DFC_EVENTS; i++) { 6531*fcf3ce44SJohn Forte dfc_event = &hba->dfc_event[i]; 6532*fcf3ce44SJohn Forte 6533*fcf3ce44SJohn Forte if (dfc_event->event == event) { 6534*fcf3ce44SJohn Forte count++; 6535*fcf3ce44SJohn Forte } 6536*fcf3ce44SJohn Forte } 6537*fcf3ce44SJohn Forte 6538*fcf3ce44SJohn Forte /* 6539*fcf3ce44SJohn Forte * If no more pids need this event, then disable logging for 6540*fcf3ce44SJohn Forte * this event 6541*fcf3ce44SJohn Forte */ 6542*fcf3ce44SJohn Forte if (count == 0) { 6543*fcf3ce44SJohn Forte hba->log_events &= ~event; 6544*fcf3ce44SJohn Forte } 6545*fcf3ce44SJohn Forte } 6546*fcf3ce44SJohn Forte 6547*fcf3ce44SJohn Forte return (0); 6548*fcf3ce44SJohn Forte 6549*fcf3ce44SJohn Forte } /* emlxs_dfc_set_event() */ 6550*fcf3ce44SJohn Forte 6551*fcf3ce44SJohn Forte 6552*fcf3ce44SJohn Forte static int32_t 6553*fcf3ce44SJohn Forte emlxs_dfc_get_eventinfo(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 6554*fcf3ce44SJohn Forte { 6555*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 6556*fcf3ce44SJohn Forte uint32_t size; 6557*fcf3ce44SJohn Forte /* uint32_t i; */ 6558*fcf3ce44SJohn Forte int32_t rval = 0; 6559*fcf3ce44SJohn Forte HBA_EVENTINFO *event_buffer = NULL; 6560*fcf3ce44SJohn Forte uint32_t event_count = 0; 6561*fcf3ce44SJohn Forte uint32_t missed = 0; 6562*fcf3ce44SJohn Forte 6563*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 6564*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6565*fcf3ce44SJohn Forte "%s: Null buffer1 buffer.", 6566*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6567*fcf3ce44SJohn Forte 6568*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 6569*fcf3ce44SJohn Forte } 6570*fcf3ce44SJohn Forte event_count = dfc->buf1_size / sizeof (HBA_EVENTINFO); 6571*fcf3ce44SJohn Forte 6572*fcf3ce44SJohn Forte if (!event_count) { 6573*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6574*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 6575*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 6576*fcf3ce44SJohn Forte 6577*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 6578*fcf3ce44SJohn Forte } 6579*fcf3ce44SJohn Forte if (!dfc->buf2 || !dfc->buf2_size) { 6580*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6581*fcf3ce44SJohn Forte "%s: Null buffer2 buffer.", 6582*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6583*fcf3ce44SJohn Forte 6584*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 6585*fcf3ce44SJohn Forte } 6586*fcf3ce44SJohn Forte if (dfc->buf2_size < sizeof (uint32_t)) { 6587*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6588*fcf3ce44SJohn Forte "%s: Buffer2 too small. (size=%d)", 6589*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf2_size); 6590*fcf3ce44SJohn Forte 6591*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 6592*fcf3ce44SJohn Forte } 6593*fcf3ce44SJohn Forte if (!dfc->buf3 || !dfc->buf3_size) { 6594*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6595*fcf3ce44SJohn Forte "%s: Null buffer3 found.", 6596*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6597*fcf3ce44SJohn Forte 6598*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 6599*fcf3ce44SJohn Forte } 6600*fcf3ce44SJohn Forte if (dfc->buf3_size < sizeof (uint32_t)) { 6601*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6602*fcf3ce44SJohn Forte "%s: Buffer3 too small. (size=%d)", 6603*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf3_size); 6604*fcf3ce44SJohn Forte 6605*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 6606*fcf3ce44SJohn Forte } 6607*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 6608*fcf3ce44SJohn Forte "%s called. max=%d", 6609*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), event_count); 6610*fcf3ce44SJohn Forte 6611*fcf3ce44SJohn Forte size = (event_count * sizeof (HBA_EVENTINFO)); 6612*fcf3ce44SJohn Forte if (!(event_buffer = (HBA_EVENTINFO *)kmem_zalloc(size, KM_SLEEP))) { 6613*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6614*fcf3ce44SJohn Forte "%s: Unable to allocate buffer. size=%d", 6615*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), size); 6616*fcf3ce44SJohn Forte 6617*fcf3ce44SJohn Forte return (DFC_SYSRES_ERROR); 6618*fcf3ce44SJohn Forte } 6619*fcf3ce44SJohn Forte if (emlxs_get_dfc_eventinfo(port, event_buffer, 6620*fcf3ce44SJohn Forte &event_count, &missed) != 0) { 6621*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6622*fcf3ce44SJohn Forte "%s: emlxs_get_dfc_eventinfo failed.", 6623*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6624*fcf3ce44SJohn Forte 6625*fcf3ce44SJohn Forte rval = DFC_DRV_ERROR; 6626*fcf3ce44SJohn Forte goto done; 6627*fcf3ce44SJohn Forte } 6628*fcf3ce44SJohn Forte if (event_count) { 6629*fcf3ce44SJohn Forte if (ddi_copyout((void *)event_buffer, dfc->buf1, 6630*fcf3ce44SJohn Forte (event_count * sizeof (HBA_EVENTINFO)), mode) != 0) { 6631*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6632*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 6633*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6634*fcf3ce44SJohn Forte 6635*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 6636*fcf3ce44SJohn Forte goto done; 6637*fcf3ce44SJohn Forte } 6638*fcf3ce44SJohn Forte } 6639*fcf3ce44SJohn Forte if (ddi_copyout((void *)&event_count, dfc->buf2, 6640*fcf3ce44SJohn Forte sizeof (uint32_t), mode) != 0) { 6641*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6642*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 6643*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6644*fcf3ce44SJohn Forte 6645*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 6646*fcf3ce44SJohn Forte goto done; 6647*fcf3ce44SJohn Forte } 6648*fcf3ce44SJohn Forte if (ddi_copyout((void *)&missed, dfc->buf3, 6649*fcf3ce44SJohn Forte sizeof (uint32_t), mode) != 0) { 6650*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6651*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 6652*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6653*fcf3ce44SJohn Forte 6654*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 6655*fcf3ce44SJohn Forte goto done; 6656*fcf3ce44SJohn Forte } 6657*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 6658*fcf3ce44SJohn Forte "%s: events=%d missed=%d new=%d last_id=%d", 6659*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), event_count, 6660*fcf3ce44SJohn Forte hba->hba_event.missed, hba->hba_event.new, 6661*fcf3ce44SJohn Forte hba->hba_event.last_id); 6662*fcf3ce44SJohn Forte 6663*fcf3ce44SJohn Forte done: 6664*fcf3ce44SJohn Forte 6665*fcf3ce44SJohn Forte if (event_buffer) { 6666*fcf3ce44SJohn Forte kmem_free(event_buffer, size); 6667*fcf3ce44SJohn Forte } 6668*fcf3ce44SJohn Forte return (rval); 6669*fcf3ce44SJohn Forte 6670*fcf3ce44SJohn Forte } /* emlxs_dfc_get_eventinfo() */ 6671*fcf3ce44SJohn Forte 6672*fcf3ce44SJohn Forte 6673*fcf3ce44SJohn Forte static int32_t 6674*fcf3ce44SJohn Forte emlxs_dfc_get_event(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 6675*fcf3ce44SJohn Forte { 6676*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 6677*fcf3ce44SJohn Forte uint32_t event; 6678*fcf3ce44SJohn Forte uint32_t pid; 6679*fcf3ce44SJohn Forte uint32_t sleep; 6680*fcf3ce44SJohn Forte uint32_t i; 6681*fcf3ce44SJohn Forte int32_t rval = DFC_SUCCESS; 6682*fcf3ce44SJohn Forte /* char *bp; */ 6683*fcf3ce44SJohn Forte emlxs_dfc_event_t *dfc_event; 6684*fcf3ce44SJohn Forte 6685*fcf3ce44SJohn Forte event = dfc->data1; 6686*fcf3ce44SJohn Forte pid = dfc->data2; 6687*fcf3ce44SJohn Forte 6688*fcf3ce44SJohn Forte if (!dfc->buf1_size) { 6689*fcf3ce44SJohn Forte dfc->buf1 = NULL; 6690*fcf3ce44SJohn Forte } else if (!dfc->buf1) { 6691*fcf3ce44SJohn Forte dfc->buf1_size = 0; 6692*fcf3ce44SJohn Forte } 6693*fcf3ce44SJohn Forte if (dfc->buf2_size < sizeof (uint32_t)) { 6694*fcf3ce44SJohn Forte dfc->buf2 = NULL; 6695*fcf3ce44SJohn Forte } else if (!dfc->buf2) { 6696*fcf3ce44SJohn Forte dfc->buf2_size = 0; 6697*fcf3ce44SJohn Forte } 6698*fcf3ce44SJohn Forte if (dfc->buf3_size < sizeof (uint32_t)) { 6699*fcf3ce44SJohn Forte dfc->buf3 = NULL; 6700*fcf3ce44SJohn Forte } else if (!dfc->buf3) { 6701*fcf3ce44SJohn Forte dfc->buf3_size = 0; 6702*fcf3ce44SJohn Forte } 6703*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 6704*fcf3ce44SJohn Forte "%s: %s. pid=%d size=%d,%p rcv_size=%d,%p id=%d", 6705*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), emlxs_dfc_event_xlate(event), 6706*fcf3ce44SJohn Forte pid, dfc->buf1_size, dfc->buf1, dfc->buf2_size, dfc->buf2, 6707*fcf3ce44SJohn Forte dfc->data3); 6708*fcf3ce44SJohn Forte 6709*fcf3ce44SJohn Forte /* Find the event entry */ 6710*fcf3ce44SJohn Forte dfc_event = NULL; 6711*fcf3ce44SJohn Forte for (i = 0; i < MAX_DFC_EVENTS; i++) { 6712*fcf3ce44SJohn Forte dfc_event = &hba->dfc_event[i]; 6713*fcf3ce44SJohn Forte 6714*fcf3ce44SJohn Forte if (dfc_event->pid == pid && dfc_event->event == event) { 6715*fcf3ce44SJohn Forte break; 6716*fcf3ce44SJohn Forte } 6717*fcf3ce44SJohn Forte } 6718*fcf3ce44SJohn Forte 6719*fcf3ce44SJohn Forte if (i == MAX_DFC_EVENTS) { 6720*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6721*fcf3ce44SJohn Forte "%s: %s. Event not registered. pid=%d", 6722*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 6723*fcf3ce44SJohn Forte emlxs_dfc_event_xlate(event), pid); 6724*fcf3ce44SJohn Forte 6725*fcf3ce44SJohn Forte return (DFC_ARG_INVALID); 6726*fcf3ce44SJohn Forte } 6727*fcf3ce44SJohn Forte if (!(hba->log_events & dfc_event->event)) { 6728*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6729*fcf3ce44SJohn Forte "%s: %s. Event not registered. pid=%d", 6730*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 6731*fcf3ce44SJohn Forte emlxs_dfc_event_xlate(event), pid); 6732*fcf3ce44SJohn Forte 6733*fcf3ce44SJohn Forte return (DFC_ARG_INVALID); 6734*fcf3ce44SJohn Forte } 6735*fcf3ce44SJohn Forte /* Initialize event buffer pointers */ 6736*fcf3ce44SJohn Forte dfc_event->dataout = dfc->buf1; 6737*fcf3ce44SJohn Forte dfc_event->size = dfc->buf1_size; 6738*fcf3ce44SJohn Forte dfc_event->last_id = dfc->data3; 6739*fcf3ce44SJohn Forte dfc_event->mode = mode; 6740*fcf3ce44SJohn Forte 6741*fcf3ce44SJohn Forte sleep = (dfc->flag & 0x01) ? 1 : 0; 6742*fcf3ce44SJohn Forte 6743*fcf3ce44SJohn Forte if ((rval = emlxs_get_dfc_event(port, dfc_event, sleep))) { 6744*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_debug_msg, 6745*fcf3ce44SJohn Forte "%s: %s. Exiting. pid=%d rsize=%d id=%d rval=%d", 6746*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 6747*fcf3ce44SJohn Forte emlxs_dfc_event_xlate(event), pid, 6748*fcf3ce44SJohn Forte dfc_event->size, dfc_event->last_id, rval); 6749*fcf3ce44SJohn Forte 6750*fcf3ce44SJohn Forte return (rval); 6751*fcf3ce44SJohn Forte } 6752*fcf3ce44SJohn Forte if (dfc->buf2) { 6753*fcf3ce44SJohn Forte if (ddi_copyout((void *)&dfc_event->size, dfc->buf2, 6754*fcf3ce44SJohn Forte sizeof (uint32_t), mode) != 0) { 6755*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6756*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 6757*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6758*fcf3ce44SJohn Forte 6759*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 6760*fcf3ce44SJohn Forte } 6761*fcf3ce44SJohn Forte } 6762*fcf3ce44SJohn Forte if (dfc->buf3) { 6763*fcf3ce44SJohn Forte if (ddi_copyout((void *)&dfc_event->last_id, dfc->buf3, 6764*fcf3ce44SJohn Forte sizeof (uint32_t), mode) != 0) { 6765*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6766*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 6767*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6768*fcf3ce44SJohn Forte 6769*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 6770*fcf3ce44SJohn Forte } 6771*fcf3ce44SJohn Forte } 6772*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_debug_msg, 6773*fcf3ce44SJohn Forte "%s: %s. Completed. pid=%d rsize=%d id=%d", 6774*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 6775*fcf3ce44SJohn Forte emlxs_dfc_event_xlate(event), pid, 6776*fcf3ce44SJohn Forte dfc_event->size, dfc_event->last_id); 6777*fcf3ce44SJohn Forte 6778*fcf3ce44SJohn Forte return (rval); 6779*fcf3ce44SJohn Forte 6780*fcf3ce44SJohn Forte } /* emlxs_dfc_get_event() */ 6781*fcf3ce44SJohn Forte 6782*fcf3ce44SJohn Forte 6783*fcf3ce44SJohn Forte 6784*fcf3ce44SJohn Forte static int32_t 6785*fcf3ce44SJohn Forte emlxs_dfc_get_dump_region(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 6786*fcf3ce44SJohn Forte { 6787*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 6788*fcf3ce44SJohn Forte uint32_t size; 6789*fcf3ce44SJohn Forte uint32_t size_only; 6790*fcf3ce44SJohn Forte uint32_t rval = 0; 6791*fcf3ce44SJohn Forte uint8_t *buffer = NULL; 6792*fcf3ce44SJohn Forte uint8_t *memptr; 6793*fcf3ce44SJohn Forte uint32_t *wptr; 6794*fcf3ce44SJohn Forte 6795*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 6796*fcf3ce44SJohn Forte "%s: region=%d size=%d", 6797*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 6798*fcf3ce44SJohn Forte dfc->data1, dfc->buf1_size); 6799*fcf3ce44SJohn Forte 6800*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 6801*fcf3ce44SJohn Forte size_only = 1; 6802*fcf3ce44SJohn Forte size = (uint32_t)-1; 6803*fcf3ce44SJohn Forte } else { 6804*fcf3ce44SJohn Forte size_only = 0; 6805*fcf3ce44SJohn Forte size = dfc->buf1_size; 6806*fcf3ce44SJohn Forte } 6807*fcf3ce44SJohn Forte 6808*fcf3ce44SJohn Forte if (!dfc->buf2 || !dfc->buf2_size) { 6809*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6810*fcf3ce44SJohn Forte "%s: Null buffer2 found.", 6811*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 6812*fcf3ce44SJohn Forte 6813*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 6814*fcf3ce44SJohn Forte } 6815*fcf3ce44SJohn Forte if (dfc->buf2_size < sizeof (uint32_t)) { 6816*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6817*fcf3ce44SJohn Forte "%s: Buffer2 too small. (size=%d)", 6818*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf2_size); 6819*fcf3ce44SJohn Forte 6820*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 6821*fcf3ce44SJohn Forte } 6822*fcf3ce44SJohn Forte switch (dfc->data1) { 6823*fcf3ce44SJohn Forte case 0: /* SLI Registers */ 6824*fcf3ce44SJohn Forte 6825*fcf3ce44SJohn Forte if (size < (4 * sizeof (uint32_t))) { 6826*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6827*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 6828*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), size); 6829*fcf3ce44SJohn Forte 6830*fcf3ce44SJohn Forte rval = DFC_ARG_TOOSMALL; 6831*fcf3ce44SJohn Forte goto done; 6832*fcf3ce44SJohn Forte } 6833*fcf3ce44SJohn Forte size = (4 * sizeof (uint32_t)); 6834*fcf3ce44SJohn Forte 6835*fcf3ce44SJohn Forte if (size_only) { 6836*fcf3ce44SJohn Forte break; 6837*fcf3ce44SJohn Forte } 6838*fcf3ce44SJohn Forte if (!(buffer = (uint8_t *)kmem_zalloc(size, KM_SLEEP))) { 6839*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6840*fcf3ce44SJohn Forte "%s: Unable to allocate buffer. size=%d", 6841*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), size); 6842*fcf3ce44SJohn Forte 6843*fcf3ce44SJohn Forte rval = DFC_SYSRES_ERROR; 6844*fcf3ce44SJohn Forte goto done; 6845*fcf3ce44SJohn Forte } 6846*fcf3ce44SJohn Forte wptr = (uint32_t *)buffer; 6847*fcf3ce44SJohn Forte 6848*fcf3ce44SJohn Forte wptr[0] = READ_CSR_REG(hba, FC_HA_REG(hba, hba->csr_addr)); 6849*fcf3ce44SJohn Forte 6850*fcf3ce44SJohn Forte wptr[1] = READ_CSR_REG(hba, FC_CA_REG(hba, hba->csr_addr)); 6851*fcf3ce44SJohn Forte 6852*fcf3ce44SJohn Forte wptr[2] = READ_CSR_REG(hba, FC_HS_REG(hba, hba->csr_addr)); 6853*fcf3ce44SJohn Forte 6854*fcf3ce44SJohn Forte wptr[3] = READ_CSR_REG(hba, FC_HC_REG(hba, hba->csr_addr)); 6855*fcf3ce44SJohn Forte 6856*fcf3ce44SJohn Forte break; 6857*fcf3ce44SJohn Forte 6858*fcf3ce44SJohn Forte case 1: /* SLIM */ 6859*fcf3ce44SJohn Forte 6860*fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 6861*fcf3ce44SJohn Forte size = MIN(SLI2_SLIM2_SIZE, size); 6862*fcf3ce44SJohn Forte } else { 6863*fcf3ce44SJohn Forte size = MIN(4096, size); 6864*fcf3ce44SJohn Forte } 6865*fcf3ce44SJohn Forte 6866*fcf3ce44SJohn Forte if (size_only) { 6867*fcf3ce44SJohn Forte break; 6868*fcf3ce44SJohn Forte } 6869*fcf3ce44SJohn Forte if (!(buffer = (uint8_t *)kmem_zalloc(size, KM_SLEEP))) { 6870*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6871*fcf3ce44SJohn Forte "%s: Unable to allocate buffer. size=%d", 6872*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), size); 6873*fcf3ce44SJohn Forte 6874*fcf3ce44SJohn Forte rval = DFC_SYSRES_ERROR; 6875*fcf3ce44SJohn Forte goto done; 6876*fcf3ce44SJohn Forte } 6877*fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 6878*fcf3ce44SJohn Forte memptr = (uint8_t *)hba->slim2.virt; 6879*fcf3ce44SJohn Forte emlxs_pcimem_bcopy((uint32_t *)memptr, 6880*fcf3ce44SJohn Forte (uint32_t *)buffer, size); 6881*fcf3ce44SJohn Forte } else { 6882*fcf3ce44SJohn Forte memptr = (uint8_t *)hba->slim_addr; 6883*fcf3ce44SJohn Forte READ_SLIM_COPY(hba, (uint32_t *)buffer, 6884*fcf3ce44SJohn Forte (uint32_t *)memptr, (size / 4)); 6885*fcf3ce44SJohn Forte } 6886*fcf3ce44SJohn Forte 6887*fcf3ce44SJohn Forte break; 6888*fcf3ce44SJohn Forte 6889*fcf3ce44SJohn Forte case 2: /* Port Control Block */ 6890*fcf3ce44SJohn Forte 6891*fcf3ce44SJohn Forte if (size < sizeof (PCB)) { 6892*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6893*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 6894*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), size); 6895*fcf3ce44SJohn Forte 6896*fcf3ce44SJohn Forte rval = DFC_ARG_TOOSMALL; 6897*fcf3ce44SJohn Forte goto done; 6898*fcf3ce44SJohn Forte } 6899*fcf3ce44SJohn Forte size = sizeof (PCB); 6900*fcf3ce44SJohn Forte 6901*fcf3ce44SJohn Forte if (size_only) { 6902*fcf3ce44SJohn Forte break; 6903*fcf3ce44SJohn Forte } 6904*fcf3ce44SJohn Forte if (!(buffer = (uint8_t *)kmem_zalloc(size, KM_SLEEP))) { 6905*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6906*fcf3ce44SJohn Forte "%s: Unable to allocate buffer. size=%d", 6907*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), size); 6908*fcf3ce44SJohn Forte 6909*fcf3ce44SJohn Forte rval = DFC_SYSRES_ERROR; 6910*fcf3ce44SJohn Forte goto done; 6911*fcf3ce44SJohn Forte } 6912*fcf3ce44SJohn Forte memptr = (uint8_t *)&(((SLIM2 *)hba->slim2.virt)->pcb); 6913*fcf3ce44SJohn Forte emlxs_pcimem_bcopy((uint32_t *)memptr, 6914*fcf3ce44SJohn Forte (uint32_t *)buffer, size); 6915*fcf3ce44SJohn Forte 6916*fcf3ce44SJohn Forte break; 6917*fcf3ce44SJohn Forte 6918*fcf3ce44SJohn Forte case 3: /* MailBox */ 6919*fcf3ce44SJohn Forte 6920*fcf3ce44SJohn Forte if (size < MAILBOX_CMD_BSIZE) { 6921*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6922*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 6923*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), size); 6924*fcf3ce44SJohn Forte 6925*fcf3ce44SJohn Forte rval = DFC_ARG_TOOSMALL; 6926*fcf3ce44SJohn Forte goto done; 6927*fcf3ce44SJohn Forte } 6928*fcf3ce44SJohn Forte size = MAILBOX_CMD_BSIZE; 6929*fcf3ce44SJohn Forte 6930*fcf3ce44SJohn Forte if (size_only) { 6931*fcf3ce44SJohn Forte break; 6932*fcf3ce44SJohn Forte } 6933*fcf3ce44SJohn Forte if (!(buffer = (uint8_t *)kmem_zalloc(size, KM_SLEEP))) { 6934*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6935*fcf3ce44SJohn Forte "%s: Unable to allocate buffer. size=%d", 6936*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), size); 6937*fcf3ce44SJohn Forte 6938*fcf3ce44SJohn Forte rval = DFC_SYSRES_ERROR; 6939*fcf3ce44SJohn Forte goto done; 6940*fcf3ce44SJohn Forte } 6941*fcf3ce44SJohn Forte if (hba->flag & FC_SLIM2_MODE) { 6942*fcf3ce44SJohn Forte memptr = (uint8_t *)hba->slim2.virt; 6943*fcf3ce44SJohn Forte emlxs_pcimem_bcopy((uint32_t *)memptr, 6944*fcf3ce44SJohn Forte (uint32_t *)buffer, size); 6945*fcf3ce44SJohn Forte } else { 6946*fcf3ce44SJohn Forte memptr = (uint8_t *)hba->slim_addr; 6947*fcf3ce44SJohn Forte READ_SLIM_COPY(hba, (uint32_t *)buffer, 6948*fcf3ce44SJohn Forte (uint32_t *)memptr, (size / 4)); 6949*fcf3ce44SJohn Forte } 6950*fcf3ce44SJohn Forte 6951*fcf3ce44SJohn Forte break; 6952*fcf3ce44SJohn Forte 6953*fcf3ce44SJohn Forte case 4: /* Host Put/Get pointer array */ 6954*fcf3ce44SJohn Forte 6955*fcf3ce44SJohn Forte if (size < MAX_RINGS * sizeof (HGP)) { 6956*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6957*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 6958*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), size); 6959*fcf3ce44SJohn Forte 6960*fcf3ce44SJohn Forte rval = DFC_ARG_TOOSMALL; 6961*fcf3ce44SJohn Forte goto done; 6962*fcf3ce44SJohn Forte } 6963*fcf3ce44SJohn Forte size = MAX_RINGS * sizeof (HGP); 6964*fcf3ce44SJohn Forte 6965*fcf3ce44SJohn Forte if (size_only) { 6966*fcf3ce44SJohn Forte break; 6967*fcf3ce44SJohn Forte } 6968*fcf3ce44SJohn Forte if (!(buffer = (uint8_t *)kmem_zalloc(size, KM_SLEEP))) { 6969*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6970*fcf3ce44SJohn Forte "%s: Unable to allocate buffer. size=%d", 6971*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), size); 6972*fcf3ce44SJohn Forte 6973*fcf3ce44SJohn Forte rval = DFC_SYSRES_ERROR; 6974*fcf3ce44SJohn Forte goto done; 6975*fcf3ce44SJohn Forte } { 6976*fcf3ce44SJohn Forte memptr = (uint8_t *)hba->slim_addr + 6977*fcf3ce44SJohn Forte hba->hgp_ring_offset; 6978*fcf3ce44SJohn Forte READ_SLIM_COPY(hba, (uint32_t *)buffer, 6979*fcf3ce44SJohn Forte (uint32_t *)memptr, (size / 4)); 6980*fcf3ce44SJohn Forte } 6981*fcf3ce44SJohn Forte 6982*fcf3ce44SJohn Forte break; 6983*fcf3ce44SJohn Forte 6984*fcf3ce44SJohn Forte case 5: /* Port Get/Put pointer array */ 6985*fcf3ce44SJohn Forte 6986*fcf3ce44SJohn Forte if (size < MAX_RINGS * sizeof (PGP)) { 6987*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 6988*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 6989*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), size); 6990*fcf3ce44SJohn Forte 6991*fcf3ce44SJohn Forte rval = DFC_ARG_TOOSMALL; 6992*fcf3ce44SJohn Forte goto done; 6993*fcf3ce44SJohn Forte } 6994*fcf3ce44SJohn Forte size = MAX_RINGS * sizeof (PGP); 6995*fcf3ce44SJohn Forte 6996*fcf3ce44SJohn Forte if (size_only) { 6997*fcf3ce44SJohn Forte break; 6998*fcf3ce44SJohn Forte } 6999*fcf3ce44SJohn Forte if (!(buffer = (uint8_t *)kmem_zalloc(size, KM_SLEEP))) { 7000*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7001*fcf3ce44SJohn Forte "%s: Unable to allocate buffer. size=%d", 7002*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), size); 7003*fcf3ce44SJohn Forte 7004*fcf3ce44SJohn Forte rval = DFC_SYSRES_ERROR; 7005*fcf3ce44SJohn Forte goto done; 7006*fcf3ce44SJohn Forte } 7007*fcf3ce44SJohn Forte memptr = (uint8_t *)((SLIM2 *)hba->slim2.virt)->mbx.us.s2.port; 7008*fcf3ce44SJohn Forte emlxs_pcimem_bcopy((uint32_t *)memptr, 7009*fcf3ce44SJohn Forte (uint32_t *)buffer, size); 7010*fcf3ce44SJohn Forte 7011*fcf3ce44SJohn Forte break; 7012*fcf3ce44SJohn Forte 7013*fcf3ce44SJohn Forte case 6: /* Command/Response Ring */ 7014*fcf3ce44SJohn Forte 7015*fcf3ce44SJohn Forte if (size < SLI_IOCB_MAX_SIZE) { 7016*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7017*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 7018*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), size); 7019*fcf3ce44SJohn Forte 7020*fcf3ce44SJohn Forte rval = DFC_ARG_TOOSMALL; 7021*fcf3ce44SJohn Forte goto done; 7022*fcf3ce44SJohn Forte } 7023*fcf3ce44SJohn Forte size = SLI_IOCB_MAX_SIZE; 7024*fcf3ce44SJohn Forte 7025*fcf3ce44SJohn Forte if (size_only) { 7026*fcf3ce44SJohn Forte break; 7027*fcf3ce44SJohn Forte } 7028*fcf3ce44SJohn Forte if (!(buffer = (uint8_t *)kmem_zalloc(size, KM_SLEEP))) { 7029*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7030*fcf3ce44SJohn Forte "%s: Unable to allocate buffer. size=%d", 7031*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), size); 7032*fcf3ce44SJohn Forte 7033*fcf3ce44SJohn Forte rval = DFC_SYSRES_ERROR; 7034*fcf3ce44SJohn Forte goto done; 7035*fcf3ce44SJohn Forte } 7036*fcf3ce44SJohn Forte memptr = (uint8_t *)((SLIM2 *)hba->slim2.virt)->IOCBs; 7037*fcf3ce44SJohn Forte emlxs_pcimem_bcopy((uint32_t *)memptr, 7038*fcf3ce44SJohn Forte (uint32_t *)buffer, size); 7039*fcf3ce44SJohn Forte 7040*fcf3ce44SJohn Forte break; 7041*fcf3ce44SJohn Forte 7042*fcf3ce44SJohn Forte case 7: /* All driver specific structures */ 7043*fcf3ce44SJohn Forte 7044*fcf3ce44SJohn Forte if (size < sizeof (emlxs_hba_t)) { 7045*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7046*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 7047*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), size); 7048*fcf3ce44SJohn Forte 7049*fcf3ce44SJohn Forte rval = DFC_ARG_TOOSMALL; 7050*fcf3ce44SJohn Forte goto done; 7051*fcf3ce44SJohn Forte } 7052*fcf3ce44SJohn Forte size = sizeof (emlxs_hba_t); 7053*fcf3ce44SJohn Forte 7054*fcf3ce44SJohn Forte if (size_only) { 7055*fcf3ce44SJohn Forte break; 7056*fcf3ce44SJohn Forte } 7057*fcf3ce44SJohn Forte if (!(buffer = (uint8_t *)kmem_zalloc(size, KM_SLEEP))) { 7058*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7059*fcf3ce44SJohn Forte "%s: Unable to allocate buffer. size=%d", 7060*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), size); 7061*fcf3ce44SJohn Forte 7062*fcf3ce44SJohn Forte rval = DFC_SYSRES_ERROR; 7063*fcf3ce44SJohn Forte goto done; 7064*fcf3ce44SJohn Forte } 7065*fcf3ce44SJohn Forte memptr = (uint8_t *)hba; 7066*fcf3ce44SJohn Forte bcopy((void *)memptr, (void *)buffer, size); 7067*fcf3ce44SJohn Forte 7068*fcf3ce44SJohn Forte break; 7069*fcf3ce44SJohn Forte 7070*fcf3ce44SJohn Forte default: 7071*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7072*fcf3ce44SJohn Forte "%s: Invalid id. id=%d", 7073*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->data1); 7074*fcf3ce44SJohn Forte 7075*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 7076*fcf3ce44SJohn Forte } 7077*fcf3ce44SJohn Forte 7078*fcf3ce44SJohn Forte if (rval == 0) { 7079*fcf3ce44SJohn Forte if (buffer) { 7080*fcf3ce44SJohn Forte if (ddi_copyout((void *)buffer, (void *)dfc->buf1, 7081*fcf3ce44SJohn Forte size, mode) != 0) { 7082*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7083*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 7084*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7085*fcf3ce44SJohn Forte 7086*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 7087*fcf3ce44SJohn Forte goto done; 7088*fcf3ce44SJohn Forte } 7089*fcf3ce44SJohn Forte } 7090*fcf3ce44SJohn Forte if (ddi_copyout((void *)&size, (void *)dfc->buf2, 7091*fcf3ce44SJohn Forte sizeof (uint32_t), mode) != 0) { 7092*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7093*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 7094*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7095*fcf3ce44SJohn Forte 7096*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 7097*fcf3ce44SJohn Forte goto done; 7098*fcf3ce44SJohn Forte } 7099*fcf3ce44SJohn Forte } 7100*fcf3ce44SJohn Forte done: 7101*fcf3ce44SJohn Forte 7102*fcf3ce44SJohn Forte if (buffer) { 7103*fcf3ce44SJohn Forte kmem_free(buffer, size); 7104*fcf3ce44SJohn Forte } 7105*fcf3ce44SJohn Forte return (rval); 7106*fcf3ce44SJohn Forte 7107*fcf3ce44SJohn Forte } /* emlxs_dfc_get_dump_region() */ 7108*fcf3ce44SJohn Forte 7109*fcf3ce44SJohn Forte 7110*fcf3ce44SJohn Forte 7111*fcf3ce44SJohn Forte /*ARGSUSED*/ 7112*fcf3ce44SJohn Forte static int32_t 7113*fcf3ce44SJohn Forte emlxs_dfc_loopback_mode(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 7114*fcf3ce44SJohn Forte { 7115*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 7116*fcf3ce44SJohn Forte MAILBOXQ *mbq = NULL; 7117*fcf3ce44SJohn Forte MAILBOX *mb = NULL; 7118*fcf3ce44SJohn Forte uint32_t rval = DFC_SUCCESS; 7119*fcf3ce44SJohn Forte uint32_t i; 7120*fcf3ce44SJohn Forte uint32_t timeout; 7121*fcf3ce44SJohn Forte uint32_t topology; 7122*fcf3ce44SJohn Forte uint32_t new_mode; 7123*fcf3ce44SJohn Forte NODELIST *ndlp; 7124*fcf3ce44SJohn Forte 7125*fcf3ce44SJohn Forte /* Reinitialize the link */ 7126*fcf3ce44SJohn Forte switch (dfc->flag) { 7127*fcf3ce44SJohn Forte case 0: /* Disable */ 7128*fcf3ce44SJohn Forte 7129*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_debug_msg, 7130*fcf3ce44SJohn Forte "%s: Disabling Loopback.", 7131*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7132*fcf3ce44SJohn Forte 7133*fcf3ce44SJohn Forte if (!(hba->flag & FC_LOOPBACK_MODE)) { 7134*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_debug_msg, 7135*fcf3ce44SJohn Forte "%s: Loopback already disabled.", 7136*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7137*fcf3ce44SJohn Forte 7138*fcf3ce44SJohn Forte return (0); 7139*fcf3ce44SJohn Forte } 7140*fcf3ce44SJohn Forte (void) emlxs_reset(port, FC_FCA_LINK_RESET); 7141*fcf3ce44SJohn Forte 7142*fcf3ce44SJohn Forte return (0); 7143*fcf3ce44SJohn Forte 7144*fcf3ce44SJohn Forte case 1: /* Internal loopback */ 7145*fcf3ce44SJohn Forte new_mode = FC_ILB_MODE; 7146*fcf3ce44SJohn Forte topology = FLAGS_LOCAL_LB; 7147*fcf3ce44SJohn Forte 7148*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_debug_msg, 7149*fcf3ce44SJohn Forte "%s: Enabling ILB.", 7150*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7151*fcf3ce44SJohn Forte 7152*fcf3ce44SJohn Forte /* Check if mode already set */ 7153*fcf3ce44SJohn Forte if ((hba->flag & FC_ILB_MODE)) { 7154*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_debug_msg, 7155*fcf3ce44SJohn Forte "%s: ILB mode already enabled.", 7156*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7157*fcf3ce44SJohn Forte 7158*fcf3ce44SJohn Forte return (0); 7159*fcf3ce44SJohn Forte } 7160*fcf3ce44SJohn Forte break; 7161*fcf3ce44SJohn Forte 7162*fcf3ce44SJohn Forte case 2: /* External loopback */ 7163*fcf3ce44SJohn Forte new_mode = FC_ELB_MODE; 7164*fcf3ce44SJohn Forte topology = FLAGS_TOPOLOGY_MODE_LOOP; 7165*fcf3ce44SJohn Forte 7166*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_debug_msg, 7167*fcf3ce44SJohn Forte "%s: Enabling ELB.", 7168*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7169*fcf3ce44SJohn Forte 7170*fcf3ce44SJohn Forte /* Check if mode already set */ 7171*fcf3ce44SJohn Forte if ((hba->flag & FC_ELB_MODE)) { 7172*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_debug_msg, 7173*fcf3ce44SJohn Forte "%s: ELB mode already enabled.", 7174*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7175*fcf3ce44SJohn Forte 7176*fcf3ce44SJohn Forte return (0); 7177*fcf3ce44SJohn Forte } 7178*fcf3ce44SJohn Forte break; 7179*fcf3ce44SJohn Forte 7180*fcf3ce44SJohn Forte default: 7181*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7182*fcf3ce44SJohn Forte "%s: Invalid loopback mode. (mode=%x)", 7183*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->flag); 7184*fcf3ce44SJohn Forte 7185*fcf3ce44SJohn Forte return (DFC_ARG_INVALID); 7186*fcf3ce44SJohn Forte } 7187*fcf3ce44SJohn Forte 7188*fcf3ce44SJohn Forte /* Make sure adapter is online */ 7189*fcf3ce44SJohn Forte if (emlxs_online(hba)) { 7190*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7191*fcf3ce44SJohn Forte "%s: Unable to bring adapter online.", 7192*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7193*fcf3ce44SJohn Forte 7194*fcf3ce44SJohn Forte return (DFC_OFFLINE_ERROR); 7195*fcf3ce44SJohn Forte } 7196*fcf3ce44SJohn Forte if ((mbq = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_SLEEP)) == 0) { 7197*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7198*fcf3ce44SJohn Forte "%s: Unable to allocate mailbox buffer.", 7199*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7200*fcf3ce44SJohn Forte 7201*fcf3ce44SJohn Forte return (DFC_SYSRES_ERROR); 7202*fcf3ce44SJohn Forte } 7203*fcf3ce44SJohn Forte mb = (MAILBOX *)mbq; 7204*fcf3ce44SJohn Forte 7205*fcf3ce44SJohn Forte /* Take the link down */ 7206*fcf3ce44SJohn Forte emlxs_mb_down_link(hba, mb); 7207*fcf3ce44SJohn Forte 7208*fcf3ce44SJohn Forte rval = emlxs_mb_issue_cmd(hba, mb, MBX_WAIT, 0); 7209*fcf3ce44SJohn Forte 7210*fcf3ce44SJohn Forte if (rval == MBX_TIMEOUT) { 7211*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7212*fcf3ce44SJohn Forte "%s: Mailbox timed out. cmd=%x", 7213*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 7214*fcf3ce44SJohn Forte 7215*fcf3ce44SJohn Forte rval = DFC_TIMEOUT; 7216*fcf3ce44SJohn Forte goto done; 7217*fcf3ce44SJohn Forte } 7218*fcf3ce44SJohn Forte if (rval) { 7219*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7220*fcf3ce44SJohn Forte "%s: %s failed. status=%x", 7221*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 7222*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), rval); 7223*fcf3ce44SJohn Forte 7224*fcf3ce44SJohn Forte rval = DFC_IO_ERROR; 7225*fcf3ce44SJohn Forte goto done; 7226*fcf3ce44SJohn Forte } 7227*fcf3ce44SJohn Forte /* Reinitialize the link */ 7228*fcf3ce44SJohn Forte emlxs_mb_init_link(hba, mb, topology, 0); 7229*fcf3ce44SJohn Forte 7230*fcf3ce44SJohn Forte /* Set the loopback mode and timer */ 7231*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 7232*fcf3ce44SJohn Forte hba->flag |= new_mode; 7233*fcf3ce44SJohn Forte hba->loopback_tics = hba->timer_tics + emlxs_loopback_tmo; 7234*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 7235*fcf3ce44SJohn Forte 7236*fcf3ce44SJohn Forte rval = emlxs_mb_issue_cmd(hba, mb, MBX_WAIT, 0); 7237*fcf3ce44SJohn Forte 7238*fcf3ce44SJohn Forte if (rval == MBX_TIMEOUT) { 7239*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7240*fcf3ce44SJohn Forte "%s: Mailbox timed out. cmd=%x", 7241*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), mb->mbxCommand); 7242*fcf3ce44SJohn Forte 7243*fcf3ce44SJohn Forte rval = DFC_TIMEOUT; 7244*fcf3ce44SJohn Forte goto done; 7245*fcf3ce44SJohn Forte } 7246*fcf3ce44SJohn Forte if (rval) { 7247*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7248*fcf3ce44SJohn Forte "%s: %s failed. status=%x", 7249*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 7250*fcf3ce44SJohn Forte emlxs_mb_cmd_xlate(mb->mbxCommand), rval); 7251*fcf3ce44SJohn Forte 7252*fcf3ce44SJohn Forte rval = DFC_IO_ERROR; 7253*fcf3ce44SJohn Forte goto done; 7254*fcf3ce44SJohn Forte } 7255*fcf3ce44SJohn Forte /* Wait for adapter to come online */ 7256*fcf3ce44SJohn Forte timeout = dfc->data1; 7257*fcf3ce44SJohn Forte if (!timeout) { 7258*fcf3ce44SJohn Forte timeout = 60; 7259*fcf3ce44SJohn Forte } 7260*fcf3ce44SJohn Forte i = 0; 7261*fcf3ce44SJohn Forte while ((hba->state < FC_LINK_UP) && (hba->state != FC_ERROR)) { 7262*fcf3ce44SJohn Forte delay(drv_usectohz(500000)); 7263*fcf3ce44SJohn Forte i++; 7264*fcf3ce44SJohn Forte 7265*fcf3ce44SJohn Forte if (i == timeout) { 7266*fcf3ce44SJohn Forte rval = DFC_TIMEOUT; 7267*fcf3ce44SJohn Forte 7268*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7269*fcf3ce44SJohn Forte "%s: Linkup timeout.", 7270*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7271*fcf3ce44SJohn Forte 7272*fcf3ce44SJohn Forte goto done; 7273*fcf3ce44SJohn Forte } 7274*fcf3ce44SJohn Forte } 7275*fcf3ce44SJohn Forte 7276*fcf3ce44SJohn Forte 7277*fcf3ce44SJohn Forte /* Create host node */ 7278*fcf3ce44SJohn Forte if (emlxs_mb_reg_did(port, port->did, (SERV_PARM *)&hba->sparam, 7279*fcf3ce44SJohn Forte NULL, NULL, NULL)) { 7280*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7281*fcf3ce44SJohn Forte "%s: Unable to register host node.", 7282*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7283*fcf3ce44SJohn Forte 7284*fcf3ce44SJohn Forte rval = DFC_DRV_ERROR; 7285*fcf3ce44SJohn Forte goto done; 7286*fcf3ce44SJohn Forte } 7287*fcf3ce44SJohn Forte i = 0; 7288*fcf3ce44SJohn Forte do { 7289*fcf3ce44SJohn Forte if (i++ > 300) { 7290*fcf3ce44SJohn Forte break; 7291*fcf3ce44SJohn Forte } 7292*fcf3ce44SJohn Forte delay(drv_usectohz(100000)); 7293*fcf3ce44SJohn Forte 7294*fcf3ce44SJohn Forte } while (!(ndlp = emlxs_node_find_did(port, port->did))); 7295*fcf3ce44SJohn Forte 7296*fcf3ce44SJohn Forte if (!ndlp) { 7297*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7298*fcf3ce44SJohn Forte "%s: Unable to create host node.", 7299*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7300*fcf3ce44SJohn Forte 7301*fcf3ce44SJohn Forte rval = DFC_DRV_ERROR; 7302*fcf3ce44SJohn Forte goto done; 7303*fcf3ce44SJohn Forte } 7304*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_debug_msg, 7305*fcf3ce44SJohn Forte "%s: Node created. node=%p", 7306*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), ndlp); 7307*fcf3ce44SJohn Forte 7308*fcf3ce44SJohn Forte 7309*fcf3ce44SJohn Forte /* Create host XRI */ 7310*fcf3ce44SJohn Forte (void) emlxs_create_xri(port, &hba->ring[FC_CT_RING], ndlp); 7311*fcf3ce44SJohn Forte 7312*fcf3ce44SJohn Forte i = 0; 7313*fcf3ce44SJohn Forte do { 7314*fcf3ce44SJohn Forte if (i++ > 300) { 7315*fcf3ce44SJohn Forte break; 7316*fcf3ce44SJohn Forte } 7317*fcf3ce44SJohn Forte delay(drv_usectohz(100000)); 7318*fcf3ce44SJohn Forte 7319*fcf3ce44SJohn Forte } while (!ndlp->nlp_Xri); 7320*fcf3ce44SJohn Forte 7321*fcf3ce44SJohn Forte if (!ndlp->nlp_Xri) { 7322*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7323*fcf3ce44SJohn Forte "%s: Unable to create XRI.", 7324*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7325*fcf3ce44SJohn Forte 7326*fcf3ce44SJohn Forte rval = DFC_DRV_ERROR; 7327*fcf3ce44SJohn Forte goto done; 7328*fcf3ce44SJohn Forte } 7329*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_debug_msg, 7330*fcf3ce44SJohn Forte "%s: XRI created. xri=%x", 7331*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), ndlp->nlp_Xri); 7332*fcf3ce44SJohn Forte 7333*fcf3ce44SJohn Forte 7334*fcf3ce44SJohn Forte done: 7335*fcf3ce44SJohn Forte 7336*fcf3ce44SJohn Forte /* Free allocated mbox memory */ 7337*fcf3ce44SJohn Forte if (mbq) { 7338*fcf3ce44SJohn Forte kmem_free(mbq, sizeof (MAILBOXQ)); 7339*fcf3ce44SJohn Forte } 7340*fcf3ce44SJohn Forte if (rval) { 7341*fcf3ce44SJohn Forte /* Reset the adapter */ 7342*fcf3ce44SJohn Forte (void) emlxs_reset(port, FC_FCA_RESET); 7343*fcf3ce44SJohn Forte } 7344*fcf3ce44SJohn Forte return (rval); 7345*fcf3ce44SJohn Forte 7346*fcf3ce44SJohn Forte } /* emlxs_dfc_loopback_mode() */ 7347*fcf3ce44SJohn Forte 7348*fcf3ce44SJohn Forte 7349*fcf3ce44SJohn Forte static int32_t 7350*fcf3ce44SJohn Forte emlxs_dfc_loopback_test(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 7351*fcf3ce44SJohn Forte { 7352*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 7353*fcf3ce44SJohn Forte uint32_t rval = 0; 7354*fcf3ce44SJohn Forte /* uint32_t i; */ 7355*fcf3ce44SJohn Forte NODELIST *ndlp; 7356*fcf3ce44SJohn Forte clock_t timeout; 7357*fcf3ce44SJohn Forte /* uint32_t tics_timeout; */ 7358*fcf3ce44SJohn Forte fc_packet_t *pkt = NULL; 7359*fcf3ce44SJohn Forte SLI_CT_REQUEST *CtCmd; 7360*fcf3ce44SJohn Forte uint16_t CtRsp; 7361*fcf3ce44SJohn Forte 7362*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 7363*fcf3ce44SJohn Forte if (!(hba->flag & FC_LOOPBACK_MODE)) { 7364*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 7365*fcf3ce44SJohn Forte 7366*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7367*fcf3ce44SJohn Forte "%s: Adapter not in loopback mode.", 7368*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7369*fcf3ce44SJohn Forte 7370*fcf3ce44SJohn Forte rval = DFC_DRV_ERROR; 7371*fcf3ce44SJohn Forte goto done; 7372*fcf3ce44SJohn Forte } 7373*fcf3ce44SJohn Forte hba->loopback_tics = hba->timer_tics + emlxs_loopback_tmo; 7374*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 7375*fcf3ce44SJohn Forte 7376*fcf3ce44SJohn Forte if (!(hba->flag & FC_ONLINE_MODE)) { 7377*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7378*fcf3ce44SJohn Forte "%s: Adapter offline.", 7379*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7380*fcf3ce44SJohn Forte 7381*fcf3ce44SJohn Forte rval = DFC_OFFLINE_ERROR; 7382*fcf3ce44SJohn Forte goto done; 7383*fcf3ce44SJohn Forte } 7384*fcf3ce44SJohn Forte if (hba->state < FC_LINK_UP) { 7385*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7386*fcf3ce44SJohn Forte "%s: Link not up.", 7387*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7388*fcf3ce44SJohn Forte 7389*fcf3ce44SJohn Forte rval = DFC_OFFLINE_ERROR; 7390*fcf3ce44SJohn Forte goto done; 7391*fcf3ce44SJohn Forte } 7392*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 7393*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7394*fcf3ce44SJohn Forte "%s: NULL buffer1 found.", 7395*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7396*fcf3ce44SJohn Forte 7397*fcf3ce44SJohn Forte rval = DFC_ARG_NULL; 7398*fcf3ce44SJohn Forte goto done; 7399*fcf3ce44SJohn Forte } 7400*fcf3ce44SJohn Forte if (!dfc->buf2 || !dfc->buf2_size) { 7401*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7402*fcf3ce44SJohn Forte "%s: NULL buffer2 found.", 7403*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7404*fcf3ce44SJohn Forte 7405*fcf3ce44SJohn Forte rval = DFC_ARG_NULL; 7406*fcf3ce44SJohn Forte goto done; 7407*fcf3ce44SJohn Forte } 7408*fcf3ce44SJohn Forte if (dfc->buf1_size > MAX_CT_PAYLOAD) { 7409*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7410*fcf3ce44SJohn Forte "%s: Buffer1 too large. (size=%d)", 7411*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 7412*fcf3ce44SJohn Forte 7413*fcf3ce44SJohn Forte rval = DFC_ARG_TOOBIG; 7414*fcf3ce44SJohn Forte goto done; 7415*fcf3ce44SJohn Forte } 7416*fcf3ce44SJohn Forte /* Check if we have a node for ourselves */ 7417*fcf3ce44SJohn Forte ndlp = emlxs_node_find_did(port, port->did); 7418*fcf3ce44SJohn Forte 7419*fcf3ce44SJohn Forte if (!ndlp) { 7420*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7421*fcf3ce44SJohn Forte "%s: Host node not found.", 7422*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7423*fcf3ce44SJohn Forte 7424*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 7425*fcf3ce44SJohn Forte goto done; 7426*fcf3ce44SJohn Forte } 7427*fcf3ce44SJohn Forte if (!ndlp->nlp_Xri) { 7428*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7429*fcf3ce44SJohn Forte "%s: Host XRI not found.", 7430*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7431*fcf3ce44SJohn Forte 7432*fcf3ce44SJohn Forte rval = DFC_DRV_ERROR; 7433*fcf3ce44SJohn Forte goto done; 7434*fcf3ce44SJohn Forte } 7435*fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, dfc->buf1_size + 16, 7436*fcf3ce44SJohn Forte dfc->buf2_size + 16, 0, KM_SLEEP))) { 7437*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7438*fcf3ce44SJohn Forte "%s: Unable to allocate pkt.", 7439*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7440*fcf3ce44SJohn Forte 7441*fcf3ce44SJohn Forte rval = DFC_SYSRES_ERROR; 7442*fcf3ce44SJohn Forte goto done; 7443*fcf3ce44SJohn Forte } 7444*fcf3ce44SJohn Forte CtCmd = (SLI_CT_REQUEST *)pkt->pkt_cmd; 7445*fcf3ce44SJohn Forte CtRsp = SLI_CT_LOOPBACK; 7446*fcf3ce44SJohn Forte CtCmd->CommandResponse.bits.CmdRsp = SWAP_DATA16(CtRsp); 7447*fcf3ce44SJohn Forte 7448*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf1, (void *)&CtCmd->un.data, 7449*fcf3ce44SJohn Forte dfc->buf1_size, mode) != 0) { 7450*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7451*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 7452*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7453*fcf3ce44SJohn Forte 7454*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 7455*fcf3ce44SJohn Forte goto done; 7456*fcf3ce44SJohn Forte } 7457*fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND; 7458*fcf3ce44SJohn Forte pkt->pkt_timeout = 2 * hba->fc_ratov; 7459*fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_NO_INTR; 7460*fcf3ce44SJohn Forte pkt->pkt_comp = NULL; 7461*fcf3ce44SJohn Forte 7462*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = port->did; 7463*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = FC_SOL_CTL; 7464*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.s_id = port->did; 7465*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_CT_TYPE; 7466*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = 0; 7467*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 7468*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 7469*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 7470*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xffff; 7471*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = ndlp->nlp_Xri; 7472*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 7473*fcf3ce44SJohn Forte 7474*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PKT_LOCK); 7475*fcf3ce44SJohn Forte timeout = emlxs_timeout(hba, (pkt->pkt_timeout + 15)); 7476*fcf3ce44SJohn Forte 7477*fcf3ce44SJohn Forte if (hba->loopback_pkt) { 7478*fcf3ce44SJohn Forte rval = 0; 7479*fcf3ce44SJohn Forte while ((rval != -1) && hba->loopback_pkt) { 7480*fcf3ce44SJohn Forte rval = cv_timedwait(&EMLXS_PKT_CV, &EMLXS_PKT_LOCK, 7481*fcf3ce44SJohn Forte timeout); 7482*fcf3ce44SJohn Forte } 7483*fcf3ce44SJohn Forte 7484*fcf3ce44SJohn Forte if (rval == -1) { 7485*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PKT_LOCK); 7486*fcf3ce44SJohn Forte 7487*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7488*fcf3ce44SJohn Forte "Loopback busy timeout."); 7489*fcf3ce44SJohn Forte rval = DFC_TIMEOUT; 7490*fcf3ce44SJohn Forte goto done; 7491*fcf3ce44SJohn Forte } 7492*fcf3ce44SJohn Forte } 7493*fcf3ce44SJohn Forte hba->loopback_pkt = (void *)pkt; 7494*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PKT_LOCK); 7495*fcf3ce44SJohn Forte 7496*fcf3ce44SJohn Forte /* Send polled command */ 7497*fcf3ce44SJohn Forte if ((rval = emlxs_pkt_send(pkt, 1)) != FC_SUCCESS) { 7498*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7499*fcf3ce44SJohn Forte "Pkt Transport error. ret=%x state=%x", 7500*fcf3ce44SJohn Forte rval, pkt->pkt_state); 7501*fcf3ce44SJohn Forte 7502*fcf3ce44SJohn Forte rval = DFC_IO_ERROR; 7503*fcf3ce44SJohn Forte goto done; 7504*fcf3ce44SJohn Forte } 7505*fcf3ce44SJohn Forte if (pkt->pkt_state != FC_PKT_SUCCESS) { 7506*fcf3ce44SJohn Forte if (pkt->pkt_state == FC_PKT_TIMEOUT) { 7507*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7508*fcf3ce44SJohn Forte "Pkt Transport error. Pkt Timeout."); 7509*fcf3ce44SJohn Forte rval = DFC_TIMEOUT; 7510*fcf3ce44SJohn Forte } else { 7511*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7512*fcf3ce44SJohn Forte "Pkt Transport error. state=%x", 7513*fcf3ce44SJohn Forte pkt->pkt_state); 7514*fcf3ce44SJohn Forte rval = DFC_IO_ERROR; 7515*fcf3ce44SJohn Forte } 7516*fcf3ce44SJohn Forte goto done; 7517*fcf3ce44SJohn Forte } 7518*fcf3ce44SJohn Forte /* Wait for sequence completion */ 7519*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PKT_LOCK); 7520*fcf3ce44SJohn Forte rval = 0; 7521*fcf3ce44SJohn Forte while ((rval != -1) && !(pkt->pkt_tran_flags & FC_TRAN_COMPLETED)) { 7522*fcf3ce44SJohn Forte rval = cv_timedwait(&EMLXS_PKT_CV, &EMLXS_PKT_LOCK, timeout); 7523*fcf3ce44SJohn Forte } 7524*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PKT_LOCK); 7525*fcf3ce44SJohn Forte 7526*fcf3ce44SJohn Forte if (rval == -1) { 7527*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7528*fcf3ce44SJohn Forte "Loopback sequence timeout."); 7529*fcf3ce44SJohn Forte 7530*fcf3ce44SJohn Forte rval = DFC_TIMEOUT; 7531*fcf3ce44SJohn Forte goto done; 7532*fcf3ce44SJohn Forte } 7533*fcf3ce44SJohn Forte CtCmd = (SLI_CT_REQUEST *)pkt->pkt_resp; 7534*fcf3ce44SJohn Forte 7535*fcf3ce44SJohn Forte if (ddi_copyout((void *)&CtCmd->un.data, (void *)dfc->buf2, 7536*fcf3ce44SJohn Forte dfc->buf2_size, mode) != 0) { 7537*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7538*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 7539*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7540*fcf3ce44SJohn Forte 7541*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 7542*fcf3ce44SJohn Forte goto done; 7543*fcf3ce44SJohn Forte } 7544*fcf3ce44SJohn Forte rval = 0; 7545*fcf3ce44SJohn Forte 7546*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_debug_msg, 7547*fcf3ce44SJohn Forte "%s: Test completed.", 7548*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7549*fcf3ce44SJohn Forte 7550*fcf3ce44SJohn Forte done: 7551*fcf3ce44SJohn Forte 7552*fcf3ce44SJohn Forte if (rval) { 7553*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PKT_LOCK); 7554*fcf3ce44SJohn Forte if (pkt && (hba->loopback_pkt == pkt)) { 7555*fcf3ce44SJohn Forte hba->loopback_pkt = NULL; 7556*fcf3ce44SJohn Forte } 7557*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PKT_LOCK); 7558*fcf3ce44SJohn Forte 7559*fcf3ce44SJohn Forte /* Reset the adapter */ 7560*fcf3ce44SJohn Forte (void) emlxs_reset(port, FC_FCA_LINK_RESET); 7561*fcf3ce44SJohn Forte } 7562*fcf3ce44SJohn Forte if (pkt) { 7563*fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 7564*fcf3ce44SJohn Forte } 7565*fcf3ce44SJohn Forte return (rval); 7566*fcf3ce44SJohn Forte 7567*fcf3ce44SJohn Forte } /* emlxs_dfc_loopback_test() */ 7568*fcf3ce44SJohn Forte 7569*fcf3ce44SJohn Forte 7570*fcf3ce44SJohn Forte extern int32_t 7571*fcf3ce44SJohn Forte emlxs_dfc_handle_event(emlxs_hba_t *hba, RING *rp, IOCBQ * iocbq) 7572*fcf3ce44SJohn Forte { 7573*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 7574*fcf3ce44SJohn Forte IOCB *cmd; 7575*fcf3ce44SJohn Forte emlxs_buf_t *sbp; 7576*fcf3ce44SJohn Forte /* NODELIST *ndlp; */ 7577*fcf3ce44SJohn Forte 7578*fcf3ce44SJohn Forte cmd = &iocbq->iocb; 7579*fcf3ce44SJohn Forte 7580*fcf3ce44SJohn Forte HBASTATS.CtEvent++; 7581*fcf3ce44SJohn Forte 7582*fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)iocbq->sbp; 7583*fcf3ce44SJohn Forte 7584*fcf3ce44SJohn Forte if (!sbp) { 7585*fcf3ce44SJohn Forte HBASTATS.CtStray++; 7586*fcf3ce44SJohn Forte 7587*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7588*fcf3ce44SJohn Forte "Stray interrupt. cmd=0x%x iotag=0x%x" 7589*fcf3ce44SJohn Forte " status=0x%x perr=0x%x", 7590*fcf3ce44SJohn Forte (uint32_t)cmd->ulpCommand, 7591*fcf3ce44SJohn Forte (uint32_t)cmd->ulpIoTag, 7592*fcf3ce44SJohn Forte cmd->ulpStatus, cmd->un.ulpWord[4]); 7593*fcf3ce44SJohn Forte 7594*fcf3ce44SJohn Forte return (DFC_ARG_INVALID); 7595*fcf3ce44SJohn Forte } 7596*fcf3ce44SJohn Forte if (rp->ringno != FC_CT_RING) { 7597*fcf3ce44SJohn Forte HBASTATS.CtStray++; 7598*fcf3ce44SJohn Forte 7599*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7600*fcf3ce44SJohn Forte "CT Event: Invalid ring: ring=%d iocbq=%p", 7601*fcf3ce44SJohn Forte rp->ringno, iocbq); 7602*fcf3ce44SJohn Forte 7603*fcf3ce44SJohn Forte return (DFC_ARG_INVALID); 7604*fcf3ce44SJohn Forte } 7605*fcf3ce44SJohn Forte switch (cmd->ulpCommand) { 7606*fcf3ce44SJohn Forte case CMD_XMIT_SEQUENCE_CR: 7607*fcf3ce44SJohn Forte case CMD_XMIT_SEQUENCE64_CR: 7608*fcf3ce44SJohn Forte case CMD_XMIT_SEQUENCE_CX: 7609*fcf3ce44SJohn Forte case CMD_XMIT_SEQUENCE64_CX: 7610*fcf3ce44SJohn Forte 7611*fcf3ce44SJohn Forte HBASTATS.CtCmdCompleted++; 7612*fcf3ce44SJohn Forte 7613*fcf3ce44SJohn Forte if (cmd->ulpStatus == 0) { 7614*fcf3ce44SJohn Forte HBASTATS.CtCmdGood++; 7615*fcf3ce44SJohn Forte 7616*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 7617*fcf3ce44SJohn Forte "XMIT_SEQUENCE comp: status=0x%x", 7618*fcf3ce44SJohn Forte cmd->ulpStatus); 7619*fcf3ce44SJohn Forte } else { 7620*fcf3ce44SJohn Forte HBASTATS.CtCmdError++; 7621*fcf3ce44SJohn Forte 7622*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7623*fcf3ce44SJohn Forte "XMIT_SEQUENCE comp: status=0x%x [%08x,%08x]", 7624*fcf3ce44SJohn Forte cmd->ulpStatus, cmd->un.ulpWord[4], 7625*fcf3ce44SJohn Forte cmd->un.ulpWord[5]); 7626*fcf3ce44SJohn Forte } 7627*fcf3ce44SJohn Forte 7628*fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, cmd->ulpStatus, 7629*fcf3ce44SJohn Forte cmd->un.grsp.perr.statLocalError, 1); 7630*fcf3ce44SJohn Forte 7631*fcf3ce44SJohn Forte break; 7632*fcf3ce44SJohn Forte 7633*fcf3ce44SJohn Forte default: 7634*fcf3ce44SJohn Forte 7635*fcf3ce44SJohn Forte HBASTATS.CtStray++; 7636*fcf3ce44SJohn Forte 7637*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7638*fcf3ce44SJohn Forte "Invalid iocb: cmd=0x%x", 7639*fcf3ce44SJohn Forte cmd->ulpCommand); 7640*fcf3ce44SJohn Forte 7641*fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, cmd->ulpStatus, 7642*fcf3ce44SJohn Forte cmd->un.grsp.perr.statLocalError, 1); 7643*fcf3ce44SJohn Forte 7644*fcf3ce44SJohn Forte break; 7645*fcf3ce44SJohn Forte 7646*fcf3ce44SJohn Forte } /* switch(cmd->ulpCommand) */ 7647*fcf3ce44SJohn Forte 7648*fcf3ce44SJohn Forte return (0); 7649*fcf3ce44SJohn Forte 7650*fcf3ce44SJohn Forte } /* emlxs_dfc_handle_event() */ 7651*fcf3ce44SJohn Forte 7652*fcf3ce44SJohn Forte 7653*fcf3ce44SJohn Forte /*ARGSUSED*/ 7654*fcf3ce44SJohn Forte extern int 7655*fcf3ce44SJohn Forte emlxs_dfc_handle_unsol_req(emlxs_port_t *port, RING *rp, 7656*fcf3ce44SJohn Forte IOCBQ *iocbq, MATCHMAP *mp, uint32_t size) 7657*fcf3ce44SJohn Forte { 7658*fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 7659*fcf3ce44SJohn Forte IOCB *iocb; 7660*fcf3ce44SJohn Forte uint8_t *bp; 7661*fcf3ce44SJohn Forte /* dfc_t *dfc; */ 7662*fcf3ce44SJohn Forte fc_packet_t *pkt; 7663*fcf3ce44SJohn Forte 7664*fcf3ce44SJohn Forte iocb = &iocbq->iocb; 7665*fcf3ce44SJohn Forte bp = (uint8_t *)mp->virt; 7666*fcf3ce44SJohn Forte 7667*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 7668*fcf3ce44SJohn Forte "CT Receive: cmd=%x status=0x%x ", 7669*fcf3ce44SJohn Forte iocb->ulpCommand, iocb->ulpStatus); 7670*fcf3ce44SJohn Forte 7671*fcf3ce44SJohn Forte /* 7672*fcf3ce44SJohn Forte * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_debug_msg, "CT Receive: 7673*fcf3ce44SJohn Forte * payload=%p size=%d [%02x,%02x, %02x, %02x]", bp, size, bp[0], 7674*fcf3ce44SJohn Forte * bp[1], bp[2],bp[3]); 7675*fcf3ce44SJohn Forte */ 7676*fcf3ce44SJohn Forte 7677*fcf3ce44SJohn Forte /* Return payload */ 7678*fcf3ce44SJohn Forte mutex_enter(&EMLXS_PKT_LOCK); 7679*fcf3ce44SJohn Forte if (hba->loopback_pkt) { 7680*fcf3ce44SJohn Forte pkt = (fc_packet_t *)hba->loopback_pkt; 7681*fcf3ce44SJohn Forte hba->loopback_pkt = NULL; 7682*fcf3ce44SJohn Forte 7683*fcf3ce44SJohn Forte size = MIN(size, pkt->pkt_rsplen); 7684*fcf3ce44SJohn Forte bcopy(bp, pkt->pkt_resp, size); 7685*fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_COMPLETED; 7686*fcf3ce44SJohn Forte 7687*fcf3ce44SJohn Forte cv_broadcast(&EMLXS_PKT_CV); 7688*fcf3ce44SJohn Forte } 7689*fcf3ce44SJohn Forte mutex_exit(&EMLXS_PKT_LOCK); 7690*fcf3ce44SJohn Forte 7691*fcf3ce44SJohn Forte return (0); 7692*fcf3ce44SJohn Forte 7693*fcf3ce44SJohn Forte } /* emlxs_dfc_handle_unsol_req() */ 7694*fcf3ce44SJohn Forte 7695*fcf3ce44SJohn Forte 7696*fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 7697*fcf3ce44SJohn Forte 7698*fcf3ce44SJohn Forte static int32_t 7699*fcf3ce44SJohn Forte emlxs_dfc_init_auth(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 7700*fcf3ce44SJohn Forte { 7701*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 7702*fcf3ce44SJohn Forte uint8_t lwwpn[8]; 7703*fcf3ce44SJohn Forte uint8_t rwwpn[8]; 7704*fcf3ce44SJohn Forte int32_t rval = 0; 7705*fcf3ce44SJohn Forte 7706*fcf3ce44SJohn Forte /* 7707*fcf3ce44SJohn Forte * dfc.cmd = EMLXS_INIT_AUTH; dfc.buf1_size = 8; dfc.buf1 7708*fcf3ce44SJohn Forte * = lwwpn; dfc.buf2_size = 8; dfc.buf2 = rwwpn; 7709*fcf3ce44SJohn Forte */ 7710*fcf3ce44SJohn Forte 7711*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 7712*fcf3ce44SJohn Forte "%s requested.", 7713*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7714*fcf3ce44SJohn Forte 7715*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 7716*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7717*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 7718*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7719*fcf3ce44SJohn Forte 7720*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 7721*fcf3ce44SJohn Forte } 7722*fcf3ce44SJohn Forte if (dfc->buf1_size < 8) { 7723*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7724*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 7725*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 7726*fcf3ce44SJohn Forte 7727*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 7728*fcf3ce44SJohn Forte } 7729*fcf3ce44SJohn Forte if (!dfc->buf2 || !dfc->buf2_size) { 7730*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7731*fcf3ce44SJohn Forte "%s: Null buffer2 found.", 7732*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7733*fcf3ce44SJohn Forte 7734*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 7735*fcf3ce44SJohn Forte } 7736*fcf3ce44SJohn Forte if (dfc->buf2_size < 8) { 7737*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7738*fcf3ce44SJohn Forte "%s: Buffer2 too small. (size=%d)", 7739*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 7740*fcf3ce44SJohn Forte 7741*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 7742*fcf3ce44SJohn Forte } 7743*fcf3ce44SJohn Forte /* Read the lwwpn */ 7744*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf1, (void *)&lwwpn, 7745*fcf3ce44SJohn Forte 8, mode) != 0) { 7746*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7747*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 7748*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7749*fcf3ce44SJohn Forte 7750*fcf3ce44SJohn Forte return (DFC_COPYIN_ERROR); 7751*fcf3ce44SJohn Forte } 7752*fcf3ce44SJohn Forte /* Read the rwwpn */ 7753*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf2, (void *)&rwwpn, 7754*fcf3ce44SJohn Forte 8, mode) != 0) { 7755*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7756*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 7757*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7758*fcf3ce44SJohn Forte 7759*fcf3ce44SJohn Forte return (DFC_COPYIN_ERROR); 7760*fcf3ce44SJohn Forte } 7761*fcf3ce44SJohn Forte /* Initiate authentication here */ 7762*fcf3ce44SJohn Forte rval = emlxs_dhc_init_auth(hba, lwwpn, rwwpn); 7763*fcf3ce44SJohn Forte 7764*fcf3ce44SJohn Forte return (rval); 7765*fcf3ce44SJohn Forte 7766*fcf3ce44SJohn Forte } /* emlxs_dfc_init_auth() */ 7767*fcf3ce44SJohn Forte 7768*fcf3ce44SJohn Forte 7769*fcf3ce44SJohn Forte static int32_t 7770*fcf3ce44SJohn Forte emlxs_dfc_get_auth_cfg(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 7771*fcf3ce44SJohn Forte { 7772*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 7773*fcf3ce44SJohn Forte dfc_fcsp_config_t fcsp_config; 7774*fcf3ce44SJohn Forte uint32_t rval = DFC_SUCCESS; 7775*fcf3ce44SJohn Forte 7776*fcf3ce44SJohn Forte /* 7777*fcf3ce44SJohn Forte * dfc.cmd = EMLXS_GET_AUTH_CFG; dfc.buf1_size = 7778*fcf3ce44SJohn Forte * sizeof(dfc_fcsp_config_t); dfc.buf1 = config; 7779*fcf3ce44SJohn Forte */ 7780*fcf3ce44SJohn Forte 7781*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 7782*fcf3ce44SJohn Forte "%s requested.", 7783*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7784*fcf3ce44SJohn Forte 7785*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 7786*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7787*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 7788*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7789*fcf3ce44SJohn Forte 7790*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 7791*fcf3ce44SJohn Forte } 7792*fcf3ce44SJohn Forte if (dfc->buf1_size < sizeof (dfc_fcsp_config_t)) { 7793*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7794*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 7795*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 7796*fcf3ce44SJohn Forte 7797*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 7798*fcf3ce44SJohn Forte } 7799*fcf3ce44SJohn Forte /* Read the fcsp_config */ 7800*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf1, (void *)&fcsp_config, 7801*fcf3ce44SJohn Forte sizeof (dfc_fcsp_config_t), mode) != 0) { 7802*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7803*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 7804*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7805*fcf3ce44SJohn Forte 7806*fcf3ce44SJohn Forte return (DFC_COPYIN_ERROR); 7807*fcf3ce44SJohn Forte } 7808*fcf3ce44SJohn Forte if ((rval = emlxs_dhc_get_auth_cfg(hba, &fcsp_config)) != 0) { 7809*fcf3ce44SJohn Forte return (rval); 7810*fcf3ce44SJohn Forte } 7811*fcf3ce44SJohn Forte if (ddi_copyout((void *)&fcsp_config, (void *)dfc->buf1, 7812*fcf3ce44SJohn Forte sizeof (dfc_fcsp_config_t), mode) != 0) { 7813*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7814*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 7815*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7816*fcf3ce44SJohn Forte 7817*fcf3ce44SJohn Forte } 7818*fcf3ce44SJohn Forte return (0); 7819*fcf3ce44SJohn Forte 7820*fcf3ce44SJohn Forte } /* emlxs_dfc_get_auth_cfg() */ 7821*fcf3ce44SJohn Forte 7822*fcf3ce44SJohn Forte 7823*fcf3ce44SJohn Forte 7824*fcf3ce44SJohn Forte static int32_t 7825*fcf3ce44SJohn Forte emlxs_dfc_set_auth_cfg(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 7826*fcf3ce44SJohn Forte { 7827*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 7828*fcf3ce44SJohn Forte dfc_fcsp_config_t fcsp_config; 7829*fcf3ce44SJohn Forte dfc_password_t dfc_pwd; 7830*fcf3ce44SJohn Forte uint32_t rval = DFC_SUCCESS; 7831*fcf3ce44SJohn Forte 7832*fcf3ce44SJohn Forte 7833*fcf3ce44SJohn Forte /* 7834*fcf3ce44SJohn Forte * dfc.cmd = EMLXS_SET_AUTH_CFG; dfc.flag = 7835*fcf3ce44SJohn Forte * EMLXS_AUTH_CFG_ADD; dfc.buf1_size = sizeof(dfc_fcsp_config_t); 7836*fcf3ce44SJohn Forte * dfc.buf1 = config; dfc.buf2_size = sizeof(dfc_password_t); 7837*fcf3ce44SJohn Forte * dfc.buf2 = password; 7838*fcf3ce44SJohn Forte */ 7839*fcf3ce44SJohn Forte 7840*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 7841*fcf3ce44SJohn Forte "%s requested.", 7842*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7843*fcf3ce44SJohn Forte 7844*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 7845*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7846*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 7847*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7848*fcf3ce44SJohn Forte 7849*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 7850*fcf3ce44SJohn Forte } 7851*fcf3ce44SJohn Forte if (dfc->buf1_size < sizeof (dfc_fcsp_config_t)) { 7852*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7853*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 7854*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 7855*fcf3ce44SJohn Forte 7856*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 7857*fcf3ce44SJohn Forte } 7858*fcf3ce44SJohn Forte if (!dfc->buf2 || !dfc->buf2_size) { 7859*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7860*fcf3ce44SJohn Forte "%s: Null buffer2 found.", 7861*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7862*fcf3ce44SJohn Forte 7863*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 7864*fcf3ce44SJohn Forte } 7865*fcf3ce44SJohn Forte if (dfc->buf2_size < sizeof (dfc_password_t)) { 7866*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7867*fcf3ce44SJohn Forte "%s: Buffer2 too small. (size=%d)", 7868*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 7869*fcf3ce44SJohn Forte 7870*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 7871*fcf3ce44SJohn Forte } 7872*fcf3ce44SJohn Forte /* Read the fcsp_config */ 7873*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf1, (void *)&fcsp_config, 7874*fcf3ce44SJohn Forte sizeof (dfc_fcsp_config_t), mode) != 0) { 7875*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7876*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 7877*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7878*fcf3ce44SJohn Forte 7879*fcf3ce44SJohn Forte return (DFC_COPYIN_ERROR); 7880*fcf3ce44SJohn Forte } 7881*fcf3ce44SJohn Forte /* Read the password */ 7882*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf2, (void *)&dfc_pwd, 7883*fcf3ce44SJohn Forte sizeof (dfc_password_t), mode) != 0) { 7884*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7885*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 7886*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7887*fcf3ce44SJohn Forte 7888*fcf3ce44SJohn Forte return (DFC_COPYIN_ERROR); 7889*fcf3ce44SJohn Forte } 7890*fcf3ce44SJohn Forte switch (dfc->flag) { 7891*fcf3ce44SJohn Forte case EMLXS_AUTH_CFG_ADD: 7892*fcf3ce44SJohn Forte rval = emlxs_dhc_add_auth_cfg(hba, &fcsp_config, &dfc_pwd); 7893*fcf3ce44SJohn Forte break; 7894*fcf3ce44SJohn Forte 7895*fcf3ce44SJohn Forte case EMLXS_AUTH_CFG_DELETE: 7896*fcf3ce44SJohn Forte rval = emlxs_dhc_delete_auth_cfg(hba, &fcsp_config, &dfc_pwd); 7897*fcf3ce44SJohn Forte break; 7898*fcf3ce44SJohn Forte } 7899*fcf3ce44SJohn Forte 7900*fcf3ce44SJohn Forte if (rval) { 7901*fcf3ce44SJohn Forte return (rval); 7902*fcf3ce44SJohn Forte } 7903*fcf3ce44SJohn Forte if (ddi_copyout((void *)&fcsp_config, (void *)dfc->buf1, 7904*fcf3ce44SJohn Forte sizeof (dfc_fcsp_config_t), mode) != 0) { 7905*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7906*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 7907*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7908*fcf3ce44SJohn Forte 7909*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 7910*fcf3ce44SJohn Forte } 7911*fcf3ce44SJohn Forte return (0); 7912*fcf3ce44SJohn Forte 7913*fcf3ce44SJohn Forte } /* emlxs_dfc_set_auth_cfg() */ 7914*fcf3ce44SJohn Forte 7915*fcf3ce44SJohn Forte 7916*fcf3ce44SJohn Forte 7917*fcf3ce44SJohn Forte static int32_t 7918*fcf3ce44SJohn Forte emlxs_dfc_get_auth_pwd(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 7919*fcf3ce44SJohn Forte { 7920*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 7921*fcf3ce44SJohn Forte dfc_auth_password_t dfc_pwd; 7922*fcf3ce44SJohn Forte uint32_t rval = DFC_SUCCESS; 7923*fcf3ce44SJohn Forte 7924*fcf3ce44SJohn Forte 7925*fcf3ce44SJohn Forte /* 7926*fcf3ce44SJohn Forte * dfc.cmd = EMLXS_GET_AUTH_PASSWORD; dfc.buf1_size = 7927*fcf3ce44SJohn Forte * sizeof(dfc_auth_password_t); dfc.buf1 = auth_password; 7928*fcf3ce44SJohn Forte */ 7929*fcf3ce44SJohn Forte 7930*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 7931*fcf3ce44SJohn Forte "%s requested.", 7932*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7933*fcf3ce44SJohn Forte 7934*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 7935*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7936*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 7937*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7938*fcf3ce44SJohn Forte 7939*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 7940*fcf3ce44SJohn Forte } 7941*fcf3ce44SJohn Forte if (dfc->buf1_size < sizeof (dfc_auth_password_t)) { 7942*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7943*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 7944*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 7945*fcf3ce44SJohn Forte 7946*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 7947*fcf3ce44SJohn Forte } 7948*fcf3ce44SJohn Forte /* Read the auth password */ 7949*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf1, (void *)&dfc_pwd, 7950*fcf3ce44SJohn Forte sizeof (dfc_auth_password_t), mode) != 0) { 7951*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7952*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 7953*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7954*fcf3ce44SJohn Forte 7955*fcf3ce44SJohn Forte return (DFC_COPYIN_ERROR); 7956*fcf3ce44SJohn Forte } 7957*fcf3ce44SJohn Forte if ((rval = emlxs_dhc_get_auth_key(hba, &dfc_pwd)) != 0) { 7958*fcf3ce44SJohn Forte return (rval); 7959*fcf3ce44SJohn Forte } 7960*fcf3ce44SJohn Forte if (ddi_copyout((void *)&dfc_pwd, (void *)dfc->buf1, 7961*fcf3ce44SJohn Forte sizeof (dfc_auth_password_t), mode) != 0) { 7962*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7963*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 7964*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7965*fcf3ce44SJohn Forte 7966*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 7967*fcf3ce44SJohn Forte } 7968*fcf3ce44SJohn Forte return (0); 7969*fcf3ce44SJohn Forte 7970*fcf3ce44SJohn Forte } /* emlxs_dfc_get_auth_pwd() */ 7971*fcf3ce44SJohn Forte 7972*fcf3ce44SJohn Forte 7973*fcf3ce44SJohn Forte static int32_t 7974*fcf3ce44SJohn Forte emlxs_dfc_set_auth_pwd(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 7975*fcf3ce44SJohn Forte { 7976*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 7977*fcf3ce44SJohn Forte dfc_auth_password_t dfc_pwd; 7978*fcf3ce44SJohn Forte uint32_t rval = DFC_SUCCESS; 7979*fcf3ce44SJohn Forte 7980*fcf3ce44SJohn Forte /* 7981*fcf3ce44SJohn Forte * dfc.cmd = EMLXS_SET_AUTH_PASSWORD; dfc.buf1_size = 7982*fcf3ce44SJohn Forte * sizeof(dfc_auth_password_t); dfc.buf1 = auth_password; 7983*fcf3ce44SJohn Forte */ 7984*fcf3ce44SJohn Forte 7985*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 7986*fcf3ce44SJohn Forte "%s requested.", 7987*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7988*fcf3ce44SJohn Forte 7989*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 7990*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7991*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 7992*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 7993*fcf3ce44SJohn Forte 7994*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 7995*fcf3ce44SJohn Forte } 7996*fcf3ce44SJohn Forte if (dfc->buf1_size < sizeof (dfc_auth_password_t)) { 7997*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 7998*fcf3ce44SJohn Forte "%s: Buffer1 too small. (size=%d)", 7999*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 8000*fcf3ce44SJohn Forte 8001*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 8002*fcf3ce44SJohn Forte } 8003*fcf3ce44SJohn Forte /* Read the auth password */ 8004*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf1, (void *)&dfc_pwd, 8005*fcf3ce44SJohn Forte sizeof (dfc_auth_password_t), mode) != 0) { 8006*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8007*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 8008*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8009*fcf3ce44SJohn Forte 8010*fcf3ce44SJohn Forte return (DFC_COPYIN_ERROR); 8011*fcf3ce44SJohn Forte } 8012*fcf3ce44SJohn Forte if ((rval = emlxs_dhc_set_auth_key(hba, &dfc_pwd))) { 8013*fcf3ce44SJohn Forte return (rval); 8014*fcf3ce44SJohn Forte } 8015*fcf3ce44SJohn Forte if (ddi_copyout((void *)&dfc_pwd, (void *)dfc->buf1, 8016*fcf3ce44SJohn Forte sizeof (dfc_auth_password_t), mode) != 0) { 8017*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8018*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 8019*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8020*fcf3ce44SJohn Forte 8021*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 8022*fcf3ce44SJohn Forte } 8023*fcf3ce44SJohn Forte return (0); 8024*fcf3ce44SJohn Forte 8025*fcf3ce44SJohn Forte } /* emlxs_dfc_set_auth_pwd() */ 8026*fcf3ce44SJohn Forte 8027*fcf3ce44SJohn Forte 8028*fcf3ce44SJohn Forte static int32_t 8029*fcf3ce44SJohn Forte emlxs_dfc_get_auth_status(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 8030*fcf3ce44SJohn Forte { 8031*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 8032*fcf3ce44SJohn Forte dfc_auth_status_t fcsp_status; 8033*fcf3ce44SJohn Forte uint32_t rval = DFC_SUCCESS; 8034*fcf3ce44SJohn Forte 8035*fcf3ce44SJohn Forte /* 8036*fcf3ce44SJohn Forte * dfc.cmd = EMLXS_GET_AUTH_STATUS; dfc.buf1_size = 8037*fcf3ce44SJohn Forte * sizeof(dfc_auth_status_t); dfc.buf1 = status; 8038*fcf3ce44SJohn Forte */ 8039*fcf3ce44SJohn Forte 8040*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 8041*fcf3ce44SJohn Forte "%s requested.", 8042*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8043*fcf3ce44SJohn Forte 8044*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 8045*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8046*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 8047*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8048*fcf3ce44SJohn Forte 8049*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 8050*fcf3ce44SJohn Forte } 8051*fcf3ce44SJohn Forte if (dfc->buf1_size < sizeof (dfc_auth_status_t)) { 8052*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8053*fcf3ce44SJohn Forte "%s: Buffer too small. (size=%d)", 8054*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size); 8055*fcf3ce44SJohn Forte 8056*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 8057*fcf3ce44SJohn Forte } 8058*fcf3ce44SJohn Forte /* Read the fcsp_config */ 8059*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf1, (void *)&fcsp_status, 8060*fcf3ce44SJohn Forte sizeof (dfc_auth_status_t), mode) != 0) { 8061*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8062*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 8063*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8064*fcf3ce44SJohn Forte 8065*fcf3ce44SJohn Forte return (DFC_COPYIN_ERROR); 8066*fcf3ce44SJohn Forte } 8067*fcf3ce44SJohn Forte if ((rval = emlxs_dhc_get_auth_status(hba, &fcsp_status)) != 0) { 8068*fcf3ce44SJohn Forte return (rval); 8069*fcf3ce44SJohn Forte } 8070*fcf3ce44SJohn Forte if (ddi_copyout((void *)&fcsp_status, (void *)dfc->buf1, 8071*fcf3ce44SJohn Forte sizeof (dfc_auth_status_t), mode) != 0) { 8072*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8073*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 8074*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8075*fcf3ce44SJohn Forte 8076*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 8077*fcf3ce44SJohn Forte } 8078*fcf3ce44SJohn Forte return (0); 8079*fcf3ce44SJohn Forte 8080*fcf3ce44SJohn Forte } /* emlxs_dfc_get_auth_status() */ 8081*fcf3ce44SJohn Forte 8082*fcf3ce44SJohn Forte 8083*fcf3ce44SJohn Forte static int32_t 8084*fcf3ce44SJohn Forte emlxs_dfc_get_auth_cfg_table(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 8085*fcf3ce44SJohn Forte { 8086*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 8087*fcf3ce44SJohn Forte dfc_fcsp_config_t *fcsp_cfg; 8088*fcf3ce44SJohn Forte uint32_t count; 8089*fcf3ce44SJohn Forte uint32_t size; 8090*fcf3ce44SJohn Forte uint32_t rval = DFC_SUCCESS; 8091*fcf3ce44SJohn Forte /* uint32_t count_sent = 0; */ 8092*fcf3ce44SJohn Forte 8093*fcf3ce44SJohn Forte /* 8094*fcf3ce44SJohn Forte * dfc.cmd = EMLXS_GET_AUTH_CFG_TABLE; dfc.buf1_size = size; 8095*fcf3ce44SJohn Forte * dfc.buf1 = fcsp_cfg; dfc.buf2_size = sizeof(uint32_t); 8096*fcf3ce44SJohn Forte * dfc.buf2 = &count; 8097*fcf3ce44SJohn Forte */ 8098*fcf3ce44SJohn Forte 8099*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 8100*fcf3ce44SJohn Forte "%s requested.", 8101*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8102*fcf3ce44SJohn Forte 8103*fcf3ce44SJohn Forte /* Lock cfg table while we do this */ 8104*fcf3ce44SJohn Forte /* This prevents the table from changing while we get a copy */ 8105*fcf3ce44SJohn Forte mutex_enter(&hba->auth_lock); 8106*fcf3ce44SJohn Forte 8107*fcf3ce44SJohn Forte if (!dfc->buf2 || !dfc->buf2_size) { 8108*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8109*fcf3ce44SJohn Forte "%s: Null buffer2 found.", 8110*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8111*fcf3ce44SJohn Forte 8112*fcf3ce44SJohn Forte mutex_exit(&hba->auth_lock); 8113*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 8114*fcf3ce44SJohn Forte } 8115*fcf3ce44SJohn Forte if (dfc->buf2_size < sizeof (uint32_t)) { 8116*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8117*fcf3ce44SJohn Forte "%s: Buffer2 too small. (size=%d)", 8118*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf2_size); 8119*fcf3ce44SJohn Forte 8120*fcf3ce44SJohn Forte mutex_exit(&hba->auth_lock); 8121*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 8122*fcf3ce44SJohn Forte } 8123*fcf3ce44SJohn Forte if (ddi_copyout((void *)&hba->auth_cfg_count, (void *)dfc->buf2, 8124*fcf3ce44SJohn Forte sizeof (uint32_t), mode) != 0) { 8125*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8126*fcf3ce44SJohn Forte "%s: ddi_copyout failed for table count. count=%d", 8127*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), hba->auth_cfg_count); 8128*fcf3ce44SJohn Forte 8129*fcf3ce44SJohn Forte mutex_exit(&hba->auth_lock); 8130*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 8131*fcf3ce44SJohn Forte } 8132*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 8133*fcf3ce44SJohn Forte mutex_exit(&hba->auth_lock); 8134*fcf3ce44SJohn Forte return (DFC_SUCCESS); 8135*fcf3ce44SJohn Forte } 8136*fcf3ce44SJohn Forte /* Check table size */ 8137*fcf3ce44SJohn Forte count = dfc->buf1_size / sizeof (dfc_fcsp_config_t); 8138*fcf3ce44SJohn Forte if (count < hba->auth_cfg_count) { 8139*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8140*fcf3ce44SJohn Forte "%s: Buffer1 too small. (%d < %d)", 8141*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), count, 8142*fcf3ce44SJohn Forte hba->auth_cfg_count); 8143*fcf3ce44SJohn Forte 8144*fcf3ce44SJohn Forte mutex_exit(&hba->auth_lock); 8145*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 8146*fcf3ce44SJohn Forte } 8147*fcf3ce44SJohn Forte size = hba->auth_cfg_count * sizeof (dfc_fcsp_config_t); 8148*fcf3ce44SJohn Forte if (!(fcsp_cfg = (dfc_fcsp_config_t *)kmem_zalloc(size, KM_SLEEP))) { 8149*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8150*fcf3ce44SJohn Forte "%s: Unable to allocate table buffer.", 8151*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8152*fcf3ce44SJohn Forte 8153*fcf3ce44SJohn Forte mutex_exit(&hba->auth_lock); 8154*fcf3ce44SJohn Forte return (DFC_SYSRES_ERROR); 8155*fcf3ce44SJohn Forte } 8156*fcf3ce44SJohn Forte if ((rval = emlxs_dhc_get_auth_cfg_table(hba, fcsp_cfg)) != 0) { 8157*fcf3ce44SJohn Forte mutex_exit(&hba->auth_lock); 8158*fcf3ce44SJohn Forte kmem_free(fcsp_cfg, size); 8159*fcf3ce44SJohn Forte return (rval); 8160*fcf3ce44SJohn Forte } 8161*fcf3ce44SJohn Forte mutex_exit(&hba->auth_lock); 8162*fcf3ce44SJohn Forte 8163*fcf3ce44SJohn Forte if (ddi_copyout((void *)fcsp_cfg, (void *)dfc->buf1, 8164*fcf3ce44SJohn Forte size, mode) != 0) { 8165*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8166*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 8167*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8168*fcf3ce44SJohn Forte 8169*fcf3ce44SJohn Forte kmem_free(fcsp_cfg, size); 8170*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 8171*fcf3ce44SJohn Forte } 8172*fcf3ce44SJohn Forte kmem_free(fcsp_cfg, size); 8173*fcf3ce44SJohn Forte return (0); 8174*fcf3ce44SJohn Forte 8175*fcf3ce44SJohn Forte } /* emlxs_dfc_get_auth_cfg_table() */ 8176*fcf3ce44SJohn Forte 8177*fcf3ce44SJohn Forte 8178*fcf3ce44SJohn Forte static int32_t 8179*fcf3ce44SJohn Forte emlxs_dfc_get_auth_key_table(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 8180*fcf3ce44SJohn Forte { 8181*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 8182*fcf3ce44SJohn Forte dfc_auth_password_t *auth_pwd; 8183*fcf3ce44SJohn Forte uint32_t count; 8184*fcf3ce44SJohn Forte uint32_t size; 8185*fcf3ce44SJohn Forte uint32_t rval = DFC_SUCCESS; 8186*fcf3ce44SJohn Forte /* uint32_t count_sent = 0; */ 8187*fcf3ce44SJohn Forte 8188*fcf3ce44SJohn Forte /* 8189*fcf3ce44SJohn Forte * dfc.cmd = EMLXS_GET_AUTH_KEY_TABLE; dfc.buf1_size = size; 8190*fcf3ce44SJohn Forte * dfc.buf1 = auth_pwd; dfc.buf2_size = sizeof(uint32_t); 8191*fcf3ce44SJohn Forte * dfc.buf2 = &count; 8192*fcf3ce44SJohn Forte */ 8193*fcf3ce44SJohn Forte 8194*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg, 8195*fcf3ce44SJohn Forte "%s requested.", 8196*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8197*fcf3ce44SJohn Forte 8198*fcf3ce44SJohn Forte /* Lock cfg table while we do this */ 8199*fcf3ce44SJohn Forte /* This prevents the table from changing while we get a copy */ 8200*fcf3ce44SJohn Forte mutex_enter(&hba->auth_lock); 8201*fcf3ce44SJohn Forte 8202*fcf3ce44SJohn Forte if (!dfc->buf2 || !dfc->buf2_size) { 8203*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8204*fcf3ce44SJohn Forte "%s: Null buffer2 found.", 8205*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8206*fcf3ce44SJohn Forte 8207*fcf3ce44SJohn Forte mutex_exit(&hba->auth_lock); 8208*fcf3ce44SJohn Forte return (DFC_ARG_NULL); 8209*fcf3ce44SJohn Forte } 8210*fcf3ce44SJohn Forte if (dfc->buf2_size < sizeof (uint32_t)) { 8211*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8212*fcf3ce44SJohn Forte "%s: Buffer2 too small. (size=%d)", 8213*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), dfc->buf2_size); 8214*fcf3ce44SJohn Forte 8215*fcf3ce44SJohn Forte mutex_exit(&hba->auth_lock); 8216*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 8217*fcf3ce44SJohn Forte } 8218*fcf3ce44SJohn Forte if (ddi_copyout((void *)&hba->auth_key_count, (void *)dfc->buf2, 8219*fcf3ce44SJohn Forte sizeof (uint32_t), mode) != 0) { 8220*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8221*fcf3ce44SJohn Forte "%s: ddi_copyout failed for table count. count=%d", 8222*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), hba->auth_key_count); 8223*fcf3ce44SJohn Forte 8224*fcf3ce44SJohn Forte mutex_exit(&hba->auth_lock); 8225*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 8226*fcf3ce44SJohn Forte } 8227*fcf3ce44SJohn Forte if (!dfc->buf1 || !dfc->buf1_size) { 8228*fcf3ce44SJohn Forte mutex_exit(&hba->auth_lock); 8229*fcf3ce44SJohn Forte return (DFC_SUCCESS); 8230*fcf3ce44SJohn Forte } 8231*fcf3ce44SJohn Forte /* Check table size */ 8232*fcf3ce44SJohn Forte count = dfc->buf1_size / sizeof (dfc_auth_password_t); 8233*fcf3ce44SJohn Forte if (count < hba->auth_key_count) { 8234*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8235*fcf3ce44SJohn Forte "%s: Buffer1 too small. (%d < %d)", 8236*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), count, 8237*fcf3ce44SJohn Forte hba->auth_key_count); 8238*fcf3ce44SJohn Forte 8239*fcf3ce44SJohn Forte mutex_exit(&hba->auth_lock); 8240*fcf3ce44SJohn Forte return (DFC_ARG_TOOSMALL); 8241*fcf3ce44SJohn Forte } 8242*fcf3ce44SJohn Forte size = hba->auth_key_count * sizeof (dfc_auth_password_t); 8243*fcf3ce44SJohn Forte if (!(auth_pwd = (dfc_auth_password_t *)kmem_zalloc(size, KM_SLEEP))) { 8244*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8245*fcf3ce44SJohn Forte "%s: Unable to allocate table buffer.", 8246*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8247*fcf3ce44SJohn Forte 8248*fcf3ce44SJohn Forte mutex_exit(&hba->auth_lock); 8249*fcf3ce44SJohn Forte return (DFC_SYSRES_ERROR); 8250*fcf3ce44SJohn Forte } 8251*fcf3ce44SJohn Forte if ((rval = emlxs_dhc_get_auth_key_table(hba, auth_pwd)) != 0) { 8252*fcf3ce44SJohn Forte mutex_exit(&hba->auth_lock); 8253*fcf3ce44SJohn Forte kmem_free(auth_pwd, size); 8254*fcf3ce44SJohn Forte return (rval); 8255*fcf3ce44SJohn Forte } 8256*fcf3ce44SJohn Forte mutex_exit(&hba->auth_lock); 8257*fcf3ce44SJohn Forte 8258*fcf3ce44SJohn Forte if (ddi_copyout((void *)auth_pwd, (void *)dfc->buf1, 8259*fcf3ce44SJohn Forte size, mode) != 0) { 8260*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8261*fcf3ce44SJohn Forte "%s: ddi_copyout failed.", 8262*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8263*fcf3ce44SJohn Forte 8264*fcf3ce44SJohn Forte kmem_free(auth_pwd, size); 8265*fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 8266*fcf3ce44SJohn Forte } 8267*fcf3ce44SJohn Forte kmem_free(auth_pwd, size); 8268*fcf3ce44SJohn Forte return (0); 8269*fcf3ce44SJohn Forte 8270*fcf3ce44SJohn Forte } /* emlxs_dfc_get_auth_key_table() */ 8271*fcf3ce44SJohn Forte 8272*fcf3ce44SJohn Forte 8273*fcf3ce44SJohn Forte 8274*fcf3ce44SJohn Forte #endif /* DHCHAP_SUPPORT */ 8275*fcf3ce44SJohn Forte 8276*fcf3ce44SJohn Forte static int32_t 8277*fcf3ce44SJohn Forte emlxs_dfc_send_scsi_fcp(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode) 8278*fcf3ce44SJohn Forte { 8279*fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 8280*fcf3ce44SJohn Forte fc_packet_t *pkt = NULL; 8281*fcf3ce44SJohn Forte NODELIST *ndlp; 8282*fcf3ce44SJohn Forte FCP_CMND *fcp_cmd; 8283*fcf3ce44SJohn Forte FCP_RSP *fcp_rsp; 8284*fcf3ce44SJohn Forte /* emlxs_xlat_err_t *entry; */ 8285*fcf3ce44SJohn Forte void *ptr; 8286*fcf3ce44SJohn Forte char buffer[64]; 8287*fcf3ce44SJohn Forte dfc_send_scsi_fcp_cmd_info_t cmdinfo; 8288*fcf3ce44SJohn Forte uint32_t rval = 0; 8289*fcf3ce44SJohn Forte 8290*fcf3ce44SJohn Forte /* cmd info */ 8291*fcf3ce44SJohn Forte if (!dfc->buf1 || 8292*fcf3ce44SJohn Forte (dfc->buf1_size != sizeof (dfc_send_scsi_fcp_cmd_info_t))) { 8293*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8294*fcf3ce44SJohn Forte "%s: Null buffer1 found.", 8295*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8296*fcf3ce44SJohn Forte 8297*fcf3ce44SJohn Forte rval = DFC_ARG_NULL; 8298*fcf3ce44SJohn Forte goto done; 8299*fcf3ce44SJohn Forte } 8300*fcf3ce44SJohn Forte /* reqBuffer info */ 8301*fcf3ce44SJohn Forte if (!dfc->buf2 || (dfc->buf2_size != sizeof (FCP_CMND))) { 8302*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8303*fcf3ce44SJohn Forte "%s: Null buffer2 found.", 8304*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8305*fcf3ce44SJohn Forte 8306*fcf3ce44SJohn Forte rval = DFC_ARG_NULL; 8307*fcf3ce44SJohn Forte goto done; 8308*fcf3ce44SJohn Forte } 8309*fcf3ce44SJohn Forte /* rspBuffer info, could be 0 for SCSI commands like TUR */ 8310*fcf3ce44SJohn Forte if (!dfc->buf3 && dfc->buf3_size) { 8311*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8312*fcf3ce44SJohn Forte "%s: Null buffer3 found.", 8313*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8314*fcf3ce44SJohn Forte 8315*fcf3ce44SJohn Forte rval = DFC_ARG_NULL; 8316*fcf3ce44SJohn Forte goto done; 8317*fcf3ce44SJohn Forte } 8318*fcf3ce44SJohn Forte /* senseBuffer info */ 8319*fcf3ce44SJohn Forte if (!dfc->buf4 || !dfc->buf4_size) { 8320*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8321*fcf3ce44SJohn Forte "%s: Null buffer4 found.", 8322*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8323*fcf3ce44SJohn Forte 8324*fcf3ce44SJohn Forte rval = DFC_ARG_NULL; 8325*fcf3ce44SJohn Forte goto done; 8326*fcf3ce44SJohn Forte } 8327*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf1, (void *)&cmdinfo, 8328*fcf3ce44SJohn Forte sizeof (dfc_send_scsi_fcp_cmd_info_t), mode) != 0) { 8329*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8330*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 8331*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8332*fcf3ce44SJohn Forte 8333*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 8334*fcf3ce44SJohn Forte goto done; 8335*fcf3ce44SJohn Forte } 8336*fcf3ce44SJohn Forte if (cmdinfo.ver == DFC_SEND_SCSI_FCP_V2) { 8337*fcf3ce44SJohn Forte port = emlxs_vport_find_wwpn(hba, 8338*fcf3ce44SJohn Forte (uint8_t *)&cmdinfo.src_wwn); 8339*fcf3ce44SJohn Forte if (port == NULL) { 8340*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8341*fcf3ce44SJohn Forte "%s: WWPN does not exists. %s", 8342*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 8343*fcf3ce44SJohn Forte emlxs_wwn_xlate(buffer, 8344*fcf3ce44SJohn Forte (uint8_t *)&cmdinfo.src_wwn)); 8345*fcf3ce44SJohn Forte 8346*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 8347*fcf3ce44SJohn Forte goto done; 8348*fcf3ce44SJohn Forte } 8349*fcf3ce44SJohn Forte } 8350*fcf3ce44SJohn Forte if ((ndlp = emlxs_node_find_wwpn(port, 8351*fcf3ce44SJohn Forte (uint8_t *)&cmdinfo.dst_wwn)) == NULL) { 8352*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8353*fcf3ce44SJohn Forte "%s: WWPN does not exists. %s", 8354*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd), 8355*fcf3ce44SJohn Forte emlxs_wwn_xlate(buffer, 8356*fcf3ce44SJohn Forte (uint8_t *)&cmdinfo.dst_wwn)); 8357*fcf3ce44SJohn Forte 8358*fcf3ce44SJohn Forte rval = DFC_ARG_INVALID; 8359*fcf3ce44SJohn Forte goto done; 8360*fcf3ce44SJohn Forte } 8361*fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, sizeof (FCP_CMND), 8362*fcf3ce44SJohn Forte sizeof (FCP_RSP), dfc->buf3_size, KM_NOSLEEP))) { 8363*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8364*fcf3ce44SJohn Forte "%s: Unable to allocate packet.", 8365*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8366*fcf3ce44SJohn Forte 8367*fcf3ce44SJohn Forte rval = DFC_SYSRES_ERROR; 8368*fcf3ce44SJohn Forte goto done; 8369*fcf3ce44SJohn Forte } 8370*fcf3ce44SJohn Forte fcp_cmd = (FCP_CMND *)pkt->pkt_cmd; 8371*fcf3ce44SJohn Forte /* Copy in the command buffer */ 8372*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf2, (void *)fcp_cmd, 8373*fcf3ce44SJohn Forte sizeof (FCP_CMND), mode) != 0) { 8374*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8375*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 8376*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8377*fcf3ce44SJohn Forte 8378*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 8379*fcf3ce44SJohn Forte goto done; 8380*fcf3ce44SJohn Forte } 8381*fcf3ce44SJohn Forte /* Make this a polled IO */ 8382*fcf3ce44SJohn Forte pkt->pkt_tran_flags &= ~FC_TRAN_INTR; 8383*fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_NO_INTR; 8384*fcf3ce44SJohn Forte pkt->pkt_comp = NULL; 8385*fcf3ce44SJohn Forte 8386*fcf3ce44SJohn Forte /* Build the fc header */ 8387*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(ndlp->nlp_DID); 8388*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = FC_FCP_CMND; 8389*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.s_id = SWAP_DATA24_LO(port->did); 8390*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_FCP_DATA; 8391*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 8392*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 8393*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 8394*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xFFFF; 8395*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xFFFF; 8396*fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 8397*fcf3ce44SJohn Forte 8398*fcf3ce44SJohn Forte pkt->pkt_timeout = 30; 8399*fcf3ce44SJohn Forte 8400*fcf3ce44SJohn Forte if ((fcp_cmd->fcpCntl3 == WRITE_DATA) && dfc->buf3_size) { 8401*fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_FCP_WRITE; 8402*fcf3ce44SJohn Forte if (ddi_copyin((void *)dfc->buf3, (void *)pkt->pkt_data, 8403*fcf3ce44SJohn Forte dfc->buf3_size, mode) != 0) { 8404*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8405*fcf3ce44SJohn Forte "%s: ddi_copyin failed.", 8406*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8407*fcf3ce44SJohn Forte 8408*fcf3ce44SJohn Forte rval = DFC_COPYIN_ERROR; 8409*fcf3ce44SJohn Forte goto done; 8410*fcf3ce44SJohn Forte } 8411*fcf3ce44SJohn Forte } else { 8412*fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_FCP_READ; 8413*fcf3ce44SJohn Forte } 8414*fcf3ce44SJohn Forte 8415*fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 8416*fcf3ce44SJohn Forte rval = DFC_IO_ERROR; 8417*fcf3ce44SJohn Forte goto done; 8418*fcf3ce44SJohn Forte } 8419*fcf3ce44SJohn Forte if (pkt->pkt_state != FC_PKT_SUCCESS) { 8420*fcf3ce44SJohn Forte if (pkt->pkt_state == FC_PKT_TIMEOUT) { 8421*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8422*fcf3ce44SJohn Forte "Pkt Transport error. Pkt Timeout."); 8423*fcf3ce44SJohn Forte rval = DFC_TIMEOUT; 8424*fcf3ce44SJohn Forte } else { 8425*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8426*fcf3ce44SJohn Forte "Pkt Transport error. state=%x", 8427*fcf3ce44SJohn Forte pkt->pkt_state); 8428*fcf3ce44SJohn Forte rval = DFC_IO_ERROR; 8429*fcf3ce44SJohn Forte } 8430*fcf3ce44SJohn Forte goto done; 8431*fcf3ce44SJohn Forte } 8432*fcf3ce44SJohn Forte if (pkt->pkt_data_resid) { 8433*fcf3ce44SJohn Forte if (pkt->pkt_data_resid < dfc->buf3_size) 8434*fcf3ce44SJohn Forte dfc->buf3_size -= pkt->pkt_data_resid; 8435*fcf3ce44SJohn Forte else 8436*fcf3ce44SJohn Forte dfc->buf3_size = 0; 8437*fcf3ce44SJohn Forte } 8438*fcf3ce44SJohn Forte SCSI_RSP_CNT(cmdinfo) = dfc->buf3_size; 8439*fcf3ce44SJohn Forte 8440*fcf3ce44SJohn Forte fcp_rsp = (FCP_RSP *)pkt->pkt_resp; 8441*fcf3ce44SJohn Forte /* 8442*fcf3ce44SJohn Forte * This is sense count for flag = 0. It is fcp response size for flag 8443*fcf3ce44SJohn Forte * = 1. 8444*fcf3ce44SJohn Forte */ 8445*fcf3ce44SJohn Forte if (dfc->flag) { 8446*fcf3ce44SJohn Forte SCSI_SNS_CNT(cmdinfo) = 24 + SWAP_DATA32(fcp_rsp->rspSnsLen) + 8447*fcf3ce44SJohn Forte SWAP_DATA32(fcp_rsp->rspRspLen); 8448*fcf3ce44SJohn Forte ptr = (void *)fcp_rsp; 8449*fcf3ce44SJohn Forte } else { 8450*fcf3ce44SJohn Forte SCSI_SNS_CNT(cmdinfo) = SWAP_DATA32(fcp_rsp->rspSnsLen); 8451*fcf3ce44SJohn Forte ptr = (void *)&fcp_rsp->rspSnsInfo[0]; 8452*fcf3ce44SJohn Forte } 8453*fcf3ce44SJohn Forte 8454*fcf3ce44SJohn Forte if (ddi_copyout((void *)&cmdinfo, (void *)dfc->buf1, 8455*fcf3ce44SJohn Forte sizeof (dfc_send_scsi_fcp_cmd_info_t), mode) != 0) { 8456*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8457*fcf3ce44SJohn Forte "%s: rsp_buf ddi_copyout failed.", 8458*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8459*fcf3ce44SJohn Forte 8460*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 8461*fcf3ce44SJohn Forte goto done; 8462*fcf3ce44SJohn Forte } 8463*fcf3ce44SJohn Forte if (SCSI_SNS_CNT(cmdinfo)) { 8464*fcf3ce44SJohn Forte if (ddi_copyout(ptr, (void *)dfc->buf4, 8465*fcf3ce44SJohn Forte SCSI_SNS_CNT(cmdinfo), mode) != 0) { 8466*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8467*fcf3ce44SJohn Forte "%s: rsp_size ddi_copyout failed.", 8468*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8469*fcf3ce44SJohn Forte 8470*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 8471*fcf3ce44SJohn Forte goto done; 8472*fcf3ce44SJohn Forte } 8473*fcf3ce44SJohn Forte } 8474*fcf3ce44SJohn Forte if (SCSI_RSP_CNT(cmdinfo)) { 8475*fcf3ce44SJohn Forte if (ddi_copyout((void *)pkt->pkt_data, (void *)dfc->buf3, 8476*fcf3ce44SJohn Forte SCSI_RSP_CNT(cmdinfo), mode) != 0) { 8477*fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg, 8478*fcf3ce44SJohn Forte "%s: rsp_size ddi_copyout failed.", 8479*fcf3ce44SJohn Forte emlxs_dfc_xlate(dfc->cmd)); 8480*fcf3ce44SJohn Forte 8481*fcf3ce44SJohn Forte rval = DFC_COPYOUT_ERROR; 8482*fcf3ce44SJohn Forte goto done; 8483*fcf3ce44SJohn Forte } 8484*fcf3ce44SJohn Forte } 8485*fcf3ce44SJohn Forte rval = 0; 8486*fcf3ce44SJohn Forte 8487*fcf3ce44SJohn Forte done: 8488*fcf3ce44SJohn Forte if (pkt) { 8489*fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 8490*fcf3ce44SJohn Forte } 8491*fcf3ce44SJohn Forte return (rval); 8492*fcf3ce44SJohn Forte 8493*fcf3ce44SJohn Forte } /* emlxs_dfc_send_scsi_fcp() */ 8494*fcf3ce44SJohn Forte 8495*fcf3ce44SJohn Forte #endif /* DFC_SUPPORT */ 8496