1fcf3ce44SJohn Forte /* 2fcf3ce44SJohn Forte * CDDL HEADER START 3fcf3ce44SJohn Forte * 4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7fcf3ce44SJohn Forte * 8fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11fcf3ce44SJohn Forte * and limitations under the License. 12fcf3ce44SJohn Forte * 13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18fcf3ce44SJohn Forte * 19fcf3ce44SJohn Forte * CDDL HEADER END 20fcf3ce44SJohn Forte */ 21fcf3ce44SJohn Forte 22fcf3ce44SJohn Forte /* 23*291a2b48SSukumar Swaminathan * Copyright 2009 Emulex. All rights reserved. 24fcf3ce44SJohn Forte * Use is subject to License terms. 25fcf3ce44SJohn Forte */ 26fcf3ce44SJohn Forte 27*291a2b48SSukumar Swaminathan #include <emlxs.h> 28fcf3ce44SJohn Forte 29fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT 30fcf3ce44SJohn Forte 31fcf3ce44SJohn Forte 32fcf3ce44SJohn Forte /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 33fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_FCT_C); 34fcf3ce44SJohn Forte 35fcf3ce44SJohn Forte #ifndef PORT_SPEED_10G 36fcf3ce44SJohn Forte #define PORT_SPEED_10G 0x10 37*291a2b48SSukumar Swaminathan #endif /* PORT_SPEED_10G */ 38fcf3ce44SJohn Forte 39fcf3ce44SJohn Forte static void emlxs_fct_handle_acc(emlxs_port_t *port, emlxs_buf_t *sbp, 40fcf3ce44SJohn Forte IOCBQ *iocbq); 41fcf3ce44SJohn Forte static void emlxs_fct_handle_reject(emlxs_port_t *port, emlxs_buf_t *sbp, 42fcf3ce44SJohn Forte IOCBQ *iocbq); 43*291a2b48SSukumar Swaminathan static emlxs_buf_t *emlxs_fct_cmd_init(emlxs_port_t *port, 44*291a2b48SSukumar Swaminathan fct_cmd_t *fct_cmd); 45fcf3ce44SJohn Forte static int emlxs_fct_cmd_uninit(emlxs_port_t *port, fct_cmd_t *fct_cmd); 46fcf3ce44SJohn Forte 47fcf3ce44SJohn Forte static fct_status_t emlxs_flogi_xchg(struct fct_local_port *fct_port, 48fcf3ce44SJohn Forte struct fct_flogi_xchg *fx); 49fcf3ce44SJohn Forte static fct_status_t emlxs_fct_get_link_info(fct_local_port_t *fct_port, 50fcf3ce44SJohn Forte fct_link_info_t *link); 51fcf3ce44SJohn Forte static fct_status_t emlxs_fct_deregister_remote_port(fct_local_port_t *fct_port, 52fcf3ce44SJohn Forte fct_remote_port_t *port_handle); 53fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_cmd(fct_cmd_t *fct_cmd); 54fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_fcp_data(fct_cmd_t *fct_cmd, 55fcf3ce44SJohn Forte stmf_data_buf_t *dbuf, uint32_t ioflags); 56*291a2b48SSukumar Swaminathan static fct_status_t emlxs_fct_send_cmd_rsp(fct_cmd_t *fct_cmd, uint32_t flags); 57*291a2b48SSukumar Swaminathan static fct_status_t emlxs_fct_abort(fct_local_port_t *fct_port, 58*291a2b48SSukumar Swaminathan fct_cmd_t *cmd, uint32_t flags); 59fcf3ce44SJohn Forte static void emlxs_fct_ctl(fct_local_port_t *fct_port, int cmd, void *arg); 60fcf3ce44SJohn Forte static fct_status_t emlxs_fct_register_remote_port(fct_local_port_t *fct_port, 61fcf3ce44SJohn Forte fct_remote_port_t *port_handle, fct_cmd_t *plogi); 62fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_els_cmd(fct_cmd_t *fct_cmd); 63fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_ct_cmd(fct_cmd_t *fct_cmd); 64fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_fcp_status(fct_cmd_t *fct_cmd); 65fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_els_rsp(fct_cmd_t *fct_cmd); 66fcf3ce44SJohn Forte static void emlxs_fct_pkt_comp(fc_packet_t *pkt); 67fcf3ce44SJohn Forte static void emlxs_populate_hba_details(fct_local_port_t *fct_port, 68fcf3ce44SJohn Forte fct_port_attrs_t *port_attrs); 69fcf3ce44SJohn Forte 70fcf3ce44SJohn Forte static fct_status_t emlxs_fct_dmem_init(emlxs_port_t *port); 71fcf3ce44SJohn Forte static void emlxs_fct_dmem_fini(emlxs_port_t *port); 72fcf3ce44SJohn Forte 73fcf3ce44SJohn Forte static stmf_data_buf_t *emlxs_fct_dbuf_alloc(fct_local_port_t *fct_port, 74fcf3ce44SJohn Forte uint32_t size, uint32_t *pminsize, uint32_t flags); 75fcf3ce44SJohn Forte static void emlxs_fct_dbuf_free(fct_dbuf_store_t *fds, stmf_data_buf_t *dbuf); 76fcf3ce44SJohn Forte 77fcf3ce44SJohn Forte static void emlxs_fct_dbuf_dma_sync(stmf_data_buf_t *dbuf, uint_t sync_type); 78*291a2b48SSukumar Swaminathan static emlxs_buf_t *emlxs_fct_pkt_init(emlxs_port_t *port, 79*291a2b48SSukumar Swaminathan fct_cmd_t *fct_cmd, fc_packet_t *pkt); 80fcf3ce44SJohn Forte 81fcf3ce44SJohn Forte static void emlxs_fct_unsol_flush(emlxs_port_t *port); 82fcf3ce44SJohn Forte static uint32_t emlxs_fct_process_unsol_flogi(emlxs_port_t *port, RING *rp, 83fcf3ce44SJohn Forte IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 84fcf3ce44SJohn Forte static uint32_t emlxs_fct_process_unsol_plogi(emlxs_port_t *port, RING *rp, 85fcf3ce44SJohn Forte IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 86fcf3ce44SJohn Forte static fct_status_t emlxs_fct_pkt_abort(emlxs_port_t *port, emlxs_buf_t *sbp); 87fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_qfull_reply(emlxs_port_t *port, 88fcf3ce44SJohn Forte emlxs_node_t *ndlp, uint16_t xid, uint32_t class, emlxs_fcp_cmd_t *fcp_cmd); 89*291a2b48SSukumar Swaminathan static void emlxs_fct_dbuf_dma_sync(stmf_data_buf_t *dbuf, uint_t sync_type); 90*291a2b48SSukumar Swaminathan 91*291a2b48SSukumar Swaminathan #ifdef FCT_IO_TRACE 92*291a2b48SSukumar Swaminathan uint8_t *emlxs_iotrace = 0; /* global for mdb */ 93*291a2b48SSukumar Swaminathan int emlxs_iotrace_cnt = 0; 94*291a2b48SSukumar Swaminathan 95*291a2b48SSukumar Swaminathan void 96*291a2b48SSukumar Swaminathan emlxs_fct_io_trace(emlxs_port_t *port, fct_cmd_t *fct_cmd, uint32_t data) 97*291a2b48SSukumar Swaminathan { 98*291a2b48SSukumar Swaminathan emlxs_iotrace_t *iop = port->iotrace; 99*291a2b48SSukumar Swaminathan uint16_t iotrace_cnt; 100*291a2b48SSukumar Swaminathan uint16_t iotrace_index; 101*291a2b48SSukumar Swaminathan int i; 102*291a2b48SSukumar Swaminathan 103*291a2b48SSukumar Swaminathan if (!iop) { 104*291a2b48SSukumar Swaminathan return; 105*291a2b48SSukumar Swaminathan } 106*291a2b48SSukumar Swaminathan 107*291a2b48SSukumar Swaminathan mutex_enter(&port->iotrace_mtx); 108*291a2b48SSukumar Swaminathan iotrace_cnt = port->iotrace_cnt; 109*291a2b48SSukumar Swaminathan iotrace_index = port->iotrace_index; 110*291a2b48SSukumar Swaminathan 111*291a2b48SSukumar Swaminathan switch (data) { 112*291a2b48SSukumar Swaminathan 113*291a2b48SSukumar Swaminathan /* New entry */ 114*291a2b48SSukumar Swaminathan case EMLXS_FCT_ELS_CMD_RECEIVED: 115*291a2b48SSukumar Swaminathan case EMLXS_FCT_FCP_CMD_RECEIVED: 116*291a2b48SSukumar Swaminathan case EMLXS_FCT_SEND_ELS_REQ: 117*291a2b48SSukumar Swaminathan case EMLXS_FCT_SEND_CT_REQ: 118*291a2b48SSukumar Swaminathan for (i = 0; i < iotrace_cnt; i++) { 119*291a2b48SSukumar Swaminathan if ((iop->fct_cmd == fct_cmd) && 120*291a2b48SSukumar Swaminathan (iop->trc[0] != (uint8_t)(0))) 121*291a2b48SSukumar Swaminathan break; 122*291a2b48SSukumar Swaminathan iop++; 123*291a2b48SSukumar Swaminathan } 124*291a2b48SSukumar Swaminathan if (i < iotrace_cnt) { 125*291a2b48SSukumar Swaminathan /* New entry already exists */ 126*291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 127*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 128*291a2b48SSukumar Swaminathan "IOTRACE: New entry already exists: fct_cmd: %p", 129*291a2b48SSukumar Swaminathan fct_cmd); 130*291a2b48SSukumar Swaminathan return; 131*291a2b48SSukumar Swaminathan } 132*291a2b48SSukumar Swaminathan iop = port->iotrace + iotrace_index; 133*291a2b48SSukumar Swaminathan for (i = 0; i < iotrace_cnt; i++) { 134*291a2b48SSukumar Swaminathan if (iop->trc[0] == (uint8_t)(0)) 135*291a2b48SSukumar Swaminathan break; 136*291a2b48SSukumar Swaminathan 137*291a2b48SSukumar Swaminathan iop++; 138*291a2b48SSukumar Swaminathan if (iop == (port->iotrace + iotrace_cnt)) 139*291a2b48SSukumar Swaminathan iop = port->iotrace; 140*291a2b48SSukumar Swaminathan } 141*291a2b48SSukumar Swaminathan if (i >= iotrace_cnt) { 142*291a2b48SSukumar Swaminathan /* No new slots available */ 143*291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 144*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 145*291a2b48SSukumar Swaminathan "IOTRACE: No new slots: fct_cmd: %p data: %d", 146*291a2b48SSukumar Swaminathan fct_cmd, data); 147*291a2b48SSukumar Swaminathan return; 148*291a2b48SSukumar Swaminathan } 149*291a2b48SSukumar Swaminathan port->iotrace_index++; 150*291a2b48SSukumar Swaminathan if (port->iotrace_index >= iotrace_cnt) 151*291a2b48SSukumar Swaminathan port->iotrace_index = 0; 152*291a2b48SSukumar Swaminathan 153*291a2b48SSukumar Swaminathan bzero((uint8_t *)iop, sizeof (emlxs_iotrace_t)); 154*291a2b48SSukumar Swaminathan iop->fct_cmd = fct_cmd; 155*291a2b48SSukumar Swaminathan iop->xri = fct_cmd->cmd_rxid; 156*291a2b48SSukumar Swaminathan iop->marker = 0xff; 157*291a2b48SSukumar Swaminathan iop->trc[0] = 2; 158*291a2b48SSukumar Swaminathan iop->trc[1] = data; 159*291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 160*291a2b48SSukumar Swaminathan return; 161*291a2b48SSukumar Swaminathan } 162*291a2b48SSukumar Swaminathan 163*291a2b48SSukumar Swaminathan for (i = 0; i < iotrace_cnt; i++) { 164*291a2b48SSukumar Swaminathan if ((iop->fct_cmd == fct_cmd) && 165*291a2b48SSukumar Swaminathan (iop->trc[0] != (uint8_t)(0))) 166*291a2b48SSukumar Swaminathan break; 167*291a2b48SSukumar Swaminathan iop++; 168*291a2b48SSukumar Swaminathan } 169*291a2b48SSukumar Swaminathan if (i >= iotrace_cnt) { 170*291a2b48SSukumar Swaminathan /* Cannot find existing slot for fct_cmd */ 171*291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 172*291a2b48SSukumar Swaminathan 173*291a2b48SSukumar Swaminathan if ((data != EMLXS_FCT_REG_PENDING) && 174*291a2b48SSukumar Swaminathan (data != EMLXS_FCT_REG_COMPLETE)) { 175*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 176*291a2b48SSukumar Swaminathan "IOTRACE: Missing slot: fct_cmd: %p data: %d", 177*291a2b48SSukumar Swaminathan fct_cmd, data); 178*291a2b48SSukumar Swaminathan } 179*291a2b48SSukumar Swaminathan return; 180*291a2b48SSukumar Swaminathan } 181*291a2b48SSukumar Swaminathan 182*291a2b48SSukumar Swaminathan if (iop->trc[0] >= MAX_IO_TRACE) { 183*291a2b48SSukumar Swaminathan /* trc overrun for fct_cmd */ 184*291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 185*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 186*291a2b48SSukumar Swaminathan "IOTRACE: trc overrun slot: fct_cmd: %p data: %d", 187*291a2b48SSukumar Swaminathan fct_cmd, data); 188*291a2b48SSukumar Swaminathan return; 189*291a2b48SSukumar Swaminathan } 190*291a2b48SSukumar Swaminathan 191*291a2b48SSukumar Swaminathan if (iop->xri != fct_cmd->cmd_rxid) { 192*291a2b48SSukumar Swaminathan /* xri mismatch for fct_cmd */ 193*291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 194*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 195*291a2b48SSukumar Swaminathan "IOTRACE: xri mismatch %x != %x: fct_cmd: %p data: %d", 196*291a2b48SSukumar Swaminathan iop->xri, fct_cmd->cmd_rxid, fct_cmd, data); 197*291a2b48SSukumar Swaminathan return; 198*291a2b48SSukumar Swaminathan } 199*291a2b48SSukumar Swaminathan 200*291a2b48SSukumar Swaminathan iop->trc[iop->trc[0]] = data; 201*291a2b48SSukumar Swaminathan if ((data == EMLXS_FCT_IO_DONE) || (data == EMLXS_FCT_ABORT_DONE)) { 202*291a2b48SSukumar Swaminathan /* IOCB ulpCommand is saved after EMLXS_FCT_IOCB_ISSUED */ 203*291a2b48SSukumar Swaminathan if (iop->trc[iop->trc[0]-1] == EMLXS_FCT_IOCB_ISSUED) 204*291a2b48SSukumar Swaminathan iop->trc[0]++; 205*291a2b48SSukumar Swaminathan else 206*291a2b48SSukumar Swaminathan iop->trc[0] = 0; 207*291a2b48SSukumar Swaminathan } 208*291a2b48SSukumar Swaminathan else 209*291a2b48SSukumar Swaminathan iop->trc[0]++; 210*291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 211*291a2b48SSukumar Swaminathan } 212*291a2b48SSukumar Swaminathan #endif /* FCT_IO_TRACE */ 213fcf3ce44SJohn Forte 214fcf3ce44SJohn Forte #ifdef MODSYM_SUPPORT 215fcf3ce44SJohn Forte 216fcf3ce44SJohn Forte static int 217fcf3ce44SJohn Forte emlxs_fct_modopen() 218fcf3ce44SJohn Forte { 219fcf3ce44SJohn Forte int err; 220fcf3ce44SJohn Forte 221fcf3ce44SJohn Forte if (emlxs_modsym.mod_fct) { 222fcf3ce44SJohn Forte return (1); 223fcf3ce44SJohn Forte } 224*291a2b48SSukumar Swaminathan 225fcf3ce44SJohn Forte /* Comstar (fct) */ 226fcf3ce44SJohn Forte err = 0; 227fcf3ce44SJohn Forte emlxs_modsym.mod_fct = ddi_modopen("drv/fct", KRTLD_MODE_FIRST, &err); 228fcf3ce44SJohn Forte if (!emlxs_modsym.mod_fct) { 229fcf3ce44SJohn Forte 230fcf3ce44SJohn Forte cmn_err(CE_WARN, "?%s: ddi_modopen drv/fct failed: err %d", 231fcf3ce44SJohn Forte DRIVER_NAME, err); 232fcf3ce44SJohn Forte goto failed; 233fcf3ce44SJohn Forte } 234*291a2b48SSukumar Swaminathan 235fcf3ce44SJohn Forte /* Comstar (stmf) */ 236fcf3ce44SJohn Forte err = 0; 237*291a2b48SSukumar Swaminathan emlxs_modsym.mod_stmf = 238*291a2b48SSukumar Swaminathan ddi_modopen("drv/stmf", KRTLD_MODE_FIRST, &err); 239fcf3ce44SJohn Forte if (!emlxs_modsym.mod_stmf) { 240fcf3ce44SJohn Forte 241fcf3ce44SJohn Forte cmn_err(CE_WARN, "?%s: ddi_modopen drv/stmf failed: err %d", 242fcf3ce44SJohn Forte DRIVER_NAME, err); 243fcf3ce44SJohn Forte goto failed; 244fcf3ce44SJohn Forte } 245*291a2b48SSukumar Swaminathan 246fcf3ce44SJohn Forte err = 0; 247fcf3ce44SJohn Forte /* Check if the fct fct_alloc is present */ 248*291a2b48SSukumar Swaminathan emlxs_modsym.fct_alloc = (void *(*)())ddi_modsym(emlxs_modsym.mod_fct, 249fcf3ce44SJohn Forte "fct_alloc", &err); 250fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_alloc == NULL) { 251fcf3ce44SJohn Forte cmn_err(CE_WARN, 252fcf3ce44SJohn Forte "?%s: drv/fct: fct_alloc not present", DRIVER_NAME); 253fcf3ce44SJohn Forte goto failed; 254fcf3ce44SJohn Forte } 255*291a2b48SSukumar Swaminathan 256fcf3ce44SJohn Forte err = 0; 257fcf3ce44SJohn Forte /* Check if the fct fct_free is present */ 258*291a2b48SSukumar Swaminathan emlxs_modsym.fct_free = (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 259fcf3ce44SJohn Forte "fct_free", &err); 260fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_free == NULL) { 261fcf3ce44SJohn Forte cmn_err(CE_WARN, 262fcf3ce44SJohn Forte "?%s: drv/fct: fct_free not present", DRIVER_NAME); 263fcf3ce44SJohn Forte goto failed; 264fcf3ce44SJohn Forte } 265*291a2b48SSukumar Swaminathan 266fcf3ce44SJohn Forte err = 0; 267fcf3ce44SJohn Forte /* Check if the fct fct_scsi_task_alloc is present */ 268*291a2b48SSukumar Swaminathan emlxs_modsym.fct_scsi_task_alloc = 269*291a2b48SSukumar Swaminathan (void *(*)(void *, uint16_t, uint32_t, uint8_t *, 270*291a2b48SSukumar Swaminathan uint16_t, uint16_t))ddi_modsym(emlxs_modsym.mod_fct, 271*291a2b48SSukumar Swaminathan "fct_scsi_task_alloc", &err); 272fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_scsi_task_alloc == NULL) { 273fcf3ce44SJohn Forte cmn_err(CE_WARN, 274fcf3ce44SJohn Forte "?%s: drv/fct: fct_scsi_task_alloc not present", 275fcf3ce44SJohn Forte DRIVER_NAME); 276fcf3ce44SJohn Forte goto failed; 277fcf3ce44SJohn Forte } 278*291a2b48SSukumar Swaminathan 279fcf3ce44SJohn Forte err = 0; 280fcf3ce44SJohn Forte /* Check if the fct fct_register_local_port is present */ 281*291a2b48SSukumar Swaminathan emlxs_modsym.fct_register_local_port = 282*291a2b48SSukumar Swaminathan (int (*)())ddi_modsym(emlxs_modsym.mod_fct, 283*291a2b48SSukumar Swaminathan "fct_register_local_port", &err); 284fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_register_local_port == NULL) { 285fcf3ce44SJohn Forte cmn_err(CE_WARN, 286fcf3ce44SJohn Forte "?%s: drv/fct: fct_register_local_port not present", 287fcf3ce44SJohn Forte DRIVER_NAME); 288fcf3ce44SJohn Forte goto failed; 289fcf3ce44SJohn Forte } 290*291a2b48SSukumar Swaminathan 291fcf3ce44SJohn Forte err = 0; 292fcf3ce44SJohn Forte /* Check if the fct fct_deregister_local_port is present */ 293*291a2b48SSukumar Swaminathan emlxs_modsym.fct_deregister_local_port = 294*291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 295*291a2b48SSukumar Swaminathan "fct_deregister_local_port", &err); 296fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_deregister_local_port == NULL) { 297fcf3ce44SJohn Forte cmn_err(CE_WARN, 298fcf3ce44SJohn Forte "?%s: drv/fct: fct_deregister_local_port not present", 299fcf3ce44SJohn Forte DRIVER_NAME); 300fcf3ce44SJohn Forte goto failed; 301fcf3ce44SJohn Forte } 302*291a2b48SSukumar Swaminathan 303fcf3ce44SJohn Forte err = 0; 304fcf3ce44SJohn Forte /* Check if the fct fct_handle_event is present */ 305*291a2b48SSukumar Swaminathan emlxs_modsym.fct_handle_event = 306*291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, "fct_handle_event", 307*291a2b48SSukumar Swaminathan &err); 308fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_handle_event == NULL) { 309fcf3ce44SJohn Forte cmn_err(CE_WARN, 310*291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_handle_event not present", 311*291a2b48SSukumar Swaminathan DRIVER_NAME); 312fcf3ce44SJohn Forte goto failed; 313fcf3ce44SJohn Forte } 314*291a2b48SSukumar Swaminathan 315fcf3ce44SJohn Forte err = 0; 316fcf3ce44SJohn Forte /* Check if the fct fct_post_rcvd_cmd is present */ 317*291a2b48SSukumar Swaminathan emlxs_modsym.fct_post_rcvd_cmd = 318*291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, "fct_post_rcvd_cmd", 319*291a2b48SSukumar Swaminathan &err); 320fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_post_rcvd_cmd == NULL) { 321fcf3ce44SJohn Forte cmn_err(CE_WARN, 322*291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_post_rcvd_cmd not present", 323*291a2b48SSukumar Swaminathan DRIVER_NAME); 324fcf3ce44SJohn Forte goto failed; 325fcf3ce44SJohn Forte } 326fcf3ce44SJohn Forte err = 0; 327fcf3ce44SJohn Forte /* Check if the fct fct_alloc is present */ 328*291a2b48SSukumar Swaminathan emlxs_modsym.fct_ctl = (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 329fcf3ce44SJohn Forte "fct_ctl", &err); 330fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_ctl == NULL) { 331fcf3ce44SJohn Forte cmn_err(CE_WARN, 332fcf3ce44SJohn Forte "?%s: drv/fct: fct_ctl not present", DRIVER_NAME); 333fcf3ce44SJohn Forte goto failed; 334fcf3ce44SJohn Forte } 335fcf3ce44SJohn Forte err = 0; 336*291a2b48SSukumar Swaminathan /* Check if the fct fct_queue_cmd_for_termination is present */ 337*291a2b48SSukumar Swaminathan emlxs_modsym.fct_queue_cmd_for_termination = 338*291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 339*291a2b48SSukumar Swaminathan "fct_queue_cmd_for_termination", &err); 340*291a2b48SSukumar Swaminathan if ((void *)emlxs_modsym.fct_queue_cmd_for_termination == NULL) { 341*291a2b48SSukumar Swaminathan cmn_err(CE_WARN, 342*291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_queue_cmd_for_termination not present", 343*291a2b48SSukumar Swaminathan DRIVER_NAME); 344*291a2b48SSukumar Swaminathan goto failed; 345*291a2b48SSukumar Swaminathan } 346*291a2b48SSukumar Swaminathan err = 0; 347fcf3ce44SJohn Forte /* Check if the fct fct_send_response_done is present */ 348*291a2b48SSukumar Swaminathan emlxs_modsym.fct_send_response_done = 349*291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 350*291a2b48SSukumar Swaminathan "fct_send_response_done", &err); 351fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_send_response_done == NULL) { 352fcf3ce44SJohn Forte cmn_err(CE_WARN, 353fcf3ce44SJohn Forte "?%s: drv/fct: fct_send_response_done not present", 354fcf3ce44SJohn Forte DRIVER_NAME); 355fcf3ce44SJohn Forte goto failed; 356fcf3ce44SJohn Forte } 357fcf3ce44SJohn Forte err = 0; 358fcf3ce44SJohn Forte /* Check if the fct fct_send_cmd_done is present */ 359*291a2b48SSukumar Swaminathan emlxs_modsym.fct_send_cmd_done = 360*291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, "fct_send_cmd_done", 361*291a2b48SSukumar Swaminathan &err); 362fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_send_cmd_done == NULL) { 363fcf3ce44SJohn Forte cmn_err(CE_WARN, 364*291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_send_cmd_done not present", 365*291a2b48SSukumar Swaminathan DRIVER_NAME); 366fcf3ce44SJohn Forte goto failed; 367fcf3ce44SJohn Forte } 368fcf3ce44SJohn Forte err = 0; 369fcf3ce44SJohn Forte /* Check if the fct fct_scsi_xfer_data_done is present */ 370*291a2b48SSukumar Swaminathan emlxs_modsym.fct_scsi_data_xfer_done = 371*291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 372*291a2b48SSukumar Swaminathan "fct_scsi_data_xfer_done", &err); 373fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_scsi_data_xfer_done == NULL) { 374fcf3ce44SJohn Forte cmn_err(CE_WARN, 375fcf3ce44SJohn Forte "?%s: drv/fct: fct_scsi_data_xfer_done not present", 376fcf3ce44SJohn Forte DRIVER_NAME); 377fcf3ce44SJohn Forte goto failed; 378fcf3ce44SJohn Forte } 379fcf3ce44SJohn Forte err = 0; 380fcf3ce44SJohn Forte /* Check if the fct fct_port_shutdown is present */ 381*291a2b48SSukumar Swaminathan emlxs_modsym.fct_port_shutdown = 382*291a2b48SSukumar Swaminathan (fct_status_t(*)())ddi_modsym(emlxs_modsym.mod_fct, 383*291a2b48SSukumar Swaminathan "fct_port_shutdown", &err); 384fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_port_shutdown == NULL) { 385fcf3ce44SJohn Forte cmn_err(CE_WARN, 386*291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_port_shutdown not present", 387*291a2b48SSukumar Swaminathan DRIVER_NAME); 388fcf3ce44SJohn Forte goto failed; 389fcf3ce44SJohn Forte } 390*291a2b48SSukumar Swaminathan 391fcf3ce44SJohn Forte err = 0; 392fcf3ce44SJohn Forte /* Check if the fct fct_port_initialize is present */ 393*291a2b48SSukumar Swaminathan emlxs_modsym.fct_port_initialize = 394*291a2b48SSukumar Swaminathan (fct_status_t(*)())ddi_modsym(emlxs_modsym.mod_fct, 395*291a2b48SSukumar Swaminathan "fct_port_initialize", &err); 396fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_port_initialize == NULL) { 397fcf3ce44SJohn Forte cmn_err(CE_WARN, 398fcf3ce44SJohn Forte "?%s: drv/fct: fct_port_initialize not present", 399fcf3ce44SJohn Forte DRIVER_NAME); 400fcf3ce44SJohn Forte goto failed; 401fcf3ce44SJohn Forte } 402*291a2b48SSukumar Swaminathan 403*291a2b48SSukumar Swaminathan err = 0; 404*291a2b48SSukumar Swaminathan /* Check if the fct fct_cmd_fca_aborted is present */ 405*291a2b48SSukumar Swaminathan emlxs_modsym.fct_cmd_fca_aborted = 406*291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 407*291a2b48SSukumar Swaminathan "fct_cmd_fca_aborted", &err); 408*291a2b48SSukumar Swaminathan if ((void *)emlxs_modsym.fct_cmd_fca_aborted == NULL) { 409*291a2b48SSukumar Swaminathan cmn_err(CE_WARN, 410*291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_cmd_fca_aborted not present", 411*291a2b48SSukumar Swaminathan DRIVER_NAME); 412*291a2b48SSukumar Swaminathan goto failed; 413*291a2b48SSukumar Swaminathan } 414*291a2b48SSukumar Swaminathan 415fcf3ce44SJohn Forte err = 0; 416fcf3ce44SJohn Forte /* Check if the fct fct_handle_rcvd_flogi is present */ 417*291a2b48SSukumar Swaminathan emlxs_modsym.fct_handle_rcvd_flogi = 418*291a2b48SSukumar Swaminathan (fct_status_t(*)())ddi_modsym(emlxs_modsym.mod_fct, 419*291a2b48SSukumar Swaminathan "fct_handle_rcvd_flogi", &err); 420fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_handle_rcvd_flogi == NULL) { 421fcf3ce44SJohn Forte cmn_err(CE_WARN, 422fcf3ce44SJohn Forte "?%s: drv/fct: fct_handle_rcvd_flogi not present", 423fcf3ce44SJohn Forte DRIVER_NAME); 424fcf3ce44SJohn Forte goto failed; 425fcf3ce44SJohn Forte } 426*291a2b48SSukumar Swaminathan 427fcf3ce44SJohn Forte /* Comstar (stmf) */ 428fcf3ce44SJohn Forte err = 0; 429fcf3ce44SJohn Forte /* Check if the stmf stmf_alloc is present */ 430*291a2b48SSukumar Swaminathan emlxs_modsym.stmf_alloc = 431*291a2b48SSukumar Swaminathan (void *(*)())ddi_modsym(emlxs_modsym.mod_stmf, "stmf_alloc", 432*291a2b48SSukumar Swaminathan &err); 433fcf3ce44SJohn Forte if ((void *)emlxs_modsym.stmf_alloc == NULL) { 434fcf3ce44SJohn Forte cmn_err(CE_WARN, 435fcf3ce44SJohn Forte "?%s: drv/stmf: stmf_alloc not present", DRIVER_NAME); 436fcf3ce44SJohn Forte goto failed; 437fcf3ce44SJohn Forte } 438*291a2b48SSukumar Swaminathan 439fcf3ce44SJohn Forte err = 0; 440fcf3ce44SJohn Forte /* Check if the stmf stmf_free is present */ 441*291a2b48SSukumar Swaminathan emlxs_modsym.stmf_free = (void (*)())ddi_modsym(emlxs_modsym.mod_stmf, 442fcf3ce44SJohn Forte "stmf_free", &err); 443fcf3ce44SJohn Forte if ((void *)emlxs_modsym.stmf_free == NULL) { 444fcf3ce44SJohn Forte cmn_err(CE_WARN, 445fcf3ce44SJohn Forte "?%s: drv/stmf: stmf_free not present", DRIVER_NAME); 446fcf3ce44SJohn Forte goto failed; 447fcf3ce44SJohn Forte } 448*291a2b48SSukumar Swaminathan 449fcf3ce44SJohn Forte err = 0; 450fcf3ce44SJohn Forte /* Check if the stmf stmf_deregister_port_provider is present */ 451fcf3ce44SJohn Forte emlxs_modsym.stmf_deregister_port_provider = 452*291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_stmf, 453fcf3ce44SJohn Forte "stmf_deregister_port_provider", &err); 454fcf3ce44SJohn Forte if ((void *)emlxs_modsym.stmf_deregister_port_provider == NULL) { 455fcf3ce44SJohn Forte cmn_err(CE_WARN, 456fcf3ce44SJohn Forte "?%s: drv/stmf: stmf_deregister_port_provider not present", 457fcf3ce44SJohn Forte DRIVER_NAME); 458fcf3ce44SJohn Forte goto failed; 459fcf3ce44SJohn Forte } 460*291a2b48SSukumar Swaminathan 461fcf3ce44SJohn Forte err = 0; 462fcf3ce44SJohn Forte /* Check if the stmf stmf_register_port_provider is present */ 463fcf3ce44SJohn Forte emlxs_modsym.stmf_register_port_provider = 464*291a2b48SSukumar Swaminathan (int (*)())ddi_modsym(emlxs_modsym.mod_stmf, 465fcf3ce44SJohn Forte "stmf_register_port_provider", &err); 466fcf3ce44SJohn Forte if ((void *)emlxs_modsym.stmf_register_port_provider == NULL) { 467fcf3ce44SJohn Forte cmn_err(CE_WARN, 468fcf3ce44SJohn Forte "?%s: drv/stmf: stmf_register_port_provider not present", 469fcf3ce44SJohn Forte DRIVER_NAME); 470fcf3ce44SJohn Forte goto failed; 471fcf3ce44SJohn Forte } 472fcf3ce44SJohn Forte return (1); 473fcf3ce44SJohn Forte 474fcf3ce44SJohn Forte failed: 475fcf3ce44SJohn Forte emlxs_fct_modclose(); 476fcf3ce44SJohn Forte return (0); 477fcf3ce44SJohn Forte 478*291a2b48SSukumar Swaminathan } /* emlxs_fct_modopen() */ 479fcf3ce44SJohn Forte 480fcf3ce44SJohn Forte 481fcf3ce44SJohn Forte extern void 482fcf3ce44SJohn Forte emlxs_fct_modclose() 483fcf3ce44SJohn Forte { 484fcf3ce44SJohn Forte 485fcf3ce44SJohn Forte if (emlxs_modsym.mod_fct) { 486fcf3ce44SJohn Forte (void) ddi_modclose(emlxs_modsym.mod_fct); 487fcf3ce44SJohn Forte emlxs_modsym.mod_fct = 0; 488fcf3ce44SJohn Forte } 489*291a2b48SSukumar Swaminathan 490fcf3ce44SJohn Forte if (emlxs_modsym.mod_stmf) { 491fcf3ce44SJohn Forte (void) ddi_modclose(emlxs_modsym.mod_stmf); 492fcf3ce44SJohn Forte emlxs_modsym.mod_stmf = 0; 493fcf3ce44SJohn Forte } 494*291a2b48SSukumar Swaminathan 495fcf3ce44SJohn Forte emlxs_modsym.fct_alloc = NULL; 496fcf3ce44SJohn Forte emlxs_modsym.fct_free = NULL; 497fcf3ce44SJohn Forte emlxs_modsym.fct_scsi_task_alloc = NULL; 498fcf3ce44SJohn Forte emlxs_modsym.fct_register_local_port = NULL; 499fcf3ce44SJohn Forte emlxs_modsym.fct_deregister_local_port = NULL; 500fcf3ce44SJohn Forte emlxs_modsym.fct_handle_event = NULL; 501fcf3ce44SJohn Forte emlxs_modsym.fct_ctl = NULL; 502*291a2b48SSukumar Swaminathan emlxs_modsym.fct_queue_cmd_for_termination = NULL; 503fcf3ce44SJohn Forte emlxs_modsym.fct_send_response_done = NULL; 504fcf3ce44SJohn Forte emlxs_modsym.fct_send_cmd_done = NULL; 505fcf3ce44SJohn Forte emlxs_modsym.fct_scsi_data_xfer_done = NULL; 506fcf3ce44SJohn Forte emlxs_modsym.fct_port_shutdown = NULL; 507fcf3ce44SJohn Forte emlxs_modsym.fct_port_initialize = NULL; 508*291a2b48SSukumar Swaminathan emlxs_modsym.fct_cmd_fca_aborted = NULL; 509fcf3ce44SJohn Forte emlxs_modsym.fct_handle_rcvd_flogi = NULL; 510fcf3ce44SJohn Forte 511fcf3ce44SJohn Forte emlxs_modsym.stmf_alloc = NULL; 512fcf3ce44SJohn Forte emlxs_modsym.stmf_free = NULL; 513fcf3ce44SJohn Forte emlxs_modsym.stmf_deregister_port_provider = NULL; 514fcf3ce44SJohn Forte emlxs_modsym.stmf_register_port_provider = NULL; 515fcf3ce44SJohn Forte 516*291a2b48SSukumar Swaminathan } /* emlxs_fct_modclose() */ 517*291a2b48SSukumar Swaminathan 518*291a2b48SSukumar Swaminathan #endif /* MODSYM_SUPPORT */ 519*291a2b48SSukumar Swaminathan 520*291a2b48SSukumar Swaminathan 521*291a2b48SSukumar Swaminathan /* This routine is called to process a FLOGI ELS command that been recieved. */ 522*291a2b48SSukumar Swaminathan static void 523*291a2b48SSukumar Swaminathan emlxs_fct_handle_rcvd_flogi(emlxs_port_t *port) 524*291a2b48SSukumar Swaminathan { 525*291a2b48SSukumar Swaminathan fct_status_t status; 526*291a2b48SSukumar Swaminathan IOCBQ iocbq; 527*291a2b48SSukumar Swaminathan 528*291a2b48SSukumar Swaminathan /* 529*291a2b48SSukumar Swaminathan * If FCT has been notified of a Link Up event, process the 530*291a2b48SSukumar Swaminathan * FLOGI now. Otherwise, defer processing till the Link Up happens. 531*291a2b48SSukumar Swaminathan */ 532*291a2b48SSukumar Swaminathan if (port->fct_flags & FCT_STATE_LINK_UP) { 533*291a2b48SSukumar Swaminathan /* Setup for call to emlxs_els_reply() */ 534*291a2b48SSukumar Swaminathan bzero((uint8_t *)&iocbq, sizeof (IOCBQ)); 535*291a2b48SSukumar Swaminathan iocbq.iocb.un.elsreq.remoteID = port->fx.fx_sid; 536*291a2b48SSukumar Swaminathan iocbq.iocb.un.elsreq.myID = port->fx.fx_did; 537*291a2b48SSukumar Swaminathan iocbq.iocb.ulpContext = port->fx_context; 538*291a2b48SSukumar Swaminathan 539*291a2b48SSukumar Swaminathan status = 540*291a2b48SSukumar Swaminathan MODSYM(fct_handle_rcvd_flogi) (port->fct_port, &port->fx); 541*291a2b48SSukumar Swaminathan 542*291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE 543*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 544*291a2b48SSukumar Swaminathan "fct_handle_rcvd_flogi %p: x%x", port->fct_port, status); 545*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 546*291a2b48SSukumar Swaminathan 547*291a2b48SSukumar Swaminathan if (status == FCT_SUCCESS) { 548*291a2b48SSukumar Swaminathan if (port->fx.fx_op == ELS_OP_ACC) { 549*291a2b48SSukumar Swaminathan (void) emlxs_els_reply(port, &iocbq, 550*291a2b48SSukumar Swaminathan ELS_CMD_ACC, ELS_CMD_FLOGI, 0, 0); 551*291a2b48SSukumar Swaminathan } else { /* ELS_OP_LSRJT */ 552*291a2b48SSukumar Swaminathan 553*291a2b48SSukumar Swaminathan (void) emlxs_els_reply(port, &iocbq, 554*291a2b48SSukumar Swaminathan ELS_CMD_LS_RJT, 555*291a2b48SSukumar Swaminathan ELS_CMD_FLOGI, port->fx.fx_rjt_reason, 556*291a2b48SSukumar Swaminathan port->fx.fx_rjt_expl); 557*291a2b48SSukumar Swaminathan } 558*291a2b48SSukumar Swaminathan } else { 559*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 560*291a2b48SSukumar Swaminathan "FLOGI: sid=%x. fct_handle_rcvd_flogi failed. " 561*291a2b48SSukumar Swaminathan "Rejecting.", 562*291a2b48SSukumar Swaminathan port->fx.fx_sid); 563*291a2b48SSukumar Swaminathan 564*291a2b48SSukumar Swaminathan (void) emlxs_els_reply(port, &iocbq, ELS_CMD_LS_RJT, 565*291a2b48SSukumar Swaminathan ELS_CMD_FLOGI, LSRJT_UNABLE_TPC, 566*291a2b48SSukumar Swaminathan LSEXP_NOTHING_MORE); 567*291a2b48SSukumar Swaminathan } 568*291a2b48SSukumar Swaminathan 569*291a2b48SSukumar Swaminathan port->fx.fx_op = 0; 570*291a2b48SSukumar Swaminathan } 571fcf3ce44SJohn Forte 572*291a2b48SSukumar Swaminathan return; 573fcf3ce44SJohn Forte 574*291a2b48SSukumar Swaminathan } /* emlxs_fct_handle_rcvd_flogi() */ 575fcf3ce44SJohn Forte 576fcf3ce44SJohn Forte 577fcf3ce44SJohn Forte extern void 578fcf3ce44SJohn Forte emlxs_fct_unsol_callback(emlxs_port_t *port, fct_cmd_t *fct_cmd) 579fcf3ce44SJohn Forte { 580fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 581fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 582fcf3ce44SJohn Forte 583fcf3ce44SJohn Forte cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 584fcf3ce44SJohn Forte 585fcf3ce44SJohn Forte if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) { 586fcf3ce44SJohn Forte mutex_enter(&cmd_sbp->mtx); 587*291a2b48SSukumar Swaminathan cmd_sbp->pkt_flags |= PACKET_RETURNED; 588*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx); 589*291a2b48SSukumar Swaminathan 590*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_CMD_POSTED); 591*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 592fcf3ce44SJohn Forte 593fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 594fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 595*291a2b48SSukumar Swaminathan "fct_post_rcvd_cmd:4 %p: portid x%x", fct_cmd, 596*291a2b48SSukumar Swaminathan fct_cmd->cmd_lportid); 597*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 598*291a2b48SSukumar Swaminathan MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0); 599*291a2b48SSukumar Swaminathan return; 600fcf3ce44SJohn Forte } 601*291a2b48SSukumar Swaminathan 602fcf3ce44SJohn Forte /* Online & Link up */ 603*291a2b48SSukumar Swaminathan if (port->fct_flags & FCT_STATE_LINK_UP) { 604*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx); 605*291a2b48SSukumar Swaminathan cmd_sbp->pkt_flags |= PACKET_RETURNED; 606*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx); 607fcf3ce44SJohn Forte 608*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_CMD_POSTED); 609*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 610fcf3ce44SJohn Forte 611fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 612*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 613*291a2b48SSukumar Swaminathan "fct_post_rcvd_cmd:1 %p: portid x%x", fct_cmd, 614*291a2b48SSukumar Swaminathan fct_cmd->cmd_lportid); 615*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 616*291a2b48SSukumar Swaminathan MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0); 617fcf3ce44SJohn Forte } else { /* Online & Link down */ 618*291a2b48SSukumar Swaminathan 619*291a2b48SSukumar Swaminathan /* 620*291a2b48SSukumar Swaminathan * Defer processing of fct_cmd till later (after link up). 621*291a2b48SSukumar Swaminathan * Add buffer to queue tail 622*291a2b48SSukumar Swaminathan */ 623fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 624fcf3ce44SJohn Forte 625fcf3ce44SJohn Forte if (port->fct_wait_tail) { 626fcf3ce44SJohn Forte port->fct_wait_tail->next = cmd_sbp; 627fcf3ce44SJohn Forte } 628fcf3ce44SJohn Forte port->fct_wait_tail = cmd_sbp; 629fcf3ce44SJohn Forte 630fcf3ce44SJohn Forte if (!port->fct_wait_head) { 631fcf3ce44SJohn Forte port->fct_wait_head = cmd_sbp; 632fcf3ce44SJohn Forte } 633*291a2b48SSukumar Swaminathan 634fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 635fcf3ce44SJohn Forte 636*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_CMD_WAITQ); 637*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 638*291a2b48SSukumar Swaminathan 639*291a2b48SSukumar Swaminathan } 640fcf3ce44SJohn Forte return; 641fcf3ce44SJohn Forte 642*291a2b48SSukumar Swaminathan } /* emlxs_fct_unsol_callback() */ 643fcf3ce44SJohn Forte 644fcf3ce44SJohn Forte 645fcf3ce44SJohn Forte /* This is called at port online and offline */ 646fcf3ce44SJohn Forte static void 647fcf3ce44SJohn Forte emlxs_fct_unsol_flush(emlxs_port_t *port) 648fcf3ce44SJohn Forte { 649fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 650fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 651fcf3ce44SJohn Forte emlxs_buf_t *next; 652fcf3ce44SJohn Forte fct_cmd_t *fct_cmd; 653fcf3ce44SJohn Forte 654fcf3ce44SJohn Forte if (!port->fct_port) { 655fcf3ce44SJohn Forte return; 656fcf3ce44SJohn Forte } 657*291a2b48SSukumar Swaminathan 658fcf3ce44SJohn Forte /* Return if nothing to do */ 659fcf3ce44SJohn Forte if (!port->fct_wait_head) { 660fcf3ce44SJohn Forte return; 661fcf3ce44SJohn Forte } 662*291a2b48SSukumar Swaminathan 663fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 664fcf3ce44SJohn Forte cmd_sbp = port->fct_wait_head; 665fcf3ce44SJohn Forte port->fct_wait_head = NULL; 666fcf3ce44SJohn Forte port->fct_wait_tail = NULL; 667fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 668fcf3ce44SJohn Forte 669*291a2b48SSukumar Swaminathan /* First, see if there is an outstanding FLOGI to process */ 670*291a2b48SSukumar Swaminathan if (port->fx.fx_op == ELS_OP_FLOGI) { 671*291a2b48SSukumar Swaminathan if (port->fct_flags & FCT_STATE_LINK_UP) { 672*291a2b48SSukumar Swaminathan /* Process Deferred FLOGI now */ 673*291a2b48SSukumar Swaminathan emlxs_fct_handle_rcvd_flogi(port); 674*291a2b48SSukumar Swaminathan } else { 675*291a2b48SSukumar Swaminathan port->fx.fx_op = 0; /* Flush delayed FLOGI */ 676*291a2b48SSukumar Swaminathan } 677*291a2b48SSukumar Swaminathan } 678*291a2b48SSukumar Swaminathan 679*291a2b48SSukumar Swaminathan /* 680*291a2b48SSukumar Swaminathan * Next process any outstanding ELS commands. It doesn't 681*291a2b48SSukumar Swaminathan * matter if the Link is up or not, always post them to FCT. 682*291a2b48SSukumar Swaminathan */ 683fcf3ce44SJohn Forte while (cmd_sbp) { 684fcf3ce44SJohn Forte next = cmd_sbp->next; 685fcf3ce44SJohn Forte fct_cmd = cmd_sbp->fct_cmd; 686fcf3ce44SJohn Forte 687*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 688*291a2b48SSukumar Swaminathan "Completing fct_cmd: %p", fct_cmd); 689fcf3ce44SJohn Forte 690*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx); 691*291a2b48SSukumar Swaminathan cmd_sbp->pkt_flags |= PACKET_RETURNED; 692*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx); 693fcf3ce44SJohn Forte 694fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 695*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 696*291a2b48SSukumar Swaminathan "fct_post_rcvd_cmd:2 %p: portid x%x", fct_cmd, 697*291a2b48SSukumar Swaminathan fct_cmd->cmd_lportid); 698*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 699*291a2b48SSukumar Swaminathan MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0); 700fcf3ce44SJohn Forte 701fcf3ce44SJohn Forte cmd_sbp = next; 702fcf3ce44SJohn Forte 703fcf3ce44SJohn Forte } /* while() */ 704fcf3ce44SJohn Forte 705fcf3ce44SJohn Forte return; 706fcf3ce44SJohn Forte 707*291a2b48SSukumar Swaminathan } /* emlxs_fct_unsol_flush() */ 708fcf3ce44SJohn Forte 709fcf3ce44SJohn Forte 710fcf3ce44SJohn Forte int 711fcf3ce44SJohn Forte emlxs_is_digit(uint8_t chr) 712fcf3ce44SJohn Forte { 713fcf3ce44SJohn Forte if ((chr >= '0') && (chr <= '9')) { 714fcf3ce44SJohn Forte return (1); 715fcf3ce44SJohn Forte } 716*291a2b48SSukumar Swaminathan 717fcf3ce44SJohn Forte return (0); 718fcf3ce44SJohn Forte 719*291a2b48SSukumar Swaminathan } /* emlxs_is_digit */ 720fcf3ce44SJohn Forte 721fcf3ce44SJohn Forte 722fcf3ce44SJohn Forte /* 723fcf3ce44SJohn Forte * Convert an ASCII decimal numeric string to integer. 724fcf3ce44SJohn Forte * Negation character '-' is not handled. 725fcf3ce44SJohn Forte */ 726fcf3ce44SJohn Forte uint32_t 727fcf3ce44SJohn Forte emlxs_str_atoi(uint8_t *string) 728fcf3ce44SJohn Forte { 729fcf3ce44SJohn Forte uint32_t num = 0; 730fcf3ce44SJohn Forte int i = 0; 731fcf3ce44SJohn Forte 732fcf3ce44SJohn Forte while (string[i]) { 733fcf3ce44SJohn Forte if (!emlxs_is_digit(string[i])) { 734fcf3ce44SJohn Forte return (num); 735fcf3ce44SJohn Forte } 736*291a2b48SSukumar Swaminathan 737fcf3ce44SJohn Forte num = num * 10 + (string[i++] - '0'); 738fcf3ce44SJohn Forte } 739fcf3ce44SJohn Forte 740fcf3ce44SJohn Forte return (num); 741fcf3ce44SJohn Forte 742*291a2b48SSukumar Swaminathan } /* emlxs_str_atoi() */ 743fcf3ce44SJohn Forte 744fcf3ce44SJohn Forte 745fcf3ce44SJohn Forte static void 746fcf3ce44SJohn Forte emlxs_init_fct_bufpool(emlxs_hba_t *hba, char **arrayp, uint32_t cnt) 747fcf3ce44SJohn Forte { 748fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 749fcf3ce44SJohn Forte uint8_t *datap; 750fcf3ce44SJohn Forte int i; 751*291a2b48SSukumar Swaminathan int bck; 752*291a2b48SSukumar Swaminathan int nbufs; 753*291a2b48SSukumar Swaminathan int maxbufs; 754*291a2b48SSukumar Swaminathan int size; 755fcf3ce44SJohn Forte 756fcf3ce44SJohn Forte bzero((uint8_t *)port->dmem_bucket, sizeof (port->dmem_bucket)); 757*291a2b48SSukumar Swaminathan bck = 0; 758fcf3ce44SJohn Forte for (i = 0; i < cnt; i++) { 759fcf3ce44SJohn Forte datap = (uint8_t *)arrayp[i]; 760fcf3ce44SJohn Forte if (datap == 0) 761fcf3ce44SJohn Forte break; 762fcf3ce44SJohn Forte 763fcf3ce44SJohn Forte while (*datap == ' ') /* Skip spaces */ 764fcf3ce44SJohn Forte datap++; 765fcf3ce44SJohn Forte 766*291a2b48SSukumar Swaminathan size = emlxs_str_atoi(datap); 767fcf3ce44SJohn Forte 768fcf3ce44SJohn Forte while ((*datap != ':') && (*datap != 0)) 769fcf3ce44SJohn Forte datap++; 770fcf3ce44SJohn Forte if (*datap == ':') /* Skip past delimeter */ 771fcf3ce44SJohn Forte datap++; 772fcf3ce44SJohn Forte while (*datap == ' ') /* Skip spaces */ 773fcf3ce44SJohn Forte datap++; 774fcf3ce44SJohn Forte 775*291a2b48SSukumar Swaminathan nbufs = emlxs_str_atoi(datap); 776fcf3ce44SJohn Forte 777fcf3ce44SJohn Forte /* Check for a bad entry */ 778*291a2b48SSukumar Swaminathan if (!size || !nbufs) { 779fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 780*291a2b48SSukumar Swaminathan "Bad fct-bufpool entry %d %d", size, nbufs); 781*291a2b48SSukumar Swaminathan 782*291a2b48SSukumar Swaminathan port->dmem_bucket[bck].dmem_buf_size = 0; 783*291a2b48SSukumar Swaminathan port->dmem_bucket[bck].dmem_nbufs = 0; 784*291a2b48SSukumar Swaminathan size = 0; 785*291a2b48SSukumar Swaminathan nbufs = 0; 786*291a2b48SSukumar Swaminathan } 787*291a2b48SSukumar Swaminathan 788*291a2b48SSukumar Swaminathan while (nbufs) { 789*291a2b48SSukumar Swaminathan port->dmem_bucket[bck].dmem_buf_size = size; 790*291a2b48SSukumar Swaminathan port->dmem_bucket[bck].dmem_nbufs = nbufs; 791*291a2b48SSukumar Swaminathan 792*291a2b48SSukumar Swaminathan /* 793*291a2b48SSukumar Swaminathan * We are not going to try to allocate a chunk 794*291a2b48SSukumar Swaminathan * of memory > FCT_DMEM_MAX_BUF_SEGMENT 795*291a2b48SSukumar Swaminathan * to accomidate the buffer pool of the 796*291a2b48SSukumar Swaminathan * requested size. 797*291a2b48SSukumar Swaminathan */ 798*291a2b48SSukumar Swaminathan maxbufs = (FCT_DMEM_MAX_BUF_SEGMENT / size); 799fcf3ce44SJohn Forte 800*291a2b48SSukumar Swaminathan if (nbufs > maxbufs) { 801*291a2b48SSukumar Swaminathan port->dmem_bucket[bck].dmem_nbufs = maxbufs; 802*291a2b48SSukumar Swaminathan nbufs -= maxbufs; 803*291a2b48SSukumar Swaminathan bck++; 804*291a2b48SSukumar Swaminathan if (bck >= FCT_MAX_BUCKETS) 805*291a2b48SSukumar Swaminathan break; 806*291a2b48SSukumar Swaminathan } else { 807*291a2b48SSukumar Swaminathan bck++; 808*291a2b48SSukumar Swaminathan nbufs = 0; 809*291a2b48SSukumar Swaminathan } 810fcf3ce44SJohn Forte } 811*291a2b48SSukumar Swaminathan 812*291a2b48SSukumar Swaminathan if (bck >= FCT_MAX_BUCKETS) { 813*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 814*291a2b48SSukumar Swaminathan "fct-bufpool entry %d %d Exceeds available buckets", 815*291a2b48SSukumar Swaminathan size, nbufs); 816fcf3ce44SJohn Forte break; 817*291a2b48SSukumar Swaminathan } 818fcf3ce44SJohn Forte } 819fcf3ce44SJohn Forte } 820fcf3ce44SJohn Forte 821fcf3ce44SJohn Forte 822fcf3ce44SJohn Forte static void 823fcf3ce44SJohn Forte emlxs_fct_cfg_init(emlxs_hba_t *hba) 824fcf3ce44SJohn Forte { 825fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 826fcf3ce44SJohn Forte char **arrayp; 827fcf3ce44SJohn Forte uint32_t cnt; 828fcf3ce44SJohn Forte char buf[32]; 829fcf3ce44SJohn Forte int status; 830fcf3ce44SJohn Forte 831*291a2b48SSukumar Swaminathan bzero((void *)buf, 32); 832fcf3ce44SJohn Forte cnt = 0; 833fcf3ce44SJohn Forte arrayp = NULL; 834fcf3ce44SJohn Forte 835fcf3ce44SJohn Forte (void) sprintf(buf, "emlxs%d-fct-bufpool", ddi_get_instance(hba->dip)); 836fcf3ce44SJohn Forte status = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, hba->dip, 837fcf3ce44SJohn Forte (DDI_PROP_DONTPASS), buf, &arrayp, &cnt); 838fcf3ce44SJohn Forte 839fcf3ce44SJohn Forte if ((status == DDI_PROP_SUCCESS) && cnt && arrayp) { 840fcf3ce44SJohn Forte emlxs_init_fct_bufpool(hba, arrayp, cnt); 841fcf3ce44SJohn Forte } else { 842fcf3ce44SJohn Forte status = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, hba->dip, 843fcf3ce44SJohn Forte (DDI_PROP_DONTPASS), "fct-bufpool", &arrayp, &cnt); 844fcf3ce44SJohn Forte 845fcf3ce44SJohn Forte if ((status == DDI_PROP_SUCCESS) && cnt && arrayp) { 846fcf3ce44SJohn Forte emlxs_init_fct_bufpool(hba, arrayp, cnt); 847fcf3ce44SJohn Forte } else { 848fcf3ce44SJohn Forte bzero((uint8_t *)port->dmem_bucket, 849fcf3ce44SJohn Forte sizeof (port->dmem_bucket)); 850fcf3ce44SJohn Forte port->dmem_bucket[0].dmem_buf_size = 512; 851fcf3ce44SJohn Forte port->dmem_bucket[0].dmem_nbufs = FCT_BUF_COUNT_512; 852*291a2b48SSukumar Swaminathan port->dmem_bucket[1].dmem_buf_size = (2 * 65536); 853*291a2b48SSukumar Swaminathan port->dmem_bucket[1].dmem_nbufs = FCT_BUF_COUNT_128K; 854fcf3ce44SJohn Forte } 855fcf3ce44SJohn Forte } 856fcf3ce44SJohn Forte 857fcf3ce44SJohn Forte bzero((void *)buf, 32); 858fcf3ce44SJohn Forte cnt = 0; 859fcf3ce44SJohn Forte 860*291a2b48SSukumar Swaminathan /* 861*291a2b48SSukumar Swaminathan * 0 means use HBA throttle for target queue depth, 862*291a2b48SSukumar Swaminathan * non-0 value is the actual target queue depth, 863*291a2b48SSukumar Swaminathan * default is EMLXS_FCT_DFLT_QDEPTH. 864*291a2b48SSukumar Swaminathan */ 865fcf3ce44SJohn Forte (void) sprintf(buf, "emlxs%d-fct-queue-depth", 866fcf3ce44SJohn Forte ddi_get_instance(hba->dip)); 867fcf3ce44SJohn Forte cnt = ddi_prop_get_int(DDI_DEV_T_ANY, hba->dip, 868*291a2b48SSukumar Swaminathan (DDI_PROP_DONTPASS), buf, EMLXS_FCT_DFLT_QDEPTH); 869fcf3ce44SJohn Forte 870*291a2b48SSukumar Swaminathan if ((cnt == DDI_PROP_NOT_FOUND) || (cnt == EMLXS_FCT_DFLT_QDEPTH)) { 871fcf3ce44SJohn Forte cnt = ddi_prop_get_int(DDI_DEV_T_ANY, hba->dip, 872*291a2b48SSukumar Swaminathan (DDI_PROP_DONTPASS), "fct-queue-depth", 873*291a2b48SSukumar Swaminathan EMLXS_FCT_DFLT_QDEPTH); 874fcf3ce44SJohn Forte 875fcf3ce44SJohn Forte if (cnt == DDI_PROP_NOT_FOUND) { 876*291a2b48SSukumar Swaminathan cnt = EMLXS_FCT_DFLT_QDEPTH; 877fcf3ce44SJohn Forte } 878fcf3ce44SJohn Forte } 879*291a2b48SSukumar Swaminathan 880fcf3ce44SJohn Forte port->fct_queue_depth = cnt; 881*291a2b48SSukumar Swaminathan 882*291a2b48SSukumar Swaminathan #ifdef FCT_IO_TRACE 883*291a2b48SSukumar Swaminathan port->iotrace_cnt = 1024; 884*291a2b48SSukumar Swaminathan port->iotrace_index = 0; 885*291a2b48SSukumar Swaminathan if (cnt) 886*291a2b48SSukumar Swaminathan port->iotrace_cnt = (2 * cnt); 887*291a2b48SSukumar Swaminathan port->iotrace = 888*291a2b48SSukumar Swaminathan kmem_zalloc(port->iotrace_cnt * sizeof (emlxs_iotrace_t), 889*291a2b48SSukumar Swaminathan KM_SLEEP); 890*291a2b48SSukumar Swaminathan mutex_init(&port->iotrace_mtx, NULL, MUTEX_DRIVER, 891*291a2b48SSukumar Swaminathan (void *)hba->intr_arg); 892*291a2b48SSukumar Swaminathan emlxs_iotrace = (uint8_t *)port->iotrace; 893*291a2b48SSukumar Swaminathan emlxs_iotrace_cnt = port->iotrace_cnt; 894*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 895*291a2b48SSukumar Swaminathan "IOTRACE: init:%p cnt:%d", emlxs_iotrace, emlxs_iotrace_cnt); 896*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 897*291a2b48SSukumar Swaminathan "FCT_ABORT_SUCCESS:%lx FCT_SUCCESS:%lx", FCT_ABORT_SUCCESS, 898*291a2b48SSukumar Swaminathan FCT_SUCCESS); 899*291a2b48SSukumar Swaminathan #endif /* FCT_IO_TRACE */ 900fcf3ce44SJohn Forte return; 901fcf3ce44SJohn Forte 902*291a2b48SSukumar Swaminathan } /* emlxs_fct_cfg_init() */ 903fcf3ce44SJohn Forte 904fcf3ce44SJohn Forte 905fcf3ce44SJohn Forte extern void 906fcf3ce44SJohn Forte emlxs_fct_init(emlxs_hba_t *hba) 907fcf3ce44SJohn Forte { 908fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 909fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 910fcf3ce44SJohn Forte emlxs_port_t *vport; 911fcf3ce44SJohn Forte uint32_t i; 912fcf3ce44SJohn Forte 913fcf3ce44SJohn Forte if (!hba->tgt_mode) { 914fcf3ce44SJohn Forte return; 915fcf3ce44SJohn Forte } 916fcf3ce44SJohn Forte #ifdef MODSYM_SUPPORT 917fcf3ce44SJohn Forte /* Open COMSTAR */ 918fcf3ce44SJohn Forte (void) emlxs_fct_modopen(); 919*291a2b48SSukumar Swaminathan #endif /* MODSYM_SUPPORT */ 920fcf3ce44SJohn Forte 921fcf3ce44SJohn Forte /* Check if COMSTAR is present */ 922fcf3ce44SJohn Forte if (((void *)MODSYM(stmf_alloc) == NULL) || 923*291a2b48SSukumar Swaminathan ((void *)MODSYM(fct_alloc) == NULL)) { 924fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg, 925fcf3ce44SJohn Forte "Comstar not present. Target mode disabled."); 926fcf3ce44SJohn Forte goto failed; 927fcf3ce44SJohn Forte } 928*291a2b48SSukumar Swaminathan 929fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg, 930fcf3ce44SJohn Forte "Comstar present. Target mode enabled."); 931fcf3ce44SJohn Forte 932fcf3ce44SJohn Forte #ifdef NPIV_SUPPORT 933fcf3ce44SJohn Forte if (cfg[CFG_NPIV_ENABLE].current) { 934fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 935fcf3ce44SJohn Forte "enable-npiv: Not supported in target mode. Disabling."); 936fcf3ce44SJohn Forte 937fcf3ce44SJohn Forte /* Temporary patch to disable npiv */ 938fcf3ce44SJohn Forte cfg[CFG_NPIV_ENABLE].current = 0; 939fcf3ce44SJohn Forte } 940*291a2b48SSukumar Swaminathan #endif /* NPIV_SUPPORT */ 941fcf3ce44SJohn Forte 942fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 943fcf3ce44SJohn Forte if (cfg[CFG_AUTH_ENABLE].current) { 944fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 945fcf3ce44SJohn Forte "enable-auth: Not supported in target mode. Disabling."); 946fcf3ce44SJohn Forte 947fcf3ce44SJohn Forte /* Temporary patch to disable auth */ 948fcf3ce44SJohn Forte cfg[CFG_AUTH_ENABLE].current = 0; 949fcf3ce44SJohn Forte } 950*291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */ 951fcf3ce44SJohn Forte 952fcf3ce44SJohn Forte emlxs_fct_cfg_init(hba); 953fcf3ce44SJohn Forte return; 954fcf3ce44SJohn Forte 955fcf3ce44SJohn Forte failed: 956fcf3ce44SJohn Forte 957fcf3ce44SJohn Forte hba->tgt_mode = 0; 958fcf3ce44SJohn Forte for (i = 0; i < MAX_VPORTS; i++) { 959fcf3ce44SJohn Forte vport = &VPORT(i); 960fcf3ce44SJohn Forte vport->tgt_mode = 0; 961fcf3ce44SJohn Forte vport->fct_flags = 0; 962fcf3ce44SJohn Forte } 963*291a2b48SSukumar Swaminathan 964*291a2b48SSukumar Swaminathan return; 965*291a2b48SSukumar Swaminathan 966*291a2b48SSukumar Swaminathan } /* emlxs_fct_init() */ 967fcf3ce44SJohn Forte 968fcf3ce44SJohn Forte 969fcf3ce44SJohn Forte extern void 970fcf3ce44SJohn Forte emlxs_fct_attach(emlxs_hba_t *hba) 971fcf3ce44SJohn Forte { 972fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 973fcf3ce44SJohn Forte uint32_t vpi; 974fcf3ce44SJohn Forte 975fcf3ce44SJohn Forte if (!hba->tgt_mode) { 976fcf3ce44SJohn Forte return; 977fcf3ce44SJohn Forte } 978*291a2b48SSukumar Swaminathan 979fcf3ce44SJohn Forte /* Bind the physical port */ 980fcf3ce44SJohn Forte emlxs_fct_bind_port(port); 981fcf3ce44SJohn Forte 982fcf3ce44SJohn Forte /* Bind virtual ports */ 983fcf3ce44SJohn Forte if (hba->flag & FC_NPIV_ENABLED) { 984fcf3ce44SJohn Forte for (vpi = 1; vpi < hba->vpi_high; vpi++) { 985fcf3ce44SJohn Forte port = &VPORT(vpi); 986fcf3ce44SJohn Forte 987fcf3ce44SJohn Forte if (!(port->flag & EMLXS_PORT_ENABLE)) { 988fcf3ce44SJohn Forte continue; 989fcf3ce44SJohn Forte } 990*291a2b48SSukumar Swaminathan 991fcf3ce44SJohn Forte emlxs_fct_bind_port(port); 992fcf3ce44SJohn Forte } 993fcf3ce44SJohn Forte } 994*291a2b48SSukumar Swaminathan 995fcf3ce44SJohn Forte return; 996fcf3ce44SJohn Forte 997*291a2b48SSukumar Swaminathan } /* emlxs_fct_attach() */ 998fcf3ce44SJohn Forte 999fcf3ce44SJohn Forte 1000fcf3ce44SJohn Forte extern void 1001fcf3ce44SJohn Forte emlxs_fct_detach(emlxs_hba_t *hba) 1002fcf3ce44SJohn Forte { 1003fcf3ce44SJohn Forte uint32_t i; 1004fcf3ce44SJohn Forte emlxs_port_t *vport; 1005fcf3ce44SJohn Forte 1006fcf3ce44SJohn Forte if (hba->tgt_mode) { 1007fcf3ce44SJohn Forte for (i = 0; i < MAX_VPORTS; i++) { 1008fcf3ce44SJohn Forte vport = &VPORT(i); 1009fcf3ce44SJohn Forte 1010fcf3ce44SJohn Forte if (!vport->tgt_mode) { 1011fcf3ce44SJohn Forte continue; 1012fcf3ce44SJohn Forte } 1013*291a2b48SSukumar Swaminathan 1014fcf3ce44SJohn Forte emlxs_fct_unbind_port(vport); 1015fcf3ce44SJohn Forte vport->tgt_mode = 0; 1016fcf3ce44SJohn Forte } 1017fcf3ce44SJohn Forte 1018fcf3ce44SJohn Forte 1019fcf3ce44SJohn Forte hba->tgt_mode = 0; 1020fcf3ce44SJohn Forte } 1021*291a2b48SSukumar Swaminathan #ifdef FCT_IO_TRACE 1022*291a2b48SSukumar Swaminathan { 1023*291a2b48SSukumar Swaminathan emlxs_port_t *port = &PPORT; 1024*291a2b48SSukumar Swaminathan 1025*291a2b48SSukumar Swaminathan mutex_destroy(&port->iotrace_mtx); 1026*291a2b48SSukumar Swaminathan if (port->iotrace) 1027*291a2b48SSukumar Swaminathan kmem_free(port->iotrace, 1028*291a2b48SSukumar Swaminathan (port->iotrace_cnt * sizeof (emlxs_iotrace_t))); 1029*291a2b48SSukumar Swaminathan port->iotrace = NULL; 1030*291a2b48SSukumar Swaminathan } 1031*291a2b48SSukumar Swaminathan #endif /* FCT_IO_TRACE */ 1032*291a2b48SSukumar Swaminathan 1033fcf3ce44SJohn Forte return; 1034fcf3ce44SJohn Forte 1035*291a2b48SSukumar Swaminathan } /* emlxs_fct_detach() */ 1036fcf3ce44SJohn Forte 1037fcf3ce44SJohn Forte 1038fcf3ce44SJohn Forte extern void 1039fcf3ce44SJohn Forte emlxs_fct_unbind_port(emlxs_port_t *port) 1040fcf3ce44SJohn Forte { 1041fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1042fcf3ce44SJohn Forte char node_name[32]; 1043fcf3ce44SJohn Forte 1044fcf3ce44SJohn Forte if (!port->tgt_mode) { 1045fcf3ce44SJohn Forte return; 1046fcf3ce44SJohn Forte } 1047*291a2b48SSukumar Swaminathan 1048fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 1049fcf3ce44SJohn Forte if (!(port->flag & EMLXS_PORT_BOUND)) { 1050fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1051fcf3ce44SJohn Forte return; 1052fcf3ce44SJohn Forte } 1053*291a2b48SSukumar Swaminathan 1054fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1055fcf3ce44SJohn Forte "emlxs_fct_unbind_port: port=%d", port->vpi); 1056fcf3ce44SJohn Forte 1057fcf3ce44SJohn Forte /* Destroy & flush all port nodes, if they exist */ 1058fcf3ce44SJohn Forte if (port->node_count) { 1059fcf3ce44SJohn Forte (void) emlxs_mb_unreg_rpi(port, 0xffff, 0, 0, 0); 1060fcf3ce44SJohn Forte } 1061*291a2b48SSukumar Swaminathan 1062fcf3ce44SJohn Forte port->flag &= ~EMLXS_PORT_BOUND; 1063fcf3ce44SJohn Forte hba->num_of_ports--; 1064fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1065fcf3ce44SJohn Forte 1066fcf3ce44SJohn Forte if (port->fct_port) { 1067fcf3ce44SJohn Forte emlxs_fct_link_down(port); 1068fcf3ce44SJohn Forte emlxs_fct_unsol_flush(port); 1069fcf3ce44SJohn Forte 1070fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1071fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1072fcf3ce44SJohn Forte "fct_deregister_local_port %p", port->fct_port); 1073*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1074fcf3ce44SJohn Forte MODSYM(fct_deregister_local_port) (port->fct_port); 1075fcf3ce44SJohn Forte 1076fcf3ce44SJohn Forte if (port->fct_port->port_fds) { 1077fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1078fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1079fcf3ce44SJohn Forte "fct_free:3 %p", port->fct_port->port_fds); 1080*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1081fcf3ce44SJohn Forte MODSYM(fct_free) (port->fct_port->port_fds); 1082fcf3ce44SJohn Forte port->fct_port->port_fds = NULL; 1083fcf3ce44SJohn Forte } 1084fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1085fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1086fcf3ce44SJohn Forte "fct_free:4 %p", port->fct_port); 1087*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1088fcf3ce44SJohn Forte MODSYM(fct_free) (port->fct_port); 1089fcf3ce44SJohn Forte port->fct_port = NULL; 1090fcf3ce44SJohn Forte port->fct_flags = 0; 1091fcf3ce44SJohn Forte } 1092*291a2b48SSukumar Swaminathan 1093fcf3ce44SJohn Forte if (port->port_provider) { 1094fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1095fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1096*291a2b48SSukumar Swaminathan "stmf_deregister_port_provider:1 %p", 1097*291a2b48SSukumar Swaminathan port->port_provider); 1098*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1099fcf3ce44SJohn Forte MODSYM(stmf_deregister_port_provider) (port->port_provider); 1100fcf3ce44SJohn Forte 1101fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1102fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1103fcf3ce44SJohn Forte "stmf_free:1 %p", port->port_provider); 1104*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1105fcf3ce44SJohn Forte MODSYM(stmf_free) (port->port_provider); 1106fcf3ce44SJohn Forte port->port_provider = NULL; 1107fcf3ce44SJohn Forte } 1108*291a2b48SSukumar Swaminathan 1109fcf3ce44SJohn Forte if (port->dmem_bucket) { 1110fcf3ce44SJohn Forte emlxs_fct_dmem_fini(port); 1111fcf3ce44SJohn Forte } 1112*291a2b48SSukumar Swaminathan 1113fcf3ce44SJohn Forte (void) sprintf(node_name, "%d,%d:SFCT", hba->ddiinst, port->vpi); 1114fcf3ce44SJohn Forte (void) ddi_remove_minor_node(hba->dip, node_name); 1115fcf3ce44SJohn Forte 1116fcf3ce44SJohn Forte return; 1117fcf3ce44SJohn Forte 1118*291a2b48SSukumar Swaminathan } /* emlxs_fct_unbind_port() */ 1119fcf3ce44SJohn Forte 1120fcf3ce44SJohn Forte 1121fcf3ce44SJohn Forte extern void 1122fcf3ce44SJohn Forte emlxs_fct_bind_port(emlxs_port_t *port) 1123fcf3ce44SJohn Forte { 1124fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1125fcf3ce44SJohn Forte fct_local_port_t *fct_port; 1126fcf3ce44SJohn Forte uint32_t flag = 0; 1127fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 1128fcf3ce44SJohn Forte fct_dbuf_store_t *fds; 1129fcf3ce44SJohn Forte char node_name[32]; 1130fcf3ce44SJohn Forte 1131fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 1132fcf3ce44SJohn Forte 1133fcf3ce44SJohn Forte if (!hba->tgt_mode || !port->tgt_mode) { 1134fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1135fcf3ce44SJohn Forte return; 1136fcf3ce44SJohn Forte } 1137*291a2b48SSukumar Swaminathan 1138fcf3ce44SJohn Forte if (port->flag & EMLXS_PORT_BOUND) { 1139fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1140fcf3ce44SJohn Forte return; 1141fcf3ce44SJohn Forte } 1142*291a2b48SSukumar Swaminathan 1143fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1144fcf3ce44SJohn Forte "emlxs_fct_bind_port: port=%d", port->vpi); 1145fcf3ce44SJohn Forte 1146fcf3ce44SJohn Forte /* Perform generic port initialization */ 1147fcf3ce44SJohn Forte emlxs_port_init(port); 1148fcf3ce44SJohn Forte 1149fcf3ce44SJohn Forte if (port->vpi == 0) { 1150fcf3ce44SJohn Forte (void) sprintf(port->cfd_name, "%s%d", DRIVER_NAME, 1151fcf3ce44SJohn Forte hba->ddiinst); 1152fcf3ce44SJohn Forte } else { 1153fcf3ce44SJohn Forte (void) sprintf(port->cfd_name, "%s%d.%d", DRIVER_NAME, 1154fcf3ce44SJohn Forte hba->ddiinst, port->vpi); 1155fcf3ce44SJohn Forte } 1156fcf3ce44SJohn Forte 1157fcf3ce44SJohn Forte if (emlxs_fct_dmem_init(port) != FCT_SUCCESS) { 1158fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1159fcf3ce44SJohn Forte "emlxs_fct_bind_port: Unable to allocate fct memory."); 1160fcf3ce44SJohn Forte goto failed; 1161fcf3ce44SJohn Forte } 1162fcf3ce44SJohn Forte flag |= 0x00000001; 1163fcf3ce44SJohn Forte 1164*291a2b48SSukumar Swaminathan port->port_provider = 1165*291a2b48SSukumar Swaminathan (stmf_port_provider_t *) 1166fcf3ce44SJohn Forte MODSYM(stmf_alloc) (STMF_STRUCT_PORT_PROVIDER, 0, 0); 1167fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1168fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1169fcf3ce44SJohn Forte "stmf_alloc port_provider %p", port->port_provider); 1170*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1171fcf3ce44SJohn Forte 1172fcf3ce44SJohn Forte if (port->port_provider == NULL) { 1173fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1174*291a2b48SSukumar Swaminathan "emlxs_fct_bind_port: Unable to allocate port provider."); 1175fcf3ce44SJohn Forte goto failed; 1176fcf3ce44SJohn Forte } 1177fcf3ce44SJohn Forte flag |= 0x00000002; 1178fcf3ce44SJohn Forte 1179fcf3ce44SJohn Forte port->port_provider->pp_portif_rev = PORTIF_REV_1; 1180fcf3ce44SJohn Forte port->port_provider->pp_name = port->cfd_name; 1181fcf3ce44SJohn Forte port->port_provider->pp_provider_private = port; 1182fcf3ce44SJohn Forte 1183fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1184fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1185fcf3ce44SJohn Forte "stmf_register_port_provider %p", port->port_provider); 1186*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1187fcf3ce44SJohn Forte /* register port provider with framework */ 1188*291a2b48SSukumar Swaminathan if (MODSYM(stmf_register_port_provider) (port->port_provider) != 1189*291a2b48SSukumar Swaminathan STMF_SUCCESS) { 1190fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1191*291a2b48SSukumar Swaminathan "emlxs_fct_bind_port: Unable to register port provider."); 1192fcf3ce44SJohn Forte goto failed; 1193fcf3ce44SJohn Forte } 1194fcf3ce44SJohn Forte flag |= 0x00000004; 1195fcf3ce44SJohn Forte 1196*291a2b48SSukumar Swaminathan port->fct_port = 1197*291a2b48SSukumar Swaminathan (fct_local_port_t *)MODSYM(fct_alloc) (FCT_STRUCT_LOCAL_PORT, 0, 1198*291a2b48SSukumar Swaminathan 0); 1199fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1200fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1201fcf3ce44SJohn Forte "fct_alloc fct_port %p", port->fct_port); 1202*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1203fcf3ce44SJohn Forte 1204fcf3ce44SJohn Forte if (port->fct_port == NULL) { 1205fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1206fcf3ce44SJohn Forte "emlxs_fct_bind_port: Unable to allocate fct port."); 1207fcf3ce44SJohn Forte goto failed; 1208fcf3ce44SJohn Forte } 1209fcf3ce44SJohn Forte flag |= 0x00000008; 1210fcf3ce44SJohn Forte 1211*291a2b48SSukumar Swaminathan port->fct_port->port_fds = 1212*291a2b48SSukumar Swaminathan (fct_dbuf_store_t *)MODSYM(fct_alloc) (FCT_STRUCT_DBUF_STORE, 0, 1213*291a2b48SSukumar Swaminathan 0); 1214fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1215fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1216fcf3ce44SJohn Forte "fct_alloc port_fds %p", port->fct_port->port_fds); 1217*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1218fcf3ce44SJohn Forte 1219fcf3ce44SJohn Forte if (port->fct_port->port_fds == NULL) { 1220fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1221fcf3ce44SJohn Forte "emlxs_fct_bind_port: Unable to allocate dbuf store."); 1222fcf3ce44SJohn Forte goto failed; 1223fcf3ce44SJohn Forte } 1224fcf3ce44SJohn Forte flag |= 0x00000010; 1225fcf3ce44SJohn Forte 1226fcf3ce44SJohn Forte (void) sprintf(node_name, "%d,%d:SFCT", hba->ddiinst, port->vpi); 1227*291a2b48SSukumar Swaminathan if (ddi_create_minor_node(hba->dip, node_name, S_IFCHR, hba->ddiinst, 1228*291a2b48SSukumar Swaminathan NULL, 0) == DDI_FAILURE) { 1229fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1230fcf3ce44SJohn Forte "Unable to create SFCT device node."); 1231fcf3ce44SJohn Forte goto failed; 1232fcf3ce44SJohn Forte } 1233fcf3ce44SJohn Forte flag |= 0x00000020; 1234fcf3ce44SJohn Forte 1235fcf3ce44SJohn Forte /* Intialize */ 1236fcf3ce44SJohn Forte fct_port = port->fct_port; 1237fcf3ce44SJohn Forte fct_port->port_fca_private = port; 1238fcf3ce44SJohn Forte fct_port->port_fca_abort_timeout = 30 * 1000; /* 30 seconds */ 1239fcf3ce44SJohn Forte 1240fcf3ce44SJohn Forte bcopy((uint8_t *)&port->wwpn, (uint8_t *)fct_port->port_pwwn, 8); 1241fcf3ce44SJohn Forte bcopy((uint8_t *)&port->wwnn, (uint8_t *)fct_port->port_nwwn, 8); 1242fcf3ce44SJohn Forte 1243fcf3ce44SJohn Forte fct_port->port_sym_node_name = port->snn; 1244fcf3ce44SJohn Forte fct_port->port_sym_port_name = port->spn; 1245fcf3ce44SJohn Forte fct_port->port_hard_address = cfg[CFG_ASSIGN_ALPA].current; 1246fcf3ce44SJohn Forte fct_port->port_default_alias = port->cfd_name; 1247fcf3ce44SJohn Forte fct_port->port_pp = port->port_provider; 1248fcf3ce44SJohn Forte fct_port->port_max_logins = hba->max_nodes; 1249fcf3ce44SJohn Forte 1250*291a2b48SSukumar Swaminathan if ((port->fct_queue_depth) && 1251*291a2b48SSukumar Swaminathan (port->fct_queue_depth < hba->io_throttle)) { 1252fcf3ce44SJohn Forte fct_port->port_max_xchges = port->fct_queue_depth; 1253fcf3ce44SJohn Forte } else { 1254fcf3ce44SJohn Forte fct_port->port_max_xchges = hba->io_throttle; 1255fcf3ce44SJohn Forte } 1256fcf3ce44SJohn Forte 1257fcf3ce44SJohn Forte fct_port->port_fca_fcp_cmd_size = sizeof (emlxs_buf_t); 1258fcf3ce44SJohn Forte fct_port->port_fca_rp_private_size = sizeof (uintptr_t); 1259fcf3ce44SJohn Forte fct_port->port_fca_sol_els_private_size = sizeof (emlxs_buf_t); 1260fcf3ce44SJohn Forte fct_port->port_fca_sol_ct_private_size = sizeof (emlxs_buf_t); 1261fcf3ce44SJohn Forte fct_port->port_get_link_info = emlxs_fct_get_link_info; 1262fcf3ce44SJohn Forte fct_port->port_register_remote_port = emlxs_fct_register_remote_port; 1263fcf3ce44SJohn Forte fct_port->port_deregister_remote_port = 1264fcf3ce44SJohn Forte emlxs_fct_deregister_remote_port; 1265fcf3ce44SJohn Forte fct_port->port_send_cmd = emlxs_fct_send_cmd; 1266fcf3ce44SJohn Forte fct_port->port_xfer_scsi_data = emlxs_fct_send_fcp_data; 1267fcf3ce44SJohn Forte fct_port->port_send_cmd_response = emlxs_fct_send_cmd_rsp; 1268fcf3ce44SJohn Forte fct_port->port_abort_cmd = emlxs_fct_abort; 1269fcf3ce44SJohn Forte fct_port->port_ctl = emlxs_fct_ctl; 1270fcf3ce44SJohn Forte fct_port->port_flogi_xchg = emlxs_flogi_xchg; 1271fcf3ce44SJohn Forte fct_port->port_populate_hba_details = emlxs_populate_hba_details; 1272fcf3ce44SJohn Forte 1273fcf3ce44SJohn Forte fds = port->fct_port->port_fds; 1274fcf3ce44SJohn Forte fds->fds_fca_private = port; 1275fcf3ce44SJohn Forte fds->fds_alloc_data_buf = emlxs_fct_dbuf_alloc; 1276fcf3ce44SJohn Forte fds->fds_free_data_buf = emlxs_fct_dbuf_free; 1277fcf3ce44SJohn Forte 1278fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1279fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1280fcf3ce44SJohn Forte "fct_register_local_port %p", fct_port); 1281*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1282fcf3ce44SJohn Forte /* register this local port with the fct module */ 1283fcf3ce44SJohn Forte if (MODSYM(fct_register_local_port) (fct_port) != FCT_SUCCESS) { 1284fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1285fcf3ce44SJohn Forte "emlxs_fct_bind_port: Unable to register fct port."); 1286fcf3ce44SJohn Forte goto failed; 1287fcf3ce44SJohn Forte } 1288*291a2b48SSukumar Swaminathan 1289fcf3ce44SJohn Forte /* Set the bound flag */ 1290fcf3ce44SJohn Forte port->flag |= EMLXS_PORT_BOUND; 1291fcf3ce44SJohn Forte hba->num_of_ports++; 1292fcf3ce44SJohn Forte 1293fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1294fcf3ce44SJohn Forte 1295fcf3ce44SJohn Forte return; 1296fcf3ce44SJohn Forte 1297fcf3ce44SJohn Forte failed: 1298fcf3ce44SJohn Forte 1299fcf3ce44SJohn Forte if (flag & 0x20) { 1300fcf3ce44SJohn Forte (void) ddi_remove_minor_node(hba->dip, node_name); 1301fcf3ce44SJohn Forte } 1302*291a2b48SSukumar Swaminathan 1303fcf3ce44SJohn Forte if (flag & 0x10) { 1304fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1305fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1306fcf3ce44SJohn Forte "fct_free:5 %p", port->fct_port->port_fds); 1307*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1308fcf3ce44SJohn Forte MODSYM(fct_free) (port->fct_port->port_fds); 1309fcf3ce44SJohn Forte port->fct_port->port_fds = NULL; 1310fcf3ce44SJohn Forte } 1311*291a2b48SSukumar Swaminathan 1312fcf3ce44SJohn Forte if (flag & 0x8) { 1313fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1314fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1315fcf3ce44SJohn Forte "fct_free:6 %p", port->fct_port); 1316*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1317fcf3ce44SJohn Forte MODSYM(fct_free) (port->fct_port); 1318fcf3ce44SJohn Forte port->fct_port = NULL; 1319fcf3ce44SJohn Forte port->fct_flags = 0; 1320fcf3ce44SJohn Forte } 1321*291a2b48SSukumar Swaminathan 1322fcf3ce44SJohn Forte if (flag & 0x4) { 1323fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1324fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1325*291a2b48SSukumar Swaminathan "stmf_deregister_port_provider:2 %p", 1326*291a2b48SSukumar Swaminathan port->port_provider); 1327*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1328fcf3ce44SJohn Forte MODSYM(stmf_deregister_port_provider) (port->port_provider); 1329fcf3ce44SJohn Forte } 1330*291a2b48SSukumar Swaminathan 1331fcf3ce44SJohn Forte if (flag & 0x2) { 1332fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1333fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1334fcf3ce44SJohn Forte "stmf_free:2 %p", port->port_provider); 1335*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1336fcf3ce44SJohn Forte MODSYM(stmf_free) (port->port_provider); 1337fcf3ce44SJohn Forte port->port_provider = NULL; 1338fcf3ce44SJohn Forte } 1339*291a2b48SSukumar Swaminathan 1340fcf3ce44SJohn Forte if (flag & 0x1) { 1341fcf3ce44SJohn Forte emlxs_fct_dmem_fini(port); 1342fcf3ce44SJohn Forte } 1343*291a2b48SSukumar Swaminathan 1344fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1345fcf3ce44SJohn Forte "Target mode disabled."); 1346fcf3ce44SJohn Forte 1347fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1348fcf3ce44SJohn Forte 1349fcf3ce44SJohn Forte return; 1350fcf3ce44SJohn Forte 1351*291a2b48SSukumar Swaminathan } /* emlxs_fct_bind_port() */ 1352fcf3ce44SJohn Forte 1353fcf3ce44SJohn Forte 1354fcf3ce44SJohn Forte static void 1355fcf3ce44SJohn Forte emlxs_populate_hba_details(fct_local_port_t *fct_port, 1356fcf3ce44SJohn Forte fct_port_attrs_t *port_attrs) 1357fcf3ce44SJohn Forte { 1358fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 1359fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1360fcf3ce44SJohn Forte emlxs_vpd_t *vpd = &VPD; 1361fcf3ce44SJohn Forte 1362fcf3ce44SJohn Forte (void) strcpy(port_attrs->manufacturer, "Emulex"); 1363fcf3ce44SJohn Forte (void) strcpy(port_attrs->serial_number, vpd->serial_num); 1364fcf3ce44SJohn Forte (void) strcpy(port_attrs->model, hba->model_info.model); 1365fcf3ce44SJohn Forte (void) strcpy(port_attrs->model_description, 1366fcf3ce44SJohn Forte hba->model_info.model_desc); 1367fcf3ce44SJohn Forte (void) sprintf(port_attrs->hardware_version, "%x", vpd->biuRev); 1368fcf3ce44SJohn Forte (void) sprintf(port_attrs->driver_version, "%s (%s)", emlxs_version, 1369fcf3ce44SJohn Forte emlxs_revision); 1370fcf3ce44SJohn Forte (void) strcpy(port_attrs->option_rom_version, vpd->fcode_version); 1371fcf3ce44SJohn Forte (void) sprintf(port_attrs->firmware_version, "%s (%s)", vpd->fw_version, 1372fcf3ce44SJohn Forte vpd->fw_label); 1373fcf3ce44SJohn Forte (void) strcpy(port_attrs->driver_name, DRIVER_NAME); 1374fcf3ce44SJohn Forte port_attrs->vendor_specific_id = 1375fcf3ce44SJohn Forte ((hba->model_info.device_id << 16) | PCI_VENDOR_ID_EMULEX); 1376fcf3ce44SJohn Forte port_attrs->supported_cos = SWAP_DATA32(FC_NS_CLASS3); 1377fcf3ce44SJohn Forte 1378fcf3ce44SJohn Forte port_attrs->max_frame_size = FF_FRAME_SIZE; 1379fcf3ce44SJohn Forte 1380fcf3ce44SJohn Forte if (vpd->link_speed & LMT_10GB_CAPABLE) { 1381*291a2b48SSukumar Swaminathan port_attrs->supported_speed |= PORT_SPEED_10G; 1382fcf3ce44SJohn Forte } 1383fcf3ce44SJohn Forte if (vpd->link_speed & LMT_8GB_CAPABLE) { 1384*291a2b48SSukumar Swaminathan port_attrs->supported_speed |= PORT_SPEED_8G; 1385fcf3ce44SJohn Forte } 1386fcf3ce44SJohn Forte if (vpd->link_speed & LMT_4GB_CAPABLE) { 1387*291a2b48SSukumar Swaminathan port_attrs->supported_speed |= PORT_SPEED_4G; 1388fcf3ce44SJohn Forte } 1389fcf3ce44SJohn Forte if (vpd->link_speed & LMT_2GB_CAPABLE) { 1390*291a2b48SSukumar Swaminathan port_attrs->supported_speed |= PORT_SPEED_2G; 1391fcf3ce44SJohn Forte } 1392fcf3ce44SJohn Forte if (vpd->link_speed & LMT_1GB_CAPABLE) { 1393*291a2b48SSukumar Swaminathan port_attrs->supported_speed |= PORT_SPEED_1G; 1394fcf3ce44SJohn Forte } 1395*291a2b48SSukumar Swaminathan 1396fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1397fcf3ce44SJohn Forte "Port attr: manufacturer = %s", port_attrs->manufacturer); 1398fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1399fcf3ce44SJohn Forte "Port attr: serial_num = %s", port_attrs->serial_number); 1400fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1401fcf3ce44SJohn Forte "Port attr: model = %s", port_attrs->model); 1402fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1403fcf3ce44SJohn Forte "Port attr: model_description = %s", 1404fcf3ce44SJohn Forte port_attrs->model_description); 1405fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1406*291a2b48SSukumar Swaminathan "Port attr: hardware_version = %s", 1407*291a2b48SSukumar Swaminathan port_attrs->hardware_version); 1408fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1409fcf3ce44SJohn Forte "Port attr: driver_version = %s", port_attrs->driver_version); 1410fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1411fcf3ce44SJohn Forte "Port attr: option_rom_version = %s", 1412fcf3ce44SJohn Forte port_attrs->option_rom_version); 1413fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1414*291a2b48SSukumar Swaminathan "Port attr: firmware_version = %s", 1415*291a2b48SSukumar Swaminathan port_attrs->firmware_version); 1416fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1417fcf3ce44SJohn Forte "Port attr: driver_name = %s", port_attrs->driver_name); 1418fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1419fcf3ce44SJohn Forte "Port attr: vendor_specific_id = 0x%x", 1420fcf3ce44SJohn Forte port_attrs->vendor_specific_id); 1421fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1422*291a2b48SSukumar Swaminathan "Port attr: supported_cos = 0x%x", 1423*291a2b48SSukumar Swaminathan port_attrs->supported_cos); 1424fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1425fcf3ce44SJohn Forte "Port attr: supported_speed = 0x%x", 1426fcf3ce44SJohn Forte port_attrs->supported_speed); 1427fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1428*291a2b48SSukumar Swaminathan "Port attr: max_frame_size = 0x%x", 1429*291a2b48SSukumar Swaminathan port_attrs->max_frame_size); 1430fcf3ce44SJohn Forte 1431fcf3ce44SJohn Forte return; 1432fcf3ce44SJohn Forte 1433*291a2b48SSukumar Swaminathan } /* emlxs_populate_hba_details() */ 1434fcf3ce44SJohn Forte 1435fcf3ce44SJohn Forte 1436fcf3ce44SJohn Forte /* ARGSUSED */ 1437fcf3ce44SJohn Forte static void 1438fcf3ce44SJohn Forte emlxs_fct_ctl(fct_local_port_t *fct_port, int cmd, void *arg) 1439fcf3ce44SJohn Forte { 1440fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 1441fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1442fcf3ce44SJohn Forte stmf_change_status_t st; 1443fcf3ce44SJohn Forte 1444fcf3ce44SJohn Forte st.st_completion_status = FCT_SUCCESS; 1445fcf3ce44SJohn Forte st.st_additional_info = NULL; 1446fcf3ce44SJohn Forte 1447fcf3ce44SJohn Forte switch (cmd) { 1448fcf3ce44SJohn Forte case FCT_CMD_PORT_ONLINE: 1449fcf3ce44SJohn Forte /* If the HBA is offline, we cannot bring the tgtport online */ 1450fcf3ce44SJohn Forte if (hba->flag & (FC_OFFLINE_MODE | FC_OFFLINING_MODE)) { 1451fcf3ce44SJohn Forte st.st_completion_status = FCT_FAILURE; 1452fcf3ce44SJohn Forte MODSYM(fct_ctl) (fct_port->port_lport, 1453fcf3ce44SJohn Forte FCT_CMD_PORT_ONLINE_COMPLETE, &st); 1454fcf3ce44SJohn Forte break; 1455fcf3ce44SJohn Forte } 1456*291a2b48SSukumar Swaminathan 1457fcf3ce44SJohn Forte if (port->fct_flags & FCT_STATE_PORT_ONLINE) { 1458fcf3ce44SJohn Forte st.st_completion_status = STMF_ALREADY; 1459fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1460fcf3ce44SJohn Forte "STATE: ONLINE chk"); 1461fcf3ce44SJohn Forte } else { 1462fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1463fcf3ce44SJohn Forte "STATE: OFFLINE --> ONLINE"); 1464fcf3ce44SJohn Forte 1465fcf3ce44SJohn Forte port->fct_flags |= FCT_STATE_NOT_ACKED; 1466fcf3ce44SJohn Forte port->fct_flags |= FCT_STATE_PORT_ONLINE; 1467fcf3ce44SJohn Forte 1468fcf3ce44SJohn Forte if (hba->state <= FC_LINK_DOWN) { 1469fcf3ce44SJohn Forte /* Try to bring the link up */ 1470fcf3ce44SJohn Forte (void) emlxs_reset_link(hba, 1); 1471fcf3ce44SJohn Forte } 1472*291a2b48SSukumar Swaminathan 1473fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1474fcf3ce44SJohn Forte "STATE: ONLINE"); 1475fcf3ce44SJohn Forte } 1476fcf3ce44SJohn Forte 1477fcf3ce44SJohn Forte MODSYM(fct_ctl) (fct_port->port_lport, 1478fcf3ce44SJohn Forte FCT_CMD_PORT_ONLINE_COMPLETE, &st); 1479fcf3ce44SJohn Forte break; 1480fcf3ce44SJohn Forte 1481fcf3ce44SJohn Forte case FCT_CMD_PORT_OFFLINE: 1482fcf3ce44SJohn Forte if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) { 1483fcf3ce44SJohn Forte st.st_completion_status = STMF_ALREADY; 1484fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1485fcf3ce44SJohn Forte "STATE: OFFLINE chk"); 1486fcf3ce44SJohn Forte 1487fcf3ce44SJohn Forte } else { 1488fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1489fcf3ce44SJohn Forte "STATE: ONLINE --> OFFLINE"); 1490fcf3ce44SJohn Forte 1491fcf3ce44SJohn Forte /* Take link down and flush */ 1492fcf3ce44SJohn Forte emlxs_fct_link_down(port); 1493fcf3ce44SJohn Forte emlxs_fct_unsol_flush(port); 1494fcf3ce44SJohn Forte 1495fcf3ce44SJohn Forte /* Declare this port offline now */ 1496fcf3ce44SJohn Forte port->fct_flags |= FCT_STATE_NOT_ACKED; 1497fcf3ce44SJohn Forte port->fct_flags &= ~FCT_STATE_PORT_ONLINE; 1498fcf3ce44SJohn Forte 1499fcf3ce44SJohn Forte /* Take link down and hold it down */ 1500fcf3ce44SJohn Forte (void) emlxs_reset_link(hba, 0); 1501fcf3ce44SJohn Forte 1502fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1503fcf3ce44SJohn Forte "STATE: OFFLINE"); 1504fcf3ce44SJohn Forte } 1505fcf3ce44SJohn Forte 1506fcf3ce44SJohn Forte MODSYM(fct_ctl) (fct_port->port_lport, 1507fcf3ce44SJohn Forte FCT_CMD_PORT_OFFLINE_COMPLETE, &st); 1508fcf3ce44SJohn Forte 1509fcf3ce44SJohn Forte break; 1510fcf3ce44SJohn Forte 1511fcf3ce44SJohn Forte case FCT_ACK_PORT_OFFLINE_COMPLETE: 1512fcf3ce44SJohn Forte port->fct_flags &= ~FCT_STATE_NOT_ACKED; 1513fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1514fcf3ce44SJohn Forte "STATE: OFFLINE ack"); 1515fcf3ce44SJohn Forte break; 1516fcf3ce44SJohn Forte 1517fcf3ce44SJohn Forte case FCT_ACK_PORT_ONLINE_COMPLETE: 1518fcf3ce44SJohn Forte port->fct_flags &= ~FCT_STATE_NOT_ACKED; 1519fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1520fcf3ce44SJohn Forte "STATE: ONLINE ack"); 1521fcf3ce44SJohn Forte break; 1522fcf3ce44SJohn Forte 1523fcf3ce44SJohn Forte } 1524fcf3ce44SJohn Forte 1525fcf3ce44SJohn Forte return; 1526fcf3ce44SJohn Forte 1527*291a2b48SSukumar Swaminathan } /* emlxs_fct_ctl() */ 1528*291a2b48SSukumar Swaminathan 1529fcf3ce44SJohn Forte 1530fcf3ce44SJohn Forte extern int 1531fcf3ce44SJohn Forte emlxs_fct_port_shutdown(emlxs_port_t *port) 1532fcf3ce44SJohn Forte { 1533fcf3ce44SJohn Forte fct_local_port_t *fct_port; 1534fcf3ce44SJohn Forte int i; 1535fcf3ce44SJohn Forte 1536fcf3ce44SJohn Forte fct_port = port->fct_port; 1537fcf3ce44SJohn Forte if (!fct_port) { 1538fcf3ce44SJohn Forte return (0); 1539fcf3ce44SJohn Forte } 1540*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, "fct_port_shutdown"); 1541fcf3ce44SJohn Forte MODSYM(fct_port_shutdown) (fct_port, STMF_RFLAG_STAY_OFFLINED, 1542fcf3ce44SJohn Forte "emlxs shutdown"); 1543fcf3ce44SJohn Forte 1544fcf3ce44SJohn Forte i = 0; 1545fcf3ce44SJohn Forte while (port->fct_flags & FCT_STATE_NOT_ACKED) { 1546fcf3ce44SJohn Forte i++; 1547fcf3ce44SJohn Forte if (i > 300) { /* 30 seconds */ 1548fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1549fcf3ce44SJohn Forte "fct_port_shutdown failed to ACK"); 1550fcf3ce44SJohn Forte break; 1551fcf3ce44SJohn Forte } 1552fcf3ce44SJohn Forte delay(drv_usectohz(100000)); /* 100 msec */ 1553fcf3ce44SJohn Forte } 1554fcf3ce44SJohn Forte return (1); 1555fcf3ce44SJohn Forte } 1556fcf3ce44SJohn Forte 1557fcf3ce44SJohn Forte 1558fcf3ce44SJohn Forte extern int 1559fcf3ce44SJohn Forte emlxs_fct_port_initialize(emlxs_port_t *port) 1560fcf3ce44SJohn Forte { 1561fcf3ce44SJohn Forte fct_local_port_t *fct_port; 1562fcf3ce44SJohn Forte int i; 1563fcf3ce44SJohn Forte 1564fcf3ce44SJohn Forte fct_port = port->fct_port; 1565fcf3ce44SJohn Forte if (!fct_port) { 1566fcf3ce44SJohn Forte return (0); 1567fcf3ce44SJohn Forte } 1568fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1569fcf3ce44SJohn Forte "fct_port_initialize"); 1570fcf3ce44SJohn Forte MODSYM(fct_port_initialize) (fct_port, STMF_RFLAG_STAY_OFFLINED, 1571fcf3ce44SJohn Forte "emlxs initialize"); 1572fcf3ce44SJohn Forte 1573fcf3ce44SJohn Forte i = 0; 1574fcf3ce44SJohn Forte while (port->fct_flags & FCT_STATE_NOT_ACKED) { 1575fcf3ce44SJohn Forte i++; 1576fcf3ce44SJohn Forte if (i > 300) { /* 30 seconds */ 1577fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1578fcf3ce44SJohn Forte "fct_port_initialize failed to ACK"); 1579fcf3ce44SJohn Forte break; 1580fcf3ce44SJohn Forte } 1581fcf3ce44SJohn Forte delay(drv_usectohz(100000)); /* 100 msec */ 1582fcf3ce44SJohn Forte } 1583fcf3ce44SJohn Forte return (1); 1584fcf3ce44SJohn Forte } 1585fcf3ce44SJohn Forte 1586*291a2b48SSukumar Swaminathan 1587fcf3ce44SJohn Forte static fct_status_t 1588fcf3ce44SJohn Forte emlxs_fct_send_cmd(fct_cmd_t *fct_cmd) 1589fcf3ce44SJohn Forte { 1590fcf3ce44SJohn Forte emlxs_port_t *port; 1591fcf3ce44SJohn Forte 1592fcf3ce44SJohn Forte port = (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 1593fcf3ce44SJohn Forte 1594fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1595fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1596fcf3ce44SJohn Forte "emlxs_fct_send_cmd %p: x%x", fct_cmd, fct_cmd->cmd_type); 1597*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1598fcf3ce44SJohn Forte 1599fcf3ce44SJohn Forte switch (fct_cmd->cmd_type) { 1600fcf3ce44SJohn Forte case FCT_CMD_SOL_ELS: 1601fcf3ce44SJohn Forte 1602fcf3ce44SJohn Forte return (emlxs_fct_send_els_cmd(fct_cmd)); 1603fcf3ce44SJohn Forte 1604fcf3ce44SJohn Forte case FCT_CMD_SOL_CT: 1605fcf3ce44SJohn Forte 1606fcf3ce44SJohn Forte return (emlxs_fct_send_ct_cmd(fct_cmd)); 1607fcf3ce44SJohn Forte 1608fcf3ce44SJohn Forte default: 1609fcf3ce44SJohn Forte 1610fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1611fcf3ce44SJohn Forte "emlxs_fct_send_cmd: Invalid cmd type found. type=%x", 1612fcf3ce44SJohn Forte fct_cmd->cmd_type); 1613fcf3ce44SJohn Forte 1614fcf3ce44SJohn Forte return (FCT_FAILURE); 1615fcf3ce44SJohn Forte } 1616fcf3ce44SJohn Forte 1617*291a2b48SSukumar Swaminathan } /* emlxs_fct_send_cmd() */ 1618fcf3ce44SJohn Forte 1619fcf3ce44SJohn Forte 1620fcf3ce44SJohn Forte static fct_status_t 1621fcf3ce44SJohn Forte emlxs_fct_send_cmd_rsp(fct_cmd_t *fct_cmd, uint32_t ioflags) 1622fcf3ce44SJohn Forte { 1623fcf3ce44SJohn Forte emlxs_port_t *port; 1624*291a2b48SSukumar Swaminathan emlxs_buf_t *cmd_sbp; 1625*291a2b48SSukumar Swaminathan fct_status_t rval; 1626fcf3ce44SJohn Forte 1627fcf3ce44SJohn Forte port = (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 1628*291a2b48SSukumar Swaminathan cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 1629fcf3ce44SJohn Forte 1630fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1631fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1632fcf3ce44SJohn Forte "emlxs_fct_send_cmd_rsp %p: x%x", fct_cmd, fct_cmd->cmd_type); 1633*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1634fcf3ce44SJohn Forte 1635fcf3ce44SJohn Forte switch (fct_cmd->cmd_type) { 1636fcf3ce44SJohn Forte case FCT_CMD_FCP_XCHG: 1637fcf3ce44SJohn Forte 1638fcf3ce44SJohn Forte if (ioflags & FCT_IOF_FORCE_FCA_DONE) { 1639fcf3ce44SJohn Forte goto failure; 1640fcf3ce44SJohn Forte } 1641*291a2b48SSukumar Swaminathan 1642*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->fct_mtx); 1643*291a2b48SSukumar Swaminathan rval = emlxs_fct_send_fcp_status(fct_cmd); 1644*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 1645*291a2b48SSukumar Swaminathan return (rval); 1646fcf3ce44SJohn Forte 1647fcf3ce44SJohn Forte case FCT_CMD_RCVD_ELS: 1648fcf3ce44SJohn Forte 1649fcf3ce44SJohn Forte if (ioflags & FCT_IOF_FORCE_FCA_DONE) { 1650fcf3ce44SJohn Forte goto failure; 1651fcf3ce44SJohn Forte } 1652fcf3ce44SJohn Forte 1653*291a2b48SSukumar Swaminathan return (emlxs_fct_send_els_rsp(fct_cmd)); 1654fcf3ce44SJohn Forte 1655fcf3ce44SJohn Forte default: 1656fcf3ce44SJohn Forte 1657fcf3ce44SJohn Forte if (ioflags & FCT_IOF_FORCE_FCA_DONE) { 1658fcf3ce44SJohn Forte fct_cmd->cmd_handle = 0; 1659fcf3ce44SJohn Forte } 1660*291a2b48SSukumar Swaminathan 1661fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1662fcf3ce44SJohn Forte "emlxs_fct_send_cmd_rsp: Invalid cmd type found. type=%x", 1663fcf3ce44SJohn Forte fct_cmd->cmd_type); 1664fcf3ce44SJohn Forte 1665fcf3ce44SJohn Forte return (FCT_FAILURE); 1666fcf3ce44SJohn Forte } 1667fcf3ce44SJohn Forte 1668fcf3ce44SJohn Forte failure: 1669fcf3ce44SJohn Forte 1670fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1671*291a2b48SSukumar Swaminathan "emlxs_fct_send_cmd_rsp: " 1672*291a2b48SSukumar Swaminathan "Unable to handle FCT_IOF_FORCE_FCA_DONE. type=%x", 1673*291a2b48SSukumar Swaminathan fct_cmd->cmd_type); 1674fcf3ce44SJohn Forte 1675fcf3ce44SJohn Forte return (FCT_FAILURE); 1676fcf3ce44SJohn Forte 1677*291a2b48SSukumar Swaminathan } /* emlxs_fct_send_cmd_rsp() */ 1678fcf3ce44SJohn Forte 1679fcf3ce44SJohn Forte 1680fcf3ce44SJohn Forte static fct_status_t 1681fcf3ce44SJohn Forte emlxs_flogi_xchg(struct fct_local_port *fct_port, struct fct_flogi_xchg *fx) 1682fcf3ce44SJohn Forte { 1683fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 1684fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1685fcf3ce44SJohn Forte uint32_t size; 1686fcf3ce44SJohn Forte fc_packet_t *pkt; 1687fcf3ce44SJohn Forte ELS_PKT *els; 1688fcf3ce44SJohn Forte 1689fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1690fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1691fcf3ce44SJohn Forte "emlxs_flogi_xchg: Sending FLOGI: %p", fct_port); 1692fcf3ce44SJohn Forte #else 1693fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1694fcf3ce44SJohn Forte "emlxs_flogi_xchg: Sending FLOGI."); 1695*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1696fcf3ce44SJohn Forte 1697fcf3ce44SJohn Forte if (hba->state <= FC_LINK_DOWN) { 1698fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1699fcf3ce44SJohn Forte "emlxs_flogi_xchg: FLOGI failed. Link down."); 1700fcf3ce44SJohn Forte return (FCT_FAILURE); 1701fcf3ce44SJohn Forte } 1702*291a2b48SSukumar Swaminathan 1703fcf3ce44SJohn Forte size = sizeof (SERV_PARM) + 4; 1704fcf3ce44SJohn Forte 1705fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, size, size, 0, KM_NOSLEEP))) { 1706fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1707fcf3ce44SJohn Forte "emlxs_flogi_xchg: FLOGI failed. Unable allocate packet."); 1708fcf3ce44SJohn Forte return (FCT_FAILURE); 1709fcf3ce44SJohn Forte } 1710*291a2b48SSukumar Swaminathan 1711fcf3ce44SJohn Forte /* Make this a polled IO */ 1712fcf3ce44SJohn Forte pkt->pkt_tran_flags &= ~FC_TRAN_INTR; 1713fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_NO_INTR; 1714fcf3ce44SJohn Forte pkt->pkt_comp = NULL; 1715fcf3ce44SJohn Forte 1716fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE; 1717fcf3ce44SJohn Forte pkt->pkt_timeout = fx->fx_sec_timeout; 1718fcf3ce44SJohn Forte 1719fcf3ce44SJohn Forte /* Build the fc header */ 1720fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(fx->fx_did); 1721*291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.r_ctl = 1722*291a2b48SSukumar Swaminathan R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL; 1723fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.s_id = SWAP_DATA24_LO(fx->fx_sid); 1724fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 1725fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = F_CTL_FIRST_SEQ | F_CTL_SEQ_INITIATIVE; 1726fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 1727fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 1728fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 1729fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xffff; 1730fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xffff; 1731fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 1732fcf3ce44SJohn Forte 1733fcf3ce44SJohn Forte /* Build the command */ 1734*291a2b48SSukumar Swaminathan /* Service paramters will be added automatically later by the driver */ 1735fcf3ce44SJohn Forte els = (ELS_PKT *)pkt->pkt_cmd; 1736fcf3ce44SJohn Forte els->elsCode = 0x04; /* FLOGI */ 1737fcf3ce44SJohn Forte 1738fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 1739fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1740fcf3ce44SJohn Forte "emlxs_flogi_xchg: FLOGI failed. Unable to send packet."); 1741fcf3ce44SJohn Forte 1742fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 1743fcf3ce44SJohn Forte return (FCT_FAILURE); 1744fcf3ce44SJohn Forte } 1745*291a2b48SSukumar Swaminathan 1746fcf3ce44SJohn Forte if ((pkt->pkt_state != FC_PKT_SUCCESS) && 1747fcf3ce44SJohn Forte (pkt->pkt_state != FC_PKT_LS_RJT)) { 1748fcf3ce44SJohn Forte if (pkt->pkt_state == FC_PKT_TIMEOUT) { 1749fcf3ce44SJohn Forte return (FCT_TIMEOUT); 1750fcf3ce44SJohn Forte } else if ((pkt->pkt_state == FC_PKT_LOCAL_RJT) && 1751fcf3ce44SJohn Forte (pkt->pkt_reason == FC_REASON_FCAL_OPN_FAIL)) { 1752fcf3ce44SJohn Forte return (FCT_NOT_FOUND); 1753fcf3ce44SJohn Forte } 1754*291a2b48SSukumar Swaminathan 1755fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1756fcf3ce44SJohn Forte "emlxs_flogi_xchg: FLOGI failed. state=%x reason=%x", 1757fcf3ce44SJohn Forte pkt->pkt_state, pkt->pkt_reason); 1758fcf3ce44SJohn Forte 1759fcf3ce44SJohn Forte return (FCT_FAILURE); 1760fcf3ce44SJohn Forte } 1761*291a2b48SSukumar Swaminathan 1762fcf3ce44SJohn Forte if (pkt->pkt_state == FC_PKT_LS_RJT) { 1763fcf3ce44SJohn Forte fx->fx_op = ELS_OP_LSRJT; 1764fcf3ce44SJohn Forte fx->fx_rjt_reason = pkt->pkt_reason; 1765fcf3ce44SJohn Forte fx->fx_rjt_expl = pkt->pkt_expln; 1766fcf3ce44SJohn Forte } else { /* FC_PKT_SUCCESS */ 1767*291a2b48SSukumar Swaminathan 1768fcf3ce44SJohn Forte fx->fx_op = ELS_OP_ACC; 1769fcf3ce44SJohn Forte fx->fx_sid = Fabric_DID; 1770fcf3ce44SJohn Forte fx->fx_did = port->did; 1771fcf3ce44SJohn Forte 1772*291a2b48SSukumar Swaminathan els = (ELS_PKT *)pkt->pkt_resp; 1773fcf3ce44SJohn Forte bcopy((caddr_t)&els->un.logi.nodeName, 1774fcf3ce44SJohn Forte (caddr_t)fx->fx_nwwn, 8); 1775fcf3ce44SJohn Forte bcopy((caddr_t)&els->un.logi.portName, 1776fcf3ce44SJohn Forte (caddr_t)fx->fx_pwwn, 8); 1777fcf3ce44SJohn Forte fx->fx_fport = els->un.logi.cmn.fPort; 1778fcf3ce44SJohn Forte } 1779fcf3ce44SJohn Forte 1780fcf3ce44SJohn Forte return (FCT_SUCCESS); 1781fcf3ce44SJohn Forte 1782*291a2b48SSukumar Swaminathan } /* emlxs_flogi_xchg() */ 1783fcf3ce44SJohn Forte 1784fcf3ce44SJohn Forte 1785fcf3ce44SJohn Forte /* This is called right after we report that link has come online */ 1786fcf3ce44SJohn Forte static fct_status_t 1787fcf3ce44SJohn Forte emlxs_fct_get_link_info(fct_local_port_t *fct_port, fct_link_info_t *link) 1788fcf3ce44SJohn Forte { 1789fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 1790fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1791fcf3ce44SJohn Forte 1792fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1793fcf3ce44SJohn Forte "emlxs_fct_get_link_info %p", fct_port); 1794fcf3ce44SJohn Forte 1795fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 1796fcf3ce44SJohn Forte 1797fcf3ce44SJohn Forte if (!(port->fct_flags & FCT_STATE_LINK_UP) || 1798*291a2b48SSukumar Swaminathan (hba->state < FC_LINK_UP) || (hba->flag & FC_LOOPBACK_MODE)) { 1799fcf3ce44SJohn Forte link->port_topology = PORT_TOPOLOGY_UNKNOWN; 1800fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_UNKNOWN; 1801fcf3ce44SJohn Forte link->portid = 0; 1802fcf3ce44SJohn Forte 1803fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1804fcf3ce44SJohn Forte 1805fcf3ce44SJohn Forte return (FCT_SUCCESS); 1806fcf3ce44SJohn Forte } 1807*291a2b48SSukumar Swaminathan 1808fcf3ce44SJohn Forte if (hba->topology == TOPOLOGY_LOOP) { 1809fcf3ce44SJohn Forte link->port_topology = PORT_TOPOLOGY_PRIVATE_LOOP; 1810fcf3ce44SJohn Forte } else { 1811fcf3ce44SJohn Forte link->port_topology = PORT_TOPOLOGY_PT_TO_PT; 1812fcf3ce44SJohn Forte } 1813fcf3ce44SJohn Forte 1814fcf3ce44SJohn Forte switch (hba->linkspeed) { 1815fcf3ce44SJohn Forte case LA_1GHZ_LINK: 1816fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_1G; 1817fcf3ce44SJohn Forte break; 1818fcf3ce44SJohn Forte case LA_2GHZ_LINK: 1819fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_2G; 1820fcf3ce44SJohn Forte break; 1821fcf3ce44SJohn Forte case LA_4GHZ_LINK: 1822fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_4G; 1823fcf3ce44SJohn Forte break; 1824fcf3ce44SJohn Forte case LA_8GHZ_LINK: 1825fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_8G; 1826fcf3ce44SJohn Forte break; 1827fcf3ce44SJohn Forte case LA_10GHZ_LINK: 1828fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_10G; 1829fcf3ce44SJohn Forte break; 1830fcf3ce44SJohn Forte default: 1831fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_UNKNOWN; 1832fcf3ce44SJohn Forte break; 1833fcf3ce44SJohn Forte } 1834fcf3ce44SJohn Forte 1835fcf3ce44SJohn Forte link->portid = port->did; 1836fcf3ce44SJohn Forte link->port_no_fct_flogi = 0; 1837fcf3ce44SJohn Forte link->port_fca_flogi_done = 0; 1838fcf3ce44SJohn Forte link->port_fct_flogi_done = 0; 1839fcf3ce44SJohn Forte 1840fcf3ce44SJohn Forte 1841fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1842fcf3ce44SJohn Forte 1843fcf3ce44SJohn Forte return (FCT_SUCCESS); 1844fcf3ce44SJohn Forte 1845*291a2b48SSukumar Swaminathan } /* emlxs_fct_get_link_info() */ 1846fcf3ce44SJohn Forte 1847fcf3ce44SJohn Forte 1848fcf3ce44SJohn Forte static fct_status_t 1849fcf3ce44SJohn Forte emlxs_fct_register_remote_port(fct_local_port_t *fct_port, 1850fcf3ce44SJohn Forte fct_remote_port_t *remote_port, fct_cmd_t *fct_cmd) 1851fcf3ce44SJohn Forte { 1852fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 1853fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1854fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 1855fcf3ce44SJohn Forte clock_t timeout; 1856fcf3ce44SJohn Forte int32_t pkt_ret; 1857fcf3ce44SJohn Forte fct_els_t *els; 1858fcf3ce44SJohn Forte SERV_PARM *sp; 1859fcf3ce44SJohn Forte emlxs_node_t *ndlp; 1860fcf3ce44SJohn Forte SERV_PARM sparam; 1861fcf3ce44SJohn Forte uint32_t *iptr; 1862fcf3ce44SJohn Forte 1863fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1864fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1865fcf3ce44SJohn Forte "emlxs_fct_register_remote_port %p", fct_port); 1866*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1867fcf3ce44SJohn Forte 1868fcf3ce44SJohn Forte if (!(cmd_sbp->pkt_flags & PACKET_VALID)) { 1869fcf3ce44SJohn Forte (void) emlxs_fct_cmd_init(port, fct_cmd); 1870*291a2b48SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 1871fcf3ce44SJohn Forte 1872fcf3ce44SJohn Forte cmd_sbp->ring = &hba->ring[FC_ELS_RING]; 1873fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_ELS_CMD; 1874*291a2b48SSukumar Swaminathan cmd_sbp->did = fct_cmd->cmd_rportid; 1875fcf3ce44SJohn Forte } else { 1876*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->fct_mtx); 1877fcf3ce44SJohn Forte } 1878fcf3ce44SJohn Forte 1879*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_REG_PENDING); 1880*291a2b48SSukumar Swaminathan 1881*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx); 1882fcf3ce44SJohn Forte cmd_sbp->pkt_flags &= ~PACKET_RETURNED; 1883*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx); 1884fcf3ce44SJohn Forte 1885fcf3ce44SJohn Forte if (!cmd_sbp->node) { 1886*291a2b48SSukumar Swaminathan cmd_sbp->node = 1887*291a2b48SSukumar Swaminathan emlxs_node_find_did(port, fct_cmd->cmd_rportid); 1888fcf3ce44SJohn Forte } 1889*291a2b48SSukumar Swaminathan 1890fcf3ce44SJohn Forte if (!cmd_sbp->node) { 1891fcf3ce44SJohn Forte els = (fct_els_t *)fct_cmd->cmd_specific; 1892fcf3ce44SJohn Forte 1893fcf3ce44SJohn Forte /* Check for unsolicited PLOGI */ 1894*291a2b48SSukumar Swaminathan if (cmd_sbp->fct_flags & EMLXS_FCT_PLOGI_RECEIVED) { 1895*291a2b48SSukumar Swaminathan sp = (SERV_PARM *)((caddr_t)els->els_req_payload + 1896*291a2b48SSukumar Swaminathan sizeof (uint32_t)); 1897fcf3ce44SJohn Forte } else { /* Solicited PLOGI */ 1898*291a2b48SSukumar Swaminathan 1899fcf3ce44SJohn Forte sp = &sparam; 1900fcf3ce44SJohn Forte bcopy((caddr_t)&port->sparam, (caddr_t)sp, 1901fcf3ce44SJohn Forte sizeof (SERV_PARM)); 1902fcf3ce44SJohn Forte 1903fcf3ce44SJohn Forte /* 1904*291a2b48SSukumar Swaminathan * Create temporary WWN's from fct_cmd address 1905fcf3ce44SJohn Forte * This simply allows us to get an RPI from the 1906*291a2b48SSukumar Swaminathan * adapter until we get real service params. 1907fcf3ce44SJohn Forte * The PLOGI ACC reply will trigger a REG_LOGIN 1908fcf3ce44SJohn Forte * update later 1909fcf3ce44SJohn Forte */ 1910fcf3ce44SJohn Forte iptr = (uint32_t *)&sp->portName; 1911*291a2b48SSukumar Swaminathan iptr[0] = putPaddrHigh(fct_cmd); 1912*291a2b48SSukumar Swaminathan iptr[1] = putPaddrLow(fct_cmd); 1913*291a2b48SSukumar Swaminathan 1914fcf3ce44SJohn Forte iptr = (uint32_t *)&sp->nodeName; 1915*291a2b48SSukumar Swaminathan iptr[0] = putPaddrHigh(fct_cmd); 1916*291a2b48SSukumar Swaminathan iptr[1] = putPaddrLow(fct_cmd); 1917fcf3ce44SJohn Forte } 1918fcf3ce44SJohn Forte 1919fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1920*291a2b48SSukumar Swaminathan "emlxs_fct_register_remote_port: Register did=%x. (%x,%p)", 1921*291a2b48SSukumar Swaminathan fct_cmd->cmd_rportid, cmd_sbp->fct_state, fct_cmd); 1922fcf3ce44SJohn Forte 1923fcf3ce44SJohn Forte /* Create a new node */ 1924fcf3ce44SJohn Forte if (emlxs_mb_reg_did(port, fct_cmd->cmd_rportid, sp, cmd_sbp, 1925fcf3ce44SJohn Forte NULL, NULL) != 0) { 1926fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 1927*291a2b48SSukumar Swaminathan "emlxs_fct_register_remote_port: " 1928*291a2b48SSukumar Swaminathan "Reg login failed. did=%x", 1929*291a2b48SSukumar Swaminathan fct_cmd->cmd_rportid); 1930fcf3ce44SJohn Forte goto done; 1931fcf3ce44SJohn Forte } 1932*291a2b48SSukumar Swaminathan 1933*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 1934fcf3ce44SJohn Forte 1935fcf3ce44SJohn Forte /* Wait for completion */ 1936fcf3ce44SJohn Forte mutex_enter(&EMLXS_PKT_LOCK); 1937fcf3ce44SJohn Forte timeout = emlxs_timeout(hba, 30); 1938fcf3ce44SJohn Forte pkt_ret = 0; 1939fcf3ce44SJohn Forte while ((pkt_ret != -1) && 1940fcf3ce44SJohn Forte (cmd_sbp->fct_state == EMLXS_FCT_REG_PENDING)) { 1941*291a2b48SSukumar Swaminathan pkt_ret = cv_timedwait(&EMLXS_PKT_CV, &EMLXS_PKT_LOCK, 1942*291a2b48SSukumar Swaminathan timeout); 1943fcf3ce44SJohn Forte } 1944fcf3ce44SJohn Forte mutex_exit(&EMLXS_PKT_LOCK); 1945fcf3ce44SJohn Forte 1946*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->fct_mtx); 1947*291a2b48SSukumar Swaminathan if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT_INP) { 1948*291a2b48SSukumar Swaminathan return (FCT_FAILURE); 1949*291a2b48SSukumar Swaminathan } 1950fcf3ce44SJohn Forte } 1951*291a2b48SSukumar Swaminathan 1952fcf3ce44SJohn Forte done: 1953fcf3ce44SJohn Forte 1954fcf3ce44SJohn Forte ndlp = (emlxs_node_t *)cmd_sbp->node; 1955fcf3ce44SJohn Forte 1956fcf3ce44SJohn Forte if (ndlp) { 1957*291a2b48SSukumar Swaminathan *((emlxs_node_t **)remote_port->rp_fca_private) = 1958*291a2b48SSukumar Swaminathan cmd_sbp->node; 1959fcf3ce44SJohn Forte remote_port->rp_handle = ndlp->nlp_Rpi; 1960fcf3ce44SJohn Forte 1961fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1962fcf3ce44SJohn Forte "emlxs_fct_register_remote_port: did=%x hdl=%x", 1963fcf3ce44SJohn Forte fct_cmd->cmd_rportid, remote_port->rp_handle); 1964fcf3ce44SJohn Forte 1965fcf3ce44SJohn Forte remote_port->rp_handle = ndlp->nlp_Rpi; 1966fcf3ce44SJohn Forte 1967*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx); 1968fcf3ce44SJohn Forte cmd_sbp->pkt_flags |= PACKET_RETURNED; 1969fcf3ce44SJohn Forte mutex_exit(&cmd_sbp->mtx); 1970fcf3ce44SJohn Forte 1971*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED); 1972*291a2b48SSukumar Swaminathan 1973*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 1974fcf3ce44SJohn Forte TGTPORTSTAT.FctPortRegister++; 1975fcf3ce44SJohn Forte return (FCT_SUCCESS); 1976fcf3ce44SJohn Forte } else { 1977fcf3ce44SJohn Forte *((emlxs_node_t **)remote_port->rp_fca_private) = NULL; 1978fcf3ce44SJohn Forte 1979fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1980fcf3ce44SJohn Forte "emlxs_fct_register_remote_port: failed. did=%x hdl=%x", 1981fcf3ce44SJohn Forte fct_cmd->cmd_rportid, remote_port->rp_handle); 1982fcf3ce44SJohn Forte 1983fcf3ce44SJohn Forte remote_port->rp_handle = FCT_HANDLE_NONE; 1984fcf3ce44SJohn Forte 1985*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx); 1986fcf3ce44SJohn Forte cmd_sbp->pkt_flags |= PACKET_RETURNED; 1987fcf3ce44SJohn Forte mutex_exit(&cmd_sbp->mtx); 1988fcf3ce44SJohn Forte 1989*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED); 1990*291a2b48SSukumar Swaminathan 1991*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 1992fcf3ce44SJohn Forte TGTPORTSTAT.FctFailedPortRegister++; 1993fcf3ce44SJohn Forte return (FCT_FAILURE); 1994fcf3ce44SJohn Forte } 1995fcf3ce44SJohn Forte 1996*291a2b48SSukumar Swaminathan } /* emlxs_fct_register_remote_port() */ 1997fcf3ce44SJohn Forte 1998fcf3ce44SJohn Forte 1999fcf3ce44SJohn Forte static fct_status_t 2000fcf3ce44SJohn Forte emlxs_fct_deregister_remote_port(fct_local_port_t *fct_port, 2001fcf3ce44SJohn Forte fct_remote_port_t *remote_port) 2002fcf3ce44SJohn Forte { 2003fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 2004fcf3ce44SJohn Forte 2005fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2006fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2007fcf3ce44SJohn Forte "emlxs_fct_deregister_remote_port: did=%x hdl=%x", 2008fcf3ce44SJohn Forte remote_port->rp_id, remote_port->rp_handle); 2009fcf3ce44SJohn Forte #else 2010fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2011fcf3ce44SJohn Forte "emlxs_fct_deregister_remote_port: did=%x hdl=%x", 2012fcf3ce44SJohn Forte remote_port->rp_id, remote_port->rp_handle); 2013*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2014fcf3ce44SJohn Forte 2015fcf3ce44SJohn Forte *((emlxs_node_t **)remote_port->rp_fca_private) = NULL; 2016fcf3ce44SJohn Forte (void) emlxs_mb_unreg_did(port, remote_port->rp_id, NULL, NULL, NULL); 2017fcf3ce44SJohn Forte 2018fcf3ce44SJohn Forte TGTPORTSTAT.FctPortDeregister++; 2019fcf3ce44SJohn Forte return (FCT_SUCCESS); 2020fcf3ce44SJohn Forte 2021*291a2b48SSukumar Swaminathan } /* emlxs_fct_deregister_remote_port() */ 2022fcf3ce44SJohn Forte 2023fcf3ce44SJohn Forte 2024fcf3ce44SJohn Forte /* ARGSUSED */ 2025fcf3ce44SJohn Forte extern int 2026fcf3ce44SJohn Forte emlxs_fct_handle_unsol_req(emlxs_port_t *port, RING *rp, IOCBQ *iocbq, 2027fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 2028fcf3ce44SJohn Forte { 2029fcf3ce44SJohn Forte IOCB *iocb; 2030fcf3ce44SJohn Forte fct_cmd_t *fct_cmd; 2031fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 2032fcf3ce44SJohn Forte emlxs_fcp_cmd_t *fcp_cmd; 2033fcf3ce44SJohn Forte emlxs_node_t *ndlp; 2034fcf3ce44SJohn Forte uint32_t cnt; 2035fcf3ce44SJohn Forte uint32_t tm; 2036fcf3ce44SJohn Forte scsi_task_t *fct_task; 2037fcf3ce44SJohn Forte uint8_t lun[8]; 2038fcf3ce44SJohn Forte uint32_t sid = 0; 2039fcf3ce44SJohn Forte 2040fcf3ce44SJohn Forte iocb = &iocbq->iocb; 2041fcf3ce44SJohn Forte ndlp = emlxs_node_find_rpi(port, iocb->ulpIoTag); 2042fcf3ce44SJohn Forte if (!ndlp) { 2043fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2044fcf3ce44SJohn Forte "FCP rcvd: Unknown RPI. rpi=%x rxid=%x. Dropping...", 2045fcf3ce44SJohn Forte iocb->ulpIoTag, iocb->ulpContext); 2046fcf3ce44SJohn Forte 2047fcf3ce44SJohn Forte goto dropped; 2048fcf3ce44SJohn Forte } 2049fcf3ce44SJohn Forte sid = ndlp->nlp_DID; 2050fcf3ce44SJohn Forte 2051fcf3ce44SJohn Forte fcp_cmd = (emlxs_fcp_cmd_t *)mp->virt; 2052fcf3ce44SJohn Forte 2053fcf3ce44SJohn Forte if (!port->fct_port) { 2054fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2055fcf3ce44SJohn Forte "FCP rcvd: Target unbound. rpi=%x rxid=%x. Dropping...", 2056fcf3ce44SJohn Forte iocb->ulpIoTag, iocb->ulpContext); 2057fcf3ce44SJohn Forte 2058fcf3ce44SJohn Forte emlxs_send_logo(port, sid); 2059fcf3ce44SJohn Forte 2060fcf3ce44SJohn Forte goto dropped; 2061fcf3ce44SJohn Forte } 2062*291a2b48SSukumar Swaminathan 2063fcf3ce44SJohn Forte if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) { 2064fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2065fcf3ce44SJohn Forte "FCP rcvd: Target offline. rpi=%x rxid=%x. Dropping...", 2066fcf3ce44SJohn Forte iocb->ulpIoTag, iocb->ulpContext); 2067fcf3ce44SJohn Forte 2068fcf3ce44SJohn Forte emlxs_send_logo(port, sid); 2069fcf3ce44SJohn Forte 2070fcf3ce44SJohn Forte goto dropped; 2071fcf3ce44SJohn Forte } 2072*291a2b48SSukumar Swaminathan 2073fcf3ce44SJohn Forte /* Get lun id */ 2074fcf3ce44SJohn Forte bcopy((void *)&fcp_cmd->fcpLunMsl, lun, 8); 2075fcf3ce44SJohn Forte 2076fcf3ce44SJohn Forte if (TGTPORTSTAT.FctOutstandingIO >= port->fct_port->port_max_xchges) { 2077fcf3ce44SJohn Forte TGTPORTSTAT.FctOverQDepth++; 2078fcf3ce44SJohn Forte } 2079*291a2b48SSukumar Swaminathan 2080*291a2b48SSukumar Swaminathan fct_cmd = 2081*291a2b48SSukumar Swaminathan MODSYM(fct_scsi_task_alloc) (port->fct_port, iocb->ulpIoTag, sid, 2082*291a2b48SSukumar Swaminathan lun, 16, 0); 2083fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2084fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2085*291a2b48SSukumar Swaminathan "fct_scsi_task_alloc %p: FCP rcvd: " 2086*291a2b48SSukumar Swaminathan "cmd=%x sid=%x rxid=%x lun=%02x%02x dl=%d", 2087*291a2b48SSukumar Swaminathan fct_cmd, fcp_cmd->fcpCdb[0], sid, iocb->ulpContext, 2088*291a2b48SSukumar Swaminathan lun[0], lun[1], SWAP_DATA32(fcp_cmd->fcpDl)); 2089*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2090fcf3ce44SJohn Forte 2091fcf3ce44SJohn Forte if (fct_cmd == NULL) { 2092fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2093*291a2b48SSukumar Swaminathan "FCP rcvd: sid=%x xid=%x. " 2094*291a2b48SSukumar Swaminathan "Unable to allocate scsi task. Returning QFULL.", 2095*291a2b48SSukumar Swaminathan sid, iocb->ulpContext); 2096fcf3ce44SJohn Forte 2097fcf3ce44SJohn Forte (void) emlxs_fct_send_qfull_reply(port, ndlp, iocb->ulpContext, 2098fcf3ce44SJohn Forte iocb->ulpClass, fcp_cmd); 2099fcf3ce44SJohn Forte 2100fcf3ce44SJohn Forte goto dropped; 2101fcf3ce44SJohn Forte } 2102*291a2b48SSukumar Swaminathan 2103*291a2b48SSukumar Swaminathan cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd); 2104*291a2b48SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 2105*291a2b48SSukumar Swaminathan 2106fcf3ce44SJohn Forte /* Initialize fct_cmd */ 2107fcf3ce44SJohn Forte fct_cmd->cmd_oxid = 0xFFFF; 2108fcf3ce44SJohn Forte fct_cmd->cmd_rxid = iocb->ulpContext; 2109fcf3ce44SJohn Forte fct_cmd->cmd_rportid = sid; 2110fcf3ce44SJohn Forte fct_cmd->cmd_lportid = port->did; 2111fcf3ce44SJohn Forte fct_cmd->cmd_rp_handle = iocb->ulpIoTag; /* RPI */ 2112fcf3ce44SJohn Forte fct_cmd->cmd_port = port->fct_port; 2113fcf3ce44SJohn Forte 2114*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_FCP_CMD_RECEIVED); 2115fcf3ce44SJohn Forte 2116*291a2b48SSukumar Swaminathan /* Initialize cmd_sbp */ 2117*291a2b48SSukumar Swaminathan cmd_sbp->did = sid; 2118fcf3ce44SJohn Forte cmd_sbp->ring = rp; 2119fcf3ce44SJohn Forte cmd_sbp->class = iocb->ulpClass; 2120fcf3ce44SJohn Forte cmd_sbp->lun = (lun[0] << 8) | lun[1]; 2121fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_FCP_CMD; 2122fcf3ce44SJohn Forte 2123fcf3ce44SJohn Forte fct_task = (scsi_task_t *)fct_cmd->cmd_specific; 2124fcf3ce44SJohn Forte 2125fcf3ce44SJohn Forte /* Set task_flags */ 2126*291a2b48SSukumar Swaminathan switch (fcp_cmd->fcpCntl1) { 2127*291a2b48SSukumar Swaminathan case SIMPLE_Q: 2128fcf3ce44SJohn Forte fct_task->task_flags = TF_ATTR_SIMPLE_QUEUE; 2129fcf3ce44SJohn Forte break; 2130fcf3ce44SJohn Forte 2131*291a2b48SSukumar Swaminathan case HEAD_OF_Q: 2132fcf3ce44SJohn Forte fct_task->task_flags = TF_ATTR_HEAD_OF_QUEUE; 2133fcf3ce44SJohn Forte break; 2134fcf3ce44SJohn Forte 2135*291a2b48SSukumar Swaminathan case ORDERED_Q: 2136fcf3ce44SJohn Forte fct_task->task_flags = TF_ATTR_ORDERED_QUEUE; 2137fcf3ce44SJohn Forte break; 2138fcf3ce44SJohn Forte 2139*291a2b48SSukumar Swaminathan case ACA_Q: 2140fcf3ce44SJohn Forte fct_task->task_flags = TF_ATTR_ACA; 2141fcf3ce44SJohn Forte break; 2142fcf3ce44SJohn Forte 2143*291a2b48SSukumar Swaminathan case UNTAGGED: 2144fcf3ce44SJohn Forte fct_task->task_flags = TF_ATTR_UNTAGGED; 2145fcf3ce44SJohn Forte break; 2146fcf3ce44SJohn Forte } 2147fcf3ce44SJohn Forte 2148fcf3ce44SJohn Forte cnt = SWAP_DATA32(fcp_cmd->fcpDl); 2149fcf3ce44SJohn Forte switch (fcp_cmd->fcpCntl3) { 2150fcf3ce44SJohn Forte case 0: 2151fcf3ce44SJohn Forte TGTPORTSTAT.FctIOCmdCnt++; 2152fcf3ce44SJohn Forte break; 2153fcf3ce44SJohn Forte case 1: 2154fcf3ce44SJohn Forte emlxs_bump_wrioctr(port, cnt); 2155fcf3ce44SJohn Forte TGTPORTSTAT.FctWriteBytes += cnt; 2156fcf3ce44SJohn Forte fct_task->task_flags |= TF_WRITE_DATA; 2157fcf3ce44SJohn Forte break; 2158fcf3ce44SJohn Forte 2159fcf3ce44SJohn Forte case 2: 2160fcf3ce44SJohn Forte emlxs_bump_rdioctr(port, cnt); 2161fcf3ce44SJohn Forte TGTPORTSTAT.FctReadBytes += cnt; 2162fcf3ce44SJohn Forte fct_task->task_flags |= TF_READ_DATA; 2163fcf3ce44SJohn Forte break; 2164fcf3ce44SJohn Forte } 2165fcf3ce44SJohn Forte 2166fcf3ce44SJohn Forte fct_task->task_priority = 0; 2167fcf3ce44SJohn Forte 2168fcf3ce44SJohn Forte /* task_mgmt_function */ 2169fcf3ce44SJohn Forte tm = fcp_cmd->fcpCntl2; 2170fcf3ce44SJohn Forte if (tm) { 2171fcf3ce44SJohn Forte if (tm & BIT_1) { 2172fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_ABORT_TASK_SET; 2173fcf3ce44SJohn Forte } else if (tm & BIT_2) { 2174fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_CLEAR_TASK_SET; 2175fcf3ce44SJohn Forte } else if (tm & BIT_4) { 2176fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_LUN_RESET; 2177fcf3ce44SJohn Forte } else if (tm & BIT_5) { 2178fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_TARGET_COLD_RESET; 2179fcf3ce44SJohn Forte } else if (tm & BIT_6) { 2180fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_CLEAR_ACA; 2181fcf3ce44SJohn Forte } else { 2182fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_ABORT_TASK; 2183fcf3ce44SJohn Forte } 2184fcf3ce44SJohn Forte } 2185*291a2b48SSukumar Swaminathan 2186fcf3ce44SJohn Forte /* Parallel buffers support - future */ 2187fcf3ce44SJohn Forte fct_task->task_max_nbufs = 1; 2188fcf3ce44SJohn Forte 2189fcf3ce44SJohn Forte fct_task->task_additional_flags = 0; 2190fcf3ce44SJohn Forte fct_task->task_cur_nbufs = 0; 2191fcf3ce44SJohn Forte fct_task->task_csn_size = 8; 2192fcf3ce44SJohn Forte fct_task->task_cmd_seq_no = 0; 2193fcf3ce44SJohn Forte fct_task->task_expected_xfer_length = cnt; 2194fcf3ce44SJohn Forte bcopy((void *)&fcp_cmd->fcpCdb, fct_task->task_cdb, 16); 2195fcf3ce44SJohn Forte 2196fcf3ce44SJohn Forte TGTPORTSTAT.FctCmdReceived++; 2197fcf3ce44SJohn Forte 2198fcf3ce44SJohn Forte TGTPORTSTAT.FctOutstandingIO++; 2199fcf3ce44SJohn Forte 2200*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx); 2201fcf3ce44SJohn Forte cmd_sbp->pkt_flags |= PACKET_RETURNED; 2202fcf3ce44SJohn Forte mutex_exit(&cmd_sbp->mtx); 2203fcf3ce44SJohn Forte 2204*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_CMD_POSTED); 2205*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 2206*291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE 2207*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2208*291a2b48SSukumar Swaminathan "fct_post_rcvd_cmd:3 %p: portid x%x", fct_cmd, 2209*291a2b48SSukumar Swaminathan fct_cmd->cmd_lportid); 2210*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2211*291a2b48SSukumar Swaminathan MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0); 2212fcf3ce44SJohn Forte 2213fcf3ce44SJohn Forte return (0); 2214fcf3ce44SJohn Forte 2215fcf3ce44SJohn Forte dropped: 2216fcf3ce44SJohn Forte 2217fcf3ce44SJohn Forte TGTPORTSTAT.FctRcvDropped++; 2218fcf3ce44SJohn Forte return (1); 2219fcf3ce44SJohn Forte 2220*291a2b48SSukumar Swaminathan } /* emlxs_fct_handle_unsol_req() */ 2221fcf3ce44SJohn Forte 2222fcf3ce44SJohn Forte 2223fcf3ce44SJohn Forte /* ARGSUSED */ 2224fcf3ce44SJohn Forte static fct_status_t 2225fcf3ce44SJohn Forte emlxs_fct_send_fcp_data(fct_cmd_t *fct_cmd, stmf_data_buf_t *dbuf, 2226fcf3ce44SJohn Forte uint32_t ioflags) 2227fcf3ce44SJohn Forte { 2228fcf3ce44SJohn Forte emlxs_port_t *port = 2229fcf3ce44SJohn Forte (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 2230fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 2231fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 2232*291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE 2233fcf3ce44SJohn Forte scsi_task_t *fct_task; 2234*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2235fcf3ce44SJohn Forte uint32_t did; 2236fcf3ce44SJohn Forte IOCBQ *iocbq; 2237fcf3ce44SJohn Forte emlxs_node_t *ndlp; 2238fcf3ce44SJohn Forte 2239fcf3ce44SJohn Forte cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 2240*291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE 2241fcf3ce44SJohn Forte fct_task = (scsi_task_t *)fct_cmd->cmd_specific; 2242*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2243fcf3ce44SJohn Forte ndlp = *(emlxs_node_t **)fct_cmd->cmd_rp->rp_fca_private; 2244fcf3ce44SJohn Forte did = fct_cmd->cmd_rportid; 2245fcf3ce44SJohn Forte 2246fcf3ce44SJohn Forte /* Initialize cmd_sbp */ 2247*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->fct_mtx); 2248*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_SEND_FCP_DATA); 2249fcf3ce44SJohn Forte 2250fcf3ce44SJohn Forte /* 2251*291a2b48SSukumar Swaminathan * This check is here because task_max_nbufs is set to 1. 2252*291a2b48SSukumar Swaminathan * This ensures we will only have 1 outstanding call 2253*291a2b48SSukumar Swaminathan * to this routine. 2254fcf3ce44SJohn Forte */ 2255fcf3ce44SJohn Forte if (!(cmd_sbp->pkt_flags & PACKET_RETURNED)) { 2256fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 2257fcf3ce44SJohn Forte "Adapter Busy. Processing IO. did=0x%x", did); 2258*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED); 2259*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 2260fcf3ce44SJohn Forte return (FCT_BUSY); 2261fcf3ce44SJohn Forte } 2262*291a2b48SSukumar Swaminathan 2263*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx); 2264fcf3ce44SJohn Forte cmd_sbp->pkt_flags &= ~PACKET_RETURNED; 2265*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx); 2266*291a2b48SSukumar Swaminathan 2267fcf3ce44SJohn Forte cmd_sbp->node = ndlp; 2268fcf3ce44SJohn Forte cmd_sbp->fct_buf = dbuf; 2269fcf3ce44SJohn Forte 2270fcf3ce44SJohn Forte iocbq = &cmd_sbp->iocbq; 2271fcf3ce44SJohn Forte 2272fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2273fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2274fcf3ce44SJohn Forte "emlxs_fct_send_fcp_data %p: flgs=%x ioflags=%x dl=%d,%d,%d", 2275fcf3ce44SJohn Forte fct_cmd, dbuf->db_flags, ioflags, fct_task->task_cmd_xfer_length, 2276fcf3ce44SJohn Forte fct_task->task_nbytes_transferred, dbuf->db_data_size); 2277*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2278fcf3ce44SJohn Forte 2279*291a2b48SSukumar Swaminathan if (emlxs_sli_prep_fct_iocb(port, cmd_sbp) != IOERR_SUCCESS) { 2280*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx); 2281fcf3ce44SJohn Forte cmd_sbp->pkt_flags |= PACKET_RETURNED; 2282fcf3ce44SJohn Forte mutex_exit(&cmd_sbp->mtx); 2283fcf3ce44SJohn Forte 2284*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED); 2285*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 2286fcf3ce44SJohn Forte return (FCT_BUSY); 2287fcf3ce44SJohn Forte } 2288*291a2b48SSukumar Swaminathan 2289fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_FCP_DATA; 2290*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_DATA_PENDING); 2291fcf3ce44SJohn Forte 2292fcf3ce44SJohn Forte if (dbuf->db_flags & DB_SEND_STATUS_GOOD) { 2293fcf3ce44SJohn Forte cmd_sbp->fct_flags |= EMLXS_FCT_SEND_STATUS; 2294fcf3ce44SJohn Forte } 2295fcf3ce44SJohn Forte 2296fcf3ce44SJohn Forte if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) { 2297fcf3ce44SJohn Forte emlxs_fct_dbuf_dma_sync(dbuf, DDI_DMA_SYNC_FORDEV); 2298fcf3ce44SJohn Forte } 2299*291a2b48SSukumar Swaminathan 2300*291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP; 2301*291a2b48SSukumar Swaminathan emlxs_sli_issue_iocb_cmd(hba, cmd_sbp->ring, iocbq); 2302*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 2303fcf3ce44SJohn Forte 2304fcf3ce44SJohn Forte return (FCT_SUCCESS); 2305fcf3ce44SJohn Forte 2306*291a2b48SSukumar Swaminathan } /* emlxs_fct_send_fcp_data() */ 2307fcf3ce44SJohn Forte 2308fcf3ce44SJohn Forte 2309fcf3ce44SJohn Forte static fct_status_t 2310fcf3ce44SJohn Forte emlxs_fct_send_fcp_status(fct_cmd_t *fct_cmd) 2311fcf3ce44SJohn Forte { 2312fcf3ce44SJohn Forte emlxs_port_t *port = 2313fcf3ce44SJohn Forte (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 2314fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 2315fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 2316fcf3ce44SJohn Forte scsi_task_t *fct_task; 2317fcf3ce44SJohn Forte fc_packet_t *pkt; 2318fcf3ce44SJohn Forte uint32_t did; 2319fcf3ce44SJohn Forte emlxs_fcp_rsp *fcp_rsp; 2320fcf3ce44SJohn Forte uint32_t size; 2321fcf3ce44SJohn Forte emlxs_node_t *ndlp; 2322fcf3ce44SJohn Forte 2323fcf3ce44SJohn Forte fct_task = (scsi_task_t *)fct_cmd->cmd_specific; 2324fcf3ce44SJohn Forte ndlp = *(emlxs_node_t **)fct_cmd->cmd_rp->rp_fca_private; 2325fcf3ce44SJohn Forte did = fct_cmd->cmd_rportid; 2326fcf3ce44SJohn Forte 2327fcf3ce44SJohn Forte /* Initialize cmd_sbp */ 2328fcf3ce44SJohn Forte cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 2329fcf3ce44SJohn Forte 2330*291a2b48SSukumar Swaminathan /* &cmd_sbp->fct_mtx should be already held */ 2331*291a2b48SSukumar Swaminathan 2332*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_SEND_FCP_STATUS); 2333*291a2b48SSukumar Swaminathan 2334fcf3ce44SJohn Forte mutex_enter(&cmd_sbp->mtx); 2335fcf3ce44SJohn Forte cmd_sbp->pkt_flags &= ~PACKET_RETURNED; 2336*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx); 2337fcf3ce44SJohn Forte cmd_sbp->node = ndlp; 2338fcf3ce44SJohn Forte 2339fcf3ce44SJohn Forte size = 24; 2340fcf3ce44SJohn Forte if (fct_task->task_sense_length) { 2341fcf3ce44SJohn Forte size += fct_task->task_sense_length; 2342fcf3ce44SJohn Forte } 2343fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2344fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2345fcf3ce44SJohn Forte "emlxs_fct_send_fcp_status %p: stat=%d resid=%d size=%d rx=%x", 2346fcf3ce44SJohn Forte fct_cmd, fct_task->task_scsi_status, 2347fcf3ce44SJohn Forte fct_task->task_resid, size, fct_cmd->cmd_rxid); 2348*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2349fcf3ce44SJohn Forte 2350fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, size, 0, 0, KM_NOSLEEP))) { 2351fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 2352fcf3ce44SJohn Forte "emlxs_fct_send_fcp_status: Unable to allocate packet."); 2353fcf3ce44SJohn Forte 2354*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx); 2355fcf3ce44SJohn Forte cmd_sbp->pkt_flags |= PACKET_RETURNED; 2356fcf3ce44SJohn Forte mutex_exit(&cmd_sbp->mtx); 2357fcf3ce44SJohn Forte 2358*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED); 2359*291a2b48SSukumar Swaminathan return (FCT_BUSY); 2360fcf3ce44SJohn Forte } 2361*291a2b48SSukumar Swaminathan 2362fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_FCP_STATUS; 2363fcf3ce44SJohn Forte 2364fcf3ce44SJohn Forte (void) emlxs_fct_pkt_init(port, fct_cmd, pkt); 2365*291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = pkt; 2366fcf3ce44SJohn Forte 2367fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND; 2368fcf3ce44SJohn Forte pkt->pkt_timeout = 2369fcf3ce44SJohn Forte ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov); 2370fcf3ce44SJohn Forte pkt->pkt_comp = emlxs_fct_pkt_comp; 2371fcf3ce44SJohn Forte 2372fcf3ce44SJohn Forte /* Build the fc header */ 2373fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(did); 2374fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_STATUS; 2375fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.s_id = SWAP_DATA24_LO(port->did); 2376fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_SCSI_FCP; 2377fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = 2378fcf3ce44SJohn Forte F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ; 2379fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 2380fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 2381fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 2382fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = fct_cmd->cmd_oxid; 2383fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = fct_cmd->cmd_rxid; 2384fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 2385fcf3ce44SJohn Forte 2386fcf3ce44SJohn Forte /* Build the status payload */ 2387fcf3ce44SJohn Forte fcp_rsp = (emlxs_fcp_rsp *)pkt->pkt_cmd; 2388fcf3ce44SJohn Forte 2389fcf3ce44SJohn Forte if (fct_task->task_resid) { 2390fcf3ce44SJohn Forte if (fct_task->task_status_ctrl & TASK_SCTRL_OVER) { 2391fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiResidOver++; 2392fcf3ce44SJohn Forte fcp_rsp->rspStatus2 |= RESID_OVER; 2393fcf3ce44SJohn Forte fcp_rsp->rspResId = SWAP_DATA32(fct_task->task_resid); 2394fcf3ce44SJohn Forte 2395fcf3ce44SJohn Forte } else if (fct_task->task_status_ctrl & TASK_SCTRL_UNDER) { 2396fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiResidUnder++; 2397fcf3ce44SJohn Forte fcp_rsp->rspStatus2 |= RESID_UNDER; 2398fcf3ce44SJohn Forte fcp_rsp->rspResId = SWAP_DATA32(fct_task->task_resid); 2399fcf3ce44SJohn Forte 2400fcf3ce44SJohn Forte } 2401fcf3ce44SJohn Forte } 2402*291a2b48SSukumar Swaminathan 2403fcf3ce44SJohn Forte if (fct_task->task_scsi_status) { 2404fcf3ce44SJohn Forte if (fct_task->task_scsi_status == SCSI_STAT_QUE_FULL) { 2405fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiQfullErr++; 2406fcf3ce44SJohn Forte } else { 2407fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiStatusErr++; 2408fcf3ce44SJohn Forte } 2409fcf3ce44SJohn Forte 2410*291a2b48SSukumar Swaminathan /* Make sure residual reported on non-SCSI_GOOD READ status */ 2411fcf3ce44SJohn Forte if ((fct_task->task_flags & TF_READ_DATA) && 2412fcf3ce44SJohn Forte (fcp_rsp->rspResId == 0)) { 2413fcf3ce44SJohn Forte fcp_rsp->rspStatus2 |= RESID_UNDER; 2414*291a2b48SSukumar Swaminathan fcp_rsp->rspResId = 2415*291a2b48SSukumar Swaminathan fct_task->task_expected_xfer_length; 2416fcf3ce44SJohn Forte } 2417fcf3ce44SJohn Forte } 2418*291a2b48SSukumar Swaminathan 2419*291a2b48SSukumar Swaminathan 2420fcf3ce44SJohn Forte if (fct_task->task_sense_length) { 2421fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiSenseErr++; 2422fcf3ce44SJohn Forte fcp_rsp->rspStatus2 |= SNS_LEN_VALID; 2423fcf3ce44SJohn Forte fcp_rsp->rspSnsLen = SWAP_DATA32(fct_task->task_sense_length); 2424fcf3ce44SJohn Forte 2425fcf3ce44SJohn Forte bcopy((uint8_t *)fct_task->task_sense_data, 2426*291a2b48SSukumar Swaminathan (uint8_t *)&fcp_rsp->rspInfo0, 2427*291a2b48SSukumar Swaminathan fct_task->task_sense_length); 2428fcf3ce44SJohn Forte } 2429*291a2b48SSukumar Swaminathan 2430fcf3ce44SJohn Forte fcp_rsp->rspStatus3 = fct_task->task_scsi_status; 2431fcf3ce44SJohn Forte fcp_rsp->rspRspLen = 0; 2432*291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP; 2433fcf3ce44SJohn Forte 2434fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 2435fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 2436fcf3ce44SJohn Forte "emlxs_fct_send_fcp_status: Unable to send packet."); 2437fcf3ce44SJohn Forte 2438fcf3ce44SJohn Forte if (cmd_sbp->pkt_flags & PACKET_VALID) { 2439fcf3ce44SJohn Forte mutex_enter(&cmd_sbp->mtx); 2440fcf3ce44SJohn Forte cmd_sbp->fct_pkt = NULL; 2441fcf3ce44SJohn Forte cmd_sbp->pkt_flags |= PACKET_RETURNED; 2442*291a2b48SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP; 2443fcf3ce44SJohn Forte mutex_exit(&cmd_sbp->mtx); 2444fcf3ce44SJohn Forte } 2445*291a2b48SSukumar Swaminathan 2446fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 2447*291a2b48SSukumar Swaminathan 2448*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED); 2449*291a2b48SSukumar Swaminathan return (FCT_BUSY); 2450fcf3ce44SJohn Forte } 2451*291a2b48SSukumar Swaminathan 2452*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_STATUS_PENDING); 2453fcf3ce44SJohn Forte return (FCT_SUCCESS); 2454fcf3ce44SJohn Forte 2455*291a2b48SSukumar Swaminathan } /* emlxs_fct_send_fcp_status() */ 2456fcf3ce44SJohn Forte 2457fcf3ce44SJohn Forte 2458fcf3ce44SJohn Forte static fct_status_t 2459*291a2b48SSukumar Swaminathan emlxs_fct_send_qfull_reply(emlxs_port_t *port, emlxs_node_t *ndlp, 2460*291a2b48SSukumar Swaminathan uint16_t xid, uint32_t class, emlxs_fcp_cmd_t *fcp_cmd) 2461fcf3ce44SJohn Forte { 2462fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 2463fcf3ce44SJohn Forte emlxs_buf_t *sbp; 2464fcf3ce44SJohn Forte fc_packet_t *pkt; 2465fcf3ce44SJohn Forte emlxs_fcp_rsp *fcp_rsp; 2466fcf3ce44SJohn Forte uint32_t size; 2467fcf3ce44SJohn Forte RING *rp = &hba->ring[FC_FCP_RING]; 2468fcf3ce44SJohn Forte uint8_t lun[8]; 2469fcf3ce44SJohn Forte 2470fcf3ce44SJohn Forte bcopy((void *)&fcp_cmd->fcpLunMsl, lun, 8); 2471fcf3ce44SJohn Forte size = 24; 2472fcf3ce44SJohn Forte 2473fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, size, 0, 0, KM_NOSLEEP))) { 2474fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 2475fcf3ce44SJohn Forte "emlxs_fct_send_qfull_reply: Unable to allocate packet."); 2476fcf3ce44SJohn Forte return (FCT_FAILURE); 2477fcf3ce44SJohn Forte } 2478*291a2b48SSukumar Swaminathan 2479*291a2b48SSukumar Swaminathan 2480fcf3ce44SJohn Forte sbp = PKT2PRIV(pkt); 2481fcf3ce44SJohn Forte sbp->node = ndlp; 2482fcf3ce44SJohn Forte sbp->ring = rp; 2483fcf3ce44SJohn Forte sbp->did = ndlp->nlp_DID; 2484fcf3ce44SJohn Forte sbp->lun = (lun[0] << 8) | lun[1]; 2485fcf3ce44SJohn Forte sbp->class = class; 2486fcf3ce44SJohn Forte 2487fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND; 2488fcf3ce44SJohn Forte pkt->pkt_timeout = 2489fcf3ce44SJohn Forte ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov); 2490fcf3ce44SJohn Forte 2491fcf3ce44SJohn Forte /* Build the fc header */ 2492fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(ndlp->nlp_DID); 2493fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_STATUS; 2494fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.s_id = SWAP_DATA24_LO(port->did); 2495fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_SCSI_FCP; 2496fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = 2497fcf3ce44SJohn Forte F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ; 2498fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 2499fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 2500fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 2501fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xFFFF; 2502fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = xid; 2503fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 2504fcf3ce44SJohn Forte 2505fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 2506fcf3ce44SJohn Forte "emlxs_fct_send_qfull_reply: Sending QFULL: x%x lun x%x: %d %d", 2507fcf3ce44SJohn Forte xid, sbp->lun, TGTPORTSTAT.FctOutstandingIO, 2508fcf3ce44SJohn Forte port->fct_port->port_max_xchges); 2509fcf3ce44SJohn Forte 2510fcf3ce44SJohn Forte /* Build the status payload */ 2511fcf3ce44SJohn Forte fcp_rsp = (emlxs_fcp_rsp *)pkt->pkt_cmd; 2512fcf3ce44SJohn Forte 2513fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiQfullErr++; 2514fcf3ce44SJohn Forte fcp_rsp->rspStatus3 = SCSI_STAT_QUE_FULL; 2515fcf3ce44SJohn Forte fcp_rsp->rspStatus2 |= RESID_UNDER; 2516fcf3ce44SJohn Forte fcp_rsp->rspResId = SWAP_DATA32(fcp_cmd->fcpDl); 2517fcf3ce44SJohn Forte 2518fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 2519fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 2520fcf3ce44SJohn Forte "emlxs_fct_send_qfull_reply: Unable to send packet."); 2521fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 2522fcf3ce44SJohn Forte return (FCT_FAILURE); 2523fcf3ce44SJohn Forte } 2524fcf3ce44SJohn Forte 2525*291a2b48SSukumar Swaminathan return (FCT_SUCCESS); 2526fcf3ce44SJohn Forte 2527*291a2b48SSukumar Swaminathan } /* emlxs_fct_send_qfull_reply() */ 2528fcf3ce44SJohn Forte 2529fcf3ce44SJohn Forte 2530fcf3ce44SJohn Forte /* ARGSUSED */ 2531fcf3ce44SJohn Forte extern int 2532fcf3ce44SJohn Forte emlxs_fct_handle_fcp_event(emlxs_hba_t *hba, RING *rp, IOCBQ *iocbq) 2533fcf3ce44SJohn Forte { 2534fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2535fcf3ce44SJohn Forte IOCB *iocb; 2536fcf3ce44SJohn Forte emlxs_buf_t *sbp; 2537fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 2538fcf3ce44SJohn Forte uint32_t status; 2539fcf3ce44SJohn Forte fct_cmd_t *fct_cmd; 2540fcf3ce44SJohn Forte stmf_data_buf_t *dbuf; 2541*291a2b48SSukumar Swaminathan uint8_t term_io; 2542fcf3ce44SJohn Forte scsi_task_t *fct_task; 2543*291a2b48SSukumar Swaminathan fc_packet_t *pkt; 2544fcf3ce44SJohn Forte 2545fcf3ce44SJohn Forte iocb = &iocbq->iocb; 2546fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)iocbq->sbp; 2547fcf3ce44SJohn Forte 2548fcf3ce44SJohn Forte 2549fcf3ce44SJohn Forte TGTPORTSTAT.FctEvent++; 2550fcf3ce44SJohn Forte 2551fcf3ce44SJohn Forte if (!sbp) { 2552fcf3ce44SJohn Forte /* completion with missing xmit command */ 2553fcf3ce44SJohn Forte TGTPORTSTAT.FctStray++; 2554fcf3ce44SJohn Forte 2555fcf3ce44SJohn Forte /* emlxs_stray_fcp_completion_msg */ 2556fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2557*291a2b48SSukumar Swaminathan "FCP event cmd=%x status=%x error=%x iotag=%x", 2558*291a2b48SSukumar Swaminathan iocb->ulpCommand, iocb->ulpStatus, 2559*291a2b48SSukumar Swaminathan iocb->un.grsp.perr.statLocalError, iocb->ulpIoTag); 2560fcf3ce44SJohn Forte 2561fcf3ce44SJohn Forte return (1); 2562fcf3ce44SJohn Forte } 2563*291a2b48SSukumar Swaminathan 2564fcf3ce44SJohn Forte TGTPORTSTAT.FctCompleted++; 2565fcf3ce44SJohn Forte 2566fcf3ce44SJohn Forte port = sbp->iocbq.port; 2567fcf3ce44SJohn Forte fct_cmd = sbp->fct_cmd; 2568fcf3ce44SJohn Forte status = iocb->ulpStatus; 2569fcf3ce44SJohn Forte 2570fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2571fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2572*291a2b48SSukumar Swaminathan "emlxs_fct_handle_fcp_event: %p: cmd=%x status=%x", fct_cmd, 2573*291a2b48SSukumar Swaminathan iocb->ulpCommand, status); 2574*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2575fcf3ce44SJohn Forte 2576fcf3ce44SJohn Forte if (fct_cmd == NULL) { 2577*291a2b48SSukumar Swaminathan /* For driver generated QFULL response */ 2578*291a2b48SSukumar Swaminathan if (((iocb->ulpCommand == CMD_FCP_TRSP_CX) || 2579*291a2b48SSukumar Swaminathan (iocb->ulpCommand == CMD_FCP_TRSP64_CX)) && sbp->pkt) { 2580fcf3ce44SJohn Forte emlxs_pkt_free(sbp->pkt); 2581fcf3ce44SJohn Forte } 2582fcf3ce44SJohn Forte return (0); 2583fcf3ce44SJohn Forte } 2584*291a2b48SSukumar Swaminathan 2585*291a2b48SSukumar Swaminathan /* Validate fct_cmd */ 2586*291a2b48SSukumar Swaminathan if ((fct_cmd->cmd_oxid == 0) && (fct_cmd->cmd_rxid == 0)) { 2587*291a2b48SSukumar Swaminathan pkt = NULL; 2588*291a2b48SSukumar Swaminathan goto done; 2589*291a2b48SSukumar Swaminathan } 2590*291a2b48SSukumar Swaminathan 2591fcf3ce44SJohn Forte cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 2592*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->fct_mtx); 2593*291a2b48SSukumar Swaminathan 2594*291a2b48SSukumar Swaminathan pkt = cmd_sbp->fct_pkt; 2595fcf3ce44SJohn Forte dbuf = sbp->fct_buf; 2596fcf3ce44SJohn Forte 2597*291a2b48SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP; 2598*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_REQ_COMPLETE); 2599fcf3ce44SJohn Forte 2600*291a2b48SSukumar Swaminathan fct_cmd->cmd_comp_status = FCT_SUCCESS; 2601*291a2b48SSukumar Swaminathan 2602*291a2b48SSukumar Swaminathan term_io = 0; 2603*291a2b48SSukumar Swaminathan if (status) { 2604*291a2b48SSukumar Swaminathan fct_cmd->cmd_comp_status = FCT_FAILURE; 2605*291a2b48SSukumar Swaminathan term_io = 1; 2606*291a2b48SSukumar Swaminathan } 2607*291a2b48SSukumar Swaminathan 2608*291a2b48SSukumar Swaminathan if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT_INP) { 2609*291a2b48SSukumar Swaminathan 2610*291a2b48SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--; 2611*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_ABORT_DONE); 2612*291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2613*291a2b48SSukumar Swaminathan (void) emlxs_fct_cmd_uninit(port, fct_cmd); 2614*291a2b48SSukumar Swaminathan MODSYM(fct_cmd_fca_aborted) (fct_cmd, 2615*291a2b48SSukumar Swaminathan FCT_ABORT_SUCCESS, FCT_IOF_FCA_DONE); 2616*291a2b48SSukumar Swaminathan goto done; 2617*291a2b48SSukumar Swaminathan } 2618fcf3ce44SJohn Forte 2619*291a2b48SSukumar Swaminathan if (term_io) { 2620fcf3ce44SJohn Forte /* 2621*291a2b48SSukumar Swaminathan * The error indicates this IO should be terminated 2622*291a2b48SSukumar Swaminathan * immediately. 2623fcf3ce44SJohn Forte */ 2624*291a2b48SSukumar Swaminathan 2625*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx); 2626*291a2b48SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_SEND_STATUS; 2627*291a2b48SSukumar Swaminathan cmd_sbp->pkt_flags |= PACKET_RETURNED; 2628*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx); 2629*291a2b48SSukumar Swaminathan 2630*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED); 2631*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 2632*291a2b48SSukumar Swaminathan 2633*291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE 2634*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2635*291a2b48SSukumar Swaminathan "fct_queue_cmd_for_termination:1 %p: x%x", 2636*291a2b48SSukumar Swaminathan fct_cmd, fct_cmd->cmd_comp_status); 2637*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2638*291a2b48SSukumar Swaminathan MODSYM(fct_queue_cmd_for_termination) (fct_cmd, 2639*291a2b48SSukumar Swaminathan FCT_ABTS_RECEIVED); 2640*291a2b48SSukumar Swaminathan goto done; 2641*291a2b48SSukumar Swaminathan } 2642*291a2b48SSukumar Swaminathan 2643*291a2b48SSukumar Swaminathan switch (iocb->ulpCommand) { 2644*291a2b48SSukumar Swaminathan 2645*291a2b48SSukumar Swaminathan /* 2646*291a2b48SSukumar Swaminathan * FCP Data completion 2647*291a2b48SSukumar Swaminathan */ 2648fcf3ce44SJohn Forte case CMD_FCP_TSEND_CX: 2649fcf3ce44SJohn Forte case CMD_FCP_TSEND64_CX: 2650fcf3ce44SJohn Forte case CMD_FCP_TRECEIVE_CX: 2651fcf3ce44SJohn Forte case CMD_FCP_TRECEIVE64_CX: 2652fcf3ce44SJohn Forte 2653fcf3ce44SJohn Forte mutex_enter(&cmd_sbp->mtx); 2654fcf3ce44SJohn Forte cmd_sbp->pkt_flags &= ~PACKET_RETURNED; 2655*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx); 2656fcf3ce44SJohn Forte 2657fcf3ce44SJohn Forte if (status == 0) { 2658fcf3ce44SJohn Forte if (dbuf->db_flags & DB_DIRECTION_FROM_RPORT) { 2659fcf3ce44SJohn Forte emlxs_fct_dbuf_dma_sync(dbuf, 2660fcf3ce44SJohn Forte DDI_DMA_SYNC_FORCPU); 2661fcf3ce44SJohn Forte } 2662*291a2b48SSukumar Swaminathan 2663fcf3ce44SJohn Forte if (cmd_sbp->fct_flags & EMLXS_FCT_SEND_STATUS) { 2664fcf3ce44SJohn Forte dbuf->db_flags |= DB_STATUS_GOOD_SENT; 2665fcf3ce44SJohn Forte 2666*291a2b48SSukumar Swaminathan fct_task = 2667*291a2b48SSukumar Swaminathan (scsi_task_t *)fct_cmd->cmd_specific; 2668fcf3ce44SJohn Forte fct_task->task_scsi_status = 0; 2669fcf3ce44SJohn Forte 2670fcf3ce44SJohn Forte (void) emlxs_fct_send_fcp_status(fct_cmd); 2671*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 2672fcf3ce44SJohn Forte 2673fcf3ce44SJohn Forte break; 2674fcf3ce44SJohn Forte } 2675fcf3ce44SJohn Forte } 2676*291a2b48SSukumar Swaminathan 2677fcf3ce44SJohn Forte cmd_sbp->fct_flags &= ~EMLXS_FCT_SEND_STATUS; 2678*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx); 2679fcf3ce44SJohn Forte cmd_sbp->pkt_flags |= PACKET_RETURNED; 2680fcf3ce44SJohn Forte mutex_exit(&cmd_sbp->mtx); 2681fcf3ce44SJohn Forte 2682*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED); 2683*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 2684fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2685fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2686fcf3ce44SJohn Forte "fct_scsi_data_xfer_done:1 %p %p", fct_cmd, dbuf); 2687*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2688fcf3ce44SJohn Forte MODSYM(fct_scsi_data_xfer_done) (fct_cmd, dbuf, 0); 2689fcf3ce44SJohn Forte 2690fcf3ce44SJohn Forte break; 2691fcf3ce44SJohn Forte 2692fcf3ce44SJohn Forte /* FCP Status completion */ 2693fcf3ce44SJohn Forte case CMD_FCP_TRSP_CX: 2694fcf3ce44SJohn Forte case CMD_FCP_TRSP64_CX: 2695fcf3ce44SJohn Forte 2696fcf3ce44SJohn Forte mutex_enter(&cmd_sbp->mtx); 2697fcf3ce44SJohn Forte cmd_sbp->pkt_flags &= ~PACKET_RETURNED; 2698*291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = NULL; 2699*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx); 2700fcf3ce44SJohn Forte 2701*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_IO_DONE); 2702fcf3ce44SJohn Forte 2703*291a2b48SSukumar Swaminathan if (cmd_sbp->fct_flags & EMLXS_FCT_SEND_STATUS) { 2704fcf3ce44SJohn Forte 2705*291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2706fcf3ce44SJohn Forte (void) emlxs_fct_cmd_uninit(port, fct_cmd); 2707fcf3ce44SJohn Forte TGTPORTSTAT.FctOutstandingIO--; 2708fcf3ce44SJohn Forte 2709fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2710fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2711fcf3ce44SJohn Forte "fct_scsi_data_xfer_done:2 %p %p", 2712fcf3ce44SJohn Forte fct_cmd, cmd_sbp->fct_buf); 2713*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2714fcf3ce44SJohn Forte MODSYM(fct_scsi_data_xfer_done) (fct_cmd, 2715fcf3ce44SJohn Forte cmd_sbp->fct_buf, FCT_IOF_FCA_DONE); 2716fcf3ce44SJohn Forte } else { 2717*291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2718fcf3ce44SJohn Forte (void) emlxs_fct_cmd_uninit(port, fct_cmd); 2719fcf3ce44SJohn Forte TGTPORTSTAT.FctOutstandingIO--; 2720fcf3ce44SJohn Forte 2721fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2722fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2723fcf3ce44SJohn Forte "fct_send_response_done:1 %p: x%x", 2724fcf3ce44SJohn Forte fct_cmd, fct_cmd->cmd_comp_status); 2725*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2726fcf3ce44SJohn Forte MODSYM(fct_send_response_done) (fct_cmd, 2727fcf3ce44SJohn Forte fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE); 2728fcf3ce44SJohn Forte } 2729fcf3ce44SJohn Forte break; 2730fcf3ce44SJohn Forte 2731fcf3ce44SJohn Forte default: 2732fcf3ce44SJohn Forte 2733*291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = NULL; 2734*291a2b48SSukumar Swaminathan 2735fcf3ce44SJohn Forte TGTPORTSTAT.FctStray++; 2736fcf3ce44SJohn Forte 2737fcf3ce44SJohn Forte TGTPORTSTAT.FctCompleted--; 2738*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 2739fcf3ce44SJohn Forte 2740fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2741fcf3ce44SJohn Forte "Invalid iocb: cmd=0x%x", iocb->ulpCommand); 2742fcf3ce44SJohn Forte 2743*291a2b48SSukumar Swaminathan if (pkt) { 2744*291a2b48SSukumar Swaminathan emlxs_pkt_complete(sbp, status, 2745*291a2b48SSukumar Swaminathan iocb->un.grsp.perr.statLocalError, 1); 2746*291a2b48SSukumar Swaminathan } 2747fcf3ce44SJohn Forte 2748fcf3ce44SJohn Forte } /* switch(iocb->ulpCommand) */ 2749fcf3ce44SJohn Forte 2750fcf3ce44SJohn Forte 2751*291a2b48SSukumar Swaminathan done: 2752*291a2b48SSukumar Swaminathan if (pkt) { 2753*291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt); 2754*291a2b48SSukumar Swaminathan } 2755*291a2b48SSukumar Swaminathan 2756fcf3ce44SJohn Forte if (status == IOSTAT_SUCCESS) { 2757fcf3ce44SJohn Forte TGTPORTSTAT.FctCmplGood++; 2758fcf3ce44SJohn Forte } else { 2759fcf3ce44SJohn Forte TGTPORTSTAT.FctCmplError++; 2760fcf3ce44SJohn Forte } 2761fcf3ce44SJohn Forte 2762fcf3ce44SJohn Forte return (0); 2763fcf3ce44SJohn Forte 2764*291a2b48SSukumar Swaminathan } /* emlxs_fct_handle_fcp_event() */ 2765*291a2b48SSukumar Swaminathan 2766*291a2b48SSukumar Swaminathan 2767*291a2b48SSukumar Swaminathan /* ARGSUSED */ 2768*291a2b48SSukumar Swaminathan extern int 2769*291a2b48SSukumar Swaminathan emlxs_fct_handle_abort(emlxs_hba_t *hba, RING *rp, IOCBQ *iocbq) 2770*291a2b48SSukumar Swaminathan { 2771*291a2b48SSukumar Swaminathan emlxs_port_t *port = &PPORT; 2772*291a2b48SSukumar Swaminathan IOCB *iocb; 2773*291a2b48SSukumar Swaminathan emlxs_buf_t *sbp; 2774*291a2b48SSukumar Swaminathan fc_packet_t *pkt; 2775*291a2b48SSukumar Swaminathan 2776*291a2b48SSukumar Swaminathan iocb = &iocbq->iocb; 2777*291a2b48SSukumar Swaminathan sbp = (emlxs_buf_t *)iocbq->sbp; 2778*291a2b48SSukumar Swaminathan 2779*291a2b48SSukumar Swaminathan TGTPORTSTAT.FctEvent++; 2780*291a2b48SSukumar Swaminathan 2781*291a2b48SSukumar Swaminathan if (!sbp) { 2782*291a2b48SSukumar Swaminathan /* completion with missing xmit command */ 2783*291a2b48SSukumar Swaminathan TGTPORTSTAT.FctStray++; 2784*291a2b48SSukumar Swaminathan 2785*291a2b48SSukumar Swaminathan /* emlxs_stray_fcp_completion_msg */ 2786*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2787*291a2b48SSukumar Swaminathan "ABORT event cmd=%x status=%x error=%x iotag=%x", 2788*291a2b48SSukumar Swaminathan iocb->ulpCommand, iocb->ulpStatus, 2789*291a2b48SSukumar Swaminathan iocb->un.grsp.perr.statLocalError, iocb->ulpIoTag); 2790*291a2b48SSukumar Swaminathan 2791*291a2b48SSukumar Swaminathan return (1); 2792*291a2b48SSukumar Swaminathan } 2793*291a2b48SSukumar Swaminathan 2794*291a2b48SSukumar Swaminathan pkt = PRIV2PKT(sbp); 2795*291a2b48SSukumar Swaminathan 2796*291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE 2797*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2798*291a2b48SSukumar Swaminathan "emlxs_fct_handle_abort: %p: xri=%x status=%x", iocb->ulpContext, 2799*291a2b48SSukumar Swaminathan iocb->ulpCommand, iocb->ulpStatus); 2800*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2801*291a2b48SSukumar Swaminathan 2802*291a2b48SSukumar Swaminathan 2803*291a2b48SSukumar Swaminathan if (pkt) { 2804*291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt); 2805*291a2b48SSukumar Swaminathan } 2806*291a2b48SSukumar Swaminathan return (0); 2807fcf3ce44SJohn Forte 2808*291a2b48SSukumar Swaminathan } /* emlxs_fct_handle_abort() */ 2809fcf3ce44SJohn Forte 2810fcf3ce44SJohn Forte 2811fcf3ce44SJohn Forte extern int 2812fcf3ce44SJohn Forte emlxs_fct_handle_unsol_els(emlxs_port_t *port, RING *rp, IOCBQ *iocbq, 2813fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 2814fcf3ce44SJohn Forte { 2815fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 2816fcf3ce44SJohn Forte IOCB *iocb; 2817fcf3ce44SJohn Forte uint32_t cmd_code; 2818fcf3ce44SJohn Forte fct_cmd_t *fct_cmd; 2819fcf3ce44SJohn Forte fct_els_t *els; 2820fcf3ce44SJohn Forte uint32_t sid; 2821fcf3ce44SJohn Forte uint32_t padding; 2822fcf3ce44SJohn Forte uint8_t *bp; 2823fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 2824fcf3ce44SJohn Forte uint32_t rval; 2825fcf3ce44SJohn Forte 2826fcf3ce44SJohn Forte HBASTATS.ElsCmdReceived++; 2827fcf3ce44SJohn Forte 2828fcf3ce44SJohn Forte bp = mp->virt; 2829fcf3ce44SJohn Forte cmd_code = (*(uint32_t *)bp) & ELS_CMD_MASK; 2830fcf3ce44SJohn Forte iocb = &iocbq->iocb; 2831fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 2832fcf3ce44SJohn Forte 2833fcf3ce44SJohn Forte if (!port->fct_port) { 2834fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 2835fcf3ce44SJohn Forte "%s: sid=%x. Target unbound. Rejecting...", 2836fcf3ce44SJohn Forte emlxs_elscmd_xlate(cmd_code), sid); 2837fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code, 2838fcf3ce44SJohn Forte LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 2839fcf3ce44SJohn Forte 2840fcf3ce44SJohn Forte goto done; 2841fcf3ce44SJohn Forte } 2842*291a2b48SSukumar Swaminathan 2843fcf3ce44SJohn Forte if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) { 2844fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 2845fcf3ce44SJohn Forte "%s: sid=%x. Target offline. Rejecting...", 2846fcf3ce44SJohn Forte emlxs_elscmd_xlate(cmd_code), sid); 2847fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code, 2848fcf3ce44SJohn Forte LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 2849fcf3ce44SJohn Forte 2850fcf3ce44SJohn Forte goto done; 2851fcf3ce44SJohn Forte } 2852*291a2b48SSukumar Swaminathan 2853fcf3ce44SJohn Forte /* Process the request */ 2854fcf3ce44SJohn Forte switch (cmd_code) { 2855fcf3ce44SJohn Forte case ELS_CMD_FLOGI: 2856*291a2b48SSukumar Swaminathan rval = 2857*291a2b48SSukumar Swaminathan emlxs_fct_process_unsol_flogi(port, rp, iocbq, mp, size); 2858*291a2b48SSukumar Swaminathan 2859*291a2b48SSukumar Swaminathan if (!rval) { 2860*291a2b48SSukumar Swaminathan ELS_PKT *els_pkt = (ELS_PKT *)bp; 2861*291a2b48SSukumar Swaminathan 2862*291a2b48SSukumar Swaminathan /* Save the FLOGI exchange information */ 2863*291a2b48SSukumar Swaminathan bzero((uint8_t *)&port->fx, 2864*291a2b48SSukumar Swaminathan sizeof (fct_flogi_xchg_t)); 2865*291a2b48SSukumar Swaminathan port->fx_context = iocb->ulpContext; 2866*291a2b48SSukumar Swaminathan bcopy((caddr_t)&els_pkt->un.logi.nodeName, 2867*291a2b48SSukumar Swaminathan (caddr_t)port->fx.fx_nwwn, 8); 2868*291a2b48SSukumar Swaminathan bcopy((caddr_t)&els_pkt->un.logi.portName, 2869*291a2b48SSukumar Swaminathan (caddr_t)port->fx.fx_pwwn, 8); 2870*291a2b48SSukumar Swaminathan port->fx.fx_sid = sid; 2871*291a2b48SSukumar Swaminathan port->fx.fx_did = iocb->un.elsreq.myID; 2872*291a2b48SSukumar Swaminathan port->fx.fx_fport = els_pkt->un.logi.cmn.fPort; 2873*291a2b48SSukumar Swaminathan port->fx.fx_op = ELS_OP_FLOGI; 2874*291a2b48SSukumar Swaminathan 2875*291a2b48SSukumar Swaminathan /* Try to handle the FLOGI now */ 2876*291a2b48SSukumar Swaminathan emlxs_fct_handle_rcvd_flogi(port); 2877*291a2b48SSukumar Swaminathan } 2878*291a2b48SSukumar Swaminathan goto done; 2879fcf3ce44SJohn Forte 2880fcf3ce44SJohn Forte case ELS_CMD_PLOGI: 2881*291a2b48SSukumar Swaminathan rval = 2882*291a2b48SSukumar Swaminathan emlxs_fct_process_unsol_plogi(port, rp, iocbq, mp, size); 2883fcf3ce44SJohn Forte break; 2884fcf3ce44SJohn Forte 2885fcf3ce44SJohn Forte default: 2886fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 2887fcf3ce44SJohn Forte "%s: sid=0x%x", emlxs_elscmd_xlate(cmd_code), sid); 2888fcf3ce44SJohn Forte rval = 0; 2889fcf3ce44SJohn Forte break; 2890fcf3ce44SJohn Forte } 2891fcf3ce44SJohn Forte 2892fcf3ce44SJohn Forte if (rval) { 2893fcf3ce44SJohn Forte goto done; 2894fcf3ce44SJohn Forte } 2895*291a2b48SSukumar Swaminathan 2896fcf3ce44SJohn Forte padding = (8 - (size & 7)) & 7; 2897fcf3ce44SJohn Forte 2898fcf3ce44SJohn Forte fct_cmd = (fct_cmd_t *)MODSYM(fct_alloc) (FCT_STRUCT_CMD_RCVD_ELS, 2899*291a2b48SSukumar Swaminathan (size + padding + GET_STRUCT_SIZE(emlxs_buf_t)), 2900*291a2b48SSukumar Swaminathan AF_FORCE_NOSLEEP); 2901fcf3ce44SJohn Forte 2902fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2903fcf3ce44SJohn Forte { 2904fcf3ce44SJohn Forte uint32_t *ptr = (uint32_t *)bp; 2905fcf3ce44SJohn Forte 2906fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2907fcf3ce44SJohn Forte "fct_alloc %p: ELS rcvd: rxid=%x payload: x%x x%x", 2908fcf3ce44SJohn Forte fct_cmd, iocb->ulpContext, *ptr, *(ptr + 1)); 2909fcf3ce44SJohn Forte } 2910*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2911fcf3ce44SJohn Forte 2912fcf3ce44SJohn Forte if (fct_cmd == NULL) { 2913fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 2914fcf3ce44SJohn Forte "%s: sid=%x. Out of memory. Rejecting...", 2915fcf3ce44SJohn Forte emlxs_elscmd_xlate(cmd_code), sid); 2916fcf3ce44SJohn Forte 2917fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code, 2918fcf3ce44SJohn Forte LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE); 2919fcf3ce44SJohn Forte goto done; 2920fcf3ce44SJohn Forte } 2921*291a2b48SSukumar Swaminathan 2922*291a2b48SSukumar Swaminathan cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd); 2923*291a2b48SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 2924*291a2b48SSukumar Swaminathan 2925fcf3ce44SJohn Forte /* Initialize fct_cmd */ 2926fcf3ce44SJohn Forte fct_cmd->cmd_oxid = (cmd_code >> ELS_CMD_SHIFT) & 0xff; 2927fcf3ce44SJohn Forte fct_cmd->cmd_rxid = iocb->ulpContext; 2928fcf3ce44SJohn Forte fct_cmd->cmd_rportid = sid; 2929fcf3ce44SJohn Forte fct_cmd->cmd_lportid = port->did; 2930fcf3ce44SJohn Forte fct_cmd->cmd_rp_handle = iocb->ulpIoTag; /* RPI */ 2931fcf3ce44SJohn Forte fct_cmd->cmd_port = port->fct_port; 2932fcf3ce44SJohn Forte 2933*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_ELS_CMD_RECEIVED); 2934fcf3ce44SJohn Forte 2935*291a2b48SSukumar Swaminathan /* Initialize cmd_sbp */ 2936*291a2b48SSukumar Swaminathan cmd_sbp->did = sid; 2937fcf3ce44SJohn Forte cmd_sbp->ring = rp; 2938fcf3ce44SJohn Forte cmd_sbp->class = iocb->ulpClass; 2939fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_ELS_CMD; 2940*291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_PLOGI_RECEIVED; 2941*291a2b48SSukumar Swaminathan 2942fcf3ce44SJohn Forte bcopy((uint8_t *)iocb, (uint8_t *)&cmd_sbp->iocbq, 2943fcf3ce44SJohn Forte sizeof (emlxs_iocb_t)); 2944fcf3ce44SJohn Forte 2945fcf3ce44SJohn Forte els = (fct_els_t *)fct_cmd->cmd_specific; 2946fcf3ce44SJohn Forte els->els_req_size = size; 2947*291a2b48SSukumar Swaminathan els->els_req_payload = 2948*291a2b48SSukumar Swaminathan GET_BYTE_OFFSET(fct_cmd->cmd_fca_private, 2949fcf3ce44SJohn Forte GET_STRUCT_SIZE(emlxs_buf_t)); 2950fcf3ce44SJohn Forte bcopy(bp, els->els_req_payload, size); 2951fcf3ce44SJohn Forte 2952*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx); 2953fcf3ce44SJohn Forte cmd_sbp->pkt_flags |= PACKET_RETURNED; 2954fcf3ce44SJohn Forte mutex_exit(&cmd_sbp->mtx); 2955fcf3ce44SJohn Forte 2956fcf3ce44SJohn Forte emlxs_fct_unsol_callback(port, fct_cmd); 2957fcf3ce44SJohn Forte 2958fcf3ce44SJohn Forte done: 2959fcf3ce44SJohn Forte 2960fcf3ce44SJohn Forte return (0); 2961fcf3ce44SJohn Forte 2962*291a2b48SSukumar Swaminathan } /* emlxs_fct_handle_unsol_els() */ 2963fcf3ce44SJohn Forte 2964fcf3ce44SJohn Forte 2965fcf3ce44SJohn Forte /* ARGSUSED */ 2966fcf3ce44SJohn Forte static uint32_t 2967fcf3ce44SJohn Forte emlxs_fct_process_unsol_flogi(emlxs_port_t *port, RING *rp, IOCBQ *iocbq, 2968fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 2969fcf3ce44SJohn Forte { 2970fcf3ce44SJohn Forte IOCB *iocb; 2971fcf3ce44SJohn Forte char buffer[64]; 2972fcf3ce44SJohn Forte 2973fcf3ce44SJohn Forte buffer[0] = 0; 2974fcf3ce44SJohn Forte 2975fcf3ce44SJohn Forte iocb = &iocbq->iocb; 2976fcf3ce44SJohn Forte 2977fcf3ce44SJohn Forte /* Perform processing of FLOGI payload */ 2978fcf3ce44SJohn Forte if (emlxs_process_unsol_flogi(port, iocbq, mp, size, buffer)) { 2979fcf3ce44SJohn Forte return (1); 2980fcf3ce44SJohn Forte } 2981*291a2b48SSukumar Swaminathan 2982fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, "FLOGI: sid=0x%x %s", 2983fcf3ce44SJohn Forte iocb->un.elsreq.remoteID, buffer); 2984fcf3ce44SJohn Forte 2985fcf3ce44SJohn Forte return (0); 2986fcf3ce44SJohn Forte 2987*291a2b48SSukumar Swaminathan } /* emlxs_fct_process_unsol_flogi() */ 2988fcf3ce44SJohn Forte 2989fcf3ce44SJohn Forte 2990fcf3ce44SJohn Forte /* ARGSUSED */ 2991fcf3ce44SJohn Forte static uint32_t 2992fcf3ce44SJohn Forte emlxs_fct_process_unsol_plogi(emlxs_port_t *port, RING *rp, IOCBQ *iocbq, 2993fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 2994fcf3ce44SJohn Forte { 2995fcf3ce44SJohn Forte IOCB *iocb; 2996fcf3ce44SJohn Forte char buffer[64]; 2997fcf3ce44SJohn Forte 2998fcf3ce44SJohn Forte buffer[0] = 0; 2999fcf3ce44SJohn Forte 3000fcf3ce44SJohn Forte iocb = &iocbq->iocb; 3001fcf3ce44SJohn Forte 3002fcf3ce44SJohn Forte /* Perform processing of PLOGI payload */ 3003fcf3ce44SJohn Forte if (emlxs_process_unsol_plogi(port, iocbq, mp, size, buffer)) { 3004fcf3ce44SJohn Forte return (1); 3005fcf3ce44SJohn Forte } 3006*291a2b48SSukumar Swaminathan 3007fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, "PLOGI: sid=0x%x %s", 3008fcf3ce44SJohn Forte iocb->un.elsreq.remoteID, buffer); 3009fcf3ce44SJohn Forte 3010fcf3ce44SJohn Forte return (0); 3011fcf3ce44SJohn Forte 3012*291a2b48SSukumar Swaminathan } /* emlxs_fct_process_unsol_plogi() */ 3013fcf3ce44SJohn Forte 3014fcf3ce44SJohn Forte 3015fcf3ce44SJohn Forte /* ARGSUSED */ 3016fcf3ce44SJohn Forte static emlxs_buf_t * 3017*291a2b48SSukumar Swaminathan emlxs_fct_pkt_init(emlxs_port_t *port, fct_cmd_t *fct_cmd, 3018*291a2b48SSukumar Swaminathan fc_packet_t *pkt) 3019fcf3ce44SJohn Forte { 3020fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 3021fcf3ce44SJohn Forte emlxs_buf_t *sbp; 3022fcf3ce44SJohn Forte 3023fcf3ce44SJohn Forte cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 3024fcf3ce44SJohn Forte 3025fcf3ce44SJohn Forte sbp = PKT2PRIV(pkt); 3026fcf3ce44SJohn Forte sbp->fct_cmd = cmd_sbp->fct_cmd; 3027fcf3ce44SJohn Forte sbp->node = cmd_sbp->node; 3028fcf3ce44SJohn Forte sbp->ring = cmd_sbp->ring; 3029fcf3ce44SJohn Forte sbp->did = cmd_sbp->did; 3030fcf3ce44SJohn Forte sbp->lun = cmd_sbp->lun; 3031fcf3ce44SJohn Forte sbp->class = cmd_sbp->class; 3032fcf3ce44SJohn Forte sbp->fct_type = cmd_sbp->fct_type; 3033fcf3ce44SJohn Forte sbp->fct_state = cmd_sbp->fct_state; 3034fcf3ce44SJohn Forte 3035fcf3ce44SJohn Forte return (sbp); 3036fcf3ce44SJohn Forte 3037*291a2b48SSukumar Swaminathan } /* emlxs_fct_pkt_init() */ 3038fcf3ce44SJohn Forte 3039fcf3ce44SJohn Forte 3040fcf3ce44SJohn Forte /* Mutex will be acquired */ 3041fcf3ce44SJohn Forte static emlxs_buf_t * 3042fcf3ce44SJohn Forte emlxs_fct_cmd_init(emlxs_port_t *port, fct_cmd_t *fct_cmd) 3043fcf3ce44SJohn Forte { 3044fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 3045fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 3046fcf3ce44SJohn Forte 3047fcf3ce44SJohn Forte bzero((void *)cmd_sbp, sizeof (emlxs_buf_t)); 3048*291a2b48SSukumar Swaminathan mutex_init(&cmd_sbp->fct_mtx, NULL, MUTEX_DRIVER, 3049*291a2b48SSukumar Swaminathan (void *)hba->intr_arg); 3050fcf3ce44SJohn Forte mutex_init(&cmd_sbp->mtx, NULL, MUTEX_DRIVER, (void *)hba->intr_arg); 3051fcf3ce44SJohn Forte 3052*291a2b48SSukumar Swaminathan 3053*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->fct_mtx); 3054fcf3ce44SJohn Forte cmd_sbp->pkt_flags = PACKET_VALID; 3055fcf3ce44SJohn Forte cmd_sbp->port = port; 3056fcf3ce44SJohn Forte cmd_sbp->fct_cmd = fct_cmd; 3057fcf3ce44SJohn Forte cmd_sbp->node = (fct_cmd->cmd_rp) ? 3058fcf3ce44SJohn Forte *(emlxs_node_t **)fct_cmd->cmd_rp->rp_fca_private : NULL; 3059fcf3ce44SJohn Forte cmd_sbp->iocbq.sbp = cmd_sbp; 3060*291a2b48SSukumar Swaminathan cmd_sbp->iocbq.port = port; 3061fcf3ce44SJohn Forte 3062fcf3ce44SJohn Forte return (cmd_sbp); 3063fcf3ce44SJohn Forte 3064*291a2b48SSukumar Swaminathan } /* emlxs_fct_cmd_init() */ 3065fcf3ce44SJohn Forte 3066fcf3ce44SJohn Forte 3067fcf3ce44SJohn Forte /* Mutex must be held */ 3068fcf3ce44SJohn Forte static int 3069fcf3ce44SJohn Forte emlxs_fct_cmd_uninit(emlxs_port_t *port, fct_cmd_t *fct_cmd) 3070fcf3ce44SJohn Forte { 3071fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 3072fcf3ce44SJohn Forte 3073*291a2b48SSukumar Swaminathan /* Flags fct_cmd is no longer used */ 3074*291a2b48SSukumar Swaminathan fct_cmd->cmd_oxid = 0; 3075*291a2b48SSukumar Swaminathan fct_cmd->cmd_rxid = 0; 3076*291a2b48SSukumar Swaminathan 3077*291a2b48SSukumar Swaminathan 3078fcf3ce44SJohn Forte if (!(cmd_sbp->pkt_flags & PACKET_VALID)) { 3079fcf3ce44SJohn Forte return (FC_FAILURE); 3080fcf3ce44SJohn Forte } 3081*291a2b48SSukumar Swaminathan 3082fcf3ce44SJohn Forte if (cmd_sbp->iotag != 0) { 3083fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3084fcf3ce44SJohn Forte "Pkt still registered! ringo=%d iotag=%d sbp=%p", 3085fcf3ce44SJohn Forte cmd_sbp->ring, cmd_sbp->iotag, cmd_sbp); 3086fcf3ce44SJohn Forte 3087fcf3ce44SJohn Forte if (cmd_sbp->ring) { 3088fcf3ce44SJohn Forte (void) emlxs_unregister_pkt(cmd_sbp->ring, 3089*291a2b48SSukumar Swaminathan cmd_sbp->iotag, 0); 3090fcf3ce44SJohn Forte } 3091fcf3ce44SJohn Forte } 3092*291a2b48SSukumar Swaminathan 3093fcf3ce44SJohn Forte cmd_sbp->pkt_flags |= PACKET_RETURNED; 3094fcf3ce44SJohn Forte cmd_sbp->pkt_flags &= ~PACKET_VALID; 3095fcf3ce44SJohn Forte 3096*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 3097fcf3ce44SJohn Forte mutex_destroy(&cmd_sbp->mtx); 3098*291a2b48SSukumar Swaminathan mutex_destroy(&cmd_sbp->fct_mtx); 3099fcf3ce44SJohn Forte 3100fcf3ce44SJohn Forte return (FC_SUCCESS); 3101fcf3ce44SJohn Forte 3102*291a2b48SSukumar Swaminathan } /* emlxs_fct_cmd_uninit() */ 3103fcf3ce44SJohn Forte 3104fcf3ce44SJohn Forte 3105fcf3ce44SJohn Forte static void 3106fcf3ce44SJohn Forte emlxs_fct_pkt_comp(fc_packet_t *pkt) 3107fcf3ce44SJohn Forte { 3108fcf3ce44SJohn Forte emlxs_port_t *port; 3109*291a2b48SSukumar Swaminathan #ifdef FMA_SUPPORT 3110*291a2b48SSukumar Swaminathan emlxs_hba_t *hba; 3111*291a2b48SSukumar Swaminathan #endif /* FMA_SUPPORT */ 3112fcf3ce44SJohn Forte emlxs_buf_t *sbp; 3113fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 3114fcf3ce44SJohn Forte fct_cmd_t *fct_cmd; 3115fcf3ce44SJohn Forte fct_els_t *fct_els; 3116fcf3ce44SJohn Forte fct_sol_ct_t *fct_ct; 3117fcf3ce44SJohn Forte 3118fcf3ce44SJohn Forte sbp = PKT2PRIV(pkt); 3119fcf3ce44SJohn Forte port = sbp->port; 3120*291a2b48SSukumar Swaminathan #ifdef FMA_SUPPORT 3121*291a2b48SSukumar Swaminathan hba = HBA; 3122*291a2b48SSukumar Swaminathan #endif /* FMA_SUPPORT */ 3123fcf3ce44SJohn Forte fct_cmd = sbp->fct_cmd; 3124fcf3ce44SJohn Forte cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 3125*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->fct_mtx); 3126*291a2b48SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP; 3127*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_PKT_COMPLETE); 3128*291a2b48SSukumar Swaminathan 3129*291a2b48SSukumar Swaminathan if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT_INP) { 3130*291a2b48SSukumar Swaminathan 3131*291a2b48SSukumar Swaminathan if (fct_cmd->cmd_type == FCT_CMD_FCP_XCHG) { 3132*291a2b48SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--; 3133*291a2b48SSukumar Swaminathan } 3134*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_ABORT_DONE); 3135*291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3136*291a2b48SSukumar Swaminathan (void) emlxs_fct_cmd_uninit(port, fct_cmd); 3137*291a2b48SSukumar Swaminathan MODSYM(fct_cmd_fca_aborted) (fct_cmd, 3138*291a2b48SSukumar Swaminathan FCT_ABORT_SUCCESS, FCT_IOF_FCA_DONE); 3139*291a2b48SSukumar Swaminathan goto done; 3140*291a2b48SSukumar Swaminathan } 3141fcf3ce44SJohn Forte 3142fcf3ce44SJohn Forte mutex_enter(&cmd_sbp->mtx); 3143fcf3ce44SJohn Forte cmd_sbp->pkt_flags &= ~PACKET_RETURNED; 3144fcf3ce44SJohn Forte cmd_sbp->fct_pkt = NULL; 3145*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx); 3146fcf3ce44SJohn Forte 3147*291a2b48SSukumar Swaminathan switch (fct_cmd->cmd_type) { 3148*291a2b48SSukumar Swaminathan case FCT_CMD_FCP_XCHG: 3149*291a2b48SSukumar Swaminathan if ((pkt->pkt_reason == FC_REASON_ABORTED) || 3150*291a2b48SSukumar Swaminathan (pkt->pkt_reason == FC_REASON_XCHG_DROPPED) || 3151*291a2b48SSukumar Swaminathan (pkt->pkt_reason == FC_REASON_OFFLINE)) { 3152*291a2b48SSukumar Swaminathan /* 3153*291a2b48SSukumar Swaminathan * The error indicates this IO should be terminated 3154*291a2b48SSukumar Swaminathan * immediately. 3155*291a2b48SSukumar Swaminathan */ 3156fcf3ce44SJohn Forte 3157*291a2b48SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_SEND_STATUS; 3158*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx); 3159*291a2b48SSukumar Swaminathan cmd_sbp->pkt_flags |= PACKET_RETURNED; 3160*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx); 3161fcf3ce44SJohn Forte 3162*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED); 3163*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 3164fcf3ce44SJohn Forte 3165*291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE 3166*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3167*291a2b48SSukumar Swaminathan "fct_queue_cmd_for_termination:2 %p: x%x", 3168*291a2b48SSukumar Swaminathan fct_cmd, fct_cmd->cmd_comp_status); 3169*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 3170*291a2b48SSukumar Swaminathan MODSYM(fct_queue_cmd_for_termination) (fct_cmd, 3171*291a2b48SSukumar Swaminathan FCT_ABTS_RECEIVED); 3172*291a2b48SSukumar Swaminathan goto done; 3173*291a2b48SSukumar Swaminathan } 3174fcf3ce44SJohn Forte 3175*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, 3176*291a2b48SSukumar Swaminathan EMLXS_FCT_PKT_FCPRSP_COMPLETE); 3177*291a2b48SSukumar Swaminathan 3178*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_IO_DONE); 3179*291a2b48SSukumar Swaminathan 3180*291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3181fcf3ce44SJohn Forte (void) emlxs_fct_cmd_uninit(port, fct_cmd); 3182fcf3ce44SJohn Forte 3183fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 3184fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3185fcf3ce44SJohn Forte "fct_send_response_done:2 %p: x%x", 3186fcf3ce44SJohn Forte fct_cmd, fct_cmd->cmd_comp_status); 3187fcf3ce44SJohn Forte #else 3188fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3189fcf3ce44SJohn Forte "emlxs_fct_pkt_comp: fct_send_response_done. dbuf=%p", 3190fcf3ce44SJohn Forte sbp->fct_buf); 3191*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 3192*291a2b48SSukumar Swaminathan 3193*291a2b48SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--; 3194fcf3ce44SJohn Forte 3195fcf3ce44SJohn Forte MODSYM(fct_send_response_done) (fct_cmd, 3196fcf3ce44SJohn Forte fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE); 3197fcf3ce44SJohn Forte 3198fcf3ce44SJohn Forte break; 3199fcf3ce44SJohn Forte 3200fcf3ce44SJohn Forte case FCT_CMD_RCVD_ELS: 3201fcf3ce44SJohn Forte 3202*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, 3203*291a2b48SSukumar Swaminathan EMLXS_FCT_PKT_ELSRSP_COMPLETE); 3204*291a2b48SSukumar Swaminathan 3205*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_IO_DONE); 3206*291a2b48SSukumar Swaminathan 3207*291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3208fcf3ce44SJohn Forte (void) emlxs_fct_cmd_uninit(port, fct_cmd); 3209fcf3ce44SJohn Forte 3210fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 3211fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3212fcf3ce44SJohn Forte "fct_send_response_done:3 %p: x%x", 3213fcf3ce44SJohn Forte fct_cmd, fct_cmd->cmd_comp_status); 3214*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 3215fcf3ce44SJohn Forte MODSYM(fct_send_response_done) (fct_cmd, 3216fcf3ce44SJohn Forte fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE); 3217fcf3ce44SJohn Forte 3218fcf3ce44SJohn Forte break; 3219fcf3ce44SJohn Forte 3220fcf3ce44SJohn Forte case FCT_CMD_SOL_ELS: 3221*291a2b48SSukumar Swaminathan 3222*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, 3223*291a2b48SSukumar Swaminathan EMLXS_FCT_PKT_ELSCMD_COMPLETE); 3224*291a2b48SSukumar Swaminathan 3225*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_IO_DONE); 3226fcf3ce44SJohn Forte 3227fcf3ce44SJohn Forte fct_els = (fct_els_t *)fct_cmd->cmd_specific; 3228fcf3ce44SJohn Forte 3229fcf3ce44SJohn Forte if (fct_els->els_resp_payload) { 3230*291a2b48SSukumar Swaminathan emlxs_mpdata_sync(pkt->pkt_resp_dma, 0, 3231*291a2b48SSukumar Swaminathan pkt->pkt_rsplen, DDI_DMA_SYNC_FORKERNEL); 3232fcf3ce44SJohn Forte 3233fcf3ce44SJohn Forte bcopy((uint8_t *)pkt->pkt_resp, 3234fcf3ce44SJohn Forte (uint8_t *)fct_els->els_resp_payload, 3235fcf3ce44SJohn Forte fct_els->els_resp_size); 3236fcf3ce44SJohn Forte } 3237*291a2b48SSukumar Swaminathan 3238*291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3239fcf3ce44SJohn Forte (void) emlxs_fct_cmd_uninit(port, fct_cmd); 3240fcf3ce44SJohn Forte 3241fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 3242fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3243fcf3ce44SJohn Forte "fct_send_cmd_done:1 %p: x%x", 3244fcf3ce44SJohn Forte fct_cmd, fct_cmd->cmd_comp_status); 3245*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 3246*291a2b48SSukumar Swaminathan MODSYM(fct_send_cmd_done) (fct_cmd, FCT_SUCCESS, 3247*291a2b48SSukumar Swaminathan FCT_IOF_FCA_DONE); 3248fcf3ce44SJohn Forte 3249fcf3ce44SJohn Forte break; 3250fcf3ce44SJohn Forte 3251fcf3ce44SJohn Forte case FCT_CMD_SOL_CT: 3252*291a2b48SSukumar Swaminathan 3253*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, 3254*291a2b48SSukumar Swaminathan EMLXS_FCT_PKT_CTCMD_COMPLETE); 3255*291a2b48SSukumar Swaminathan 3256*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_IO_DONE); 3257fcf3ce44SJohn Forte 3258fcf3ce44SJohn Forte fct_ct = (fct_sol_ct_t *)fct_cmd->cmd_specific; 3259fcf3ce44SJohn Forte 3260fcf3ce44SJohn Forte if (fct_ct->ct_resp_payload) { 3261*291a2b48SSukumar Swaminathan emlxs_mpdata_sync(pkt->pkt_resp_dma, 0, 3262*291a2b48SSukumar Swaminathan pkt->pkt_rsplen, DDI_DMA_SYNC_FORKERNEL); 3263fcf3ce44SJohn Forte 3264fcf3ce44SJohn Forte bcopy((uint8_t *)pkt->pkt_resp, 3265fcf3ce44SJohn Forte (uint8_t *)fct_ct->ct_resp_payload, 3266fcf3ce44SJohn Forte fct_ct->ct_resp_size); 3267fcf3ce44SJohn Forte } 3268*291a2b48SSukumar Swaminathan 3269*291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3270fcf3ce44SJohn Forte (void) emlxs_fct_cmd_uninit(port, fct_cmd); 3271fcf3ce44SJohn Forte 3272fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 3273fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3274fcf3ce44SJohn Forte "fct_send_cmd_done:2 %p: x%x", 3275fcf3ce44SJohn Forte fct_cmd, fct_cmd->cmd_comp_status); 3276*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 3277*291a2b48SSukumar Swaminathan MODSYM(fct_send_cmd_done) (fct_cmd, FCT_SUCCESS, 3278*291a2b48SSukumar Swaminathan FCT_IOF_FCA_DONE); 3279fcf3ce44SJohn Forte break; 3280fcf3ce44SJohn Forte 3281fcf3ce44SJohn Forte default: 3282fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3283fcf3ce44SJohn Forte "emlxs_fct_pkt_comp: Invalid cmd type found. type=%x", 3284fcf3ce44SJohn Forte fct_cmd->cmd_type); 3285*291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = NULL; 3286fcf3ce44SJohn Forte 3287*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 3288fcf3ce44SJohn Forte } 3289fcf3ce44SJohn Forte 3290fcf3ce44SJohn Forte done: 3291fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 3292fcf3ce44SJohn Forte return; 3293fcf3ce44SJohn Forte 3294*291a2b48SSukumar Swaminathan } /* emlxs_fct_pkt_comp() */ 3295fcf3ce44SJohn Forte 3296fcf3ce44SJohn Forte 3297*291a2b48SSukumar Swaminathan static void 3298*291a2b48SSukumar Swaminathan emlxs_fct_abort_pkt_comp(fc_packet_t *pkt) 3299fcf3ce44SJohn Forte { 3300*291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE 3301*291a2b48SSukumar Swaminathan emlxs_buf_t *sbp; 3302*291a2b48SSukumar Swaminathan IOCBQ *iocbq; 3303*291a2b48SSukumar Swaminathan IOCB *iocb; 3304*291a2b48SSukumar Swaminathan 3305*291a2b48SSukumar Swaminathan sbp = PKT2PRIV(pkt); 3306*291a2b48SSukumar Swaminathan iocbq = &sbp->iocbq; 3307*291a2b48SSukumar Swaminathan iocb = &iocbq->iocb; 3308*291a2b48SSukumar Swaminathan 3309*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3310*291a2b48SSukumar Swaminathan "emlxs_fct_handle_abort: %p: xri=%x status=%x", iocb->ulpContext, 3311*291a2b48SSukumar Swaminathan iocb->ulpCommand, iocb->ulpStatus); 3312*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 3313*291a2b48SSukumar Swaminathan 3314*291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt); 3315*291a2b48SSukumar Swaminathan return; 3316*291a2b48SSukumar Swaminathan 3317*291a2b48SSukumar Swaminathan } /* emlxs_fct_abort_pkt_comp() */ 3318*291a2b48SSukumar Swaminathan 3319*291a2b48SSukumar Swaminathan 3320*291a2b48SSukumar Swaminathan static fct_status_t 3321*291a2b48SSukumar Swaminathan emlxs_fct_send_els_cmd(fct_cmd_t *fct_cmd) 3322*291a2b48SSukumar Swaminathan { 3323*291a2b48SSukumar Swaminathan emlxs_port_t *port = 3324*291a2b48SSukumar Swaminathan (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 3325fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 3326fcf3ce44SJohn Forte uint32_t did; 3327fcf3ce44SJohn Forte fct_els_t *fct_els; 3328fcf3ce44SJohn Forte fc_packet_t *pkt; 3329fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 3330fcf3ce44SJohn Forte 3331fcf3ce44SJohn Forte did = fct_cmd->cmd_rportid; 3332fcf3ce44SJohn Forte fct_els = (fct_els_t *)fct_cmd->cmd_specific; 3333fcf3ce44SJohn Forte 3334fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, fct_els->els_req_size, 3335fcf3ce44SJohn Forte fct_els->els_resp_size, 0, KM_NOSLEEP))) { 3336fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 3337fcf3ce44SJohn Forte "emlxs_fct_send_els_cmd: Unable to allocate packet."); 3338fcf3ce44SJohn Forte return (FCT_FAILURE); 3339fcf3ce44SJohn Forte } 3340*291a2b48SSukumar Swaminathan 3341fcf3ce44SJohn Forte cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd); 3342*291a2b48SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 3343*291a2b48SSukumar Swaminathan 3344*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_SEND_ELS_REQ); 3345fcf3ce44SJohn Forte 3346fcf3ce44SJohn Forte cmd_sbp->ring = &hba->ring[FC_ELS_RING]; 3347fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_ELS_REQ; 3348*291a2b48SSukumar Swaminathan cmd_sbp->did = fct_cmd->cmd_rportid; 3349fcf3ce44SJohn Forte 3350fcf3ce44SJohn Forte (void) emlxs_fct_pkt_init(port, fct_cmd, pkt); 3351*291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = pkt; 3352fcf3ce44SJohn Forte 3353fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE; 3354fcf3ce44SJohn Forte pkt->pkt_timeout = 3355fcf3ce44SJohn Forte ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov); 3356fcf3ce44SJohn Forte pkt->pkt_comp = emlxs_fct_pkt_comp; 3357fcf3ce44SJohn Forte 3358fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3359fcf3ce44SJohn Forte "emlxs_fct_send_els_cmd: pkt_timeout=%d ratov=%d", 3360fcf3ce44SJohn Forte pkt->pkt_timeout, hba->fc_ratov); 3361fcf3ce44SJohn Forte 3362fcf3ce44SJohn Forte 3363fcf3ce44SJohn Forte /* Build the fc header */ 3364fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(did); 3365fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_ELS_REQ; 3366fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.s_id = SWAP_DATA24_LO(port->did); 3367fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 3368fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = 3369fcf3ce44SJohn Forte F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE; 3370fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 3371fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 3372fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 3373fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xFFFF; 3374fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xFFFF; 3375fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 3376fcf3ce44SJohn Forte 3377fcf3ce44SJohn Forte /* Copy the cmd payload */ 3378fcf3ce44SJohn Forte bcopy((uint8_t *)fct_els->els_req_payload, (uint8_t *)pkt->pkt_cmd, 3379fcf3ce44SJohn Forte fct_els->els_req_size); 3380*291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP; 3381fcf3ce44SJohn Forte 3382fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 3383fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 3384fcf3ce44SJohn Forte "emlxs_fct_send_els_cmd: Unable to send packet."); 3385fcf3ce44SJohn Forte 3386fcf3ce44SJohn Forte if (cmd_sbp->pkt_flags & PACKET_VALID) { 3387fcf3ce44SJohn Forte mutex_enter(&cmd_sbp->mtx); 3388fcf3ce44SJohn Forte cmd_sbp->fct_pkt = NULL; 3389fcf3ce44SJohn Forte cmd_sbp->pkt_flags |= PACKET_RETURNED; 3390*291a2b48SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP; 3391fcf3ce44SJohn Forte mutex_exit(&cmd_sbp->mtx); 3392fcf3ce44SJohn Forte } 3393fcf3ce44SJohn Forte 3394*291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt); 3395fcf3ce44SJohn Forte 3396*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED); 3397*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 3398*291a2b48SSukumar Swaminathan return (FCT_FAILURE); 3399fcf3ce44SJohn Forte } 3400fcf3ce44SJohn Forte 3401*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_REQ_PENDING); 3402*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 3403fcf3ce44SJohn Forte return (FCT_SUCCESS); 3404fcf3ce44SJohn Forte 3405*291a2b48SSukumar Swaminathan } /* emlxs_fct_send_els_cmd() */ 3406fcf3ce44SJohn Forte 3407fcf3ce44SJohn Forte 3408fcf3ce44SJohn Forte static fct_status_t 3409fcf3ce44SJohn Forte emlxs_fct_send_els_rsp(fct_cmd_t *fct_cmd) 3410fcf3ce44SJohn Forte { 3411fcf3ce44SJohn Forte emlxs_port_t *port = 3412fcf3ce44SJohn Forte (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 3413fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 3414fcf3ce44SJohn Forte uint32_t did; 3415fcf3ce44SJohn Forte fct_els_t *fct_els; 3416fcf3ce44SJohn Forte fc_packet_t *pkt; 3417fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 3418fcf3ce44SJohn Forte 3419fcf3ce44SJohn Forte fct_els = (fct_els_t *)fct_cmd->cmd_specific; 3420fcf3ce44SJohn Forte did = fct_cmd->cmd_rportid; 3421fcf3ce44SJohn Forte 3422*291a2b48SSukumar Swaminathan if (!(pkt = emlxs_pkt_alloc(port, fct_els->els_resp_size, 0, 0, 3423*291a2b48SSukumar Swaminathan KM_NOSLEEP))) { 3424fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 3425fcf3ce44SJohn Forte "emlxs_fct_send_els_rsp: Unable to allocate packet."); 3426fcf3ce44SJohn Forte return (FCT_FAILURE); 3427fcf3ce44SJohn Forte } 3428*291a2b48SSukumar Swaminathan 3429fcf3ce44SJohn Forte cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 3430fcf3ce44SJohn Forte 3431*291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->fct_mtx); 3432*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_SEND_ELS_RSP); 3433*291a2b48SSukumar Swaminathan 3434fcf3ce44SJohn Forte mutex_enter(&cmd_sbp->mtx); 3435fcf3ce44SJohn Forte cmd_sbp->pkt_flags &= ~PACKET_RETURNED; 3436*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx); 3437fcf3ce44SJohn Forte 3438fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_ELS_RSP; 3439fcf3ce44SJohn Forte 3440fcf3ce44SJohn Forte (void) emlxs_fct_pkt_init(port, fct_cmd, pkt); 3441*291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = pkt; 3442fcf3ce44SJohn Forte 3443fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND; 3444fcf3ce44SJohn Forte pkt->pkt_timeout = 3445fcf3ce44SJohn Forte ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov); 3446fcf3ce44SJohn Forte pkt->pkt_comp = emlxs_fct_pkt_comp; 3447fcf3ce44SJohn Forte 3448fcf3ce44SJohn Forte /* Build the fc header */ 3449fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(did); 3450fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_ELS_RSP; 3451fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.s_id = SWAP_DATA24_LO(port->did); 3452fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 3453fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = 3454fcf3ce44SJohn Forte F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ; 3455fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 3456fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 3457fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 3458fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = fct_cmd->cmd_oxid; 3459fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = fct_cmd->cmd_rxid; 3460fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 3461fcf3ce44SJohn Forte 3462fcf3ce44SJohn Forte /* Copy the resp payload to pkt_cmd buffer */ 3463fcf3ce44SJohn Forte bcopy((uint8_t *)fct_els->els_resp_payload, (uint8_t *)pkt->pkt_cmd, 3464fcf3ce44SJohn Forte fct_els->els_resp_size); 3465*291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP; 3466fcf3ce44SJohn Forte 3467fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 3468fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 3469fcf3ce44SJohn Forte "emlxs_fct_send_els_rsp: Unable to send packet."); 3470fcf3ce44SJohn Forte 3471fcf3ce44SJohn Forte if (cmd_sbp->pkt_flags & PACKET_VALID) { 3472fcf3ce44SJohn Forte mutex_enter(&cmd_sbp->mtx); 3473fcf3ce44SJohn Forte cmd_sbp->fct_pkt = NULL; 3474fcf3ce44SJohn Forte cmd_sbp->pkt_flags |= PACKET_RETURNED; 3475*291a2b48SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP; 3476fcf3ce44SJohn Forte mutex_exit(&cmd_sbp->mtx); 3477fcf3ce44SJohn Forte } 3478*291a2b48SSukumar Swaminathan 3479fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 3480*291a2b48SSukumar Swaminathan 3481*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED); 3482*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 3483fcf3ce44SJohn Forte return (FCT_FAILURE); 3484fcf3ce44SJohn Forte } 3485fcf3ce44SJohn Forte 3486*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_RSP_PENDING); 3487*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 3488*291a2b48SSukumar Swaminathan return (FCT_SUCCESS); 3489fcf3ce44SJohn Forte 3490*291a2b48SSukumar Swaminathan } /* emlxs_fct_send_els_rsp() */ 3491fcf3ce44SJohn Forte 3492fcf3ce44SJohn Forte 3493fcf3ce44SJohn Forte static fct_status_t 3494fcf3ce44SJohn Forte emlxs_fct_send_ct_cmd(fct_cmd_t *fct_cmd) 3495fcf3ce44SJohn Forte { 3496fcf3ce44SJohn Forte emlxs_port_t *port = 3497fcf3ce44SJohn Forte (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 3498fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 3499fcf3ce44SJohn Forte uint32_t did; 3500fcf3ce44SJohn Forte fct_sol_ct_t *fct_ct; 3501fcf3ce44SJohn Forte fc_packet_t *pkt; 3502fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 3503fcf3ce44SJohn Forte 3504fcf3ce44SJohn Forte did = fct_cmd->cmd_rportid; 3505fcf3ce44SJohn Forte fct_ct = (fct_sol_ct_t *)fct_cmd->cmd_specific; 3506fcf3ce44SJohn Forte 3507fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, fct_ct->ct_req_size, 3508fcf3ce44SJohn Forte fct_ct->ct_resp_size, 0, KM_NOSLEEP))) { 3509fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 3510fcf3ce44SJohn Forte "emlxs_fct_send_ct_cmd: Unable to allocate packet."); 3511fcf3ce44SJohn Forte return (FCT_FAILURE); 3512fcf3ce44SJohn Forte } 3513*291a2b48SSukumar Swaminathan 3514fcf3ce44SJohn Forte cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd); 3515*291a2b48SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 3516fcf3ce44SJohn Forte 3517*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_SEND_CT_REQ); 3518fcf3ce44SJohn Forte cmd_sbp->ring = &hba->ring[FC_CT_RING]; 3519fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_CT_REQ; 3520*291a2b48SSukumar Swaminathan cmd_sbp->did = fct_cmd->cmd_rportid; 3521fcf3ce44SJohn Forte 3522fcf3ce44SJohn Forte (void) emlxs_fct_pkt_init(port, fct_cmd, pkt); 3523*291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = pkt; 3524fcf3ce44SJohn Forte 3525fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE; 3526fcf3ce44SJohn Forte pkt->pkt_timeout = 3527fcf3ce44SJohn Forte ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov); 3528fcf3ce44SJohn Forte pkt->pkt_comp = emlxs_fct_pkt_comp; 3529fcf3ce44SJohn Forte 3530fcf3ce44SJohn Forte /* Build the fc header */ 3531fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(did); 3532fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_UNSOL_CONTROL; 3533fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.s_id = SWAP_DATA24_LO(port->did); 3534fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_FC_SERVICES; 3535fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = 3536fcf3ce44SJohn Forte F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE; 3537fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 3538fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 3539fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 3540fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xFFFF; 3541fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xFFFF; 3542fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 3543fcf3ce44SJohn Forte 3544fcf3ce44SJohn Forte /* Copy the cmd payload */ 3545fcf3ce44SJohn Forte bcopy((uint8_t *)fct_ct->ct_req_payload, (uint8_t *)pkt->pkt_cmd, 3546fcf3ce44SJohn Forte fct_ct->ct_req_size); 3547*291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP; 3548fcf3ce44SJohn Forte 3549fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 3550fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 3551fcf3ce44SJohn Forte "emlxs_fct_send_ct_cmd: Unable to send packet."); 3552fcf3ce44SJohn Forte 3553fcf3ce44SJohn Forte if (cmd_sbp->pkt_flags & PACKET_VALID) { 3554fcf3ce44SJohn Forte mutex_enter(&cmd_sbp->mtx); 3555fcf3ce44SJohn Forte cmd_sbp->fct_pkt = NULL; 3556fcf3ce44SJohn Forte cmd_sbp->pkt_flags |= PACKET_RETURNED; 3557*291a2b48SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP; 3558fcf3ce44SJohn Forte mutex_exit(&cmd_sbp->mtx); 3559fcf3ce44SJohn Forte } 3560fcf3ce44SJohn Forte 3561*291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt); 3562fcf3ce44SJohn Forte 3563*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED); 3564*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 3565*291a2b48SSukumar Swaminathan return (FCT_FAILURE); 3566fcf3ce44SJohn Forte } 3567fcf3ce44SJohn Forte 3568*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_REQ_PENDING); 3569*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 3570fcf3ce44SJohn Forte return (FCT_SUCCESS); 3571fcf3ce44SJohn Forte 3572*291a2b48SSukumar Swaminathan } /* emlxs_fct_send_ct_cmd() */ 3573fcf3ce44SJohn Forte 3574fcf3ce44SJohn Forte 3575*291a2b48SSukumar Swaminathan uint32_t 3576*291a2b48SSukumar Swaminathan emlxs_fct_pkt_abort_txq(emlxs_port_t *port, emlxs_buf_t *cmd_sbp) 3577fcf3ce44SJohn Forte { 3578fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 3579fcf3ce44SJohn Forte NODELIST *nlp; 3580*291a2b48SSukumar Swaminathan fc_packet_t *pkt; 3581*291a2b48SSukumar Swaminathan emlxs_buf_t *sbp; 3582*291a2b48SSukumar Swaminathan emlxs_buf_t *iocb_sbp; 3583fcf3ce44SJohn Forte uint8_t ringno; 3584fcf3ce44SJohn Forte RING *rp; 3585fcf3ce44SJohn Forte IOCBQ *iocbq; 3586fcf3ce44SJohn Forte IOCBQ *next; 3587fcf3ce44SJohn Forte IOCBQ *prev; 3588fcf3ce44SJohn Forte uint32_t found; 3589*291a2b48SSukumar Swaminathan uint32_t pkt_flags; 3590*291a2b48SSukumar Swaminathan uint32_t rval = 0; 3591fcf3ce44SJohn Forte 3592*291a2b48SSukumar Swaminathan /* Check the transmit queue */ 3593*291a2b48SSukumar Swaminathan mutex_enter(&EMLXS_RINGTX_LOCK); 3594fcf3ce44SJohn Forte 3595*291a2b48SSukumar Swaminathan /* The IOCB could point to a cmd_sbp (no packet) or a sbp (packet) */ 3596*291a2b48SSukumar Swaminathan pkt = cmd_sbp->fct_pkt; 3597*291a2b48SSukumar Swaminathan if (pkt) { 3598*291a2b48SSukumar Swaminathan sbp = PKT2PRIV(pkt); 3599*291a2b48SSukumar Swaminathan if (sbp == NULL) { 3600*291a2b48SSukumar Swaminathan goto done; 3601*291a2b48SSukumar Swaminathan } 3602*291a2b48SSukumar Swaminathan iocb_sbp = sbp; 3603*291a2b48SSukumar Swaminathan iocbq = &sbp->iocbq; 3604*291a2b48SSukumar Swaminathan pkt_flags = sbp->pkt_flags; 3605*291a2b48SSukumar Swaminathan } else { 3606*291a2b48SSukumar Swaminathan sbp = NULL; 3607*291a2b48SSukumar Swaminathan iocb_sbp = cmd_sbp; 3608*291a2b48SSukumar Swaminathan iocbq = &cmd_sbp->iocbq; 3609*291a2b48SSukumar Swaminathan pkt_flags = cmd_sbp->pkt_flags; 3610fcf3ce44SJohn Forte } 3611fcf3ce44SJohn Forte 3612*291a2b48SSukumar Swaminathan nlp = (NODELIST *)cmd_sbp->node; 3613*291a2b48SSukumar Swaminathan rp = (RING *)cmd_sbp->ring; 3614*291a2b48SSukumar Swaminathan ringno = (rp) ? rp->ringno : 0; 3615fcf3ce44SJohn Forte 3616*291a2b48SSukumar Swaminathan if (pkt_flags & PACKET_IN_TXQ) { 3617fcf3ce44SJohn Forte /* Find it on the queue */ 3618fcf3ce44SJohn Forte found = 0; 3619fcf3ce44SJohn Forte if (iocbq->flag & IOCB_PRIORITY) { 3620fcf3ce44SJohn Forte /* Search the priority queue */ 3621fcf3ce44SJohn Forte prev = NULL; 3622fcf3ce44SJohn Forte next = (IOCBQ *)nlp->nlp_ptx[ringno].q_first; 3623fcf3ce44SJohn Forte 3624fcf3ce44SJohn Forte while (next) { 3625fcf3ce44SJohn Forte if (next == iocbq) { 3626fcf3ce44SJohn Forte /* Remove it */ 3627fcf3ce44SJohn Forte if (prev) { 3628fcf3ce44SJohn Forte prev->next = iocbq->next; 3629fcf3ce44SJohn Forte } 3630*291a2b48SSukumar Swaminathan 3631fcf3ce44SJohn Forte if (nlp->nlp_ptx[ringno].q_last == 3632fcf3ce44SJohn Forte (void *)iocbq) { 3633fcf3ce44SJohn Forte nlp->nlp_ptx[ringno].q_last = 3634fcf3ce44SJohn Forte (void *)prev; 3635fcf3ce44SJohn Forte } 3636*291a2b48SSukumar Swaminathan 3637fcf3ce44SJohn Forte if (nlp->nlp_ptx[ringno].q_first == 3638fcf3ce44SJohn Forte (void *)iocbq) { 3639fcf3ce44SJohn Forte nlp->nlp_ptx[ringno].q_first = 3640fcf3ce44SJohn Forte (void *)iocbq->next; 3641fcf3ce44SJohn Forte } 3642*291a2b48SSukumar Swaminathan 3643fcf3ce44SJohn Forte nlp->nlp_ptx[ringno].q_cnt--; 3644fcf3ce44SJohn Forte iocbq->next = NULL; 3645fcf3ce44SJohn Forte found = 1; 3646fcf3ce44SJohn Forte break; 3647fcf3ce44SJohn Forte } 3648*291a2b48SSukumar Swaminathan 3649fcf3ce44SJohn Forte prev = next; 3650fcf3ce44SJohn Forte next = next->next; 3651fcf3ce44SJohn Forte } 3652fcf3ce44SJohn Forte } else { 3653fcf3ce44SJohn Forte /* Search the normal queue */ 3654fcf3ce44SJohn Forte prev = NULL; 3655fcf3ce44SJohn Forte next = (IOCBQ *)nlp->nlp_tx[ringno].q_first; 3656fcf3ce44SJohn Forte 3657fcf3ce44SJohn Forte while (next) { 3658fcf3ce44SJohn Forte if (next == iocbq) { 3659fcf3ce44SJohn Forte /* Remove it */ 3660fcf3ce44SJohn Forte if (prev) { 3661fcf3ce44SJohn Forte prev->next = iocbq->next; 3662fcf3ce44SJohn Forte } 3663*291a2b48SSukumar Swaminathan 3664fcf3ce44SJohn Forte if (nlp->nlp_tx[ringno].q_last == 3665fcf3ce44SJohn Forte (void *)iocbq) { 3666fcf3ce44SJohn Forte nlp->nlp_tx[ringno].q_last = 3667fcf3ce44SJohn Forte (void *)prev; 3668fcf3ce44SJohn Forte } 3669*291a2b48SSukumar Swaminathan 3670fcf3ce44SJohn Forte if (nlp->nlp_tx[ringno].q_first == 3671fcf3ce44SJohn Forte (void *)iocbq) { 3672fcf3ce44SJohn Forte nlp->nlp_tx[ringno].q_first = 3673fcf3ce44SJohn Forte (void *)iocbq->next; 3674fcf3ce44SJohn Forte } 3675*291a2b48SSukumar Swaminathan 3676fcf3ce44SJohn Forte nlp->nlp_tx[ringno].q_cnt--; 3677fcf3ce44SJohn Forte iocbq->next = NULL; 3678fcf3ce44SJohn Forte found = 1; 3679fcf3ce44SJohn Forte break; 3680fcf3ce44SJohn Forte } 3681*291a2b48SSukumar Swaminathan 3682fcf3ce44SJohn Forte prev = next; 3683fcf3ce44SJohn Forte next = (IOCBQ *)next->next; 3684fcf3ce44SJohn Forte } 3685fcf3ce44SJohn Forte } 3686fcf3ce44SJohn Forte 3687fcf3ce44SJohn Forte if (!found) { 3688fcf3ce44SJohn Forte goto done; 3689fcf3ce44SJohn Forte } 3690*291a2b48SSukumar Swaminathan 3691fcf3ce44SJohn Forte /* Check if node still needs servicing */ 3692fcf3ce44SJohn Forte if ((nlp->nlp_ptx[ringno].q_first) || 3693fcf3ce44SJohn Forte (nlp->nlp_tx[ringno].q_first && 3694fcf3ce44SJohn Forte !(nlp->nlp_flag[ringno] & NLP_CLOSED))) { 3695fcf3ce44SJohn Forte 3696fcf3ce44SJohn Forte /* 3697*291a2b48SSukumar Swaminathan * If this is the base node, don't shift the pointers 3698fcf3ce44SJohn Forte */ 3699fcf3ce44SJohn Forte /* We want to drain the base node before moving on */ 3700fcf3ce44SJohn Forte if (!nlp->nlp_base) { 3701*291a2b48SSukumar Swaminathan /* Shift ring queue pointers to next node */ 3702fcf3ce44SJohn Forte rp->nodeq.q_last = (void *)nlp; 3703fcf3ce44SJohn Forte rp->nodeq.q_first = nlp->nlp_next[ringno]; 3704fcf3ce44SJohn Forte } 3705fcf3ce44SJohn Forte } else { 3706fcf3ce44SJohn Forte /* Remove node from ring queue */ 3707fcf3ce44SJohn Forte 3708fcf3ce44SJohn Forte /* If this is the last node on list */ 3709fcf3ce44SJohn Forte if (rp->nodeq.q_last == (void *)nlp) { 3710fcf3ce44SJohn Forte rp->nodeq.q_last = NULL; 3711fcf3ce44SJohn Forte rp->nodeq.q_first = NULL; 3712fcf3ce44SJohn Forte rp->nodeq.q_cnt = 0; 3713fcf3ce44SJohn Forte } else { 3714fcf3ce44SJohn Forte /* Remove node from head */ 3715fcf3ce44SJohn Forte rp->nodeq.q_first = nlp->nlp_next[ringno]; 3716fcf3ce44SJohn Forte ((NODELIST *)rp->nodeq.q_last)-> 3717fcf3ce44SJohn Forte nlp_next[ringno] = rp->nodeq.q_first; 3718fcf3ce44SJohn Forte rp->nodeq.q_cnt--; 3719fcf3ce44SJohn Forte } 3720fcf3ce44SJohn Forte 3721fcf3ce44SJohn Forte /* Clear node */ 3722fcf3ce44SJohn Forte nlp->nlp_next[ringno] = NULL; 3723fcf3ce44SJohn Forte } 3724fcf3ce44SJohn Forte 3725*291a2b48SSukumar Swaminathan /* The IOCB points to a cmd_sbp (no packet) or a sbp (packet) */ 3726*291a2b48SSukumar Swaminathan mutex_enter(&iocb_sbp->mtx); 3727fcf3ce44SJohn Forte 3728*291a2b48SSukumar Swaminathan if (iocb_sbp->pkt_flags & PACKET_IN_TXQ) { 3729*291a2b48SSukumar Swaminathan iocb_sbp->pkt_flags &= ~PACKET_IN_TXQ; 3730fcf3ce44SJohn Forte hba->ring_tx_count[ringno]--; 3731fcf3ce44SJohn Forte } 3732fcf3ce44SJohn Forte 3733*291a2b48SSukumar Swaminathan mutex_exit(&iocb_sbp->mtx); 3734*291a2b48SSukumar Swaminathan 3735*291a2b48SSukumar Swaminathan (void) emlxs_unregister_pkt(rp, iocb_sbp->iotag, 0); 3736fcf3ce44SJohn Forte 3737fcf3ce44SJohn Forte mutex_exit(&EMLXS_RINGTX_LOCK); 3738fcf3ce44SJohn Forte 3739*291a2b48SSukumar Swaminathan rval = 1; 3740fcf3ce44SJohn Forte 3741*291a2b48SSukumar Swaminathan if (pkt) { 3742*291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt); 3743*291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = NULL; 3744fcf3ce44SJohn Forte } 3745*291a2b48SSukumar Swaminathan return (rval); 3746fcf3ce44SJohn Forte } 3747*291a2b48SSukumar Swaminathan done: 3748fcf3ce44SJohn Forte mutex_exit(&EMLXS_RINGTX_LOCK); 3749*291a2b48SSukumar Swaminathan return (rval); 3750*291a2b48SSukumar Swaminathan } 3751fcf3ce44SJohn Forte 3752fcf3ce44SJohn Forte 3753*291a2b48SSukumar Swaminathan /* FCT_NOT_FOUND & FCT_ABORT_SUCCESS indicates IO is done */ 3754*291a2b48SSukumar Swaminathan /* FCT_SUCCESS indicates abort will occur asyncronously */ 3755*291a2b48SSukumar Swaminathan static fct_status_t 3756*291a2b48SSukumar Swaminathan emlxs_fct_abort(fct_local_port_t *fct_port, fct_cmd_t *fct_cmd, 3757*291a2b48SSukumar Swaminathan uint32_t flags) 3758*291a2b48SSukumar Swaminathan { 3759*291a2b48SSukumar Swaminathan emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 3760*291a2b48SSukumar Swaminathan emlxs_hba_t *hba = HBA; 3761*291a2b48SSukumar Swaminathan emlxs_buf_t *cmd_sbp; 3762*291a2b48SSukumar Swaminathan fc_packet_t *pkt; 3763*291a2b48SSukumar Swaminathan uint32_t state; 3764*291a2b48SSukumar Swaminathan emlxs_buf_t *sbp = NULL; 3765*291a2b48SSukumar Swaminathan fct_status_t rval; 3766fcf3ce44SJohn Forte 3767*291a2b48SSukumar Swaminathan top: 3768*291a2b48SSukumar Swaminathan /* Sanity check */ 3769*291a2b48SSukumar Swaminathan if ((fct_cmd->cmd_oxid == 0) && (fct_cmd->cmd_rxid == 0)) { 3770*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3771*291a2b48SSukumar Swaminathan "emlxs_fct_abort: Invalid fct_cmd=%p.", fct_cmd); 3772fcf3ce44SJohn Forte 3773*291a2b48SSukumar Swaminathan return (FCT_NOT_FOUND); 3774*291a2b48SSukumar Swaminathan } 3775fcf3ce44SJohn Forte 3776*291a2b48SSukumar Swaminathan cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 3777*291a2b48SSukumar Swaminathan if (!(cmd_sbp->pkt_flags & PACKET_VALID)) { 3778*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3779*291a2b48SSukumar Swaminathan "emlxs_fct_abort: Invalid cmd_sbp=%p.", cmd_sbp); 3780fcf3ce44SJohn Forte 3781*291a2b48SSukumar Swaminathan return (FCT_NOT_FOUND); 3782fcf3ce44SJohn Forte } 3783fcf3ce44SJohn Forte 3784*291a2b48SSukumar Swaminathan if (mutex_tryenter(&cmd_sbp->fct_mtx) == 0) { 3785fcf3ce44SJohn Forte 3786fcf3ce44SJohn Forte /* 3787*291a2b48SSukumar Swaminathan * This code path handles a race condition if 3788*291a2b48SSukumar Swaminathan * an IO completes, in emlxs_fct_handle_fcp_event(), 3789*291a2b48SSukumar Swaminathan * and we get an abort at the same time. 3790fcf3ce44SJohn Forte */ 3791*291a2b48SSukumar Swaminathan delay(drv_usectohz(100000)); /* 100 msec */ 3792*291a2b48SSukumar Swaminathan goto top; 3793fcf3ce44SJohn Forte } 3794*291a2b48SSukumar Swaminathan /* At this point, we have entered the mutex */ 3795fcf3ce44SJohn Forte 3796fcf3ce44SJohn Forte 3797*291a2b48SSukumar Swaminathan if (!(cmd_sbp->pkt_flags & PACKET_VALID)) { 3798*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3799*291a2b48SSukumar Swaminathan "emlxs_fct_abort: Invalid cmd_sbp=%p.", cmd_sbp); 3800fcf3ce44SJohn Forte 3801*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 3802*291a2b48SSukumar Swaminathan return (FCT_NOT_FOUND); 3803fcf3ce44SJohn Forte } 3804fcf3ce44SJohn Forte 3805*291a2b48SSukumar Swaminathan if (flags & FCT_IOF_FORCE_FCA_DONE) { 3806*291a2b48SSukumar Swaminathan fct_cmd->cmd_handle = 0; 3807fcf3ce44SJohn Forte } 3808fcf3ce44SJohn Forte 3809*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3810*291a2b48SSukumar Swaminathan "emlxs_fct_abort: HbaLink %d. " 3811*291a2b48SSukumar Swaminathan "xid=%x. cmd_sbp=%p state=%d flags=%x,%x,%x", 3812*291a2b48SSukumar Swaminathan hba->state, fct_cmd->cmd_rxid, cmd_sbp, cmd_sbp->fct_state, flags, 3813*291a2b48SSukumar Swaminathan cmd_sbp->fct_flags, cmd_sbp->pkt_flags); 3814*291a2b48SSukumar Swaminathan 3815*291a2b48SSukumar Swaminathan rval = FCT_SUCCESS; 3816*291a2b48SSukumar Swaminathan state = cmd_sbp->fct_state; 3817*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_SEND_ABORT); 3818*291a2b48SSukumar Swaminathan 3819*291a2b48SSukumar Swaminathan if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT_INP) { 3820*291a2b48SSukumar Swaminathan emlxs_sli_issue_iocb_cmd(hba, cmd_sbp->ring, 0); 3821*291a2b48SSukumar Swaminathan /* If Abort is already in progress */ 3822*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 3823*291a2b48SSukumar Swaminathan return (rval); 3824*291a2b48SSukumar Swaminathan } 3825fcf3ce44SJohn Forte 3826*291a2b48SSukumar Swaminathan TGTPORTSTAT.FctAbortSent++; 3827fcf3ce44SJohn Forte 3828*291a2b48SSukumar Swaminathan switch (state) { 3829*291a2b48SSukumar Swaminathan case EMLXS_FCT_CMD_POSTED: 3830*291a2b48SSukumar Swaminathan case EMLXS_FCT_SEND_ELS_RSP: 3831*291a2b48SSukumar Swaminathan case EMLXS_FCT_SEND_ELS_REQ: 3832*291a2b48SSukumar Swaminathan case EMLXS_FCT_SEND_CT_REQ: 3833*291a2b48SSukumar Swaminathan case EMLXS_FCT_RSP_PENDING: 3834*291a2b48SSukumar Swaminathan case EMLXS_FCT_REQ_PENDING: 3835*291a2b48SSukumar Swaminathan case EMLXS_FCT_REG_PENDING: 3836*291a2b48SSukumar Swaminathan case EMLXS_FCT_REG_COMPLETE: 3837*291a2b48SSukumar Swaminathan case EMLXS_FCT_OWNED: 3838*291a2b48SSukumar Swaminathan case EMLXS_FCT_SEND_FCP_DATA: 3839*291a2b48SSukumar Swaminathan case EMLXS_FCT_SEND_FCP_STATUS: 3840*291a2b48SSukumar Swaminathan case EMLXS_FCT_DATA_PENDING: 3841*291a2b48SSukumar Swaminathan case EMLXS_FCT_STATUS_PENDING: 3842*291a2b48SSukumar Swaminathan case EMLXS_FCT_IOCB_ISSUED: 3843*291a2b48SSukumar Swaminathan case EMLXS_FCT_IOCB_COMPLETE: 3844*291a2b48SSukumar Swaminathan case EMLXS_FCT_PKT_COMPLETE: 3845*291a2b48SSukumar Swaminathan case EMLXS_FCT_PKT_FCPRSP_COMPLETE: 3846*291a2b48SSukumar Swaminathan case EMLXS_FCT_PKT_ELSRSP_COMPLETE: 3847*291a2b48SSukumar Swaminathan case EMLXS_FCT_PKT_ELSCMD_COMPLETE: 3848*291a2b48SSukumar Swaminathan case EMLXS_FCT_PKT_CTCMD_COMPLETE: 3849*291a2b48SSukumar Swaminathan case EMLXS_FCT_REQ_COMPLETE: 3850*291a2b48SSukumar Swaminathan case EMLXS_FCT_ABORT_DONE: 3851*291a2b48SSukumar Swaminathan case EMLXS_FCT_IO_DONE: 3852*291a2b48SSukumar Swaminathan if (emlxs_fct_pkt_abort_txq(port, cmd_sbp)) { 3853fcf3ce44SJohn Forte 3854*291a2b48SSukumar Swaminathan if (fct_cmd->cmd_type == FCT_CMD_FCP_XCHG) { 3855*291a2b48SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--; 3856fcf3ce44SJohn Forte } 3857*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, 3858*291a2b48SSukumar Swaminathan EMLXS_FCT_ABORT_DONE); 3859*291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3860*291a2b48SSukumar Swaminathan (void) emlxs_fct_cmd_uninit(port, fct_cmd); 3861*291a2b48SSukumar Swaminathan MODSYM(fct_cmd_fca_aborted) (fct_cmd, 3862*291a2b48SSukumar Swaminathan FCT_ABORT_SUCCESS, FCT_IOF_FCA_DONE); 3863*291a2b48SSukumar Swaminathan return (rval); 3864*291a2b48SSukumar Swaminathan } 3865fcf3ce44SJohn Forte 3866*291a2b48SSukumar Swaminathan if (!(hba->flag & FC_ONLINE_MODE)) { 3867*291a2b48SSukumar Swaminathan if ((state == EMLXS_FCT_OWNED) || 3868*291a2b48SSukumar Swaminathan (state == EMLXS_FCT_CMD_POSTED)) { 3869*291a2b48SSukumar Swaminathan 3870*291a2b48SSukumar Swaminathan if (fct_cmd->cmd_type == FCT_CMD_FCP_XCHG) { 3871*291a2b48SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--; 3872*291a2b48SSukumar Swaminathan } 3873*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, 3874*291a2b48SSukumar Swaminathan EMLXS_FCT_ABORT_DONE); 3875*291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3876*291a2b48SSukumar Swaminathan (void) emlxs_fct_cmd_uninit(port, fct_cmd); 3877*291a2b48SSukumar Swaminathan MODSYM(fct_cmd_fca_aborted) (fct_cmd, 3878*291a2b48SSukumar Swaminathan FCT_ABORT_SUCCESS, FCT_IOF_FCA_DONE); 3879*291a2b48SSukumar Swaminathan return (rval); 3880fcf3ce44SJohn Forte } 3881*291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_ABORT_INP; 3882*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 3883*291a2b48SSukumar Swaminathan return (rval); 3884fcf3ce44SJohn Forte } 3885fcf3ce44SJohn Forte 3886*291a2b48SSukumar Swaminathan if (!(pkt = emlxs_pkt_alloc(port, 0, 0, 0, KM_NOSLEEP))) { 3887*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 3888*291a2b48SSukumar Swaminathan "emlxs_fct_abort: Unable to allocate packet."); 3889*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 3890*291a2b48SSukumar Swaminathan return (rval); 3891fcf3ce44SJohn Forte } 3892fcf3ce44SJohn Forte 3893*291a2b48SSukumar Swaminathan sbp = emlxs_fct_pkt_init(port, fct_cmd, pkt); 3894*291a2b48SSukumar Swaminathan 3895*291a2b48SSukumar Swaminathan pkt->pkt_tran_type = FC_PKT_OUTBOUND; 3896*291a2b48SSukumar Swaminathan pkt->pkt_timeout = 3897*291a2b48SSukumar Swaminathan ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov); 3898*291a2b48SSukumar Swaminathan pkt->pkt_comp = emlxs_fct_abort_pkt_comp; 3899*291a2b48SSukumar Swaminathan 3900*291a2b48SSukumar Swaminathan /* Build the fc header */ 3901*291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(fct_cmd->cmd_rportid); 3902*291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.r_ctl = R_CTL_STATUS; 3903*291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = SWAP_DATA24_LO(port->did); 3904*291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.type = FC_TYPE_BASIC_LS; 3905*291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.f_ctl = 3906*291a2b48SSukumar Swaminathan (F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ); 3907*291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.seq_id = 0; 3908*291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.df_ctl = 0; 3909*291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.seq_cnt = 0; 3910*291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.ox_id = fct_cmd->cmd_oxid; 3911*291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id = fct_cmd->cmd_rxid; 3912*291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.ro = 0; 3913*291a2b48SSukumar Swaminathan 3914*291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_ABORT_INP; 3915*291a2b48SSukumar Swaminathan cmd_sbp->fct_cmd = fct_cmd; 3916*291a2b48SSukumar Swaminathan cmd_sbp->abort_attempts++; 3917fcf3ce44SJohn Forte 3918*291a2b48SSukumar Swaminathan /* Now disassociate the sbp / pkt from the fct_cmd */ 3919*291a2b48SSukumar Swaminathan sbp->fct_cmd = NULL; 3920*291a2b48SSukumar Swaminathan if (hba->state >= FC_LINK_UP) { 3921*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, 3922*291a2b48SSukumar Swaminathan EMLXS_FCT_ABORT_PENDING); 3923fcf3ce44SJohn Forte 3924*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3925*291a2b48SSukumar Swaminathan "emlxs_fct_abort: ABORT: %p xri x%x", 3926*291a2b48SSukumar Swaminathan fct_cmd, fct_cmd->cmd_rxid); 3927*291a2b48SSukumar Swaminathan } else { 3928*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, 3929*291a2b48SSukumar Swaminathan EMLXS_FCT_CLOSE_PENDING); 3930fcf3ce44SJohn Forte 3931*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3932*291a2b48SSukumar Swaminathan "emlxs_fct_abort: CLOSE: %p xri x%x", 3933*291a2b48SSukumar Swaminathan fct_cmd, fct_cmd->cmd_rxid); 3934*291a2b48SSukumar Swaminathan } 3935fcf3ce44SJohn Forte 3936*291a2b48SSukumar Swaminathan /* 3937*291a2b48SSukumar Swaminathan * If there isn't an outstanding IO, indicate the fct_cmd 3938*291a2b48SSukumar Swaminathan * is aborted now. 3939*291a2b48SSukumar Swaminathan */ 3940*291a2b48SSukumar Swaminathan if ((state == EMLXS_FCT_OWNED) || 3941*291a2b48SSukumar Swaminathan (state == EMLXS_FCT_CMD_POSTED)) { 3942fcf3ce44SJohn Forte 3943*291a2b48SSukumar Swaminathan if (fct_cmd->cmd_type == FCT_CMD_FCP_XCHG) { 3944*291a2b48SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--; 3945*291a2b48SSukumar Swaminathan } 3946*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, 3947*291a2b48SSukumar Swaminathan EMLXS_FCT_ABORT_DONE); 3948*291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3949*291a2b48SSukumar Swaminathan (void) emlxs_fct_cmd_uninit(port, fct_cmd); 3950*291a2b48SSukumar Swaminathan MODSYM(fct_cmd_fca_aborted) (fct_cmd, 3951*291a2b48SSukumar Swaminathan FCT_ABORT_SUCCESS, FCT_IOF_FCA_DONE); 3952*291a2b48SSukumar Swaminathan } 3953fcf3ce44SJohn Forte 3954*291a2b48SSukumar Swaminathan if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 3955*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 3956*291a2b48SSukumar Swaminathan "emlxs_fct_abort: Unable to send packet."); 3957fcf3ce44SJohn Forte 3958*291a2b48SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_ABORT_INP; 3959*291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt); 3960fcf3ce44SJohn Forte 3961*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 3962*291a2b48SSukumar Swaminathan return (rval); 3963*291a2b48SSukumar Swaminathan } 3964*291a2b48SSukumar Swaminathan break; 3965fcf3ce44SJohn Forte 3966*291a2b48SSukumar Swaminathan case EMLXS_FCT_CMD_WAITQ: 3967*291a2b48SSukumar Swaminathan case EMLXS_FCT_FCP_CMD_RECEIVED: 3968*291a2b48SSukumar Swaminathan case EMLXS_FCT_ELS_CMD_RECEIVED: 3969*291a2b48SSukumar Swaminathan case EMLXS_FCT_SEND_ABORT: 3970*291a2b48SSukumar Swaminathan case EMLXS_FCT_CLOSE_PENDING: 3971*291a2b48SSukumar Swaminathan case EMLXS_FCT_ABORT_PENDING: 3972*291a2b48SSukumar Swaminathan case EMLXS_FCT_ABORT_COMPLETE: 3973*291a2b48SSukumar Swaminathan default: 3974*291a2b48SSukumar Swaminathan emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED); 3975*291a2b48SSukumar Swaminathan rval = FCT_FAILURE; 3976*291a2b48SSukumar Swaminathan break; 3977fcf3ce44SJohn Forte 3978*291a2b48SSukumar Swaminathan } /* switch */ 3979fcf3ce44SJohn Forte 3980*291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 3981*291a2b48SSukumar Swaminathan return (rval); 3982fcf3ce44SJohn Forte 3983*291a2b48SSukumar Swaminathan } /* emlxs_fct_abort() */ 3984fcf3ce44SJohn Forte 3985fcf3ce44SJohn Forte 3986fcf3ce44SJohn Forte extern void 3987fcf3ce44SJohn Forte emlxs_fct_link_up(emlxs_port_t *port) 3988fcf3ce44SJohn Forte { 3989fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 3990fcf3ce44SJohn Forte 3991fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 3992fcf3ce44SJohn Forte 3993fcf3ce44SJohn Forte if (port->fct_port && 3994fcf3ce44SJohn Forte (port->fct_flags & FCT_STATE_PORT_ONLINE) && 3995fcf3ce44SJohn Forte !(port->fct_flags & FCT_STATE_LINK_UP)) { 3996fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3997fcf3ce44SJohn Forte "emlxs_fct_link_up event."); 3998fcf3ce44SJohn Forte 3999fcf3ce44SJohn Forte port->fct_flags |= FCT_STATE_LINK_UP; 4000fcf3ce44SJohn Forte 4001fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 4002fcf3ce44SJohn Forte 4003fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 4004fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 4005fcf3ce44SJohn Forte "fct_handle_event LINK_UP"); 4006*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 4007*291a2b48SSukumar Swaminathan MODSYM(fct_handle_event) (port->fct_port, FCT_EVENT_LINK_UP, 4008*291a2b48SSukumar Swaminathan 0, 0); 4009fcf3ce44SJohn Forte 4010fcf3ce44SJohn Forte emlxs_fct_unsol_flush(port); 4011fcf3ce44SJohn Forte } else { 4012fcf3ce44SJohn Forte if (!hba->ini_mode && 4013fcf3ce44SJohn Forte !(port->fct_flags & FCT_STATE_PORT_ONLINE)) { 4014fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 4015fcf3ce44SJohn Forte 4016fcf3ce44SJohn Forte /* Take link down and hold it down */ 4017fcf3ce44SJohn Forte (void) emlxs_reset_link(hba, 0); 4018fcf3ce44SJohn Forte } else { 4019fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 4020fcf3ce44SJohn Forte } 4021fcf3ce44SJohn Forte } 4022fcf3ce44SJohn Forte 4023fcf3ce44SJohn Forte return; 4024fcf3ce44SJohn Forte 4025*291a2b48SSukumar Swaminathan } /* emlxs_fct_link_up() */ 4026*291a2b48SSukumar Swaminathan 4027fcf3ce44SJohn Forte 4028fcf3ce44SJohn Forte extern void 4029fcf3ce44SJohn Forte emlxs_fct_link_down(emlxs_port_t *port) 4030fcf3ce44SJohn Forte { 4031fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 4032fcf3ce44SJohn Forte 4033fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 4034fcf3ce44SJohn Forte 4035fcf3ce44SJohn Forte if (port->fct_port && 4036fcf3ce44SJohn Forte (port->fct_flags & FCT_STATE_PORT_ONLINE) && 4037fcf3ce44SJohn Forte (port->fct_flags & FCT_STATE_LINK_UP)) { 4038fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4039fcf3ce44SJohn Forte "emlxs_fct_link_down event."); 4040fcf3ce44SJohn Forte 4041fcf3ce44SJohn Forte port->fct_flags &= ~FCT_STATE_LINK_UP; 4042fcf3ce44SJohn Forte 4043fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 4044fcf3ce44SJohn Forte 4045fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 4046fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 4047fcf3ce44SJohn Forte "fct_handle_event LINK_DOWN"); 4048*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 4049*291a2b48SSukumar Swaminathan MODSYM(fct_handle_event) (port->fct_port, FCT_EVENT_LINK_DOWN, 4050*291a2b48SSukumar Swaminathan 0, 0); 4051fcf3ce44SJohn Forte } else { 4052fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 4053fcf3ce44SJohn Forte } 4054fcf3ce44SJohn Forte 4055fcf3ce44SJohn Forte return; 4056fcf3ce44SJohn Forte 4057*291a2b48SSukumar Swaminathan } /* emlxs_fct_link_down() */ 4058fcf3ce44SJohn Forte 4059fcf3ce44SJohn Forte 4060*291a2b48SSukumar Swaminathan /* DMA FUNCTIONS */ 4061fcf3ce44SJohn Forte 4062fcf3ce44SJohn Forte fct_status_t 4063fcf3ce44SJohn Forte emlxs_fct_dmem_init(emlxs_port_t *port) 4064fcf3ce44SJohn Forte { 4065fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 4066fcf3ce44SJohn Forte emlxs_fct_dmem_bucket_t *p; 4067fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *bctl; 4068fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *bc; 4069fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *prev; 4070fcf3ce44SJohn Forte int32_t j; 4071fcf3ce44SJohn Forte int32_t i; 4072fcf3ce44SJohn Forte uint32_t total_mem; 4073fcf3ce44SJohn Forte uint8_t *addr; 4074fcf3ce44SJohn Forte uint8_t *host_addr; 4075fcf3ce44SJohn Forte uint64_t dev_addr; 4076fcf3ce44SJohn Forte ddi_dma_cookie_t cookie; 4077fcf3ce44SJohn Forte uint32_t ncookie; 4078fcf3ce44SJohn Forte uint32_t bsize; 4079fcf3ce44SJohn Forte size_t len; 4080fcf3ce44SJohn Forte char buf[64]; 4081fcf3ce44SJohn Forte ddi_device_acc_attr_t acc; 4082fcf3ce44SJohn Forte 4083fcf3ce44SJohn Forte bzero(&acc, sizeof (acc)); 4084fcf3ce44SJohn Forte acc.devacc_attr_version = DDI_DEVICE_ATTR_V0; 4085fcf3ce44SJohn Forte acc.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC; 4086fcf3ce44SJohn Forte acc.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 4087fcf3ce44SJohn Forte 4088fcf3ce44SJohn Forte p = port->dmem_bucket; 4089fcf3ce44SJohn Forte for (i = 0; i < FCT_MAX_BUCKETS; i++, p++) { 4090fcf3ce44SJohn Forte if (!p->dmem_nbufs) { 4091fcf3ce44SJohn Forte continue; 4092fcf3ce44SJohn Forte } 4093*291a2b48SSukumar Swaminathan 4094fcf3ce44SJohn Forte bctl = (emlxs_fct_dmem_bctl_t *)kmem_zalloc(p->dmem_nbufs * 4095fcf3ce44SJohn Forte sizeof (emlxs_fct_dmem_bctl_t), KM_NOSLEEP); 4096fcf3ce44SJohn Forte 4097fcf3ce44SJohn Forte if (bctl == NULL) { 4098fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4099fcf3ce44SJohn Forte "emlxs_fct_dmem_init: Unable to allocate bctl."); 4100fcf3ce44SJohn Forte goto alloc_bctl_failed; 4101fcf3ce44SJohn Forte } 4102*291a2b48SSukumar Swaminathan 4103fcf3ce44SJohn Forte p->dmem_bctls_mem = bctl; 4104fcf3ce44SJohn Forte 4105fcf3ce44SJohn Forte if (ddi_dma_alloc_handle(hba->dip, &emlxs_dma_attr_1sg, 4106fcf3ce44SJohn Forte DDI_DMA_SLEEP, 0, &p->dmem_dma_handle) != DDI_SUCCESS) { 4107fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4108fcf3ce44SJohn Forte "emlxs_fct_dmem_init: Unable to allocate handle."); 4109fcf3ce44SJohn Forte goto alloc_handle_failed; 4110fcf3ce44SJohn Forte } 4111fcf3ce44SJohn Forte 4112fcf3ce44SJohn Forte total_mem = p->dmem_buf_size * p->dmem_nbufs; 4113fcf3ce44SJohn Forte 4114fcf3ce44SJohn Forte if (ddi_dma_mem_alloc(p->dmem_dma_handle, total_mem, &acc, 4115*291a2b48SSukumar Swaminathan DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, 0, 4116*291a2b48SSukumar Swaminathan (caddr_t *)&addr, &len, 4117*291a2b48SSukumar Swaminathan &p->dmem_acc_handle) != DDI_SUCCESS) { 4118fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4119fcf3ce44SJohn Forte "emlxs_fct_dmem_init: Unable to allocate memory."); 4120fcf3ce44SJohn Forte goto mem_alloc_failed; 4121fcf3ce44SJohn Forte } 4122fcf3ce44SJohn Forte 4123fcf3ce44SJohn Forte if (ddi_dma_addr_bind_handle(p->dmem_dma_handle, NULL, 4124*291a2b48SSukumar Swaminathan (caddr_t)addr, total_mem, 4125*291a2b48SSukumar Swaminathan DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, 0, 4126*291a2b48SSukumar Swaminathan &cookie, &ncookie) != DDI_SUCCESS) { 4127fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4128fcf3ce44SJohn Forte "emlxs_fct_dmem_init: Unable to bind handle."); 4129fcf3ce44SJohn Forte goto addr_bind_handle_failed; 4130fcf3ce44SJohn Forte } 4131fcf3ce44SJohn Forte 4132fcf3ce44SJohn Forte if (ncookie != 1) { 4133fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4134fcf3ce44SJohn Forte "emlxs_fct_dmem_init: DMEM init failed."); 4135fcf3ce44SJohn Forte goto dmem_init_failed; 4136fcf3ce44SJohn Forte } 4137fcf3ce44SJohn Forte (void) sprintf(buf, "%s%d_bucket%d mutex", DRIVER_NAME, 4138fcf3ce44SJohn Forte hba->ddiinst, i); 4139fcf3ce44SJohn Forte mutex_init(&p->dmem_lock, buf, MUTEX_DRIVER, 4140fcf3ce44SJohn Forte (void *)hba->intr_arg); 4141fcf3ce44SJohn Forte 4142fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4143fcf3ce44SJohn Forte "bufsize=%d cnt=%d", p->dmem_buf_size, p->dmem_nbufs); 4144fcf3ce44SJohn Forte 4145fcf3ce44SJohn Forte host_addr = addr; 4146fcf3ce44SJohn Forte dev_addr = (uint64_t)cookie.dmac_laddress; 4147fcf3ce44SJohn Forte 4148fcf3ce44SJohn Forte p->dmem_host_addr = addr; 4149fcf3ce44SJohn Forte p->dmem_dev_addr = dev_addr; 4150fcf3ce44SJohn Forte p->dmem_bctl_free_list = bctl; 4151fcf3ce44SJohn Forte p->dmem_nbufs_free = p->dmem_nbufs; 4152fcf3ce44SJohn Forte bsize = p->dmem_buf_size; 4153fcf3ce44SJohn Forte 4154fcf3ce44SJohn Forte for (j = 0; j < p->dmem_nbufs; j++) { 4155fcf3ce44SJohn Forte stmf_data_buf_t *db; 4156fcf3ce44SJohn Forte 4157fcf3ce44SJohn Forte db = MODSYM(stmf_alloc) (STMF_STRUCT_DATA_BUF, 0, 0); 4158fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 4159fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 4160fcf3ce44SJohn Forte "stmf_alloc data_buf %p", db); 4161*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 4162fcf3ce44SJohn Forte if (db == NULL) { 4163fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4164*291a2b48SSukumar Swaminathan "emlxs_fct_dmem_init: alloc failed."); 4165fcf3ce44SJohn Forte goto dmem_init_failed; 4166fcf3ce44SJohn Forte } 4167fcf3ce44SJohn Forte db->db_port_private = bctl; 4168fcf3ce44SJohn Forte db->db_sglist[0].seg_addr = host_addr; 4169fcf3ce44SJohn Forte db->db_sglist[0].seg_length = bsize; 4170fcf3ce44SJohn Forte db->db_buf_size = bsize; 4171fcf3ce44SJohn Forte db->db_sglist_length = 1; 4172fcf3ce44SJohn Forte 4173fcf3ce44SJohn Forte bctl->bctl_bucket = p; 4174fcf3ce44SJohn Forte bctl->bctl_buf = db; 4175fcf3ce44SJohn Forte bctl->bctl_dev_addr = dev_addr; 4176fcf3ce44SJohn Forte 4177fcf3ce44SJohn Forte host_addr += bsize; 4178fcf3ce44SJohn Forte dev_addr += bsize; 4179fcf3ce44SJohn Forte 4180fcf3ce44SJohn Forte prev = bctl; 4181fcf3ce44SJohn Forte bctl++; 4182fcf3ce44SJohn Forte prev->bctl_next = bctl; 4183fcf3ce44SJohn Forte } 4184fcf3ce44SJohn Forte 4185fcf3ce44SJohn Forte prev->bctl_next = NULL; 4186fcf3ce44SJohn Forte } 4187fcf3ce44SJohn Forte 4188fcf3ce44SJohn Forte return (FCT_SUCCESS); 4189fcf3ce44SJohn Forte 4190fcf3ce44SJohn Forte dmem_failure_loop: 4191fcf3ce44SJohn Forte mutex_destroy(&p->dmem_lock); 4192fcf3ce44SJohn Forte bc = bctl; 4193fcf3ce44SJohn Forte while (bc) { 4194fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 4195fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 4196fcf3ce44SJohn Forte "stmf_free:3 %p", bctl->bctl_buf); 4197*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 4198fcf3ce44SJohn Forte MODSYM(stmf_free) (bc->bctl_buf); 4199fcf3ce44SJohn Forte bc = bc->bctl_next; 4200fcf3ce44SJohn Forte } 4201fcf3ce44SJohn Forte 4202fcf3ce44SJohn Forte dmem_init_failed: 4203fcf3ce44SJohn Forte (void) ddi_dma_unbind_handle(p->dmem_dma_handle); 4204fcf3ce44SJohn Forte 4205fcf3ce44SJohn Forte addr_bind_handle_failed: 4206fcf3ce44SJohn Forte (void) ddi_dma_mem_free(&p->dmem_acc_handle); 4207fcf3ce44SJohn Forte 4208fcf3ce44SJohn Forte mem_alloc_failed: 4209fcf3ce44SJohn Forte (void) ddi_dma_free_handle(&p->dmem_dma_handle); 4210fcf3ce44SJohn Forte 4211fcf3ce44SJohn Forte alloc_handle_failed: 4212fcf3ce44SJohn Forte kmem_free(p->dmem_bctls_mem, 4213fcf3ce44SJohn Forte p->dmem_nbufs * sizeof (emlxs_fct_dmem_bctl_t)); 4214fcf3ce44SJohn Forte 4215fcf3ce44SJohn Forte alloc_bctl_failed: 4216fcf3ce44SJohn Forte if (--i >= 0) { 4217fcf3ce44SJohn Forte p = &port->dmem_bucket[i]; 4218fcf3ce44SJohn Forte bctl = p->dmem_bctl_free_list; 4219fcf3ce44SJohn Forte goto dmem_failure_loop; 4220fcf3ce44SJohn Forte } 4221fcf3ce44SJohn Forte 4222*291a2b48SSukumar Swaminathan return (FCT_FAILURE); 4223fcf3ce44SJohn Forte 4224*291a2b48SSukumar Swaminathan } /* emlxs_fct_dmem_init() */ 4225fcf3ce44SJohn Forte 4226fcf3ce44SJohn Forte 4227fcf3ce44SJohn Forte void 4228fcf3ce44SJohn Forte emlxs_fct_dmem_fini(emlxs_port_t *port) 4229fcf3ce44SJohn Forte { 4230fcf3ce44SJohn Forte emlxs_fct_dmem_bucket_t *p; 4231fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *bctl; 4232fcf3ce44SJohn Forte uint32_t i; 4233fcf3ce44SJohn Forte 4234fcf3ce44SJohn Forte p = port->dmem_bucket; 4235fcf3ce44SJohn Forte for (i = 0; i < FCT_MAX_BUCKETS; i++, p++) { 4236fcf3ce44SJohn Forte if (!p->dmem_nbufs) { 4237fcf3ce44SJohn Forte continue; 4238fcf3ce44SJohn Forte } 4239*291a2b48SSukumar Swaminathan 4240fcf3ce44SJohn Forte bctl = p->dmem_bctl_free_list; 4241fcf3ce44SJohn Forte 4242fcf3ce44SJohn Forte while (bctl) { 4243fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 4244fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 4245fcf3ce44SJohn Forte "stmf_free:4 %p", bctl->bctl_buf); 4246*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 4247fcf3ce44SJohn Forte MODSYM(stmf_free) (bctl->bctl_buf); 4248fcf3ce44SJohn Forte bctl = bctl->bctl_next; 4249fcf3ce44SJohn Forte } 4250fcf3ce44SJohn Forte 4251fcf3ce44SJohn Forte bctl = p->dmem_bctl_free_list; 4252fcf3ce44SJohn Forte 4253fcf3ce44SJohn Forte (void) ddi_dma_unbind_handle(p->dmem_dma_handle); 4254fcf3ce44SJohn Forte (void) ddi_dma_mem_free(&p->dmem_acc_handle); 4255fcf3ce44SJohn Forte (void) ddi_dma_free_handle(&p->dmem_dma_handle); 4256fcf3ce44SJohn Forte 4257fcf3ce44SJohn Forte kmem_free(p->dmem_bctls_mem, 4258fcf3ce44SJohn Forte (p->dmem_nbufs * sizeof (emlxs_fct_dmem_bctl_t))); 4259fcf3ce44SJohn Forte mutex_destroy(&p->dmem_lock); 4260fcf3ce44SJohn Forte } 4261fcf3ce44SJohn Forte 4262fcf3ce44SJohn Forte bzero((uint8_t *)port->dmem_bucket, sizeof (port->dmem_bucket)); 4263fcf3ce44SJohn Forte 4264fcf3ce44SJohn Forte return; 4265fcf3ce44SJohn Forte 4266*291a2b48SSukumar Swaminathan } /* emlxs_fct_dmem_fini() */ 4267fcf3ce44SJohn Forte 4268fcf3ce44SJohn Forte 4269fcf3ce44SJohn Forte /* ARGSUSED */ 4270fcf3ce44SJohn Forte static stmf_data_buf_t * 4271fcf3ce44SJohn Forte emlxs_fct_dbuf_alloc(fct_local_port_t *fct_port, uint32_t size, 4272fcf3ce44SJohn Forte uint32_t *pminsize, uint32_t flags) 4273fcf3ce44SJohn Forte { 4274fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 4275fcf3ce44SJohn Forte emlxs_fct_dmem_bucket_t *p; 4276fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *bctl; 4277fcf3ce44SJohn Forte uint32_t i; 4278fcf3ce44SJohn Forte 4279fcf3ce44SJohn Forte if (size > FCT_DMEM_MAX_BUF_SIZE) { 4280fcf3ce44SJohn Forte size = FCT_DMEM_MAX_BUF_SIZE; 4281fcf3ce44SJohn Forte } 4282*291a2b48SSukumar Swaminathan 4283fcf3ce44SJohn Forte p = port->dmem_bucket; 4284fcf3ce44SJohn Forte for (i = 0; i < FCT_MAX_BUCKETS; i++, p++) { 4285fcf3ce44SJohn Forte if (!p->dmem_nbufs) { 4286fcf3ce44SJohn Forte continue; 4287fcf3ce44SJohn Forte } 4288*291a2b48SSukumar Swaminathan 4289fcf3ce44SJohn Forte if (p->dmem_buf_size >= size) { 4290fcf3ce44SJohn Forte mutex_enter(&p->dmem_lock); 4291fcf3ce44SJohn Forte if (p->dmem_nbufs_free) { 4292fcf3ce44SJohn Forte if (p->dmem_buf_size < *pminsize) { 4293fcf3ce44SJohn Forte *pminsize = p->dmem_buf_size; 4294fcf3ce44SJohn Forte TGTPORTSTAT.FctNoBuffer++; 4295fcf3ce44SJohn Forte 4296fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 4297fcf3ce44SJohn Forte &emlxs_fct_api_msg, 4298fcf3ce44SJohn Forte "emlxs_fct_dbuf_alloc: Failed(1)."); 4299fcf3ce44SJohn Forte mutex_exit(&p->dmem_lock); 4300fcf3ce44SJohn Forte return (NULL); 4301fcf3ce44SJohn Forte } 4302*291a2b48SSukumar Swaminathan 4303fcf3ce44SJohn Forte bctl = p->dmem_bctl_free_list; 4304fcf3ce44SJohn Forte if (bctl == NULL) { 4305fcf3ce44SJohn Forte mutex_exit(&p->dmem_lock); 4306fcf3ce44SJohn Forte continue; 4307fcf3ce44SJohn Forte } 4308*291a2b48SSukumar Swaminathan 4309fcf3ce44SJohn Forte p->dmem_bctl_free_list = bctl->bctl_next; 4310fcf3ce44SJohn Forte p->dmem_nbufs_free--; 4311fcf3ce44SJohn Forte bctl->bctl_buf->db_data_size = size; 4312fcf3ce44SJohn Forte mutex_exit(&p->dmem_lock); 4313fcf3ce44SJohn Forte 4314fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 4315fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 4316fcf3ce44SJohn Forte "emlx_fct_buf_alloc size %p: %d", 4317fcf3ce44SJohn Forte bctl->bctl_buf, size); 4318*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 4319fcf3ce44SJohn Forte 4320fcf3ce44SJohn Forte return (bctl->bctl_buf); 4321fcf3ce44SJohn Forte } 4322fcf3ce44SJohn Forte mutex_exit(&p->dmem_lock); 4323fcf3ce44SJohn Forte 4324fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4325fcf3ce44SJohn Forte "emlx_fct_buf_alloc size %d Nothing free bck %d", 4326fcf3ce44SJohn Forte size, i); 4327fcf3ce44SJohn Forte } 4328fcf3ce44SJohn Forte } 4329fcf3ce44SJohn Forte 4330fcf3ce44SJohn Forte *pminsize = 0; 4331fcf3ce44SJohn Forte TGTPORTSTAT.FctNoBuffer++; 4332fcf3ce44SJohn Forte 4333fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 4334fcf3ce44SJohn Forte "emlxs_fct_dbuf_alloc: Failed(2)."); 4335fcf3ce44SJohn Forte 4336fcf3ce44SJohn Forte return (NULL); 4337fcf3ce44SJohn Forte 4338*291a2b48SSukumar Swaminathan } /* emlxs_fct_dbuf_alloc() */ 4339fcf3ce44SJohn Forte 4340fcf3ce44SJohn Forte 4341*291a2b48SSukumar Swaminathan /*ARGSUSED*/ 4342fcf3ce44SJohn Forte static void 4343fcf3ce44SJohn Forte emlxs_fct_dbuf_free(fct_dbuf_store_t *fds, stmf_data_buf_t *dbuf) 4344fcf3ce44SJohn Forte { 4345fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *bctl = 4346fcf3ce44SJohn Forte (emlxs_fct_dmem_bctl_t *)dbuf->db_port_private; 4347fcf3ce44SJohn Forte emlxs_fct_dmem_bucket_t *p = bctl->bctl_bucket; 4348fcf3ce44SJohn Forte 4349fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 4350fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 4351fcf3ce44SJohn Forte "emlx_fct_buf_free %p", dbuf); 4352*291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 4353fcf3ce44SJohn Forte 4354fcf3ce44SJohn Forte mutex_enter(&p->dmem_lock); 4355fcf3ce44SJohn Forte bctl->bctl_next = p->dmem_bctl_free_list; 4356fcf3ce44SJohn Forte p->dmem_bctl_free_list = bctl; 4357fcf3ce44SJohn Forte p->dmem_nbufs_free++; 4358fcf3ce44SJohn Forte mutex_exit(&p->dmem_lock); 4359fcf3ce44SJohn Forte 4360*291a2b48SSukumar Swaminathan } /* emlxs_fct_dbuf_free() */ 4361fcf3ce44SJohn Forte 4362fcf3ce44SJohn Forte 4363*291a2b48SSukumar Swaminathan static void 4364fcf3ce44SJohn Forte emlxs_fct_dbuf_dma_sync(stmf_data_buf_t *dbuf, uint_t sync_type) 4365fcf3ce44SJohn Forte { 4366fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *bctl = 4367fcf3ce44SJohn Forte (emlxs_fct_dmem_bctl_t *)dbuf->db_port_private; 4368fcf3ce44SJohn Forte emlxs_fct_dmem_bucket_t *p = bctl->bctl_bucket; 4369fcf3ce44SJohn Forte 4370fcf3ce44SJohn Forte (void) ddi_dma_sync(p->dmem_dma_handle, 4371fcf3ce44SJohn Forte (unsigned long)(bctl->bctl_dev_addr - p->dmem_dev_addr), 4372fcf3ce44SJohn Forte dbuf->db_data_size, sync_type); 4373fcf3ce44SJohn Forte 4374*291a2b48SSukumar Swaminathan } /* emlxs_fct_dbuf_dma_sync() */ 4375fcf3ce44SJohn Forte 4376fcf3ce44SJohn Forte 4377*291a2b48SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 4378