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 /* 23bce54adfSSukumar Swaminathan * Copyright 2010 Emulex. All rights reserved. 2482527734SSukumar Swaminathan * Use is subject to license terms. 25fcf3ce44SJohn Forte */ 26fcf3ce44SJohn Forte 2782527734SSukumar Swaminathan 28291a2b48SSukumar Swaminathan #include <emlxs.h> 29fcf3ce44SJohn Forte 30fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT 31fcf3ce44SJohn Forte 32fcf3ce44SJohn Forte 33fcf3ce44SJohn Forte /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 34fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_FCT_C); 35fcf3ce44SJohn Forte 3682527734SSukumar Swaminathan static fct_status_t emlxs_fct_cmd_acquire(emlxs_port_t *port, 3782527734SSukumar Swaminathan fct_cmd_t *fct_cmd, uint16_t fct_state); 3882527734SSukumar Swaminathan static fct_status_t emlxs_fct_cmd_accept(emlxs_port_t *port, 3982527734SSukumar Swaminathan fct_cmd_t *fct_cmd, uint16_t fct_state); 4082527734SSukumar Swaminathan static void emlxs_fct_cmd_release(emlxs_port_t *port, fct_cmd_t *fct_cmd, 4182527734SSukumar Swaminathan uint16_t fct_state); 42fcf3ce44SJohn Forte 43291a2b48SSukumar Swaminathan static emlxs_buf_t *emlxs_fct_cmd_init(emlxs_port_t *port, 44*a9800bebSGarrett D'Amore fct_cmd_t *fct_cmd, uint16_t fct_state); 4582527734SSukumar Swaminathan static void emlxs_fct_cmd_done(emlxs_port_t *port, fct_cmd_t *fct_cmd, 4682527734SSukumar Swaminathan uint16_t fct_state); 4782527734SSukumar Swaminathan static void emlxs_fct_cmd_post(emlxs_port_t *port, fct_cmd_t *fct_cmd, 4882527734SSukumar Swaminathan uint16_t fct_state); 49fcf3ce44SJohn Forte 5082527734SSukumar Swaminathan static fct_status_t emlxs_fct_flogi_xchg(struct fct_local_port *fct_port, 51fcf3ce44SJohn Forte struct fct_flogi_xchg *fx); 52fcf3ce44SJohn Forte static fct_status_t emlxs_fct_get_link_info(fct_local_port_t *fct_port, 53fcf3ce44SJohn Forte fct_link_info_t *link); 54fcf3ce44SJohn Forte static fct_status_t emlxs_fct_deregister_remote_port(fct_local_port_t *fct_port, 55fcf3ce44SJohn Forte fct_remote_port_t *port_handle); 56fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_cmd(fct_cmd_t *fct_cmd); 57fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_fcp_data(fct_cmd_t *fct_cmd, 58fcf3ce44SJohn Forte stmf_data_buf_t *dbuf, uint32_t ioflags); 59291a2b48SSukumar Swaminathan static fct_status_t emlxs_fct_send_cmd_rsp(fct_cmd_t *fct_cmd, uint32_t flags); 60291a2b48SSukumar Swaminathan static fct_status_t emlxs_fct_abort(fct_local_port_t *fct_port, 61291a2b48SSukumar Swaminathan fct_cmd_t *cmd, uint32_t flags); 62fcf3ce44SJohn Forte static void emlxs_fct_ctl(fct_local_port_t *fct_port, int cmd, void *arg); 63fcf3ce44SJohn Forte static fct_status_t emlxs_fct_register_remote_port(fct_local_port_t *fct_port, 64fcf3ce44SJohn Forte fct_remote_port_t *port_handle, fct_cmd_t *plogi); 65fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_els_cmd(fct_cmd_t *fct_cmd); 66fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_ct_cmd(fct_cmd_t *fct_cmd); 67fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_fcp_status(fct_cmd_t *fct_cmd); 68fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_els_rsp(fct_cmd_t *fct_cmd); 69fcf3ce44SJohn Forte static void emlxs_fct_pkt_comp(fc_packet_t *pkt); 7082527734SSukumar Swaminathan static void emlxs_fct_populate_hba_details(fct_local_port_t *fct_port, 71fcf3ce44SJohn Forte fct_port_attrs_t *port_attrs); 7282527734SSukumar Swaminathan static fct_status_t emlxs_fct_port_info(uint32_t cmd, 7382527734SSukumar Swaminathan fct_local_port_t *fct_port, void *arg, uint8_t *buffer, uint32_t *size); 74fcf3ce44SJohn Forte 75fcf3ce44SJohn Forte static fct_status_t emlxs_fct_dmem_init(emlxs_port_t *port); 76fcf3ce44SJohn Forte static void emlxs_fct_dmem_fini(emlxs_port_t *port); 77fcf3ce44SJohn Forte 78fcf3ce44SJohn Forte static stmf_data_buf_t *emlxs_fct_dbuf_alloc(fct_local_port_t *fct_port, 79fcf3ce44SJohn Forte uint32_t size, uint32_t *pminsize, uint32_t flags); 80fcf3ce44SJohn Forte static void emlxs_fct_dbuf_free(fct_dbuf_store_t *fds, stmf_data_buf_t *dbuf); 81fcf3ce44SJohn Forte 82b3660a96SSukumar Swaminathan static int emlxs_fct_dbuf_dma_sync(emlxs_hba_t *hba, stmf_data_buf_t *dbuf, 83b3660a96SSukumar Swaminathan uint_t sync_type); 84291a2b48SSukumar Swaminathan static emlxs_buf_t *emlxs_fct_pkt_init(emlxs_port_t *port, 85291a2b48SSukumar Swaminathan fct_cmd_t *fct_cmd, fc_packet_t *pkt); 86fcf3ce44SJohn Forte 87fcf3ce44SJohn Forte static void emlxs_fct_unsol_flush(emlxs_port_t *port); 8882527734SSukumar Swaminathan static uint32_t emlxs_fct_process_unsol_flogi(emlxs_port_t *port, 8982527734SSukumar Swaminathan CHANNEL *cp, IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 9082527734SSukumar Swaminathan static uint32_t emlxs_fct_process_unsol_plogi(emlxs_port_t *port, 9182527734SSukumar Swaminathan CHANNEL *cp, IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 92fe199829SSukumar Swaminathan static uint32_t emlxs_fct_pkt_abort_txq(emlxs_port_t *port, 93fe199829SSukumar Swaminathan emlxs_buf_t *cmd_sbp); 94fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_qfull_reply(emlxs_port_t *port, 95fcf3ce44SJohn Forte emlxs_node_t *ndlp, uint16_t xid, uint32_t class, emlxs_fcp_cmd_t *fcp_cmd); 96291a2b48SSukumar Swaminathan 97291a2b48SSukumar Swaminathan #ifdef FCT_IO_TRACE 98291a2b48SSukumar Swaminathan uint8_t *emlxs_iotrace = 0; /* global for mdb */ 99291a2b48SSukumar Swaminathan int emlxs_iotrace_cnt = 0; 100291a2b48SSukumar Swaminathan 10182527734SSukumar Swaminathan /* 10282527734SSukumar Swaminathan * 10382527734SSukumar Swaminathan * FCT_CMD (cmd_sbp->fct_state) 10482527734SSukumar Swaminathan * 10582527734SSukumar Swaminathan * STATE LOCK STATUS OWNER 10682527734SSukumar Swaminathan * ----------------------------------------------------------------------------- 10782527734SSukumar Swaminathan * EMLXS_FCT_ABORT_DONE Lock Destroyed COMSTAR 10882527734SSukumar Swaminathan * EMLXS_FCT_IO_DONE Lock Destroyed COMSTAR 10982527734SSukumar Swaminathan * 11082527734SSukumar Swaminathan * EMLXS_FCT_CMD_POSTED Lock Released COMSTAR 11182527734SSukumar Swaminathan * EMLXS_FCT_OWNED Lock Released COMSTAR 11282527734SSukumar Swaminathan * 11382527734SSukumar Swaminathan * EMLXS_FCT_CMD_WAITQ Lock Released DRIVER 11482527734SSukumar Swaminathan * EMLXS_FCT_RSP_PENDING Lock Released DRIVER 11582527734SSukumar Swaminathan * EMLXS_FCT_REQ_PENDING Lock Released DRIVER 11682527734SSukumar Swaminathan * EMLXS_FCT_REG_PENDING Lock Released DRIVER 11782527734SSukumar Swaminathan * EMLXS_FCT_DATA_PENDING Lock Released DRIVER 11882527734SSukumar Swaminathan * EMLXS_FCT_STATUS_PENDING Lock Released DRIVER 11982527734SSukumar Swaminathan * EMLXS_FCT_CLOSE_PENDING Lock Released DRIVER 12082527734SSukumar Swaminathan * EMLXS_FCT_ABORT_PENDING Lock Released DRIVER 12182527734SSukumar Swaminathan * 12282527734SSukumar Swaminathan * EMLXS_FCT_FCP_CMD_RECEIVED Transistional, lock held DRIVER 12382527734SSukumar Swaminathan * EMLXS_FCT_ELS_CMD_RECEIVED Transistional, lock held DRIVER 12482527734SSukumar Swaminathan * EMLXS_FCT_SEND_CMD_RSP Transistional, lock held DRIVER 12582527734SSukumar Swaminathan * EMLXS_FCT_SEND_ELS_RSP Transistional, lock held DRIVER 12682527734SSukumar Swaminathan * EMLXS_FCT_SEND_ELS_REQ Transistional, lock held DRIVER 12782527734SSukumar Swaminathan * EMLXS_FCT_SEND_CT_REQ Transistional, lock held DRIVER 12882527734SSukumar Swaminathan * EMLXS_FCT_REG_COMPLETE Transistional, lock held DRIVER 12982527734SSukumar Swaminathan * EMLXS_FCT_SEND_FCP_DATA Transistional, lock held DRIVER 13082527734SSukumar Swaminathan * EMLXS_FCT_SEND_FCP_STATUS Transistional, lock held DRIVER 13182527734SSukumar Swaminathan * EMLXS_FCT_PKT_COMPLETE Transistional, lock held DRIVER 13282527734SSukumar Swaminathan * EMLXS_FCT_PKT_FCPRSP_COMPLETE Transistional, lock held DRIVER 13382527734SSukumar Swaminathan * EMLXS_FCT_PKT_ELSRSP_COMPLETE Transistional, lock held DRIVER 13482527734SSukumar Swaminathan * EMLXS_FCT_PKT_ELSCMD_COMPLETE Transistional, lock held DRIVER 13582527734SSukumar Swaminathan * EMLXS_FCT_PKT_CTCMD_COMPLETE Transistional, lock held DRIVER 13682527734SSukumar Swaminathan * EMLXS_FCT_REQ_COMPLETE Transistional, lock held DRIVER 13782527734SSukumar Swaminathan * 13882527734SSukumar Swaminathan * 13982527734SSukumar Swaminathan * COMSTAR OWNED DRIVER OWNED 14082527734SSukumar Swaminathan * ------------- --------------------------------------------------- 14182527734SSukumar Swaminathan * ------- > @ Accept---- >Release @ Acquire--- >+ 14282527734SSukumar Swaminathan * | 14382527734SSukumar Swaminathan * < ------- @ Post/Done< ----Acquire @ Release< ---+ 14482527734SSukumar Swaminathan * 14582527734SSukumar Swaminathan * @ :Indicates COMSTAR use of emlxs_fct_abort() 14682527734SSukumar Swaminathan * Abort requests set the EMLXS_FCT_ABORT_INP flag. 14782527734SSukumar Swaminathan * 14882527734SSukumar Swaminathan * Accept :Indicates use of emlxs_fct_cmd_accept() 14982527734SSukumar Swaminathan * Acquire :Indicates use of emlxs_fct_cmd_acquire() 15082527734SSukumar Swaminathan * Post :Indicates use of emlxs_fct_cmd_post() 15182527734SSukumar Swaminathan * Done :Indicates use of emlxs_fct_cmd_done() 15282527734SSukumar Swaminathan */ 15382527734SSukumar Swaminathan 154291a2b48SSukumar Swaminathan void 155291a2b48SSukumar Swaminathan emlxs_fct_io_trace(emlxs_port_t *port, fct_cmd_t *fct_cmd, uint32_t data) 156291a2b48SSukumar Swaminathan { 157291a2b48SSukumar Swaminathan emlxs_iotrace_t *iop = port->iotrace; 158291a2b48SSukumar Swaminathan uint16_t iotrace_cnt; 159291a2b48SSukumar Swaminathan uint16_t iotrace_index; 160291a2b48SSukumar Swaminathan int i; 161291a2b48SSukumar Swaminathan 162291a2b48SSukumar Swaminathan if (!iop) { 163291a2b48SSukumar Swaminathan return; 164291a2b48SSukumar Swaminathan } 165291a2b48SSukumar Swaminathan 166291a2b48SSukumar Swaminathan mutex_enter(&port->iotrace_mtx); 167291a2b48SSukumar Swaminathan iotrace_cnt = port->iotrace_cnt; 168291a2b48SSukumar Swaminathan iotrace_index = port->iotrace_index; 169291a2b48SSukumar Swaminathan 170291a2b48SSukumar Swaminathan switch (data) { 171291a2b48SSukumar Swaminathan 172291a2b48SSukumar Swaminathan /* New entry */ 173291a2b48SSukumar Swaminathan case EMLXS_FCT_ELS_CMD_RECEIVED: 174291a2b48SSukumar Swaminathan case EMLXS_FCT_FCP_CMD_RECEIVED: 175291a2b48SSukumar Swaminathan case EMLXS_FCT_SEND_ELS_REQ: 176291a2b48SSukumar Swaminathan case EMLXS_FCT_SEND_CT_REQ: 177291a2b48SSukumar Swaminathan for (i = 0; i < iotrace_cnt; i++) { 178291a2b48SSukumar Swaminathan if ((iop->fct_cmd == fct_cmd) && 179291a2b48SSukumar Swaminathan (iop->trc[0] != (uint8_t)(0))) 180291a2b48SSukumar Swaminathan break; 181291a2b48SSukumar Swaminathan iop++; 182291a2b48SSukumar Swaminathan } 183291a2b48SSukumar Swaminathan if (i < iotrace_cnt) { 184291a2b48SSukumar Swaminathan /* New entry already exists */ 185291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 186291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 187291a2b48SSukumar Swaminathan "IOTRACE: New entry already exists: fct_cmd: %p", 188291a2b48SSukumar Swaminathan fct_cmd); 189291a2b48SSukumar Swaminathan return; 190291a2b48SSukumar Swaminathan } 191291a2b48SSukumar Swaminathan iop = port->iotrace + iotrace_index; 192291a2b48SSukumar Swaminathan for (i = 0; i < iotrace_cnt; i++) { 193291a2b48SSukumar Swaminathan if (iop->trc[0] == (uint8_t)(0)) 194291a2b48SSukumar Swaminathan break; 195291a2b48SSukumar Swaminathan 196291a2b48SSukumar Swaminathan iop++; 197291a2b48SSukumar Swaminathan if (iop == (port->iotrace + iotrace_cnt)) 198291a2b48SSukumar Swaminathan iop = port->iotrace; 199291a2b48SSukumar Swaminathan } 200291a2b48SSukumar Swaminathan if (i >= iotrace_cnt) { 201291a2b48SSukumar Swaminathan /* No new slots available */ 202291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 203291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 204291a2b48SSukumar Swaminathan "IOTRACE: No new slots: fct_cmd: %p data: %d", 205291a2b48SSukumar Swaminathan fct_cmd, data); 206291a2b48SSukumar Swaminathan return; 207291a2b48SSukumar Swaminathan } 208291a2b48SSukumar Swaminathan port->iotrace_index++; 209291a2b48SSukumar Swaminathan if (port->iotrace_index >= iotrace_cnt) 210291a2b48SSukumar Swaminathan port->iotrace_index = 0; 211291a2b48SSukumar Swaminathan 212291a2b48SSukumar Swaminathan bzero((uint8_t *)iop, sizeof (emlxs_iotrace_t)); 213291a2b48SSukumar Swaminathan iop->fct_cmd = fct_cmd; 214291a2b48SSukumar Swaminathan iop->xri = fct_cmd->cmd_rxid; 215291a2b48SSukumar Swaminathan iop->marker = 0xff; 216291a2b48SSukumar Swaminathan iop->trc[0] = 2; 217291a2b48SSukumar Swaminathan iop->trc[1] = data; 218291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 219291a2b48SSukumar Swaminathan return; 220291a2b48SSukumar Swaminathan } 221291a2b48SSukumar Swaminathan 222291a2b48SSukumar Swaminathan for (i = 0; i < iotrace_cnt; i++) { 223291a2b48SSukumar Swaminathan if ((iop->fct_cmd == fct_cmd) && 224291a2b48SSukumar Swaminathan (iop->trc[0] != (uint8_t)(0))) 225291a2b48SSukumar Swaminathan break; 226291a2b48SSukumar Swaminathan iop++; 227291a2b48SSukumar Swaminathan } 228291a2b48SSukumar Swaminathan if (i >= iotrace_cnt) { 229291a2b48SSukumar Swaminathan /* Cannot find existing slot for fct_cmd */ 230291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 231291a2b48SSukumar Swaminathan 232291a2b48SSukumar Swaminathan if ((data != EMLXS_FCT_REG_PENDING) && 233291a2b48SSukumar Swaminathan (data != EMLXS_FCT_REG_COMPLETE)) { 234291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 235291a2b48SSukumar Swaminathan "IOTRACE: Missing slot: fct_cmd: %p data: %d", 236291a2b48SSukumar Swaminathan fct_cmd, data); 237291a2b48SSukumar Swaminathan } 238291a2b48SSukumar Swaminathan return; 239291a2b48SSukumar Swaminathan } 240291a2b48SSukumar Swaminathan 241291a2b48SSukumar Swaminathan if (iop->trc[0] >= MAX_IO_TRACE) { 242291a2b48SSukumar Swaminathan /* trc overrun for fct_cmd */ 243291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 244291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 245291a2b48SSukumar Swaminathan "IOTRACE: trc overrun slot: fct_cmd: %p data: %d", 246291a2b48SSukumar Swaminathan fct_cmd, data); 247291a2b48SSukumar Swaminathan return; 248291a2b48SSukumar Swaminathan } 249291a2b48SSukumar Swaminathan 250291a2b48SSukumar Swaminathan if (iop->xri != fct_cmd->cmd_rxid) { 251291a2b48SSukumar Swaminathan /* xri mismatch for fct_cmd */ 252291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 253291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 254291a2b48SSukumar Swaminathan "IOTRACE: xri mismatch %x != %x: fct_cmd: %p data: %d", 255291a2b48SSukumar Swaminathan iop->xri, fct_cmd->cmd_rxid, fct_cmd, data); 256291a2b48SSukumar Swaminathan return; 257291a2b48SSukumar Swaminathan } 258291a2b48SSukumar Swaminathan 259291a2b48SSukumar Swaminathan iop->trc[iop->trc[0]] = data; 260291a2b48SSukumar Swaminathan if ((data == EMLXS_FCT_IO_DONE) || (data == EMLXS_FCT_ABORT_DONE)) { 26182527734SSukumar Swaminathan /* IOCB ULPCOMMAND is saved after EMLXS_FCT_IOCB_ISSUED */ 26282527734SSukumar Swaminathan if (iop->trc[iop->trc[0]-1] == EMLXS_FCT_IOCB_ISSUED) { 263291a2b48SSukumar Swaminathan iop->trc[0]++; 26482527734SSukumar Swaminathan } else { 265291a2b48SSukumar Swaminathan iop->trc[0] = 0; 26682527734SSukumar Swaminathan } else { 267291a2b48SSukumar Swaminathan iop->trc[0]++; 26882527734SSukumar Swaminathan } 269291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 27082527734SSukumar Swaminathan 27182527734SSukumar Swaminathan return; 27282527734SSukumar Swaminathan 27382527734SSukumar Swaminathan } /* emlxs_fct_io_trace() */ 274291a2b48SSukumar Swaminathan #endif /* FCT_IO_TRACE */ 275fcf3ce44SJohn Forte 276fcf3ce44SJohn Forte #ifdef MODSYM_SUPPORT 277fcf3ce44SJohn Forte 278e51761e0SSukumar Swaminathan extern int 279fcf3ce44SJohn Forte emlxs_fct_modopen() 280fcf3ce44SJohn Forte { 281fcf3ce44SJohn Forte int err; 282fcf3ce44SJohn Forte 28382527734SSukumar Swaminathan mutex_enter(&emlxs_device.lock); 28482527734SSukumar Swaminathan 28582527734SSukumar Swaminathan if (emlxs_modsym.fct_modopen) { 28682527734SSukumar Swaminathan mutex_exit(&emlxs_device.lock); 28782527734SSukumar Swaminathan return (0); 288fcf3ce44SJohn Forte } 289291a2b48SSukumar Swaminathan 29082527734SSukumar Swaminathan emlxs_modsym.fct_modopen++; 29182527734SSukumar Swaminathan 292fcf3ce44SJohn Forte /* Comstar (fct) */ 293fcf3ce44SJohn Forte err = 0; 294fcf3ce44SJohn Forte emlxs_modsym.mod_fct = ddi_modopen("drv/fct", KRTLD_MODE_FIRST, &err); 295fcf3ce44SJohn Forte if (!emlxs_modsym.mod_fct) { 296fcf3ce44SJohn Forte 297fcf3ce44SJohn Forte cmn_err(CE_WARN, "?%s: ddi_modopen drv/fct failed: err %d", 298fcf3ce44SJohn Forte DRIVER_NAME, err); 299fcf3ce44SJohn Forte goto failed; 300fcf3ce44SJohn Forte } 301291a2b48SSukumar Swaminathan 302fcf3ce44SJohn Forte /* Comstar (stmf) */ 303fcf3ce44SJohn Forte err = 0; 304291a2b48SSukumar Swaminathan emlxs_modsym.mod_stmf = 305291a2b48SSukumar Swaminathan ddi_modopen("drv/stmf", KRTLD_MODE_FIRST, &err); 306fcf3ce44SJohn Forte if (!emlxs_modsym.mod_stmf) { 307fcf3ce44SJohn Forte 308fcf3ce44SJohn Forte cmn_err(CE_WARN, "?%s: ddi_modopen drv/stmf failed: err %d", 309fcf3ce44SJohn Forte DRIVER_NAME, err); 310fcf3ce44SJohn Forte goto failed; 311fcf3ce44SJohn Forte } 312291a2b48SSukumar Swaminathan 313fcf3ce44SJohn Forte err = 0; 314fcf3ce44SJohn Forte /* Check if the fct fct_alloc is present */ 315291a2b48SSukumar Swaminathan emlxs_modsym.fct_alloc = (void *(*)())ddi_modsym(emlxs_modsym.mod_fct, 316fcf3ce44SJohn Forte "fct_alloc", &err); 317fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_alloc == NULL) { 318fcf3ce44SJohn Forte cmn_err(CE_WARN, 319fcf3ce44SJohn Forte "?%s: drv/fct: fct_alloc not present", DRIVER_NAME); 320fcf3ce44SJohn Forte goto failed; 321fcf3ce44SJohn Forte } 322291a2b48SSukumar Swaminathan 323fcf3ce44SJohn Forte err = 0; 324fcf3ce44SJohn Forte /* Check if the fct fct_free is present */ 325291a2b48SSukumar Swaminathan emlxs_modsym.fct_free = (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 326fcf3ce44SJohn Forte "fct_free", &err); 327fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_free == NULL) { 328fcf3ce44SJohn Forte cmn_err(CE_WARN, 329fcf3ce44SJohn Forte "?%s: drv/fct: fct_free not present", DRIVER_NAME); 330fcf3ce44SJohn Forte goto failed; 331fcf3ce44SJohn Forte } 332291a2b48SSukumar Swaminathan 333fcf3ce44SJohn Forte err = 0; 334fcf3ce44SJohn Forte /* Check if the fct fct_scsi_task_alloc is present */ 335291a2b48SSukumar Swaminathan emlxs_modsym.fct_scsi_task_alloc = 336291a2b48SSukumar Swaminathan (void *(*)(void *, uint16_t, uint32_t, uint8_t *, 337291a2b48SSukumar Swaminathan uint16_t, uint16_t))ddi_modsym(emlxs_modsym.mod_fct, 338291a2b48SSukumar Swaminathan "fct_scsi_task_alloc", &err); 339fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_scsi_task_alloc == NULL) { 340fcf3ce44SJohn Forte cmn_err(CE_WARN, 341fcf3ce44SJohn Forte "?%s: drv/fct: fct_scsi_task_alloc not present", 342fcf3ce44SJohn Forte DRIVER_NAME); 343fcf3ce44SJohn Forte goto failed; 344fcf3ce44SJohn Forte } 345291a2b48SSukumar Swaminathan 346fcf3ce44SJohn Forte err = 0; 347fcf3ce44SJohn Forte /* Check if the fct fct_register_local_port is present */ 348291a2b48SSukumar Swaminathan emlxs_modsym.fct_register_local_port = 349291a2b48SSukumar Swaminathan (int (*)())ddi_modsym(emlxs_modsym.mod_fct, 350291a2b48SSukumar Swaminathan "fct_register_local_port", &err); 351fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_register_local_port == NULL) { 352fcf3ce44SJohn Forte cmn_err(CE_WARN, 353fcf3ce44SJohn Forte "?%s: drv/fct: fct_register_local_port not present", 354fcf3ce44SJohn Forte DRIVER_NAME); 355fcf3ce44SJohn Forte goto failed; 356fcf3ce44SJohn Forte } 357291a2b48SSukumar Swaminathan 358fcf3ce44SJohn Forte err = 0; 359fcf3ce44SJohn Forte /* Check if the fct fct_deregister_local_port is present */ 360291a2b48SSukumar Swaminathan emlxs_modsym.fct_deregister_local_port = 361291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 362291a2b48SSukumar Swaminathan "fct_deregister_local_port", &err); 363fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_deregister_local_port == NULL) { 364fcf3ce44SJohn Forte cmn_err(CE_WARN, 365fcf3ce44SJohn Forte "?%s: drv/fct: fct_deregister_local_port not present", 366fcf3ce44SJohn Forte DRIVER_NAME); 367fcf3ce44SJohn Forte goto failed; 368fcf3ce44SJohn Forte } 369291a2b48SSukumar Swaminathan 370fcf3ce44SJohn Forte err = 0; 371fcf3ce44SJohn Forte /* Check if the fct fct_handle_event is present */ 372291a2b48SSukumar Swaminathan emlxs_modsym.fct_handle_event = 373291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, "fct_handle_event", 374291a2b48SSukumar Swaminathan &err); 375fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_handle_event == NULL) { 376fcf3ce44SJohn Forte cmn_err(CE_WARN, 377291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_handle_event not present", 378291a2b48SSukumar Swaminathan DRIVER_NAME); 379fcf3ce44SJohn Forte goto failed; 380fcf3ce44SJohn Forte } 381291a2b48SSukumar Swaminathan 382fcf3ce44SJohn Forte err = 0; 383fcf3ce44SJohn Forte /* Check if the fct fct_post_rcvd_cmd is present */ 384291a2b48SSukumar Swaminathan emlxs_modsym.fct_post_rcvd_cmd = 385291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, "fct_post_rcvd_cmd", 386291a2b48SSukumar Swaminathan &err); 387fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_post_rcvd_cmd == NULL) { 388fcf3ce44SJohn Forte cmn_err(CE_WARN, 389291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_post_rcvd_cmd not present", 390291a2b48SSukumar Swaminathan DRIVER_NAME); 391fcf3ce44SJohn Forte goto failed; 392fcf3ce44SJohn Forte } 393fcf3ce44SJohn Forte err = 0; 394fcf3ce44SJohn Forte /* Check if the fct fct_alloc is present */ 395291a2b48SSukumar Swaminathan emlxs_modsym.fct_ctl = (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 396fcf3ce44SJohn Forte "fct_ctl", &err); 397fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_ctl == NULL) { 398fcf3ce44SJohn Forte cmn_err(CE_WARN, 399fcf3ce44SJohn Forte "?%s: drv/fct: fct_ctl not present", DRIVER_NAME); 400fcf3ce44SJohn Forte goto failed; 401fcf3ce44SJohn Forte } 402fcf3ce44SJohn Forte err = 0; 403291a2b48SSukumar Swaminathan /* Check if the fct fct_queue_cmd_for_termination is present */ 404291a2b48SSukumar Swaminathan emlxs_modsym.fct_queue_cmd_for_termination = 405291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 406291a2b48SSukumar Swaminathan "fct_queue_cmd_for_termination", &err); 407291a2b48SSukumar Swaminathan if ((void *)emlxs_modsym.fct_queue_cmd_for_termination == NULL) { 408291a2b48SSukumar Swaminathan cmn_err(CE_WARN, 409291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_queue_cmd_for_termination not present", 410291a2b48SSukumar Swaminathan DRIVER_NAME); 411291a2b48SSukumar Swaminathan goto failed; 412291a2b48SSukumar Swaminathan } 413291a2b48SSukumar Swaminathan err = 0; 414fcf3ce44SJohn Forte /* Check if the fct fct_send_response_done is present */ 415291a2b48SSukumar Swaminathan emlxs_modsym.fct_send_response_done = 416291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 417291a2b48SSukumar Swaminathan "fct_send_response_done", &err); 418fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_send_response_done == NULL) { 419fcf3ce44SJohn Forte cmn_err(CE_WARN, 420fcf3ce44SJohn Forte "?%s: drv/fct: fct_send_response_done not present", 421fcf3ce44SJohn Forte DRIVER_NAME); 422fcf3ce44SJohn Forte goto failed; 423fcf3ce44SJohn Forte } 424fcf3ce44SJohn Forte err = 0; 425fcf3ce44SJohn Forte /* Check if the fct fct_send_cmd_done is present */ 426291a2b48SSukumar Swaminathan emlxs_modsym.fct_send_cmd_done = 427291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, "fct_send_cmd_done", 428291a2b48SSukumar Swaminathan &err); 429fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_send_cmd_done == NULL) { 430fcf3ce44SJohn Forte cmn_err(CE_WARN, 431291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_send_cmd_done not present", 432291a2b48SSukumar Swaminathan DRIVER_NAME); 433fcf3ce44SJohn Forte goto failed; 434fcf3ce44SJohn Forte } 435fcf3ce44SJohn Forte err = 0; 436fcf3ce44SJohn Forte /* Check if the fct fct_scsi_xfer_data_done is present */ 437291a2b48SSukumar Swaminathan emlxs_modsym.fct_scsi_data_xfer_done = 438291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 439291a2b48SSukumar Swaminathan "fct_scsi_data_xfer_done", &err); 440fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_scsi_data_xfer_done == NULL) { 441fcf3ce44SJohn Forte cmn_err(CE_WARN, 442fcf3ce44SJohn Forte "?%s: drv/fct: fct_scsi_data_xfer_done not present", 443fcf3ce44SJohn Forte DRIVER_NAME); 444fcf3ce44SJohn Forte goto failed; 445fcf3ce44SJohn Forte } 446fcf3ce44SJohn Forte err = 0; 447fcf3ce44SJohn Forte /* Check if the fct fct_port_shutdown is present */ 448291a2b48SSukumar Swaminathan emlxs_modsym.fct_port_shutdown = 449291a2b48SSukumar Swaminathan (fct_status_t(*)())ddi_modsym(emlxs_modsym.mod_fct, 450291a2b48SSukumar Swaminathan "fct_port_shutdown", &err); 451fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_port_shutdown == NULL) { 452fcf3ce44SJohn Forte cmn_err(CE_WARN, 453291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_port_shutdown not present", 454291a2b48SSukumar Swaminathan DRIVER_NAME); 455fcf3ce44SJohn Forte goto failed; 456fcf3ce44SJohn Forte } 457291a2b48SSukumar Swaminathan 458fcf3ce44SJohn Forte err = 0; 459fcf3ce44SJohn Forte /* Check if the fct fct_port_initialize is present */ 460291a2b48SSukumar Swaminathan emlxs_modsym.fct_port_initialize = 461291a2b48SSukumar Swaminathan (fct_status_t(*)())ddi_modsym(emlxs_modsym.mod_fct, 462291a2b48SSukumar Swaminathan "fct_port_initialize", &err); 463fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_port_initialize == NULL) { 464fcf3ce44SJohn Forte cmn_err(CE_WARN, 465fcf3ce44SJohn Forte "?%s: drv/fct: fct_port_initialize not present", 466fcf3ce44SJohn Forte DRIVER_NAME); 467fcf3ce44SJohn Forte goto failed; 468fcf3ce44SJohn Forte } 469291a2b48SSukumar Swaminathan 470291a2b48SSukumar Swaminathan err = 0; 471291a2b48SSukumar Swaminathan /* Check if the fct fct_cmd_fca_aborted is present */ 472291a2b48SSukumar Swaminathan emlxs_modsym.fct_cmd_fca_aborted = 473291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 474291a2b48SSukumar Swaminathan "fct_cmd_fca_aborted", &err); 475291a2b48SSukumar Swaminathan if ((void *)emlxs_modsym.fct_cmd_fca_aborted == NULL) { 476291a2b48SSukumar Swaminathan cmn_err(CE_WARN, 477291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_cmd_fca_aborted not present", 478291a2b48SSukumar Swaminathan DRIVER_NAME); 479291a2b48SSukumar Swaminathan goto failed; 480291a2b48SSukumar Swaminathan } 481291a2b48SSukumar Swaminathan 482fcf3ce44SJohn Forte err = 0; 483fcf3ce44SJohn Forte /* Check if the fct fct_handle_rcvd_flogi is present */ 484291a2b48SSukumar Swaminathan emlxs_modsym.fct_handle_rcvd_flogi = 485291a2b48SSukumar Swaminathan (fct_status_t(*)())ddi_modsym(emlxs_modsym.mod_fct, 486291a2b48SSukumar Swaminathan "fct_handle_rcvd_flogi", &err); 487fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_handle_rcvd_flogi == NULL) { 488fcf3ce44SJohn Forte cmn_err(CE_WARN, 489fcf3ce44SJohn Forte "?%s: drv/fct: fct_handle_rcvd_flogi not present", 490fcf3ce44SJohn Forte DRIVER_NAME); 491fcf3ce44SJohn Forte goto failed; 492fcf3ce44SJohn Forte } 493291a2b48SSukumar Swaminathan 494fcf3ce44SJohn Forte /* Comstar (stmf) */ 495fcf3ce44SJohn Forte err = 0; 496fcf3ce44SJohn Forte /* Check if the stmf stmf_alloc is present */ 497291a2b48SSukumar Swaminathan emlxs_modsym.stmf_alloc = 498291a2b48SSukumar Swaminathan (void *(*)())ddi_modsym(emlxs_modsym.mod_stmf, "stmf_alloc", 499291a2b48SSukumar Swaminathan &err); 500fcf3ce44SJohn Forte if ((void *)emlxs_modsym.stmf_alloc == NULL) { 501fcf3ce44SJohn Forte cmn_err(CE_WARN, 502fcf3ce44SJohn Forte "?%s: drv/stmf: stmf_alloc not present", DRIVER_NAME); 503fcf3ce44SJohn Forte goto failed; 504fcf3ce44SJohn Forte } 505291a2b48SSukumar Swaminathan 506fcf3ce44SJohn Forte err = 0; 507fcf3ce44SJohn Forte /* Check if the stmf stmf_free is present */ 508291a2b48SSukumar Swaminathan emlxs_modsym.stmf_free = (void (*)())ddi_modsym(emlxs_modsym.mod_stmf, 509fcf3ce44SJohn Forte "stmf_free", &err); 510fcf3ce44SJohn Forte if ((void *)emlxs_modsym.stmf_free == NULL) { 511fcf3ce44SJohn Forte cmn_err(CE_WARN, 512fcf3ce44SJohn Forte "?%s: drv/stmf: stmf_free not present", DRIVER_NAME); 513fcf3ce44SJohn Forte goto failed; 514fcf3ce44SJohn Forte } 515291a2b48SSukumar Swaminathan 516fcf3ce44SJohn Forte err = 0; 517fcf3ce44SJohn Forte /* Check if the stmf stmf_deregister_port_provider is present */ 518fcf3ce44SJohn Forte emlxs_modsym.stmf_deregister_port_provider = 519291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_stmf, 520fcf3ce44SJohn Forte "stmf_deregister_port_provider", &err); 521fcf3ce44SJohn Forte if ((void *)emlxs_modsym.stmf_deregister_port_provider == NULL) { 522fcf3ce44SJohn Forte cmn_err(CE_WARN, 523fcf3ce44SJohn Forte "?%s: drv/stmf: stmf_deregister_port_provider not present", 524fcf3ce44SJohn Forte DRIVER_NAME); 525fcf3ce44SJohn Forte goto failed; 526fcf3ce44SJohn Forte } 527291a2b48SSukumar Swaminathan 528fcf3ce44SJohn Forte err = 0; 529fcf3ce44SJohn Forte /* Check if the stmf stmf_register_port_provider is present */ 530fcf3ce44SJohn Forte emlxs_modsym.stmf_register_port_provider = 531291a2b48SSukumar Swaminathan (int (*)())ddi_modsym(emlxs_modsym.mod_stmf, 532fcf3ce44SJohn Forte "stmf_register_port_provider", &err); 533fcf3ce44SJohn Forte if ((void *)emlxs_modsym.stmf_register_port_provider == NULL) { 534fcf3ce44SJohn Forte cmn_err(CE_WARN, 535fcf3ce44SJohn Forte "?%s: drv/stmf: stmf_register_port_provider not present", 536fcf3ce44SJohn Forte DRIVER_NAME); 537fcf3ce44SJohn Forte goto failed; 538fcf3ce44SJohn Forte } 53982527734SSukumar Swaminathan 54082527734SSukumar Swaminathan mutex_exit(&emlxs_device.lock); 54182527734SSukumar Swaminathan return (0); 542fcf3ce44SJohn Forte 543fcf3ce44SJohn Forte failed: 54482527734SSukumar Swaminathan 54582527734SSukumar Swaminathan mutex_exit(&emlxs_device.lock); 546fcf3ce44SJohn Forte emlxs_fct_modclose(); 54782527734SSukumar Swaminathan return (1); 548fcf3ce44SJohn Forte 54982527734SSukumar Swaminathan } /* emlxs_fct_modopen() */ 550fcf3ce44SJohn Forte 551fcf3ce44SJohn Forte 552fcf3ce44SJohn Forte extern void 553fcf3ce44SJohn Forte emlxs_fct_modclose() 554fcf3ce44SJohn Forte { 55582527734SSukumar Swaminathan mutex_enter(&emlxs_device.lock); 55682527734SSukumar Swaminathan 55782527734SSukumar Swaminathan if (emlxs_modsym.fct_modopen == 0) { 55882527734SSukumar Swaminathan mutex_exit(&emlxs_device.lock); 55982527734SSukumar Swaminathan return; 56082527734SSukumar Swaminathan } 56182527734SSukumar Swaminathan 56282527734SSukumar Swaminathan emlxs_modsym.fct_modopen--; 56382527734SSukumar Swaminathan 56482527734SSukumar Swaminathan if (emlxs_modsym.fct_modopen) { 56582527734SSukumar Swaminathan mutex_exit(&emlxs_device.lock); 56682527734SSukumar Swaminathan return; 56782527734SSukumar Swaminathan } 568fcf3ce44SJohn Forte 569fcf3ce44SJohn Forte if (emlxs_modsym.mod_fct) { 570fcf3ce44SJohn Forte (void) ddi_modclose(emlxs_modsym.mod_fct); 571fcf3ce44SJohn Forte emlxs_modsym.mod_fct = 0; 572fcf3ce44SJohn Forte } 573291a2b48SSukumar Swaminathan 574fcf3ce44SJohn Forte if (emlxs_modsym.mod_stmf) { 575fcf3ce44SJohn Forte (void) ddi_modclose(emlxs_modsym.mod_stmf); 576fcf3ce44SJohn Forte emlxs_modsym.mod_stmf = 0; 577fcf3ce44SJohn Forte } 578291a2b48SSukumar Swaminathan 579fcf3ce44SJohn Forte emlxs_modsym.fct_alloc = NULL; 580fcf3ce44SJohn Forte emlxs_modsym.fct_free = NULL; 581fcf3ce44SJohn Forte emlxs_modsym.fct_scsi_task_alloc = NULL; 582fcf3ce44SJohn Forte emlxs_modsym.fct_register_local_port = NULL; 583fcf3ce44SJohn Forte emlxs_modsym.fct_deregister_local_port = NULL; 584fcf3ce44SJohn Forte emlxs_modsym.fct_handle_event = NULL; 585fcf3ce44SJohn Forte emlxs_modsym.fct_ctl = NULL; 586291a2b48SSukumar Swaminathan emlxs_modsym.fct_queue_cmd_for_termination = NULL; 587fcf3ce44SJohn Forte emlxs_modsym.fct_send_response_done = NULL; 588fcf3ce44SJohn Forte emlxs_modsym.fct_send_cmd_done = NULL; 589fcf3ce44SJohn Forte emlxs_modsym.fct_scsi_data_xfer_done = NULL; 590fcf3ce44SJohn Forte emlxs_modsym.fct_port_shutdown = NULL; 591fcf3ce44SJohn Forte emlxs_modsym.fct_port_initialize = NULL; 592291a2b48SSukumar Swaminathan emlxs_modsym.fct_cmd_fca_aborted = NULL; 593fcf3ce44SJohn Forte emlxs_modsym.fct_handle_rcvd_flogi = NULL; 594fcf3ce44SJohn Forte 595fcf3ce44SJohn Forte emlxs_modsym.stmf_alloc = NULL; 596fcf3ce44SJohn Forte emlxs_modsym.stmf_free = NULL; 597fcf3ce44SJohn Forte emlxs_modsym.stmf_deregister_port_provider = NULL; 598fcf3ce44SJohn Forte emlxs_modsym.stmf_register_port_provider = NULL; 599fcf3ce44SJohn Forte 60082527734SSukumar Swaminathan mutex_exit(&emlxs_device.lock); 60182527734SSukumar Swaminathan 60282527734SSukumar Swaminathan } /* emlxs_fct_modclose() */ 603291a2b48SSukumar Swaminathan 604291a2b48SSukumar Swaminathan #endif /* MODSYM_SUPPORT */ 605291a2b48SSukumar Swaminathan 606e2ca2865SSukumar Swaminathan /* 607e2ca2865SSukumar Swaminathan * This routine is called to handle an unsol FLOGI exchange 608e2ca2865SSukumar Swaminathan * fx save 609e2ca2865SSukumar Swaminathan * 0 1 Process or save port->fx 610e2ca2865SSukumar Swaminathan * 0 0 Process or reject port->fx 611e2ca2865SSukumar Swaminathan * 1 1 Process port->fx, Process or save fx 612e2ca2865SSukumar Swaminathan * 1 0 Process or reject port->fx, Process or reject fx 613e2ca2865SSukumar Swaminathan */ 614291a2b48SSukumar Swaminathan static void 615e2ca2865SSukumar Swaminathan emlxs_fct_handle_unsol_flogi(emlxs_port_t *port, fct_flogi_xchg_t *fx, 616e2ca2865SSukumar Swaminathan uint32_t save) 617291a2b48SSukumar Swaminathan { 618e2ca2865SSukumar Swaminathan emlxs_hba_t *hba = HBA; 619291a2b48SSukumar Swaminathan fct_status_t status; 620291a2b48SSukumar Swaminathan IOCBQ iocbq; 621e2ca2865SSukumar Swaminathan fct_flogi_xchg_t fxchg; 622e2ca2865SSukumar Swaminathan 623e2ca2865SSukumar Swaminathan begin: 624e2ca2865SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 625e2ca2865SSukumar Swaminathan 626e2ca2865SSukumar Swaminathan /* Check if there is an old saved FLOGI */ 627e2ca2865SSukumar Swaminathan if (port->fx.fx_op) { 628e2ca2865SSukumar Swaminathan /* Get it now */ 629e2ca2865SSukumar Swaminathan bcopy(&port->fx, &fxchg, sizeof (fct_flogi_xchg_t)); 630e2ca2865SSukumar Swaminathan 631e2ca2865SSukumar Swaminathan if (fx) { 632e2ca2865SSukumar Swaminathan /* Save new FLOGI */ 633e2ca2865SSukumar Swaminathan bcopy(fx, &port->fx, sizeof (fct_flogi_xchg_t)); 634e2ca2865SSukumar Swaminathan 635e2ca2865SSukumar Swaminathan /* Reject old stale FLOGI */ 636e2ca2865SSukumar Swaminathan fx = &fxchg; 637e2ca2865SSukumar Swaminathan goto reject_it; 638e2ca2865SSukumar Swaminathan 639e2ca2865SSukumar Swaminathan } else { 640e2ca2865SSukumar Swaminathan bzero(&port->fx, sizeof (fct_flogi_xchg_t)); 641e2ca2865SSukumar Swaminathan fx = &fxchg; 642e2ca2865SSukumar Swaminathan } 643e2ca2865SSukumar Swaminathan 644e2ca2865SSukumar Swaminathan } else if (!fx) { 645e2ca2865SSukumar Swaminathan /* Nothing to do, just return */ 646e2ca2865SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 647e2ca2865SSukumar Swaminathan return; 648e2ca2865SSukumar Swaminathan } 649e2ca2865SSukumar Swaminathan 650e2ca2865SSukumar Swaminathan /* We have a valid FLOGI here */ 651e2ca2865SSukumar Swaminathan /* There is no saved FLOGI at this point either */ 652e2ca2865SSukumar Swaminathan 653e2ca2865SSukumar Swaminathan /* Check if COMSTAR is ready to accept it */ 654e2ca2865SSukumar Swaminathan if (port->fct_flags & FCT_STATE_LINK_UP_ACKED) { 655e2ca2865SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 656291a2b48SSukumar Swaminathan 657291a2b48SSukumar Swaminathan bzero((uint8_t *)&iocbq, sizeof (IOCBQ)); 658e2ca2865SSukumar Swaminathan iocbq.iocb.un.elsreq.remoteID = fx->fx_sid; 659e2ca2865SSukumar Swaminathan iocbq.iocb.un.elsreq.myID = fx->fx_did; 660e2ca2865SSukumar Swaminathan iocbq.iocb.ULPCONTEXT = (uint16_t)fx->rsvd2; 661e2ca2865SSukumar Swaminathan fx->rsvd2 = 0; /* Clear the reserved field now */ 662291a2b48SSukumar Swaminathan 663e2ca2865SSukumar Swaminathan status = MODSYM(fct_handle_rcvd_flogi) (port->fct_port, fx); 664291a2b48SSukumar Swaminathan 665291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE 666291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 667e2ca2865SSukumar Swaminathan "fct_handle_rcvd_flogi %p: status=%x", 668e2ca2865SSukumar Swaminathan port->fct_port, status); 669291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 670291a2b48SSukumar Swaminathan 671291a2b48SSukumar Swaminathan if (status == FCT_SUCCESS) { 672e2ca2865SSukumar Swaminathan if (fx->fx_op == ELS_OP_ACC) { 673291a2b48SSukumar Swaminathan (void) emlxs_els_reply(port, &iocbq, 674291a2b48SSukumar Swaminathan ELS_CMD_ACC, ELS_CMD_FLOGI, 0, 0); 675291a2b48SSukumar Swaminathan 676e2ca2865SSukumar Swaminathan } else { /* ELS_OP_LSRJT */ 677291a2b48SSukumar Swaminathan (void) emlxs_els_reply(port, &iocbq, 678e2ca2865SSukumar Swaminathan ELS_CMD_LS_RJT, ELS_CMD_FLOGI, 679e2ca2865SSukumar Swaminathan fx->fx_rjt_reason, fx->fx_rjt_expl); 680291a2b48SSukumar Swaminathan } 681291a2b48SSukumar Swaminathan } else { 682291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 683e2ca2865SSukumar Swaminathan "FLOGI: sid=%x xid=%x. " 684e2ca2865SSukumar Swaminathan "fct_handle_rcvd_flogi failed. Rejecting.", 685e2ca2865SSukumar Swaminathan fx->fx_sid, iocbq.iocb.ULPCONTEXT); 686291a2b48SSukumar Swaminathan 687e2ca2865SSukumar Swaminathan (void) emlxs_els_reply(port, &iocbq, 688e2ca2865SSukumar Swaminathan ELS_CMD_LS_RJT, ELS_CMD_FLOGI, 689e2ca2865SSukumar Swaminathan LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 690291a2b48SSukumar Swaminathan } 691291a2b48SSukumar Swaminathan 692e2ca2865SSukumar Swaminathan return; 693291a2b48SSukumar Swaminathan } 694fcf3ce44SJohn Forte 695e2ca2865SSukumar Swaminathan if (save) { 696e2ca2865SSukumar Swaminathan /* Save FLOGI for later */ 697e2ca2865SSukumar Swaminathan bcopy(fx, &port->fx, sizeof (fct_flogi_xchg_t)); 698e2ca2865SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 699291a2b48SSukumar Swaminathan return; 700fcf3ce44SJohn Forte } 701291a2b48SSukumar Swaminathan 702e2ca2865SSukumar Swaminathan reject_it: 703291a2b48SSukumar Swaminathan 704e2ca2865SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 705fcf3ce44SJohn Forte 706e2ca2865SSukumar Swaminathan if (port->fct_flags & FCT_STATE_LINK_UP) { 707e2ca2865SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 708e2ca2865SSukumar Swaminathan "FLOGI: sid=%x xid=%x. Stale. Rejecting.", 709e2ca2865SSukumar Swaminathan fx->fx_sid, fx->rsvd2); 710fcf3ce44SJohn Forte 711e2ca2865SSukumar Swaminathan bzero((uint8_t *)&iocbq, sizeof (IOCBQ)); 712e2ca2865SSukumar Swaminathan iocbq.iocb.un.elsreq.remoteID = fx->fx_sid; 713e2ca2865SSukumar Swaminathan iocbq.iocb.un.elsreq.myID = fx->fx_did; 714e2ca2865SSukumar Swaminathan iocbq.iocb.ULPCONTEXT = fx->rsvd2; 715291a2b48SSukumar Swaminathan 716e2ca2865SSukumar Swaminathan (void) emlxs_els_reply(port, &iocbq, 717e2ca2865SSukumar Swaminathan ELS_CMD_LS_RJT, ELS_CMD_FLOGI, 718e2ca2865SSukumar Swaminathan LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 719fcf3ce44SJohn Forte 720e2ca2865SSukumar Swaminathan /* If we have an FLOGI saved, try sending it now */ 721e2ca2865SSukumar Swaminathan if (port->fx.fx_op) { 722e2ca2865SSukumar Swaminathan fx = NULL; 723e2ca2865SSukumar Swaminathan goto begin; 724e2ca2865SSukumar Swaminathan } 725291a2b48SSukumar Swaminathan 726e2ca2865SSukumar Swaminathan } else { 727e2ca2865SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 728e2ca2865SSukumar Swaminathan "FLOGI: sid=%x xid=%x. Link down. " 729e2ca2865SSukumar Swaminathan "Dropping.", 730e2ca2865SSukumar Swaminathan fx->fx_sid, fx->rsvd2); 731291a2b48SSukumar Swaminathan } 73282527734SSukumar Swaminathan 733fcf3ce44SJohn Forte return; 734fcf3ce44SJohn Forte 735e2ca2865SSukumar Swaminathan } /* emlxs_fct_handle_unsol_flogi() */ 736fcf3ce44SJohn Forte 737fcf3ce44SJohn Forte 738fcf3ce44SJohn Forte /* This is called at port online and offline */ 739fcf3ce44SJohn Forte static void 740fcf3ce44SJohn Forte emlxs_fct_unsol_flush(emlxs_port_t *port) 741fcf3ce44SJohn Forte { 742fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 743fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 744fcf3ce44SJohn Forte emlxs_buf_t *next; 745fcf3ce44SJohn Forte fct_cmd_t *fct_cmd; 74682527734SSukumar Swaminathan fct_status_t rval; 747e2ca2865SSukumar Swaminathan uint32_t cmd_code; 748fcf3ce44SJohn Forte 749fcf3ce44SJohn Forte if (!port->fct_port) { 750fcf3ce44SJohn Forte return; 751fcf3ce44SJohn Forte } 752291a2b48SSukumar Swaminathan 753e2ca2865SSukumar Swaminathan /* First handle any pending FLOGI */ 754e2ca2865SSukumar Swaminathan emlxs_fct_handle_unsol_flogi(port, NULL, 0); 755291a2b48SSukumar Swaminathan 756e2ca2865SSukumar Swaminathan /* Wait queue */ 757fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 758fcf3ce44SJohn Forte cmd_sbp = port->fct_wait_head; 759fcf3ce44SJohn Forte port->fct_wait_head = NULL; 760fcf3ce44SJohn Forte port->fct_wait_tail = NULL; 761fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 762fcf3ce44SJohn Forte 763291a2b48SSukumar Swaminathan /* 764291a2b48SSukumar Swaminathan * Next process any outstanding ELS commands. It doesn't 765291a2b48SSukumar Swaminathan * matter if the Link is up or not, always post them to FCT. 766291a2b48SSukumar Swaminathan */ 767fcf3ce44SJohn Forte while (cmd_sbp) { 768fcf3ce44SJohn Forte next = cmd_sbp->next; 769fcf3ce44SJohn Forte fct_cmd = cmd_sbp->fct_cmd; 770fcf3ce44SJohn Forte 771e2ca2865SSukumar Swaminathan cmd_code = (fct_cmd->cmd_oxid << ELS_CMD_SHIFT); 772e2ca2865SSukumar Swaminathan 77382527734SSukumar Swaminathan /* Reacquire ownership of the fct_cmd */ 77482527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, 0); 77582527734SSukumar Swaminathan if (rval) { 77682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 777e2ca2865SSukumar Swaminathan "emlxs_fct_unsol_flush: %s: sid=%x xid=%x " 778e2ca2865SSukumar Swaminathan "Unable to reacquire fct_cmd.", 779e2ca2865SSukumar Swaminathan emlxs_elscmd_xlate(cmd_code), 780e2ca2865SSukumar Swaminathan fct_cmd->cmd_rxid, fct_cmd->cmd_rportid); 78182527734SSukumar Swaminathan 78282527734SSukumar Swaminathan cmd_sbp = next; 78382527734SSukumar Swaminathan continue; 78482527734SSukumar Swaminathan } 78582527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 78682527734SSukumar Swaminathan 787291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 788e2ca2865SSukumar Swaminathan "Completing %s: sid=%x xid=%x %p", 789e2ca2865SSukumar Swaminathan emlxs_elscmd_xlate(cmd_code), 790e2ca2865SSukumar Swaminathan fct_cmd->cmd_rportid, fct_cmd->cmd_rxid, 791e2ca2865SSukumar Swaminathan fct_cmd); 792fcf3ce44SJohn Forte 79382527734SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 79482527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 795fcf3ce44SJohn Forte 796fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 797291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 798291a2b48SSukumar Swaminathan "fct_post_rcvd_cmd:2 %p: portid x%x", fct_cmd, 799291a2b48SSukumar Swaminathan fct_cmd->cmd_lportid); 800291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 80182527734SSukumar Swaminathan 802291a2b48SSukumar Swaminathan MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0); 803fcf3ce44SJohn Forte 804fcf3ce44SJohn Forte cmd_sbp = next; 805fcf3ce44SJohn Forte 80682527734SSukumar Swaminathan } /* while () */ 807fcf3ce44SJohn Forte 808fcf3ce44SJohn Forte return; 809fcf3ce44SJohn Forte 81082527734SSukumar Swaminathan } /* emlxs_fct_unsol_flush() */ 811fcf3ce44SJohn Forte 812fcf3ce44SJohn Forte 813fcf3ce44SJohn Forte int 814fcf3ce44SJohn Forte emlxs_is_digit(uint8_t chr) 815fcf3ce44SJohn Forte { 816fcf3ce44SJohn Forte if ((chr >= '0') && (chr <= '9')) { 817fcf3ce44SJohn Forte return (1); 818fcf3ce44SJohn Forte } 819291a2b48SSukumar Swaminathan 820fcf3ce44SJohn Forte return (0); 821fcf3ce44SJohn Forte 82282527734SSukumar Swaminathan } /* emlxs_is_digit */ 823fcf3ce44SJohn Forte 824fcf3ce44SJohn Forte 825fcf3ce44SJohn Forte /* 826fcf3ce44SJohn Forte * Convert an ASCII decimal numeric string to integer. 827fcf3ce44SJohn Forte * Negation character '-' is not handled. 828fcf3ce44SJohn Forte */ 829fcf3ce44SJohn Forte uint32_t 830fcf3ce44SJohn Forte emlxs_str_atoi(uint8_t *string) 831fcf3ce44SJohn Forte { 832fcf3ce44SJohn Forte uint32_t num = 0; 833fcf3ce44SJohn Forte int i = 0; 834fcf3ce44SJohn Forte 835fcf3ce44SJohn Forte while (string[i]) { 836fcf3ce44SJohn Forte if (!emlxs_is_digit(string[i])) { 837fcf3ce44SJohn Forte return (num); 838fcf3ce44SJohn Forte } 839291a2b48SSukumar Swaminathan 840fcf3ce44SJohn Forte num = num * 10 + (string[i++] - '0'); 841fcf3ce44SJohn Forte } 842fcf3ce44SJohn Forte 843fcf3ce44SJohn Forte return (num); 844fcf3ce44SJohn Forte 84582527734SSukumar Swaminathan } /* emlxs_str_atoi() */ 846fcf3ce44SJohn Forte 847fcf3ce44SJohn Forte 848fcf3ce44SJohn Forte static void 849fcf3ce44SJohn Forte emlxs_init_fct_bufpool(emlxs_hba_t *hba, char **arrayp, uint32_t cnt) 850fcf3ce44SJohn Forte { 851fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 852fcf3ce44SJohn Forte uint8_t *datap; 853fcf3ce44SJohn Forte int i; 854291a2b48SSukumar Swaminathan int bck; 855291a2b48SSukumar Swaminathan int nbufs; 856291a2b48SSukumar Swaminathan int maxbufs; 857291a2b48SSukumar Swaminathan int size; 858fcf3ce44SJohn Forte 859fcf3ce44SJohn Forte bzero((uint8_t *)port->dmem_bucket, sizeof (port->dmem_bucket)); 860291a2b48SSukumar Swaminathan bck = 0; 861bce54adfSSukumar Swaminathan 862bce54adfSSukumar Swaminathan if (!cnt || !arrayp) { 863bce54adfSSukumar Swaminathan goto done; 864bce54adfSSukumar Swaminathan } 865bce54adfSSukumar Swaminathan 866fcf3ce44SJohn Forte for (i = 0; i < cnt; i++) { 867fcf3ce44SJohn Forte datap = (uint8_t *)arrayp[i]; 868bce54adfSSukumar Swaminathan if (datap == 0) { 869fcf3ce44SJohn Forte break; 870bce54adfSSukumar Swaminathan } 871fcf3ce44SJohn Forte 872bce54adfSSukumar Swaminathan while (*datap == ' ') { /* Skip spaces */ 873fcf3ce44SJohn Forte datap++; 874bce54adfSSukumar Swaminathan } 875fcf3ce44SJohn Forte 876291a2b48SSukumar Swaminathan size = emlxs_str_atoi(datap); 877fcf3ce44SJohn Forte 878bce54adfSSukumar Swaminathan while ((*datap != ':') && (*datap != 0)) { 879fcf3ce44SJohn Forte datap++; 880bce54adfSSukumar Swaminathan } 881bce54adfSSukumar Swaminathan if (*datap == ':') { /* Skip past delimeter */ 882fcf3ce44SJohn Forte datap++; 883bce54adfSSukumar Swaminathan } 884bce54adfSSukumar Swaminathan while (*datap == ' ') { /* Skip spaces */ 885fcf3ce44SJohn Forte datap++; 886bce54adfSSukumar Swaminathan } 887fcf3ce44SJohn Forte 888291a2b48SSukumar Swaminathan nbufs = emlxs_str_atoi(datap); 889fcf3ce44SJohn Forte 890fcf3ce44SJohn Forte /* Check for a bad entry */ 891291a2b48SSukumar Swaminathan if (!size || !nbufs) { 892fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 893291a2b48SSukumar Swaminathan "Bad fct-bufpool entry %d %d", size, nbufs); 894291a2b48SSukumar Swaminathan 895291a2b48SSukumar Swaminathan port->dmem_bucket[bck].dmem_buf_size = 0; 896291a2b48SSukumar Swaminathan port->dmem_bucket[bck].dmem_nbufs = 0; 897291a2b48SSukumar Swaminathan size = 0; 898291a2b48SSukumar Swaminathan nbufs = 0; 899291a2b48SSukumar Swaminathan } 900291a2b48SSukumar Swaminathan 901291a2b48SSukumar Swaminathan while (nbufs) { 902291a2b48SSukumar Swaminathan port->dmem_bucket[bck].dmem_buf_size = size; 903291a2b48SSukumar Swaminathan port->dmem_bucket[bck].dmem_nbufs = nbufs; 904291a2b48SSukumar Swaminathan 905291a2b48SSukumar Swaminathan /* 906291a2b48SSukumar Swaminathan * We are not going to try to allocate a chunk 907291a2b48SSukumar Swaminathan * of memory > FCT_DMEM_MAX_BUF_SEGMENT 908291a2b48SSukumar Swaminathan * to accomidate the buffer pool of the 909291a2b48SSukumar Swaminathan * requested size. 910291a2b48SSukumar Swaminathan */ 911291a2b48SSukumar Swaminathan maxbufs = (FCT_DMEM_MAX_BUF_SEGMENT / size); 912fcf3ce44SJohn Forte 913291a2b48SSukumar Swaminathan if (nbufs > maxbufs) { 914291a2b48SSukumar Swaminathan port->dmem_bucket[bck].dmem_nbufs = maxbufs; 915291a2b48SSukumar Swaminathan nbufs -= maxbufs; 916291a2b48SSukumar Swaminathan bck++; 917291a2b48SSukumar Swaminathan if (bck >= FCT_MAX_BUCKETS) 918291a2b48SSukumar Swaminathan break; 919291a2b48SSukumar Swaminathan } else { 920291a2b48SSukumar Swaminathan bck++; 921291a2b48SSukumar Swaminathan nbufs = 0; 922291a2b48SSukumar Swaminathan } 923fcf3ce44SJohn Forte } 924291a2b48SSukumar Swaminathan 925291a2b48SSukumar Swaminathan if (bck >= FCT_MAX_BUCKETS) { 926291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 927291a2b48SSukumar Swaminathan "fct-bufpool entry %d %d Exceeds available buckets", 928291a2b48SSukumar Swaminathan size, nbufs); 929fcf3ce44SJohn Forte break; 930291a2b48SSukumar Swaminathan } 931fcf3ce44SJohn Forte } 932bce54adfSSukumar Swaminathan 933bce54adfSSukumar Swaminathan done: 934bce54adfSSukumar Swaminathan /* If no entries found then use defaults */ 935bce54adfSSukumar Swaminathan if (bck == 0) { 936bce54adfSSukumar Swaminathan port->dmem_bucket[0].dmem_buf_size = 512; 937bce54adfSSukumar Swaminathan port->dmem_bucket[0].dmem_nbufs = FCT_BUF_COUNT_512; 938bce54adfSSukumar Swaminathan port->dmem_bucket[1].dmem_buf_size = 8192; 939bce54adfSSukumar Swaminathan port->dmem_bucket[1].dmem_nbufs = FCT_BUF_COUNT_8K; 940bce54adfSSukumar Swaminathan port->dmem_bucket[2].dmem_buf_size = 65536; 941bce54adfSSukumar Swaminathan port->dmem_bucket[2].dmem_nbufs = FCT_BUF_COUNT_64K; 942bce54adfSSukumar Swaminathan port->dmem_bucket[3].dmem_buf_size = 131072; 943bce54adfSSukumar Swaminathan port->dmem_bucket[3].dmem_nbufs = FCT_BUF_COUNT_128K; 944bce54adfSSukumar Swaminathan } 945bce54adfSSukumar Swaminathan 946bce54adfSSukumar Swaminathan } /* emlxs_init_fct_bufpool() */ 947fcf3ce44SJohn Forte 948fcf3ce44SJohn Forte 949fcf3ce44SJohn Forte static void 950fcf3ce44SJohn Forte emlxs_fct_cfg_init(emlxs_hba_t *hba) 951fcf3ce44SJohn Forte { 952bce54adfSSukumar Swaminathan #ifdef FCT_IO_TRACE 953fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 954bce54adfSSukumar Swaminathan emlxs_config_t *cfg = &CFG; 955bce54adfSSukumar Swaminathan #endif /* FCT_IO_TRACE */ 956fcf3ce44SJohn Forte char **arrayp; 957fcf3ce44SJohn Forte uint32_t cnt; 958fcf3ce44SJohn Forte char buf[32]; 959bce54adfSSukumar Swaminathan uint32_t rval; 960fcf3ce44SJohn Forte 961bce54adfSSukumar Swaminathan /* Check for the per adapter setting */ 962bce54adfSSukumar Swaminathan (void) sprintf(buf, "%s%d-fct-bufpool", DRIVER_NAME, hba->ddiinst); 963fcf3ce44SJohn Forte cnt = 0; 964fcf3ce44SJohn Forte arrayp = NULL; 965bce54adfSSukumar Swaminathan rval = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, hba->dip, 966fcf3ce44SJohn Forte (DDI_PROP_DONTPASS), buf, &arrayp, &cnt); 967fcf3ce44SJohn Forte 968bce54adfSSukumar Swaminathan if ((rval != DDI_PROP_SUCCESS) || !cnt || !arrayp) { 969bce54adfSSukumar Swaminathan /* Check for the global setting */ 970bce54adfSSukumar Swaminathan cnt = 0; 971bce54adfSSukumar Swaminathan arrayp = NULL; 972bce54adfSSukumar Swaminathan rval = 973bce54adfSSukumar Swaminathan ddi_prop_lookup_string_array(DDI_DEV_T_ANY, hba->dip, 974fcf3ce44SJohn Forte (DDI_PROP_DONTPASS), "fct-bufpool", &arrayp, &cnt); 975fcf3ce44SJohn Forte 976bce54adfSSukumar Swaminathan if ((rval != DDI_PROP_SUCCESS) || !cnt || !arrayp) { 977bce54adfSSukumar Swaminathan cnt = 0; 978bce54adfSSukumar Swaminathan arrayp = NULL; 979fcf3ce44SJohn Forte } 980fcf3ce44SJohn Forte } 981291a2b48SSukumar Swaminathan 982bce54adfSSukumar Swaminathan emlxs_init_fct_bufpool(hba, arrayp, cnt); 983291a2b48SSukumar Swaminathan 984291a2b48SSukumar Swaminathan #ifdef FCT_IO_TRACE 985291a2b48SSukumar Swaminathan port->iotrace_cnt = 1024; 986291a2b48SSukumar Swaminathan port->iotrace_index = 0; 987bce54adfSSukumar Swaminathan if (cfg[CFG_FCT_QDEPTH].current) { 988bce54adfSSukumar Swaminathan port->iotrace_cnt = (2 * cfg[CFG_FCT_QDEPTH].current); 989bce54adfSSukumar Swaminathan } 990291a2b48SSukumar Swaminathan port->iotrace = 991291a2b48SSukumar Swaminathan kmem_zalloc(port->iotrace_cnt * sizeof (emlxs_iotrace_t), 992291a2b48SSukumar Swaminathan KM_SLEEP); 99382527734SSukumar Swaminathan 994291a2b48SSukumar Swaminathan mutex_init(&port->iotrace_mtx, NULL, MUTEX_DRIVER, 995*a9800bebSGarrett D'Amore DDI_INTR_PRI(hba->intr_arg)); 996291a2b48SSukumar Swaminathan emlxs_iotrace = (uint8_t *)port->iotrace; 997291a2b48SSukumar Swaminathan emlxs_iotrace_cnt = port->iotrace_cnt; 998291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 999291a2b48SSukumar Swaminathan "IOTRACE: init:%p cnt:%d", emlxs_iotrace, emlxs_iotrace_cnt); 1000291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1001291a2b48SSukumar Swaminathan "FCT_ABORT_SUCCESS:%lx FCT_SUCCESS:%lx", FCT_ABORT_SUCCESS, 1002291a2b48SSukumar Swaminathan FCT_SUCCESS); 1003291a2b48SSukumar Swaminathan #endif /* FCT_IO_TRACE */ 1004bce54adfSSukumar Swaminathan 1005fcf3ce44SJohn Forte return; 1006fcf3ce44SJohn Forte 100782527734SSukumar Swaminathan } /* emlxs_fct_cfg_init() */ 1008fcf3ce44SJohn Forte 1009fcf3ce44SJohn Forte 1010fcf3ce44SJohn Forte extern void 1011fcf3ce44SJohn Forte emlxs_fct_init(emlxs_hba_t *hba) 1012fcf3ce44SJohn Forte { 1013fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1014fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 1015fcf3ce44SJohn Forte emlxs_port_t *vport; 1016fcf3ce44SJohn Forte uint32_t i; 1017fcf3ce44SJohn Forte 1018fcf3ce44SJohn Forte if (!hba->tgt_mode) { 1019fcf3ce44SJohn Forte return; 1020fcf3ce44SJohn Forte } 1021fcf3ce44SJohn Forte 1022fcf3ce44SJohn Forte /* Check if COMSTAR is present */ 1023fcf3ce44SJohn Forte if (((void *)MODSYM(stmf_alloc) == NULL) || 1024291a2b48SSukumar Swaminathan ((void *)MODSYM(fct_alloc) == NULL)) { 1025fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg, 1026fcf3ce44SJohn Forte "Comstar not present. Target mode disabled."); 1027fcf3ce44SJohn Forte goto failed; 1028fcf3ce44SJohn Forte } 1029291a2b48SSukumar Swaminathan 1030fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg, 1031fcf3ce44SJohn Forte "Comstar present. Target mode enabled."); 1032fcf3ce44SJohn Forte 1033fcf3ce44SJohn Forte if (cfg[CFG_NPIV_ENABLE].current) { 1034fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 1035fcf3ce44SJohn Forte "enable-npiv: Not supported in target mode. Disabling."); 1036fcf3ce44SJohn Forte 1037fcf3ce44SJohn Forte /* Temporary patch to disable npiv */ 1038fcf3ce44SJohn Forte cfg[CFG_NPIV_ENABLE].current = 0; 1039fcf3ce44SJohn Forte } 1040fcf3ce44SJohn Forte 1041fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 1042fcf3ce44SJohn Forte if (cfg[CFG_AUTH_ENABLE].current) { 1043fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 1044fcf3ce44SJohn Forte "enable-auth: Not supported in target mode. Disabling."); 1045fcf3ce44SJohn Forte 1046fcf3ce44SJohn Forte /* Temporary patch to disable auth */ 1047fcf3ce44SJohn Forte cfg[CFG_AUTH_ENABLE].current = 0; 1048fcf3ce44SJohn Forte } 1049291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */ 1050fcf3ce44SJohn Forte 1051fcf3ce44SJohn Forte emlxs_fct_cfg_init(hba); 1052fcf3ce44SJohn Forte return; 1053fcf3ce44SJohn Forte 1054fcf3ce44SJohn Forte failed: 1055fcf3ce44SJohn Forte 1056fcf3ce44SJohn Forte hba->tgt_mode = 0; 1057fcf3ce44SJohn Forte for (i = 0; i < MAX_VPORTS; i++) { 1058fcf3ce44SJohn Forte vport = &VPORT(i); 1059fcf3ce44SJohn Forte vport->tgt_mode = 0; 1060fcf3ce44SJohn Forte vport->fct_flags = 0; 1061fcf3ce44SJohn Forte } 1062291a2b48SSukumar Swaminathan 1063291a2b48SSukumar Swaminathan return; 1064291a2b48SSukumar Swaminathan 106582527734SSukumar Swaminathan } /* emlxs_fct_init() */ 1066fcf3ce44SJohn Forte 1067fcf3ce44SJohn Forte 1068fcf3ce44SJohn Forte extern void 1069fcf3ce44SJohn Forte emlxs_fct_attach(emlxs_hba_t *hba) 1070fcf3ce44SJohn Forte { 1071fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1072fcf3ce44SJohn Forte uint32_t vpi; 1073fcf3ce44SJohn Forte 1074fcf3ce44SJohn Forte if (!hba->tgt_mode) { 1075fcf3ce44SJohn Forte return; 1076fcf3ce44SJohn Forte } 1077291a2b48SSukumar Swaminathan 1078fcf3ce44SJohn Forte /* Bind the physical port */ 1079fcf3ce44SJohn Forte emlxs_fct_bind_port(port); 1080fcf3ce44SJohn Forte 1081fcf3ce44SJohn Forte /* Bind virtual ports */ 1082fcf3ce44SJohn Forte if (hba->flag & FC_NPIV_ENABLED) { 108382527734SSukumar Swaminathan for (vpi = 1; vpi <= hba->vpi_high; vpi++) { 1084fcf3ce44SJohn Forte port = &VPORT(vpi); 1085fcf3ce44SJohn Forte 1086fcf3ce44SJohn Forte if (!(port->flag & EMLXS_PORT_ENABLE)) { 1087fcf3ce44SJohn Forte continue; 1088fcf3ce44SJohn Forte } 1089291a2b48SSukumar Swaminathan 1090fcf3ce44SJohn Forte emlxs_fct_bind_port(port); 1091fcf3ce44SJohn Forte } 1092fcf3ce44SJohn Forte } 1093291a2b48SSukumar Swaminathan 1094fcf3ce44SJohn Forte return; 1095fcf3ce44SJohn Forte 109682527734SSukumar Swaminathan } /* emlxs_fct_attach() */ 1097fcf3ce44SJohn Forte 1098fcf3ce44SJohn Forte 1099fcf3ce44SJohn Forte extern void 1100fcf3ce44SJohn Forte emlxs_fct_detach(emlxs_hba_t *hba) 1101fcf3ce44SJohn Forte { 1102fcf3ce44SJohn Forte uint32_t i; 1103fcf3ce44SJohn Forte emlxs_port_t *vport; 1104fcf3ce44SJohn Forte 1105fcf3ce44SJohn Forte if (hba->tgt_mode) { 1106fcf3ce44SJohn Forte for (i = 0; i < MAX_VPORTS; i++) { 1107fcf3ce44SJohn Forte vport = &VPORT(i); 1108fcf3ce44SJohn Forte 1109fcf3ce44SJohn Forte if (!vport->tgt_mode) { 1110fcf3ce44SJohn Forte continue; 1111fcf3ce44SJohn Forte } 1112291a2b48SSukumar Swaminathan 1113fcf3ce44SJohn Forte emlxs_fct_unbind_port(vport); 1114fcf3ce44SJohn Forte vport->tgt_mode = 0; 1115fcf3ce44SJohn Forte } 1116fcf3ce44SJohn Forte 1117fcf3ce44SJohn Forte 1118fcf3ce44SJohn Forte hba->tgt_mode = 0; 1119fcf3ce44SJohn Forte } 1120291a2b48SSukumar Swaminathan #ifdef FCT_IO_TRACE 1121291a2b48SSukumar Swaminathan { 1122291a2b48SSukumar Swaminathan emlxs_port_t *port = &PPORT; 1123291a2b48SSukumar Swaminathan 1124291a2b48SSukumar Swaminathan mutex_destroy(&port->iotrace_mtx); 1125291a2b48SSukumar Swaminathan if (port->iotrace) 1126291a2b48SSukumar Swaminathan kmem_free(port->iotrace, 1127291a2b48SSukumar Swaminathan (port->iotrace_cnt * sizeof (emlxs_iotrace_t))); 1128291a2b48SSukumar Swaminathan port->iotrace = NULL; 1129291a2b48SSukumar Swaminathan } 1130291a2b48SSukumar Swaminathan #endif /* FCT_IO_TRACE */ 1131291a2b48SSukumar Swaminathan 1132fcf3ce44SJohn Forte return; 1133fcf3ce44SJohn Forte 113482527734SSukumar Swaminathan } /* emlxs_fct_detach() */ 1135fcf3ce44SJohn Forte 1136fcf3ce44SJohn Forte 1137fcf3ce44SJohn Forte extern void 1138fcf3ce44SJohn Forte emlxs_fct_unbind_port(emlxs_port_t *port) 1139fcf3ce44SJohn Forte { 1140fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1141fcf3ce44SJohn Forte char node_name[32]; 1142fcf3ce44SJohn Forte 1143fcf3ce44SJohn Forte if (!port->tgt_mode) { 1144fcf3ce44SJohn Forte return; 1145fcf3ce44SJohn Forte } 1146291a2b48SSukumar Swaminathan 1147fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 1148fcf3ce44SJohn Forte if (!(port->flag & EMLXS_PORT_BOUND)) { 1149fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1150fcf3ce44SJohn Forte return; 1151fcf3ce44SJohn Forte } 1152291a2b48SSukumar Swaminathan 1153fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1154fcf3ce44SJohn Forte "emlxs_fct_unbind_port: port=%d", port->vpi); 1155fcf3ce44SJohn Forte 1156fcf3ce44SJohn Forte /* Destroy & flush all port nodes, if they exist */ 1157fcf3ce44SJohn Forte if (port->node_count) { 1158*a9800bebSGarrett D'Amore (void) emlxs_mb_unreg_node(port, NULL, NULL, NULL, NULL); 1159fcf3ce44SJohn Forte } 1160291a2b48SSukumar Swaminathan 1161fcf3ce44SJohn Forte port->flag &= ~EMLXS_PORT_BOUND; 1162fcf3ce44SJohn Forte hba->num_of_ports--; 1163fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1164fcf3ce44SJohn Forte 1165fcf3ce44SJohn Forte if (port->fct_port) { 1166fcf3ce44SJohn Forte emlxs_fct_link_down(port); 1167fcf3ce44SJohn Forte emlxs_fct_unsol_flush(port); 1168fcf3ce44SJohn Forte 1169fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1170fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1171fcf3ce44SJohn Forte "fct_deregister_local_port %p", port->fct_port); 1172291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1173fcf3ce44SJohn Forte MODSYM(fct_deregister_local_port) (port->fct_port); 1174fcf3ce44SJohn Forte 1175fcf3ce44SJohn Forte if (port->fct_port->port_fds) { 1176fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1177fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1178fcf3ce44SJohn Forte "fct_free:3 %p", port->fct_port->port_fds); 1179291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1180fcf3ce44SJohn Forte MODSYM(fct_free) (port->fct_port->port_fds); 1181fcf3ce44SJohn Forte port->fct_port->port_fds = NULL; 1182fcf3ce44SJohn Forte } 1183fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1184fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1185fcf3ce44SJohn Forte "fct_free:4 %p", port->fct_port); 1186291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1187fcf3ce44SJohn Forte MODSYM(fct_free) (port->fct_port); 1188fcf3ce44SJohn Forte port->fct_port = NULL; 1189fcf3ce44SJohn Forte port->fct_flags = 0; 1190fcf3ce44SJohn Forte } 1191291a2b48SSukumar Swaminathan 1192fcf3ce44SJohn Forte if (port->port_provider) { 1193fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1194fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1195291a2b48SSukumar Swaminathan "stmf_deregister_port_provider:1 %p", 1196291a2b48SSukumar Swaminathan port->port_provider); 1197291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1198fcf3ce44SJohn Forte MODSYM(stmf_deregister_port_provider) (port->port_provider); 1199fcf3ce44SJohn Forte 1200fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1201fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1202fcf3ce44SJohn Forte "stmf_free:1 %p", port->port_provider); 1203291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1204fcf3ce44SJohn Forte MODSYM(stmf_free) (port->port_provider); 1205fcf3ce44SJohn Forte port->port_provider = NULL; 1206fcf3ce44SJohn Forte } 1207291a2b48SSukumar Swaminathan 1208fcf3ce44SJohn Forte if (port->dmem_bucket) { 1209fcf3ce44SJohn Forte emlxs_fct_dmem_fini(port); 1210fcf3ce44SJohn Forte } 1211291a2b48SSukumar Swaminathan 1212fcf3ce44SJohn Forte (void) sprintf(node_name, "%d,%d:SFCT", hba->ddiinst, port->vpi); 1213fcf3ce44SJohn Forte (void) ddi_remove_minor_node(hba->dip, node_name); 1214fcf3ce44SJohn Forte 1215fcf3ce44SJohn Forte return; 1216fcf3ce44SJohn Forte 121782527734SSukumar Swaminathan } /* emlxs_fct_unbind_port() */ 1218fcf3ce44SJohn Forte 1219fcf3ce44SJohn Forte 1220fcf3ce44SJohn Forte extern void 1221fcf3ce44SJohn Forte emlxs_fct_bind_port(emlxs_port_t *port) 1222fcf3ce44SJohn Forte { 1223fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1224fcf3ce44SJohn Forte fct_local_port_t *fct_port; 1225fcf3ce44SJohn Forte uint32_t flag = 0; 1226fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 1227fcf3ce44SJohn Forte fct_dbuf_store_t *fds; 1228fcf3ce44SJohn Forte char node_name[32]; 122982527734SSukumar Swaminathan uint8_t *bptr; 1230fcf3ce44SJohn Forte 1231fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 1232fcf3ce44SJohn Forte 1233fcf3ce44SJohn Forte if (!hba->tgt_mode || !port->tgt_mode) { 1234fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1235fcf3ce44SJohn Forte return; 1236fcf3ce44SJohn Forte } 1237291a2b48SSukumar Swaminathan 1238fcf3ce44SJohn Forte if (port->flag & EMLXS_PORT_BOUND) { 1239fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1240fcf3ce44SJohn Forte return; 1241fcf3ce44SJohn Forte } 1242291a2b48SSukumar Swaminathan 1243fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1244fcf3ce44SJohn Forte "emlxs_fct_bind_port: port=%d", port->vpi); 1245fcf3ce44SJohn Forte 1246fcf3ce44SJohn Forte /* Perform generic port initialization */ 1247fcf3ce44SJohn Forte emlxs_port_init(port); 1248fcf3ce44SJohn Forte 1249fcf3ce44SJohn Forte if (port->vpi == 0) { 1250fcf3ce44SJohn Forte (void) sprintf(port->cfd_name, "%s%d", DRIVER_NAME, 1251fcf3ce44SJohn Forte hba->ddiinst); 1252fcf3ce44SJohn Forte } else { 1253fcf3ce44SJohn Forte (void) sprintf(port->cfd_name, "%s%d.%d", DRIVER_NAME, 1254fcf3ce44SJohn Forte hba->ddiinst, port->vpi); 1255fcf3ce44SJohn Forte } 1256fcf3ce44SJohn Forte 1257fcf3ce44SJohn Forte if (emlxs_fct_dmem_init(port) != FCT_SUCCESS) { 1258fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1259fcf3ce44SJohn Forte "emlxs_fct_bind_port: Unable to allocate fct memory."); 1260fcf3ce44SJohn Forte goto failed; 1261fcf3ce44SJohn Forte } 1262fcf3ce44SJohn Forte flag |= 0x00000001; 1263fcf3ce44SJohn Forte 1264291a2b48SSukumar Swaminathan port->port_provider = 1265291a2b48SSukumar Swaminathan (stmf_port_provider_t *) 1266fcf3ce44SJohn Forte MODSYM(stmf_alloc) (STMF_STRUCT_PORT_PROVIDER, 0, 0); 1267fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1268fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1269fcf3ce44SJohn Forte "stmf_alloc port_provider %p", port->port_provider); 1270291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1271fcf3ce44SJohn Forte 1272fcf3ce44SJohn Forte if (port->port_provider == NULL) { 1273fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1274291a2b48SSukumar Swaminathan "emlxs_fct_bind_port: Unable to allocate port provider."); 1275fcf3ce44SJohn Forte goto failed; 1276fcf3ce44SJohn Forte } 1277fcf3ce44SJohn Forte flag |= 0x00000002; 1278fcf3ce44SJohn Forte 1279fcf3ce44SJohn Forte port->port_provider->pp_portif_rev = PORTIF_REV_1; 1280fcf3ce44SJohn Forte port->port_provider->pp_name = port->cfd_name; 1281fcf3ce44SJohn Forte port->port_provider->pp_provider_private = port; 1282fcf3ce44SJohn Forte 1283fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1284fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1285fcf3ce44SJohn Forte "stmf_register_port_provider %p", port->port_provider); 1286291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1287fcf3ce44SJohn Forte /* register port provider with framework */ 1288291a2b48SSukumar Swaminathan if (MODSYM(stmf_register_port_provider) (port->port_provider) != 1289291a2b48SSukumar Swaminathan STMF_SUCCESS) { 1290fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1291291a2b48SSukumar Swaminathan "emlxs_fct_bind_port: Unable to register port provider."); 1292fcf3ce44SJohn Forte goto failed; 1293fcf3ce44SJohn Forte } 1294fcf3ce44SJohn Forte flag |= 0x00000004; 1295fcf3ce44SJohn Forte 1296291a2b48SSukumar Swaminathan port->fct_port = 1297291a2b48SSukumar Swaminathan (fct_local_port_t *)MODSYM(fct_alloc) (FCT_STRUCT_LOCAL_PORT, 0, 1298291a2b48SSukumar Swaminathan 0); 1299fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1300fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1301fcf3ce44SJohn Forte "fct_alloc fct_port %p", port->fct_port); 1302291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1303fcf3ce44SJohn Forte 1304fcf3ce44SJohn Forte if (port->fct_port == NULL) { 1305fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1306fcf3ce44SJohn Forte "emlxs_fct_bind_port: Unable to allocate fct port."); 1307fcf3ce44SJohn Forte goto failed; 1308fcf3ce44SJohn Forte } 1309fcf3ce44SJohn Forte flag |= 0x00000008; 1310fcf3ce44SJohn Forte 1311291a2b48SSukumar Swaminathan port->fct_port->port_fds = 1312291a2b48SSukumar Swaminathan (fct_dbuf_store_t *)MODSYM(fct_alloc) (FCT_STRUCT_DBUF_STORE, 0, 1313291a2b48SSukumar Swaminathan 0); 1314fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1315fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1316fcf3ce44SJohn Forte "fct_alloc port_fds %p", port->fct_port->port_fds); 1317291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1318fcf3ce44SJohn Forte 1319fcf3ce44SJohn Forte if (port->fct_port->port_fds == NULL) { 1320fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1321fcf3ce44SJohn Forte "emlxs_fct_bind_port: Unable to allocate dbuf store."); 1322fcf3ce44SJohn Forte goto failed; 1323fcf3ce44SJohn Forte } 1324fcf3ce44SJohn Forte flag |= 0x00000010; 1325fcf3ce44SJohn Forte 1326fcf3ce44SJohn Forte (void) sprintf(node_name, "%d,%d:SFCT", hba->ddiinst, port->vpi); 1327291a2b48SSukumar Swaminathan if (ddi_create_minor_node(hba->dip, node_name, S_IFCHR, hba->ddiinst, 1328291a2b48SSukumar Swaminathan NULL, 0) == DDI_FAILURE) { 1329fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1330fcf3ce44SJohn Forte "Unable to create SFCT device node."); 1331fcf3ce44SJohn Forte goto failed; 1332fcf3ce44SJohn Forte } 1333fcf3ce44SJohn Forte flag |= 0x00000020; 1334fcf3ce44SJohn Forte 1335fcf3ce44SJohn Forte /* Intialize */ 1336fcf3ce44SJohn Forte fct_port = port->fct_port; 1337162fafd3Sallan fct_port->port_fca_version = FCT_FCA_MODREV_1; 1338fcf3ce44SJohn Forte fct_port->port_fca_private = port; 1339fcf3ce44SJohn Forte fct_port->port_fca_abort_timeout = 30 * 1000; /* 30 seconds */ 1340fcf3ce44SJohn Forte 1341fcf3ce44SJohn Forte bcopy((uint8_t *)&port->wwpn, (uint8_t *)fct_port->port_pwwn, 8); 1342fcf3ce44SJohn Forte bcopy((uint8_t *)&port->wwnn, (uint8_t *)fct_port->port_nwwn, 8); 1343fcf3ce44SJohn Forte 134482527734SSukumar Swaminathan bptr = (uint8_t *)&port->wwnn; 134582527734SSukumar Swaminathan (void) sprintf(fct_port->port_nwwn_str, 134682527734SSukumar Swaminathan "%02x%02x%02x%02x%02x%02x%02x%02x", 134782527734SSukumar Swaminathan bptr[0], bptr[1], bptr[2], bptr[3], 134882527734SSukumar Swaminathan bptr[4], bptr[5], bptr[6], bptr[7]); 134982527734SSukumar Swaminathan 135082527734SSukumar Swaminathan bptr = (uint8_t *)&port->wwpn; 135182527734SSukumar Swaminathan (void) sprintf(fct_port->port_pwwn_str, 135282527734SSukumar Swaminathan "%02x%02x%02x%02x%02x%02x%02x%02x", 135382527734SSukumar Swaminathan bptr[0], bptr[1], bptr[2], bptr[3], 135482527734SSukumar Swaminathan bptr[4], bptr[5], bptr[6], bptr[7]); 135582527734SSukumar Swaminathan 1356fcf3ce44SJohn Forte fct_port->port_sym_node_name = port->snn; 1357fcf3ce44SJohn Forte fct_port->port_sym_port_name = port->spn; 1358fcf3ce44SJohn Forte fct_port->port_hard_address = cfg[CFG_ASSIGN_ALPA].current; 1359fcf3ce44SJohn Forte fct_port->port_default_alias = port->cfd_name; 1360fcf3ce44SJohn Forte fct_port->port_pp = port->port_provider; 1361fcf3ce44SJohn Forte fct_port->port_max_logins = hba->max_nodes; 1362fcf3ce44SJohn Forte 1363bce54adfSSukumar Swaminathan if (cfg[CFG_FCT_QDEPTH].current && 1364bce54adfSSukumar Swaminathan (cfg[CFG_FCT_QDEPTH].current < hba->io_throttle)) { 1365bce54adfSSukumar Swaminathan fct_port->port_max_xchges = cfg[CFG_FCT_QDEPTH].current; 1366fcf3ce44SJohn Forte } else { 1367fcf3ce44SJohn Forte fct_port->port_max_xchges = hba->io_throttle; 1368fcf3ce44SJohn Forte } 1369fcf3ce44SJohn Forte 1370fcf3ce44SJohn Forte fct_port->port_fca_fcp_cmd_size = sizeof (emlxs_buf_t); 1371fcf3ce44SJohn Forte fct_port->port_fca_rp_private_size = sizeof (uintptr_t); 1372fcf3ce44SJohn Forte fct_port->port_fca_sol_els_private_size = sizeof (emlxs_buf_t); 1373fcf3ce44SJohn Forte fct_port->port_fca_sol_ct_private_size = sizeof (emlxs_buf_t); 1374fcf3ce44SJohn Forte fct_port->port_get_link_info = emlxs_fct_get_link_info; 1375fcf3ce44SJohn Forte fct_port->port_register_remote_port = emlxs_fct_register_remote_port; 1376fcf3ce44SJohn Forte fct_port->port_deregister_remote_port = 1377fcf3ce44SJohn Forte emlxs_fct_deregister_remote_port; 1378fcf3ce44SJohn Forte fct_port->port_send_cmd = emlxs_fct_send_cmd; 1379fcf3ce44SJohn Forte fct_port->port_xfer_scsi_data = emlxs_fct_send_fcp_data; 1380fcf3ce44SJohn Forte fct_port->port_send_cmd_response = emlxs_fct_send_cmd_rsp; 1381fcf3ce44SJohn Forte fct_port->port_abort_cmd = emlxs_fct_abort; 1382fcf3ce44SJohn Forte fct_port->port_ctl = emlxs_fct_ctl; 138382527734SSukumar Swaminathan fct_port->port_flogi_xchg = emlxs_fct_flogi_xchg; 138482527734SSukumar Swaminathan fct_port->port_populate_hba_details = emlxs_fct_populate_hba_details; 138582527734SSukumar Swaminathan fct_port->port_info = emlxs_fct_port_info; 1386fcf3ce44SJohn Forte 1387fcf3ce44SJohn Forte fds = port->fct_port->port_fds; 1388fcf3ce44SJohn Forte fds->fds_fca_private = port; 1389fcf3ce44SJohn Forte fds->fds_alloc_data_buf = emlxs_fct_dbuf_alloc; 1390fcf3ce44SJohn Forte fds->fds_free_data_buf = emlxs_fct_dbuf_free; 1391fcf3ce44SJohn Forte 1392fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1393fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1394fcf3ce44SJohn Forte "fct_register_local_port %p", fct_port); 1395291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1396fcf3ce44SJohn Forte /* register this local port with the fct module */ 1397fcf3ce44SJohn Forte if (MODSYM(fct_register_local_port) (fct_port) != FCT_SUCCESS) { 1398fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1399fcf3ce44SJohn Forte "emlxs_fct_bind_port: Unable to register fct port."); 1400fcf3ce44SJohn Forte goto failed; 1401fcf3ce44SJohn Forte } 1402291a2b48SSukumar Swaminathan 1403fcf3ce44SJohn Forte /* Set the bound flag */ 1404fcf3ce44SJohn Forte port->flag |= EMLXS_PORT_BOUND; 1405fcf3ce44SJohn Forte hba->num_of_ports++; 1406fcf3ce44SJohn Forte 1407fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1408fcf3ce44SJohn Forte 1409fcf3ce44SJohn Forte return; 1410fcf3ce44SJohn Forte 1411fcf3ce44SJohn Forte failed: 1412fcf3ce44SJohn Forte 1413fcf3ce44SJohn Forte if (flag & 0x20) { 1414fcf3ce44SJohn Forte (void) ddi_remove_minor_node(hba->dip, node_name); 1415fcf3ce44SJohn Forte } 1416291a2b48SSukumar Swaminathan 1417fcf3ce44SJohn Forte if (flag & 0x10) { 1418fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1419fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1420fcf3ce44SJohn Forte "fct_free:5 %p", port->fct_port->port_fds); 1421291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1422fcf3ce44SJohn Forte MODSYM(fct_free) (port->fct_port->port_fds); 1423fcf3ce44SJohn Forte port->fct_port->port_fds = NULL; 1424fcf3ce44SJohn Forte } 1425291a2b48SSukumar Swaminathan 1426fcf3ce44SJohn Forte if (flag & 0x8) { 1427fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1428fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1429fcf3ce44SJohn Forte "fct_free:6 %p", port->fct_port); 1430291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1431fcf3ce44SJohn Forte MODSYM(fct_free) (port->fct_port); 1432fcf3ce44SJohn Forte port->fct_port = NULL; 1433fcf3ce44SJohn Forte port->fct_flags = 0; 1434fcf3ce44SJohn Forte } 1435291a2b48SSukumar Swaminathan 1436fcf3ce44SJohn Forte if (flag & 0x4) { 1437fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1438fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1439291a2b48SSukumar Swaminathan "stmf_deregister_port_provider:2 %p", 1440291a2b48SSukumar Swaminathan port->port_provider); 1441291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1442fcf3ce44SJohn Forte MODSYM(stmf_deregister_port_provider) (port->port_provider); 1443fcf3ce44SJohn Forte } 1444291a2b48SSukumar Swaminathan 1445fcf3ce44SJohn Forte if (flag & 0x2) { 1446fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1447fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1448fcf3ce44SJohn Forte "stmf_free:2 %p", port->port_provider); 1449291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1450fcf3ce44SJohn Forte MODSYM(stmf_free) (port->port_provider); 1451fcf3ce44SJohn Forte port->port_provider = NULL; 1452fcf3ce44SJohn Forte } 1453291a2b48SSukumar Swaminathan 1454fcf3ce44SJohn Forte if (flag & 0x1) { 1455fcf3ce44SJohn Forte emlxs_fct_dmem_fini(port); 1456fcf3ce44SJohn Forte } 1457291a2b48SSukumar Swaminathan 1458fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1459fcf3ce44SJohn Forte "Target mode disabled."); 1460fcf3ce44SJohn Forte 1461fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1462fcf3ce44SJohn Forte 1463fcf3ce44SJohn Forte return; 1464fcf3ce44SJohn Forte 146582527734SSukumar Swaminathan } /* emlxs_fct_bind_port() */ 146682527734SSukumar Swaminathan 146782527734SSukumar Swaminathan 146882527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 146982527734SSukumar Swaminathan /*ARGSUSED*/ 147082527734SSukumar Swaminathan static fct_status_t 147182527734SSukumar Swaminathan emlxs_fct_port_info(uint32_t cmd, fct_local_port_t *fct_port, void *arg, 147282527734SSukumar Swaminathan uint8_t *buffer, uint32_t *size) 147382527734SSukumar Swaminathan { 147482527734SSukumar Swaminathan emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 147582527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 147682527734SSukumar Swaminathan fct_status_t rval = FCT_SUCCESS; 147782527734SSukumar Swaminathan fct_port_link_status_t *link_status; 147882527734SSukumar Swaminathan MAILBOX *mb; 147982527734SSukumar Swaminathan MAILBOXQ *mbq; 148082527734SSukumar Swaminathan 148182527734SSukumar Swaminathan switch (cmd) { 148282527734SSukumar Swaminathan case FC_TGT_PORT_RLS: 148382527734SSukumar Swaminathan bzero(buffer, *size); 148482527734SSukumar Swaminathan 148582527734SSukumar Swaminathan if ((*size) < sizeof (fct_port_link_status_t)) { 148682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 148782527734SSukumar Swaminathan "FC_TGT_PORT_RLS: Buffer too small. %d < %d", 148882527734SSukumar Swaminathan *size, sizeof (fct_port_link_status_t)); 148982527734SSukumar Swaminathan 149082527734SSukumar Swaminathan rval = FCT_FAILURE; 149182527734SSukumar Swaminathan break; 149282527734SSukumar Swaminathan } 149382527734SSukumar Swaminathan 149482527734SSukumar Swaminathan if ((mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1)) == 0) { 149582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 149682527734SSukumar Swaminathan "FC_TGT_PORT_RLS: Unable to allocate mailbox."); 149782527734SSukumar Swaminathan 149882527734SSukumar Swaminathan rval = FCT_ALLOC_FAILURE; 149982527734SSukumar Swaminathan break; 150082527734SSukumar Swaminathan } 150182527734SSukumar Swaminathan mb = (MAILBOX *)mbq; 150282527734SSukumar Swaminathan 150382527734SSukumar Swaminathan emlxs_mb_read_lnk_stat(hba, mbq); 150482527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) 150582527734SSukumar Swaminathan != MBX_SUCCESS) { 150682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 150782527734SSukumar Swaminathan "FC_TGT_PORT_RLS: Unable to send request."); 150882527734SSukumar Swaminathan 150982527734SSukumar Swaminathan rval = FCT_BUSY; 151082527734SSukumar Swaminathan } else { 151182527734SSukumar Swaminathan link_status = (fct_port_link_status_t *)buffer; 151282527734SSukumar Swaminathan link_status->LinkFailureCount = 151382527734SSukumar Swaminathan mb->un.varRdLnk.linkFailureCnt; 151482527734SSukumar Swaminathan link_status->LossOfSyncCount = 151582527734SSukumar Swaminathan mb->un.varRdLnk.lossSyncCnt; 151682527734SSukumar Swaminathan link_status->LossOfSignalsCount = 151782527734SSukumar Swaminathan mb->un.varRdLnk.lossSignalCnt; 151882527734SSukumar Swaminathan link_status->PrimitiveSeqProtocolErrorCount = 151982527734SSukumar Swaminathan mb->un.varRdLnk.primSeqErrCnt; 152082527734SSukumar Swaminathan link_status->InvalidTransmissionWordCount = 152182527734SSukumar Swaminathan mb->un.varRdLnk.invalidXmitWord; 152282527734SSukumar Swaminathan link_status->InvalidCRCCount = 152382527734SSukumar Swaminathan mb->un.varRdLnk.crcCnt; 152482527734SSukumar Swaminathan } 152582527734SSukumar Swaminathan 1526*a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 152782527734SSukumar Swaminathan break; 152882527734SSukumar Swaminathan 152982527734SSukumar Swaminathan default: 153082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 153182527734SSukumar Swaminathan "emlxs_fct_port_info: Invalid request. cmd=%x", 153282527734SSukumar Swaminathan cmd); 153382527734SSukumar Swaminathan 153482527734SSukumar Swaminathan rval = FCT_FAILURE; 153582527734SSukumar Swaminathan break; 153682527734SSukumar Swaminathan 153782527734SSukumar Swaminathan } 1538fcf3ce44SJohn Forte 153982527734SSukumar Swaminathan return (rval); 154082527734SSukumar Swaminathan 154182527734SSukumar Swaminathan } /* emlxs_fct_port_info() */ 1542fcf3ce44SJohn Forte 154382527734SSukumar Swaminathan 154482527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 1545fcf3ce44SJohn Forte static void 154682527734SSukumar Swaminathan emlxs_fct_populate_hba_details(fct_local_port_t *fct_port, 1547fcf3ce44SJohn Forte fct_port_attrs_t *port_attrs) 1548fcf3ce44SJohn Forte { 1549fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 1550fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1551fcf3ce44SJohn Forte emlxs_vpd_t *vpd = &VPD; 1552fcf3ce44SJohn Forte 1553fcf3ce44SJohn Forte (void) strcpy(port_attrs->manufacturer, "Emulex"); 1554fcf3ce44SJohn Forte (void) strcpy(port_attrs->serial_number, vpd->serial_num); 1555fcf3ce44SJohn Forte (void) strcpy(port_attrs->model, hba->model_info.model); 1556fcf3ce44SJohn Forte (void) strcpy(port_attrs->model_description, 1557fcf3ce44SJohn Forte hba->model_info.model_desc); 1558fcf3ce44SJohn Forte (void) sprintf(port_attrs->hardware_version, "%x", vpd->biuRev); 1559fcf3ce44SJohn Forte (void) sprintf(port_attrs->driver_version, "%s (%s)", emlxs_version, 1560fcf3ce44SJohn Forte emlxs_revision); 1561fcf3ce44SJohn Forte (void) strcpy(port_attrs->option_rom_version, vpd->fcode_version); 1562fcf3ce44SJohn Forte (void) sprintf(port_attrs->firmware_version, "%s (%s)", vpd->fw_version, 1563fcf3ce44SJohn Forte vpd->fw_label); 1564fcf3ce44SJohn Forte (void) strcpy(port_attrs->driver_name, DRIVER_NAME); 1565fcf3ce44SJohn Forte port_attrs->vendor_specific_id = 1566fcf3ce44SJohn Forte ((hba->model_info.device_id << 16) | PCI_VENDOR_ID_EMULEX); 156782527734SSukumar Swaminathan port_attrs->supported_cos = LE_SWAP32(FC_NS_CLASS3); 1568fcf3ce44SJohn Forte 1569fcf3ce44SJohn Forte port_attrs->max_frame_size = FF_FRAME_SIZE; 1570fcf3ce44SJohn Forte 1571fcf3ce44SJohn Forte if (vpd->link_speed & LMT_10GB_CAPABLE) { 1572291a2b48SSukumar Swaminathan port_attrs->supported_speed |= PORT_SPEED_10G; 1573fcf3ce44SJohn Forte } 1574fcf3ce44SJohn Forte if (vpd->link_speed & LMT_8GB_CAPABLE) { 1575291a2b48SSukumar Swaminathan port_attrs->supported_speed |= PORT_SPEED_8G; 1576fcf3ce44SJohn Forte } 1577fcf3ce44SJohn Forte if (vpd->link_speed & LMT_4GB_CAPABLE) { 1578291a2b48SSukumar Swaminathan port_attrs->supported_speed |= PORT_SPEED_4G; 1579fcf3ce44SJohn Forte } 1580fcf3ce44SJohn Forte if (vpd->link_speed & LMT_2GB_CAPABLE) { 1581291a2b48SSukumar Swaminathan port_attrs->supported_speed |= PORT_SPEED_2G; 1582fcf3ce44SJohn Forte } 1583fcf3ce44SJohn Forte if (vpd->link_speed & LMT_1GB_CAPABLE) { 1584291a2b48SSukumar Swaminathan port_attrs->supported_speed |= PORT_SPEED_1G; 1585fcf3ce44SJohn Forte } 1586291a2b48SSukumar Swaminathan 1587fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1588fcf3ce44SJohn Forte "Port attr: manufacturer = %s", port_attrs->manufacturer); 1589fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1590fcf3ce44SJohn Forte "Port attr: serial_num = %s", port_attrs->serial_number); 1591fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1592fcf3ce44SJohn Forte "Port attr: model = %s", port_attrs->model); 1593fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1594fcf3ce44SJohn Forte "Port attr: model_description = %s", 1595fcf3ce44SJohn Forte port_attrs->model_description); 1596fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1597291a2b48SSukumar Swaminathan "Port attr: hardware_version = %s", 1598291a2b48SSukumar Swaminathan port_attrs->hardware_version); 1599fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1600fcf3ce44SJohn Forte "Port attr: driver_version = %s", port_attrs->driver_version); 1601fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1602fcf3ce44SJohn Forte "Port attr: option_rom_version = %s", 1603fcf3ce44SJohn Forte port_attrs->option_rom_version); 1604fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1605291a2b48SSukumar Swaminathan "Port attr: firmware_version = %s", 1606291a2b48SSukumar Swaminathan port_attrs->firmware_version); 1607fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1608fcf3ce44SJohn Forte "Port attr: driver_name = %s", port_attrs->driver_name); 1609fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1610fcf3ce44SJohn Forte "Port attr: vendor_specific_id = 0x%x", 1611fcf3ce44SJohn Forte port_attrs->vendor_specific_id); 1612fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1613291a2b48SSukumar Swaminathan "Port attr: supported_cos = 0x%x", 1614291a2b48SSukumar Swaminathan port_attrs->supported_cos); 1615fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1616fcf3ce44SJohn Forte "Port attr: supported_speed = 0x%x", 1617fcf3ce44SJohn Forte port_attrs->supported_speed); 1618fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1619291a2b48SSukumar Swaminathan "Port attr: max_frame_size = 0x%x", 1620291a2b48SSukumar Swaminathan port_attrs->max_frame_size); 1621fcf3ce44SJohn Forte 1622fcf3ce44SJohn Forte return; 1623fcf3ce44SJohn Forte 162482527734SSukumar Swaminathan } /* emlxs_fct_populate_hba_details() */ 1625fcf3ce44SJohn Forte 1626fcf3ce44SJohn Forte 162782527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 1628fcf3ce44SJohn Forte /* ARGSUSED */ 1629fcf3ce44SJohn Forte static void 1630fcf3ce44SJohn Forte emlxs_fct_ctl(fct_local_port_t *fct_port, int cmd, void *arg) 1631fcf3ce44SJohn Forte { 1632fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 1633fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1634fcf3ce44SJohn Forte stmf_change_status_t st; 1635fcf3ce44SJohn Forte 1636fcf3ce44SJohn Forte st.st_completion_status = FCT_SUCCESS; 1637fcf3ce44SJohn Forte st.st_additional_info = NULL; 1638fcf3ce44SJohn Forte 1639fcf3ce44SJohn Forte switch (cmd) { 1640fcf3ce44SJohn Forte case FCT_CMD_PORT_ONLINE: 1641fcf3ce44SJohn Forte /* If the HBA is offline, we cannot bring the tgtport online */ 1642fcf3ce44SJohn Forte if (hba->flag & (FC_OFFLINE_MODE | FC_OFFLINING_MODE)) { 1643fcf3ce44SJohn Forte st.st_completion_status = FCT_FAILURE; 1644fcf3ce44SJohn Forte MODSYM(fct_ctl) (fct_port->port_lport, 1645fcf3ce44SJohn Forte FCT_CMD_PORT_ONLINE_COMPLETE, &st); 1646fcf3ce44SJohn Forte break; 1647fcf3ce44SJohn Forte } 1648291a2b48SSukumar Swaminathan 1649fcf3ce44SJohn Forte if (port->fct_flags & FCT_STATE_PORT_ONLINE) { 1650fcf3ce44SJohn Forte st.st_completion_status = STMF_ALREADY; 1651fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1652fcf3ce44SJohn Forte "STATE: ONLINE chk"); 1653fcf3ce44SJohn Forte } else { 1654fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1655fcf3ce44SJohn Forte "STATE: OFFLINE --> ONLINE"); 1656fcf3ce44SJohn Forte 1657fcf3ce44SJohn Forte port->fct_flags |= FCT_STATE_NOT_ACKED; 1658fcf3ce44SJohn Forte port->fct_flags |= FCT_STATE_PORT_ONLINE; 1659fcf3ce44SJohn Forte 1660fcf3ce44SJohn Forte if (hba->state <= FC_LINK_DOWN) { 1661fcf3ce44SJohn Forte /* Try to bring the link up */ 166282527734SSukumar Swaminathan (void) emlxs_reset_link(hba, 1, 1); 1663fcf3ce44SJohn Forte } 1664291a2b48SSukumar Swaminathan 1665fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1666fcf3ce44SJohn Forte "STATE: ONLINE"); 1667fcf3ce44SJohn Forte } 1668fcf3ce44SJohn Forte 1669fcf3ce44SJohn Forte MODSYM(fct_ctl) (fct_port->port_lport, 1670fcf3ce44SJohn Forte FCT_CMD_PORT_ONLINE_COMPLETE, &st); 1671fcf3ce44SJohn Forte break; 1672fcf3ce44SJohn Forte 1673fcf3ce44SJohn Forte case FCT_CMD_PORT_OFFLINE: 1674fcf3ce44SJohn Forte if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) { 1675fcf3ce44SJohn Forte st.st_completion_status = STMF_ALREADY; 1676fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1677fcf3ce44SJohn Forte "STATE: OFFLINE chk"); 1678fcf3ce44SJohn Forte 1679fcf3ce44SJohn Forte } else { 1680fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1681fcf3ce44SJohn Forte "STATE: ONLINE --> OFFLINE"); 1682fcf3ce44SJohn Forte 1683fcf3ce44SJohn Forte /* Take link down and flush */ 1684fcf3ce44SJohn Forte emlxs_fct_link_down(port); 1685fcf3ce44SJohn Forte emlxs_fct_unsol_flush(port); 1686fcf3ce44SJohn Forte 1687fcf3ce44SJohn Forte /* Declare this port offline now */ 1688fcf3ce44SJohn Forte port->fct_flags |= FCT_STATE_NOT_ACKED; 1689fcf3ce44SJohn Forte port->fct_flags &= ~FCT_STATE_PORT_ONLINE; 1690fcf3ce44SJohn Forte 1691fcf3ce44SJohn Forte /* Take link down and hold it down */ 169282527734SSukumar Swaminathan (void) emlxs_reset_link(hba, 0, 1); 1693fcf3ce44SJohn Forte 1694fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1695fcf3ce44SJohn Forte "STATE: OFFLINE"); 1696fcf3ce44SJohn Forte } 1697fcf3ce44SJohn Forte 1698fcf3ce44SJohn Forte MODSYM(fct_ctl) (fct_port->port_lport, 1699fcf3ce44SJohn Forte FCT_CMD_PORT_OFFLINE_COMPLETE, &st); 1700fcf3ce44SJohn Forte 1701fcf3ce44SJohn Forte break; 1702fcf3ce44SJohn Forte 1703fcf3ce44SJohn Forte case FCT_ACK_PORT_OFFLINE_COMPLETE: 1704fcf3ce44SJohn Forte port->fct_flags &= ~FCT_STATE_NOT_ACKED; 1705fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1706fcf3ce44SJohn Forte "STATE: OFFLINE ack"); 1707fcf3ce44SJohn Forte break; 1708fcf3ce44SJohn Forte 1709fcf3ce44SJohn Forte case FCT_ACK_PORT_ONLINE_COMPLETE: 1710fcf3ce44SJohn Forte port->fct_flags &= ~FCT_STATE_NOT_ACKED; 1711fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1712fcf3ce44SJohn Forte "STATE: ONLINE ack"); 1713fcf3ce44SJohn Forte break; 1714fcf3ce44SJohn Forte 171582527734SSukumar Swaminathan case FCT_CMD_FORCE_LIP: 1716*a9800bebSGarrett D'Amore if (hba->fw_flag & FW_UPDATE_NEEDED) { 1717*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1718*a9800bebSGarrett D'Amore "emlxs_fct_ctl: FCT_CMD_FORCE_LIP -> " 1719*a9800bebSGarrett D'Amore "FCT_CMD_RESET"); 1720*a9800bebSGarrett D'Amore 1721*a9800bebSGarrett D'Amore hba->fw_flag |= FW_UPDATE_KERNEL; 1722*a9800bebSGarrett D'Amore /* Reset the adapter */ 1723*a9800bebSGarrett D'Amore (void) emlxs_reset(port, FC_FCA_RESET); 1724*a9800bebSGarrett D'Amore } else { 1725*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1726*a9800bebSGarrett D'Amore "emlxs_fct_ctl: FCT_CMD_FORCE_LIP"); 172782527734SSukumar Swaminathan 1728*a9800bebSGarrett D'Amore /* Reset the link */ 1729*a9800bebSGarrett D'Amore (void) emlxs_reset(port, FC_FCA_LINK_RESET); 1730*a9800bebSGarrett D'Amore } 173182527734SSukumar Swaminathan break; 1732fcf3ce44SJohn Forte } 1733fcf3ce44SJohn Forte 1734fcf3ce44SJohn Forte return; 1735fcf3ce44SJohn Forte 173682527734SSukumar Swaminathan } /* emlxs_fct_ctl() */ 1737291a2b48SSukumar Swaminathan 1738fcf3ce44SJohn Forte 1739fcf3ce44SJohn Forte extern int 1740fcf3ce44SJohn Forte emlxs_fct_port_shutdown(emlxs_port_t *port) 1741fcf3ce44SJohn Forte { 1742fcf3ce44SJohn Forte fct_local_port_t *fct_port; 174382527734SSukumar Swaminathan int i; 1744fcf3ce44SJohn Forte 1745fcf3ce44SJohn Forte fct_port = port->fct_port; 1746fcf3ce44SJohn Forte if (!fct_port) { 1747fcf3ce44SJohn Forte return (0); 1748fcf3ce44SJohn Forte } 17493be114edSSukumar Swaminathan 17503be114edSSukumar Swaminathan port->fct_flags |= FCT_STATE_NOT_ACKED; 17513be114edSSukumar Swaminathan 1752291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, "fct_port_shutdown"); 1753fcf3ce44SJohn Forte MODSYM(fct_port_shutdown) (fct_port, STMF_RFLAG_STAY_OFFLINED, 1754fcf3ce44SJohn Forte "emlxs shutdown"); 1755fcf3ce44SJohn Forte 175682527734SSukumar Swaminathan i = 0; 1757fcf3ce44SJohn Forte while (port->fct_flags & FCT_STATE_NOT_ACKED) { 1758fcf3ce44SJohn Forte i++; 1759fcf3ce44SJohn Forte if (i > 300) { /* 30 seconds */ 1760fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1761fcf3ce44SJohn Forte "fct_port_shutdown failed to ACK"); 1762fcf3ce44SJohn Forte break; 1763fcf3ce44SJohn Forte } 1764fcf3ce44SJohn Forte delay(drv_usectohz(100000)); /* 100 msec */ 1765fcf3ce44SJohn Forte } 1766fcf3ce44SJohn Forte return (1); 1767fcf3ce44SJohn Forte } 1768fcf3ce44SJohn Forte 1769fcf3ce44SJohn Forte 1770fcf3ce44SJohn Forte extern int 1771fcf3ce44SJohn Forte emlxs_fct_port_initialize(emlxs_port_t *port) 1772fcf3ce44SJohn Forte { 1773fcf3ce44SJohn Forte fct_local_port_t *fct_port; 177482527734SSukumar Swaminathan int i; 1775fcf3ce44SJohn Forte 1776fcf3ce44SJohn Forte fct_port = port->fct_port; 1777fcf3ce44SJohn Forte if (!fct_port) { 1778fcf3ce44SJohn Forte return (0); 1779fcf3ce44SJohn Forte } 17803be114edSSukumar Swaminathan 17813be114edSSukumar Swaminathan port->fct_flags |= FCT_STATE_NOT_ACKED; 17823be114edSSukumar Swaminathan 1783fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1784fcf3ce44SJohn Forte "fct_port_initialize"); 1785fcf3ce44SJohn Forte MODSYM(fct_port_initialize) (fct_port, STMF_RFLAG_STAY_OFFLINED, 1786fcf3ce44SJohn Forte "emlxs initialize"); 1787fcf3ce44SJohn Forte 178882527734SSukumar Swaminathan i = 0; 1789fcf3ce44SJohn Forte while (port->fct_flags & FCT_STATE_NOT_ACKED) { 1790fcf3ce44SJohn Forte i++; 1791fcf3ce44SJohn Forte if (i > 300) { /* 30 seconds */ 1792fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1793fcf3ce44SJohn Forte "fct_port_initialize failed to ACK"); 1794fcf3ce44SJohn Forte break; 1795fcf3ce44SJohn Forte } 1796fcf3ce44SJohn Forte delay(drv_usectohz(100000)); /* 100 msec */ 1797fcf3ce44SJohn Forte } 1798fcf3ce44SJohn Forte return (1); 1799fcf3ce44SJohn Forte } 1800fcf3ce44SJohn Forte 1801291a2b48SSukumar Swaminathan 180282527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 1803fcf3ce44SJohn Forte static fct_status_t 1804fcf3ce44SJohn Forte emlxs_fct_send_cmd(fct_cmd_t *fct_cmd) 1805fcf3ce44SJohn Forte { 1806fcf3ce44SJohn Forte emlxs_port_t *port; 1807fcf3ce44SJohn Forte 1808fcf3ce44SJohn Forte port = (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 1809fcf3ce44SJohn Forte 1810fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1811fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1812fcf3ce44SJohn Forte "emlxs_fct_send_cmd %p: x%x", fct_cmd, fct_cmd->cmd_type); 1813291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1814fcf3ce44SJohn Forte 1815fcf3ce44SJohn Forte switch (fct_cmd->cmd_type) { 1816fcf3ce44SJohn Forte case FCT_CMD_SOL_ELS: 1817fcf3ce44SJohn Forte 1818fcf3ce44SJohn Forte return (emlxs_fct_send_els_cmd(fct_cmd)); 1819fcf3ce44SJohn Forte 1820fcf3ce44SJohn Forte case FCT_CMD_SOL_CT: 1821fcf3ce44SJohn Forte 1822fcf3ce44SJohn Forte return (emlxs_fct_send_ct_cmd(fct_cmd)); 1823fcf3ce44SJohn Forte 1824fcf3ce44SJohn Forte default: 1825fcf3ce44SJohn Forte 1826fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1827fcf3ce44SJohn Forte "emlxs_fct_send_cmd: Invalid cmd type found. type=%x", 1828fcf3ce44SJohn Forte fct_cmd->cmd_type); 1829fcf3ce44SJohn Forte 1830fcf3ce44SJohn Forte return (FCT_FAILURE); 1831fcf3ce44SJohn Forte } 1832fcf3ce44SJohn Forte 183382527734SSukumar Swaminathan } /* emlxs_fct_send_cmd() */ 1834fcf3ce44SJohn Forte 1835fcf3ce44SJohn Forte 183682527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 1837fcf3ce44SJohn Forte static fct_status_t 1838fcf3ce44SJohn Forte emlxs_fct_send_cmd_rsp(fct_cmd_t *fct_cmd, uint32_t ioflags) 1839fcf3ce44SJohn Forte { 1840fcf3ce44SJohn Forte emlxs_port_t *port; 1841291a2b48SSukumar Swaminathan emlxs_buf_t *cmd_sbp; 1842291a2b48SSukumar Swaminathan fct_status_t rval; 184382527734SSukumar Swaminathan IOCBQ *iocbq; 184482527734SSukumar Swaminathan IOCB *iocb; 184582527734SSukumar Swaminathan uint32_t status; 1846fcf3ce44SJohn Forte 1847fcf3ce44SJohn Forte port = (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 184882527734SSukumar Swaminathan 184982527734SSukumar Swaminathan rval = emlxs_fct_cmd_accept(port, fct_cmd, EMLXS_FCT_SEND_CMD_RSP); 185082527734SSukumar Swaminathan if (rval) { 185182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 185282527734SSukumar Swaminathan "emlxs_fct_send_cmd_rsp: " 185382527734SSukumar Swaminathan "Unable to accept fct_cmd. type=%x", 185482527734SSukumar Swaminathan fct_cmd->cmd_type); 185582527734SSukumar Swaminathan 185682527734SSukumar Swaminathan return (rval); 185782527734SSukumar Swaminathan } 185882527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 185982527734SSukumar Swaminathan 1860291a2b48SSukumar Swaminathan cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 186182527734SSukumar Swaminathan iocbq = &cmd_sbp->iocbq; 186282527734SSukumar Swaminathan iocb = &iocbq->iocb; 186382527734SSukumar Swaminathan status = iocb->ULPSTATUS; 1864fcf3ce44SJohn Forte 1865fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1866fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 186782527734SSukumar Swaminathan "emlxs_fct_send_cmd_rsp %p: x%x, %x, %x", 186882527734SSukumar Swaminathan fct_cmd, fct_cmd->cmd_type, iocb->ULPCT, status); 1869291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1870fcf3ce44SJohn Forte 1871fcf3ce44SJohn Forte switch (fct_cmd->cmd_type) { 1872fcf3ce44SJohn Forte case FCT_CMD_FCP_XCHG: 1873fcf3ce44SJohn Forte 1874fcf3ce44SJohn Forte if (ioflags & FCT_IOF_FORCE_FCA_DONE) { 1875fcf3ce44SJohn Forte goto failure; 1876fcf3ce44SJohn Forte } 1877291a2b48SSukumar Swaminathan 187882527734SSukumar Swaminathan if ((iocb->ULPCT == 0x1) && (status == 0)) { 187982527734SSukumar Swaminathan 188082527734SSukumar Swaminathan /* Firmware already sent out resp */ 188182527734SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_SEND_STATUS; 188282527734SSukumar Swaminathan 188382527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_IO_DONE); 188482527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 188582527734SSukumar Swaminathan 188682527734SSukumar Swaminathan #ifdef FCT_API_TRACE 188782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 188882527734SSukumar Swaminathan "fct_send_response_done:4 %p: x%x", 188982527734SSukumar Swaminathan fct_cmd, fct_cmd->cmd_comp_status); 189082527734SSukumar Swaminathan 189182527734SSukumar Swaminathan #endif /* FCT_API_TRACE */ 189282527734SSukumar Swaminathan 189382527734SSukumar Swaminathan MODSYM(fct_send_response_done) (fct_cmd, 189482527734SSukumar Swaminathan fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE); 189582527734SSukumar Swaminathan 189682527734SSukumar Swaminathan return (FCT_SUCCESS); 189782527734SSukumar Swaminathan } 189882527734SSukumar Swaminathan 1899291a2b48SSukumar Swaminathan rval = emlxs_fct_send_fcp_status(fct_cmd); 190082527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 190182527734SSukumar Swaminathan 1902291a2b48SSukumar Swaminathan return (rval); 1903fcf3ce44SJohn Forte 1904fcf3ce44SJohn Forte case FCT_CMD_RCVD_ELS: 1905fcf3ce44SJohn Forte 1906fcf3ce44SJohn Forte if (ioflags & FCT_IOF_FORCE_FCA_DONE) { 1907fcf3ce44SJohn Forte goto failure; 1908fcf3ce44SJohn Forte } 1909fcf3ce44SJohn Forte 191082527734SSukumar Swaminathan rval = emlxs_fct_send_els_rsp(fct_cmd); 191182527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 191282527734SSukumar Swaminathan 191382527734SSukumar Swaminathan return (rval); 1914fcf3ce44SJohn Forte 1915fcf3ce44SJohn Forte default: 1916fcf3ce44SJohn Forte 1917fcf3ce44SJohn Forte if (ioflags & FCT_IOF_FORCE_FCA_DONE) { 1918fcf3ce44SJohn Forte fct_cmd->cmd_handle = 0; 1919fcf3ce44SJohn Forte } 1920291a2b48SSukumar Swaminathan 1921fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1922fcf3ce44SJohn Forte "emlxs_fct_send_cmd_rsp: Invalid cmd type found. type=%x", 1923fcf3ce44SJohn Forte fct_cmd->cmd_type); 1924fcf3ce44SJohn Forte 1925fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 192682527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 192782527734SSukumar Swaminathan 1928fcf3ce44SJohn Forte return (FCT_FAILURE); 1929fcf3ce44SJohn Forte } 1930fcf3ce44SJohn Forte 1931fcf3ce44SJohn Forte failure: 1932fcf3ce44SJohn Forte 1933fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1934291a2b48SSukumar Swaminathan "emlxs_fct_send_cmd_rsp: " 1935291a2b48SSukumar Swaminathan "Unable to handle FCT_IOF_FORCE_FCA_DONE. type=%x", 1936291a2b48SSukumar Swaminathan fct_cmd->cmd_type); 1937fcf3ce44SJohn Forte 1938fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 193982527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 194082527734SSukumar Swaminathan 1941fcf3ce44SJohn Forte return (FCT_FAILURE); 1942fcf3ce44SJohn Forte 194382527734SSukumar Swaminathan } /* emlxs_fct_send_cmd_rsp() */ 1944fcf3ce44SJohn Forte 1945fcf3ce44SJohn Forte 194682527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 1947fcf3ce44SJohn Forte static fct_status_t 194882527734SSukumar Swaminathan emlxs_fct_flogi_xchg(struct fct_local_port *fct_port, struct fct_flogi_xchg *fx) 1949fcf3ce44SJohn Forte { 1950fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 1951fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1952fcf3ce44SJohn Forte uint32_t size; 195382527734SSukumar Swaminathan fc_packet_t *pkt = NULL; 1954fcf3ce44SJohn Forte ELS_PKT *els; 195582527734SSukumar Swaminathan fct_status_t rval = FCT_SUCCESS; 1956fcf3ce44SJohn Forte 1957fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1958fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 195982527734SSukumar Swaminathan "emlxs_fct_flogi_xchg: Sending FLOGI: %p", fct_port); 1960fcf3ce44SJohn Forte #else 1961fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 196282527734SSukumar Swaminathan "emlxs_fct_flogi_xchg: Sending FLOGI."); 1963291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1964fcf3ce44SJohn Forte 1965fcf3ce44SJohn Forte if (hba->state <= FC_LINK_DOWN) { 1966fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 196782527734SSukumar Swaminathan "emlxs_fct_flogi_xchg: FLOGI failed. Link down."); 196882527734SSukumar Swaminathan rval = FCT_FAILURE; 196982527734SSukumar Swaminathan goto done; 1970fcf3ce44SJohn Forte } 1971291a2b48SSukumar Swaminathan 1972e2ca2865SSukumar Swaminathan /* Use this entyr point as the link up acknowlegment */ 1973e2ca2865SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 1974e2ca2865SSukumar Swaminathan port->fct_flags |= FCT_STATE_LINK_UP_ACKED; 1975e2ca2865SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1976e2ca2865SSukumar Swaminathan "emlxs_fct_link_up acked."); 1977e2ca2865SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 1978e2ca2865SSukumar Swaminathan 1979e2ca2865SSukumar Swaminathan /* Now flush any pending unsolicited requests */ 1980e2ca2865SSukumar Swaminathan emlxs_fct_unsol_flush(port); 1981e2ca2865SSukumar Swaminathan 1982fcf3ce44SJohn Forte size = sizeof (SERV_PARM) + 4; 1983fcf3ce44SJohn Forte 1984fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, size, size, 0, KM_NOSLEEP))) { 1985fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 198682527734SSukumar Swaminathan "emlxs_fct_flogi_xchg: FLOGI failed. " 198782527734SSukumar Swaminathan "Unable allocate packet."); 198882527734SSukumar Swaminathan rval = FCT_FAILURE; 198982527734SSukumar Swaminathan goto done; 1990fcf3ce44SJohn Forte } 1991291a2b48SSukumar Swaminathan 1992fcf3ce44SJohn Forte /* Make this a polled IO */ 1993fcf3ce44SJohn Forte pkt->pkt_tran_flags &= ~FC_TRAN_INTR; 1994fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_NO_INTR; 1995fcf3ce44SJohn Forte pkt->pkt_comp = NULL; 1996fcf3ce44SJohn Forte 1997fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE; 1998fcf3ce44SJohn Forte pkt->pkt_timeout = fx->fx_sec_timeout; 1999fcf3ce44SJohn Forte 2000fcf3ce44SJohn Forte /* Build the fc header */ 200182527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(fx->fx_did); 2002291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.r_ctl = 2003291a2b48SSukumar Swaminathan R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL; 200482527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(fx->fx_sid); 2005fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 2006fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = F_CTL_FIRST_SEQ | F_CTL_SEQ_INITIATIVE; 2007fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 2008fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 2009fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 2010fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xffff; 2011fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xffff; 2012fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 2013fcf3ce44SJohn Forte 2014fcf3ce44SJohn Forte /* Build the command */ 2015291a2b48SSukumar Swaminathan /* Service paramters will be added automatically later by the driver */ 2016fcf3ce44SJohn Forte els = (ELS_PKT *)pkt->pkt_cmd; 2017fcf3ce44SJohn Forte els->elsCode = 0x04; /* FLOGI */ 2018fcf3ce44SJohn Forte 2019fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 2020fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 202182527734SSukumar Swaminathan "emlxs_fct_flogi_xchg: FLOGI failed. " 202282527734SSukumar Swaminathan "Unable to send packet."); 2023fcf3ce44SJohn Forte 202482527734SSukumar Swaminathan rval = FCT_FAILURE; 202582527734SSukumar Swaminathan goto done; 2026fcf3ce44SJohn Forte } 2027291a2b48SSukumar Swaminathan 2028fcf3ce44SJohn Forte if ((pkt->pkt_state != FC_PKT_SUCCESS) && 2029fcf3ce44SJohn Forte (pkt->pkt_state != FC_PKT_LS_RJT)) { 2030fcf3ce44SJohn Forte if (pkt->pkt_state == FC_PKT_TIMEOUT) { 203182527734SSukumar Swaminathan rval = FCT_TIMEOUT; 2032fcf3ce44SJohn Forte } else if ((pkt->pkt_state == FC_PKT_LOCAL_RJT) && 2033fcf3ce44SJohn Forte (pkt->pkt_reason == FC_REASON_FCAL_OPN_FAIL)) { 203482527734SSukumar Swaminathan rval = FCT_NOT_FOUND; 203582527734SSukumar Swaminathan } else { 203682527734SSukumar Swaminathan rval = FCT_FAILURE; 2037fcf3ce44SJohn Forte } 2038291a2b48SSukumar Swaminathan 2039fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 204082527734SSukumar Swaminathan "emlxs_fct_flogi_xchg: FLOGI failed. state=%x reason=%x", 2041fcf3ce44SJohn Forte pkt->pkt_state, pkt->pkt_reason); 2042fcf3ce44SJohn Forte 204382527734SSukumar Swaminathan goto done; 2044fcf3ce44SJohn Forte } 2045291a2b48SSukumar Swaminathan 2046fcf3ce44SJohn Forte if (pkt->pkt_state == FC_PKT_LS_RJT) { 2047fcf3ce44SJohn Forte fx->fx_op = ELS_OP_LSRJT; 2048fcf3ce44SJohn Forte fx->fx_rjt_reason = pkt->pkt_reason; 2049fcf3ce44SJohn Forte fx->fx_rjt_expl = pkt->pkt_expln; 2050fcf3ce44SJohn Forte } else { /* FC_PKT_SUCCESS */ 2051291a2b48SSukumar Swaminathan 2052fcf3ce44SJohn Forte fx->fx_op = ELS_OP_ACC; 205382527734SSukumar Swaminathan fx->fx_sid = FABRIC_DID; 2054fcf3ce44SJohn Forte fx->fx_did = port->did; 2055fcf3ce44SJohn Forte 2056291a2b48SSukumar Swaminathan els = (ELS_PKT *)pkt->pkt_resp; 2057fcf3ce44SJohn Forte bcopy((caddr_t)&els->un.logi.nodeName, 2058fcf3ce44SJohn Forte (caddr_t)fx->fx_nwwn, 8); 2059fcf3ce44SJohn Forte bcopy((caddr_t)&els->un.logi.portName, 2060fcf3ce44SJohn Forte (caddr_t)fx->fx_pwwn, 8); 2061fcf3ce44SJohn Forte fx->fx_fport = els->un.logi.cmn.fPort; 2062fcf3ce44SJohn Forte } 2063fcf3ce44SJohn Forte 206482527734SSukumar Swaminathan done: 206582527734SSukumar Swaminathan if (pkt) { 206682527734SSukumar Swaminathan emlxs_pkt_free(pkt); 206782527734SSukumar Swaminathan } 206882527734SSukumar Swaminathan 206982527734SSukumar Swaminathan return (rval); 2070fcf3ce44SJohn Forte 207182527734SSukumar Swaminathan } /* emlxs_fct_flogi_xchg() */ 2072fcf3ce44SJohn Forte 2073fcf3ce44SJohn Forte 207482527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 2075fcf3ce44SJohn Forte /* This is called right after we report that link has come online */ 2076fcf3ce44SJohn Forte static fct_status_t 2077fcf3ce44SJohn Forte emlxs_fct_get_link_info(fct_local_port_t *fct_port, fct_link_info_t *link) 2078fcf3ce44SJohn Forte { 2079fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 2080fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 2081fcf3ce44SJohn Forte 2082fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2083fcf3ce44SJohn Forte "emlxs_fct_get_link_info %p", fct_port); 2084fcf3ce44SJohn Forte 2085fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 2086fcf3ce44SJohn Forte 2087fcf3ce44SJohn Forte if (!(port->fct_flags & FCT_STATE_LINK_UP) || 2088291a2b48SSukumar Swaminathan (hba->state < FC_LINK_UP) || (hba->flag & FC_LOOPBACK_MODE)) { 2089fcf3ce44SJohn Forte link->port_topology = PORT_TOPOLOGY_UNKNOWN; 2090fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_UNKNOWN; 2091fcf3ce44SJohn Forte link->portid = 0; 2092fcf3ce44SJohn Forte 2093fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 2094fcf3ce44SJohn Forte 2095fcf3ce44SJohn Forte return (FCT_SUCCESS); 2096fcf3ce44SJohn Forte } 2097291a2b48SSukumar Swaminathan 2098fcf3ce44SJohn Forte if (hba->topology == TOPOLOGY_LOOP) { 2099fcf3ce44SJohn Forte link->port_topology = PORT_TOPOLOGY_PRIVATE_LOOP; 2100fcf3ce44SJohn Forte } else { 2101fcf3ce44SJohn Forte link->port_topology = PORT_TOPOLOGY_PT_TO_PT; 2102fcf3ce44SJohn Forte } 2103fcf3ce44SJohn Forte 2104fcf3ce44SJohn Forte switch (hba->linkspeed) { 2105fcf3ce44SJohn Forte case LA_1GHZ_LINK: 2106fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_1G; 2107fcf3ce44SJohn Forte break; 2108fcf3ce44SJohn Forte case LA_2GHZ_LINK: 2109fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_2G; 2110fcf3ce44SJohn Forte break; 2111fcf3ce44SJohn Forte case LA_4GHZ_LINK: 2112fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_4G; 2113fcf3ce44SJohn Forte break; 2114fcf3ce44SJohn Forte case LA_8GHZ_LINK: 2115fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_8G; 2116fcf3ce44SJohn Forte break; 2117fcf3ce44SJohn Forte case LA_10GHZ_LINK: 2118fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_10G; 2119fcf3ce44SJohn Forte break; 2120fcf3ce44SJohn Forte default: 2121fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_UNKNOWN; 2122fcf3ce44SJohn Forte break; 2123fcf3ce44SJohn Forte } 2124fcf3ce44SJohn Forte 2125fcf3ce44SJohn Forte link->portid = port->did; 2126fcf3ce44SJohn Forte link->port_no_fct_flogi = 0; 2127fcf3ce44SJohn Forte link->port_fca_flogi_done = 0; 2128fcf3ce44SJohn Forte link->port_fct_flogi_done = 0; 2129fcf3ce44SJohn Forte 2130fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 2131fcf3ce44SJohn Forte 2132fcf3ce44SJohn Forte return (FCT_SUCCESS); 2133fcf3ce44SJohn Forte 213482527734SSukumar Swaminathan } /* emlxs_fct_get_link_info() */ 2135fcf3ce44SJohn Forte 2136fcf3ce44SJohn Forte 213782527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 2138fcf3ce44SJohn Forte static fct_status_t 2139fcf3ce44SJohn Forte emlxs_fct_register_remote_port(fct_local_port_t *fct_port, 2140fcf3ce44SJohn Forte fct_remote_port_t *remote_port, fct_cmd_t *fct_cmd) 2141fcf3ce44SJohn Forte { 2142fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 2143fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 2144fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 2145fcf3ce44SJohn Forte clock_t timeout; 2146fcf3ce44SJohn Forte int32_t pkt_ret; 2147fcf3ce44SJohn Forte fct_els_t *els; 2148fcf3ce44SJohn Forte SERV_PARM *sp; 2149fcf3ce44SJohn Forte emlxs_node_t *ndlp; 2150fcf3ce44SJohn Forte SERV_PARM sparam; 2151fcf3ce44SJohn Forte uint32_t *iptr; 21523be114edSSukumar Swaminathan uint64_t addr; 215382527734SSukumar Swaminathan fct_status_t rval; 215482527734SSukumar Swaminathan fct_status_t rval2; 2155fcf3ce44SJohn Forte 2156fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2157fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2158fcf3ce44SJohn Forte "emlxs_fct_register_remote_port %p", fct_port); 2159291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2160fcf3ce44SJohn Forte 2161fcf3ce44SJohn Forte if (!(cmd_sbp->pkt_flags & PACKET_VALID)) { 216282527734SSukumar Swaminathan 216382527734SSukumar Swaminathan cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd, 216482527734SSukumar Swaminathan EMLXS_FCT_REG_PENDING); 2165291a2b48SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 2166fcf3ce44SJohn Forte 216782527734SSukumar Swaminathan cmd_sbp->channel = &hba->chan[hba->channel_els]; 2168fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_ELS_CMD; 216982527734SSukumar Swaminathan 2170fcf3ce44SJohn Forte } else { 2171fcf3ce44SJohn Forte 217282527734SSukumar Swaminathan rval = emlxs_fct_cmd_accept(port, fct_cmd, 217382527734SSukumar Swaminathan EMLXS_FCT_REG_PENDING); 217482527734SSukumar Swaminathan if (rval) { 217582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 217682527734SSukumar Swaminathan "emlxs_fct_register_remote_port: " 217782527734SSukumar Swaminathan "Unable to accept fct_cmd. did=%x", 217882527734SSukumar Swaminathan fct_cmd->cmd_rportid); 2179291a2b48SSukumar Swaminathan 218082527734SSukumar Swaminathan return (rval); 218182527734SSukumar Swaminathan } 218282527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 218382527734SSukumar Swaminathan } 2184fcf3ce44SJohn Forte 2185*a9800bebSGarrett D'Amore cmd_sbp->fct_flags &= ~EMLXS_FCT_REGISTERED; 2186*a9800bebSGarrett D'Amore 2187fcf3ce44SJohn Forte if (!cmd_sbp->node) { 2188291a2b48SSukumar Swaminathan cmd_sbp->node = 2189291a2b48SSukumar Swaminathan emlxs_node_find_did(port, fct_cmd->cmd_rportid); 2190fcf3ce44SJohn Forte } 2191291a2b48SSukumar Swaminathan 2192fcf3ce44SJohn Forte if (!cmd_sbp->node) { 2193fcf3ce44SJohn Forte els = (fct_els_t *)fct_cmd->cmd_specific; 2194fcf3ce44SJohn Forte 2195fcf3ce44SJohn Forte /* Check for unsolicited PLOGI */ 2196291a2b48SSukumar Swaminathan if (cmd_sbp->fct_flags & EMLXS_FCT_PLOGI_RECEIVED) { 2197291a2b48SSukumar Swaminathan sp = (SERV_PARM *)((caddr_t)els->els_req_payload + 2198291a2b48SSukumar Swaminathan sizeof (uint32_t)); 2199fcf3ce44SJohn Forte } else { /* Solicited PLOGI */ 2200291a2b48SSukumar Swaminathan 2201fcf3ce44SJohn Forte sp = &sparam; 2202fcf3ce44SJohn Forte bcopy((caddr_t)&port->sparam, (caddr_t)sp, 2203fcf3ce44SJohn Forte sizeof (SERV_PARM)); 2204fcf3ce44SJohn Forte 2205fcf3ce44SJohn Forte /* 2206291a2b48SSukumar Swaminathan * Create temporary WWN's from fct_cmd address 2207fcf3ce44SJohn Forte * This simply allows us to get an RPI from the 2208291a2b48SSukumar Swaminathan * adapter until we get real service params. 2209fcf3ce44SJohn Forte * The PLOGI ACC reply will trigger a REG_LOGIN 2210fcf3ce44SJohn Forte * update later 2211fcf3ce44SJohn Forte */ 22123be114edSSukumar Swaminathan addr = (uint64_t)((unsigned long)fct_cmd); 22133be114edSSukumar Swaminathan 2214fcf3ce44SJohn Forte iptr = (uint32_t *)&sp->portName; 221582527734SSukumar Swaminathan iptr[0] = PADDR_HI(addr); 221682527734SSukumar Swaminathan iptr[1] = PADDR_LO(addr); 2217291a2b48SSukumar Swaminathan 2218fcf3ce44SJohn Forte iptr = (uint32_t *)&sp->nodeName; 221982527734SSukumar Swaminathan iptr[0] = PADDR_HI(addr); 222082527734SSukumar Swaminathan iptr[1] = PADDR_LO(addr); 2221fcf3ce44SJohn Forte } 2222fcf3ce44SJohn Forte 2223fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 2224291a2b48SSukumar Swaminathan "emlxs_fct_register_remote_port: Register did=%x. (%x,%p)", 2225291a2b48SSukumar Swaminathan fct_cmd->cmd_rportid, cmd_sbp->fct_state, fct_cmd); 2226fcf3ce44SJohn Forte 222782527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, 0); 222882527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 222982527734SSukumar Swaminathan 2230fcf3ce44SJohn Forte /* Create a new node */ 2231fcf3ce44SJohn Forte if (emlxs_mb_reg_did(port, fct_cmd->cmd_rportid, sp, cmd_sbp, 2232fcf3ce44SJohn Forte NULL, NULL) != 0) { 2233fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 2234291a2b48SSukumar Swaminathan "emlxs_fct_register_remote_port: " 2235291a2b48SSukumar Swaminathan "Reg login failed. did=%x", 2236291a2b48SSukumar Swaminathan fct_cmd->cmd_rportid); 223782527734SSukumar Swaminathan } else { 2238fcf3ce44SJohn Forte 223982527734SSukumar Swaminathan /* Wait for completion */ 224082527734SSukumar Swaminathan mutex_enter(&EMLXS_PKT_LOCK); 224182527734SSukumar Swaminathan timeout = emlxs_timeout(hba, 30); 224282527734SSukumar Swaminathan pkt_ret = 0; 224382527734SSukumar Swaminathan while ((pkt_ret != -1) && 224482527734SSukumar Swaminathan (cmd_sbp->fct_state == EMLXS_FCT_REG_PENDING) && 2245*a9800bebSGarrett D'Amore !(cmd_sbp->fct_flags & EMLXS_FCT_REGISTERED)) { 224682527734SSukumar Swaminathan pkt_ret = cv_timedwait(&EMLXS_PKT_CV, 224782527734SSukumar Swaminathan &EMLXS_PKT_LOCK, timeout); 224882527734SSukumar Swaminathan } 224982527734SSukumar Swaminathan mutex_exit(&EMLXS_PKT_LOCK); 2250fcf3ce44SJohn Forte } 2251fcf3ce44SJohn Forte 225282527734SSukumar Swaminathan /* Reacquire ownership of the fct_cmd */ 225382527734SSukumar Swaminathan rval2 = emlxs_fct_cmd_acquire(port, fct_cmd, 225482527734SSukumar Swaminathan EMLXS_FCT_REG_COMPLETE); 225582527734SSukumar Swaminathan if (rval2) { 225682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 225782527734SSukumar Swaminathan "emlxs_fct_register_remote_port: " 225882527734SSukumar Swaminathan "Unable to reacquire fct_cmd. did=%x", 225982527734SSukumar Swaminathan fct_cmd->cmd_rportid); 226082527734SSukumar Swaminathan 226182527734SSukumar Swaminathan return (rval2); 2262291a2b48SSukumar Swaminathan } 226382527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 2264fcf3ce44SJohn Forte } 2265291a2b48SSukumar Swaminathan 2266fcf3ce44SJohn Forte done: 2267fcf3ce44SJohn Forte 2268fcf3ce44SJohn Forte ndlp = (emlxs_node_t *)cmd_sbp->node; 2269fcf3ce44SJohn Forte 2270fcf3ce44SJohn Forte if (ndlp) { 2271*a9800bebSGarrett D'Amore cmd_sbp->fct_flags |= EMLXS_FCT_REGISTERED; 2272*a9800bebSGarrett D'Amore 2273291a2b48SSukumar Swaminathan *((emlxs_node_t **)remote_port->rp_fca_private) = 2274291a2b48SSukumar Swaminathan cmd_sbp->node; 2275fcf3ce44SJohn Forte remote_port->rp_handle = ndlp->nlp_Rpi; 2276fcf3ce44SJohn Forte 2277fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2278fcf3ce44SJohn Forte "emlxs_fct_register_remote_port: did=%x hdl=%x", 2279fcf3ce44SJohn Forte fct_cmd->cmd_rportid, remote_port->rp_handle); 2280fcf3ce44SJohn Forte 2281fcf3ce44SJohn Forte remote_port->rp_handle = ndlp->nlp_Rpi; 2282fcf3ce44SJohn Forte 2283fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 228482527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2285291a2b48SSukumar Swaminathan 2286fcf3ce44SJohn Forte TGTPORTSTAT.FctPortRegister++; 2287fcf3ce44SJohn Forte return (FCT_SUCCESS); 2288fcf3ce44SJohn Forte } else { 2289fcf3ce44SJohn Forte *((emlxs_node_t **)remote_port->rp_fca_private) = NULL; 2290fcf3ce44SJohn Forte 2291fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2292fcf3ce44SJohn Forte "emlxs_fct_register_remote_port: failed. did=%x hdl=%x", 2293fcf3ce44SJohn Forte fct_cmd->cmd_rportid, remote_port->rp_handle); 2294fcf3ce44SJohn Forte 2295fcf3ce44SJohn Forte remote_port->rp_handle = FCT_HANDLE_NONE; 2296fcf3ce44SJohn Forte 2297fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 229882527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2299291a2b48SSukumar Swaminathan 2300fcf3ce44SJohn Forte TGTPORTSTAT.FctFailedPortRegister++; 2301fcf3ce44SJohn Forte return (FCT_FAILURE); 2302fcf3ce44SJohn Forte } 2303fcf3ce44SJohn Forte 230482527734SSukumar Swaminathan } /* emlxs_fct_register_remote_port() */ 2305fcf3ce44SJohn Forte 2306fcf3ce44SJohn Forte 230782527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 2308fcf3ce44SJohn Forte static fct_status_t 2309fcf3ce44SJohn Forte emlxs_fct_deregister_remote_port(fct_local_port_t *fct_port, 2310fcf3ce44SJohn Forte fct_remote_port_t *remote_port) 2311fcf3ce44SJohn Forte { 2312fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 2313*a9800bebSGarrett D'Amore emlxs_node_t *ndlp; 2314fcf3ce44SJohn Forte 2315fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2316fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2317fcf3ce44SJohn Forte "emlxs_fct_deregister_remote_port: did=%x hdl=%x", 2318fcf3ce44SJohn Forte remote_port->rp_id, remote_port->rp_handle); 2319fcf3ce44SJohn Forte #else 2320fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2321fcf3ce44SJohn Forte "emlxs_fct_deregister_remote_port: did=%x hdl=%x", 2322fcf3ce44SJohn Forte remote_port->rp_id, remote_port->rp_handle); 2323291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2324fcf3ce44SJohn Forte 2325*a9800bebSGarrett D'Amore ndlp = *((emlxs_node_t **)remote_port->rp_fca_private); 2326fcf3ce44SJohn Forte *((emlxs_node_t **)remote_port->rp_fca_private) = NULL; 2327*a9800bebSGarrett D'Amore 2328*a9800bebSGarrett D'Amore if (ndlp) { 2329*a9800bebSGarrett D'Amore (void) emlxs_mb_unreg_node(port, ndlp, NULL, 2330*a9800bebSGarrett D'Amore NULL, NULL); 2331*a9800bebSGarrett D'Amore } 2332fcf3ce44SJohn Forte 2333fcf3ce44SJohn Forte TGTPORTSTAT.FctPortDeregister++; 2334fcf3ce44SJohn Forte return (FCT_SUCCESS); 2335fcf3ce44SJohn Forte 233682527734SSukumar Swaminathan } /* emlxs_fct_deregister_remote_port() */ 2337fcf3ce44SJohn Forte 2338fcf3ce44SJohn Forte 2339fcf3ce44SJohn Forte /* ARGSUSED */ 2340fcf3ce44SJohn Forte extern int 234182527734SSukumar Swaminathan emlxs_fct_handle_unsol_req(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 2342fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 2343fcf3ce44SJohn Forte { 2344fcf3ce44SJohn Forte IOCB *iocb; 2345fcf3ce44SJohn Forte fct_cmd_t *fct_cmd; 2346fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 2347fcf3ce44SJohn Forte emlxs_fcp_cmd_t *fcp_cmd; 2348fcf3ce44SJohn Forte emlxs_node_t *ndlp; 2349fcf3ce44SJohn Forte uint32_t cnt; 2350fcf3ce44SJohn Forte uint32_t tm; 2351fcf3ce44SJohn Forte scsi_task_t *fct_task; 2352fcf3ce44SJohn Forte uint8_t lun[8]; 2353fcf3ce44SJohn Forte uint32_t sid = 0; 2354fcf3ce44SJohn Forte 2355fcf3ce44SJohn Forte iocb = &iocbq->iocb; 235682527734SSukumar Swaminathan ndlp = emlxs_node_find_rpi(port, iocb->ULPIOTAG); 2357fcf3ce44SJohn Forte if (!ndlp) { 2358fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2359fcf3ce44SJohn Forte "FCP rcvd: Unknown RPI. rpi=%x rxid=%x. Dropping...", 236082527734SSukumar Swaminathan iocb->ULPIOTAG, iocb->ULPCONTEXT); 2361fcf3ce44SJohn Forte 2362fcf3ce44SJohn Forte goto dropped; 2363fcf3ce44SJohn Forte } 2364fcf3ce44SJohn Forte sid = ndlp->nlp_DID; 2365fcf3ce44SJohn Forte 2366fcf3ce44SJohn Forte fcp_cmd = (emlxs_fcp_cmd_t *)mp->virt; 2367fcf3ce44SJohn Forte 2368fcf3ce44SJohn Forte if (!port->fct_port) { 2369fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2370fcf3ce44SJohn Forte "FCP rcvd: Target unbound. rpi=%x rxid=%x. Dropping...", 237182527734SSukumar Swaminathan iocb->ULPIOTAG, iocb->ULPCONTEXT); 2372fcf3ce44SJohn Forte 2373fcf3ce44SJohn Forte emlxs_send_logo(port, sid); 2374fcf3ce44SJohn Forte 2375fcf3ce44SJohn Forte goto dropped; 2376fcf3ce44SJohn Forte } 2377291a2b48SSukumar Swaminathan 2378fcf3ce44SJohn Forte if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) { 2379fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2380fcf3ce44SJohn Forte "FCP rcvd: Target offline. rpi=%x rxid=%x. Dropping...", 238182527734SSukumar Swaminathan iocb->ULPIOTAG, iocb->ULPCONTEXT); 2382fcf3ce44SJohn Forte 2383fcf3ce44SJohn Forte emlxs_send_logo(port, sid); 2384fcf3ce44SJohn Forte 2385fcf3ce44SJohn Forte goto dropped; 2386fcf3ce44SJohn Forte } 2387291a2b48SSukumar Swaminathan 2388fcf3ce44SJohn Forte /* Get lun id */ 2389fcf3ce44SJohn Forte bcopy((void *)&fcp_cmd->fcpLunMsl, lun, 8); 2390fcf3ce44SJohn Forte 2391fcf3ce44SJohn Forte if (TGTPORTSTAT.FctOutstandingIO >= port->fct_port->port_max_xchges) { 2392fcf3ce44SJohn Forte TGTPORTSTAT.FctOverQDepth++; 2393fcf3ce44SJohn Forte } 2394291a2b48SSukumar Swaminathan 2395291a2b48SSukumar Swaminathan fct_cmd = 239682527734SSukumar Swaminathan MODSYM(fct_scsi_task_alloc) (port->fct_port, iocb->ULPIOTAG, sid, 2397291a2b48SSukumar Swaminathan lun, 16, 0); 2398fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2399fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2400291a2b48SSukumar Swaminathan "fct_scsi_task_alloc %p: FCP rcvd: " 2401291a2b48SSukumar Swaminathan "cmd=%x sid=%x rxid=%x lun=%02x%02x dl=%d", 240282527734SSukumar Swaminathan fct_cmd, fcp_cmd->fcpCdb[0], sid, iocb->ULPCONTEXT, 240382527734SSukumar Swaminathan lun[0], lun[1], LE_SWAP32(fcp_cmd->fcpDl)); 2404291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2405fcf3ce44SJohn Forte 2406fcf3ce44SJohn Forte if (fct_cmd == NULL) { 2407fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2408291a2b48SSukumar Swaminathan "FCP rcvd: sid=%x xid=%x. " 2409291a2b48SSukumar Swaminathan "Unable to allocate scsi task. Returning QFULL.", 241082527734SSukumar Swaminathan sid, iocb->ULPCONTEXT); 2411fcf3ce44SJohn Forte 241282527734SSukumar Swaminathan (void) emlxs_fct_send_qfull_reply(port, ndlp, iocb->ULPCONTEXT, 241382527734SSukumar Swaminathan iocb->ULPCLASS, fcp_cmd); 2414fcf3ce44SJohn Forte 2415fcf3ce44SJohn Forte goto dropped; 2416fcf3ce44SJohn Forte } 2417291a2b48SSukumar Swaminathan 2418fcf3ce44SJohn Forte /* Initialize fct_cmd */ 2419fcf3ce44SJohn Forte fct_cmd->cmd_oxid = 0xFFFF; 242082527734SSukumar Swaminathan fct_cmd->cmd_rxid = iocb->ULPCONTEXT; 2421fcf3ce44SJohn Forte fct_cmd->cmd_rportid = sid; 2422fcf3ce44SJohn Forte fct_cmd->cmd_lportid = port->did; 242382527734SSukumar Swaminathan fct_cmd->cmd_rp_handle = iocb->ULPIOTAG; /* RPI */ 2424fcf3ce44SJohn Forte fct_cmd->cmd_port = port->fct_port; 2425fcf3ce44SJohn Forte 242682527734SSukumar Swaminathan cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd, EMLXS_FCT_FCP_CMD_RECEIVED); 242782527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 2428fcf3ce44SJohn Forte 2429291a2b48SSukumar Swaminathan /* Initialize cmd_sbp */ 243082527734SSukumar Swaminathan cmd_sbp->channel = cp; 243182527734SSukumar Swaminathan cmd_sbp->class = iocb->ULPCLASS; 2432fcf3ce44SJohn Forte cmd_sbp->lun = (lun[0] << 8) | lun[1]; 2433fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_FCP_CMD; 2434fcf3ce44SJohn Forte 2435fcf3ce44SJohn Forte fct_task = (scsi_task_t *)fct_cmd->cmd_specific; 2436fcf3ce44SJohn Forte 2437fcf3ce44SJohn Forte /* Set task_flags */ 2438291a2b48SSukumar Swaminathan switch (fcp_cmd->fcpCntl1) { 2439291a2b48SSukumar Swaminathan case SIMPLE_Q: 2440fcf3ce44SJohn Forte fct_task->task_flags = TF_ATTR_SIMPLE_QUEUE; 2441fcf3ce44SJohn Forte break; 2442fcf3ce44SJohn Forte 2443291a2b48SSukumar Swaminathan case HEAD_OF_Q: 2444fcf3ce44SJohn Forte fct_task->task_flags = TF_ATTR_HEAD_OF_QUEUE; 2445fcf3ce44SJohn Forte break; 2446fcf3ce44SJohn Forte 2447291a2b48SSukumar Swaminathan case ORDERED_Q: 2448fcf3ce44SJohn Forte fct_task->task_flags = TF_ATTR_ORDERED_QUEUE; 2449fcf3ce44SJohn Forte break; 2450fcf3ce44SJohn Forte 2451291a2b48SSukumar Swaminathan case ACA_Q: 2452fcf3ce44SJohn Forte fct_task->task_flags = TF_ATTR_ACA; 2453fcf3ce44SJohn Forte break; 2454fcf3ce44SJohn Forte 2455291a2b48SSukumar Swaminathan case UNTAGGED: 2456fcf3ce44SJohn Forte fct_task->task_flags = TF_ATTR_UNTAGGED; 2457fcf3ce44SJohn Forte break; 2458fcf3ce44SJohn Forte } 2459fcf3ce44SJohn Forte 246082527734SSukumar Swaminathan cnt = LE_SWAP32(fcp_cmd->fcpDl); 2461fcf3ce44SJohn Forte switch (fcp_cmd->fcpCntl3) { 2462fcf3ce44SJohn Forte case 0: 2463fcf3ce44SJohn Forte TGTPORTSTAT.FctIOCmdCnt++; 2464fcf3ce44SJohn Forte break; 2465fcf3ce44SJohn Forte case 1: 246682527734SSukumar Swaminathan EMLXS_BUMP_WRIOCTR(port, cnt); 2467fcf3ce44SJohn Forte TGTPORTSTAT.FctWriteBytes += cnt; 2468fcf3ce44SJohn Forte fct_task->task_flags |= TF_WRITE_DATA; 2469fcf3ce44SJohn Forte break; 2470fcf3ce44SJohn Forte 2471fcf3ce44SJohn Forte case 2: 247282527734SSukumar Swaminathan EMLXS_BUMP_RDIOCTR(port, cnt); 2473fcf3ce44SJohn Forte TGTPORTSTAT.FctReadBytes += cnt; 2474fcf3ce44SJohn Forte fct_task->task_flags |= TF_READ_DATA; 2475fcf3ce44SJohn Forte break; 2476fcf3ce44SJohn Forte } 2477fcf3ce44SJohn Forte 2478fcf3ce44SJohn Forte fct_task->task_priority = 0; 2479fcf3ce44SJohn Forte 2480fcf3ce44SJohn Forte /* task_mgmt_function */ 2481fcf3ce44SJohn Forte tm = fcp_cmd->fcpCntl2; 2482fcf3ce44SJohn Forte if (tm) { 2483fcf3ce44SJohn Forte if (tm & BIT_1) { 2484fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_ABORT_TASK_SET; 2485fcf3ce44SJohn Forte } else if (tm & BIT_2) { 2486fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_CLEAR_TASK_SET; 2487fcf3ce44SJohn Forte } else if (tm & BIT_4) { 2488fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_LUN_RESET; 2489fcf3ce44SJohn Forte } else if (tm & BIT_5) { 2490fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_TARGET_COLD_RESET; 2491fcf3ce44SJohn Forte } else if (tm & BIT_6) { 2492fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_CLEAR_ACA; 2493fcf3ce44SJohn Forte } else { 2494fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_ABORT_TASK; 2495fcf3ce44SJohn Forte } 2496fcf3ce44SJohn Forte } 2497291a2b48SSukumar Swaminathan 2498fcf3ce44SJohn Forte /* Parallel buffers support - future */ 2499fcf3ce44SJohn Forte fct_task->task_max_nbufs = 1; 2500fcf3ce44SJohn Forte 2501fcf3ce44SJohn Forte fct_task->task_additional_flags = 0; 2502fcf3ce44SJohn Forte fct_task->task_cur_nbufs = 0; 2503fcf3ce44SJohn Forte fct_task->task_csn_size = 8; 2504fcf3ce44SJohn Forte fct_task->task_cmd_seq_no = 0; 2505fcf3ce44SJohn Forte fct_task->task_expected_xfer_length = cnt; 2506fcf3ce44SJohn Forte bcopy((void *)&fcp_cmd->fcpCdb, fct_task->task_cdb, 16); 2507fcf3ce44SJohn Forte 2508fcf3ce44SJohn Forte TGTPORTSTAT.FctCmdReceived++; 2509fcf3ce44SJohn Forte TGTPORTSTAT.FctOutstandingIO++; 2510fcf3ce44SJohn Forte 251182527734SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 251282527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2513fcf3ce44SJohn Forte 2514291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE 2515291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 251682527734SSukumar Swaminathan "fct_post_rcvd_cmd:3 %p: portid x%x, %d", fct_cmd, 251782527734SSukumar Swaminathan fct_cmd->cmd_lportid, fct_task->task_expected_xfer_length); 2518291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 251982527734SSukumar Swaminathan 2520291a2b48SSukumar Swaminathan MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0); 2521fcf3ce44SJohn Forte 2522fcf3ce44SJohn Forte return (0); 2523fcf3ce44SJohn Forte 2524fcf3ce44SJohn Forte dropped: 2525fcf3ce44SJohn Forte 2526fcf3ce44SJohn Forte TGTPORTSTAT.FctRcvDropped++; 2527fcf3ce44SJohn Forte return (1); 2528fcf3ce44SJohn Forte 252982527734SSukumar Swaminathan } /* emlxs_fct_handle_unsol_req() */ 2530fcf3ce44SJohn Forte 2531fcf3ce44SJohn Forte 253282527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 2533fcf3ce44SJohn Forte /* ARGSUSED */ 2534fcf3ce44SJohn Forte static fct_status_t 2535fcf3ce44SJohn Forte emlxs_fct_send_fcp_data(fct_cmd_t *fct_cmd, stmf_data_buf_t *dbuf, 2536fcf3ce44SJohn Forte uint32_t ioflags) 2537fcf3ce44SJohn Forte { 2538fcf3ce44SJohn Forte emlxs_port_t *port = 2539fcf3ce44SJohn Forte (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 2540fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 2541fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 2542291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE 2543fcf3ce44SJohn Forte scsi_task_t *fct_task; 2544291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2545fcf3ce44SJohn Forte IOCBQ *iocbq; 2546fcf3ce44SJohn Forte emlxs_node_t *ndlp; 2547fcf3ce44SJohn Forte 254882527734SSukumar Swaminathan int channel; 254982527734SSukumar Swaminathan int channelno; 2550b3660a96SSukumar Swaminathan fct_status_t rval = 0; 2551fcf3ce44SJohn Forte 255282527734SSukumar Swaminathan rval = emlxs_fct_cmd_accept(port, fct_cmd, EMLXS_FCT_SEND_FCP_DATA); 255382527734SSukumar Swaminathan if (rval) { 255482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 255582527734SSukumar Swaminathan "emlxs_fct_send_fcp_data: " 255682527734SSukumar Swaminathan "Unable to accept fct_cmd. did=%x", 255782527734SSukumar Swaminathan fct_cmd->cmd_rportid); 2558fcf3ce44SJohn Forte 255982527734SSukumar Swaminathan return (rval); 2560fcf3ce44SJohn Forte } 256182527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 2562291a2b48SSukumar Swaminathan 256382527734SSukumar Swaminathan cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 256482527734SSukumar Swaminathan #ifdef FCT_API_TRACE 256582527734SSukumar Swaminathan fct_task = (scsi_task_t *)fct_cmd->cmd_specific; 256682527734SSukumar Swaminathan #endif /* FCT_API_TRACE */ 256782527734SSukumar Swaminathan ndlp = *(emlxs_node_t **)fct_cmd->cmd_rp->rp_fca_private; 2568291a2b48SSukumar Swaminathan 2569fcf3ce44SJohn Forte cmd_sbp->node = ndlp; 2570fcf3ce44SJohn Forte cmd_sbp->fct_buf = dbuf; 2571fcf3ce44SJohn Forte 257282527734SSukumar Swaminathan channelno = ((CHANNEL *)cmd_sbp->channel)->channelno; 257382527734SSukumar Swaminathan 257482527734SSukumar Swaminathan channel = channelno; 257582527734SSukumar Swaminathan 257682527734SSukumar Swaminathan 257782527734SSukumar Swaminathan 2578fcf3ce44SJohn Forte iocbq = &cmd_sbp->iocbq; 2579fcf3ce44SJohn Forte 2580fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2581fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 258282527734SSukumar Swaminathan "emlxs_fct_send_fcp_data %p: flgs=%x ioflags=%x dl=%d,%d,%d, %d", 2583fcf3ce44SJohn Forte fct_cmd, dbuf->db_flags, ioflags, fct_task->task_cmd_xfer_length, 258482527734SSukumar Swaminathan fct_task->task_nbytes_transferred, dbuf->db_data_size, 258582527734SSukumar Swaminathan fct_task->task_expected_xfer_length); 2586291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2587fcf3ce44SJohn Forte 258882527734SSukumar Swaminathan if (EMLXS_SLI_PREP_FCT_IOCB(port, cmd_sbp, channel) != IOERR_SUCCESS) { 258982527734SSukumar Swaminathan 2590fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 259182527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2592fcf3ce44SJohn Forte 2593fcf3ce44SJohn Forte return (FCT_BUSY); 2594fcf3ce44SJohn Forte } 2595291a2b48SSukumar Swaminathan 2596fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_FCP_DATA; 2597fcf3ce44SJohn Forte 2598fcf3ce44SJohn Forte if (dbuf->db_flags & DB_SEND_STATUS_GOOD) { 2599fcf3ce44SJohn Forte cmd_sbp->fct_flags |= EMLXS_FCT_SEND_STATUS; 2600fcf3ce44SJohn Forte } 2601fcf3ce44SJohn Forte 2602fcf3ce44SJohn Forte if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) { 2603b3660a96SSukumar Swaminathan if (emlxs_fct_dbuf_dma_sync(hba, dbuf, DDI_DMA_SYNC_FORDEV)) { 2604b3660a96SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 2605b3660a96SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2606b3660a96SSukumar Swaminathan 2607b3660a96SSukumar Swaminathan return (FCT_BUSY); 2608b3660a96SSukumar Swaminathan } 2609fcf3ce44SJohn Forte } 2610291a2b48SSukumar Swaminathan 2611291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP; 261282527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, EMLXS_FCT_DATA_PENDING); 261382527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 261482527734SSukumar Swaminathan 261582527734SSukumar Swaminathan EMLXS_SLI_ISSUE_IOCB_CMD(hba, cmd_sbp->channel, iocbq); 2616fcf3ce44SJohn Forte 2617fcf3ce44SJohn Forte return (FCT_SUCCESS); 2618fcf3ce44SJohn Forte 261982527734SSukumar Swaminathan } /* emlxs_fct_send_fcp_data() */ 2620fcf3ce44SJohn Forte 2621fcf3ce44SJohn Forte 262282527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be held to enter */ 262382527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be released before exiting */ 2624fcf3ce44SJohn Forte static fct_status_t 2625fcf3ce44SJohn Forte emlxs_fct_send_fcp_status(fct_cmd_t *fct_cmd) 2626fcf3ce44SJohn Forte { 2627fcf3ce44SJohn Forte emlxs_port_t *port = 2628fcf3ce44SJohn Forte (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 2629fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 2630fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 2631fcf3ce44SJohn Forte scsi_task_t *fct_task; 2632fcf3ce44SJohn Forte fc_packet_t *pkt; 2633fcf3ce44SJohn Forte uint32_t did; 2634fcf3ce44SJohn Forte emlxs_fcp_rsp *fcp_rsp; 2635fcf3ce44SJohn Forte uint32_t size; 2636fcf3ce44SJohn Forte emlxs_node_t *ndlp; 263782527734SSukumar Swaminathan fct_status_t rval; 2638fcf3ce44SJohn Forte 2639fcf3ce44SJohn Forte fct_task = (scsi_task_t *)fct_cmd->cmd_specific; 2640fcf3ce44SJohn Forte ndlp = *(emlxs_node_t **)fct_cmd->cmd_rp->rp_fca_private; 2641fcf3ce44SJohn Forte did = fct_cmd->cmd_rportid; 2642fcf3ce44SJohn Forte 2643fcf3ce44SJohn Forte /* Initialize cmd_sbp */ 2644fcf3ce44SJohn Forte cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 2645fcf3ce44SJohn Forte 264682527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, EMLXS_FCT_SEND_FCP_STATUS); 2647291a2b48SSukumar Swaminathan 2648fcf3ce44SJohn Forte cmd_sbp->node = ndlp; 2649fcf3ce44SJohn Forte 2650fcf3ce44SJohn Forte size = 24; 2651fcf3ce44SJohn Forte if (fct_task->task_sense_length) { 2652fcf3ce44SJohn Forte size += fct_task->task_sense_length; 2653fcf3ce44SJohn Forte } 2654fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2655fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2656fcf3ce44SJohn Forte "emlxs_fct_send_fcp_status %p: stat=%d resid=%d size=%d rx=%x", 2657fcf3ce44SJohn Forte fct_cmd, fct_task->task_scsi_status, 2658fcf3ce44SJohn Forte fct_task->task_resid, size, fct_cmd->cmd_rxid); 2659291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2660fcf3ce44SJohn Forte 2661fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, size, 0, 0, KM_NOSLEEP))) { 2662fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 2663fcf3ce44SJohn Forte "emlxs_fct_send_fcp_status: Unable to allocate packet."); 2664fcf3ce44SJohn Forte 2665fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 266682527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2667fcf3ce44SJohn Forte 2668291a2b48SSukumar Swaminathan return (FCT_BUSY); 2669fcf3ce44SJohn Forte } 2670291a2b48SSukumar Swaminathan 2671fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_FCP_STATUS; 2672fcf3ce44SJohn Forte 2673fcf3ce44SJohn Forte (void) emlxs_fct_pkt_init(port, fct_cmd, pkt); 2674291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = pkt; 2675fcf3ce44SJohn Forte 2676fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND; 2677fcf3ce44SJohn Forte pkt->pkt_timeout = 2678fcf3ce44SJohn Forte ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov); 2679fcf3ce44SJohn Forte pkt->pkt_comp = emlxs_fct_pkt_comp; 2680fcf3ce44SJohn Forte 2681fcf3ce44SJohn Forte /* Build the fc header */ 268282527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(did); 2683fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_STATUS; 268482527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did); 2685fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_SCSI_FCP; 2686fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = 2687fcf3ce44SJohn Forte F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ; 2688fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 2689fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 2690fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 2691fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = fct_cmd->cmd_oxid; 2692fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = fct_cmd->cmd_rxid; 2693fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 2694fcf3ce44SJohn Forte 2695fcf3ce44SJohn Forte /* Build the status payload */ 2696fcf3ce44SJohn Forte fcp_rsp = (emlxs_fcp_rsp *)pkt->pkt_cmd; 2697fcf3ce44SJohn Forte 2698fcf3ce44SJohn Forte if (fct_task->task_resid) { 2699fcf3ce44SJohn Forte if (fct_task->task_status_ctrl & TASK_SCTRL_OVER) { 2700fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiResidOver++; 2701fcf3ce44SJohn Forte fcp_rsp->rspStatus2 |= RESID_OVER; 270282527734SSukumar Swaminathan fcp_rsp->rspResId = LE_SWAP32(fct_task->task_resid); 2703fcf3ce44SJohn Forte 2704fcf3ce44SJohn Forte } else if (fct_task->task_status_ctrl & TASK_SCTRL_UNDER) { 2705fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiResidUnder++; 2706fcf3ce44SJohn Forte fcp_rsp->rspStatus2 |= RESID_UNDER; 270782527734SSukumar Swaminathan fcp_rsp->rspResId = LE_SWAP32(fct_task->task_resid); 2708fcf3ce44SJohn Forte 2709fcf3ce44SJohn Forte } 2710fcf3ce44SJohn Forte } 2711291a2b48SSukumar Swaminathan 2712fcf3ce44SJohn Forte if (fct_task->task_scsi_status) { 2713fcf3ce44SJohn Forte if (fct_task->task_scsi_status == SCSI_STAT_QUE_FULL) { 2714fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiQfullErr++; 2715fcf3ce44SJohn Forte } else { 2716fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiStatusErr++; 2717fcf3ce44SJohn Forte } 2718fcf3ce44SJohn Forte 2719291a2b48SSukumar Swaminathan /* Make sure residual reported on non-SCSI_GOOD READ status */ 2720fcf3ce44SJohn Forte if ((fct_task->task_flags & TF_READ_DATA) && 2721fcf3ce44SJohn Forte (fcp_rsp->rspResId == 0)) { 2722fcf3ce44SJohn Forte fcp_rsp->rspStatus2 |= RESID_UNDER; 2723291a2b48SSukumar Swaminathan fcp_rsp->rspResId = 2724291a2b48SSukumar Swaminathan fct_task->task_expected_xfer_length; 2725fcf3ce44SJohn Forte } 2726fcf3ce44SJohn Forte } 2727291a2b48SSukumar Swaminathan 2728291a2b48SSukumar Swaminathan 2729fcf3ce44SJohn Forte if (fct_task->task_sense_length) { 2730fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiSenseErr++; 2731fcf3ce44SJohn Forte fcp_rsp->rspStatus2 |= SNS_LEN_VALID; 273282527734SSukumar Swaminathan fcp_rsp->rspSnsLen = LE_SWAP32(fct_task->task_sense_length); 2733fcf3ce44SJohn Forte 2734fcf3ce44SJohn Forte bcopy((uint8_t *)fct_task->task_sense_data, 2735291a2b48SSukumar Swaminathan (uint8_t *)&fcp_rsp->rspInfo0, 2736291a2b48SSukumar Swaminathan fct_task->task_sense_length); 2737fcf3ce44SJohn Forte } 2738291a2b48SSukumar Swaminathan 2739fcf3ce44SJohn Forte fcp_rsp->rspStatus3 = fct_task->task_scsi_status; 2740fcf3ce44SJohn Forte fcp_rsp->rspRspLen = 0; 274182527734SSukumar Swaminathan 2742291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP; 274382527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, EMLXS_FCT_STATUS_PENDING); 274482527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2745fcf3ce44SJohn Forte 2746fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 274782527734SSukumar Swaminathan 2748fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 2749fcf3ce44SJohn Forte "emlxs_fct_send_fcp_status: Unable to send packet."); 2750fcf3ce44SJohn Forte 275182527734SSukumar Swaminathan /* Reacquire ownership of the fct_cmd */ 275282527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, 0); 275382527734SSukumar Swaminathan if (rval) { 275482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 275582527734SSukumar Swaminathan "emlxs_fct_send_fcp_status: " 275682527734SSukumar Swaminathan "Unable to acquire fct_cmd."); 275782527734SSukumar Swaminathan return (rval); 2758fcf3ce44SJohn Forte } 275982527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 2760291a2b48SSukumar Swaminathan 2761fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 276282527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2763291a2b48SSukumar Swaminathan 2764291a2b48SSukumar Swaminathan return (FCT_BUSY); 2765fcf3ce44SJohn Forte } 2766291a2b48SSukumar Swaminathan 2767fcf3ce44SJohn Forte return (FCT_SUCCESS); 2768fcf3ce44SJohn Forte 276982527734SSukumar Swaminathan } /* emlxs_fct_send_fcp_status() */ 2770fcf3ce44SJohn Forte 2771fcf3ce44SJohn Forte 2772fcf3ce44SJohn Forte static fct_status_t 2773291a2b48SSukumar Swaminathan emlxs_fct_send_qfull_reply(emlxs_port_t *port, emlxs_node_t *ndlp, 2774291a2b48SSukumar Swaminathan uint16_t xid, uint32_t class, emlxs_fcp_cmd_t *fcp_cmd) 2775fcf3ce44SJohn Forte { 2776fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 2777fcf3ce44SJohn Forte emlxs_buf_t *sbp; 2778fcf3ce44SJohn Forte fc_packet_t *pkt; 2779fcf3ce44SJohn Forte emlxs_fcp_rsp *fcp_rsp; 2780fcf3ce44SJohn Forte uint32_t size; 278182527734SSukumar Swaminathan CHANNEL *cp = &hba->chan[hba->CHANNEL_FCT]; 2782fcf3ce44SJohn Forte uint8_t lun[8]; 2783fcf3ce44SJohn Forte 2784fcf3ce44SJohn Forte bcopy((void *)&fcp_cmd->fcpLunMsl, lun, 8); 2785fcf3ce44SJohn Forte size = 24; 2786fcf3ce44SJohn Forte 2787fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, size, 0, 0, KM_NOSLEEP))) { 2788fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 2789fcf3ce44SJohn Forte "emlxs_fct_send_qfull_reply: Unable to allocate packet."); 2790fcf3ce44SJohn Forte return (FCT_FAILURE); 2791fcf3ce44SJohn Forte } 2792291a2b48SSukumar Swaminathan 2793291a2b48SSukumar Swaminathan 2794fcf3ce44SJohn Forte sbp = PKT2PRIV(pkt); 2795fcf3ce44SJohn Forte sbp->node = ndlp; 279682527734SSukumar Swaminathan sbp->channel = cp; 2797fcf3ce44SJohn Forte sbp->did = ndlp->nlp_DID; 2798fcf3ce44SJohn Forte sbp->lun = (lun[0] << 8) | lun[1]; 2799fcf3ce44SJohn Forte sbp->class = class; 2800fcf3ce44SJohn Forte 2801fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND; 2802fcf3ce44SJohn Forte pkt->pkt_timeout = 2803fcf3ce44SJohn Forte ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov); 2804fcf3ce44SJohn Forte 2805fcf3ce44SJohn Forte /* Build the fc header */ 280682527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(ndlp->nlp_DID); 2807fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_STATUS; 280882527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did); 2809fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_SCSI_FCP; 2810fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = 2811fcf3ce44SJohn Forte F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ; 2812fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 2813fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 2814fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 2815fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xFFFF; 2816fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = xid; 2817fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 2818fcf3ce44SJohn Forte 2819fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 2820fcf3ce44SJohn Forte "emlxs_fct_send_qfull_reply: Sending QFULL: x%x lun x%x: %d %d", 2821fcf3ce44SJohn Forte xid, sbp->lun, TGTPORTSTAT.FctOutstandingIO, 2822fcf3ce44SJohn Forte port->fct_port->port_max_xchges); 2823fcf3ce44SJohn Forte 2824fcf3ce44SJohn Forte /* Build the status payload */ 2825fcf3ce44SJohn Forte fcp_rsp = (emlxs_fcp_rsp *)pkt->pkt_cmd; 2826fcf3ce44SJohn Forte 2827fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiQfullErr++; 2828fcf3ce44SJohn Forte fcp_rsp->rspStatus3 = SCSI_STAT_QUE_FULL; 2829fcf3ce44SJohn Forte fcp_rsp->rspStatus2 |= RESID_UNDER; 283082527734SSukumar Swaminathan fcp_rsp->rspResId = LE_SWAP32(fcp_cmd->fcpDl); 2831fcf3ce44SJohn Forte 2832fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 2833fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 2834fcf3ce44SJohn Forte "emlxs_fct_send_qfull_reply: Unable to send packet."); 2835fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 2836fcf3ce44SJohn Forte return (FCT_FAILURE); 2837fcf3ce44SJohn Forte } 2838fcf3ce44SJohn Forte 2839291a2b48SSukumar Swaminathan return (FCT_SUCCESS); 2840fcf3ce44SJohn Forte 284182527734SSukumar Swaminathan } /* emlxs_fct_send_qfull_reply() */ 2842fcf3ce44SJohn Forte 2843fcf3ce44SJohn Forte 2844fcf3ce44SJohn Forte /* ARGSUSED */ 2845fcf3ce44SJohn Forte extern int 284682527734SSukumar Swaminathan emlxs_fct_handle_fcp_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq) 2847fcf3ce44SJohn Forte { 2848fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2849fcf3ce44SJohn Forte IOCB *iocb; 2850fcf3ce44SJohn Forte emlxs_buf_t *sbp; 2851fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 2852fcf3ce44SJohn Forte uint32_t status; 2853fcf3ce44SJohn Forte fct_cmd_t *fct_cmd; 2854fcf3ce44SJohn Forte stmf_data_buf_t *dbuf; 2855fcf3ce44SJohn Forte scsi_task_t *fct_task; 2856291a2b48SSukumar Swaminathan fc_packet_t *pkt; 285782527734SSukumar Swaminathan uint32_t fct_flags; 285882527734SSukumar Swaminathan stmf_data_buf_t *fct_buf; 285982527734SSukumar Swaminathan fct_status_t rval; 2860fcf3ce44SJohn Forte 2861fcf3ce44SJohn Forte iocb = &iocbq->iocb; 2862fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)iocbq->sbp; 2863fcf3ce44SJohn Forte 2864fcf3ce44SJohn Forte TGTPORTSTAT.FctEvent++; 2865fcf3ce44SJohn Forte 2866fcf3ce44SJohn Forte if (!sbp) { 2867fcf3ce44SJohn Forte /* completion with missing xmit command */ 2868fcf3ce44SJohn Forte TGTPORTSTAT.FctStray++; 2869fcf3ce44SJohn Forte 2870fcf3ce44SJohn Forte /* emlxs_stray_fcp_completion_msg */ 2871fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2872291a2b48SSukumar Swaminathan "FCP event cmd=%x status=%x error=%x iotag=%x", 287382527734SSukumar Swaminathan iocb->ULPCOMMAND, iocb->ULPSTATUS, 287482527734SSukumar Swaminathan iocb->un.grsp.perr.statLocalError, iocb->ULPIOTAG); 2875fcf3ce44SJohn Forte 2876fcf3ce44SJohn Forte return (1); 2877fcf3ce44SJohn Forte } 2878291a2b48SSukumar Swaminathan 2879fcf3ce44SJohn Forte TGTPORTSTAT.FctCompleted++; 2880fcf3ce44SJohn Forte 2881fcf3ce44SJohn Forte port = sbp->iocbq.port; 2882fcf3ce44SJohn Forte fct_cmd = sbp->fct_cmd; 288382527734SSukumar Swaminathan status = iocb->ULPSTATUS; 2884fcf3ce44SJohn Forte 2885fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2886fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 288782527734SSukumar Swaminathan "emlxs_fct_handle_fcp_event: %p: cmd=%x status=%x, %x", 288882527734SSukumar Swaminathan fct_cmd, iocb->ULPCOMMAND, status, iocb->ULPCT); 2889291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2890fcf3ce44SJohn Forte 2891fcf3ce44SJohn Forte if (fct_cmd == NULL) { 2892291a2b48SSukumar Swaminathan /* For driver generated QFULL response */ 289382527734SSukumar Swaminathan if (((iocb->ULPCOMMAND == CMD_FCP_TRSP_CX) || 289482527734SSukumar Swaminathan (iocb->ULPCOMMAND == CMD_FCP_TRSP64_CX)) && sbp->pkt) { 2895fcf3ce44SJohn Forte emlxs_pkt_free(sbp->pkt); 2896fcf3ce44SJohn Forte } 2897fcf3ce44SJohn Forte return (0); 2898fcf3ce44SJohn Forte } 2899291a2b48SSukumar Swaminathan 290082527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, EMLXS_FCT_REQ_COMPLETE); 290182527734SSukumar Swaminathan if (rval) { 290282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 290382527734SSukumar Swaminathan "emlxs_fct_handle_fcp_event: " 290482527734SSukumar Swaminathan "Unable to reacquire fct_cmd. type=%x", 290582527734SSukumar Swaminathan fct_cmd->cmd_type); 290682527734SSukumar Swaminathan 290782527734SSukumar Swaminathan return (1); 2908291a2b48SSukumar Swaminathan } 290982527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 2910291a2b48SSukumar Swaminathan 2911fcf3ce44SJohn Forte cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 291282527734SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP; 2913291a2b48SSukumar Swaminathan 2914291a2b48SSukumar Swaminathan pkt = cmd_sbp->fct_pkt; 291582527734SSukumar Swaminathan cmd_sbp->fct_pkt = NULL; 2916fcf3ce44SJohn Forte 291782527734SSukumar Swaminathan dbuf = sbp->fct_buf; 2918fcf3ce44SJohn Forte 2919291a2b48SSukumar Swaminathan fct_cmd->cmd_comp_status = FCT_SUCCESS; 2920291a2b48SSukumar Swaminathan 2921291a2b48SSukumar Swaminathan if (status) { 2922b3660a96SSukumar Swaminathan emlxs_dma_error: 2923fcf3ce44SJohn Forte /* 2924291a2b48SSukumar Swaminathan * The error indicates this IO should be terminated 2925291a2b48SSukumar Swaminathan * immediately. 2926fcf3ce44SJohn Forte */ 2927291a2b48SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_SEND_STATUS; 292882527734SSukumar Swaminathan fct_cmd->cmd_comp_status = FCT_FAILURE; 2929291a2b48SSukumar Swaminathan 293082527734SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED); 293182527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2932291a2b48SSukumar Swaminathan 2933291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE 2934291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2935291a2b48SSukumar Swaminathan "fct_queue_cmd_for_termination:1 %p: x%x", 2936291a2b48SSukumar Swaminathan fct_cmd, fct_cmd->cmd_comp_status); 2937291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 293882527734SSukumar Swaminathan 2939291a2b48SSukumar Swaminathan MODSYM(fct_queue_cmd_for_termination) (fct_cmd, 2940291a2b48SSukumar Swaminathan FCT_ABTS_RECEIVED); 294182527734SSukumar Swaminathan 2942291a2b48SSukumar Swaminathan goto done; 2943291a2b48SSukumar Swaminathan } 2944291a2b48SSukumar Swaminathan 294582527734SSukumar Swaminathan switch (iocb->ULPCOMMAND) { 2946291a2b48SSukumar Swaminathan 2947291a2b48SSukumar Swaminathan /* 2948291a2b48SSukumar Swaminathan * FCP Data completion 2949291a2b48SSukumar Swaminathan */ 2950fcf3ce44SJohn Forte case CMD_FCP_TSEND_CX: 2951fcf3ce44SJohn Forte case CMD_FCP_TSEND64_CX: 2952fcf3ce44SJohn Forte case CMD_FCP_TRECEIVE_CX: 2953fcf3ce44SJohn Forte case CMD_FCP_TRECEIVE64_CX: 2954fcf3ce44SJohn Forte 295582527734SSukumar Swaminathan if (dbuf->db_flags & DB_DIRECTION_FROM_RPORT) { 2956b3660a96SSukumar Swaminathan if (emlxs_fct_dbuf_dma_sync(hba, dbuf, 2957b3660a96SSukumar Swaminathan DDI_DMA_SYNC_FORCPU)) { 2958b3660a96SSukumar Swaminathan goto emlxs_dma_error; 2959b3660a96SSukumar Swaminathan } 296082527734SSukumar Swaminathan } 2961fcf3ce44SJohn Forte 296282527734SSukumar Swaminathan if ((cmd_sbp->fct_flags & EMLXS_FCT_SEND_STATUS) && 296382527734SSukumar Swaminathan (iocb->ULPCT != 1)) { 2964291a2b48SSukumar Swaminathan 296582527734SSukumar Swaminathan dbuf->db_flags |= DB_STATUS_GOOD_SENT; 2966fcf3ce44SJohn Forte 296782527734SSukumar Swaminathan fct_task = 296882527734SSukumar Swaminathan (scsi_task_t *)fct_cmd->cmd_specific; 296982527734SSukumar Swaminathan fct_task->task_scsi_status = 0; 2970fcf3ce44SJohn Forte 297182527734SSukumar Swaminathan (void) emlxs_fct_send_fcp_status(fct_cmd); 297282527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2973fcf3ce44SJohn Forte 297482527734SSukumar Swaminathan break; 297582527734SSukumar Swaminathan 297682527734SSukumar Swaminathan } else if ((cmd_sbp->fct_flags & 297782527734SSukumar Swaminathan EMLXS_FCT_SEND_STATUS) && 297882527734SSukumar Swaminathan (iocb->ULPCT == 1)) { 297982527734SSukumar Swaminathan /* Auto-resp has been sent out by firmware */ 298082527734SSukumar Swaminathan /* We can assume this is really a FC_TRSP_CX */ 298182527734SSukumar Swaminathan 298282527734SSukumar Swaminathan dbuf->db_flags |= DB_STATUS_GOOD_SENT; 298382527734SSukumar Swaminathan fct_task = 298482527734SSukumar Swaminathan (scsi_task_t *)fct_cmd->cmd_specific; 298582527734SSukumar Swaminathan fct_task->task_scsi_status = 0; 298682527734SSukumar Swaminathan 298782527734SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_SEND_STATUS; 298882527734SSukumar Swaminathan 298982527734SSukumar Swaminathan goto auto_resp; 2990fcf3ce44SJohn Forte } 2991291a2b48SSukumar Swaminathan 2992fcf3ce44SJohn Forte cmd_sbp->fct_flags &= ~EMLXS_FCT_SEND_STATUS; 2993fcf3ce44SJohn Forte 2994fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 299582527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 299682527734SSukumar Swaminathan 2997fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2998fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2999fcf3ce44SJohn Forte "fct_scsi_data_xfer_done:1 %p %p", fct_cmd, dbuf); 3000291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 300182527734SSukumar Swaminathan 3002fcf3ce44SJohn Forte MODSYM(fct_scsi_data_xfer_done) (fct_cmd, dbuf, 0); 3003fcf3ce44SJohn Forte 3004fcf3ce44SJohn Forte break; 3005fcf3ce44SJohn Forte 3006fcf3ce44SJohn Forte /* FCP Status completion */ 3007fcf3ce44SJohn Forte case CMD_FCP_TRSP_CX: 3008fcf3ce44SJohn Forte case CMD_FCP_TRSP64_CX: 3009fcf3ce44SJohn Forte 301082527734SSukumar Swaminathan auto_resp: 301182527734SSukumar Swaminathan /* Copy these before calling emlxs_fct_cmd_done */ 301282527734SSukumar Swaminathan fct_flags = cmd_sbp->fct_flags; 301382527734SSukumar Swaminathan fct_buf = cmd_sbp->fct_buf; 3014fcf3ce44SJohn Forte 301582527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_IO_DONE); 301682527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3017fcf3ce44SJohn Forte 301882527734SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--; 3019fcf3ce44SJohn Forte 302082527734SSukumar Swaminathan if (fct_flags & EMLXS_FCT_SEND_STATUS) { 3021fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 3022fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3023fcf3ce44SJohn Forte "fct_scsi_data_xfer_done:2 %p %p", 302482527734SSukumar Swaminathan fct_cmd, fct_buf); 3025291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 302682527734SSukumar Swaminathan 3027fcf3ce44SJohn Forte MODSYM(fct_scsi_data_xfer_done) (fct_cmd, 302882527734SSukumar Swaminathan fct_buf, FCT_IOF_FCA_DONE); 3029fcf3ce44SJohn Forte } else { 3030fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 3031fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3032fcf3ce44SJohn Forte "fct_send_response_done:1 %p: x%x", 3033fcf3ce44SJohn Forte fct_cmd, fct_cmd->cmd_comp_status); 3034291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 303582527734SSukumar Swaminathan 3036fcf3ce44SJohn Forte MODSYM(fct_send_response_done) (fct_cmd, 3037fcf3ce44SJohn Forte fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE); 3038fcf3ce44SJohn Forte } 3039fcf3ce44SJohn Forte break; 3040fcf3ce44SJohn Forte 3041fcf3ce44SJohn Forte default: 304282527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, 0); 304382527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3044291a2b48SSukumar Swaminathan 3045fcf3ce44SJohn Forte TGTPORTSTAT.FctStray++; 3046fcf3ce44SJohn Forte TGTPORTSTAT.FctCompleted--; 3047fcf3ce44SJohn Forte 3048fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 304982527734SSukumar Swaminathan "Invalid iocb: cmd=0x%x", iocb->ULPCOMMAND); 3050fcf3ce44SJohn Forte 3051291a2b48SSukumar Swaminathan if (pkt) { 3052291a2b48SSukumar Swaminathan emlxs_pkt_complete(sbp, status, 3053291a2b48SSukumar Swaminathan iocb->un.grsp.perr.statLocalError, 1); 3054291a2b48SSukumar Swaminathan } 3055fcf3ce44SJohn Forte 305682527734SSukumar Swaminathan } /* switch(iocb->ULPCOMMAND) */ 3057fcf3ce44SJohn Forte 3058fcf3ce44SJohn Forte 3059291a2b48SSukumar Swaminathan done: 3060291a2b48SSukumar Swaminathan if (pkt) { 3061291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt); 3062291a2b48SSukumar Swaminathan } 3063291a2b48SSukumar Swaminathan 3064fcf3ce44SJohn Forte if (status == IOSTAT_SUCCESS) { 3065fcf3ce44SJohn Forte TGTPORTSTAT.FctCmplGood++; 3066fcf3ce44SJohn Forte } else { 3067fcf3ce44SJohn Forte TGTPORTSTAT.FctCmplError++; 3068fcf3ce44SJohn Forte } 3069fcf3ce44SJohn Forte 3070fcf3ce44SJohn Forte return (0); 3071fcf3ce44SJohn Forte 307282527734SSukumar Swaminathan } /* emlxs_fct_handle_fcp_event() */ 3073291a2b48SSukumar Swaminathan 3074291a2b48SSukumar Swaminathan 3075291a2b48SSukumar Swaminathan /* ARGSUSED */ 3076291a2b48SSukumar Swaminathan extern int 307782527734SSukumar Swaminathan emlxs_fct_handle_abort(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq) 3078291a2b48SSukumar Swaminathan { 3079291a2b48SSukumar Swaminathan emlxs_port_t *port = &PPORT; 3080291a2b48SSukumar Swaminathan IOCB *iocb; 3081291a2b48SSukumar Swaminathan emlxs_buf_t *sbp; 3082291a2b48SSukumar Swaminathan fc_packet_t *pkt; 3083291a2b48SSukumar Swaminathan 3084291a2b48SSukumar Swaminathan iocb = &iocbq->iocb; 3085291a2b48SSukumar Swaminathan sbp = (emlxs_buf_t *)iocbq->sbp; 3086291a2b48SSukumar Swaminathan 3087291a2b48SSukumar Swaminathan TGTPORTSTAT.FctEvent++; 3088291a2b48SSukumar Swaminathan 3089291a2b48SSukumar Swaminathan if (!sbp) { 3090291a2b48SSukumar Swaminathan /* completion with missing xmit command */ 3091291a2b48SSukumar Swaminathan TGTPORTSTAT.FctStray++; 3092291a2b48SSukumar Swaminathan 3093291a2b48SSukumar Swaminathan /* emlxs_stray_fcp_completion_msg */ 3094291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3095291a2b48SSukumar Swaminathan "ABORT event cmd=%x status=%x error=%x iotag=%x", 309682527734SSukumar Swaminathan iocb->ULPCOMMAND, iocb->ULPSTATUS, 309782527734SSukumar Swaminathan iocb->un.grsp.perr.statLocalError, iocb->ULPIOTAG); 3098291a2b48SSukumar Swaminathan 3099291a2b48SSukumar Swaminathan return (1); 3100291a2b48SSukumar Swaminathan } 3101291a2b48SSukumar Swaminathan 3102291a2b48SSukumar Swaminathan pkt = PRIV2PKT(sbp); 3103291a2b48SSukumar Swaminathan 3104291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE 3105291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 310682527734SSukumar Swaminathan "emlxs_fct_handle_abort: %p: xri=%x status=%x", iocb->ULPCONTEXT, 310782527734SSukumar Swaminathan iocb->ULPCOMMAND, iocb->ULPSTATUS); 3108291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 3109291a2b48SSukumar Swaminathan 3110291a2b48SSukumar Swaminathan 3111291a2b48SSukumar Swaminathan if (pkt) { 3112291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt); 3113291a2b48SSukumar Swaminathan } 3114291a2b48SSukumar Swaminathan return (0); 3115fcf3ce44SJohn Forte 311682527734SSukumar Swaminathan } /* emlxs_fct_handle_abort() */ 3117fcf3ce44SJohn Forte 3118fcf3ce44SJohn Forte 3119fcf3ce44SJohn Forte extern int 312082527734SSukumar Swaminathan emlxs_fct_handle_unsol_els(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 3121fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 3122fcf3ce44SJohn Forte { 3123fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 3124fcf3ce44SJohn Forte IOCB *iocb; 3125fcf3ce44SJohn Forte uint32_t cmd_code; 3126fcf3ce44SJohn Forte fct_cmd_t *fct_cmd; 3127fcf3ce44SJohn Forte fct_els_t *els; 3128fcf3ce44SJohn Forte uint32_t sid; 3129fcf3ce44SJohn Forte uint32_t padding; 3130fcf3ce44SJohn Forte uint8_t *bp; 3131fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 3132fcf3ce44SJohn Forte uint32_t rval; 3133fcf3ce44SJohn Forte 3134fcf3ce44SJohn Forte HBASTATS.ElsCmdReceived++; 3135fcf3ce44SJohn Forte 3136fcf3ce44SJohn Forte bp = mp->virt; 3137fcf3ce44SJohn Forte cmd_code = (*(uint32_t *)bp) & ELS_CMD_MASK; 3138fcf3ce44SJohn Forte iocb = &iocbq->iocb; 3139fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 3140fcf3ce44SJohn Forte 3141fcf3ce44SJohn Forte if (!port->fct_port) { 3142fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 3143fcf3ce44SJohn Forte "%s: sid=%x. Target unbound. Rejecting...", 3144fcf3ce44SJohn Forte emlxs_elscmd_xlate(cmd_code), sid); 3145fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code, 3146fcf3ce44SJohn Forte LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 3147fcf3ce44SJohn Forte 3148fcf3ce44SJohn Forte goto done; 3149fcf3ce44SJohn Forte } 3150291a2b48SSukumar Swaminathan 3151fcf3ce44SJohn Forte if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) { 3152fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 3153fcf3ce44SJohn Forte "%s: sid=%x. Target offline. Rejecting...", 3154fcf3ce44SJohn Forte emlxs_elscmd_xlate(cmd_code), sid); 3155fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code, 3156fcf3ce44SJohn Forte LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 3157fcf3ce44SJohn Forte 3158fcf3ce44SJohn Forte goto done; 3159fcf3ce44SJohn Forte } 3160291a2b48SSukumar Swaminathan 3161fcf3ce44SJohn Forte /* Process the request */ 3162fcf3ce44SJohn Forte switch (cmd_code) { 3163fcf3ce44SJohn Forte case ELS_CMD_FLOGI: 3164e2ca2865SSukumar Swaminathan rval = emlxs_fct_process_unsol_flogi(port, cp, iocbq, mp, size); 3165291a2b48SSukumar Swaminathan 3166291a2b48SSukumar Swaminathan if (!rval) { 3167291a2b48SSukumar Swaminathan ELS_PKT *els_pkt = (ELS_PKT *)bp; 3168e2ca2865SSukumar Swaminathan fct_flogi_xchg_t fx; 3169e2ca2865SSukumar Swaminathan 3170e2ca2865SSukumar Swaminathan bzero((uint8_t *)&fx, sizeof (fct_flogi_xchg_t)); 3171291a2b48SSukumar Swaminathan 3172291a2b48SSukumar Swaminathan /* Save the FLOGI exchange information */ 3173e2ca2865SSukumar Swaminathan fx.rsvd2 = iocb->ULPCONTEXT; 3174291a2b48SSukumar Swaminathan bcopy((caddr_t)&els_pkt->un.logi.nodeName, 3175e2ca2865SSukumar Swaminathan (caddr_t)fx.fx_nwwn, 8); 3176291a2b48SSukumar Swaminathan bcopy((caddr_t)&els_pkt->un.logi.portName, 3177e2ca2865SSukumar Swaminathan (caddr_t)fx.fx_pwwn, 8); 3178e2ca2865SSukumar Swaminathan fx.fx_sid = sid; 3179e2ca2865SSukumar Swaminathan fx.fx_did = iocb->un.elsreq.myID; 3180e2ca2865SSukumar Swaminathan fx.fx_fport = els_pkt->un.logi.cmn.fPort; 3181e2ca2865SSukumar Swaminathan fx.fx_op = ELS_OP_FLOGI; 3182e2ca2865SSukumar Swaminathan 3183e2ca2865SSukumar Swaminathan emlxs_fct_handle_unsol_flogi(port, &fx, 1); 3184291a2b48SSukumar Swaminathan } 3185e2ca2865SSukumar Swaminathan 3186291a2b48SSukumar Swaminathan goto done; 3187fcf3ce44SJohn Forte 3188fcf3ce44SJohn Forte case ELS_CMD_PLOGI: 3189291a2b48SSukumar Swaminathan rval = 319082527734SSukumar Swaminathan emlxs_fct_process_unsol_plogi(port, cp, iocbq, mp, size); 3191fcf3ce44SJohn Forte break; 3192fcf3ce44SJohn Forte 3193fcf3ce44SJohn Forte default: 3194fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 3195fcf3ce44SJohn Forte "%s: sid=0x%x", emlxs_elscmd_xlate(cmd_code), sid); 3196fcf3ce44SJohn Forte rval = 0; 3197fcf3ce44SJohn Forte break; 3198fcf3ce44SJohn Forte } 3199fcf3ce44SJohn Forte 3200fcf3ce44SJohn Forte if (rval) { 3201fcf3ce44SJohn Forte goto done; 3202fcf3ce44SJohn Forte } 3203291a2b48SSukumar Swaminathan 3204fcf3ce44SJohn Forte padding = (8 - (size & 7)) & 7; 3205fcf3ce44SJohn Forte 3206fcf3ce44SJohn Forte fct_cmd = (fct_cmd_t *)MODSYM(fct_alloc) (FCT_STRUCT_CMD_RCVD_ELS, 3207291a2b48SSukumar Swaminathan (size + padding + GET_STRUCT_SIZE(emlxs_buf_t)), 3208291a2b48SSukumar Swaminathan AF_FORCE_NOSLEEP); 3209fcf3ce44SJohn Forte 3210fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 3211fcf3ce44SJohn Forte { 3212fcf3ce44SJohn Forte uint32_t *ptr = (uint32_t *)bp; 3213fcf3ce44SJohn Forte 3214fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3215fcf3ce44SJohn Forte "fct_alloc %p: ELS rcvd: rxid=%x payload: x%x x%x", 321682527734SSukumar Swaminathan fct_cmd, iocb->ULPCONTEXT, *ptr, *(ptr + 1)); 3217fcf3ce44SJohn Forte } 3218291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 3219fcf3ce44SJohn Forte 3220fcf3ce44SJohn Forte if (fct_cmd == NULL) { 3221fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 3222fcf3ce44SJohn Forte "%s: sid=%x. Out of memory. Rejecting...", 3223fcf3ce44SJohn Forte emlxs_elscmd_xlate(cmd_code), sid); 3224fcf3ce44SJohn Forte 3225fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code, 3226fcf3ce44SJohn Forte LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE); 3227fcf3ce44SJohn Forte goto done; 3228fcf3ce44SJohn Forte } 3229291a2b48SSukumar Swaminathan 3230fcf3ce44SJohn Forte /* Initialize fct_cmd */ 3231fcf3ce44SJohn Forte fct_cmd->cmd_oxid = (cmd_code >> ELS_CMD_SHIFT) & 0xff; 323282527734SSukumar Swaminathan fct_cmd->cmd_rxid = iocb->ULPCONTEXT; 3233fcf3ce44SJohn Forte fct_cmd->cmd_rportid = sid; 3234fcf3ce44SJohn Forte fct_cmd->cmd_lportid = port->did; 323582527734SSukumar Swaminathan fct_cmd->cmd_rp_handle = iocb->ULPIOTAG; /* RPI */ 3236fcf3ce44SJohn Forte fct_cmd->cmd_port = port->fct_port; 3237fcf3ce44SJohn Forte 323882527734SSukumar Swaminathan cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd, EMLXS_FCT_ELS_CMD_RECEIVED); 323982527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 3240fcf3ce44SJohn Forte 3241291a2b48SSukumar Swaminathan /* Initialize cmd_sbp */ 324282527734SSukumar Swaminathan cmd_sbp->channel = cp; 324382527734SSukumar Swaminathan cmd_sbp->class = iocb->ULPCLASS; 3244fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_ELS_CMD; 3245291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_PLOGI_RECEIVED; 3246291a2b48SSukumar Swaminathan 3247fcf3ce44SJohn Forte bcopy((uint8_t *)iocb, (uint8_t *)&cmd_sbp->iocbq, 3248fcf3ce44SJohn Forte sizeof (emlxs_iocb_t)); 3249fcf3ce44SJohn Forte 3250fcf3ce44SJohn Forte els = (fct_els_t *)fct_cmd->cmd_specific; 3251*a9800bebSGarrett D'Amore els->els_req_size = (uint16_t)size; 3252291a2b48SSukumar Swaminathan els->els_req_payload = 3253291a2b48SSukumar Swaminathan GET_BYTE_OFFSET(fct_cmd->cmd_fca_private, 3254fcf3ce44SJohn Forte GET_STRUCT_SIZE(emlxs_buf_t)); 3255fcf3ce44SJohn Forte bcopy(bp, els->els_req_payload, size); 3256fcf3ce44SJohn Forte 3257e2ca2865SSukumar Swaminathan 3258e2ca2865SSukumar Swaminathan /* Check if Offline */ 3259e2ca2865SSukumar Swaminathan if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) { 3260e2ca2865SSukumar Swaminathan 3261e2ca2865SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 3262e2ca2865SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3263e2ca2865SSukumar Swaminathan 3264e2ca2865SSukumar Swaminathan #ifdef FCT_API_TRACE 3265e2ca2865SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3266e2ca2865SSukumar Swaminathan "fct_post_rcvd_cmd:4 %p: portid x%x", fct_cmd, 3267e2ca2865SSukumar Swaminathan fct_cmd->cmd_lportid); 3268e2ca2865SSukumar Swaminathan #endif /* FCT_API_TRACE */ 3269e2ca2865SSukumar Swaminathan 3270e2ca2865SSukumar Swaminathan MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0); 3271e2ca2865SSukumar Swaminathan 3272e2ca2865SSukumar Swaminathan goto done; 3273e2ca2865SSukumar Swaminathan } 3274e2ca2865SSukumar Swaminathan 3275e2ca2865SSukumar Swaminathan /* Online */ 3276e2ca2865SSukumar Swaminathan /* Check if Link up is acked */ 3277e2ca2865SSukumar Swaminathan if (port->fct_flags & FCT_STATE_LINK_UP_ACKED) { 3278e2ca2865SSukumar Swaminathan 3279e2ca2865SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 3280e2ca2865SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3281e2ca2865SSukumar Swaminathan 3282e2ca2865SSukumar Swaminathan #ifdef FCT_API_TRACE 3283e2ca2865SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3284e2ca2865SSukumar Swaminathan "fct_post_rcvd_cmd:1 %p: portid x%x", fct_cmd, 3285e2ca2865SSukumar Swaminathan fct_cmd->cmd_lportid); 3286e2ca2865SSukumar Swaminathan #endif /* FCT_API_TRACE */ 3287e2ca2865SSukumar Swaminathan 3288e2ca2865SSukumar Swaminathan MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0); 3289e2ca2865SSukumar Swaminathan 3290e2ca2865SSukumar Swaminathan goto done; 3291e2ca2865SSukumar Swaminathan 3292e2ca2865SSukumar Swaminathan } 3293e2ca2865SSukumar Swaminathan 3294e2ca2865SSukumar Swaminathan /* Defer processing of fct_cmd till later (after link up ack). */ 3295e2ca2865SSukumar Swaminathan 3296e2ca2865SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, EMLXS_FCT_CMD_WAITQ); 3297e2ca2865SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3298e2ca2865SSukumar Swaminathan 3299e2ca2865SSukumar Swaminathan /* Add cmd_sbp to queue tail */ 3300e2ca2865SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 3301e2ca2865SSukumar Swaminathan 3302e2ca2865SSukumar Swaminathan if (port->fct_wait_tail) { 3303e2ca2865SSukumar Swaminathan port->fct_wait_tail->next = cmd_sbp; 3304e2ca2865SSukumar Swaminathan } 3305e2ca2865SSukumar Swaminathan port->fct_wait_tail = cmd_sbp; 3306e2ca2865SSukumar Swaminathan 3307e2ca2865SSukumar Swaminathan if (!port->fct_wait_head) { 3308e2ca2865SSukumar Swaminathan port->fct_wait_head = cmd_sbp; 3309e2ca2865SSukumar Swaminathan } 3310e2ca2865SSukumar Swaminathan 3311e2ca2865SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 3312fcf3ce44SJohn Forte 3313fcf3ce44SJohn Forte done: 3314fcf3ce44SJohn Forte 3315fcf3ce44SJohn Forte return (0); 3316fcf3ce44SJohn Forte 331782527734SSukumar Swaminathan } /* emlxs_fct_handle_unsol_els() */ 3318fcf3ce44SJohn Forte 3319fcf3ce44SJohn Forte 3320fcf3ce44SJohn Forte /* ARGSUSED */ 3321fcf3ce44SJohn Forte static uint32_t 332282527734SSukumar Swaminathan emlxs_fct_process_unsol_flogi(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 3323fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 3324fcf3ce44SJohn Forte { 3325fcf3ce44SJohn Forte IOCB *iocb; 3326fcf3ce44SJohn Forte char buffer[64]; 3327fcf3ce44SJohn Forte 3328fcf3ce44SJohn Forte buffer[0] = 0; 3329fcf3ce44SJohn Forte 3330fcf3ce44SJohn Forte iocb = &iocbq->iocb; 3331fcf3ce44SJohn Forte 3332fcf3ce44SJohn Forte /* Perform processing of FLOGI payload */ 3333fcf3ce44SJohn Forte if (emlxs_process_unsol_flogi(port, iocbq, mp, size, buffer)) { 3334fcf3ce44SJohn Forte return (1); 3335fcf3ce44SJohn Forte } 3336291a2b48SSukumar Swaminathan 3337fe199829SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 3338fe199829SSukumar Swaminathan "FLOGI: sid=0x%x xid=%x %s", 3339fe199829SSukumar Swaminathan iocb->un.elsreq.remoteID, iocb->ULPIOTAG, buffer); 3340fcf3ce44SJohn Forte 3341fcf3ce44SJohn Forte return (0); 3342fcf3ce44SJohn Forte 334382527734SSukumar Swaminathan } /* emlxs_fct_process_unsol_flogi() */ 3344fcf3ce44SJohn Forte 3345fcf3ce44SJohn Forte 3346fcf3ce44SJohn Forte /* ARGSUSED */ 3347fcf3ce44SJohn Forte static uint32_t 334882527734SSukumar Swaminathan emlxs_fct_process_unsol_plogi(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 3349fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 3350fcf3ce44SJohn Forte { 3351fcf3ce44SJohn Forte IOCB *iocb; 3352fcf3ce44SJohn Forte char buffer[64]; 3353fcf3ce44SJohn Forte 3354fcf3ce44SJohn Forte buffer[0] = 0; 3355fcf3ce44SJohn Forte 3356fcf3ce44SJohn Forte iocb = &iocbq->iocb; 3357fcf3ce44SJohn Forte 3358fcf3ce44SJohn Forte /* Perform processing of PLOGI payload */ 3359fcf3ce44SJohn Forte if (emlxs_process_unsol_plogi(port, iocbq, mp, size, buffer)) { 3360fcf3ce44SJohn Forte return (1); 3361fcf3ce44SJohn Forte } 3362291a2b48SSukumar Swaminathan 3363fe199829SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 3364fe199829SSukumar Swaminathan "PLOGI: sid=0x%x xid=%x %s", 3365fe199829SSukumar Swaminathan iocb->un.elsreq.remoteID, iocb->ULPIOTAG, buffer); 3366fcf3ce44SJohn Forte 3367fcf3ce44SJohn Forte return (0); 3368fcf3ce44SJohn Forte 336982527734SSukumar Swaminathan } /* emlxs_fct_process_unsol_plogi() */ 3370fcf3ce44SJohn Forte 3371fcf3ce44SJohn Forte 3372fcf3ce44SJohn Forte /* ARGSUSED */ 3373fcf3ce44SJohn Forte static emlxs_buf_t * 3374291a2b48SSukumar Swaminathan emlxs_fct_pkt_init(emlxs_port_t *port, fct_cmd_t *fct_cmd, 3375291a2b48SSukumar Swaminathan fc_packet_t *pkt) 3376fcf3ce44SJohn Forte { 3377fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 3378fcf3ce44SJohn Forte emlxs_buf_t *sbp; 3379fcf3ce44SJohn Forte 3380fcf3ce44SJohn Forte cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 3381fcf3ce44SJohn Forte 3382fcf3ce44SJohn Forte sbp = PKT2PRIV(pkt); 3383fcf3ce44SJohn Forte sbp->fct_cmd = cmd_sbp->fct_cmd; 3384fcf3ce44SJohn Forte sbp->node = cmd_sbp->node; 338582527734SSukumar Swaminathan sbp->channel = cmd_sbp->channel; 3386fcf3ce44SJohn Forte sbp->did = cmd_sbp->did; 3387fcf3ce44SJohn Forte sbp->lun = cmd_sbp->lun; 3388fcf3ce44SJohn Forte sbp->class = cmd_sbp->class; 3389fcf3ce44SJohn Forte sbp->fct_type = cmd_sbp->fct_type; 3390fcf3ce44SJohn Forte sbp->fct_state = cmd_sbp->fct_state; 3391fcf3ce44SJohn Forte 3392fcf3ce44SJohn Forte return (sbp); 3393fcf3ce44SJohn Forte 339482527734SSukumar Swaminathan } /* emlxs_fct_pkt_init() */ 3395fcf3ce44SJohn Forte 3396fcf3ce44SJohn Forte 3397fcf3ce44SJohn Forte /* Mutex will be acquired */ 3398fcf3ce44SJohn Forte static emlxs_buf_t * 3399*a9800bebSGarrett D'Amore emlxs_fct_cmd_init(emlxs_port_t *port, fct_cmd_t *fct_cmd, uint16_t fct_state) 3400fcf3ce44SJohn Forte { 3401fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 3402fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 3403fcf3ce44SJohn Forte 3404fcf3ce44SJohn Forte bzero((void *)cmd_sbp, sizeof (emlxs_buf_t)); 3405291a2b48SSukumar Swaminathan mutex_init(&cmd_sbp->fct_mtx, NULL, MUTEX_DRIVER, 3406*a9800bebSGarrett D'Amore DDI_INTR_PRI(hba->intr_arg)); 3407*a9800bebSGarrett D'Amore mutex_init(&cmd_sbp->mtx, NULL, MUTEX_DRIVER, 3408*a9800bebSGarrett D'Amore DDI_INTR_PRI(hba->intr_arg)); 3409fcf3ce44SJohn Forte 3410291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->fct_mtx); 3411fcf3ce44SJohn Forte cmd_sbp->pkt_flags = PACKET_VALID; 3412fcf3ce44SJohn Forte cmd_sbp->port = port; 3413fcf3ce44SJohn Forte cmd_sbp->fct_cmd = fct_cmd; 3414fcf3ce44SJohn Forte cmd_sbp->node = (fct_cmd->cmd_rp) ? 3415fcf3ce44SJohn Forte *(emlxs_node_t **)fct_cmd->cmd_rp->rp_fca_private : NULL; 3416fcf3ce44SJohn Forte cmd_sbp->iocbq.sbp = cmd_sbp; 3417291a2b48SSukumar Swaminathan cmd_sbp->iocbq.port = port; 341882527734SSukumar Swaminathan cmd_sbp->did = fct_cmd->cmd_rportid; 341982527734SSukumar Swaminathan 342082527734SSukumar Swaminathan /* Flags fct_cmd as inuse */ 342182527734SSukumar Swaminathan if ((fct_cmd->cmd_oxid == 0) && (fct_cmd->cmd_rxid == 0)) { 342282527734SSukumar Swaminathan fct_cmd->cmd_oxid = 0xffff; 342382527734SSukumar Swaminathan fct_cmd->cmd_rxid = 0xffff; 342482527734SSukumar Swaminathan } 342582527734SSukumar Swaminathan 342682527734SSukumar Swaminathan if (fct_state) { 342782527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, fct_state); 342882527734SSukumar Swaminathan } 3429fcf3ce44SJohn Forte 3430fcf3ce44SJohn Forte return (cmd_sbp); 3431fcf3ce44SJohn Forte 343282527734SSukumar Swaminathan } /* emlxs_fct_cmd_init() */ 3433fcf3ce44SJohn Forte 3434fcf3ce44SJohn Forte 343582527734SSukumar Swaminathan /* Called after receiving fct_cmd from COMSTAR */ 343682527734SSukumar Swaminathan static fct_status_t 343782527734SSukumar Swaminathan emlxs_fct_cmd_accept(emlxs_port_t *port, fct_cmd_t *fct_cmd, uint16_t fct_state) 3438fcf3ce44SJohn Forte { 3439fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 3440fcf3ce44SJohn Forte 344182527734SSukumar Swaminathan if (!(cmd_sbp->pkt_flags & PACKET_VALID)) { 344282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 344382527734SSukumar Swaminathan "emlxs_fct_cmd_accept: " 344482527734SSukumar Swaminathan "Invalid fct_cmd found! fct_cmd=%p state=%x", 344582527734SSukumar Swaminathan fct_cmd, fct_state); 344682527734SSukumar Swaminathan 344782527734SSukumar Swaminathan return (FCT_NOT_FOUND); 344882527734SSukumar Swaminathan } 344982527734SSukumar Swaminathan 345082527734SSukumar Swaminathan mutex_enter(&cmd_sbp->fct_mtx); 345182527734SSukumar Swaminathan 345282527734SSukumar Swaminathan if (!(cmd_sbp->pkt_flags & PACKET_VALID)) { 345382527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 345482527734SSukumar Swaminathan 345582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 345682527734SSukumar Swaminathan "emlxs_fct_cmd_accept:2 " 345782527734SSukumar Swaminathan "Invalid fct_cmd found! fct_cmd=%p state=%x", 345882527734SSukumar Swaminathan fct_cmd, fct_state); 345982527734SSukumar Swaminathan 346082527734SSukumar Swaminathan return (FCT_NOT_FOUND); 346182527734SSukumar Swaminathan } 346282527734SSukumar Swaminathan 346382527734SSukumar Swaminathan if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT_INP) { 346482527734SSukumar Swaminathan 346582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 346682527734SSukumar Swaminathan "emlxs_fct_cmd_accept: " 346782527734SSukumar Swaminathan "Aborted fct_cmd found! fct_cmd=%p state=%x", 346882527734SSukumar Swaminathan fct_cmd, fct_state); 346982527734SSukumar Swaminathan 347082527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_ABORT_DONE); 347182527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 347282527734SSukumar Swaminathan 347382527734SSukumar Swaminathan MODSYM(fct_cmd_fca_aborted) (fct_cmd, 347482527734SSukumar Swaminathan FCT_ABORT_SUCCESS, FCT_IOF_FCA_DONE); 347582527734SSukumar Swaminathan 347682527734SSukumar Swaminathan return (FCT_NOT_FOUND); 347782527734SSukumar Swaminathan } 347882527734SSukumar Swaminathan 347982527734SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx); 348082527734SSukumar Swaminathan if (!(cmd_sbp->pkt_flags & PACKET_ULP_OWNED)) { 348182527734SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx); 348282527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 348382527734SSukumar Swaminathan 348482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 348582527734SSukumar Swaminathan "emlxs_fct_cmd_accept: " 348682527734SSukumar Swaminathan "Busy fct_cmd found! fct_cmd=%p state=%x", 348782527734SSukumar Swaminathan fct_cmd, fct_state); 348882527734SSukumar Swaminathan 348982527734SSukumar Swaminathan return (FCT_BUSY); 349082527734SSukumar Swaminathan } 349182527734SSukumar Swaminathan cmd_sbp->pkt_flags &= ~PACKET_ULP_OWNED; 349282527734SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx); 349382527734SSukumar Swaminathan 349482527734SSukumar Swaminathan if (fct_state) { 349582527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, fct_state); 349682527734SSukumar Swaminathan } 349782527734SSukumar Swaminathan 349882527734SSukumar Swaminathan return (FCT_SUCCESS); 349982527734SSukumar Swaminathan 350082527734SSukumar Swaminathan } /* emlxs_fct_cmd_accept() */ 350182527734SSukumar Swaminathan 350282527734SSukumar Swaminathan 350382527734SSukumar Swaminathan /* Called after receiving fct_cmd from driver */ 350482527734SSukumar Swaminathan static fct_status_t 350582527734SSukumar Swaminathan emlxs_fct_cmd_acquire(emlxs_port_t *port, fct_cmd_t *fct_cmd, 350682527734SSukumar Swaminathan uint16_t fct_state) 350782527734SSukumar Swaminathan { 350882527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 350982527734SSukumar Swaminathan 351082527734SSukumar Swaminathan if ((fct_cmd->cmd_oxid == 0) && (fct_cmd->cmd_rxid == 0)) { 351182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 351282527734SSukumar Swaminathan "emlxs_fct_cmd_acquire: " 351382527734SSukumar Swaminathan "Bad fct_cmd found! fct_cmd=%p state=%x", 351482527734SSukumar Swaminathan fct_cmd, fct_state); 351582527734SSukumar Swaminathan 351682527734SSukumar Swaminathan return (FCT_NOT_FOUND); 351782527734SSukumar Swaminathan } 351882527734SSukumar Swaminathan 351982527734SSukumar Swaminathan if (!(cmd_sbp->pkt_flags & PACKET_VALID)) { 352082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 352182527734SSukumar Swaminathan "emlxs_fct_cmd_acquire: " 352282527734SSukumar Swaminathan "Invalid fct_cmd found! fct_cmd=%p state=%x", 352382527734SSukumar Swaminathan fct_cmd, fct_state); 352482527734SSukumar Swaminathan 352582527734SSukumar Swaminathan return (FCT_NOT_FOUND); 352682527734SSukumar Swaminathan } 352782527734SSukumar Swaminathan 352882527734SSukumar Swaminathan if ((cmd_sbp->pkt_flags & PACKET_ULP_OWNED)) { 352982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 353082527734SSukumar Swaminathan "emlxs_fct_cmd_acquire: " 353182527734SSukumar Swaminathan "Returned fct_cmd found! fct_cmd=%p state=%x", 353282527734SSukumar Swaminathan fct_cmd, fct_state); 353382527734SSukumar Swaminathan 353482527734SSukumar Swaminathan return (FCT_NOT_FOUND); 353582527734SSukumar Swaminathan } 353682527734SSukumar Swaminathan 353782527734SSukumar Swaminathan mutex_enter(&cmd_sbp->fct_mtx); 353882527734SSukumar Swaminathan 353982527734SSukumar Swaminathan if ((fct_cmd->cmd_oxid == 0) && (fct_cmd->cmd_rxid == 0)) { 354082527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 354182527734SSukumar Swaminathan 354282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 354382527734SSukumar Swaminathan "emlxs_fct_cmd_acquire:2 " 354482527734SSukumar Swaminathan "Bad fct_cmd found! fct_cmd=%p state=%x", 354582527734SSukumar Swaminathan fct_cmd, fct_state); 3546291a2b48SSukumar Swaminathan 354782527734SSukumar Swaminathan return (FCT_NOT_FOUND); 354882527734SSukumar Swaminathan } 3549291a2b48SSukumar Swaminathan 3550fcf3ce44SJohn Forte if (!(cmd_sbp->pkt_flags & PACKET_VALID)) { 355182527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 355282527734SSukumar Swaminathan 355382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 355482527734SSukumar Swaminathan "emlxs_fct_cmd_acquire:2 " 355582527734SSukumar Swaminathan "Invalid fct_cmd found! fct_cmd=%p state=%x", 355682527734SSukumar Swaminathan fct_cmd, fct_state); 355782527734SSukumar Swaminathan 355882527734SSukumar Swaminathan return (FCT_NOT_FOUND); 355982527734SSukumar Swaminathan } 356082527734SSukumar Swaminathan 356182527734SSukumar Swaminathan if ((cmd_sbp->pkt_flags & PACKET_ULP_OWNED)) { 356282527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 356382527734SSukumar Swaminathan 356482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 356582527734SSukumar Swaminathan "emlxs_fct_cmd_acquire:2 " 356682527734SSukumar Swaminathan "Returned fct_cmd found! fct_cmd=%p state=%x", 356782527734SSukumar Swaminathan fct_cmd, fct_state); 356882527734SSukumar Swaminathan 356982527734SSukumar Swaminathan return (FCT_NOT_FOUND); 357082527734SSukumar Swaminathan } 357182527734SSukumar Swaminathan 357282527734SSukumar Swaminathan if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT_INP) { 357382527734SSukumar Swaminathan 357482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 357582527734SSukumar Swaminathan "emlxs_fct_cmd_acquire: " 357682527734SSukumar Swaminathan "Aborting cmd. fct_cmd=%p state=%x", 357782527734SSukumar Swaminathan fct_cmd, fct_state); 357882527734SSukumar Swaminathan 357982527734SSukumar Swaminathan if (fct_cmd->cmd_type == FCT_CMD_FCP_XCHG) { 358082527734SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--; 358182527734SSukumar Swaminathan } 358282527734SSukumar Swaminathan 358382527734SSukumar Swaminathan fct_cmd->cmd_comp_status = FCT_FAILURE; 358482527734SSukumar Swaminathan 358582527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_ABORT_DONE); 358682527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 358782527734SSukumar Swaminathan 358882527734SSukumar Swaminathan MODSYM(fct_cmd_fca_aborted) (fct_cmd, 358982527734SSukumar Swaminathan FCT_ABORT_SUCCESS, FCT_IOF_FCA_DONE); 359082527734SSukumar Swaminathan 359182527734SSukumar Swaminathan return (FCT_NOT_FOUND); 359282527734SSukumar Swaminathan } 359382527734SSukumar Swaminathan 359482527734SSukumar Swaminathan if (fct_state) { 359582527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, fct_state); 359682527734SSukumar Swaminathan } 359782527734SSukumar Swaminathan 359882527734SSukumar Swaminathan return (FCT_SUCCESS); 359982527734SSukumar Swaminathan 360082527734SSukumar Swaminathan } /* emlxs_fct_cmd_acquire() */ 360182527734SSukumar Swaminathan 360282527734SSukumar Swaminathan 360382527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be held to enter */ 360482527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be released before exiting */ 360582527734SSukumar Swaminathan /* Called before transitionally sending fct_cmd to driver */ 360682527734SSukumar Swaminathan /*ARGSUSED*/ 360782527734SSukumar Swaminathan static void 360882527734SSukumar Swaminathan emlxs_fct_cmd_release(emlxs_port_t *port, fct_cmd_t *fct_cmd, 360982527734SSukumar Swaminathan uint16_t fct_state) 361082527734SSukumar Swaminathan { 361182527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 361282527734SSukumar Swaminathan 361382527734SSukumar Swaminathan if (fct_state) { 361482527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, fct_state); 3615fcf3ce44SJohn Forte } 3616291a2b48SSukumar Swaminathan 361782527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 361882527734SSukumar Swaminathan 361982527734SSukumar Swaminathan return; 362082527734SSukumar Swaminathan 362182527734SSukumar Swaminathan } /* emlxs_fct_cmd_release() */ 362282527734SSukumar Swaminathan 362382527734SSukumar Swaminathan 362482527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be held to enter */ 362582527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be released before exiting */ 362682527734SSukumar Swaminathan /* Called before posting fct_cmd back to COMSTAR */ 362782527734SSukumar Swaminathan /*ARGSUSED*/ 362882527734SSukumar Swaminathan static void 362982527734SSukumar Swaminathan emlxs_fct_cmd_post(emlxs_port_t *port, fct_cmd_t *fct_cmd, 363082527734SSukumar Swaminathan uint16_t fct_state) 363182527734SSukumar Swaminathan { 363282527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 363382527734SSukumar Swaminathan fc_packet_t *pkt; 363482527734SSukumar Swaminathan 363582527734SSukumar Swaminathan pkt = cmd_sbp->fct_pkt; 363682527734SSukumar Swaminathan cmd_sbp->fct_pkt = NULL; 363782527734SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP; 363882527734SSukumar Swaminathan 363982527734SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx); 364082527734SSukumar Swaminathan cmd_sbp->pkt_flags |= PACKET_ULP_OWNED; 364182527734SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx); 364282527734SSukumar Swaminathan 364382527734SSukumar Swaminathan if (fct_state) { 364482527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, fct_state); 364582527734SSukumar Swaminathan } 364682527734SSukumar Swaminathan 364782527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 364882527734SSukumar Swaminathan 364982527734SSukumar Swaminathan if (pkt) { 365082527734SSukumar Swaminathan emlxs_pkt_free(pkt); 365182527734SSukumar Swaminathan } 365282527734SSukumar Swaminathan 365382527734SSukumar Swaminathan return; 365482527734SSukumar Swaminathan 365582527734SSukumar Swaminathan } /* emlxs_fct_cmd_post() */ 365682527734SSukumar Swaminathan 365782527734SSukumar Swaminathan 365882527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be held to enter */ 365982527734SSukumar Swaminathan /* Called before completing fct_cmd back to COMSTAR */ 366082527734SSukumar Swaminathan static void 366182527734SSukumar Swaminathan emlxs_fct_cmd_done(emlxs_port_t *port, fct_cmd_t *fct_cmd, uint16_t fct_state) 366282527734SSukumar Swaminathan { 366382527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 366482527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 366582527734SSukumar Swaminathan fc_packet_t *pkt; 366682527734SSukumar Swaminathan 366782527734SSukumar Swaminathan /* Flags fct_cmd is no longer used */ 366882527734SSukumar Swaminathan fct_cmd->cmd_oxid = 0; 366982527734SSukumar Swaminathan fct_cmd->cmd_rxid = 0; 367082527734SSukumar Swaminathan 3671fcf3ce44SJohn Forte if (cmd_sbp->iotag != 0) { 3672fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 367382527734SSukumar Swaminathan "Pkt still registered! channel=%d iotag=%d sbp=%p", 367482527734SSukumar Swaminathan cmd_sbp->channel, cmd_sbp->iotag, cmd_sbp); 367582527734SSukumar Swaminathan 367682527734SSukumar Swaminathan if (cmd_sbp->channel) { 367782527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 3678*a9800bebSGarrett D'Amore emlxs_sli4_free_xri(hba, cmd_sbp, cmd_sbp->xrip, 3679*a9800bebSGarrett D'Amore 1); 368082527734SSukumar Swaminathan } else { 368182527734SSukumar Swaminathan (void) emlxs_unregister_pkt(cmd_sbp->channel, 368282527734SSukumar Swaminathan cmd_sbp->iotag, 0); 368382527734SSukumar Swaminathan } 3684fcf3ce44SJohn Forte 3685fcf3ce44SJohn Forte } 3686fcf3ce44SJohn Forte } 3687291a2b48SSukumar Swaminathan 368882527734SSukumar Swaminathan pkt = cmd_sbp->fct_pkt; 368982527734SSukumar Swaminathan cmd_sbp->fct_pkt = NULL; 369082527734SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP; 369182527734SSukumar Swaminathan 369282527734SSukumar Swaminathan if (fct_state) { 369382527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, fct_state); 369482527734SSukumar Swaminathan } 3695fcf3ce44SJohn Forte 369682527734SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx); 369782527734SSukumar Swaminathan cmd_sbp->pkt_flags |= PACKET_ULP_OWNED; 369882527734SSukumar Swaminathan cmd_sbp->pkt_flags &= ~PACKET_VALID; 369982527734SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx); 3700291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 370182527734SSukumar Swaminathan 370282527734SSukumar Swaminathan 3703291a2b48SSukumar Swaminathan mutex_destroy(&cmd_sbp->fct_mtx); 370482527734SSukumar Swaminathan mutex_destroy(&cmd_sbp->mtx); 370582527734SSukumar Swaminathan 370682527734SSukumar Swaminathan if (pkt) { 370782527734SSukumar Swaminathan emlxs_pkt_free(pkt); 370882527734SSukumar Swaminathan } 3709fcf3ce44SJohn Forte 371082527734SSukumar Swaminathan return; 3711fcf3ce44SJohn Forte 371282527734SSukumar Swaminathan } /* emlxs_fct_cmd_done() */ 3713fcf3ce44SJohn Forte 3714fcf3ce44SJohn Forte 3715fcf3ce44SJohn Forte static void 3716fcf3ce44SJohn Forte emlxs_fct_pkt_comp(fc_packet_t *pkt) 3717fcf3ce44SJohn Forte { 3718fcf3ce44SJohn Forte emlxs_port_t *port; 3719291a2b48SSukumar Swaminathan #ifdef FMA_SUPPORT 3720291a2b48SSukumar Swaminathan emlxs_hba_t *hba; 3721291a2b48SSukumar Swaminathan #endif /* FMA_SUPPORT */ 3722fcf3ce44SJohn Forte emlxs_buf_t *sbp; 3723fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 3724fcf3ce44SJohn Forte fct_cmd_t *fct_cmd; 3725fcf3ce44SJohn Forte fct_els_t *fct_els; 3726fcf3ce44SJohn Forte fct_sol_ct_t *fct_ct; 372782527734SSukumar Swaminathan fct_status_t rval; 3728fcf3ce44SJohn Forte 3729fcf3ce44SJohn Forte sbp = PKT2PRIV(pkt); 3730fcf3ce44SJohn Forte port = sbp->port; 3731291a2b48SSukumar Swaminathan #ifdef FMA_SUPPORT 3732291a2b48SSukumar Swaminathan hba = HBA; 3733291a2b48SSukumar Swaminathan #endif /* FMA_SUPPORT */ 3734fcf3ce44SJohn Forte fct_cmd = sbp->fct_cmd; 3735291a2b48SSukumar Swaminathan 373682527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, EMLXS_FCT_PKT_COMPLETE); 373782527734SSukumar Swaminathan if (rval) { 373882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 373982527734SSukumar Swaminathan "emlxs_fct_pkt_comp: " 374082527734SSukumar Swaminathan "Unable to reacquire fct_cmd."); 374182527734SSukumar Swaminathan return; 3742291a2b48SSukumar Swaminathan } 374382527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 3744fcf3ce44SJohn Forte 374582527734SSukumar Swaminathan cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 374682527734SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP; 3747fcf3ce44SJohn Forte cmd_sbp->fct_pkt = NULL; 3748fcf3ce44SJohn Forte 3749291a2b48SSukumar Swaminathan switch (fct_cmd->cmd_type) { 3750291a2b48SSukumar Swaminathan case FCT_CMD_FCP_XCHG: 3751291a2b48SSukumar Swaminathan if ((pkt->pkt_reason == FC_REASON_ABORTED) || 3752291a2b48SSukumar Swaminathan (pkt->pkt_reason == FC_REASON_XCHG_DROPPED) || 3753291a2b48SSukumar Swaminathan (pkt->pkt_reason == FC_REASON_OFFLINE)) { 3754291a2b48SSukumar Swaminathan /* 3755291a2b48SSukumar Swaminathan * The error indicates this IO should be terminated 3756291a2b48SSukumar Swaminathan * immediately. 3757291a2b48SSukumar Swaminathan */ 3758291a2b48SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_SEND_STATUS; 3759fcf3ce44SJohn Forte 376082527734SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED); 376182527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3762fcf3ce44SJohn Forte 3763291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE 3764291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3765291a2b48SSukumar Swaminathan "fct_queue_cmd_for_termination:2 %p: x%x", 3766291a2b48SSukumar Swaminathan fct_cmd, fct_cmd->cmd_comp_status); 3767291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 376882527734SSukumar Swaminathan 3769291a2b48SSukumar Swaminathan MODSYM(fct_queue_cmd_for_termination) (fct_cmd, 3770291a2b48SSukumar Swaminathan FCT_ABTS_RECEIVED); 377182527734SSukumar Swaminathan 377282527734SSukumar Swaminathan break; 3773291a2b48SSukumar Swaminathan } 3774fcf3ce44SJohn Forte 377582527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, 3776291a2b48SSukumar Swaminathan EMLXS_FCT_PKT_FCPRSP_COMPLETE); 3777291a2b48SSukumar Swaminathan 377882527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_IO_DONE); 3779291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3780fcf3ce44SJohn Forte 3781fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 3782fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3783fcf3ce44SJohn Forte "fct_send_response_done:2 %p: x%x", 3784fcf3ce44SJohn Forte fct_cmd, fct_cmd->cmd_comp_status); 3785fcf3ce44SJohn Forte #else 3786fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3787fcf3ce44SJohn Forte "emlxs_fct_pkt_comp: fct_send_response_done. dbuf=%p", 3788fcf3ce44SJohn Forte sbp->fct_buf); 3789291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 3790291a2b48SSukumar Swaminathan 3791291a2b48SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--; 3792fcf3ce44SJohn Forte 3793fcf3ce44SJohn Forte MODSYM(fct_send_response_done) (fct_cmd, 3794fcf3ce44SJohn Forte fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE); 3795fcf3ce44SJohn Forte 3796fcf3ce44SJohn Forte break; 3797fcf3ce44SJohn Forte 3798fcf3ce44SJohn Forte case FCT_CMD_RCVD_ELS: 3799fcf3ce44SJohn Forte 380082527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, 3801291a2b48SSukumar Swaminathan EMLXS_FCT_PKT_ELSRSP_COMPLETE); 3802291a2b48SSukumar Swaminathan 380382527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_IO_DONE); 3804291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3805fcf3ce44SJohn Forte 3806fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 3807fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3808fcf3ce44SJohn Forte "fct_send_response_done:3 %p: x%x", 3809fcf3ce44SJohn Forte fct_cmd, fct_cmd->cmd_comp_status); 3810291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 381182527734SSukumar Swaminathan 3812fcf3ce44SJohn Forte MODSYM(fct_send_response_done) (fct_cmd, 3813fcf3ce44SJohn Forte fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE); 3814fcf3ce44SJohn Forte 3815fcf3ce44SJohn Forte break; 3816fcf3ce44SJohn Forte 3817fcf3ce44SJohn Forte case FCT_CMD_SOL_ELS: 3818291a2b48SSukumar Swaminathan 381982527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, 3820291a2b48SSukumar Swaminathan EMLXS_FCT_PKT_ELSCMD_COMPLETE); 3821291a2b48SSukumar Swaminathan 3822fcf3ce44SJohn Forte fct_els = (fct_els_t *)fct_cmd->cmd_specific; 3823fcf3ce44SJohn Forte 3824fcf3ce44SJohn Forte if (fct_els->els_resp_payload) { 382582527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, 3826291a2b48SSukumar Swaminathan pkt->pkt_rsplen, DDI_DMA_SYNC_FORKERNEL); 3827fcf3ce44SJohn Forte 3828fcf3ce44SJohn Forte bcopy((uint8_t *)pkt->pkt_resp, 3829fcf3ce44SJohn Forte (uint8_t *)fct_els->els_resp_payload, 3830fcf3ce44SJohn Forte fct_els->els_resp_size); 3831fcf3ce44SJohn Forte } 3832291a2b48SSukumar Swaminathan 383382527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_IO_DONE); 3834291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3835fcf3ce44SJohn Forte 3836fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 3837fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3838fcf3ce44SJohn Forte "fct_send_cmd_done:1 %p: x%x", 3839fcf3ce44SJohn Forte fct_cmd, fct_cmd->cmd_comp_status); 3840291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 384182527734SSukumar Swaminathan 3842b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 3843b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, pkt->pkt_resp_dma) 3844b3660a96SSukumar Swaminathan != DDI_FM_OK) { 3845b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 3846b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 3847b3660a96SSukumar Swaminathan "emlxs_fct_pkt_comp: hdl=%p", 3848b3660a96SSukumar Swaminathan pkt->pkt_resp_dma); 3849b3660a96SSukumar Swaminathan MODSYM(fct_send_cmd_done) (fct_cmd, FCT_FAILURE, 3850b3660a96SSukumar Swaminathan FCT_IOF_FCA_DONE); 3851b3660a96SSukumar Swaminathan 3852b3660a96SSukumar Swaminathan break; 3853b3660a96SSukumar Swaminathan } 3854b3660a96SSukumar Swaminathan #endif /* FMA_SUPPORT */ 3855b3660a96SSukumar Swaminathan 3856291a2b48SSukumar Swaminathan MODSYM(fct_send_cmd_done) (fct_cmd, FCT_SUCCESS, 3857291a2b48SSukumar Swaminathan FCT_IOF_FCA_DONE); 3858fcf3ce44SJohn Forte 3859fcf3ce44SJohn Forte break; 3860fcf3ce44SJohn Forte 3861fcf3ce44SJohn Forte case FCT_CMD_SOL_CT: 3862291a2b48SSukumar Swaminathan 386382527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, 3864291a2b48SSukumar Swaminathan EMLXS_FCT_PKT_CTCMD_COMPLETE); 3865291a2b48SSukumar Swaminathan 3866fcf3ce44SJohn Forte fct_ct = (fct_sol_ct_t *)fct_cmd->cmd_specific; 3867fcf3ce44SJohn Forte 3868fcf3ce44SJohn Forte if (fct_ct->ct_resp_payload) { 386982527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, 3870291a2b48SSukumar Swaminathan pkt->pkt_rsplen, DDI_DMA_SYNC_FORKERNEL); 3871fcf3ce44SJohn Forte 3872fcf3ce44SJohn Forte bcopy((uint8_t *)pkt->pkt_resp, 3873fcf3ce44SJohn Forte (uint8_t *)fct_ct->ct_resp_payload, 3874fcf3ce44SJohn Forte fct_ct->ct_resp_size); 3875fcf3ce44SJohn Forte } 3876291a2b48SSukumar Swaminathan 387782527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_IO_DONE); 3878291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3879fcf3ce44SJohn Forte 3880fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 3881fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3882fcf3ce44SJohn Forte "fct_send_cmd_done:2 %p: x%x", 3883fcf3ce44SJohn Forte fct_cmd, fct_cmd->cmd_comp_status); 3884291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 388582527734SSukumar Swaminathan 3886b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 3887b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, pkt->pkt_resp_dma) 3888b3660a96SSukumar Swaminathan != DDI_FM_OK) { 3889b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 3890b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 3891b3660a96SSukumar Swaminathan "emlxs_fct_pkt_comp: hdl=%p", 3892b3660a96SSukumar Swaminathan pkt->pkt_resp_dma); 3893b3660a96SSukumar Swaminathan MODSYM(fct_send_cmd_done) (fct_cmd, FCT_FAILURE, 3894b3660a96SSukumar Swaminathan FCT_IOF_FCA_DONE); 3895b3660a96SSukumar Swaminathan 3896b3660a96SSukumar Swaminathan break; 3897b3660a96SSukumar Swaminathan } 3898b3660a96SSukumar Swaminathan #endif /* FMA_SUPPORT */ 3899291a2b48SSukumar Swaminathan MODSYM(fct_send_cmd_done) (fct_cmd, FCT_SUCCESS, 3900291a2b48SSukumar Swaminathan FCT_IOF_FCA_DONE); 390182527734SSukumar Swaminathan 3902fcf3ce44SJohn Forte break; 3903fcf3ce44SJohn Forte 3904fcf3ce44SJohn Forte default: 3905fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3906fcf3ce44SJohn Forte "emlxs_fct_pkt_comp: Invalid cmd type found. type=%x", 3907fcf3ce44SJohn Forte fct_cmd->cmd_type); 3908fcf3ce44SJohn Forte 390982527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_IO_DONE); 391082527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 391182527734SSukumar Swaminathan 391282527734SSukumar Swaminathan break; 3913fcf3ce44SJohn Forte } 3914fcf3ce44SJohn Forte 3915fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 3916fcf3ce44SJohn Forte return; 3917fcf3ce44SJohn Forte 391882527734SSukumar Swaminathan } /* emlxs_fct_pkt_comp() */ 3919fcf3ce44SJohn Forte 3920fcf3ce44SJohn Forte 3921291a2b48SSukumar Swaminathan static void 3922291a2b48SSukumar Swaminathan emlxs_fct_abort_pkt_comp(fc_packet_t *pkt) 3923fcf3ce44SJohn Forte { 392482527734SSukumar Swaminathan #ifdef FCT_API_TRACE_11 3925291a2b48SSukumar Swaminathan emlxs_buf_t *sbp; 3926291a2b48SSukumar Swaminathan IOCBQ *iocbq; 3927291a2b48SSukumar Swaminathan IOCB *iocb; 3928291a2b48SSukumar Swaminathan 3929291a2b48SSukumar Swaminathan sbp = PKT2PRIV(pkt); 3930291a2b48SSukumar Swaminathan iocbq = &sbp->iocbq; 3931291a2b48SSukumar Swaminathan iocb = &iocbq->iocb; 3932291a2b48SSukumar Swaminathan 3933291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3934bce54adfSSukumar Swaminathan "emlxs_fct_abort_pkt_comp: %p: xri=%x status=%x", iocb->ULPCONTEXT, 393582527734SSukumar Swaminathan iocb->ULPCOMMAND, iocb->ULPSTATUS); 3936291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 3937291a2b48SSukumar Swaminathan 3938291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt); 3939291a2b48SSukumar Swaminathan return; 3940291a2b48SSukumar Swaminathan 394182527734SSukumar Swaminathan } /* emlxs_fct_abort_pkt_comp() */ 3942291a2b48SSukumar Swaminathan 3943291a2b48SSukumar Swaminathan 394482527734SSukumar Swaminathan /* COMSTAR ENTER POINT (INDIRECT) */ 3945291a2b48SSukumar Swaminathan static fct_status_t 3946291a2b48SSukumar Swaminathan emlxs_fct_send_els_cmd(fct_cmd_t *fct_cmd) 3947291a2b48SSukumar Swaminathan { 3948291a2b48SSukumar Swaminathan emlxs_port_t *port = 3949291a2b48SSukumar Swaminathan (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 3950fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 3951fcf3ce44SJohn Forte uint32_t did; 3952fcf3ce44SJohn Forte fct_els_t *fct_els; 3953fcf3ce44SJohn Forte fc_packet_t *pkt; 3954fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 395582527734SSukumar Swaminathan fct_status_t rval; 3956fcf3ce44SJohn Forte 3957fcf3ce44SJohn Forte did = fct_cmd->cmd_rportid; 3958fcf3ce44SJohn Forte fct_els = (fct_els_t *)fct_cmd->cmd_specific; 3959fcf3ce44SJohn Forte 3960fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, fct_els->els_req_size, 3961fcf3ce44SJohn Forte fct_els->els_resp_size, 0, KM_NOSLEEP))) { 3962fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 3963fcf3ce44SJohn Forte "emlxs_fct_send_els_cmd: Unable to allocate packet."); 396482527734SSukumar Swaminathan 396582527734SSukumar Swaminathan return (FCT_BUSY); 3966fcf3ce44SJohn Forte } 3967291a2b48SSukumar Swaminathan 396882527734SSukumar Swaminathan cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd, EMLXS_FCT_SEND_ELS_REQ); 3969291a2b48SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 3970291a2b48SSukumar Swaminathan 397182527734SSukumar Swaminathan cmd_sbp->channel = &hba->chan[hba->channel_els]; 3972fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_ELS_REQ; 3973fcf3ce44SJohn Forte 3974fcf3ce44SJohn Forte (void) emlxs_fct_pkt_init(port, fct_cmd, pkt); 3975291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = pkt; 3976fcf3ce44SJohn Forte 3977fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE; 3978fcf3ce44SJohn Forte pkt->pkt_timeout = 3979fcf3ce44SJohn Forte ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov); 3980fcf3ce44SJohn Forte pkt->pkt_comp = emlxs_fct_pkt_comp; 3981fcf3ce44SJohn Forte 3982fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3983fcf3ce44SJohn Forte "emlxs_fct_send_els_cmd: pkt_timeout=%d ratov=%d", 3984fcf3ce44SJohn Forte pkt->pkt_timeout, hba->fc_ratov); 3985fcf3ce44SJohn Forte 3986fcf3ce44SJohn Forte /* Build the fc header */ 398782527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(did); 3988fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_ELS_REQ; 398982527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did); 3990fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 3991fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = 3992fcf3ce44SJohn Forte F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE; 3993fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 3994fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 3995fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 3996fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xFFFF; 3997fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xFFFF; 3998fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 3999fcf3ce44SJohn Forte 4000fcf3ce44SJohn Forte /* Copy the cmd payload */ 4001fcf3ce44SJohn Forte bcopy((uint8_t *)fct_els->els_req_payload, (uint8_t *)pkt->pkt_cmd, 4002fcf3ce44SJohn Forte fct_els->els_req_size); 400382527734SSukumar Swaminathan 4004291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP; 400582527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, EMLXS_FCT_REQ_PENDING); 400682527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 4007fcf3ce44SJohn Forte 4008fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 400982527734SSukumar Swaminathan 4010fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 4011fcf3ce44SJohn Forte "emlxs_fct_send_els_cmd: Unable to send packet."); 4012fcf3ce44SJohn Forte 401382527734SSukumar Swaminathan /* Reacquire ownership of the fct_cmd */ 401482527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, 0); 401582527734SSukumar Swaminathan if (rval) { 401682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 401782527734SSukumar Swaminathan "emlxs_fct_send_els_cmd: " 401882527734SSukumar Swaminathan "Unable to reacquire fct_cmd."); 401982527734SSukumar Swaminathan return (rval); 4020fcf3ce44SJohn Forte } 402182527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 4022fcf3ce44SJohn Forte 402382527734SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED); 402482527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 4025fcf3ce44SJohn Forte 402682527734SSukumar Swaminathan return (FCT_BUSY); 4027fcf3ce44SJohn Forte } 4028fcf3ce44SJohn Forte 4029fcf3ce44SJohn Forte return (FCT_SUCCESS); 4030fcf3ce44SJohn Forte 403182527734SSukumar Swaminathan } /* emlxs_fct_send_els_cmd() */ 4032fcf3ce44SJohn Forte 4033fcf3ce44SJohn Forte 403482527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be held to enter */ 403582527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be released before exiting */ 4036fcf3ce44SJohn Forte static fct_status_t 4037fcf3ce44SJohn Forte emlxs_fct_send_els_rsp(fct_cmd_t *fct_cmd) 4038fcf3ce44SJohn Forte { 4039fcf3ce44SJohn Forte emlxs_port_t *port = 4040fcf3ce44SJohn Forte (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 4041fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 4042fcf3ce44SJohn Forte uint32_t did; 4043fcf3ce44SJohn Forte fct_els_t *fct_els; 4044fcf3ce44SJohn Forte fc_packet_t *pkt; 4045fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 404682527734SSukumar Swaminathan fct_status_t rval; 4047fcf3ce44SJohn Forte 4048fcf3ce44SJohn Forte fct_els = (fct_els_t *)fct_cmd->cmd_specific; 4049fcf3ce44SJohn Forte did = fct_cmd->cmd_rportid; 405082527734SSukumar Swaminathan cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 4051fcf3ce44SJohn Forte 4052291a2b48SSukumar Swaminathan if (!(pkt = emlxs_pkt_alloc(port, fct_els->els_resp_size, 0, 0, 4053291a2b48SSukumar Swaminathan KM_NOSLEEP))) { 4054fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 4055fcf3ce44SJohn Forte "emlxs_fct_send_els_rsp: Unable to allocate packet."); 4056291a2b48SSukumar Swaminathan 4057fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 405882527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 4059fcf3ce44SJohn Forte 406082527734SSukumar Swaminathan return (FCT_FAILURE); 406182527734SSukumar Swaminathan } 4062291a2b48SSukumar Swaminathan 406382527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, EMLXS_FCT_SEND_ELS_RSP); 4064fcf3ce44SJohn Forte 4065fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_ELS_RSP; 4066fcf3ce44SJohn Forte 4067fcf3ce44SJohn Forte (void) emlxs_fct_pkt_init(port, fct_cmd, pkt); 4068291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = pkt; 4069fcf3ce44SJohn Forte 4070fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND; 4071fcf3ce44SJohn Forte pkt->pkt_timeout = 4072fcf3ce44SJohn Forte ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov); 4073fcf3ce44SJohn Forte pkt->pkt_comp = emlxs_fct_pkt_comp; 4074fcf3ce44SJohn Forte 4075fcf3ce44SJohn Forte /* Build the fc header */ 407682527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(did); 4077fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_ELS_RSP; 407882527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did); 4079fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 4080fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = 4081fcf3ce44SJohn Forte F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ; 4082fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 4083fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 4084fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 4085fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = fct_cmd->cmd_oxid; 4086fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = fct_cmd->cmd_rxid; 4087fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 4088fcf3ce44SJohn Forte 4089fcf3ce44SJohn Forte /* Copy the resp payload to pkt_cmd buffer */ 4090fcf3ce44SJohn Forte bcopy((uint8_t *)fct_els->els_resp_payload, (uint8_t *)pkt->pkt_cmd, 4091fcf3ce44SJohn Forte fct_els->els_resp_size); 409282527734SSukumar Swaminathan 4093291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP; 409482527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, EMLXS_FCT_RSP_PENDING); 409582527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 4096fcf3ce44SJohn Forte 4097fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 409882527734SSukumar Swaminathan 4099fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 4100fcf3ce44SJohn Forte "emlxs_fct_send_els_rsp: Unable to send packet."); 4101fcf3ce44SJohn Forte 410282527734SSukumar Swaminathan /* Reacquire ownership of the fct_cmd */ 410382527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, 0); 410482527734SSukumar Swaminathan if (rval) { 410582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 410682527734SSukumar Swaminathan "emlxs_fct_send_els_rsp: " 410782527734SSukumar Swaminathan "Unable to reacquire fct_cmd."); 410882527734SSukumar Swaminathan return (rval); 4109fcf3ce44SJohn Forte } 411082527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 4111291a2b48SSukumar Swaminathan 4112fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 411382527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 4114291a2b48SSukumar Swaminathan 4115fcf3ce44SJohn Forte return (FCT_FAILURE); 4116fcf3ce44SJohn Forte } 4117fcf3ce44SJohn Forte 4118291a2b48SSukumar Swaminathan return (FCT_SUCCESS); 4119fcf3ce44SJohn Forte 412082527734SSukumar Swaminathan } /* emlxs_fct_send_els_rsp() */ 4121fcf3ce44SJohn Forte 4122fcf3ce44SJohn Forte 412382527734SSukumar Swaminathan /* COMSTAR ENTER POINT (INDIRECT) */ 4124fcf3ce44SJohn Forte static fct_status_t 4125fcf3ce44SJohn Forte emlxs_fct_send_ct_cmd(fct_cmd_t *fct_cmd) 4126fcf3ce44SJohn Forte { 4127fcf3ce44SJohn Forte emlxs_port_t *port = 4128fcf3ce44SJohn Forte (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 4129fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 4130fcf3ce44SJohn Forte uint32_t did; 4131fcf3ce44SJohn Forte fct_sol_ct_t *fct_ct; 4132fcf3ce44SJohn Forte fc_packet_t *pkt; 4133fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 413482527734SSukumar Swaminathan fct_status_t rval; 4135fcf3ce44SJohn Forte 4136fcf3ce44SJohn Forte did = fct_cmd->cmd_rportid; 4137fcf3ce44SJohn Forte fct_ct = (fct_sol_ct_t *)fct_cmd->cmd_specific; 4138fcf3ce44SJohn Forte 4139fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, fct_ct->ct_req_size, 4140fcf3ce44SJohn Forte fct_ct->ct_resp_size, 0, KM_NOSLEEP))) { 4141fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 4142fcf3ce44SJohn Forte "emlxs_fct_send_ct_cmd: Unable to allocate packet."); 414382527734SSukumar Swaminathan return (FCT_BUSY); 4144fcf3ce44SJohn Forte } 4145291a2b48SSukumar Swaminathan 414682527734SSukumar Swaminathan cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd, EMLXS_FCT_SEND_CT_REQ); 4147291a2b48SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 4148fcf3ce44SJohn Forte 414982527734SSukumar Swaminathan cmd_sbp->channel = &hba->chan[hba->channel_ct]; 4150fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_CT_REQ; 4151fcf3ce44SJohn Forte 4152fcf3ce44SJohn Forte (void) emlxs_fct_pkt_init(port, fct_cmd, pkt); 4153291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = pkt; 4154fcf3ce44SJohn Forte 4155fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE; 4156fcf3ce44SJohn Forte pkt->pkt_timeout = 4157fcf3ce44SJohn Forte ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov); 4158fcf3ce44SJohn Forte pkt->pkt_comp = emlxs_fct_pkt_comp; 4159fcf3ce44SJohn Forte 4160fcf3ce44SJohn Forte /* Build the fc header */ 416182527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(did); 4162fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_UNSOL_CONTROL; 416382527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did); 4164fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_FC_SERVICES; 4165fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = 4166fcf3ce44SJohn Forte F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE; 4167fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 4168fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 4169fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 4170fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xFFFF; 4171fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xFFFF; 4172fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 4173fcf3ce44SJohn Forte 4174fcf3ce44SJohn Forte /* Copy the cmd payload */ 4175fcf3ce44SJohn Forte bcopy((uint8_t *)fct_ct->ct_req_payload, (uint8_t *)pkt->pkt_cmd, 4176fcf3ce44SJohn Forte fct_ct->ct_req_size); 417782527734SSukumar Swaminathan 4178291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP; 417982527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, EMLXS_FCT_REQ_PENDING); 418082527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 4181fcf3ce44SJohn Forte 4182fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 418382527734SSukumar Swaminathan 4184fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 4185fcf3ce44SJohn Forte "emlxs_fct_send_ct_cmd: Unable to send packet."); 4186fcf3ce44SJohn Forte 418782527734SSukumar Swaminathan /* Reacquire ownership of the fct_cmd */ 418882527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, 0); 418982527734SSukumar Swaminathan if (rval) { 419082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 419182527734SSukumar Swaminathan "emlxs_fct_send_ct_cmd: " 419282527734SSukumar Swaminathan "Unable to reacquire fct_cmd."); 419382527734SSukumar Swaminathan 419482527734SSukumar Swaminathan return (rval); 4195fcf3ce44SJohn Forte } 419682527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 4197fcf3ce44SJohn Forte 419882527734SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED); 419982527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 4200fcf3ce44SJohn Forte 420182527734SSukumar Swaminathan return (FCT_BUSY); 4202fcf3ce44SJohn Forte } 4203fcf3ce44SJohn Forte 4204fcf3ce44SJohn Forte return (FCT_SUCCESS); 4205fcf3ce44SJohn Forte 420682527734SSukumar Swaminathan } /* emlxs_fct_send_ct_cmd() */ 4207fcf3ce44SJohn Forte 4208fcf3ce44SJohn Forte 420982527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be held to enter */ 4210fe199829SSukumar Swaminathan static uint32_t 4211291a2b48SSukumar Swaminathan emlxs_fct_pkt_abort_txq(emlxs_port_t *port, emlxs_buf_t *cmd_sbp) 4212fcf3ce44SJohn Forte { 4213fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 4214fcf3ce44SJohn Forte NODELIST *nlp; 4215291a2b48SSukumar Swaminathan fc_packet_t *pkt; 4216291a2b48SSukumar Swaminathan emlxs_buf_t *sbp; 4217291a2b48SSukumar Swaminathan emlxs_buf_t *iocb_sbp; 421882527734SSukumar Swaminathan uint8_t channelno; 421982527734SSukumar Swaminathan CHANNEL *cp; 4220fcf3ce44SJohn Forte IOCBQ *iocbq; 4221fcf3ce44SJohn Forte IOCBQ *next; 4222fcf3ce44SJohn Forte IOCBQ *prev; 4223fcf3ce44SJohn Forte uint32_t found; 4224291a2b48SSukumar Swaminathan uint32_t pkt_flags; 4225fcf3ce44SJohn Forte 4226291a2b48SSukumar Swaminathan /* Check the transmit queue */ 422782527734SSukumar Swaminathan mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 4228fcf3ce44SJohn Forte 4229291a2b48SSukumar Swaminathan /* The IOCB could point to a cmd_sbp (no packet) or a sbp (packet) */ 4230291a2b48SSukumar Swaminathan pkt = cmd_sbp->fct_pkt; 4231291a2b48SSukumar Swaminathan if (pkt) { 4232291a2b48SSukumar Swaminathan sbp = PKT2PRIV(pkt); 4233291a2b48SSukumar Swaminathan if (sbp == NULL) { 4234291a2b48SSukumar Swaminathan goto done; 4235291a2b48SSukumar Swaminathan } 4236291a2b48SSukumar Swaminathan iocb_sbp = sbp; 4237291a2b48SSukumar Swaminathan iocbq = &sbp->iocbq; 4238291a2b48SSukumar Swaminathan pkt_flags = sbp->pkt_flags; 4239291a2b48SSukumar Swaminathan } else { 4240291a2b48SSukumar Swaminathan sbp = NULL; 4241291a2b48SSukumar Swaminathan iocb_sbp = cmd_sbp; 4242291a2b48SSukumar Swaminathan iocbq = &cmd_sbp->iocbq; 4243291a2b48SSukumar Swaminathan pkt_flags = cmd_sbp->pkt_flags; 4244fcf3ce44SJohn Forte } 4245fcf3ce44SJohn Forte 4246291a2b48SSukumar Swaminathan nlp = (NODELIST *)cmd_sbp->node; 424782527734SSukumar Swaminathan cp = (CHANNEL *)cmd_sbp->channel; 424882527734SSukumar Swaminathan channelno = (cp) ? cp->channelno : 0; 4249fcf3ce44SJohn Forte 4250291a2b48SSukumar Swaminathan if (pkt_flags & PACKET_IN_TXQ) { 4251fcf3ce44SJohn Forte /* Find it on the queue */ 4252fcf3ce44SJohn Forte found = 0; 4253fcf3ce44SJohn Forte if (iocbq->flag & IOCB_PRIORITY) { 4254fcf3ce44SJohn Forte /* Search the priority queue */ 4255fcf3ce44SJohn Forte prev = NULL; 425682527734SSukumar Swaminathan next = (IOCBQ *)nlp->nlp_ptx[channelno].q_first; 4257fcf3ce44SJohn Forte 4258fcf3ce44SJohn Forte while (next) { 4259fcf3ce44SJohn Forte if (next == iocbq) { 4260fcf3ce44SJohn Forte /* Remove it */ 4261fcf3ce44SJohn Forte if (prev) { 4262fcf3ce44SJohn Forte prev->next = iocbq->next; 4263fcf3ce44SJohn Forte } 4264291a2b48SSukumar Swaminathan 426582527734SSukumar Swaminathan if (nlp->nlp_ptx[channelno].q_last == 4266fcf3ce44SJohn Forte (void *)iocbq) { 426782527734SSukumar Swaminathan nlp->nlp_ptx[channelno].q_last = 4268fcf3ce44SJohn Forte (void *)prev; 4269fcf3ce44SJohn Forte } 4270291a2b48SSukumar Swaminathan 427182527734SSukumar Swaminathan if (nlp->nlp_ptx[channelno].q_first == 4272fcf3ce44SJohn Forte (void *)iocbq) { 427382527734SSukumar Swaminathan nlp->nlp_ptx[channelno]. 427482527734SSukumar Swaminathan q_first = 4275fcf3ce44SJohn Forte (void *)iocbq->next; 4276fcf3ce44SJohn Forte } 4277291a2b48SSukumar Swaminathan 427882527734SSukumar Swaminathan nlp->nlp_ptx[channelno].q_cnt--; 4279fcf3ce44SJohn Forte iocbq->next = NULL; 4280fcf3ce44SJohn Forte found = 1; 4281fcf3ce44SJohn Forte break; 4282fcf3ce44SJohn Forte } 4283291a2b48SSukumar Swaminathan 4284fcf3ce44SJohn Forte prev = next; 4285fcf3ce44SJohn Forte next = next->next; 4286fcf3ce44SJohn Forte } 4287fcf3ce44SJohn Forte } else { 4288fcf3ce44SJohn Forte /* Search the normal queue */ 4289fcf3ce44SJohn Forte prev = NULL; 429082527734SSukumar Swaminathan next = (IOCBQ *)nlp->nlp_tx[channelno].q_first; 4291fcf3ce44SJohn Forte 4292fcf3ce44SJohn Forte while (next) { 4293fcf3ce44SJohn Forte if (next == iocbq) { 4294fcf3ce44SJohn Forte /* Remove it */ 4295fcf3ce44SJohn Forte if (prev) { 4296fcf3ce44SJohn Forte prev->next = iocbq->next; 4297fcf3ce44SJohn Forte } 4298291a2b48SSukumar Swaminathan 429982527734SSukumar Swaminathan if (nlp->nlp_tx[channelno].q_last == 4300fcf3ce44SJohn Forte (void *)iocbq) { 430182527734SSukumar Swaminathan nlp->nlp_tx[channelno].q_last = 4302fcf3ce44SJohn Forte (void *)prev; 4303fcf3ce44SJohn Forte } 4304291a2b48SSukumar Swaminathan 430582527734SSukumar Swaminathan if (nlp->nlp_tx[channelno].q_first == 4306fcf3ce44SJohn Forte (void *)iocbq) { 430782527734SSukumar Swaminathan nlp->nlp_tx[channelno].q_first = 4308fcf3ce44SJohn Forte (void *)iocbq->next; 4309fcf3ce44SJohn Forte } 4310291a2b48SSukumar Swaminathan 431182527734SSukumar Swaminathan nlp->nlp_tx[channelno].q_cnt--; 4312fcf3ce44SJohn Forte iocbq->next = NULL; 4313fcf3ce44SJohn Forte found = 1; 4314fcf3ce44SJohn Forte break; 4315fcf3ce44SJohn Forte } 4316291a2b48SSukumar Swaminathan 4317fcf3ce44SJohn Forte prev = next; 4318fcf3ce44SJohn Forte next = (IOCBQ *)next->next; 4319fcf3ce44SJohn Forte } 4320fcf3ce44SJohn Forte } 4321fcf3ce44SJohn Forte 4322fcf3ce44SJohn Forte if (!found) { 4323fcf3ce44SJohn Forte goto done; 4324fcf3ce44SJohn Forte } 4325291a2b48SSukumar Swaminathan 4326fcf3ce44SJohn Forte /* Check if node still needs servicing */ 432782527734SSukumar Swaminathan if ((nlp->nlp_ptx[channelno].q_first) || 432882527734SSukumar Swaminathan (nlp->nlp_tx[channelno].q_first && 432982527734SSukumar Swaminathan !(nlp->nlp_flag[channelno] & NLP_CLOSED))) { 4330fcf3ce44SJohn Forte 4331fcf3ce44SJohn Forte /* 4332291a2b48SSukumar Swaminathan * If this is the base node, don't shift the pointers 4333fcf3ce44SJohn Forte */ 4334fcf3ce44SJohn Forte /* We want to drain the base node before moving on */ 4335fcf3ce44SJohn Forte if (!nlp->nlp_base) { 433682527734SSukumar Swaminathan /* Shift channel queue pointers to next node */ 433782527734SSukumar Swaminathan cp->nodeq.q_last = (void *)nlp; 433882527734SSukumar Swaminathan cp->nodeq.q_first = nlp->nlp_next[channelno]; 4339fcf3ce44SJohn Forte } 4340fcf3ce44SJohn Forte } else { 434182527734SSukumar Swaminathan /* Remove node from channel queue */ 4342fcf3ce44SJohn Forte 4343fcf3ce44SJohn Forte /* If this is the last node on list */ 434482527734SSukumar Swaminathan if (cp->nodeq.q_last == (void *)nlp) { 434582527734SSukumar Swaminathan cp->nodeq.q_last = NULL; 434682527734SSukumar Swaminathan cp->nodeq.q_first = NULL; 434782527734SSukumar Swaminathan cp->nodeq.q_cnt = 0; 4348fcf3ce44SJohn Forte } else { 4349fcf3ce44SJohn Forte /* Remove node from head */ 435082527734SSukumar Swaminathan cp->nodeq.q_first = nlp->nlp_next[channelno]; 435182527734SSukumar Swaminathan ((NODELIST *)cp->nodeq.q_last)-> 435282527734SSukumar Swaminathan nlp_next[channelno] = cp->nodeq.q_first; 435382527734SSukumar Swaminathan cp->nodeq.q_cnt--; 4354fcf3ce44SJohn Forte } 4355fcf3ce44SJohn Forte 4356fcf3ce44SJohn Forte /* Clear node */ 435782527734SSukumar Swaminathan nlp->nlp_next[channelno] = NULL; 4358fcf3ce44SJohn Forte } 4359fcf3ce44SJohn Forte 436082527734SSukumar Swaminathan /* The IOCB points to iocb_sbp (no packet) or a sbp (packet) */ 436182527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 4362*a9800bebSGarrett D'Amore emlxs_sli4_free_xri(hba, iocb_sbp, iocb_sbp->xrip, 1); 436382527734SSukumar Swaminathan } else { 436482527734SSukumar Swaminathan (void) emlxs_unregister_pkt(cp, iocb_sbp->iotag, 0); 4365fcf3ce44SJohn Forte } 4366fcf3ce44SJohn Forte 436782527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 4368fcf3ce44SJohn Forte 4369291a2b48SSukumar Swaminathan if (pkt) { 4370291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt); 4371291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = NULL; 4372fcf3ce44SJohn Forte } 437382527734SSukumar Swaminathan return (1); 4374fcf3ce44SJohn Forte } 4375291a2b48SSukumar Swaminathan done: 437682527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 437782527734SSukumar Swaminathan return (0); 437882527734SSukumar Swaminathan 437982527734SSukumar Swaminathan } /* emlxs_fct_pkt_abort_txq() */ 4380fcf3ce44SJohn Forte 4381fcf3ce44SJohn Forte 438282527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 4383291a2b48SSukumar Swaminathan /* FCT_NOT_FOUND & FCT_ABORT_SUCCESS indicates IO is done */ 4384291a2b48SSukumar Swaminathan /* FCT_SUCCESS indicates abort will occur asyncronously */ 4385291a2b48SSukumar Swaminathan static fct_status_t 4386291a2b48SSukumar Swaminathan emlxs_fct_abort(fct_local_port_t *fct_port, fct_cmd_t *fct_cmd, 4387291a2b48SSukumar Swaminathan uint32_t flags) 4388291a2b48SSukumar Swaminathan { 4389291a2b48SSukumar Swaminathan emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 4390291a2b48SSukumar Swaminathan emlxs_hba_t *hba = HBA; 4391291a2b48SSukumar Swaminathan emlxs_buf_t *cmd_sbp; 439282527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp2; 439382527734SSukumar Swaminathan emlxs_buf_t *prev; 4394291a2b48SSukumar Swaminathan fc_packet_t *pkt; 4395291a2b48SSukumar Swaminathan emlxs_buf_t *sbp = NULL; 439682527734SSukumar Swaminathan kmutex_t *fct_mtx; 439782527734SSukumar Swaminathan uint32_t fct_state; 439882527734SSukumar Swaminathan 439982527734SSukumar Swaminathan cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 440082527734SSukumar Swaminathan fct_mtx = &cmd_sbp->fct_mtx; 4401fcf3ce44SJohn Forte 4402291a2b48SSukumar Swaminathan top: 440382527734SSukumar Swaminathan 4404291a2b48SSukumar Swaminathan /* Sanity check */ 4405291a2b48SSukumar Swaminathan if ((fct_cmd->cmd_oxid == 0) && (fct_cmd->cmd_rxid == 0)) { 4406291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 440782527734SSukumar Swaminathan "emlxs_fct_abort: Bad fct_cmd=%p.", fct_cmd); 4408fcf3ce44SJohn Forte 4409291a2b48SSukumar Swaminathan return (FCT_NOT_FOUND); 4410291a2b48SSukumar Swaminathan } 4411fcf3ce44SJohn Forte 4412291a2b48SSukumar Swaminathan if (!(cmd_sbp->pkt_flags & PACKET_VALID)) { 4413291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 441482527734SSukumar Swaminathan "emlxs_fct_abort: Pkt invalid. cmd_sbp=%p", 441582527734SSukumar Swaminathan cmd_sbp); 4416fcf3ce44SJohn Forte 4417291a2b48SSukumar Swaminathan return (FCT_NOT_FOUND); 4418fcf3ce44SJohn Forte } 4419fcf3ce44SJohn Forte 442082527734SSukumar Swaminathan if (mutex_tryenter(fct_mtx) == 0) { 4421fcf3ce44SJohn Forte /* 4422291a2b48SSukumar Swaminathan * This code path handles a race condition if 4423291a2b48SSukumar Swaminathan * an IO completes, in emlxs_fct_handle_fcp_event(), 4424291a2b48SSukumar Swaminathan * and we get an abort at the same time. 4425fcf3ce44SJohn Forte */ 4426291a2b48SSukumar Swaminathan delay(drv_usectohz(100000)); /* 100 msec */ 4427291a2b48SSukumar Swaminathan goto top; 4428fcf3ce44SJohn Forte } 4429291a2b48SSukumar Swaminathan /* At this point, we have entered the mutex */ 4430fcf3ce44SJohn Forte 443182527734SSukumar Swaminathan /* Sanity check */ 443282527734SSukumar Swaminathan if ((fct_cmd->cmd_oxid == 0) && (fct_cmd->cmd_rxid == 0)) { 4433291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 443482527734SSukumar Swaminathan "emlxs_fct_abort: Bad fct_cmd=%p.", fct_cmd); 4435fcf3ce44SJohn Forte 443682527734SSukumar Swaminathan mutex_exit(fct_mtx); 4437291a2b48SSukumar Swaminathan return (FCT_NOT_FOUND); 4438fcf3ce44SJohn Forte } 4439fcf3ce44SJohn Forte 444082527734SSukumar Swaminathan if (!(cmd_sbp->pkt_flags & PACKET_VALID)) { 444182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 444282527734SSukumar Swaminathan "emlxs_fct_abort: Pkt invalid. cmd_sbp=%p", 444382527734SSukumar Swaminathan cmd_sbp); 444482527734SSukumar Swaminathan 444582527734SSukumar Swaminathan mutex_exit(fct_mtx); 444682527734SSukumar Swaminathan return (FCT_NOT_FOUND); 4447fcf3ce44SJohn Forte } 4448fcf3ce44SJohn Forte 4449291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4450fe199829SSukumar Swaminathan "emlxs_fct_abort: hbastate=%x. " 4451fe199829SSukumar Swaminathan "xid=%x,%x cmd_sbp=%p fctstate=%d flags=%x,%x,%x", 4452fe199829SSukumar Swaminathan hba->state, fct_cmd->cmd_oxid, fct_cmd->cmd_rxid, cmd_sbp, 4453fe199829SSukumar Swaminathan cmd_sbp->fct_state, flags, cmd_sbp->fct_flags, cmd_sbp->pkt_flags); 4454291a2b48SSukumar Swaminathan 4455291a2b48SSukumar Swaminathan if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT_INP) { 445682527734SSukumar Swaminathan EMLXS_SLI_ISSUE_IOCB_CMD(hba, cmd_sbp->channel, 0); 445782527734SSukumar Swaminathan 4458291a2b48SSukumar Swaminathan /* If Abort is already in progress */ 445982527734SSukumar Swaminathan mutex_exit(fct_mtx); 446082527734SSukumar Swaminathan return (FCT_SUCCESS); 446182527734SSukumar Swaminathan } 446282527734SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_ABORT_INP; 446382527734SSukumar Swaminathan 446482527734SSukumar Swaminathan if (flags & FCT_IOF_FORCE_FCA_DONE) { 446582527734SSukumar Swaminathan fct_cmd->cmd_handle = 0; 4466291a2b48SSukumar Swaminathan } 4467fcf3ce44SJohn Forte 4468291a2b48SSukumar Swaminathan TGTPORTSTAT.FctAbortSent++; 4469fcf3ce44SJohn Forte 447082527734SSukumar Swaminathan switch (cmd_sbp->fct_state) { 447182527734SSukumar Swaminathan /* These are currently owned by COMSTAR. */ 447282527734SSukumar Swaminathan /* They were last processed by emlxs_fct_cmd_post() */ 4473fe199829SSukumar Swaminathan /* We have NO exchange resources associated with this IO. */ 447482527734SSukumar Swaminathan case EMLXS_FCT_OWNED: 4475fe199829SSukumar Swaminathan goto abort_done; 447682527734SSukumar Swaminathan 447782527734SSukumar Swaminathan /* These are on the unsol waitQ in the driver */ 447882527734SSukumar Swaminathan case EMLXS_FCT_CMD_WAITQ: 447982527734SSukumar Swaminathan /* Find and remove it */ 448082527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 448182527734SSukumar Swaminathan cmd_sbp2 = port->fct_wait_head; 448282527734SSukumar Swaminathan prev = NULL; 448382527734SSukumar Swaminathan while (cmd_sbp2) { 448482527734SSukumar Swaminathan if (cmd_sbp2 == cmd_sbp) { 448582527734SSukumar Swaminathan /* Remove it */ 448682527734SSukumar Swaminathan if (prev) { 448782527734SSukumar Swaminathan prev->next = cmd_sbp2->next; 448882527734SSukumar Swaminathan } 448982527734SSukumar Swaminathan 449082527734SSukumar Swaminathan if (port->fct_wait_head == cmd_sbp2) { 449182527734SSukumar Swaminathan port->fct_wait_head = cmd_sbp2->next; 449282527734SSukumar Swaminathan } 449382527734SSukumar Swaminathan 449482527734SSukumar Swaminathan if (port->fct_wait_tail == cmd_sbp2) { 449582527734SSukumar Swaminathan port->fct_wait_tail = prev; 449682527734SSukumar Swaminathan } 449782527734SSukumar Swaminathan 449882527734SSukumar Swaminathan cmd_sbp2->next = NULL; 449982527734SSukumar Swaminathan break; 450082527734SSukumar Swaminathan } 450182527734SSukumar Swaminathan prev = cmd_sbp2; 450282527734SSukumar Swaminathan cmd_sbp2 = cmd_sbp2->next; 450382527734SSukumar Swaminathan } 450482527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 450582527734SSukumar Swaminathan 4506fe199829SSukumar Swaminathan /*FALLTHROUGH*/ 4507fe199829SSukumar Swaminathan 4508fe199829SSukumar Swaminathan /* These are currently owned by COMSTAR. */ 4509fe199829SSukumar Swaminathan /* They were last processed by emlxs_fct_cmd_post() */ 4510fe199829SSukumar Swaminathan /* We have residual exchange resources associated with this IO */ 4511fe199829SSukumar Swaminathan case EMLXS_FCT_CMD_POSTED: 4512fe199829SSukumar Swaminathan switch (fct_cmd->cmd_type) { 4513fe199829SSukumar Swaminathan case FCT_CMD_FCP_XCHG: /* Unsol */ 4514fe199829SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--; 4515fe199829SSukumar Swaminathan emlxs_abort_fct_exchange(hba, port, fct_cmd->cmd_rxid); 4516fe199829SSukumar Swaminathan break; 4517fe199829SSukumar Swaminathan 4518fe199829SSukumar Swaminathan case FCT_CMD_RCVD_ELS: /* Unsol */ 4519fe199829SSukumar Swaminathan emlxs_abort_els_exchange(hba, port, fct_cmd->cmd_rxid); 4520fe199829SSukumar Swaminathan break; 4521fe199829SSukumar Swaminathan } 4522fe199829SSukumar Swaminathan 4523fe199829SSukumar Swaminathan goto abort_done; 452482527734SSukumar Swaminathan 452582527734SSukumar Swaminathan /* These are active in the driver */ 452682527734SSukumar Swaminathan /* They were last processed by emlxs_fct_cmd_release() */ 4527291a2b48SSukumar Swaminathan case EMLXS_FCT_RSP_PENDING: 4528291a2b48SSukumar Swaminathan case EMLXS_FCT_REQ_PENDING: 4529291a2b48SSukumar Swaminathan case EMLXS_FCT_REG_PENDING: 4530291a2b48SSukumar Swaminathan case EMLXS_FCT_DATA_PENDING: 4531291a2b48SSukumar Swaminathan case EMLXS_FCT_STATUS_PENDING: 453282527734SSukumar Swaminathan 453382527734SSukumar Swaminathan /* Abort anything pending */ 4534291a2b48SSukumar Swaminathan if (emlxs_fct_pkt_abort_txq(port, cmd_sbp)) { 4535fcf3ce44SJohn Forte 4536291a2b48SSukumar Swaminathan if (fct_cmd->cmd_type == FCT_CMD_FCP_XCHG) { 4537291a2b48SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--; 4538fcf3ce44SJohn Forte } 453982527734SSukumar Swaminathan 4540fe199829SSukumar Swaminathan goto abort_done; 4541291a2b48SSukumar Swaminathan } 4542fcf3ce44SJohn Forte 454382527734SSukumar Swaminathan /* If we're not online, then all IO will be flushed anyway */ 4544291a2b48SSukumar Swaminathan if (!(hba->flag & FC_ONLINE_MODE)) { 454582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 454682527734SSukumar Swaminathan "emlxs_fct_abort: Not online. fct_cmd=%p.", 454782527734SSukumar Swaminathan fct_cmd); 4548291a2b48SSukumar Swaminathan 454982527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, 0); 455082527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 455182527734SSukumar Swaminathan 455282527734SSukumar Swaminathan /* The cmd will be aborted on the */ 455382527734SSukumar Swaminathan /* next emlxs_fct_cmd_acquire */ 455482527734SSukumar Swaminathan /* because EMLXS_FCT_ABORT_INP is set. */ 455582527734SSukumar Swaminathan break; 4556fcf3ce44SJohn Forte } 4557fcf3ce44SJohn Forte 455882527734SSukumar Swaminathan /* Try to send abort request */ 4559291a2b48SSukumar Swaminathan if (!(pkt = emlxs_pkt_alloc(port, 0, 0, 0, KM_NOSLEEP))) { 4560291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 456182527734SSukumar Swaminathan "emlxs_fct_abort: Unable to allocate packet. " 456282527734SSukumar Swaminathan "fct_cmd=%p", 456382527734SSukumar Swaminathan fct_cmd); 456482527734SSukumar Swaminathan 456582527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, 0); 456682527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 456782527734SSukumar Swaminathan 456882527734SSukumar Swaminathan /* The cmd will be aborted on the */ 456982527734SSukumar Swaminathan /* next emlxs_fct_cmd_acquire anyway */ 457082527734SSukumar Swaminathan /* because EMLXS_FCT_ABORT_INP is set. */ 457182527734SSukumar Swaminathan break; 4572fcf3ce44SJohn Forte } 4573fcf3ce44SJohn Forte 4574291a2b48SSukumar Swaminathan sbp = emlxs_fct_pkt_init(port, fct_cmd, pkt); 4575291a2b48SSukumar Swaminathan 4576291a2b48SSukumar Swaminathan pkt->pkt_tran_type = FC_PKT_OUTBOUND; 4577291a2b48SSukumar Swaminathan pkt->pkt_timeout = 4578291a2b48SSukumar Swaminathan ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov); 4579291a2b48SSukumar Swaminathan pkt->pkt_comp = emlxs_fct_abort_pkt_comp; 4580291a2b48SSukumar Swaminathan 4581291a2b48SSukumar Swaminathan /* Build the fc header */ 458282527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(fct_cmd->cmd_rportid); 4583291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.r_ctl = R_CTL_STATUS; 458482527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did); 4585291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.type = FC_TYPE_BASIC_LS; 4586291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.f_ctl = 4587291a2b48SSukumar Swaminathan (F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ); 4588291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.seq_id = 0; 4589291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.df_ctl = 0; 4590291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.seq_cnt = 0; 4591291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.ox_id = fct_cmd->cmd_oxid; 4592291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id = fct_cmd->cmd_rxid; 4593291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.ro = 0; 4594291a2b48SSukumar Swaminathan 4595291a2b48SSukumar Swaminathan cmd_sbp->fct_cmd = fct_cmd; 4596291a2b48SSukumar Swaminathan cmd_sbp->abort_attempts++; 4597fcf3ce44SJohn Forte 4598291a2b48SSukumar Swaminathan /* Now disassociate the sbp / pkt from the fct_cmd */ 4599291a2b48SSukumar Swaminathan sbp->fct_cmd = NULL; 4600fcf3ce44SJohn Forte 460182527734SSukumar Swaminathan if (hba->state >= FC_LINK_UP) { 4602291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4603291a2b48SSukumar Swaminathan "emlxs_fct_abort: ABORT: %p xri x%x", 4604291a2b48SSukumar Swaminathan fct_cmd, fct_cmd->cmd_rxid); 4605fcf3ce44SJohn Forte 460682527734SSukumar Swaminathan fct_state = EMLXS_FCT_ABORT_PENDING; 460782527734SSukumar Swaminathan 460882527734SSukumar Swaminathan } else { 4609291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4610291a2b48SSukumar Swaminathan "emlxs_fct_abort: CLOSE: %p xri x%x", 4611291a2b48SSukumar Swaminathan fct_cmd, fct_cmd->cmd_rxid); 4612fcf3ce44SJohn Forte 461382527734SSukumar Swaminathan fct_state = EMLXS_FCT_CLOSE_PENDING; 4614291a2b48SSukumar Swaminathan } 4615fcf3ce44SJohn Forte 461682527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, fct_state); 461782527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 461882527734SSukumar Swaminathan 4619291a2b48SSukumar Swaminathan if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 4620291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 462182527734SSukumar Swaminathan "emlxs_fct_abort: Unable to send abort packet."); 4622fcf3ce44SJohn Forte 4623291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt); 4624fcf3ce44SJohn Forte 462582527734SSukumar Swaminathan /* The cmd will be aborted on the */ 462682527734SSukumar Swaminathan /* next emlxs_fct_cmd_acquire anyway */ 462782527734SSukumar Swaminathan /* because EMLXS_FCT_ABORT_INP is set. */ 4628291a2b48SSukumar Swaminathan } 462982527734SSukumar Swaminathan 4630291a2b48SSukumar Swaminathan break; 4631fcf3ce44SJohn Forte 4632291a2b48SSukumar Swaminathan default: 463382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 463482527734SSukumar Swaminathan "emlxs_fct_abort: Unexpected fct_state. " 463582527734SSukumar Swaminathan "fct_cmd=%p state=%x", 463682527734SSukumar Swaminathan fct_cmd, cmd_sbp->fct_state); 463782527734SSukumar Swaminathan 463882527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, 0); 463982527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 464082527734SSukumar Swaminathan 464182527734SSukumar Swaminathan /* The cmd will be aborted on the */ 464282527734SSukumar Swaminathan /* next emlxs_fct_cmd_acquire anyway */ 464382527734SSukumar Swaminathan /* because EMLXS_FCT_ABORT_INP is set. */ 4644fcf3ce44SJohn Forte 4645291a2b48SSukumar Swaminathan } /* switch */ 4646fcf3ce44SJohn Forte 464782527734SSukumar Swaminathan return (FCT_SUCCESS); 4648fcf3ce44SJohn Forte 4649fe199829SSukumar Swaminathan abort_done: 465082527734SSukumar Swaminathan 465182527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, 465282527734SSukumar Swaminathan EMLXS_FCT_ABORT_DONE); 465382527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 465482527734SSukumar Swaminathan 465582527734SSukumar Swaminathan return (FCT_ABORT_SUCCESS); 465682527734SSukumar Swaminathan 465782527734SSukumar Swaminathan } /* emlxs_fct_abort() */ 4658fcf3ce44SJohn Forte 4659fcf3ce44SJohn Forte 4660fcf3ce44SJohn Forte extern void 4661fcf3ce44SJohn Forte emlxs_fct_link_up(emlxs_port_t *port) 4662fcf3ce44SJohn Forte { 4663fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 4664fcf3ce44SJohn Forte 4665fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 4666fcf3ce44SJohn Forte 4667fcf3ce44SJohn Forte if (port->fct_port && 4668fcf3ce44SJohn Forte (port->fct_flags & FCT_STATE_PORT_ONLINE) && 4669fcf3ce44SJohn Forte !(port->fct_flags & FCT_STATE_LINK_UP)) { 4670fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4671fcf3ce44SJohn Forte "emlxs_fct_link_up event."); 4672fcf3ce44SJohn Forte 4673e2ca2865SSukumar Swaminathan port->fct_flags &= ~FCT_STATE_LINK_UP_ACKED; 4674fcf3ce44SJohn Forte port->fct_flags |= FCT_STATE_LINK_UP; 4675fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 4676fcf3ce44SJohn Forte 4677fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 4678fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 4679fcf3ce44SJohn Forte "fct_handle_event LINK_UP"); 4680291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 4681291a2b48SSukumar Swaminathan MODSYM(fct_handle_event) (port->fct_port, FCT_EVENT_LINK_UP, 4682291a2b48SSukumar Swaminathan 0, 0); 4683fcf3ce44SJohn Forte } else { 4684fcf3ce44SJohn Forte if (!hba->ini_mode && 4685fcf3ce44SJohn Forte !(port->fct_flags & FCT_STATE_PORT_ONLINE)) { 4686fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 4687fcf3ce44SJohn Forte 4688fcf3ce44SJohn Forte /* Take link down and hold it down */ 468982527734SSukumar Swaminathan (void) emlxs_reset_link(hba, 0, 1); 4690fcf3ce44SJohn Forte } else { 4691fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 4692fcf3ce44SJohn Forte } 4693fcf3ce44SJohn Forte } 4694fcf3ce44SJohn Forte 4695fcf3ce44SJohn Forte return; 4696fcf3ce44SJohn Forte 469782527734SSukumar Swaminathan } /* emlxs_fct_link_up() */ 4698291a2b48SSukumar Swaminathan 4699fcf3ce44SJohn Forte 4700fcf3ce44SJohn Forte extern void 4701fcf3ce44SJohn Forte emlxs_fct_link_down(emlxs_port_t *port) 4702fcf3ce44SJohn Forte { 4703fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 4704fcf3ce44SJohn Forte 4705fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 4706fcf3ce44SJohn Forte 4707fcf3ce44SJohn Forte if (port->fct_port && 4708fcf3ce44SJohn Forte (port->fct_flags & FCT_STATE_PORT_ONLINE) && 4709fcf3ce44SJohn Forte (port->fct_flags & FCT_STATE_LINK_UP)) { 4710fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4711fcf3ce44SJohn Forte "emlxs_fct_link_down event."); 4712fcf3ce44SJohn Forte 4713e2ca2865SSukumar Swaminathan port->fct_flags &= ~FCT_STATE_LINK_UP_ACKED; 4714fcf3ce44SJohn Forte port->fct_flags &= ~FCT_STATE_LINK_UP; 4715fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 4716fcf3ce44SJohn Forte 4717fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 4718fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 4719fcf3ce44SJohn Forte "fct_handle_event LINK_DOWN"); 4720291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 472182527734SSukumar Swaminathan 4722291a2b48SSukumar Swaminathan MODSYM(fct_handle_event) (port->fct_port, FCT_EVENT_LINK_DOWN, 4723291a2b48SSukumar Swaminathan 0, 0); 4724fcf3ce44SJohn Forte } else { 4725fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 4726fcf3ce44SJohn Forte } 4727fcf3ce44SJohn Forte 4728fcf3ce44SJohn Forte return; 4729fcf3ce44SJohn Forte 473082527734SSukumar Swaminathan } /* emlxs_fct_link_down() */ 4731fcf3ce44SJohn Forte 4732fcf3ce44SJohn Forte 4733291a2b48SSukumar Swaminathan /* DMA FUNCTIONS */ 4734fcf3ce44SJohn Forte 4735fcf3ce44SJohn Forte fct_status_t 4736fcf3ce44SJohn Forte emlxs_fct_dmem_init(emlxs_port_t *port) 4737fcf3ce44SJohn Forte { 4738fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 4739fcf3ce44SJohn Forte emlxs_fct_dmem_bucket_t *p; 4740fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *bctl; 4741fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *bc; 4742fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *prev; 4743fcf3ce44SJohn Forte int32_t j; 4744fcf3ce44SJohn Forte int32_t i; 4745fcf3ce44SJohn Forte uint32_t total_mem; 4746fcf3ce44SJohn Forte uint8_t *addr; 4747fcf3ce44SJohn Forte uint8_t *host_addr; 4748fcf3ce44SJohn Forte uint64_t dev_addr; 4749fcf3ce44SJohn Forte ddi_dma_cookie_t cookie; 4750fcf3ce44SJohn Forte uint32_t ncookie; 4751fcf3ce44SJohn Forte uint32_t bsize; 4752fcf3ce44SJohn Forte size_t len; 4753fcf3ce44SJohn Forte char buf[64]; 4754fcf3ce44SJohn Forte ddi_device_acc_attr_t acc; 4755fcf3ce44SJohn Forte 4756fcf3ce44SJohn Forte bzero(&acc, sizeof (acc)); 4757fcf3ce44SJohn Forte acc.devacc_attr_version = DDI_DEVICE_ATTR_V0; 4758fcf3ce44SJohn Forte acc.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC; 4759fcf3ce44SJohn Forte acc.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 4760fcf3ce44SJohn Forte 4761fcf3ce44SJohn Forte p = port->dmem_bucket; 4762fcf3ce44SJohn Forte for (i = 0; i < FCT_MAX_BUCKETS; i++, p++) { 4763fcf3ce44SJohn Forte if (!p->dmem_nbufs) { 4764fcf3ce44SJohn Forte continue; 4765fcf3ce44SJohn Forte } 4766291a2b48SSukumar Swaminathan 4767fcf3ce44SJohn Forte bctl = (emlxs_fct_dmem_bctl_t *)kmem_zalloc(p->dmem_nbufs * 476882527734SSukumar Swaminathan sizeof (emlxs_fct_dmem_bctl_t), KM_NOSLEEP); 4769fcf3ce44SJohn Forte 4770fcf3ce44SJohn Forte if (bctl == NULL) { 4771fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4772fcf3ce44SJohn Forte "emlxs_fct_dmem_init: Unable to allocate bctl."); 4773fcf3ce44SJohn Forte goto alloc_bctl_failed; 4774fcf3ce44SJohn Forte } 4775291a2b48SSukumar Swaminathan 4776fcf3ce44SJohn Forte p->dmem_bctls_mem = bctl; 4777fcf3ce44SJohn Forte 477862379b58SSukumar Swaminathan if (ddi_dma_alloc_handle(hba->dip, &hba->dma_attr_1sg, 4779fcf3ce44SJohn Forte DDI_DMA_SLEEP, 0, &p->dmem_dma_handle) != DDI_SUCCESS) { 4780fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4781fcf3ce44SJohn Forte "emlxs_fct_dmem_init: Unable to allocate handle."); 4782fcf3ce44SJohn Forte goto alloc_handle_failed; 4783fcf3ce44SJohn Forte } 4784fcf3ce44SJohn Forte 4785fcf3ce44SJohn Forte total_mem = p->dmem_buf_size * p->dmem_nbufs; 4786fcf3ce44SJohn Forte 4787fcf3ce44SJohn Forte if (ddi_dma_mem_alloc(p->dmem_dma_handle, total_mem, &acc, 478882527734SSukumar Swaminathan DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, 0, 4789291a2b48SSukumar Swaminathan (caddr_t *)&addr, &len, 4790291a2b48SSukumar Swaminathan &p->dmem_acc_handle) != DDI_SUCCESS) { 4791fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4792fcf3ce44SJohn Forte "emlxs_fct_dmem_init: Unable to allocate memory."); 4793fcf3ce44SJohn Forte goto mem_alloc_failed; 4794fcf3ce44SJohn Forte } 4795fcf3ce44SJohn Forte 4796fcf3ce44SJohn Forte if (ddi_dma_addr_bind_handle(p->dmem_dma_handle, NULL, 4797291a2b48SSukumar Swaminathan (caddr_t)addr, total_mem, 479882527734SSukumar Swaminathan DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, 0, 4799291a2b48SSukumar Swaminathan &cookie, &ncookie) != DDI_SUCCESS) { 4800fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4801fcf3ce44SJohn Forte "emlxs_fct_dmem_init: Unable to bind handle."); 4802fcf3ce44SJohn Forte goto addr_bind_handle_failed; 4803fcf3ce44SJohn Forte } 4804fcf3ce44SJohn Forte 4805fcf3ce44SJohn Forte if (ncookie != 1) { 4806fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4807fcf3ce44SJohn Forte "emlxs_fct_dmem_init: DMEM init failed."); 4808fcf3ce44SJohn Forte goto dmem_init_failed; 4809fcf3ce44SJohn Forte } 4810fcf3ce44SJohn Forte (void) sprintf(buf, "%s%d_bucket%d mutex", DRIVER_NAME, 4811fcf3ce44SJohn Forte hba->ddiinst, i); 4812fcf3ce44SJohn Forte mutex_init(&p->dmem_lock, buf, MUTEX_DRIVER, 4813*a9800bebSGarrett D'Amore DDI_INTR_PRI(hba->intr_arg)); 4814fcf3ce44SJohn Forte 4815fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4816fcf3ce44SJohn Forte "bufsize=%d cnt=%d", p->dmem_buf_size, p->dmem_nbufs); 4817fcf3ce44SJohn Forte 4818fcf3ce44SJohn Forte host_addr = addr; 4819fcf3ce44SJohn Forte dev_addr = (uint64_t)cookie.dmac_laddress; 4820fcf3ce44SJohn Forte 4821fcf3ce44SJohn Forte p->dmem_host_addr = addr; 4822fcf3ce44SJohn Forte p->dmem_dev_addr = dev_addr; 4823fcf3ce44SJohn Forte p->dmem_bctl_free_list = bctl; 4824fcf3ce44SJohn Forte p->dmem_nbufs_free = p->dmem_nbufs; 4825fcf3ce44SJohn Forte bsize = p->dmem_buf_size; 4826fcf3ce44SJohn Forte 4827fcf3ce44SJohn Forte for (j = 0; j < p->dmem_nbufs; j++) { 4828fcf3ce44SJohn Forte stmf_data_buf_t *db; 4829fcf3ce44SJohn Forte 4830fcf3ce44SJohn Forte db = MODSYM(stmf_alloc) (STMF_STRUCT_DATA_BUF, 0, 0); 4831fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 4832fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 4833fcf3ce44SJohn Forte "stmf_alloc data_buf %p", db); 4834291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 4835fcf3ce44SJohn Forte if (db == NULL) { 4836fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4837291a2b48SSukumar Swaminathan "emlxs_fct_dmem_init: alloc failed."); 4838fcf3ce44SJohn Forte goto dmem_init_failed; 4839fcf3ce44SJohn Forte } 4840fcf3ce44SJohn Forte db->db_port_private = bctl; 4841fcf3ce44SJohn Forte db->db_sglist[0].seg_addr = host_addr; 4842fcf3ce44SJohn Forte db->db_sglist[0].seg_length = bsize; 4843fcf3ce44SJohn Forte db->db_buf_size = bsize; 4844fcf3ce44SJohn Forte db->db_sglist_length = 1; 4845fcf3ce44SJohn Forte 4846fcf3ce44SJohn Forte bctl->bctl_bucket = p; 4847fcf3ce44SJohn Forte bctl->bctl_buf = db; 4848fcf3ce44SJohn Forte bctl->bctl_dev_addr = dev_addr; 4849fcf3ce44SJohn Forte 4850fcf3ce44SJohn Forte host_addr += bsize; 4851fcf3ce44SJohn Forte dev_addr += bsize; 4852fcf3ce44SJohn Forte 4853fcf3ce44SJohn Forte prev = bctl; 4854fcf3ce44SJohn Forte bctl++; 4855fcf3ce44SJohn Forte prev->bctl_next = bctl; 4856fcf3ce44SJohn Forte } 4857fcf3ce44SJohn Forte 4858fcf3ce44SJohn Forte prev->bctl_next = NULL; 4859fcf3ce44SJohn Forte } 4860fcf3ce44SJohn Forte 4861fcf3ce44SJohn Forte return (FCT_SUCCESS); 4862fcf3ce44SJohn Forte 4863fcf3ce44SJohn Forte dmem_failure_loop: 4864fcf3ce44SJohn Forte mutex_destroy(&p->dmem_lock); 4865fcf3ce44SJohn Forte bc = bctl; 4866fcf3ce44SJohn Forte while (bc) { 4867fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 4868fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 4869fcf3ce44SJohn Forte "stmf_free:3 %p", bctl->bctl_buf); 4870291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 4871fcf3ce44SJohn Forte MODSYM(stmf_free) (bc->bctl_buf); 4872fcf3ce44SJohn Forte bc = bc->bctl_next; 4873fcf3ce44SJohn Forte } 4874fcf3ce44SJohn Forte 4875fcf3ce44SJohn Forte dmem_init_failed: 4876fcf3ce44SJohn Forte (void) ddi_dma_unbind_handle(p->dmem_dma_handle); 4877fcf3ce44SJohn Forte 4878fcf3ce44SJohn Forte addr_bind_handle_failed: 4879fcf3ce44SJohn Forte (void) ddi_dma_mem_free(&p->dmem_acc_handle); 4880fcf3ce44SJohn Forte 4881fcf3ce44SJohn Forte mem_alloc_failed: 4882fcf3ce44SJohn Forte (void) ddi_dma_free_handle(&p->dmem_dma_handle); 4883fcf3ce44SJohn Forte 4884fcf3ce44SJohn Forte alloc_handle_failed: 4885fcf3ce44SJohn Forte kmem_free(p->dmem_bctls_mem, 4886fcf3ce44SJohn Forte p->dmem_nbufs * sizeof (emlxs_fct_dmem_bctl_t)); 4887fcf3ce44SJohn Forte 4888fcf3ce44SJohn Forte alloc_bctl_failed: 4889fcf3ce44SJohn Forte if (--i >= 0) { 4890fcf3ce44SJohn Forte p = &port->dmem_bucket[i]; 4891fcf3ce44SJohn Forte bctl = p->dmem_bctl_free_list; 4892fcf3ce44SJohn Forte goto dmem_failure_loop; 4893fcf3ce44SJohn Forte } 4894fcf3ce44SJohn Forte 4895291a2b48SSukumar Swaminathan return (FCT_FAILURE); 4896fcf3ce44SJohn Forte 489782527734SSukumar Swaminathan } /* emlxs_fct_dmem_init() */ 4898fcf3ce44SJohn Forte 4899fcf3ce44SJohn Forte 4900fcf3ce44SJohn Forte void 4901fcf3ce44SJohn Forte emlxs_fct_dmem_fini(emlxs_port_t *port) 4902fcf3ce44SJohn Forte { 4903fcf3ce44SJohn Forte emlxs_fct_dmem_bucket_t *p; 4904fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *bctl; 4905fcf3ce44SJohn Forte uint32_t i; 4906fcf3ce44SJohn Forte 4907fcf3ce44SJohn Forte p = port->dmem_bucket; 4908fcf3ce44SJohn Forte for (i = 0; i < FCT_MAX_BUCKETS; i++, p++) { 4909fcf3ce44SJohn Forte if (!p->dmem_nbufs) { 4910fcf3ce44SJohn Forte continue; 4911fcf3ce44SJohn Forte } 4912291a2b48SSukumar Swaminathan 4913fcf3ce44SJohn Forte bctl = p->dmem_bctl_free_list; 4914fcf3ce44SJohn Forte 4915fcf3ce44SJohn Forte while (bctl) { 4916fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 4917fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 4918fcf3ce44SJohn Forte "stmf_free:4 %p", bctl->bctl_buf); 4919291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 4920fcf3ce44SJohn Forte MODSYM(stmf_free) (bctl->bctl_buf); 4921fcf3ce44SJohn Forte bctl = bctl->bctl_next; 4922fcf3ce44SJohn Forte } 4923fcf3ce44SJohn Forte 4924fcf3ce44SJohn Forte bctl = p->dmem_bctl_free_list; 4925fcf3ce44SJohn Forte 4926fcf3ce44SJohn Forte (void) ddi_dma_unbind_handle(p->dmem_dma_handle); 4927fcf3ce44SJohn Forte (void) ddi_dma_mem_free(&p->dmem_acc_handle); 4928fcf3ce44SJohn Forte (void) ddi_dma_free_handle(&p->dmem_dma_handle); 4929fcf3ce44SJohn Forte 4930fcf3ce44SJohn Forte kmem_free(p->dmem_bctls_mem, 4931fcf3ce44SJohn Forte (p->dmem_nbufs * sizeof (emlxs_fct_dmem_bctl_t))); 4932fcf3ce44SJohn Forte mutex_destroy(&p->dmem_lock); 4933fcf3ce44SJohn Forte } 4934fcf3ce44SJohn Forte 4935fcf3ce44SJohn Forte bzero((uint8_t *)port->dmem_bucket, sizeof (port->dmem_bucket)); 4936fcf3ce44SJohn Forte 4937fcf3ce44SJohn Forte return; 4938fcf3ce44SJohn Forte 493982527734SSukumar Swaminathan } /* emlxs_fct_dmem_fini() */ 4940fcf3ce44SJohn Forte 4941fcf3ce44SJohn Forte 494282527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 4943fcf3ce44SJohn Forte /* ARGSUSED */ 4944fcf3ce44SJohn Forte static stmf_data_buf_t * 4945fcf3ce44SJohn Forte emlxs_fct_dbuf_alloc(fct_local_port_t *fct_port, uint32_t size, 4946fcf3ce44SJohn Forte uint32_t *pminsize, uint32_t flags) 4947fcf3ce44SJohn Forte { 4948fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 4949fcf3ce44SJohn Forte emlxs_fct_dmem_bucket_t *p; 4950fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *bctl; 4951fcf3ce44SJohn Forte uint32_t i; 4952fcf3ce44SJohn Forte 4953fcf3ce44SJohn Forte if (size > FCT_DMEM_MAX_BUF_SIZE) { 4954fcf3ce44SJohn Forte size = FCT_DMEM_MAX_BUF_SIZE; 4955fcf3ce44SJohn Forte } 4956291a2b48SSukumar Swaminathan 4957fcf3ce44SJohn Forte p = port->dmem_bucket; 4958fcf3ce44SJohn Forte for (i = 0; i < FCT_MAX_BUCKETS; i++, p++) { 4959fcf3ce44SJohn Forte if (!p->dmem_nbufs) { 4960fcf3ce44SJohn Forte continue; 4961fcf3ce44SJohn Forte } 4962291a2b48SSukumar Swaminathan 4963fcf3ce44SJohn Forte if (p->dmem_buf_size >= size) { 4964fcf3ce44SJohn Forte mutex_enter(&p->dmem_lock); 4965fcf3ce44SJohn Forte if (p->dmem_nbufs_free) { 4966fcf3ce44SJohn Forte if (p->dmem_buf_size < *pminsize) { 4967fcf3ce44SJohn Forte *pminsize = p->dmem_buf_size; 4968fcf3ce44SJohn Forte TGTPORTSTAT.FctNoBuffer++; 4969fcf3ce44SJohn Forte 4970fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 4971fcf3ce44SJohn Forte &emlxs_fct_api_msg, 4972fcf3ce44SJohn Forte "emlxs_fct_dbuf_alloc: Failed(1)."); 4973fcf3ce44SJohn Forte mutex_exit(&p->dmem_lock); 4974fcf3ce44SJohn Forte return (NULL); 4975fcf3ce44SJohn Forte } 4976291a2b48SSukumar Swaminathan 4977fcf3ce44SJohn Forte bctl = p->dmem_bctl_free_list; 4978fcf3ce44SJohn Forte if (bctl == NULL) { 4979fcf3ce44SJohn Forte mutex_exit(&p->dmem_lock); 4980fcf3ce44SJohn Forte continue; 4981fcf3ce44SJohn Forte } 4982291a2b48SSukumar Swaminathan 4983fcf3ce44SJohn Forte p->dmem_bctl_free_list = bctl->bctl_next; 4984fcf3ce44SJohn Forte p->dmem_nbufs_free--; 4985fcf3ce44SJohn Forte bctl->bctl_buf->db_data_size = size; 4986fcf3ce44SJohn Forte mutex_exit(&p->dmem_lock); 4987fcf3ce44SJohn Forte 4988fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 4989fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 499082527734SSukumar Swaminathan "emlx_fct_buf_alloc: bctl_buf %p: size %d", 4991fcf3ce44SJohn Forte bctl->bctl_buf, size); 4992291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 4993fcf3ce44SJohn Forte 4994fcf3ce44SJohn Forte return (bctl->bctl_buf); 4995fcf3ce44SJohn Forte } 4996fcf3ce44SJohn Forte mutex_exit(&p->dmem_lock); 4997fcf3ce44SJohn Forte 4998fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4999fcf3ce44SJohn Forte "emlx_fct_buf_alloc size %d Nothing free bck %d", 5000fcf3ce44SJohn Forte size, i); 5001fcf3ce44SJohn Forte } 5002fcf3ce44SJohn Forte } 5003fcf3ce44SJohn Forte 5004fcf3ce44SJohn Forte *pminsize = 0; 5005fcf3ce44SJohn Forte TGTPORTSTAT.FctNoBuffer++; 5006fcf3ce44SJohn Forte 5007fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 5008fcf3ce44SJohn Forte "emlxs_fct_dbuf_alloc: Failed(2)."); 5009fcf3ce44SJohn Forte 5010fcf3ce44SJohn Forte return (NULL); 5011fcf3ce44SJohn Forte 501282527734SSukumar Swaminathan } /* emlxs_fct_dbuf_alloc() */ 5013fcf3ce44SJohn Forte 5014fcf3ce44SJohn Forte 501582527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 5016291a2b48SSukumar Swaminathan /*ARGSUSED*/ 5017fcf3ce44SJohn Forte static void 5018fcf3ce44SJohn Forte emlxs_fct_dbuf_free(fct_dbuf_store_t *fds, stmf_data_buf_t *dbuf) 5019fcf3ce44SJohn Forte { 5020fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *bctl = 5021fcf3ce44SJohn Forte (emlxs_fct_dmem_bctl_t *)dbuf->db_port_private; 5022fcf3ce44SJohn Forte emlxs_fct_dmem_bucket_t *p = bctl->bctl_bucket; 5023fcf3ce44SJohn Forte 502482527734SSukumar Swaminathan #ifdef FCT_API_TRACE_1 5025fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 5026fcf3ce44SJohn Forte "emlx_fct_buf_free %p", dbuf); 5027291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 5028fcf3ce44SJohn Forte 5029fcf3ce44SJohn Forte mutex_enter(&p->dmem_lock); 5030fcf3ce44SJohn Forte bctl->bctl_next = p->dmem_bctl_free_list; 5031fcf3ce44SJohn Forte p->dmem_bctl_free_list = bctl; 5032fcf3ce44SJohn Forte p->dmem_nbufs_free++; 5033fcf3ce44SJohn Forte mutex_exit(&p->dmem_lock); 5034fcf3ce44SJohn Forte 503582527734SSukumar Swaminathan } /* emlxs_fct_dbuf_free() */ 5036fcf3ce44SJohn Forte 5037fcf3ce44SJohn Forte 5038b3660a96SSukumar Swaminathan static int 5039b3660a96SSukumar Swaminathan emlxs_fct_dbuf_dma_sync(emlxs_hba_t *hba, stmf_data_buf_t *dbuf, 5040b3660a96SSukumar Swaminathan uint_t sync_type) 5041fcf3ce44SJohn Forte { 5042fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *bctl = 5043fcf3ce44SJohn Forte (emlxs_fct_dmem_bctl_t *)dbuf->db_port_private; 5044fcf3ce44SJohn Forte emlxs_fct_dmem_bucket_t *p = bctl->bctl_bucket; 5045b3660a96SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5046b3660a96SSukumar Swaminathan int retval = 0; 5047fcf3ce44SJohn Forte 5048fcf3ce44SJohn Forte (void) ddi_dma_sync(p->dmem_dma_handle, 5049fcf3ce44SJohn Forte (unsigned long)(bctl->bctl_dev_addr - p->dmem_dev_addr), 5050fcf3ce44SJohn Forte dbuf->db_data_size, sync_type); 5051fcf3ce44SJohn Forte 5052b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 5053b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, p->dmem_dma_handle) 5054b3660a96SSukumar Swaminathan != DDI_FM_OK) { 5055b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 5056b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 5057b3660a96SSukumar Swaminathan "emlxs_fct_dbuf_dma_sync: hdl=%p", 5058b3660a96SSukumar Swaminathan p->dmem_dma_handle); 5059b3660a96SSukumar Swaminathan retval = 1; 5060b3660a96SSukumar Swaminathan } 5061b3660a96SSukumar Swaminathan #endif /* FMA_SUPPORT */ 5062b3660a96SSukumar Swaminathan 5063b3660a96SSukumar Swaminathan return (retval); 5064b3660a96SSukumar Swaminathan 506582527734SSukumar Swaminathan } /* emlxs_fct_dbuf_dma_sync() */ 5066fcf3ce44SJohn Forte 5067fcf3ce44SJohn Forte 5068291a2b48SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 5069