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 /* 23291a2b48SSukumar Swaminathan * Copyright 2009 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 43fcf3ce44SJohn Forte static void emlxs_fct_handle_acc(emlxs_port_t *port, emlxs_buf_t *sbp, 44fcf3ce44SJohn Forte IOCBQ *iocbq); 45fcf3ce44SJohn Forte static void emlxs_fct_handle_reject(emlxs_port_t *port, emlxs_buf_t *sbp, 46fcf3ce44SJohn Forte IOCBQ *iocbq); 47291a2b48SSukumar Swaminathan static emlxs_buf_t *emlxs_fct_cmd_init(emlxs_port_t *port, 4882527734SSukumar Swaminathan fct_cmd_t *fct_cmd, uint32_t fct_state); 4982527734SSukumar Swaminathan static void emlxs_fct_cmd_done(emlxs_port_t *port, fct_cmd_t *fct_cmd, 5082527734SSukumar Swaminathan uint16_t fct_state); 5182527734SSukumar Swaminathan static void emlxs_fct_cmd_post(emlxs_port_t *port, fct_cmd_t *fct_cmd, 5282527734SSukumar Swaminathan uint16_t fct_state); 53fcf3ce44SJohn Forte 5482527734SSukumar Swaminathan static fct_status_t emlxs_fct_flogi_xchg(struct fct_local_port *fct_port, 55fcf3ce44SJohn Forte struct fct_flogi_xchg *fx); 56fcf3ce44SJohn Forte static fct_status_t emlxs_fct_get_link_info(fct_local_port_t *fct_port, 57fcf3ce44SJohn Forte fct_link_info_t *link); 58fcf3ce44SJohn Forte static fct_status_t emlxs_fct_deregister_remote_port(fct_local_port_t *fct_port, 59fcf3ce44SJohn Forte fct_remote_port_t *port_handle); 60fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_cmd(fct_cmd_t *fct_cmd); 61fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_fcp_data(fct_cmd_t *fct_cmd, 62fcf3ce44SJohn Forte stmf_data_buf_t *dbuf, uint32_t ioflags); 63291a2b48SSukumar Swaminathan static fct_status_t emlxs_fct_send_cmd_rsp(fct_cmd_t *fct_cmd, uint32_t flags); 64291a2b48SSukumar Swaminathan static fct_status_t emlxs_fct_abort(fct_local_port_t *fct_port, 65291a2b48SSukumar Swaminathan fct_cmd_t *cmd, uint32_t flags); 66fcf3ce44SJohn Forte static void emlxs_fct_ctl(fct_local_port_t *fct_port, int cmd, void *arg); 67fcf3ce44SJohn Forte static fct_status_t emlxs_fct_register_remote_port(fct_local_port_t *fct_port, 68fcf3ce44SJohn Forte fct_remote_port_t *port_handle, fct_cmd_t *plogi); 69fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_els_cmd(fct_cmd_t *fct_cmd); 70fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_ct_cmd(fct_cmd_t *fct_cmd); 71fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_fcp_status(fct_cmd_t *fct_cmd); 72fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_els_rsp(fct_cmd_t *fct_cmd); 73fcf3ce44SJohn Forte static void emlxs_fct_pkt_comp(fc_packet_t *pkt); 7482527734SSukumar Swaminathan static void emlxs_fct_populate_hba_details(fct_local_port_t *fct_port, 75fcf3ce44SJohn Forte fct_port_attrs_t *port_attrs); 7682527734SSukumar Swaminathan static fct_status_t emlxs_fct_port_info(uint32_t cmd, 7782527734SSukumar Swaminathan fct_local_port_t *fct_port, void *arg, uint8_t *buffer, uint32_t *size); 78fcf3ce44SJohn Forte 79fcf3ce44SJohn Forte static fct_status_t emlxs_fct_dmem_init(emlxs_port_t *port); 80fcf3ce44SJohn Forte static void emlxs_fct_dmem_fini(emlxs_port_t *port); 81fcf3ce44SJohn Forte 82fcf3ce44SJohn Forte static stmf_data_buf_t *emlxs_fct_dbuf_alloc(fct_local_port_t *fct_port, 83fcf3ce44SJohn Forte uint32_t size, uint32_t *pminsize, uint32_t flags); 84fcf3ce44SJohn Forte static void emlxs_fct_dbuf_free(fct_dbuf_store_t *fds, stmf_data_buf_t *dbuf); 85fcf3ce44SJohn Forte 86*b3660a96SSukumar Swaminathan static int emlxs_fct_dbuf_dma_sync(emlxs_hba_t *hba, stmf_data_buf_t *dbuf, 87*b3660a96SSukumar Swaminathan uint_t sync_type); 88291a2b48SSukumar Swaminathan static emlxs_buf_t *emlxs_fct_pkt_init(emlxs_port_t *port, 89291a2b48SSukumar Swaminathan fct_cmd_t *fct_cmd, fc_packet_t *pkt); 90fcf3ce44SJohn Forte 91fcf3ce44SJohn Forte static void emlxs_fct_unsol_flush(emlxs_port_t *port); 9282527734SSukumar Swaminathan static uint32_t emlxs_fct_process_unsol_flogi(emlxs_port_t *port, 9382527734SSukumar Swaminathan CHANNEL *cp, IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 9482527734SSukumar Swaminathan static uint32_t emlxs_fct_process_unsol_plogi(emlxs_port_t *port, 9582527734SSukumar Swaminathan CHANNEL *cp, IOCBQ *iocbq, MATCHMAP *mp, uint32_t size); 96fe199829SSukumar Swaminathan static uint32_t emlxs_fct_pkt_abort_txq(emlxs_port_t *port, 97fe199829SSukumar Swaminathan emlxs_buf_t *cmd_sbp); 98fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_qfull_reply(emlxs_port_t *port, 99fcf3ce44SJohn Forte emlxs_node_t *ndlp, uint16_t xid, uint32_t class, emlxs_fcp_cmd_t *fcp_cmd); 100291a2b48SSukumar Swaminathan 101291a2b48SSukumar Swaminathan #ifdef FCT_IO_TRACE 102291a2b48SSukumar Swaminathan uint8_t *emlxs_iotrace = 0; /* global for mdb */ 103291a2b48SSukumar Swaminathan int emlxs_iotrace_cnt = 0; 104291a2b48SSukumar Swaminathan 10582527734SSukumar Swaminathan /* 10682527734SSukumar Swaminathan * 10782527734SSukumar Swaminathan * FCT_CMD (cmd_sbp->fct_state) 10882527734SSukumar Swaminathan * 10982527734SSukumar Swaminathan * STATE LOCK STATUS OWNER 11082527734SSukumar Swaminathan * ----------------------------------------------------------------------------- 11182527734SSukumar Swaminathan * EMLXS_FCT_ABORT_DONE Lock Destroyed COMSTAR 11282527734SSukumar Swaminathan * EMLXS_FCT_IO_DONE Lock Destroyed COMSTAR 11382527734SSukumar Swaminathan * 11482527734SSukumar Swaminathan * EMLXS_FCT_CMD_POSTED Lock Released COMSTAR 11582527734SSukumar Swaminathan * EMLXS_FCT_OWNED Lock Released COMSTAR 11682527734SSukumar Swaminathan * 11782527734SSukumar Swaminathan * EMLXS_FCT_CMD_WAITQ Lock Released DRIVER 11882527734SSukumar Swaminathan * EMLXS_FCT_RSP_PENDING Lock Released DRIVER 11982527734SSukumar Swaminathan * EMLXS_FCT_REQ_PENDING Lock Released DRIVER 12082527734SSukumar Swaminathan * EMLXS_FCT_REG_PENDING Lock Released DRIVER 12182527734SSukumar Swaminathan * EMLXS_FCT_DATA_PENDING Lock Released DRIVER 12282527734SSukumar Swaminathan * EMLXS_FCT_STATUS_PENDING Lock Released DRIVER 12382527734SSukumar Swaminathan * EMLXS_FCT_CLOSE_PENDING Lock Released DRIVER 12482527734SSukumar Swaminathan * EMLXS_FCT_ABORT_PENDING Lock Released DRIVER 12582527734SSukumar Swaminathan * 12682527734SSukumar Swaminathan * EMLXS_FCT_FCP_CMD_RECEIVED Transistional, lock held DRIVER 12782527734SSukumar Swaminathan * EMLXS_FCT_ELS_CMD_RECEIVED Transistional, lock held DRIVER 12882527734SSukumar Swaminathan * EMLXS_FCT_SEND_CMD_RSP Transistional, lock held DRIVER 12982527734SSukumar Swaminathan * EMLXS_FCT_SEND_ELS_RSP Transistional, lock held DRIVER 13082527734SSukumar Swaminathan * EMLXS_FCT_SEND_ELS_REQ Transistional, lock held DRIVER 13182527734SSukumar Swaminathan * EMLXS_FCT_SEND_CT_REQ Transistional, lock held DRIVER 13282527734SSukumar Swaminathan * EMLXS_FCT_REG_COMPLETE Transistional, lock held DRIVER 13382527734SSukumar Swaminathan * EMLXS_FCT_SEND_FCP_DATA Transistional, lock held DRIVER 13482527734SSukumar Swaminathan * EMLXS_FCT_SEND_FCP_STATUS Transistional, lock held DRIVER 13582527734SSukumar Swaminathan * EMLXS_FCT_PKT_COMPLETE Transistional, lock held DRIVER 13682527734SSukumar Swaminathan * EMLXS_FCT_PKT_FCPRSP_COMPLETE Transistional, lock held DRIVER 13782527734SSukumar Swaminathan * EMLXS_FCT_PKT_ELSRSP_COMPLETE Transistional, lock held DRIVER 13882527734SSukumar Swaminathan * EMLXS_FCT_PKT_ELSCMD_COMPLETE Transistional, lock held DRIVER 13982527734SSukumar Swaminathan * EMLXS_FCT_PKT_CTCMD_COMPLETE Transistional, lock held DRIVER 14082527734SSukumar Swaminathan * EMLXS_FCT_REQ_COMPLETE Transistional, lock held DRIVER 14182527734SSukumar Swaminathan * 14282527734SSukumar Swaminathan * 14382527734SSukumar Swaminathan * COMSTAR OWNED DRIVER OWNED 14482527734SSukumar Swaminathan * ------------- --------------------------------------------------- 14582527734SSukumar Swaminathan * ------- > @ Accept---- >Release @ Acquire--- >+ 14682527734SSukumar Swaminathan * | 14782527734SSukumar Swaminathan * < ------- @ Post/Done< ----Acquire @ Release< ---+ 14882527734SSukumar Swaminathan * 14982527734SSukumar Swaminathan * @ :Indicates COMSTAR use of emlxs_fct_abort() 15082527734SSukumar Swaminathan * Abort requests set the EMLXS_FCT_ABORT_INP flag. 15182527734SSukumar Swaminathan * 15282527734SSukumar Swaminathan * Accept :Indicates use of emlxs_fct_cmd_accept() 15382527734SSukumar Swaminathan * Acquire :Indicates use of emlxs_fct_cmd_acquire() 15482527734SSukumar Swaminathan * Post :Indicates use of emlxs_fct_cmd_post() 15582527734SSukumar Swaminathan * Done :Indicates use of emlxs_fct_cmd_done() 15682527734SSukumar Swaminathan */ 15782527734SSukumar Swaminathan 158291a2b48SSukumar Swaminathan void 159291a2b48SSukumar Swaminathan emlxs_fct_io_trace(emlxs_port_t *port, fct_cmd_t *fct_cmd, uint32_t data) 160291a2b48SSukumar Swaminathan { 161291a2b48SSukumar Swaminathan emlxs_iotrace_t *iop = port->iotrace; 162291a2b48SSukumar Swaminathan uint16_t iotrace_cnt; 163291a2b48SSukumar Swaminathan uint16_t iotrace_index; 164291a2b48SSukumar Swaminathan int i; 165291a2b48SSukumar Swaminathan 166291a2b48SSukumar Swaminathan if (!iop) { 167291a2b48SSukumar Swaminathan return; 168291a2b48SSukumar Swaminathan } 169291a2b48SSukumar Swaminathan 170291a2b48SSukumar Swaminathan mutex_enter(&port->iotrace_mtx); 171291a2b48SSukumar Swaminathan iotrace_cnt = port->iotrace_cnt; 172291a2b48SSukumar Swaminathan iotrace_index = port->iotrace_index; 173291a2b48SSukumar Swaminathan 174291a2b48SSukumar Swaminathan switch (data) { 175291a2b48SSukumar Swaminathan 176291a2b48SSukumar Swaminathan /* New entry */ 177291a2b48SSukumar Swaminathan case EMLXS_FCT_ELS_CMD_RECEIVED: 178291a2b48SSukumar Swaminathan case EMLXS_FCT_FCP_CMD_RECEIVED: 179291a2b48SSukumar Swaminathan case EMLXS_FCT_SEND_ELS_REQ: 180291a2b48SSukumar Swaminathan case EMLXS_FCT_SEND_CT_REQ: 181291a2b48SSukumar Swaminathan for (i = 0; i < iotrace_cnt; i++) { 182291a2b48SSukumar Swaminathan if ((iop->fct_cmd == fct_cmd) && 183291a2b48SSukumar Swaminathan (iop->trc[0] != (uint8_t)(0))) 184291a2b48SSukumar Swaminathan break; 185291a2b48SSukumar Swaminathan iop++; 186291a2b48SSukumar Swaminathan } 187291a2b48SSukumar Swaminathan if (i < iotrace_cnt) { 188291a2b48SSukumar Swaminathan /* New entry already exists */ 189291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 190291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 191291a2b48SSukumar Swaminathan "IOTRACE: New entry already exists: fct_cmd: %p", 192291a2b48SSukumar Swaminathan fct_cmd); 193291a2b48SSukumar Swaminathan return; 194291a2b48SSukumar Swaminathan } 195291a2b48SSukumar Swaminathan iop = port->iotrace + iotrace_index; 196291a2b48SSukumar Swaminathan for (i = 0; i < iotrace_cnt; i++) { 197291a2b48SSukumar Swaminathan if (iop->trc[0] == (uint8_t)(0)) 198291a2b48SSukumar Swaminathan break; 199291a2b48SSukumar Swaminathan 200291a2b48SSukumar Swaminathan iop++; 201291a2b48SSukumar Swaminathan if (iop == (port->iotrace + iotrace_cnt)) 202291a2b48SSukumar Swaminathan iop = port->iotrace; 203291a2b48SSukumar Swaminathan } 204291a2b48SSukumar Swaminathan if (i >= iotrace_cnt) { 205291a2b48SSukumar Swaminathan /* No new slots available */ 206291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 207291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 208291a2b48SSukumar Swaminathan "IOTRACE: No new slots: fct_cmd: %p data: %d", 209291a2b48SSukumar Swaminathan fct_cmd, data); 210291a2b48SSukumar Swaminathan return; 211291a2b48SSukumar Swaminathan } 212291a2b48SSukumar Swaminathan port->iotrace_index++; 213291a2b48SSukumar Swaminathan if (port->iotrace_index >= iotrace_cnt) 214291a2b48SSukumar Swaminathan port->iotrace_index = 0; 215291a2b48SSukumar Swaminathan 216291a2b48SSukumar Swaminathan bzero((uint8_t *)iop, sizeof (emlxs_iotrace_t)); 217291a2b48SSukumar Swaminathan iop->fct_cmd = fct_cmd; 218291a2b48SSukumar Swaminathan iop->xri = fct_cmd->cmd_rxid; 219291a2b48SSukumar Swaminathan iop->marker = 0xff; 220291a2b48SSukumar Swaminathan iop->trc[0] = 2; 221291a2b48SSukumar Swaminathan iop->trc[1] = data; 222291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 223291a2b48SSukumar Swaminathan return; 224291a2b48SSukumar Swaminathan } 225291a2b48SSukumar Swaminathan 226291a2b48SSukumar Swaminathan for (i = 0; i < iotrace_cnt; i++) { 227291a2b48SSukumar Swaminathan if ((iop->fct_cmd == fct_cmd) && 228291a2b48SSukumar Swaminathan (iop->trc[0] != (uint8_t)(0))) 229291a2b48SSukumar Swaminathan break; 230291a2b48SSukumar Swaminathan iop++; 231291a2b48SSukumar Swaminathan } 232291a2b48SSukumar Swaminathan if (i >= iotrace_cnt) { 233291a2b48SSukumar Swaminathan /* Cannot find existing slot for fct_cmd */ 234291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 235291a2b48SSukumar Swaminathan 236291a2b48SSukumar Swaminathan if ((data != EMLXS_FCT_REG_PENDING) && 237291a2b48SSukumar Swaminathan (data != EMLXS_FCT_REG_COMPLETE)) { 238291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 239291a2b48SSukumar Swaminathan "IOTRACE: Missing slot: fct_cmd: %p data: %d", 240291a2b48SSukumar Swaminathan fct_cmd, data); 241291a2b48SSukumar Swaminathan } 242291a2b48SSukumar Swaminathan return; 243291a2b48SSukumar Swaminathan } 244291a2b48SSukumar Swaminathan 245291a2b48SSukumar Swaminathan if (iop->trc[0] >= MAX_IO_TRACE) { 246291a2b48SSukumar Swaminathan /* trc overrun for fct_cmd */ 247291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 248291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 249291a2b48SSukumar Swaminathan "IOTRACE: trc overrun slot: fct_cmd: %p data: %d", 250291a2b48SSukumar Swaminathan fct_cmd, data); 251291a2b48SSukumar Swaminathan return; 252291a2b48SSukumar Swaminathan } 253291a2b48SSukumar Swaminathan 254291a2b48SSukumar Swaminathan if (iop->xri != fct_cmd->cmd_rxid) { 255291a2b48SSukumar Swaminathan /* xri mismatch for fct_cmd */ 256291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 257291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 258291a2b48SSukumar Swaminathan "IOTRACE: xri mismatch %x != %x: fct_cmd: %p data: %d", 259291a2b48SSukumar Swaminathan iop->xri, fct_cmd->cmd_rxid, fct_cmd, data); 260291a2b48SSukumar Swaminathan return; 261291a2b48SSukumar Swaminathan } 262291a2b48SSukumar Swaminathan 263291a2b48SSukumar Swaminathan iop->trc[iop->trc[0]] = data; 264291a2b48SSukumar Swaminathan if ((data == EMLXS_FCT_IO_DONE) || (data == EMLXS_FCT_ABORT_DONE)) { 26582527734SSukumar Swaminathan /* IOCB ULPCOMMAND is saved after EMLXS_FCT_IOCB_ISSUED */ 26682527734SSukumar Swaminathan if (iop->trc[iop->trc[0]-1] == EMLXS_FCT_IOCB_ISSUED) { 267291a2b48SSukumar Swaminathan iop->trc[0]++; 26882527734SSukumar Swaminathan } else { 269291a2b48SSukumar Swaminathan iop->trc[0] = 0; 27082527734SSukumar Swaminathan } else { 271291a2b48SSukumar Swaminathan iop->trc[0]++; 27282527734SSukumar Swaminathan } 273291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx); 27482527734SSukumar Swaminathan 27582527734SSukumar Swaminathan return; 27682527734SSukumar Swaminathan 27782527734SSukumar Swaminathan } /* emlxs_fct_io_trace() */ 278291a2b48SSukumar Swaminathan #endif /* FCT_IO_TRACE */ 279fcf3ce44SJohn Forte 280fcf3ce44SJohn Forte #ifdef MODSYM_SUPPORT 281fcf3ce44SJohn Forte 282e51761e0SSukumar Swaminathan extern int 283fcf3ce44SJohn Forte emlxs_fct_modopen() 284fcf3ce44SJohn Forte { 285fcf3ce44SJohn Forte int err; 286fcf3ce44SJohn Forte 28782527734SSukumar Swaminathan mutex_enter(&emlxs_device.lock); 28882527734SSukumar Swaminathan 28982527734SSukumar Swaminathan if (emlxs_modsym.fct_modopen) { 29082527734SSukumar Swaminathan mutex_exit(&emlxs_device.lock); 29182527734SSukumar Swaminathan return (0); 292fcf3ce44SJohn Forte } 293291a2b48SSukumar Swaminathan 29482527734SSukumar Swaminathan emlxs_modsym.fct_modopen++; 29582527734SSukumar Swaminathan 296fcf3ce44SJohn Forte /* Comstar (fct) */ 297fcf3ce44SJohn Forte err = 0; 298fcf3ce44SJohn Forte emlxs_modsym.mod_fct = ddi_modopen("drv/fct", KRTLD_MODE_FIRST, &err); 299fcf3ce44SJohn Forte if (!emlxs_modsym.mod_fct) { 300fcf3ce44SJohn Forte 301fcf3ce44SJohn Forte cmn_err(CE_WARN, "?%s: ddi_modopen drv/fct failed: err %d", 302fcf3ce44SJohn Forte DRIVER_NAME, err); 303fcf3ce44SJohn Forte goto failed; 304fcf3ce44SJohn Forte } 305291a2b48SSukumar Swaminathan 306fcf3ce44SJohn Forte /* Comstar (stmf) */ 307fcf3ce44SJohn Forte err = 0; 308291a2b48SSukumar Swaminathan emlxs_modsym.mod_stmf = 309291a2b48SSukumar Swaminathan ddi_modopen("drv/stmf", KRTLD_MODE_FIRST, &err); 310fcf3ce44SJohn Forte if (!emlxs_modsym.mod_stmf) { 311fcf3ce44SJohn Forte 312fcf3ce44SJohn Forte cmn_err(CE_WARN, "?%s: ddi_modopen drv/stmf failed: err %d", 313fcf3ce44SJohn Forte DRIVER_NAME, err); 314fcf3ce44SJohn Forte goto failed; 315fcf3ce44SJohn Forte } 316291a2b48SSukumar Swaminathan 317fcf3ce44SJohn Forte err = 0; 318fcf3ce44SJohn Forte /* Check if the fct fct_alloc is present */ 319291a2b48SSukumar Swaminathan emlxs_modsym.fct_alloc = (void *(*)())ddi_modsym(emlxs_modsym.mod_fct, 320fcf3ce44SJohn Forte "fct_alloc", &err); 321fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_alloc == NULL) { 322fcf3ce44SJohn Forte cmn_err(CE_WARN, 323fcf3ce44SJohn Forte "?%s: drv/fct: fct_alloc not present", DRIVER_NAME); 324fcf3ce44SJohn Forte goto failed; 325fcf3ce44SJohn Forte } 326291a2b48SSukumar Swaminathan 327fcf3ce44SJohn Forte err = 0; 328fcf3ce44SJohn Forte /* Check if the fct fct_free is present */ 329291a2b48SSukumar Swaminathan emlxs_modsym.fct_free = (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 330fcf3ce44SJohn Forte "fct_free", &err); 331fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_free == NULL) { 332fcf3ce44SJohn Forte cmn_err(CE_WARN, 333fcf3ce44SJohn Forte "?%s: drv/fct: fct_free not present", DRIVER_NAME); 334fcf3ce44SJohn Forte goto failed; 335fcf3ce44SJohn Forte } 336291a2b48SSukumar Swaminathan 337fcf3ce44SJohn Forte err = 0; 338fcf3ce44SJohn Forte /* Check if the fct fct_scsi_task_alloc is present */ 339291a2b48SSukumar Swaminathan emlxs_modsym.fct_scsi_task_alloc = 340291a2b48SSukumar Swaminathan (void *(*)(void *, uint16_t, uint32_t, uint8_t *, 341291a2b48SSukumar Swaminathan uint16_t, uint16_t))ddi_modsym(emlxs_modsym.mod_fct, 342291a2b48SSukumar Swaminathan "fct_scsi_task_alloc", &err); 343fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_scsi_task_alloc == NULL) { 344fcf3ce44SJohn Forte cmn_err(CE_WARN, 345fcf3ce44SJohn Forte "?%s: drv/fct: fct_scsi_task_alloc not present", 346fcf3ce44SJohn Forte DRIVER_NAME); 347fcf3ce44SJohn Forte goto failed; 348fcf3ce44SJohn Forte } 349291a2b48SSukumar Swaminathan 350fcf3ce44SJohn Forte err = 0; 351fcf3ce44SJohn Forte /* Check if the fct fct_register_local_port is present */ 352291a2b48SSukumar Swaminathan emlxs_modsym.fct_register_local_port = 353291a2b48SSukumar Swaminathan (int (*)())ddi_modsym(emlxs_modsym.mod_fct, 354291a2b48SSukumar Swaminathan "fct_register_local_port", &err); 355fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_register_local_port == NULL) { 356fcf3ce44SJohn Forte cmn_err(CE_WARN, 357fcf3ce44SJohn Forte "?%s: drv/fct: fct_register_local_port not present", 358fcf3ce44SJohn Forte DRIVER_NAME); 359fcf3ce44SJohn Forte goto failed; 360fcf3ce44SJohn Forte } 361291a2b48SSukumar Swaminathan 362fcf3ce44SJohn Forte err = 0; 363fcf3ce44SJohn Forte /* Check if the fct fct_deregister_local_port is present */ 364291a2b48SSukumar Swaminathan emlxs_modsym.fct_deregister_local_port = 365291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 366291a2b48SSukumar Swaminathan "fct_deregister_local_port", &err); 367fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_deregister_local_port == NULL) { 368fcf3ce44SJohn Forte cmn_err(CE_WARN, 369fcf3ce44SJohn Forte "?%s: drv/fct: fct_deregister_local_port not present", 370fcf3ce44SJohn Forte DRIVER_NAME); 371fcf3ce44SJohn Forte goto failed; 372fcf3ce44SJohn Forte } 373291a2b48SSukumar Swaminathan 374fcf3ce44SJohn Forte err = 0; 375fcf3ce44SJohn Forte /* Check if the fct fct_handle_event is present */ 376291a2b48SSukumar Swaminathan emlxs_modsym.fct_handle_event = 377291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, "fct_handle_event", 378291a2b48SSukumar Swaminathan &err); 379fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_handle_event == NULL) { 380fcf3ce44SJohn Forte cmn_err(CE_WARN, 381291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_handle_event not present", 382291a2b48SSukumar Swaminathan DRIVER_NAME); 383fcf3ce44SJohn Forte goto failed; 384fcf3ce44SJohn Forte } 385291a2b48SSukumar Swaminathan 386fcf3ce44SJohn Forte err = 0; 387fcf3ce44SJohn Forte /* Check if the fct fct_post_rcvd_cmd is present */ 388291a2b48SSukumar Swaminathan emlxs_modsym.fct_post_rcvd_cmd = 389291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, "fct_post_rcvd_cmd", 390291a2b48SSukumar Swaminathan &err); 391fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_post_rcvd_cmd == NULL) { 392fcf3ce44SJohn Forte cmn_err(CE_WARN, 393291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_post_rcvd_cmd not present", 394291a2b48SSukumar Swaminathan DRIVER_NAME); 395fcf3ce44SJohn Forte goto failed; 396fcf3ce44SJohn Forte } 397fcf3ce44SJohn Forte err = 0; 398fcf3ce44SJohn Forte /* Check if the fct fct_alloc is present */ 399291a2b48SSukumar Swaminathan emlxs_modsym.fct_ctl = (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 400fcf3ce44SJohn Forte "fct_ctl", &err); 401fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_ctl == NULL) { 402fcf3ce44SJohn Forte cmn_err(CE_WARN, 403fcf3ce44SJohn Forte "?%s: drv/fct: fct_ctl not present", DRIVER_NAME); 404fcf3ce44SJohn Forte goto failed; 405fcf3ce44SJohn Forte } 406fcf3ce44SJohn Forte err = 0; 407291a2b48SSukumar Swaminathan /* Check if the fct fct_queue_cmd_for_termination is present */ 408291a2b48SSukumar Swaminathan emlxs_modsym.fct_queue_cmd_for_termination = 409291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 410291a2b48SSukumar Swaminathan "fct_queue_cmd_for_termination", &err); 411291a2b48SSukumar Swaminathan if ((void *)emlxs_modsym.fct_queue_cmd_for_termination == NULL) { 412291a2b48SSukumar Swaminathan cmn_err(CE_WARN, 413291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_queue_cmd_for_termination not present", 414291a2b48SSukumar Swaminathan DRIVER_NAME); 415291a2b48SSukumar Swaminathan goto failed; 416291a2b48SSukumar Swaminathan } 417291a2b48SSukumar Swaminathan err = 0; 418fcf3ce44SJohn Forte /* Check if the fct fct_send_response_done is present */ 419291a2b48SSukumar Swaminathan emlxs_modsym.fct_send_response_done = 420291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 421291a2b48SSukumar Swaminathan "fct_send_response_done", &err); 422fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_send_response_done == NULL) { 423fcf3ce44SJohn Forte cmn_err(CE_WARN, 424fcf3ce44SJohn Forte "?%s: drv/fct: fct_send_response_done not present", 425fcf3ce44SJohn Forte DRIVER_NAME); 426fcf3ce44SJohn Forte goto failed; 427fcf3ce44SJohn Forte } 428fcf3ce44SJohn Forte err = 0; 429fcf3ce44SJohn Forte /* Check if the fct fct_send_cmd_done is present */ 430291a2b48SSukumar Swaminathan emlxs_modsym.fct_send_cmd_done = 431291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, "fct_send_cmd_done", 432291a2b48SSukumar Swaminathan &err); 433fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_send_cmd_done == NULL) { 434fcf3ce44SJohn Forte cmn_err(CE_WARN, 435291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_send_cmd_done not present", 436291a2b48SSukumar Swaminathan DRIVER_NAME); 437fcf3ce44SJohn Forte goto failed; 438fcf3ce44SJohn Forte } 439fcf3ce44SJohn Forte err = 0; 440fcf3ce44SJohn Forte /* Check if the fct fct_scsi_xfer_data_done is present */ 441291a2b48SSukumar Swaminathan emlxs_modsym.fct_scsi_data_xfer_done = 442291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 443291a2b48SSukumar Swaminathan "fct_scsi_data_xfer_done", &err); 444fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_scsi_data_xfer_done == NULL) { 445fcf3ce44SJohn Forte cmn_err(CE_WARN, 446fcf3ce44SJohn Forte "?%s: drv/fct: fct_scsi_data_xfer_done not present", 447fcf3ce44SJohn Forte DRIVER_NAME); 448fcf3ce44SJohn Forte goto failed; 449fcf3ce44SJohn Forte } 450fcf3ce44SJohn Forte err = 0; 451fcf3ce44SJohn Forte /* Check if the fct fct_port_shutdown is present */ 452291a2b48SSukumar Swaminathan emlxs_modsym.fct_port_shutdown = 453291a2b48SSukumar Swaminathan (fct_status_t(*)())ddi_modsym(emlxs_modsym.mod_fct, 454291a2b48SSukumar Swaminathan "fct_port_shutdown", &err); 455fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_port_shutdown == NULL) { 456fcf3ce44SJohn Forte cmn_err(CE_WARN, 457291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_port_shutdown not present", 458291a2b48SSukumar Swaminathan DRIVER_NAME); 459fcf3ce44SJohn Forte goto failed; 460fcf3ce44SJohn Forte } 461291a2b48SSukumar Swaminathan 462fcf3ce44SJohn Forte err = 0; 463fcf3ce44SJohn Forte /* Check if the fct fct_port_initialize is present */ 464291a2b48SSukumar Swaminathan emlxs_modsym.fct_port_initialize = 465291a2b48SSukumar Swaminathan (fct_status_t(*)())ddi_modsym(emlxs_modsym.mod_fct, 466291a2b48SSukumar Swaminathan "fct_port_initialize", &err); 467fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_port_initialize == NULL) { 468fcf3ce44SJohn Forte cmn_err(CE_WARN, 469fcf3ce44SJohn Forte "?%s: drv/fct: fct_port_initialize not present", 470fcf3ce44SJohn Forte DRIVER_NAME); 471fcf3ce44SJohn Forte goto failed; 472fcf3ce44SJohn Forte } 473291a2b48SSukumar Swaminathan 474291a2b48SSukumar Swaminathan err = 0; 475291a2b48SSukumar Swaminathan /* Check if the fct fct_cmd_fca_aborted is present */ 476291a2b48SSukumar Swaminathan emlxs_modsym.fct_cmd_fca_aborted = 477291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, 478291a2b48SSukumar Swaminathan "fct_cmd_fca_aborted", &err); 479291a2b48SSukumar Swaminathan if ((void *)emlxs_modsym.fct_cmd_fca_aborted == NULL) { 480291a2b48SSukumar Swaminathan cmn_err(CE_WARN, 481291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_cmd_fca_aborted not present", 482291a2b48SSukumar Swaminathan DRIVER_NAME); 483291a2b48SSukumar Swaminathan goto failed; 484291a2b48SSukumar Swaminathan } 485291a2b48SSukumar Swaminathan 486fcf3ce44SJohn Forte err = 0; 487fcf3ce44SJohn Forte /* Check if the fct fct_handle_rcvd_flogi is present */ 488291a2b48SSukumar Swaminathan emlxs_modsym.fct_handle_rcvd_flogi = 489291a2b48SSukumar Swaminathan (fct_status_t(*)())ddi_modsym(emlxs_modsym.mod_fct, 490291a2b48SSukumar Swaminathan "fct_handle_rcvd_flogi", &err); 491fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_handle_rcvd_flogi == NULL) { 492fcf3ce44SJohn Forte cmn_err(CE_WARN, 493fcf3ce44SJohn Forte "?%s: drv/fct: fct_handle_rcvd_flogi not present", 494fcf3ce44SJohn Forte DRIVER_NAME); 495fcf3ce44SJohn Forte goto failed; 496fcf3ce44SJohn Forte } 497291a2b48SSukumar Swaminathan 498fcf3ce44SJohn Forte /* Comstar (stmf) */ 499fcf3ce44SJohn Forte err = 0; 500fcf3ce44SJohn Forte /* Check if the stmf stmf_alloc is present */ 501291a2b48SSukumar Swaminathan emlxs_modsym.stmf_alloc = 502291a2b48SSukumar Swaminathan (void *(*)())ddi_modsym(emlxs_modsym.mod_stmf, "stmf_alloc", 503291a2b48SSukumar Swaminathan &err); 504fcf3ce44SJohn Forte if ((void *)emlxs_modsym.stmf_alloc == NULL) { 505fcf3ce44SJohn Forte cmn_err(CE_WARN, 506fcf3ce44SJohn Forte "?%s: drv/stmf: stmf_alloc not present", DRIVER_NAME); 507fcf3ce44SJohn Forte goto failed; 508fcf3ce44SJohn Forte } 509291a2b48SSukumar Swaminathan 510fcf3ce44SJohn Forte err = 0; 511fcf3ce44SJohn Forte /* Check if the stmf stmf_free is present */ 512291a2b48SSukumar Swaminathan emlxs_modsym.stmf_free = (void (*)())ddi_modsym(emlxs_modsym.mod_stmf, 513fcf3ce44SJohn Forte "stmf_free", &err); 514fcf3ce44SJohn Forte if ((void *)emlxs_modsym.stmf_free == NULL) { 515fcf3ce44SJohn Forte cmn_err(CE_WARN, 516fcf3ce44SJohn Forte "?%s: drv/stmf: stmf_free not present", DRIVER_NAME); 517fcf3ce44SJohn Forte goto failed; 518fcf3ce44SJohn Forte } 519291a2b48SSukumar Swaminathan 520fcf3ce44SJohn Forte err = 0; 521fcf3ce44SJohn Forte /* Check if the stmf stmf_deregister_port_provider is present */ 522fcf3ce44SJohn Forte emlxs_modsym.stmf_deregister_port_provider = 523291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_stmf, 524fcf3ce44SJohn Forte "stmf_deregister_port_provider", &err); 525fcf3ce44SJohn Forte if ((void *)emlxs_modsym.stmf_deregister_port_provider == NULL) { 526fcf3ce44SJohn Forte cmn_err(CE_WARN, 527fcf3ce44SJohn Forte "?%s: drv/stmf: stmf_deregister_port_provider not present", 528fcf3ce44SJohn Forte DRIVER_NAME); 529fcf3ce44SJohn Forte goto failed; 530fcf3ce44SJohn Forte } 531291a2b48SSukumar Swaminathan 532fcf3ce44SJohn Forte err = 0; 533fcf3ce44SJohn Forte /* Check if the stmf stmf_register_port_provider is present */ 534fcf3ce44SJohn Forte emlxs_modsym.stmf_register_port_provider = 535291a2b48SSukumar Swaminathan (int (*)())ddi_modsym(emlxs_modsym.mod_stmf, 536fcf3ce44SJohn Forte "stmf_register_port_provider", &err); 537fcf3ce44SJohn Forte if ((void *)emlxs_modsym.stmf_register_port_provider == NULL) { 538fcf3ce44SJohn Forte cmn_err(CE_WARN, 539fcf3ce44SJohn Forte "?%s: drv/stmf: stmf_register_port_provider not present", 540fcf3ce44SJohn Forte DRIVER_NAME); 541fcf3ce44SJohn Forte goto failed; 542fcf3ce44SJohn Forte } 54382527734SSukumar Swaminathan 54482527734SSukumar Swaminathan mutex_exit(&emlxs_device.lock); 54582527734SSukumar Swaminathan return (0); 546fcf3ce44SJohn Forte 547fcf3ce44SJohn Forte failed: 54882527734SSukumar Swaminathan 54982527734SSukumar Swaminathan mutex_exit(&emlxs_device.lock); 550fcf3ce44SJohn Forte emlxs_fct_modclose(); 55182527734SSukumar Swaminathan return (1); 552fcf3ce44SJohn Forte 55382527734SSukumar Swaminathan } /* emlxs_fct_modopen() */ 554fcf3ce44SJohn Forte 555fcf3ce44SJohn Forte 556fcf3ce44SJohn Forte extern void 557fcf3ce44SJohn Forte emlxs_fct_modclose() 558fcf3ce44SJohn Forte { 55982527734SSukumar Swaminathan mutex_enter(&emlxs_device.lock); 56082527734SSukumar Swaminathan 56182527734SSukumar Swaminathan if (emlxs_modsym.fct_modopen == 0) { 56282527734SSukumar Swaminathan mutex_exit(&emlxs_device.lock); 56382527734SSukumar Swaminathan return; 56482527734SSukumar Swaminathan } 56582527734SSukumar Swaminathan 56682527734SSukumar Swaminathan emlxs_modsym.fct_modopen--; 56782527734SSukumar Swaminathan 56882527734SSukumar Swaminathan if (emlxs_modsym.fct_modopen) { 56982527734SSukumar Swaminathan mutex_exit(&emlxs_device.lock); 57082527734SSukumar Swaminathan return; 57182527734SSukumar Swaminathan } 572fcf3ce44SJohn Forte 573fcf3ce44SJohn Forte if (emlxs_modsym.mod_fct) { 574fcf3ce44SJohn Forte (void) ddi_modclose(emlxs_modsym.mod_fct); 575fcf3ce44SJohn Forte emlxs_modsym.mod_fct = 0; 576fcf3ce44SJohn Forte } 577291a2b48SSukumar Swaminathan 578fcf3ce44SJohn Forte if (emlxs_modsym.mod_stmf) { 579fcf3ce44SJohn Forte (void) ddi_modclose(emlxs_modsym.mod_stmf); 580fcf3ce44SJohn Forte emlxs_modsym.mod_stmf = 0; 581fcf3ce44SJohn Forte } 582291a2b48SSukumar Swaminathan 583fcf3ce44SJohn Forte emlxs_modsym.fct_alloc = NULL; 584fcf3ce44SJohn Forte emlxs_modsym.fct_free = NULL; 585fcf3ce44SJohn Forte emlxs_modsym.fct_scsi_task_alloc = NULL; 586fcf3ce44SJohn Forte emlxs_modsym.fct_register_local_port = NULL; 587fcf3ce44SJohn Forte emlxs_modsym.fct_deregister_local_port = NULL; 588fcf3ce44SJohn Forte emlxs_modsym.fct_handle_event = NULL; 589fcf3ce44SJohn Forte emlxs_modsym.fct_ctl = NULL; 590291a2b48SSukumar Swaminathan emlxs_modsym.fct_queue_cmd_for_termination = NULL; 591fcf3ce44SJohn Forte emlxs_modsym.fct_send_response_done = NULL; 592fcf3ce44SJohn Forte emlxs_modsym.fct_send_cmd_done = NULL; 593fcf3ce44SJohn Forte emlxs_modsym.fct_scsi_data_xfer_done = NULL; 594fcf3ce44SJohn Forte emlxs_modsym.fct_port_shutdown = NULL; 595fcf3ce44SJohn Forte emlxs_modsym.fct_port_initialize = NULL; 596291a2b48SSukumar Swaminathan emlxs_modsym.fct_cmd_fca_aborted = NULL; 597fcf3ce44SJohn Forte emlxs_modsym.fct_handle_rcvd_flogi = NULL; 598fcf3ce44SJohn Forte 599fcf3ce44SJohn Forte emlxs_modsym.stmf_alloc = NULL; 600fcf3ce44SJohn Forte emlxs_modsym.stmf_free = NULL; 601fcf3ce44SJohn Forte emlxs_modsym.stmf_deregister_port_provider = NULL; 602fcf3ce44SJohn Forte emlxs_modsym.stmf_register_port_provider = NULL; 603fcf3ce44SJohn Forte 60482527734SSukumar Swaminathan mutex_exit(&emlxs_device.lock); 60582527734SSukumar Swaminathan 60682527734SSukumar Swaminathan } /* emlxs_fct_modclose() */ 607291a2b48SSukumar Swaminathan 608291a2b48SSukumar Swaminathan #endif /* MODSYM_SUPPORT */ 609291a2b48SSukumar Swaminathan 610e2ca2865SSukumar Swaminathan /* 611e2ca2865SSukumar Swaminathan * This routine is called to handle an unsol FLOGI exchange 612e2ca2865SSukumar Swaminathan * fx save 613e2ca2865SSukumar Swaminathan * 0 1 Process or save port->fx 614e2ca2865SSukumar Swaminathan * 0 0 Process or reject port->fx 615e2ca2865SSukumar Swaminathan * 1 1 Process port->fx, Process or save fx 616e2ca2865SSukumar Swaminathan * 1 0 Process or reject port->fx, Process or reject fx 617e2ca2865SSukumar Swaminathan */ 618291a2b48SSukumar Swaminathan static void 619e2ca2865SSukumar Swaminathan emlxs_fct_handle_unsol_flogi(emlxs_port_t *port, fct_flogi_xchg_t *fx, 620e2ca2865SSukumar Swaminathan uint32_t save) 621291a2b48SSukumar Swaminathan { 622e2ca2865SSukumar Swaminathan emlxs_hba_t *hba = HBA; 623291a2b48SSukumar Swaminathan fct_status_t status; 624291a2b48SSukumar Swaminathan IOCBQ iocbq; 625e2ca2865SSukumar Swaminathan fct_flogi_xchg_t fxchg; 626e2ca2865SSukumar Swaminathan 627e2ca2865SSukumar Swaminathan begin: 628e2ca2865SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 629e2ca2865SSukumar Swaminathan 630e2ca2865SSukumar Swaminathan /* Check if there is an old saved FLOGI */ 631e2ca2865SSukumar Swaminathan if (port->fx.fx_op) { 632e2ca2865SSukumar Swaminathan /* Get it now */ 633e2ca2865SSukumar Swaminathan bcopy(&port->fx, &fxchg, sizeof (fct_flogi_xchg_t)); 634e2ca2865SSukumar Swaminathan 635e2ca2865SSukumar Swaminathan if (fx) { 636e2ca2865SSukumar Swaminathan /* Save new FLOGI */ 637e2ca2865SSukumar Swaminathan bcopy(fx, &port->fx, sizeof (fct_flogi_xchg_t)); 638e2ca2865SSukumar Swaminathan 639e2ca2865SSukumar Swaminathan /* Reject old stale FLOGI */ 640e2ca2865SSukumar Swaminathan fx = &fxchg; 641e2ca2865SSukumar Swaminathan goto reject_it; 642e2ca2865SSukumar Swaminathan 643e2ca2865SSukumar Swaminathan } else { 644e2ca2865SSukumar Swaminathan bzero(&port->fx, sizeof (fct_flogi_xchg_t)); 645e2ca2865SSukumar Swaminathan fx = &fxchg; 646e2ca2865SSukumar Swaminathan } 647e2ca2865SSukumar Swaminathan 648e2ca2865SSukumar Swaminathan } else if (!fx) { 649e2ca2865SSukumar Swaminathan /* Nothing to do, just return */ 650e2ca2865SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 651e2ca2865SSukumar Swaminathan return; 652e2ca2865SSukumar Swaminathan } 653e2ca2865SSukumar Swaminathan 654e2ca2865SSukumar Swaminathan /* We have a valid FLOGI here */ 655e2ca2865SSukumar Swaminathan /* There is no saved FLOGI at this point either */ 656e2ca2865SSukumar Swaminathan 657e2ca2865SSukumar Swaminathan /* Check if COMSTAR is ready to accept it */ 658e2ca2865SSukumar Swaminathan if (port->fct_flags & FCT_STATE_LINK_UP_ACKED) { 659e2ca2865SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 660291a2b48SSukumar Swaminathan 661291a2b48SSukumar Swaminathan bzero((uint8_t *)&iocbq, sizeof (IOCBQ)); 662e2ca2865SSukumar Swaminathan iocbq.iocb.un.elsreq.remoteID = fx->fx_sid; 663e2ca2865SSukumar Swaminathan iocbq.iocb.un.elsreq.myID = fx->fx_did; 664e2ca2865SSukumar Swaminathan iocbq.iocb.ULPCONTEXT = (uint16_t)fx->rsvd2; 665e2ca2865SSukumar Swaminathan fx->rsvd2 = 0; /* Clear the reserved field now */ 666291a2b48SSukumar Swaminathan 667e2ca2865SSukumar Swaminathan status = MODSYM(fct_handle_rcvd_flogi) (port->fct_port, fx); 668291a2b48SSukumar Swaminathan 669291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE 670291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 671e2ca2865SSukumar Swaminathan "fct_handle_rcvd_flogi %p: status=%x", 672e2ca2865SSukumar Swaminathan port->fct_port, status); 673291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 674291a2b48SSukumar Swaminathan 675291a2b48SSukumar Swaminathan if (status == FCT_SUCCESS) { 676e2ca2865SSukumar Swaminathan if (fx->fx_op == ELS_OP_ACC) { 677291a2b48SSukumar Swaminathan (void) emlxs_els_reply(port, &iocbq, 678291a2b48SSukumar Swaminathan ELS_CMD_ACC, ELS_CMD_FLOGI, 0, 0); 679291a2b48SSukumar Swaminathan 680e2ca2865SSukumar Swaminathan } else { /* ELS_OP_LSRJT */ 681291a2b48SSukumar Swaminathan (void) emlxs_els_reply(port, &iocbq, 682e2ca2865SSukumar Swaminathan ELS_CMD_LS_RJT, ELS_CMD_FLOGI, 683e2ca2865SSukumar Swaminathan fx->fx_rjt_reason, fx->fx_rjt_expl); 684291a2b48SSukumar Swaminathan } 685291a2b48SSukumar Swaminathan } else { 686291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 687e2ca2865SSukumar Swaminathan "FLOGI: sid=%x xid=%x. " 688e2ca2865SSukumar Swaminathan "fct_handle_rcvd_flogi failed. Rejecting.", 689e2ca2865SSukumar Swaminathan fx->fx_sid, iocbq.iocb.ULPCONTEXT); 690291a2b48SSukumar Swaminathan 691e2ca2865SSukumar Swaminathan (void) emlxs_els_reply(port, &iocbq, 692e2ca2865SSukumar Swaminathan ELS_CMD_LS_RJT, ELS_CMD_FLOGI, 693e2ca2865SSukumar Swaminathan LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 694291a2b48SSukumar Swaminathan } 695291a2b48SSukumar Swaminathan 696e2ca2865SSukumar Swaminathan return; 697291a2b48SSukumar Swaminathan } 698fcf3ce44SJohn Forte 699e2ca2865SSukumar Swaminathan if (save) { 700e2ca2865SSukumar Swaminathan /* Save FLOGI for later */ 701e2ca2865SSukumar Swaminathan bcopy(fx, &port->fx, sizeof (fct_flogi_xchg_t)); 702e2ca2865SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 703291a2b48SSukumar Swaminathan return; 704fcf3ce44SJohn Forte } 705291a2b48SSukumar Swaminathan 706e2ca2865SSukumar Swaminathan reject_it: 707291a2b48SSukumar Swaminathan 708e2ca2865SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 709fcf3ce44SJohn Forte 710e2ca2865SSukumar Swaminathan if (port->fct_flags & FCT_STATE_LINK_UP) { 711e2ca2865SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 712e2ca2865SSukumar Swaminathan "FLOGI: sid=%x xid=%x. Stale. Rejecting.", 713e2ca2865SSukumar Swaminathan fx->fx_sid, fx->rsvd2); 714fcf3ce44SJohn Forte 715e2ca2865SSukumar Swaminathan bzero((uint8_t *)&iocbq, sizeof (IOCBQ)); 716e2ca2865SSukumar Swaminathan iocbq.iocb.un.elsreq.remoteID = fx->fx_sid; 717e2ca2865SSukumar Swaminathan iocbq.iocb.un.elsreq.myID = fx->fx_did; 718e2ca2865SSukumar Swaminathan iocbq.iocb.ULPCONTEXT = fx->rsvd2; 719291a2b48SSukumar Swaminathan 720e2ca2865SSukumar Swaminathan (void) emlxs_els_reply(port, &iocbq, 721e2ca2865SSukumar Swaminathan ELS_CMD_LS_RJT, ELS_CMD_FLOGI, 722e2ca2865SSukumar Swaminathan LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 723fcf3ce44SJohn Forte 724e2ca2865SSukumar Swaminathan /* If we have an FLOGI saved, try sending it now */ 725e2ca2865SSukumar Swaminathan if (port->fx.fx_op) { 726e2ca2865SSukumar Swaminathan fx = NULL; 727e2ca2865SSukumar Swaminathan goto begin; 728e2ca2865SSukumar Swaminathan } 729291a2b48SSukumar Swaminathan 730e2ca2865SSukumar Swaminathan } else { 731e2ca2865SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 732e2ca2865SSukumar Swaminathan "FLOGI: sid=%x xid=%x. Link down. " 733e2ca2865SSukumar Swaminathan "Dropping.", 734e2ca2865SSukumar Swaminathan fx->fx_sid, fx->rsvd2); 735291a2b48SSukumar Swaminathan } 73682527734SSukumar Swaminathan 737fcf3ce44SJohn Forte return; 738fcf3ce44SJohn Forte 739e2ca2865SSukumar Swaminathan } /* emlxs_fct_handle_unsol_flogi() */ 740fcf3ce44SJohn Forte 741fcf3ce44SJohn Forte 742fcf3ce44SJohn Forte /* This is called at port online and offline */ 743fcf3ce44SJohn Forte static void 744fcf3ce44SJohn Forte emlxs_fct_unsol_flush(emlxs_port_t *port) 745fcf3ce44SJohn Forte { 746fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 747fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 748fcf3ce44SJohn Forte emlxs_buf_t *next; 749fcf3ce44SJohn Forte fct_cmd_t *fct_cmd; 75082527734SSukumar Swaminathan fct_status_t rval; 751e2ca2865SSukumar Swaminathan uint32_t cmd_code; 752fcf3ce44SJohn Forte 753fcf3ce44SJohn Forte if (!port->fct_port) { 754fcf3ce44SJohn Forte return; 755fcf3ce44SJohn Forte } 756291a2b48SSukumar Swaminathan 757e2ca2865SSukumar Swaminathan /* First handle any pending FLOGI */ 758e2ca2865SSukumar Swaminathan emlxs_fct_handle_unsol_flogi(port, NULL, 0); 759291a2b48SSukumar Swaminathan 760e2ca2865SSukumar Swaminathan /* Wait queue */ 761fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 762fcf3ce44SJohn Forte cmd_sbp = port->fct_wait_head; 763fcf3ce44SJohn Forte port->fct_wait_head = NULL; 764fcf3ce44SJohn Forte port->fct_wait_tail = NULL; 765fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 766fcf3ce44SJohn Forte 767291a2b48SSukumar Swaminathan /* 768291a2b48SSukumar Swaminathan * Next process any outstanding ELS commands. It doesn't 769291a2b48SSukumar Swaminathan * matter if the Link is up or not, always post them to FCT. 770291a2b48SSukumar Swaminathan */ 771fcf3ce44SJohn Forte while (cmd_sbp) { 772fcf3ce44SJohn Forte next = cmd_sbp->next; 773fcf3ce44SJohn Forte fct_cmd = cmd_sbp->fct_cmd; 774fcf3ce44SJohn Forte 775e2ca2865SSukumar Swaminathan cmd_code = (fct_cmd->cmd_oxid << ELS_CMD_SHIFT); 776e2ca2865SSukumar Swaminathan 77782527734SSukumar Swaminathan /* Reacquire ownership of the fct_cmd */ 77882527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, 0); 77982527734SSukumar Swaminathan if (rval) { 78082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 781e2ca2865SSukumar Swaminathan "emlxs_fct_unsol_flush: %s: sid=%x xid=%x " 782e2ca2865SSukumar Swaminathan "Unable to reacquire fct_cmd.", 783e2ca2865SSukumar Swaminathan emlxs_elscmd_xlate(cmd_code), 784e2ca2865SSukumar Swaminathan fct_cmd->cmd_rxid, fct_cmd->cmd_rportid); 78582527734SSukumar Swaminathan 78682527734SSukumar Swaminathan cmd_sbp = next; 78782527734SSukumar Swaminathan continue; 78882527734SSukumar Swaminathan } 78982527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 79082527734SSukumar Swaminathan 791291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 792e2ca2865SSukumar Swaminathan "Completing %s: sid=%x xid=%x %p", 793e2ca2865SSukumar Swaminathan emlxs_elscmd_xlate(cmd_code), 794e2ca2865SSukumar Swaminathan fct_cmd->cmd_rportid, fct_cmd->cmd_rxid, 795e2ca2865SSukumar Swaminathan fct_cmd); 796fcf3ce44SJohn Forte 79782527734SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 79882527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 799fcf3ce44SJohn Forte 800fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 801291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 802291a2b48SSukumar Swaminathan "fct_post_rcvd_cmd:2 %p: portid x%x", fct_cmd, 803291a2b48SSukumar Swaminathan fct_cmd->cmd_lportid); 804291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 80582527734SSukumar Swaminathan 806291a2b48SSukumar Swaminathan MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0); 807fcf3ce44SJohn Forte 808fcf3ce44SJohn Forte cmd_sbp = next; 809fcf3ce44SJohn Forte 81082527734SSukumar Swaminathan } /* while () */ 811fcf3ce44SJohn Forte 812fcf3ce44SJohn Forte return; 813fcf3ce44SJohn Forte 81482527734SSukumar Swaminathan } /* emlxs_fct_unsol_flush() */ 815fcf3ce44SJohn Forte 816fcf3ce44SJohn Forte 817fcf3ce44SJohn Forte int 818fcf3ce44SJohn Forte emlxs_is_digit(uint8_t chr) 819fcf3ce44SJohn Forte { 820fcf3ce44SJohn Forte if ((chr >= '0') && (chr <= '9')) { 821fcf3ce44SJohn Forte return (1); 822fcf3ce44SJohn Forte } 823291a2b48SSukumar Swaminathan 824fcf3ce44SJohn Forte return (0); 825fcf3ce44SJohn Forte 82682527734SSukumar Swaminathan } /* emlxs_is_digit */ 827fcf3ce44SJohn Forte 828fcf3ce44SJohn Forte 829fcf3ce44SJohn Forte /* 830fcf3ce44SJohn Forte * Convert an ASCII decimal numeric string to integer. 831fcf3ce44SJohn Forte * Negation character '-' is not handled. 832fcf3ce44SJohn Forte */ 833fcf3ce44SJohn Forte uint32_t 834fcf3ce44SJohn Forte emlxs_str_atoi(uint8_t *string) 835fcf3ce44SJohn Forte { 836fcf3ce44SJohn Forte uint32_t num = 0; 837fcf3ce44SJohn Forte int i = 0; 838fcf3ce44SJohn Forte 839fcf3ce44SJohn Forte while (string[i]) { 840fcf3ce44SJohn Forte if (!emlxs_is_digit(string[i])) { 841fcf3ce44SJohn Forte return (num); 842fcf3ce44SJohn Forte } 843291a2b48SSukumar Swaminathan 844fcf3ce44SJohn Forte num = num * 10 + (string[i++] - '0'); 845fcf3ce44SJohn Forte } 846fcf3ce44SJohn Forte 847fcf3ce44SJohn Forte return (num); 848fcf3ce44SJohn Forte 84982527734SSukumar Swaminathan } /* emlxs_str_atoi() */ 850fcf3ce44SJohn Forte 851fcf3ce44SJohn Forte 852fcf3ce44SJohn Forte static void 853fcf3ce44SJohn Forte emlxs_init_fct_bufpool(emlxs_hba_t *hba, char **arrayp, uint32_t cnt) 854fcf3ce44SJohn Forte { 855fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 856fcf3ce44SJohn Forte uint8_t *datap; 857fcf3ce44SJohn Forte int i; 858291a2b48SSukumar Swaminathan int bck; 859291a2b48SSukumar Swaminathan int nbufs; 860291a2b48SSukumar Swaminathan int maxbufs; 861291a2b48SSukumar Swaminathan int size; 862fcf3ce44SJohn Forte 863fcf3ce44SJohn Forte bzero((uint8_t *)port->dmem_bucket, sizeof (port->dmem_bucket)); 864291a2b48SSukumar Swaminathan bck = 0; 865fcf3ce44SJohn Forte for (i = 0; i < cnt; i++) { 866fcf3ce44SJohn Forte datap = (uint8_t *)arrayp[i]; 867fcf3ce44SJohn Forte if (datap == 0) 868fcf3ce44SJohn Forte break; 869fcf3ce44SJohn Forte 870fcf3ce44SJohn Forte while (*datap == ' ') /* Skip spaces */ 871fcf3ce44SJohn Forte datap++; 872fcf3ce44SJohn Forte 873291a2b48SSukumar Swaminathan size = emlxs_str_atoi(datap); 874fcf3ce44SJohn Forte 875fcf3ce44SJohn Forte while ((*datap != ':') && (*datap != 0)) 876fcf3ce44SJohn Forte datap++; 877fcf3ce44SJohn Forte if (*datap == ':') /* Skip past delimeter */ 878fcf3ce44SJohn Forte datap++; 879fcf3ce44SJohn Forte while (*datap == ' ') /* Skip spaces */ 880fcf3ce44SJohn Forte datap++; 881fcf3ce44SJohn Forte 882291a2b48SSukumar Swaminathan nbufs = emlxs_str_atoi(datap); 883fcf3ce44SJohn Forte 884fcf3ce44SJohn Forte /* Check for a bad entry */ 885291a2b48SSukumar Swaminathan if (!size || !nbufs) { 886fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 887291a2b48SSukumar Swaminathan "Bad fct-bufpool entry %d %d", size, nbufs); 888291a2b48SSukumar Swaminathan 889291a2b48SSukumar Swaminathan port->dmem_bucket[bck].dmem_buf_size = 0; 890291a2b48SSukumar Swaminathan port->dmem_bucket[bck].dmem_nbufs = 0; 891291a2b48SSukumar Swaminathan size = 0; 892291a2b48SSukumar Swaminathan nbufs = 0; 893291a2b48SSukumar Swaminathan } 894291a2b48SSukumar Swaminathan 895291a2b48SSukumar Swaminathan while (nbufs) { 896291a2b48SSukumar Swaminathan port->dmem_bucket[bck].dmem_buf_size = size; 897291a2b48SSukumar Swaminathan port->dmem_bucket[bck].dmem_nbufs = nbufs; 898291a2b48SSukumar Swaminathan 899291a2b48SSukumar Swaminathan /* 900291a2b48SSukumar Swaminathan * We are not going to try to allocate a chunk 901291a2b48SSukumar Swaminathan * of memory > FCT_DMEM_MAX_BUF_SEGMENT 902291a2b48SSukumar Swaminathan * to accomidate the buffer pool of the 903291a2b48SSukumar Swaminathan * requested size. 904291a2b48SSukumar Swaminathan */ 905291a2b48SSukumar Swaminathan maxbufs = (FCT_DMEM_MAX_BUF_SEGMENT / size); 906fcf3ce44SJohn Forte 907291a2b48SSukumar Swaminathan if (nbufs > maxbufs) { 908291a2b48SSukumar Swaminathan port->dmem_bucket[bck].dmem_nbufs = maxbufs; 909291a2b48SSukumar Swaminathan nbufs -= maxbufs; 910291a2b48SSukumar Swaminathan bck++; 911291a2b48SSukumar Swaminathan if (bck >= FCT_MAX_BUCKETS) 912291a2b48SSukumar Swaminathan break; 913291a2b48SSukumar Swaminathan } else { 914291a2b48SSukumar Swaminathan bck++; 915291a2b48SSukumar Swaminathan nbufs = 0; 916291a2b48SSukumar Swaminathan } 917fcf3ce44SJohn Forte } 918291a2b48SSukumar Swaminathan 919291a2b48SSukumar Swaminathan if (bck >= FCT_MAX_BUCKETS) { 920291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 921291a2b48SSukumar Swaminathan "fct-bufpool entry %d %d Exceeds available buckets", 922291a2b48SSukumar Swaminathan size, nbufs); 923fcf3ce44SJohn Forte break; 924291a2b48SSukumar Swaminathan } 925fcf3ce44SJohn Forte } 926fcf3ce44SJohn Forte } 927fcf3ce44SJohn Forte 928fcf3ce44SJohn Forte 929fcf3ce44SJohn Forte static void 930fcf3ce44SJohn Forte emlxs_fct_cfg_init(emlxs_hba_t *hba) 931fcf3ce44SJohn Forte { 932fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 933fcf3ce44SJohn Forte char **arrayp; 934fcf3ce44SJohn Forte uint32_t cnt; 935fcf3ce44SJohn Forte char buf[32]; 936fcf3ce44SJohn Forte int status; 937fcf3ce44SJohn Forte 938291a2b48SSukumar Swaminathan bzero((void *)buf, 32); 939fcf3ce44SJohn Forte cnt = 0; 940fcf3ce44SJohn Forte arrayp = NULL; 941fcf3ce44SJohn Forte 942fcf3ce44SJohn Forte (void) sprintf(buf, "emlxs%d-fct-bufpool", ddi_get_instance(hba->dip)); 943fcf3ce44SJohn Forte status = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, hba->dip, 944fcf3ce44SJohn Forte (DDI_PROP_DONTPASS), buf, &arrayp, &cnt); 945fcf3ce44SJohn Forte 946fcf3ce44SJohn Forte if ((status == DDI_PROP_SUCCESS) && cnt && arrayp) { 947fcf3ce44SJohn Forte emlxs_init_fct_bufpool(hba, arrayp, cnt); 948fcf3ce44SJohn Forte } else { 949fcf3ce44SJohn Forte status = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, hba->dip, 950fcf3ce44SJohn Forte (DDI_PROP_DONTPASS), "fct-bufpool", &arrayp, &cnt); 951fcf3ce44SJohn Forte 952fcf3ce44SJohn Forte if ((status == DDI_PROP_SUCCESS) && cnt && arrayp) { 953fcf3ce44SJohn Forte emlxs_init_fct_bufpool(hba, arrayp, cnt); 954fcf3ce44SJohn Forte } else { 955fcf3ce44SJohn Forte bzero((uint8_t *)port->dmem_bucket, 956fcf3ce44SJohn Forte sizeof (port->dmem_bucket)); 957fcf3ce44SJohn Forte port->dmem_bucket[0].dmem_buf_size = 512; 958fcf3ce44SJohn Forte port->dmem_bucket[0].dmem_nbufs = FCT_BUF_COUNT_512; 959291a2b48SSukumar Swaminathan port->dmem_bucket[1].dmem_buf_size = (2 * 65536); 960291a2b48SSukumar Swaminathan port->dmem_bucket[1].dmem_nbufs = FCT_BUF_COUNT_128K; 961fcf3ce44SJohn Forte } 962fcf3ce44SJohn Forte } 963fcf3ce44SJohn Forte 964fcf3ce44SJohn Forte bzero((void *)buf, 32); 965fcf3ce44SJohn Forte cnt = 0; 966fcf3ce44SJohn Forte 967291a2b48SSukumar Swaminathan /* 968291a2b48SSukumar Swaminathan * 0 means use HBA throttle for target queue depth, 969291a2b48SSukumar Swaminathan * non-0 value is the actual target queue depth, 970291a2b48SSukumar Swaminathan * default is EMLXS_FCT_DFLT_QDEPTH. 971291a2b48SSukumar Swaminathan */ 972fcf3ce44SJohn Forte (void) sprintf(buf, "emlxs%d-fct-queue-depth", 973fcf3ce44SJohn Forte ddi_get_instance(hba->dip)); 974fcf3ce44SJohn Forte cnt = ddi_prop_get_int(DDI_DEV_T_ANY, hba->dip, 975291a2b48SSukumar Swaminathan (DDI_PROP_DONTPASS), buf, EMLXS_FCT_DFLT_QDEPTH); 976fcf3ce44SJohn Forte 977291a2b48SSukumar Swaminathan if ((cnt == DDI_PROP_NOT_FOUND) || (cnt == EMLXS_FCT_DFLT_QDEPTH)) { 978fcf3ce44SJohn Forte cnt = ddi_prop_get_int(DDI_DEV_T_ANY, hba->dip, 979291a2b48SSukumar Swaminathan (DDI_PROP_DONTPASS), "fct-queue-depth", 980291a2b48SSukumar Swaminathan EMLXS_FCT_DFLT_QDEPTH); 981fcf3ce44SJohn Forte 982fcf3ce44SJohn Forte if (cnt == DDI_PROP_NOT_FOUND) { 983291a2b48SSukumar Swaminathan cnt = EMLXS_FCT_DFLT_QDEPTH; 984fcf3ce44SJohn Forte } 985fcf3ce44SJohn Forte } 986291a2b48SSukumar Swaminathan 987fcf3ce44SJohn Forte port->fct_queue_depth = cnt; 988291a2b48SSukumar Swaminathan 989291a2b48SSukumar Swaminathan #ifdef FCT_IO_TRACE 990291a2b48SSukumar Swaminathan port->iotrace_cnt = 1024; 991291a2b48SSukumar Swaminathan port->iotrace_index = 0; 992291a2b48SSukumar Swaminathan if (cnt) 993291a2b48SSukumar Swaminathan port->iotrace_cnt = (2 * cnt); 994291a2b48SSukumar Swaminathan port->iotrace = 995291a2b48SSukumar Swaminathan kmem_zalloc(port->iotrace_cnt * sizeof (emlxs_iotrace_t), 996291a2b48SSukumar Swaminathan KM_SLEEP); 99782527734SSukumar Swaminathan 998291a2b48SSukumar Swaminathan mutex_init(&port->iotrace_mtx, NULL, MUTEX_DRIVER, 999291a2b48SSukumar Swaminathan (void *)hba->intr_arg); 1000291a2b48SSukumar Swaminathan emlxs_iotrace = (uint8_t *)port->iotrace; 1001291a2b48SSukumar Swaminathan emlxs_iotrace_cnt = port->iotrace_cnt; 1002291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1003291a2b48SSukumar Swaminathan "IOTRACE: init:%p cnt:%d", emlxs_iotrace, emlxs_iotrace_cnt); 1004291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1005291a2b48SSukumar Swaminathan "FCT_ABORT_SUCCESS:%lx FCT_SUCCESS:%lx", FCT_ABORT_SUCCESS, 1006291a2b48SSukumar Swaminathan FCT_SUCCESS); 1007291a2b48SSukumar Swaminathan #endif /* FCT_IO_TRACE */ 1008fcf3ce44SJohn Forte return; 1009fcf3ce44SJohn Forte 101082527734SSukumar Swaminathan } /* emlxs_fct_cfg_init() */ 1011fcf3ce44SJohn Forte 1012fcf3ce44SJohn Forte 1013fcf3ce44SJohn Forte extern void 1014fcf3ce44SJohn Forte emlxs_fct_init(emlxs_hba_t *hba) 1015fcf3ce44SJohn Forte { 1016fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1017fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 1018fcf3ce44SJohn Forte emlxs_port_t *vport; 1019fcf3ce44SJohn Forte uint32_t i; 1020fcf3ce44SJohn Forte 1021fcf3ce44SJohn Forte if (!hba->tgt_mode) { 1022fcf3ce44SJohn Forte return; 1023fcf3ce44SJohn Forte } 1024fcf3ce44SJohn Forte 1025fcf3ce44SJohn Forte /* Check if COMSTAR is present */ 1026fcf3ce44SJohn Forte if (((void *)MODSYM(stmf_alloc) == NULL) || 1027291a2b48SSukumar Swaminathan ((void *)MODSYM(fct_alloc) == NULL)) { 1028fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg, 1029fcf3ce44SJohn Forte "Comstar not present. Target mode disabled."); 1030fcf3ce44SJohn Forte goto failed; 1031fcf3ce44SJohn Forte } 1032291a2b48SSukumar Swaminathan 1033fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg, 1034fcf3ce44SJohn Forte "Comstar present. Target mode enabled."); 1035fcf3ce44SJohn Forte 1036fcf3ce44SJohn Forte if (cfg[CFG_NPIV_ENABLE].current) { 1037fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 1038fcf3ce44SJohn Forte "enable-npiv: Not supported in target mode. Disabling."); 1039fcf3ce44SJohn Forte 1040fcf3ce44SJohn Forte /* Temporary patch to disable npiv */ 1041fcf3ce44SJohn Forte cfg[CFG_NPIV_ENABLE].current = 0; 1042fcf3ce44SJohn Forte } 1043fcf3ce44SJohn Forte 1044fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 1045fcf3ce44SJohn Forte if (cfg[CFG_AUTH_ENABLE].current) { 1046fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 1047fcf3ce44SJohn Forte "enable-auth: Not supported in target mode. Disabling."); 1048fcf3ce44SJohn Forte 1049fcf3ce44SJohn Forte /* Temporary patch to disable auth */ 1050fcf3ce44SJohn Forte cfg[CFG_AUTH_ENABLE].current = 0; 1051fcf3ce44SJohn Forte } 1052291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */ 1053fcf3ce44SJohn Forte 1054fcf3ce44SJohn Forte emlxs_fct_cfg_init(hba); 1055fcf3ce44SJohn Forte return; 1056fcf3ce44SJohn Forte 1057fcf3ce44SJohn Forte failed: 1058fcf3ce44SJohn Forte 1059fcf3ce44SJohn Forte hba->tgt_mode = 0; 1060fcf3ce44SJohn Forte for (i = 0; i < MAX_VPORTS; i++) { 1061fcf3ce44SJohn Forte vport = &VPORT(i); 1062fcf3ce44SJohn Forte vport->tgt_mode = 0; 1063fcf3ce44SJohn Forte vport->fct_flags = 0; 1064fcf3ce44SJohn Forte } 1065291a2b48SSukumar Swaminathan 1066291a2b48SSukumar Swaminathan return; 1067291a2b48SSukumar Swaminathan 106882527734SSukumar Swaminathan } /* emlxs_fct_init() */ 1069fcf3ce44SJohn Forte 1070fcf3ce44SJohn Forte 1071fcf3ce44SJohn Forte extern void 1072fcf3ce44SJohn Forte emlxs_fct_attach(emlxs_hba_t *hba) 1073fcf3ce44SJohn Forte { 1074fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1075fcf3ce44SJohn Forte uint32_t vpi; 1076fcf3ce44SJohn Forte 1077fcf3ce44SJohn Forte if (!hba->tgt_mode) { 1078fcf3ce44SJohn Forte return; 1079fcf3ce44SJohn Forte } 1080291a2b48SSukumar Swaminathan 1081fcf3ce44SJohn Forte /* Bind the physical port */ 1082fcf3ce44SJohn Forte emlxs_fct_bind_port(port); 1083fcf3ce44SJohn Forte 1084fcf3ce44SJohn Forte /* Bind virtual ports */ 1085fcf3ce44SJohn Forte if (hba->flag & FC_NPIV_ENABLED) { 108682527734SSukumar Swaminathan for (vpi = 1; vpi <= hba->vpi_high; vpi++) { 1087fcf3ce44SJohn Forte port = &VPORT(vpi); 1088fcf3ce44SJohn Forte 1089fcf3ce44SJohn Forte if (!(port->flag & EMLXS_PORT_ENABLE)) { 1090fcf3ce44SJohn Forte continue; 1091fcf3ce44SJohn Forte } 1092291a2b48SSukumar Swaminathan 1093fcf3ce44SJohn Forte emlxs_fct_bind_port(port); 1094fcf3ce44SJohn Forte } 1095fcf3ce44SJohn Forte } 1096291a2b48SSukumar Swaminathan 1097fcf3ce44SJohn Forte return; 1098fcf3ce44SJohn Forte 109982527734SSukumar Swaminathan } /* emlxs_fct_attach() */ 1100fcf3ce44SJohn Forte 1101fcf3ce44SJohn Forte 1102fcf3ce44SJohn Forte extern void 1103fcf3ce44SJohn Forte emlxs_fct_detach(emlxs_hba_t *hba) 1104fcf3ce44SJohn Forte { 1105fcf3ce44SJohn Forte uint32_t i; 1106fcf3ce44SJohn Forte emlxs_port_t *vport; 1107fcf3ce44SJohn Forte 1108fcf3ce44SJohn Forte if (hba->tgt_mode) { 1109fcf3ce44SJohn Forte for (i = 0; i < MAX_VPORTS; i++) { 1110fcf3ce44SJohn Forte vport = &VPORT(i); 1111fcf3ce44SJohn Forte 1112fcf3ce44SJohn Forte if (!vport->tgt_mode) { 1113fcf3ce44SJohn Forte continue; 1114fcf3ce44SJohn Forte } 1115291a2b48SSukumar Swaminathan 1116fcf3ce44SJohn Forte emlxs_fct_unbind_port(vport); 1117fcf3ce44SJohn Forte vport->tgt_mode = 0; 1118fcf3ce44SJohn Forte } 1119fcf3ce44SJohn Forte 1120fcf3ce44SJohn Forte 1121fcf3ce44SJohn Forte hba->tgt_mode = 0; 1122fcf3ce44SJohn Forte } 1123291a2b48SSukumar Swaminathan #ifdef FCT_IO_TRACE 1124291a2b48SSukumar Swaminathan { 1125291a2b48SSukumar Swaminathan emlxs_port_t *port = &PPORT; 1126291a2b48SSukumar Swaminathan 1127291a2b48SSukumar Swaminathan mutex_destroy(&port->iotrace_mtx); 1128291a2b48SSukumar Swaminathan if (port->iotrace) 1129291a2b48SSukumar Swaminathan kmem_free(port->iotrace, 1130291a2b48SSukumar Swaminathan (port->iotrace_cnt * sizeof (emlxs_iotrace_t))); 1131291a2b48SSukumar Swaminathan port->iotrace = NULL; 1132291a2b48SSukumar Swaminathan } 1133291a2b48SSukumar Swaminathan #endif /* FCT_IO_TRACE */ 1134291a2b48SSukumar Swaminathan 1135fcf3ce44SJohn Forte return; 1136fcf3ce44SJohn Forte 113782527734SSukumar Swaminathan } /* emlxs_fct_detach() */ 1138fcf3ce44SJohn Forte 1139fcf3ce44SJohn Forte 1140fcf3ce44SJohn Forte extern void 1141fcf3ce44SJohn Forte emlxs_fct_unbind_port(emlxs_port_t *port) 1142fcf3ce44SJohn Forte { 1143fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1144fcf3ce44SJohn Forte char node_name[32]; 1145fcf3ce44SJohn Forte 1146fcf3ce44SJohn Forte if (!port->tgt_mode) { 1147fcf3ce44SJohn Forte return; 1148fcf3ce44SJohn Forte } 1149291a2b48SSukumar Swaminathan 1150fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 1151fcf3ce44SJohn Forte if (!(port->flag & EMLXS_PORT_BOUND)) { 1152fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1153fcf3ce44SJohn Forte return; 1154fcf3ce44SJohn Forte } 1155291a2b48SSukumar Swaminathan 1156fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1157fcf3ce44SJohn Forte "emlxs_fct_unbind_port: port=%d", port->vpi); 1158fcf3ce44SJohn Forte 1159fcf3ce44SJohn Forte /* Destroy & flush all port nodes, if they exist */ 1160fcf3ce44SJohn Forte if (port->node_count) { 116182527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 116282527734SSukumar Swaminathan (void) emlxs_sli4_unreg_all_rpi_by_port(port); 116382527734SSukumar Swaminathan } else { 116482527734SSukumar Swaminathan (void) emlxs_mb_unreg_rpi(port, 0xffff, 0, 0, 116582527734SSukumar Swaminathan 0); 116682527734SSukumar Swaminathan } 1167fcf3ce44SJohn Forte } 1168291a2b48SSukumar Swaminathan 1169fcf3ce44SJohn Forte port->flag &= ~EMLXS_PORT_BOUND; 1170fcf3ce44SJohn Forte hba->num_of_ports--; 1171fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1172fcf3ce44SJohn Forte 1173fcf3ce44SJohn Forte if (port->fct_port) { 1174fcf3ce44SJohn Forte emlxs_fct_link_down(port); 1175fcf3ce44SJohn Forte emlxs_fct_unsol_flush(port); 1176fcf3ce44SJohn Forte 1177fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1178fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1179fcf3ce44SJohn Forte "fct_deregister_local_port %p", port->fct_port); 1180291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1181fcf3ce44SJohn Forte MODSYM(fct_deregister_local_port) (port->fct_port); 1182fcf3ce44SJohn Forte 1183fcf3ce44SJohn Forte if (port->fct_port->port_fds) { 1184fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1185fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1186fcf3ce44SJohn Forte "fct_free:3 %p", port->fct_port->port_fds); 1187291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1188fcf3ce44SJohn Forte MODSYM(fct_free) (port->fct_port->port_fds); 1189fcf3ce44SJohn Forte port->fct_port->port_fds = NULL; 1190fcf3ce44SJohn Forte } 1191fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1192fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1193fcf3ce44SJohn Forte "fct_free:4 %p", port->fct_port); 1194291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1195fcf3ce44SJohn Forte MODSYM(fct_free) (port->fct_port); 1196fcf3ce44SJohn Forte port->fct_port = NULL; 1197fcf3ce44SJohn Forte port->fct_flags = 0; 1198fcf3ce44SJohn Forte } 1199291a2b48SSukumar Swaminathan 1200fcf3ce44SJohn Forte if (port->port_provider) { 1201fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1202fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1203291a2b48SSukumar Swaminathan "stmf_deregister_port_provider:1 %p", 1204291a2b48SSukumar Swaminathan port->port_provider); 1205291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1206fcf3ce44SJohn Forte MODSYM(stmf_deregister_port_provider) (port->port_provider); 1207fcf3ce44SJohn Forte 1208fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1209fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1210fcf3ce44SJohn Forte "stmf_free:1 %p", port->port_provider); 1211291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1212fcf3ce44SJohn Forte MODSYM(stmf_free) (port->port_provider); 1213fcf3ce44SJohn Forte port->port_provider = NULL; 1214fcf3ce44SJohn Forte } 1215291a2b48SSukumar Swaminathan 1216fcf3ce44SJohn Forte if (port->dmem_bucket) { 1217fcf3ce44SJohn Forte emlxs_fct_dmem_fini(port); 1218fcf3ce44SJohn Forte } 1219291a2b48SSukumar Swaminathan 1220fcf3ce44SJohn Forte (void) sprintf(node_name, "%d,%d:SFCT", hba->ddiinst, port->vpi); 1221fcf3ce44SJohn Forte (void) ddi_remove_minor_node(hba->dip, node_name); 1222fcf3ce44SJohn Forte 1223fcf3ce44SJohn Forte return; 1224fcf3ce44SJohn Forte 122582527734SSukumar Swaminathan } /* emlxs_fct_unbind_port() */ 1226fcf3ce44SJohn Forte 1227fcf3ce44SJohn Forte 1228fcf3ce44SJohn Forte extern void 1229fcf3ce44SJohn Forte emlxs_fct_bind_port(emlxs_port_t *port) 1230fcf3ce44SJohn Forte { 1231fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1232fcf3ce44SJohn Forte fct_local_port_t *fct_port; 1233fcf3ce44SJohn Forte uint32_t flag = 0; 1234fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 1235fcf3ce44SJohn Forte fct_dbuf_store_t *fds; 1236fcf3ce44SJohn Forte char node_name[32]; 123782527734SSukumar Swaminathan uint8_t *bptr; 1238fcf3ce44SJohn Forte 1239fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 1240fcf3ce44SJohn Forte 1241fcf3ce44SJohn Forte if (!hba->tgt_mode || !port->tgt_mode) { 1242fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1243fcf3ce44SJohn Forte return; 1244fcf3ce44SJohn Forte } 1245291a2b48SSukumar Swaminathan 1246fcf3ce44SJohn Forte if (port->flag & EMLXS_PORT_BOUND) { 1247fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1248fcf3ce44SJohn Forte return; 1249fcf3ce44SJohn Forte } 1250291a2b48SSukumar Swaminathan 1251fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1252fcf3ce44SJohn Forte "emlxs_fct_bind_port: port=%d", port->vpi); 1253fcf3ce44SJohn Forte 1254fcf3ce44SJohn Forte /* Perform generic port initialization */ 1255fcf3ce44SJohn Forte emlxs_port_init(port); 1256fcf3ce44SJohn Forte 1257fcf3ce44SJohn Forte if (port->vpi == 0) { 1258fcf3ce44SJohn Forte (void) sprintf(port->cfd_name, "%s%d", DRIVER_NAME, 1259fcf3ce44SJohn Forte hba->ddiinst); 1260fcf3ce44SJohn Forte } else { 1261fcf3ce44SJohn Forte (void) sprintf(port->cfd_name, "%s%d.%d", DRIVER_NAME, 1262fcf3ce44SJohn Forte hba->ddiinst, port->vpi); 1263fcf3ce44SJohn Forte } 1264fcf3ce44SJohn Forte 1265fcf3ce44SJohn Forte if (emlxs_fct_dmem_init(port) != FCT_SUCCESS) { 1266fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1267fcf3ce44SJohn Forte "emlxs_fct_bind_port: Unable to allocate fct memory."); 1268fcf3ce44SJohn Forte goto failed; 1269fcf3ce44SJohn Forte } 1270fcf3ce44SJohn Forte flag |= 0x00000001; 1271fcf3ce44SJohn Forte 1272291a2b48SSukumar Swaminathan port->port_provider = 1273291a2b48SSukumar Swaminathan (stmf_port_provider_t *) 1274fcf3ce44SJohn Forte MODSYM(stmf_alloc) (STMF_STRUCT_PORT_PROVIDER, 0, 0); 1275fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1276fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1277fcf3ce44SJohn Forte "stmf_alloc port_provider %p", port->port_provider); 1278291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1279fcf3ce44SJohn Forte 1280fcf3ce44SJohn Forte if (port->port_provider == NULL) { 1281fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1282291a2b48SSukumar Swaminathan "emlxs_fct_bind_port: Unable to allocate port provider."); 1283fcf3ce44SJohn Forte goto failed; 1284fcf3ce44SJohn Forte } 1285fcf3ce44SJohn Forte flag |= 0x00000002; 1286fcf3ce44SJohn Forte 1287fcf3ce44SJohn Forte port->port_provider->pp_portif_rev = PORTIF_REV_1; 1288fcf3ce44SJohn Forte port->port_provider->pp_name = port->cfd_name; 1289fcf3ce44SJohn Forte port->port_provider->pp_provider_private = port; 1290fcf3ce44SJohn Forte 1291fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1292fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1293fcf3ce44SJohn Forte "stmf_register_port_provider %p", port->port_provider); 1294291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1295fcf3ce44SJohn Forte /* register port provider with framework */ 1296291a2b48SSukumar Swaminathan if (MODSYM(stmf_register_port_provider) (port->port_provider) != 1297291a2b48SSukumar Swaminathan STMF_SUCCESS) { 1298fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1299291a2b48SSukumar Swaminathan "emlxs_fct_bind_port: Unable to register port provider."); 1300fcf3ce44SJohn Forte goto failed; 1301fcf3ce44SJohn Forte } 1302fcf3ce44SJohn Forte flag |= 0x00000004; 1303fcf3ce44SJohn Forte 1304291a2b48SSukumar Swaminathan port->fct_port = 1305291a2b48SSukumar Swaminathan (fct_local_port_t *)MODSYM(fct_alloc) (FCT_STRUCT_LOCAL_PORT, 0, 1306291a2b48SSukumar Swaminathan 0); 1307fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1308fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1309fcf3ce44SJohn Forte "fct_alloc fct_port %p", port->fct_port); 1310291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1311fcf3ce44SJohn Forte 1312fcf3ce44SJohn Forte if (port->fct_port == NULL) { 1313fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1314fcf3ce44SJohn Forte "emlxs_fct_bind_port: Unable to allocate fct port."); 1315fcf3ce44SJohn Forte goto failed; 1316fcf3ce44SJohn Forte } 1317fcf3ce44SJohn Forte flag |= 0x00000008; 1318fcf3ce44SJohn Forte 1319291a2b48SSukumar Swaminathan port->fct_port->port_fds = 1320291a2b48SSukumar Swaminathan (fct_dbuf_store_t *)MODSYM(fct_alloc) (FCT_STRUCT_DBUF_STORE, 0, 1321291a2b48SSukumar Swaminathan 0); 1322fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1323fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1324fcf3ce44SJohn Forte "fct_alloc port_fds %p", port->fct_port->port_fds); 1325291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1326fcf3ce44SJohn Forte 1327fcf3ce44SJohn Forte if (port->fct_port->port_fds == NULL) { 1328fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1329fcf3ce44SJohn Forte "emlxs_fct_bind_port: Unable to allocate dbuf store."); 1330fcf3ce44SJohn Forte goto failed; 1331fcf3ce44SJohn Forte } 1332fcf3ce44SJohn Forte flag |= 0x00000010; 1333fcf3ce44SJohn Forte 1334fcf3ce44SJohn Forte (void) sprintf(node_name, "%d,%d:SFCT", hba->ddiinst, port->vpi); 1335291a2b48SSukumar Swaminathan if (ddi_create_minor_node(hba->dip, node_name, S_IFCHR, hba->ddiinst, 1336291a2b48SSukumar Swaminathan NULL, 0) == DDI_FAILURE) { 1337fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1338fcf3ce44SJohn Forte "Unable to create SFCT device node."); 1339fcf3ce44SJohn Forte goto failed; 1340fcf3ce44SJohn Forte } 1341fcf3ce44SJohn Forte flag |= 0x00000020; 1342fcf3ce44SJohn Forte 1343fcf3ce44SJohn Forte /* Intialize */ 1344fcf3ce44SJohn Forte fct_port = port->fct_port; 1345162fafd3Sallan fct_port->port_fca_version = FCT_FCA_MODREV_1; 1346fcf3ce44SJohn Forte fct_port->port_fca_private = port; 1347fcf3ce44SJohn Forte fct_port->port_fca_abort_timeout = 30 * 1000; /* 30 seconds */ 1348fcf3ce44SJohn Forte 1349fcf3ce44SJohn Forte bcopy((uint8_t *)&port->wwpn, (uint8_t *)fct_port->port_pwwn, 8); 1350fcf3ce44SJohn Forte bcopy((uint8_t *)&port->wwnn, (uint8_t *)fct_port->port_nwwn, 8); 1351fcf3ce44SJohn Forte 135282527734SSukumar Swaminathan bptr = (uint8_t *)&port->wwnn; 135382527734SSukumar Swaminathan (void) sprintf(fct_port->port_nwwn_str, 135482527734SSukumar Swaminathan "%02x%02x%02x%02x%02x%02x%02x%02x", 135582527734SSukumar Swaminathan bptr[0], bptr[1], bptr[2], bptr[3], 135682527734SSukumar Swaminathan bptr[4], bptr[5], bptr[6], bptr[7]); 135782527734SSukumar Swaminathan 135882527734SSukumar Swaminathan bptr = (uint8_t *)&port->wwpn; 135982527734SSukumar Swaminathan (void) sprintf(fct_port->port_pwwn_str, 136082527734SSukumar Swaminathan "%02x%02x%02x%02x%02x%02x%02x%02x", 136182527734SSukumar Swaminathan bptr[0], bptr[1], bptr[2], bptr[3], 136282527734SSukumar Swaminathan bptr[4], bptr[5], bptr[6], bptr[7]); 136382527734SSukumar Swaminathan 1364fcf3ce44SJohn Forte fct_port->port_sym_node_name = port->snn; 1365fcf3ce44SJohn Forte fct_port->port_sym_port_name = port->spn; 1366fcf3ce44SJohn Forte fct_port->port_hard_address = cfg[CFG_ASSIGN_ALPA].current; 1367fcf3ce44SJohn Forte fct_port->port_default_alias = port->cfd_name; 1368fcf3ce44SJohn Forte fct_port->port_pp = port->port_provider; 1369fcf3ce44SJohn Forte fct_port->port_max_logins = hba->max_nodes; 1370fcf3ce44SJohn Forte 1371291a2b48SSukumar Swaminathan if ((port->fct_queue_depth) && 1372291a2b48SSukumar Swaminathan (port->fct_queue_depth < hba->io_throttle)) { 1373fcf3ce44SJohn Forte fct_port->port_max_xchges = port->fct_queue_depth; 1374fcf3ce44SJohn Forte } else { 1375fcf3ce44SJohn Forte fct_port->port_max_xchges = hba->io_throttle; 1376fcf3ce44SJohn Forte } 1377fcf3ce44SJohn Forte 1378fcf3ce44SJohn Forte fct_port->port_fca_fcp_cmd_size = sizeof (emlxs_buf_t); 1379fcf3ce44SJohn Forte fct_port->port_fca_rp_private_size = sizeof (uintptr_t); 1380fcf3ce44SJohn Forte fct_port->port_fca_sol_els_private_size = sizeof (emlxs_buf_t); 1381fcf3ce44SJohn Forte fct_port->port_fca_sol_ct_private_size = sizeof (emlxs_buf_t); 1382fcf3ce44SJohn Forte fct_port->port_get_link_info = emlxs_fct_get_link_info; 1383fcf3ce44SJohn Forte fct_port->port_register_remote_port = emlxs_fct_register_remote_port; 1384fcf3ce44SJohn Forte fct_port->port_deregister_remote_port = 1385fcf3ce44SJohn Forte emlxs_fct_deregister_remote_port; 1386fcf3ce44SJohn Forte fct_port->port_send_cmd = emlxs_fct_send_cmd; 1387fcf3ce44SJohn Forte fct_port->port_xfer_scsi_data = emlxs_fct_send_fcp_data; 1388fcf3ce44SJohn Forte fct_port->port_send_cmd_response = emlxs_fct_send_cmd_rsp; 1389fcf3ce44SJohn Forte fct_port->port_abort_cmd = emlxs_fct_abort; 1390fcf3ce44SJohn Forte fct_port->port_ctl = emlxs_fct_ctl; 139182527734SSukumar Swaminathan fct_port->port_flogi_xchg = emlxs_fct_flogi_xchg; 139282527734SSukumar Swaminathan fct_port->port_populate_hba_details = emlxs_fct_populate_hba_details; 139382527734SSukumar Swaminathan fct_port->port_info = emlxs_fct_port_info; 1394fcf3ce44SJohn Forte 1395fcf3ce44SJohn Forte fds = port->fct_port->port_fds; 1396fcf3ce44SJohn Forte fds->fds_fca_private = port; 1397fcf3ce44SJohn Forte fds->fds_alloc_data_buf = emlxs_fct_dbuf_alloc; 1398fcf3ce44SJohn Forte fds->fds_free_data_buf = emlxs_fct_dbuf_free; 1399fcf3ce44SJohn Forte 1400fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1401fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1402fcf3ce44SJohn Forte "fct_register_local_port %p", fct_port); 1403291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1404fcf3ce44SJohn Forte /* register this local port with the fct module */ 1405fcf3ce44SJohn Forte if (MODSYM(fct_register_local_port) (fct_port) != FCT_SUCCESS) { 1406fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1407fcf3ce44SJohn Forte "emlxs_fct_bind_port: Unable to register fct port."); 1408fcf3ce44SJohn Forte goto failed; 1409fcf3ce44SJohn Forte } 1410291a2b48SSukumar Swaminathan 1411fcf3ce44SJohn Forte /* Set the bound flag */ 1412fcf3ce44SJohn Forte port->flag |= EMLXS_PORT_BOUND; 1413fcf3ce44SJohn Forte hba->num_of_ports++; 1414fcf3ce44SJohn Forte 1415fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1416fcf3ce44SJohn Forte 1417fcf3ce44SJohn Forte return; 1418fcf3ce44SJohn Forte 1419fcf3ce44SJohn Forte failed: 1420fcf3ce44SJohn Forte 1421fcf3ce44SJohn Forte if (flag & 0x20) { 1422fcf3ce44SJohn Forte (void) ddi_remove_minor_node(hba->dip, node_name); 1423fcf3ce44SJohn Forte } 1424291a2b48SSukumar Swaminathan 1425fcf3ce44SJohn Forte if (flag & 0x10) { 1426fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1427fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1428fcf3ce44SJohn Forte "fct_free:5 %p", port->fct_port->port_fds); 1429291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1430fcf3ce44SJohn Forte MODSYM(fct_free) (port->fct_port->port_fds); 1431fcf3ce44SJohn Forte port->fct_port->port_fds = NULL; 1432fcf3ce44SJohn Forte } 1433291a2b48SSukumar Swaminathan 1434fcf3ce44SJohn Forte if (flag & 0x8) { 1435fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1436fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1437fcf3ce44SJohn Forte "fct_free:6 %p", port->fct_port); 1438291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1439fcf3ce44SJohn Forte MODSYM(fct_free) (port->fct_port); 1440fcf3ce44SJohn Forte port->fct_port = NULL; 1441fcf3ce44SJohn Forte port->fct_flags = 0; 1442fcf3ce44SJohn Forte } 1443291a2b48SSukumar Swaminathan 1444fcf3ce44SJohn Forte if (flag & 0x4) { 1445fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1446fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1447291a2b48SSukumar Swaminathan "stmf_deregister_port_provider:2 %p", 1448291a2b48SSukumar Swaminathan port->port_provider); 1449291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1450fcf3ce44SJohn Forte MODSYM(stmf_deregister_port_provider) (port->port_provider); 1451fcf3ce44SJohn Forte } 1452291a2b48SSukumar Swaminathan 1453fcf3ce44SJohn Forte if (flag & 0x2) { 1454fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1455fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1456fcf3ce44SJohn Forte "stmf_free:2 %p", port->port_provider); 1457291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1458fcf3ce44SJohn Forte MODSYM(stmf_free) (port->port_provider); 1459fcf3ce44SJohn Forte port->port_provider = NULL; 1460fcf3ce44SJohn Forte } 1461291a2b48SSukumar Swaminathan 1462fcf3ce44SJohn Forte if (flag & 0x1) { 1463fcf3ce44SJohn Forte emlxs_fct_dmem_fini(port); 1464fcf3ce44SJohn Forte } 1465291a2b48SSukumar Swaminathan 1466fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 1467fcf3ce44SJohn Forte "Target mode disabled."); 1468fcf3ce44SJohn Forte 1469fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 1470fcf3ce44SJohn Forte 1471fcf3ce44SJohn Forte return; 1472fcf3ce44SJohn Forte 147382527734SSukumar Swaminathan } /* emlxs_fct_bind_port() */ 147482527734SSukumar Swaminathan 147582527734SSukumar Swaminathan 147682527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 147782527734SSukumar Swaminathan /*ARGSUSED*/ 147882527734SSukumar Swaminathan static fct_status_t 147982527734SSukumar Swaminathan emlxs_fct_port_info(uint32_t cmd, fct_local_port_t *fct_port, void *arg, 148082527734SSukumar Swaminathan uint8_t *buffer, uint32_t *size) 148182527734SSukumar Swaminathan { 148282527734SSukumar Swaminathan emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 148382527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 148482527734SSukumar Swaminathan fct_status_t rval = FCT_SUCCESS; 148582527734SSukumar Swaminathan fct_port_link_status_t *link_status; 148682527734SSukumar Swaminathan MAILBOX *mb; 148782527734SSukumar Swaminathan MAILBOXQ *mbq; 148882527734SSukumar Swaminathan 148982527734SSukumar Swaminathan switch (cmd) { 149082527734SSukumar Swaminathan case FC_TGT_PORT_RLS: 149182527734SSukumar Swaminathan bzero(buffer, *size); 149282527734SSukumar Swaminathan 149382527734SSukumar Swaminathan if ((*size) < sizeof (fct_port_link_status_t)) { 149482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 149582527734SSukumar Swaminathan "FC_TGT_PORT_RLS: Buffer too small. %d < %d", 149682527734SSukumar Swaminathan *size, sizeof (fct_port_link_status_t)); 149782527734SSukumar Swaminathan 149882527734SSukumar Swaminathan rval = FCT_FAILURE; 149982527734SSukumar Swaminathan break; 150082527734SSukumar Swaminathan } 150182527734SSukumar Swaminathan 150282527734SSukumar Swaminathan if ((mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1)) == 0) { 150382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 150482527734SSukumar Swaminathan "FC_TGT_PORT_RLS: Unable to allocate mailbox."); 150582527734SSukumar Swaminathan 150682527734SSukumar Swaminathan rval = FCT_ALLOC_FAILURE; 150782527734SSukumar Swaminathan break; 150882527734SSukumar Swaminathan } 150982527734SSukumar Swaminathan mb = (MAILBOX *)mbq; 151082527734SSukumar Swaminathan 151182527734SSukumar Swaminathan emlxs_mb_read_lnk_stat(hba, mbq); 151282527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) 151382527734SSukumar Swaminathan != MBX_SUCCESS) { 151482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 151582527734SSukumar Swaminathan "FC_TGT_PORT_RLS: Unable to send request."); 151682527734SSukumar Swaminathan 151782527734SSukumar Swaminathan rval = FCT_BUSY; 151882527734SSukumar Swaminathan } else { 151982527734SSukumar Swaminathan link_status = (fct_port_link_status_t *)buffer; 152082527734SSukumar Swaminathan link_status->LinkFailureCount = 152182527734SSukumar Swaminathan mb->un.varRdLnk.linkFailureCnt; 152282527734SSukumar Swaminathan link_status->LossOfSyncCount = 152382527734SSukumar Swaminathan mb->un.varRdLnk.lossSyncCnt; 152482527734SSukumar Swaminathan link_status->LossOfSignalsCount = 152582527734SSukumar Swaminathan mb->un.varRdLnk.lossSignalCnt; 152682527734SSukumar Swaminathan link_status->PrimitiveSeqProtocolErrorCount = 152782527734SSukumar Swaminathan mb->un.varRdLnk.primSeqErrCnt; 152882527734SSukumar Swaminathan link_status->InvalidTransmissionWordCount = 152982527734SSukumar Swaminathan mb->un.varRdLnk.invalidXmitWord; 153082527734SSukumar Swaminathan link_status->InvalidCRCCount = 153182527734SSukumar Swaminathan mb->un.varRdLnk.crcCnt; 153282527734SSukumar Swaminathan } 153382527734SSukumar Swaminathan 153482527734SSukumar Swaminathan (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq); 153582527734SSukumar Swaminathan break; 153682527734SSukumar Swaminathan 153782527734SSukumar Swaminathan default: 153882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 153982527734SSukumar Swaminathan "emlxs_fct_port_info: Invalid request. cmd=%x", 154082527734SSukumar Swaminathan cmd); 154182527734SSukumar Swaminathan 154282527734SSukumar Swaminathan rval = FCT_FAILURE; 154382527734SSukumar Swaminathan break; 154482527734SSukumar Swaminathan 154582527734SSukumar Swaminathan } 1546fcf3ce44SJohn Forte 154782527734SSukumar Swaminathan return (rval); 154882527734SSukumar Swaminathan 154982527734SSukumar Swaminathan } /* emlxs_fct_port_info() */ 1550fcf3ce44SJohn Forte 155182527734SSukumar Swaminathan 155282527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 1553fcf3ce44SJohn Forte static void 155482527734SSukumar Swaminathan emlxs_fct_populate_hba_details(fct_local_port_t *fct_port, 1555fcf3ce44SJohn Forte fct_port_attrs_t *port_attrs) 1556fcf3ce44SJohn Forte { 1557fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 1558fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1559fcf3ce44SJohn Forte emlxs_vpd_t *vpd = &VPD; 1560fcf3ce44SJohn Forte 1561fcf3ce44SJohn Forte (void) strcpy(port_attrs->manufacturer, "Emulex"); 1562fcf3ce44SJohn Forte (void) strcpy(port_attrs->serial_number, vpd->serial_num); 1563fcf3ce44SJohn Forte (void) strcpy(port_attrs->model, hba->model_info.model); 1564fcf3ce44SJohn Forte (void) strcpy(port_attrs->model_description, 1565fcf3ce44SJohn Forte hba->model_info.model_desc); 1566fcf3ce44SJohn Forte (void) sprintf(port_attrs->hardware_version, "%x", vpd->biuRev); 1567fcf3ce44SJohn Forte (void) sprintf(port_attrs->driver_version, "%s (%s)", emlxs_version, 1568fcf3ce44SJohn Forte emlxs_revision); 1569fcf3ce44SJohn Forte (void) strcpy(port_attrs->option_rom_version, vpd->fcode_version); 1570fcf3ce44SJohn Forte (void) sprintf(port_attrs->firmware_version, "%s (%s)", vpd->fw_version, 1571fcf3ce44SJohn Forte vpd->fw_label); 1572fcf3ce44SJohn Forte (void) strcpy(port_attrs->driver_name, DRIVER_NAME); 1573fcf3ce44SJohn Forte port_attrs->vendor_specific_id = 1574fcf3ce44SJohn Forte ((hba->model_info.device_id << 16) | PCI_VENDOR_ID_EMULEX); 157582527734SSukumar Swaminathan port_attrs->supported_cos = LE_SWAP32(FC_NS_CLASS3); 1576fcf3ce44SJohn Forte 1577fcf3ce44SJohn Forte port_attrs->max_frame_size = FF_FRAME_SIZE; 1578fcf3ce44SJohn Forte 1579fcf3ce44SJohn Forte if (vpd->link_speed & LMT_10GB_CAPABLE) { 1580291a2b48SSukumar Swaminathan port_attrs->supported_speed |= PORT_SPEED_10G; 1581fcf3ce44SJohn Forte } 1582fcf3ce44SJohn Forte if (vpd->link_speed & LMT_8GB_CAPABLE) { 1583291a2b48SSukumar Swaminathan port_attrs->supported_speed |= PORT_SPEED_8G; 1584fcf3ce44SJohn Forte } 1585fcf3ce44SJohn Forte if (vpd->link_speed & LMT_4GB_CAPABLE) { 1586291a2b48SSukumar Swaminathan port_attrs->supported_speed |= PORT_SPEED_4G; 1587fcf3ce44SJohn Forte } 1588fcf3ce44SJohn Forte if (vpd->link_speed & LMT_2GB_CAPABLE) { 1589291a2b48SSukumar Swaminathan port_attrs->supported_speed |= PORT_SPEED_2G; 1590fcf3ce44SJohn Forte } 1591fcf3ce44SJohn Forte if (vpd->link_speed & LMT_1GB_CAPABLE) { 1592291a2b48SSukumar Swaminathan port_attrs->supported_speed |= PORT_SPEED_1G; 1593fcf3ce44SJohn Forte } 1594291a2b48SSukumar Swaminathan 1595fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1596fcf3ce44SJohn Forte "Port attr: manufacturer = %s", port_attrs->manufacturer); 1597fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1598fcf3ce44SJohn Forte "Port attr: serial_num = %s", port_attrs->serial_number); 1599fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1600fcf3ce44SJohn Forte "Port attr: model = %s", port_attrs->model); 1601fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1602fcf3ce44SJohn Forte "Port attr: model_description = %s", 1603fcf3ce44SJohn Forte port_attrs->model_description); 1604fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1605291a2b48SSukumar Swaminathan "Port attr: hardware_version = %s", 1606291a2b48SSukumar Swaminathan port_attrs->hardware_version); 1607fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1608fcf3ce44SJohn Forte "Port attr: driver_version = %s", port_attrs->driver_version); 1609fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1610fcf3ce44SJohn Forte "Port attr: option_rom_version = %s", 1611fcf3ce44SJohn Forte port_attrs->option_rom_version); 1612fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1613291a2b48SSukumar Swaminathan "Port attr: firmware_version = %s", 1614291a2b48SSukumar Swaminathan port_attrs->firmware_version); 1615fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1616fcf3ce44SJohn Forte "Port attr: driver_name = %s", port_attrs->driver_name); 1617fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1618fcf3ce44SJohn Forte "Port attr: vendor_specific_id = 0x%x", 1619fcf3ce44SJohn Forte port_attrs->vendor_specific_id); 1620fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1621291a2b48SSukumar Swaminathan "Port attr: supported_cos = 0x%x", 1622291a2b48SSukumar Swaminathan port_attrs->supported_cos); 1623fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1624fcf3ce44SJohn Forte "Port attr: supported_speed = 0x%x", 1625fcf3ce44SJohn Forte port_attrs->supported_speed); 1626fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1627291a2b48SSukumar Swaminathan "Port attr: max_frame_size = 0x%x", 1628291a2b48SSukumar Swaminathan port_attrs->max_frame_size); 1629fcf3ce44SJohn Forte 1630fcf3ce44SJohn Forte return; 1631fcf3ce44SJohn Forte 163282527734SSukumar Swaminathan } /* emlxs_fct_populate_hba_details() */ 1633fcf3ce44SJohn Forte 1634fcf3ce44SJohn Forte 163582527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 1636fcf3ce44SJohn Forte /* ARGSUSED */ 1637fcf3ce44SJohn Forte static void 1638fcf3ce44SJohn Forte emlxs_fct_ctl(fct_local_port_t *fct_port, int cmd, void *arg) 1639fcf3ce44SJohn Forte { 1640fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 1641fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1642fcf3ce44SJohn Forte stmf_change_status_t st; 1643fcf3ce44SJohn Forte 1644fcf3ce44SJohn Forte st.st_completion_status = FCT_SUCCESS; 1645fcf3ce44SJohn Forte st.st_additional_info = NULL; 1646fcf3ce44SJohn Forte 1647fcf3ce44SJohn Forte switch (cmd) { 1648fcf3ce44SJohn Forte case FCT_CMD_PORT_ONLINE: 1649fcf3ce44SJohn Forte /* If the HBA is offline, we cannot bring the tgtport online */ 1650fcf3ce44SJohn Forte if (hba->flag & (FC_OFFLINE_MODE | FC_OFFLINING_MODE)) { 1651fcf3ce44SJohn Forte st.st_completion_status = FCT_FAILURE; 1652fcf3ce44SJohn Forte MODSYM(fct_ctl) (fct_port->port_lport, 1653fcf3ce44SJohn Forte FCT_CMD_PORT_ONLINE_COMPLETE, &st); 1654fcf3ce44SJohn Forte break; 1655fcf3ce44SJohn Forte } 1656291a2b48SSukumar Swaminathan 1657fcf3ce44SJohn Forte if (port->fct_flags & FCT_STATE_PORT_ONLINE) { 1658fcf3ce44SJohn Forte st.st_completion_status = STMF_ALREADY; 1659fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1660fcf3ce44SJohn Forte "STATE: ONLINE chk"); 1661fcf3ce44SJohn Forte } else { 1662fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1663fcf3ce44SJohn Forte "STATE: OFFLINE --> ONLINE"); 1664fcf3ce44SJohn Forte 1665fcf3ce44SJohn Forte port->fct_flags |= FCT_STATE_NOT_ACKED; 1666fcf3ce44SJohn Forte port->fct_flags |= FCT_STATE_PORT_ONLINE; 1667fcf3ce44SJohn Forte 1668fcf3ce44SJohn Forte if (hba->state <= FC_LINK_DOWN) { 1669fcf3ce44SJohn Forte /* Try to bring the link up */ 167082527734SSukumar Swaminathan (void) emlxs_reset_link(hba, 1, 1); 1671fcf3ce44SJohn Forte } 1672291a2b48SSukumar Swaminathan 1673fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1674fcf3ce44SJohn Forte "STATE: ONLINE"); 1675fcf3ce44SJohn Forte } 1676fcf3ce44SJohn Forte 1677fcf3ce44SJohn Forte MODSYM(fct_ctl) (fct_port->port_lport, 1678fcf3ce44SJohn Forte FCT_CMD_PORT_ONLINE_COMPLETE, &st); 1679fcf3ce44SJohn Forte break; 1680fcf3ce44SJohn Forte 1681fcf3ce44SJohn Forte case FCT_CMD_PORT_OFFLINE: 1682fcf3ce44SJohn Forte if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) { 1683fcf3ce44SJohn Forte st.st_completion_status = STMF_ALREADY; 1684fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1685fcf3ce44SJohn Forte "STATE: OFFLINE chk"); 1686fcf3ce44SJohn Forte 1687fcf3ce44SJohn Forte } else { 1688fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1689fcf3ce44SJohn Forte "STATE: ONLINE --> OFFLINE"); 1690fcf3ce44SJohn Forte 1691fcf3ce44SJohn Forte /* Take link down and flush */ 1692fcf3ce44SJohn Forte emlxs_fct_link_down(port); 1693fcf3ce44SJohn Forte emlxs_fct_unsol_flush(port); 1694fcf3ce44SJohn Forte 1695fcf3ce44SJohn Forte /* Declare this port offline now */ 1696fcf3ce44SJohn Forte port->fct_flags |= FCT_STATE_NOT_ACKED; 1697fcf3ce44SJohn Forte port->fct_flags &= ~FCT_STATE_PORT_ONLINE; 1698fcf3ce44SJohn Forte 1699fcf3ce44SJohn Forte /* Take link down and hold it down */ 170082527734SSukumar Swaminathan (void) emlxs_reset_link(hba, 0, 1); 1701fcf3ce44SJohn Forte 1702fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1703fcf3ce44SJohn Forte "STATE: OFFLINE"); 1704fcf3ce44SJohn Forte } 1705fcf3ce44SJohn Forte 1706fcf3ce44SJohn Forte MODSYM(fct_ctl) (fct_port->port_lport, 1707fcf3ce44SJohn Forte FCT_CMD_PORT_OFFLINE_COMPLETE, &st); 1708fcf3ce44SJohn Forte 1709fcf3ce44SJohn Forte break; 1710fcf3ce44SJohn Forte 1711fcf3ce44SJohn Forte case FCT_ACK_PORT_OFFLINE_COMPLETE: 1712fcf3ce44SJohn Forte port->fct_flags &= ~FCT_STATE_NOT_ACKED; 1713fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1714fcf3ce44SJohn Forte "STATE: OFFLINE ack"); 1715fcf3ce44SJohn Forte break; 1716fcf3ce44SJohn Forte 1717fcf3ce44SJohn Forte case FCT_ACK_PORT_ONLINE_COMPLETE: 1718fcf3ce44SJohn Forte port->fct_flags &= ~FCT_STATE_NOT_ACKED; 1719fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1720fcf3ce44SJohn Forte "STATE: ONLINE ack"); 1721fcf3ce44SJohn Forte break; 1722fcf3ce44SJohn Forte 172382527734SSukumar Swaminathan case FCT_CMD_FORCE_LIP: 172482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 172582527734SSukumar Swaminathan "emlxs_fct_ctl: FCT_CMD_FORCE_LIP"); 172682527734SSukumar Swaminathan 172782527734SSukumar Swaminathan /* Reset the link */ 172882527734SSukumar Swaminathan (void) emlxs_reset(port, FC_FCA_LINK_RESET); 172982527734SSukumar Swaminathan break; 1730fcf3ce44SJohn Forte } 1731fcf3ce44SJohn Forte 1732fcf3ce44SJohn Forte return; 1733fcf3ce44SJohn Forte 173482527734SSukumar Swaminathan } /* emlxs_fct_ctl() */ 1735291a2b48SSukumar Swaminathan 1736fcf3ce44SJohn Forte 1737fcf3ce44SJohn Forte extern int 1738fcf3ce44SJohn Forte emlxs_fct_port_shutdown(emlxs_port_t *port) 1739fcf3ce44SJohn Forte { 1740fcf3ce44SJohn Forte fct_local_port_t *fct_port; 174182527734SSukumar Swaminathan int i; 1742fcf3ce44SJohn Forte 1743fcf3ce44SJohn Forte fct_port = port->fct_port; 1744fcf3ce44SJohn Forte if (!fct_port) { 1745fcf3ce44SJohn Forte return (0); 1746fcf3ce44SJohn Forte } 17473be114edSSukumar Swaminathan 17483be114edSSukumar Swaminathan port->fct_flags |= FCT_STATE_NOT_ACKED; 17493be114edSSukumar Swaminathan 1750291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, "fct_port_shutdown"); 1751fcf3ce44SJohn Forte MODSYM(fct_port_shutdown) (fct_port, STMF_RFLAG_STAY_OFFLINED, 1752fcf3ce44SJohn Forte "emlxs shutdown"); 1753fcf3ce44SJohn Forte 175482527734SSukumar Swaminathan i = 0; 1755fcf3ce44SJohn Forte while (port->fct_flags & FCT_STATE_NOT_ACKED) { 1756fcf3ce44SJohn Forte i++; 1757fcf3ce44SJohn Forte if (i > 300) { /* 30 seconds */ 1758fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1759fcf3ce44SJohn Forte "fct_port_shutdown failed to ACK"); 1760fcf3ce44SJohn Forte break; 1761fcf3ce44SJohn Forte } 1762fcf3ce44SJohn Forte delay(drv_usectohz(100000)); /* 100 msec */ 1763fcf3ce44SJohn Forte } 1764fcf3ce44SJohn Forte return (1); 1765fcf3ce44SJohn Forte } 1766fcf3ce44SJohn Forte 1767fcf3ce44SJohn Forte 1768fcf3ce44SJohn Forte extern int 1769fcf3ce44SJohn Forte emlxs_fct_port_initialize(emlxs_port_t *port) 1770fcf3ce44SJohn Forte { 1771fcf3ce44SJohn Forte fct_local_port_t *fct_port; 177282527734SSukumar Swaminathan int i; 1773fcf3ce44SJohn Forte 1774fcf3ce44SJohn Forte fct_port = port->fct_port; 1775fcf3ce44SJohn Forte if (!fct_port) { 1776fcf3ce44SJohn Forte return (0); 1777fcf3ce44SJohn Forte } 17783be114edSSukumar Swaminathan 17793be114edSSukumar Swaminathan port->fct_flags |= FCT_STATE_NOT_ACKED; 17803be114edSSukumar Swaminathan 1781fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1782fcf3ce44SJohn Forte "fct_port_initialize"); 1783fcf3ce44SJohn Forte MODSYM(fct_port_initialize) (fct_port, STMF_RFLAG_STAY_OFFLINED, 1784fcf3ce44SJohn Forte "emlxs initialize"); 1785fcf3ce44SJohn Forte 178682527734SSukumar Swaminathan i = 0; 1787fcf3ce44SJohn Forte while (port->fct_flags & FCT_STATE_NOT_ACKED) { 1788fcf3ce44SJohn Forte i++; 1789fcf3ce44SJohn Forte if (i > 300) { /* 30 seconds */ 1790fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1791fcf3ce44SJohn Forte "fct_port_initialize failed to ACK"); 1792fcf3ce44SJohn Forte break; 1793fcf3ce44SJohn Forte } 1794fcf3ce44SJohn Forte delay(drv_usectohz(100000)); /* 100 msec */ 1795fcf3ce44SJohn Forte } 1796fcf3ce44SJohn Forte return (1); 1797fcf3ce44SJohn Forte } 1798fcf3ce44SJohn Forte 1799291a2b48SSukumar Swaminathan 180082527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 1801fcf3ce44SJohn Forte static fct_status_t 1802fcf3ce44SJohn Forte emlxs_fct_send_cmd(fct_cmd_t *fct_cmd) 1803fcf3ce44SJohn Forte { 1804fcf3ce44SJohn Forte emlxs_port_t *port; 1805fcf3ce44SJohn Forte 1806fcf3ce44SJohn Forte port = (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 1807fcf3ce44SJohn Forte 1808fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1809fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 1810fcf3ce44SJohn Forte "emlxs_fct_send_cmd %p: x%x", fct_cmd, fct_cmd->cmd_type); 1811291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1812fcf3ce44SJohn Forte 1813fcf3ce44SJohn Forte switch (fct_cmd->cmd_type) { 1814fcf3ce44SJohn Forte case FCT_CMD_SOL_ELS: 1815fcf3ce44SJohn Forte 1816fcf3ce44SJohn Forte return (emlxs_fct_send_els_cmd(fct_cmd)); 1817fcf3ce44SJohn Forte 1818fcf3ce44SJohn Forte case FCT_CMD_SOL_CT: 1819fcf3ce44SJohn Forte 1820fcf3ce44SJohn Forte return (emlxs_fct_send_ct_cmd(fct_cmd)); 1821fcf3ce44SJohn Forte 1822fcf3ce44SJohn Forte default: 1823fcf3ce44SJohn Forte 1824fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1825fcf3ce44SJohn Forte "emlxs_fct_send_cmd: Invalid cmd type found. type=%x", 1826fcf3ce44SJohn Forte fct_cmd->cmd_type); 1827fcf3ce44SJohn Forte 1828fcf3ce44SJohn Forte return (FCT_FAILURE); 1829fcf3ce44SJohn Forte } 1830fcf3ce44SJohn Forte 183182527734SSukumar Swaminathan } /* emlxs_fct_send_cmd() */ 1832fcf3ce44SJohn Forte 1833fcf3ce44SJohn Forte 183482527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 1835fcf3ce44SJohn Forte static fct_status_t 1836fcf3ce44SJohn Forte emlxs_fct_send_cmd_rsp(fct_cmd_t *fct_cmd, uint32_t ioflags) 1837fcf3ce44SJohn Forte { 1838fcf3ce44SJohn Forte emlxs_port_t *port; 1839291a2b48SSukumar Swaminathan emlxs_buf_t *cmd_sbp; 1840291a2b48SSukumar Swaminathan fct_status_t rval; 184182527734SSukumar Swaminathan IOCBQ *iocbq; 184282527734SSukumar Swaminathan IOCB *iocb; 184382527734SSukumar Swaminathan uint32_t status; 1844fcf3ce44SJohn Forte 1845fcf3ce44SJohn Forte port = (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 184682527734SSukumar Swaminathan 184782527734SSukumar Swaminathan rval = emlxs_fct_cmd_accept(port, fct_cmd, EMLXS_FCT_SEND_CMD_RSP); 184882527734SSukumar Swaminathan if (rval) { 184982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 185082527734SSukumar Swaminathan "emlxs_fct_send_cmd_rsp: " 185182527734SSukumar Swaminathan "Unable to accept fct_cmd. type=%x", 185282527734SSukumar Swaminathan fct_cmd->cmd_type); 185382527734SSukumar Swaminathan 185482527734SSukumar Swaminathan return (rval); 185582527734SSukumar Swaminathan } 185682527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 185782527734SSukumar Swaminathan 1858291a2b48SSukumar Swaminathan cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 185982527734SSukumar Swaminathan iocbq = &cmd_sbp->iocbq; 186082527734SSukumar Swaminathan iocb = &iocbq->iocb; 186182527734SSukumar Swaminathan status = iocb->ULPSTATUS; 1862fcf3ce44SJohn Forte 1863fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1864fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 186582527734SSukumar Swaminathan "emlxs_fct_send_cmd_rsp %p: x%x, %x, %x", 186682527734SSukumar Swaminathan fct_cmd, fct_cmd->cmd_type, iocb->ULPCT, status); 1867291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1868fcf3ce44SJohn Forte 1869fcf3ce44SJohn Forte switch (fct_cmd->cmd_type) { 1870fcf3ce44SJohn Forte case FCT_CMD_FCP_XCHG: 1871fcf3ce44SJohn Forte 1872fcf3ce44SJohn Forte if (ioflags & FCT_IOF_FORCE_FCA_DONE) { 1873fcf3ce44SJohn Forte goto failure; 1874fcf3ce44SJohn Forte } 1875291a2b48SSukumar Swaminathan 187682527734SSukumar Swaminathan if ((iocb->ULPCT == 0x1) && (status == 0)) { 187782527734SSukumar Swaminathan 187882527734SSukumar Swaminathan /* Firmware already sent out resp */ 187982527734SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_SEND_STATUS; 188082527734SSukumar Swaminathan 188182527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_IO_DONE); 188282527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 188382527734SSukumar Swaminathan 188482527734SSukumar Swaminathan #ifdef FCT_API_TRACE 188582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 188682527734SSukumar Swaminathan "fct_send_response_done:4 %p: x%x", 188782527734SSukumar Swaminathan fct_cmd, fct_cmd->cmd_comp_status); 188882527734SSukumar Swaminathan 188982527734SSukumar Swaminathan #endif /* FCT_API_TRACE */ 189082527734SSukumar Swaminathan 189182527734SSukumar Swaminathan MODSYM(fct_send_response_done) (fct_cmd, 189282527734SSukumar Swaminathan fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE); 189382527734SSukumar Swaminathan 189482527734SSukumar Swaminathan return (FCT_SUCCESS); 189582527734SSukumar Swaminathan } 189682527734SSukumar Swaminathan 1897291a2b48SSukumar Swaminathan rval = emlxs_fct_send_fcp_status(fct_cmd); 189882527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 189982527734SSukumar Swaminathan 1900291a2b48SSukumar Swaminathan return (rval); 1901fcf3ce44SJohn Forte 1902fcf3ce44SJohn Forte case FCT_CMD_RCVD_ELS: 1903fcf3ce44SJohn Forte 1904fcf3ce44SJohn Forte if (ioflags & FCT_IOF_FORCE_FCA_DONE) { 1905fcf3ce44SJohn Forte goto failure; 1906fcf3ce44SJohn Forte } 1907fcf3ce44SJohn Forte 190882527734SSukumar Swaminathan rval = emlxs_fct_send_els_rsp(fct_cmd); 190982527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 191082527734SSukumar Swaminathan 191182527734SSukumar Swaminathan return (rval); 1912fcf3ce44SJohn Forte 1913fcf3ce44SJohn Forte default: 1914fcf3ce44SJohn Forte 1915fcf3ce44SJohn Forte if (ioflags & FCT_IOF_FORCE_FCA_DONE) { 1916fcf3ce44SJohn Forte fct_cmd->cmd_handle = 0; 1917fcf3ce44SJohn Forte } 1918291a2b48SSukumar Swaminathan 1919fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1920fcf3ce44SJohn Forte "emlxs_fct_send_cmd_rsp: Invalid cmd type found. type=%x", 1921fcf3ce44SJohn Forte fct_cmd->cmd_type); 1922fcf3ce44SJohn Forte 1923fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 192482527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 192582527734SSukumar Swaminathan 1926fcf3ce44SJohn Forte return (FCT_FAILURE); 1927fcf3ce44SJohn Forte } 1928fcf3ce44SJohn Forte 1929fcf3ce44SJohn Forte failure: 1930fcf3ce44SJohn Forte 1931fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1932291a2b48SSukumar Swaminathan "emlxs_fct_send_cmd_rsp: " 1933291a2b48SSukumar Swaminathan "Unable to handle FCT_IOF_FORCE_FCA_DONE. type=%x", 1934291a2b48SSukumar Swaminathan fct_cmd->cmd_type); 1935fcf3ce44SJohn Forte 1936fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 193782527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 193882527734SSukumar Swaminathan 1939fcf3ce44SJohn Forte return (FCT_FAILURE); 1940fcf3ce44SJohn Forte 194182527734SSukumar Swaminathan } /* emlxs_fct_send_cmd_rsp() */ 1942fcf3ce44SJohn Forte 1943fcf3ce44SJohn Forte 194482527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 1945fcf3ce44SJohn Forte static fct_status_t 194682527734SSukumar Swaminathan emlxs_fct_flogi_xchg(struct fct_local_port *fct_port, struct fct_flogi_xchg *fx) 1947fcf3ce44SJohn Forte { 1948fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 1949fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1950fcf3ce44SJohn Forte uint32_t size; 195182527734SSukumar Swaminathan fc_packet_t *pkt = NULL; 1952fcf3ce44SJohn Forte ELS_PKT *els; 195382527734SSukumar Swaminathan fct_status_t rval = FCT_SUCCESS; 1954fcf3ce44SJohn Forte 1955fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 1956fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 195782527734SSukumar Swaminathan "emlxs_fct_flogi_xchg: Sending FLOGI: %p", fct_port); 1958fcf3ce44SJohn Forte #else 1959fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 196082527734SSukumar Swaminathan "emlxs_fct_flogi_xchg: Sending FLOGI."); 1961291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 1962fcf3ce44SJohn Forte 1963fcf3ce44SJohn Forte if (hba->state <= FC_LINK_DOWN) { 1964fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 196582527734SSukumar Swaminathan "emlxs_fct_flogi_xchg: FLOGI failed. Link down."); 196682527734SSukumar Swaminathan rval = FCT_FAILURE; 196782527734SSukumar Swaminathan goto done; 1968fcf3ce44SJohn Forte } 1969291a2b48SSukumar Swaminathan 1970e2ca2865SSukumar Swaminathan /* Use this entyr point as the link up acknowlegment */ 1971e2ca2865SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 1972e2ca2865SSukumar Swaminathan port->fct_flags |= FCT_STATE_LINK_UP_ACKED; 1973e2ca2865SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 1974e2ca2865SSukumar Swaminathan "emlxs_fct_link_up acked."); 1975e2ca2865SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 1976e2ca2865SSukumar Swaminathan 1977e2ca2865SSukumar Swaminathan /* Now flush any pending unsolicited requests */ 1978e2ca2865SSukumar Swaminathan emlxs_fct_unsol_flush(port); 1979e2ca2865SSukumar Swaminathan 1980fcf3ce44SJohn Forte size = sizeof (SERV_PARM) + 4; 1981fcf3ce44SJohn Forte 1982fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, size, size, 0, KM_NOSLEEP))) { 1983fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 198482527734SSukumar Swaminathan "emlxs_fct_flogi_xchg: FLOGI failed. " 198582527734SSukumar Swaminathan "Unable allocate packet."); 198682527734SSukumar Swaminathan rval = FCT_FAILURE; 198782527734SSukumar Swaminathan goto done; 1988fcf3ce44SJohn Forte } 1989291a2b48SSukumar Swaminathan 1990fcf3ce44SJohn Forte /* Make this a polled IO */ 1991fcf3ce44SJohn Forte pkt->pkt_tran_flags &= ~FC_TRAN_INTR; 1992fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_NO_INTR; 1993fcf3ce44SJohn Forte pkt->pkt_comp = NULL; 1994fcf3ce44SJohn Forte 1995fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE; 1996fcf3ce44SJohn Forte pkt->pkt_timeout = fx->fx_sec_timeout; 1997fcf3ce44SJohn Forte 1998fcf3ce44SJohn Forte /* Build the fc header */ 199982527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(fx->fx_did); 2000291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.r_ctl = 2001291a2b48SSukumar Swaminathan R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL; 200282527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(fx->fx_sid); 2003fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 2004fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = F_CTL_FIRST_SEQ | F_CTL_SEQ_INITIATIVE; 2005fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 2006fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 2007fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 2008fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xffff; 2009fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xffff; 2010fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 2011fcf3ce44SJohn Forte 2012fcf3ce44SJohn Forte /* Build the command */ 2013291a2b48SSukumar Swaminathan /* Service paramters will be added automatically later by the driver */ 2014fcf3ce44SJohn Forte els = (ELS_PKT *)pkt->pkt_cmd; 2015fcf3ce44SJohn Forte els->elsCode = 0x04; /* FLOGI */ 2016fcf3ce44SJohn Forte 2017fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 2018fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 201982527734SSukumar Swaminathan "emlxs_fct_flogi_xchg: FLOGI failed. " 202082527734SSukumar Swaminathan "Unable to send packet."); 2021fcf3ce44SJohn Forte 202282527734SSukumar Swaminathan rval = FCT_FAILURE; 202382527734SSukumar Swaminathan goto done; 2024fcf3ce44SJohn Forte } 2025291a2b48SSukumar Swaminathan 2026fcf3ce44SJohn Forte if ((pkt->pkt_state != FC_PKT_SUCCESS) && 2027fcf3ce44SJohn Forte (pkt->pkt_state != FC_PKT_LS_RJT)) { 2028fcf3ce44SJohn Forte if (pkt->pkt_state == FC_PKT_TIMEOUT) { 202982527734SSukumar Swaminathan rval = FCT_TIMEOUT; 2030fcf3ce44SJohn Forte } else if ((pkt->pkt_state == FC_PKT_LOCAL_RJT) && 2031fcf3ce44SJohn Forte (pkt->pkt_reason == FC_REASON_FCAL_OPN_FAIL)) { 203282527734SSukumar Swaminathan rval = FCT_NOT_FOUND; 203382527734SSukumar Swaminathan } else { 203482527734SSukumar Swaminathan rval = FCT_FAILURE; 2035fcf3ce44SJohn Forte } 2036291a2b48SSukumar Swaminathan 2037fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 203882527734SSukumar Swaminathan "emlxs_fct_flogi_xchg: FLOGI failed. state=%x reason=%x", 2039fcf3ce44SJohn Forte pkt->pkt_state, pkt->pkt_reason); 2040fcf3ce44SJohn Forte 204182527734SSukumar Swaminathan goto done; 2042fcf3ce44SJohn Forte } 2043291a2b48SSukumar Swaminathan 2044fcf3ce44SJohn Forte if (pkt->pkt_state == FC_PKT_LS_RJT) { 2045fcf3ce44SJohn Forte fx->fx_op = ELS_OP_LSRJT; 2046fcf3ce44SJohn Forte fx->fx_rjt_reason = pkt->pkt_reason; 2047fcf3ce44SJohn Forte fx->fx_rjt_expl = pkt->pkt_expln; 2048fcf3ce44SJohn Forte } else { /* FC_PKT_SUCCESS */ 2049291a2b48SSukumar Swaminathan 2050fcf3ce44SJohn Forte fx->fx_op = ELS_OP_ACC; 205182527734SSukumar Swaminathan fx->fx_sid = FABRIC_DID; 2052fcf3ce44SJohn Forte fx->fx_did = port->did; 2053fcf3ce44SJohn Forte 2054291a2b48SSukumar Swaminathan els = (ELS_PKT *)pkt->pkt_resp; 2055fcf3ce44SJohn Forte bcopy((caddr_t)&els->un.logi.nodeName, 2056fcf3ce44SJohn Forte (caddr_t)fx->fx_nwwn, 8); 2057fcf3ce44SJohn Forte bcopy((caddr_t)&els->un.logi.portName, 2058fcf3ce44SJohn Forte (caddr_t)fx->fx_pwwn, 8); 2059fcf3ce44SJohn Forte fx->fx_fport = els->un.logi.cmn.fPort; 2060fcf3ce44SJohn Forte } 2061fcf3ce44SJohn Forte 206282527734SSukumar Swaminathan done: 206382527734SSukumar Swaminathan if (pkt) { 206482527734SSukumar Swaminathan emlxs_pkt_free(pkt); 206582527734SSukumar Swaminathan } 206682527734SSukumar Swaminathan 206782527734SSukumar Swaminathan return (rval); 2068fcf3ce44SJohn Forte 206982527734SSukumar Swaminathan } /* emlxs_fct_flogi_xchg() */ 2070fcf3ce44SJohn Forte 2071fcf3ce44SJohn Forte 207282527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 2073fcf3ce44SJohn Forte /* This is called right after we report that link has come online */ 2074fcf3ce44SJohn Forte static fct_status_t 2075fcf3ce44SJohn Forte emlxs_fct_get_link_info(fct_local_port_t *fct_port, fct_link_info_t *link) 2076fcf3ce44SJohn Forte { 2077fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 2078fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 2079fcf3ce44SJohn Forte 2080fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2081fcf3ce44SJohn Forte "emlxs_fct_get_link_info %p", fct_port); 2082fcf3ce44SJohn Forte 2083fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 2084fcf3ce44SJohn Forte 2085fcf3ce44SJohn Forte if (!(port->fct_flags & FCT_STATE_LINK_UP) || 2086291a2b48SSukumar Swaminathan (hba->state < FC_LINK_UP) || (hba->flag & FC_LOOPBACK_MODE)) { 2087fcf3ce44SJohn Forte link->port_topology = PORT_TOPOLOGY_UNKNOWN; 2088fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_UNKNOWN; 2089fcf3ce44SJohn Forte link->portid = 0; 2090fcf3ce44SJohn Forte 2091fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 2092fcf3ce44SJohn Forte 2093fcf3ce44SJohn Forte return (FCT_SUCCESS); 2094fcf3ce44SJohn Forte } 2095291a2b48SSukumar Swaminathan 2096fcf3ce44SJohn Forte if (hba->topology == TOPOLOGY_LOOP) { 2097fcf3ce44SJohn Forte link->port_topology = PORT_TOPOLOGY_PRIVATE_LOOP; 2098fcf3ce44SJohn Forte } else { 2099fcf3ce44SJohn Forte link->port_topology = PORT_TOPOLOGY_PT_TO_PT; 2100fcf3ce44SJohn Forte } 2101fcf3ce44SJohn Forte 2102fcf3ce44SJohn Forte switch (hba->linkspeed) { 2103fcf3ce44SJohn Forte case LA_1GHZ_LINK: 2104fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_1G; 2105fcf3ce44SJohn Forte break; 2106fcf3ce44SJohn Forte case LA_2GHZ_LINK: 2107fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_2G; 2108fcf3ce44SJohn Forte break; 2109fcf3ce44SJohn Forte case LA_4GHZ_LINK: 2110fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_4G; 2111fcf3ce44SJohn Forte break; 2112fcf3ce44SJohn Forte case LA_8GHZ_LINK: 2113fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_8G; 2114fcf3ce44SJohn Forte break; 2115fcf3ce44SJohn Forte case LA_10GHZ_LINK: 2116fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_10G; 2117fcf3ce44SJohn Forte break; 2118fcf3ce44SJohn Forte default: 2119fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_UNKNOWN; 2120fcf3ce44SJohn Forte break; 2121fcf3ce44SJohn Forte } 2122fcf3ce44SJohn Forte 2123fcf3ce44SJohn Forte link->portid = port->did; 2124fcf3ce44SJohn Forte link->port_no_fct_flogi = 0; 2125fcf3ce44SJohn Forte link->port_fca_flogi_done = 0; 2126fcf3ce44SJohn Forte link->port_fct_flogi_done = 0; 2127fcf3ce44SJohn Forte 2128fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 2129fcf3ce44SJohn Forte 2130fcf3ce44SJohn Forte return (FCT_SUCCESS); 2131fcf3ce44SJohn Forte 213282527734SSukumar Swaminathan } /* emlxs_fct_get_link_info() */ 2133fcf3ce44SJohn Forte 2134fcf3ce44SJohn Forte 213582527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 2136fcf3ce44SJohn Forte static fct_status_t 2137fcf3ce44SJohn Forte emlxs_fct_register_remote_port(fct_local_port_t *fct_port, 2138fcf3ce44SJohn Forte fct_remote_port_t *remote_port, fct_cmd_t *fct_cmd) 2139fcf3ce44SJohn Forte { 2140fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 2141fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 2142fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 2143fcf3ce44SJohn Forte clock_t timeout; 2144fcf3ce44SJohn Forte int32_t pkt_ret; 2145fcf3ce44SJohn Forte fct_els_t *els; 2146fcf3ce44SJohn Forte SERV_PARM *sp; 2147fcf3ce44SJohn Forte emlxs_node_t *ndlp; 2148fcf3ce44SJohn Forte SERV_PARM sparam; 2149fcf3ce44SJohn Forte uint32_t *iptr; 21503be114edSSukumar Swaminathan uint64_t addr; 215182527734SSukumar Swaminathan fct_status_t rval; 215282527734SSukumar Swaminathan fct_status_t rval2; 2153fcf3ce44SJohn Forte 2154fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2155fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2156fcf3ce44SJohn Forte "emlxs_fct_register_remote_port %p", fct_port); 2157291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2158fcf3ce44SJohn Forte 2159fcf3ce44SJohn Forte if (!(cmd_sbp->pkt_flags & PACKET_VALID)) { 216082527734SSukumar Swaminathan 216182527734SSukumar Swaminathan cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd, 216282527734SSukumar Swaminathan EMLXS_FCT_REG_PENDING); 2163291a2b48SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 2164fcf3ce44SJohn Forte 216582527734SSukumar Swaminathan cmd_sbp->channel = &hba->chan[hba->channel_els]; 2166fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_ELS_CMD; 216782527734SSukumar Swaminathan 2168fcf3ce44SJohn Forte } else { 2169fcf3ce44SJohn Forte 217082527734SSukumar Swaminathan rval = emlxs_fct_cmd_accept(port, fct_cmd, 217182527734SSukumar Swaminathan EMLXS_FCT_REG_PENDING); 217282527734SSukumar Swaminathan if (rval) { 217382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 217482527734SSukumar Swaminathan "emlxs_fct_register_remote_port: " 217582527734SSukumar Swaminathan "Unable to accept fct_cmd. did=%x", 217682527734SSukumar Swaminathan fct_cmd->cmd_rportid); 2177291a2b48SSukumar Swaminathan 217882527734SSukumar Swaminathan return (rval); 217982527734SSukumar Swaminathan } 218082527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 218182527734SSukumar Swaminathan } 2182fcf3ce44SJohn Forte 2183fcf3ce44SJohn Forte if (!cmd_sbp->node) { 2184291a2b48SSukumar Swaminathan cmd_sbp->node = 2185291a2b48SSukumar Swaminathan emlxs_node_find_did(port, fct_cmd->cmd_rportid); 2186fcf3ce44SJohn Forte } 2187291a2b48SSukumar Swaminathan 2188fcf3ce44SJohn Forte if (!cmd_sbp->node) { 2189fcf3ce44SJohn Forte els = (fct_els_t *)fct_cmd->cmd_specific; 2190fcf3ce44SJohn Forte 2191fcf3ce44SJohn Forte /* Check for unsolicited PLOGI */ 2192291a2b48SSukumar Swaminathan if (cmd_sbp->fct_flags & EMLXS_FCT_PLOGI_RECEIVED) { 2193291a2b48SSukumar Swaminathan sp = (SERV_PARM *)((caddr_t)els->els_req_payload + 2194291a2b48SSukumar Swaminathan sizeof (uint32_t)); 2195fcf3ce44SJohn Forte } else { /* Solicited PLOGI */ 2196291a2b48SSukumar Swaminathan 2197fcf3ce44SJohn Forte sp = &sparam; 2198fcf3ce44SJohn Forte bcopy((caddr_t)&port->sparam, (caddr_t)sp, 2199fcf3ce44SJohn Forte sizeof (SERV_PARM)); 2200fcf3ce44SJohn Forte 2201fcf3ce44SJohn Forte /* 2202291a2b48SSukumar Swaminathan * Create temporary WWN's from fct_cmd address 2203fcf3ce44SJohn Forte * This simply allows us to get an RPI from the 2204291a2b48SSukumar Swaminathan * adapter until we get real service params. 2205fcf3ce44SJohn Forte * The PLOGI ACC reply will trigger a REG_LOGIN 2206fcf3ce44SJohn Forte * update later 2207fcf3ce44SJohn Forte */ 22083be114edSSukumar Swaminathan addr = (uint64_t)((unsigned long)fct_cmd); 22093be114edSSukumar Swaminathan 2210fcf3ce44SJohn Forte iptr = (uint32_t *)&sp->portName; 221182527734SSukumar Swaminathan iptr[0] = PADDR_HI(addr); 221282527734SSukumar Swaminathan iptr[1] = PADDR_LO(addr); 2213291a2b48SSukumar Swaminathan 2214fcf3ce44SJohn Forte iptr = (uint32_t *)&sp->nodeName; 221582527734SSukumar Swaminathan iptr[0] = PADDR_HI(addr); 221682527734SSukumar Swaminathan iptr[1] = PADDR_LO(addr); 2217fcf3ce44SJohn Forte } 2218fcf3ce44SJohn Forte 2219fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg, 2220291a2b48SSukumar Swaminathan "emlxs_fct_register_remote_port: Register did=%x. (%x,%p)", 2221291a2b48SSukumar Swaminathan fct_cmd->cmd_rportid, cmd_sbp->fct_state, fct_cmd); 2222fcf3ce44SJohn Forte 222382527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, 0); 222482527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 222582527734SSukumar Swaminathan 2226fcf3ce44SJohn Forte /* Create a new node */ 2227fcf3ce44SJohn Forte if (emlxs_mb_reg_did(port, fct_cmd->cmd_rportid, sp, cmd_sbp, 2228fcf3ce44SJohn Forte NULL, NULL) != 0) { 2229fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 2230291a2b48SSukumar Swaminathan "emlxs_fct_register_remote_port: " 2231291a2b48SSukumar Swaminathan "Reg login failed. did=%x", 2232291a2b48SSukumar Swaminathan fct_cmd->cmd_rportid); 223382527734SSukumar Swaminathan } else { 2234fcf3ce44SJohn Forte 223582527734SSukumar Swaminathan /* Wait for completion */ 223682527734SSukumar Swaminathan mutex_enter(&EMLXS_PKT_LOCK); 223782527734SSukumar Swaminathan timeout = emlxs_timeout(hba, 30); 223882527734SSukumar Swaminathan pkt_ret = 0; 223982527734SSukumar Swaminathan while ((pkt_ret != -1) && 224082527734SSukumar Swaminathan (cmd_sbp->fct_state == EMLXS_FCT_REG_PENDING) && 224182527734SSukumar Swaminathan (cmd_sbp->node == NULL)) { 224282527734SSukumar Swaminathan pkt_ret = cv_timedwait(&EMLXS_PKT_CV, 224382527734SSukumar Swaminathan &EMLXS_PKT_LOCK, timeout); 224482527734SSukumar Swaminathan } 224582527734SSukumar Swaminathan mutex_exit(&EMLXS_PKT_LOCK); 2246fcf3ce44SJohn Forte } 2247fcf3ce44SJohn Forte 224882527734SSukumar Swaminathan /* Reacquire ownership of the fct_cmd */ 224982527734SSukumar Swaminathan rval2 = emlxs_fct_cmd_acquire(port, fct_cmd, 225082527734SSukumar Swaminathan EMLXS_FCT_REG_COMPLETE); 225182527734SSukumar Swaminathan if (rval2) { 225282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 225382527734SSukumar Swaminathan "emlxs_fct_register_remote_port: " 225482527734SSukumar Swaminathan "Unable to reacquire fct_cmd. did=%x", 225582527734SSukumar Swaminathan fct_cmd->cmd_rportid); 225682527734SSukumar Swaminathan 225782527734SSukumar Swaminathan return (rval2); 2258291a2b48SSukumar Swaminathan } 225982527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 2260fcf3ce44SJohn Forte } 2261291a2b48SSukumar Swaminathan 2262fcf3ce44SJohn Forte done: 2263fcf3ce44SJohn Forte 2264fcf3ce44SJohn Forte ndlp = (emlxs_node_t *)cmd_sbp->node; 2265fcf3ce44SJohn Forte 2266fcf3ce44SJohn Forte if (ndlp) { 2267291a2b48SSukumar Swaminathan *((emlxs_node_t **)remote_port->rp_fca_private) = 2268291a2b48SSukumar Swaminathan cmd_sbp->node; 2269fcf3ce44SJohn Forte remote_port->rp_handle = ndlp->nlp_Rpi; 2270fcf3ce44SJohn Forte 2271fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2272fcf3ce44SJohn Forte "emlxs_fct_register_remote_port: did=%x hdl=%x", 2273fcf3ce44SJohn Forte fct_cmd->cmd_rportid, remote_port->rp_handle); 2274fcf3ce44SJohn Forte 2275fcf3ce44SJohn Forte remote_port->rp_handle = ndlp->nlp_Rpi; 2276fcf3ce44SJohn Forte 2277fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 227882527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2279291a2b48SSukumar Swaminathan 2280fcf3ce44SJohn Forte TGTPORTSTAT.FctPortRegister++; 2281fcf3ce44SJohn Forte return (FCT_SUCCESS); 2282fcf3ce44SJohn Forte } else { 2283fcf3ce44SJohn Forte *((emlxs_node_t **)remote_port->rp_fca_private) = NULL; 2284fcf3ce44SJohn Forte 2285fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2286fcf3ce44SJohn Forte "emlxs_fct_register_remote_port: failed. did=%x hdl=%x", 2287fcf3ce44SJohn Forte fct_cmd->cmd_rportid, remote_port->rp_handle); 2288fcf3ce44SJohn Forte 2289fcf3ce44SJohn Forte remote_port->rp_handle = FCT_HANDLE_NONE; 2290fcf3ce44SJohn Forte 2291fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 229282527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2293291a2b48SSukumar Swaminathan 2294fcf3ce44SJohn Forte TGTPORTSTAT.FctFailedPortRegister++; 2295fcf3ce44SJohn Forte return (FCT_FAILURE); 2296fcf3ce44SJohn Forte } 2297fcf3ce44SJohn Forte 229882527734SSukumar Swaminathan } /* emlxs_fct_register_remote_port() */ 2299fcf3ce44SJohn Forte 2300fcf3ce44SJohn Forte 230182527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 2302fcf3ce44SJohn Forte static fct_status_t 2303fcf3ce44SJohn Forte emlxs_fct_deregister_remote_port(fct_local_port_t *fct_port, 2304fcf3ce44SJohn Forte fct_remote_port_t *remote_port) 2305fcf3ce44SJohn Forte { 2306fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 2307fcf3ce44SJohn Forte 2308fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2309fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2310fcf3ce44SJohn Forte "emlxs_fct_deregister_remote_port: did=%x hdl=%x", 2311fcf3ce44SJohn Forte remote_port->rp_id, remote_port->rp_handle); 2312fcf3ce44SJohn Forte #else 2313fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2314fcf3ce44SJohn Forte "emlxs_fct_deregister_remote_port: did=%x hdl=%x", 2315fcf3ce44SJohn Forte remote_port->rp_id, remote_port->rp_handle); 2316291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2317fcf3ce44SJohn Forte 2318fcf3ce44SJohn Forte *((emlxs_node_t **)remote_port->rp_fca_private) = NULL; 2319fcf3ce44SJohn Forte (void) emlxs_mb_unreg_did(port, remote_port->rp_id, NULL, NULL, NULL); 2320fcf3ce44SJohn Forte 2321fcf3ce44SJohn Forte TGTPORTSTAT.FctPortDeregister++; 2322fcf3ce44SJohn Forte return (FCT_SUCCESS); 2323fcf3ce44SJohn Forte 232482527734SSukumar Swaminathan } /* emlxs_fct_deregister_remote_port() */ 2325fcf3ce44SJohn Forte 2326fcf3ce44SJohn Forte 2327fcf3ce44SJohn Forte /* ARGSUSED */ 2328fcf3ce44SJohn Forte extern int 232982527734SSukumar Swaminathan emlxs_fct_handle_unsol_req(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 2330fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 2331fcf3ce44SJohn Forte { 2332fcf3ce44SJohn Forte IOCB *iocb; 2333fcf3ce44SJohn Forte fct_cmd_t *fct_cmd; 2334fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 2335fcf3ce44SJohn Forte emlxs_fcp_cmd_t *fcp_cmd; 2336fcf3ce44SJohn Forte emlxs_node_t *ndlp; 2337fcf3ce44SJohn Forte uint32_t cnt; 2338fcf3ce44SJohn Forte uint32_t tm; 2339fcf3ce44SJohn Forte scsi_task_t *fct_task; 2340fcf3ce44SJohn Forte uint8_t lun[8]; 2341fcf3ce44SJohn Forte uint32_t sid = 0; 2342fcf3ce44SJohn Forte 2343fcf3ce44SJohn Forte iocb = &iocbq->iocb; 234482527734SSukumar Swaminathan ndlp = emlxs_node_find_rpi(port, iocb->ULPIOTAG); 2345fcf3ce44SJohn Forte if (!ndlp) { 2346fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2347fcf3ce44SJohn Forte "FCP rcvd: Unknown RPI. rpi=%x rxid=%x. Dropping...", 234882527734SSukumar Swaminathan iocb->ULPIOTAG, iocb->ULPCONTEXT); 2349fcf3ce44SJohn Forte 2350fcf3ce44SJohn Forte goto dropped; 2351fcf3ce44SJohn Forte } 2352fcf3ce44SJohn Forte sid = ndlp->nlp_DID; 2353fcf3ce44SJohn Forte 2354fcf3ce44SJohn Forte fcp_cmd = (emlxs_fcp_cmd_t *)mp->virt; 2355fcf3ce44SJohn Forte 2356fcf3ce44SJohn Forte if (!port->fct_port) { 2357fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2358fcf3ce44SJohn Forte "FCP rcvd: Target unbound. rpi=%x rxid=%x. Dropping...", 235982527734SSukumar Swaminathan iocb->ULPIOTAG, iocb->ULPCONTEXT); 2360fcf3ce44SJohn Forte 2361fcf3ce44SJohn Forte emlxs_send_logo(port, sid); 2362fcf3ce44SJohn Forte 2363fcf3ce44SJohn Forte goto dropped; 2364fcf3ce44SJohn Forte } 2365291a2b48SSukumar Swaminathan 2366fcf3ce44SJohn Forte if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) { 2367fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2368fcf3ce44SJohn Forte "FCP rcvd: Target offline. rpi=%x rxid=%x. Dropping...", 236982527734SSukumar Swaminathan iocb->ULPIOTAG, iocb->ULPCONTEXT); 2370fcf3ce44SJohn Forte 2371fcf3ce44SJohn Forte emlxs_send_logo(port, sid); 2372fcf3ce44SJohn Forte 2373fcf3ce44SJohn Forte goto dropped; 2374fcf3ce44SJohn Forte } 2375291a2b48SSukumar Swaminathan 2376fcf3ce44SJohn Forte /* Get lun id */ 2377fcf3ce44SJohn Forte bcopy((void *)&fcp_cmd->fcpLunMsl, lun, 8); 2378fcf3ce44SJohn Forte 2379fcf3ce44SJohn Forte if (TGTPORTSTAT.FctOutstandingIO >= port->fct_port->port_max_xchges) { 2380fcf3ce44SJohn Forte TGTPORTSTAT.FctOverQDepth++; 2381fcf3ce44SJohn Forte } 2382291a2b48SSukumar Swaminathan 2383291a2b48SSukumar Swaminathan fct_cmd = 238482527734SSukumar Swaminathan MODSYM(fct_scsi_task_alloc) (port->fct_port, iocb->ULPIOTAG, sid, 2385291a2b48SSukumar Swaminathan lun, 16, 0); 2386fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2387fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2388291a2b48SSukumar Swaminathan "fct_scsi_task_alloc %p: FCP rcvd: " 2389291a2b48SSukumar Swaminathan "cmd=%x sid=%x rxid=%x lun=%02x%02x dl=%d", 239082527734SSukumar Swaminathan fct_cmd, fcp_cmd->fcpCdb[0], sid, iocb->ULPCONTEXT, 239182527734SSukumar Swaminathan lun[0], lun[1], LE_SWAP32(fcp_cmd->fcpDl)); 2392291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2393fcf3ce44SJohn Forte 2394fcf3ce44SJohn Forte if (fct_cmd == NULL) { 2395fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2396291a2b48SSukumar Swaminathan "FCP rcvd: sid=%x xid=%x. " 2397291a2b48SSukumar Swaminathan "Unable to allocate scsi task. Returning QFULL.", 239882527734SSukumar Swaminathan sid, iocb->ULPCONTEXT); 2399fcf3ce44SJohn Forte 240082527734SSukumar Swaminathan (void) emlxs_fct_send_qfull_reply(port, ndlp, iocb->ULPCONTEXT, 240182527734SSukumar Swaminathan iocb->ULPCLASS, fcp_cmd); 2402fcf3ce44SJohn Forte 2403fcf3ce44SJohn Forte goto dropped; 2404fcf3ce44SJohn Forte } 2405291a2b48SSukumar Swaminathan 2406fcf3ce44SJohn Forte /* Initialize fct_cmd */ 2407fcf3ce44SJohn Forte fct_cmd->cmd_oxid = 0xFFFF; 240882527734SSukumar Swaminathan fct_cmd->cmd_rxid = iocb->ULPCONTEXT; 2409fcf3ce44SJohn Forte fct_cmd->cmd_rportid = sid; 2410fcf3ce44SJohn Forte fct_cmd->cmd_lportid = port->did; 241182527734SSukumar Swaminathan fct_cmd->cmd_rp_handle = iocb->ULPIOTAG; /* RPI */ 2412fcf3ce44SJohn Forte fct_cmd->cmd_port = port->fct_port; 2413fcf3ce44SJohn Forte 241482527734SSukumar Swaminathan cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd, EMLXS_FCT_FCP_CMD_RECEIVED); 241582527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 2416fcf3ce44SJohn Forte 2417291a2b48SSukumar Swaminathan /* Initialize cmd_sbp */ 241882527734SSukumar Swaminathan cmd_sbp->channel = cp; 241982527734SSukumar Swaminathan cmd_sbp->class = iocb->ULPCLASS; 2420fcf3ce44SJohn Forte cmd_sbp->lun = (lun[0] << 8) | lun[1]; 2421fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_FCP_CMD; 2422fcf3ce44SJohn Forte 2423fcf3ce44SJohn Forte fct_task = (scsi_task_t *)fct_cmd->cmd_specific; 2424fcf3ce44SJohn Forte 2425fcf3ce44SJohn Forte /* Set task_flags */ 2426291a2b48SSukumar Swaminathan switch (fcp_cmd->fcpCntl1) { 2427291a2b48SSukumar Swaminathan case SIMPLE_Q: 2428fcf3ce44SJohn Forte fct_task->task_flags = TF_ATTR_SIMPLE_QUEUE; 2429fcf3ce44SJohn Forte break; 2430fcf3ce44SJohn Forte 2431291a2b48SSukumar Swaminathan case HEAD_OF_Q: 2432fcf3ce44SJohn Forte fct_task->task_flags = TF_ATTR_HEAD_OF_QUEUE; 2433fcf3ce44SJohn Forte break; 2434fcf3ce44SJohn Forte 2435291a2b48SSukumar Swaminathan case ORDERED_Q: 2436fcf3ce44SJohn Forte fct_task->task_flags = TF_ATTR_ORDERED_QUEUE; 2437fcf3ce44SJohn Forte break; 2438fcf3ce44SJohn Forte 2439291a2b48SSukumar Swaminathan case ACA_Q: 2440fcf3ce44SJohn Forte fct_task->task_flags = TF_ATTR_ACA; 2441fcf3ce44SJohn Forte break; 2442fcf3ce44SJohn Forte 2443291a2b48SSukumar Swaminathan case UNTAGGED: 2444fcf3ce44SJohn Forte fct_task->task_flags = TF_ATTR_UNTAGGED; 2445fcf3ce44SJohn Forte break; 2446fcf3ce44SJohn Forte } 2447fcf3ce44SJohn Forte 244882527734SSukumar Swaminathan cnt = LE_SWAP32(fcp_cmd->fcpDl); 2449fcf3ce44SJohn Forte switch (fcp_cmd->fcpCntl3) { 2450fcf3ce44SJohn Forte case 0: 2451fcf3ce44SJohn Forte TGTPORTSTAT.FctIOCmdCnt++; 2452fcf3ce44SJohn Forte break; 2453fcf3ce44SJohn Forte case 1: 245482527734SSukumar Swaminathan EMLXS_BUMP_WRIOCTR(port, cnt); 2455fcf3ce44SJohn Forte TGTPORTSTAT.FctWriteBytes += cnt; 2456fcf3ce44SJohn Forte fct_task->task_flags |= TF_WRITE_DATA; 2457fcf3ce44SJohn Forte break; 2458fcf3ce44SJohn Forte 2459fcf3ce44SJohn Forte case 2: 246082527734SSukumar Swaminathan EMLXS_BUMP_RDIOCTR(port, cnt); 2461fcf3ce44SJohn Forte TGTPORTSTAT.FctReadBytes += cnt; 2462fcf3ce44SJohn Forte fct_task->task_flags |= TF_READ_DATA; 2463fcf3ce44SJohn Forte break; 2464fcf3ce44SJohn Forte } 2465fcf3ce44SJohn Forte 2466fcf3ce44SJohn Forte fct_task->task_priority = 0; 2467fcf3ce44SJohn Forte 2468fcf3ce44SJohn Forte /* task_mgmt_function */ 2469fcf3ce44SJohn Forte tm = fcp_cmd->fcpCntl2; 2470fcf3ce44SJohn Forte if (tm) { 2471fcf3ce44SJohn Forte if (tm & BIT_1) { 2472fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_ABORT_TASK_SET; 2473fcf3ce44SJohn Forte } else if (tm & BIT_2) { 2474fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_CLEAR_TASK_SET; 2475fcf3ce44SJohn Forte } else if (tm & BIT_4) { 2476fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_LUN_RESET; 2477fcf3ce44SJohn Forte } else if (tm & BIT_5) { 2478fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_TARGET_COLD_RESET; 2479fcf3ce44SJohn Forte } else if (tm & BIT_6) { 2480fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_CLEAR_ACA; 2481fcf3ce44SJohn Forte } else { 2482fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_ABORT_TASK; 2483fcf3ce44SJohn Forte } 2484fcf3ce44SJohn Forte } 2485291a2b48SSukumar Swaminathan 2486fcf3ce44SJohn Forte /* Parallel buffers support - future */ 2487fcf3ce44SJohn Forte fct_task->task_max_nbufs = 1; 2488fcf3ce44SJohn Forte 2489fcf3ce44SJohn Forte fct_task->task_additional_flags = 0; 2490fcf3ce44SJohn Forte fct_task->task_cur_nbufs = 0; 2491fcf3ce44SJohn Forte fct_task->task_csn_size = 8; 2492fcf3ce44SJohn Forte fct_task->task_cmd_seq_no = 0; 2493fcf3ce44SJohn Forte fct_task->task_expected_xfer_length = cnt; 2494fcf3ce44SJohn Forte bcopy((void *)&fcp_cmd->fcpCdb, fct_task->task_cdb, 16); 2495fcf3ce44SJohn Forte 2496fcf3ce44SJohn Forte TGTPORTSTAT.FctCmdReceived++; 2497fcf3ce44SJohn Forte TGTPORTSTAT.FctOutstandingIO++; 2498fcf3ce44SJohn Forte 249982527734SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 250082527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2501fcf3ce44SJohn Forte 2502291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE 2503291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 250482527734SSukumar Swaminathan "fct_post_rcvd_cmd:3 %p: portid x%x, %d", fct_cmd, 250582527734SSukumar Swaminathan fct_cmd->cmd_lportid, fct_task->task_expected_xfer_length); 2506291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 250782527734SSukumar Swaminathan 2508291a2b48SSukumar Swaminathan MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0); 2509fcf3ce44SJohn Forte 2510fcf3ce44SJohn Forte return (0); 2511fcf3ce44SJohn Forte 2512fcf3ce44SJohn Forte dropped: 2513fcf3ce44SJohn Forte 2514fcf3ce44SJohn Forte TGTPORTSTAT.FctRcvDropped++; 2515fcf3ce44SJohn Forte return (1); 2516fcf3ce44SJohn Forte 251782527734SSukumar Swaminathan } /* emlxs_fct_handle_unsol_req() */ 2518fcf3ce44SJohn Forte 2519fcf3ce44SJohn Forte 252082527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 2521fcf3ce44SJohn Forte /* ARGSUSED */ 2522fcf3ce44SJohn Forte static fct_status_t 2523fcf3ce44SJohn Forte emlxs_fct_send_fcp_data(fct_cmd_t *fct_cmd, stmf_data_buf_t *dbuf, 2524fcf3ce44SJohn Forte uint32_t ioflags) 2525fcf3ce44SJohn Forte { 2526fcf3ce44SJohn Forte emlxs_port_t *port = 2527fcf3ce44SJohn Forte (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 2528fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 2529fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 2530291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE 2531fcf3ce44SJohn Forte scsi_task_t *fct_task; 2532291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2533fcf3ce44SJohn Forte IOCBQ *iocbq; 2534fcf3ce44SJohn Forte emlxs_node_t *ndlp; 2535fcf3ce44SJohn Forte 253682527734SSukumar Swaminathan int channel; 253782527734SSukumar Swaminathan int channelno; 2538*b3660a96SSukumar Swaminathan fct_status_t rval = 0; 2539fcf3ce44SJohn Forte 254082527734SSukumar Swaminathan rval = emlxs_fct_cmd_accept(port, fct_cmd, EMLXS_FCT_SEND_FCP_DATA); 254182527734SSukumar Swaminathan if (rval) { 254282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 254382527734SSukumar Swaminathan "emlxs_fct_send_fcp_data: " 254482527734SSukumar Swaminathan "Unable to accept fct_cmd. did=%x", 254582527734SSukumar Swaminathan fct_cmd->cmd_rportid); 2546fcf3ce44SJohn Forte 254782527734SSukumar Swaminathan return (rval); 2548fcf3ce44SJohn Forte } 254982527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 2550291a2b48SSukumar Swaminathan 255182527734SSukumar Swaminathan cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 255282527734SSukumar Swaminathan #ifdef FCT_API_TRACE 255382527734SSukumar Swaminathan fct_task = (scsi_task_t *)fct_cmd->cmd_specific; 255482527734SSukumar Swaminathan #endif /* FCT_API_TRACE */ 255582527734SSukumar Swaminathan ndlp = *(emlxs_node_t **)fct_cmd->cmd_rp->rp_fca_private; 2556291a2b48SSukumar Swaminathan 2557fcf3ce44SJohn Forte cmd_sbp->node = ndlp; 2558fcf3ce44SJohn Forte cmd_sbp->fct_buf = dbuf; 2559fcf3ce44SJohn Forte 256082527734SSukumar Swaminathan channelno = ((CHANNEL *)cmd_sbp->channel)->channelno; 256182527734SSukumar Swaminathan 256282527734SSukumar Swaminathan channel = channelno; 256382527734SSukumar Swaminathan 256482527734SSukumar Swaminathan 256582527734SSukumar Swaminathan 2566fcf3ce44SJohn Forte iocbq = &cmd_sbp->iocbq; 2567fcf3ce44SJohn Forte 2568fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2569fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 257082527734SSukumar Swaminathan "emlxs_fct_send_fcp_data %p: flgs=%x ioflags=%x dl=%d,%d,%d, %d", 2571fcf3ce44SJohn Forte fct_cmd, dbuf->db_flags, ioflags, fct_task->task_cmd_xfer_length, 257282527734SSukumar Swaminathan fct_task->task_nbytes_transferred, dbuf->db_data_size, 257382527734SSukumar Swaminathan fct_task->task_expected_xfer_length); 2574291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2575fcf3ce44SJohn Forte 257682527734SSukumar Swaminathan if (EMLXS_SLI_PREP_FCT_IOCB(port, cmd_sbp, channel) != IOERR_SUCCESS) { 257782527734SSukumar Swaminathan 2578fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 257982527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2580fcf3ce44SJohn Forte 2581fcf3ce44SJohn Forte return (FCT_BUSY); 2582fcf3ce44SJohn Forte } 2583291a2b48SSukumar Swaminathan 2584fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_FCP_DATA; 2585fcf3ce44SJohn Forte 2586fcf3ce44SJohn Forte if (dbuf->db_flags & DB_SEND_STATUS_GOOD) { 2587fcf3ce44SJohn Forte cmd_sbp->fct_flags |= EMLXS_FCT_SEND_STATUS; 2588fcf3ce44SJohn Forte } 2589fcf3ce44SJohn Forte 2590fcf3ce44SJohn Forte if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) { 2591*b3660a96SSukumar Swaminathan if (emlxs_fct_dbuf_dma_sync(hba, dbuf, DDI_DMA_SYNC_FORDEV)) { 2592*b3660a96SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 2593*b3660a96SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2594*b3660a96SSukumar Swaminathan 2595*b3660a96SSukumar Swaminathan return (FCT_BUSY); 2596*b3660a96SSukumar Swaminathan } 2597fcf3ce44SJohn Forte } 2598291a2b48SSukumar Swaminathan 2599291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP; 260082527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, EMLXS_FCT_DATA_PENDING); 260182527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 260282527734SSukumar Swaminathan 260382527734SSukumar Swaminathan EMLXS_SLI_ISSUE_IOCB_CMD(hba, cmd_sbp->channel, iocbq); 2604fcf3ce44SJohn Forte 2605fcf3ce44SJohn Forte return (FCT_SUCCESS); 2606fcf3ce44SJohn Forte 260782527734SSukumar Swaminathan } /* emlxs_fct_send_fcp_data() */ 2608fcf3ce44SJohn Forte 2609fcf3ce44SJohn Forte 261082527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be held to enter */ 261182527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be released before exiting */ 2612fcf3ce44SJohn Forte static fct_status_t 2613fcf3ce44SJohn Forte emlxs_fct_send_fcp_status(fct_cmd_t *fct_cmd) 2614fcf3ce44SJohn Forte { 2615fcf3ce44SJohn Forte emlxs_port_t *port = 2616fcf3ce44SJohn Forte (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 2617fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 2618fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 2619fcf3ce44SJohn Forte scsi_task_t *fct_task; 2620fcf3ce44SJohn Forte fc_packet_t *pkt; 2621fcf3ce44SJohn Forte uint32_t did; 2622fcf3ce44SJohn Forte emlxs_fcp_rsp *fcp_rsp; 2623fcf3ce44SJohn Forte uint32_t size; 2624fcf3ce44SJohn Forte emlxs_node_t *ndlp; 262582527734SSukumar Swaminathan fct_status_t rval; 2626fcf3ce44SJohn Forte 2627fcf3ce44SJohn Forte fct_task = (scsi_task_t *)fct_cmd->cmd_specific; 2628fcf3ce44SJohn Forte ndlp = *(emlxs_node_t **)fct_cmd->cmd_rp->rp_fca_private; 2629fcf3ce44SJohn Forte did = fct_cmd->cmd_rportid; 2630fcf3ce44SJohn Forte 2631fcf3ce44SJohn Forte /* Initialize cmd_sbp */ 2632fcf3ce44SJohn Forte cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 2633fcf3ce44SJohn Forte 263482527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, EMLXS_FCT_SEND_FCP_STATUS); 2635291a2b48SSukumar Swaminathan 2636fcf3ce44SJohn Forte cmd_sbp->node = ndlp; 2637fcf3ce44SJohn Forte 2638fcf3ce44SJohn Forte size = 24; 2639fcf3ce44SJohn Forte if (fct_task->task_sense_length) { 2640fcf3ce44SJohn Forte size += fct_task->task_sense_length; 2641fcf3ce44SJohn Forte } 2642fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2643fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2644fcf3ce44SJohn Forte "emlxs_fct_send_fcp_status %p: stat=%d resid=%d size=%d rx=%x", 2645fcf3ce44SJohn Forte fct_cmd, fct_task->task_scsi_status, 2646fcf3ce44SJohn Forte fct_task->task_resid, size, fct_cmd->cmd_rxid); 2647291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2648fcf3ce44SJohn Forte 2649fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, size, 0, 0, KM_NOSLEEP))) { 2650fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 2651fcf3ce44SJohn Forte "emlxs_fct_send_fcp_status: Unable to allocate packet."); 2652fcf3ce44SJohn Forte 2653fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 265482527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2655fcf3ce44SJohn Forte 2656291a2b48SSukumar Swaminathan return (FCT_BUSY); 2657fcf3ce44SJohn Forte } 2658291a2b48SSukumar Swaminathan 2659fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_FCP_STATUS; 2660fcf3ce44SJohn Forte 2661fcf3ce44SJohn Forte (void) emlxs_fct_pkt_init(port, fct_cmd, pkt); 2662291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = pkt; 2663fcf3ce44SJohn Forte 2664fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND; 2665fcf3ce44SJohn Forte pkt->pkt_timeout = 2666fcf3ce44SJohn Forte ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov); 2667fcf3ce44SJohn Forte pkt->pkt_comp = emlxs_fct_pkt_comp; 2668fcf3ce44SJohn Forte 2669fcf3ce44SJohn Forte /* Build the fc header */ 267082527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(did); 2671fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_STATUS; 267282527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did); 2673fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_SCSI_FCP; 2674fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = 2675fcf3ce44SJohn Forte F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ; 2676fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 2677fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 2678fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 2679fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = fct_cmd->cmd_oxid; 2680fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = fct_cmd->cmd_rxid; 2681fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 2682fcf3ce44SJohn Forte 2683fcf3ce44SJohn Forte /* Build the status payload */ 2684fcf3ce44SJohn Forte fcp_rsp = (emlxs_fcp_rsp *)pkt->pkt_cmd; 2685fcf3ce44SJohn Forte 2686fcf3ce44SJohn Forte if (fct_task->task_resid) { 2687fcf3ce44SJohn Forte if (fct_task->task_status_ctrl & TASK_SCTRL_OVER) { 2688fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiResidOver++; 2689fcf3ce44SJohn Forte fcp_rsp->rspStatus2 |= RESID_OVER; 269082527734SSukumar Swaminathan fcp_rsp->rspResId = LE_SWAP32(fct_task->task_resid); 2691fcf3ce44SJohn Forte 2692fcf3ce44SJohn Forte } else if (fct_task->task_status_ctrl & TASK_SCTRL_UNDER) { 2693fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiResidUnder++; 2694fcf3ce44SJohn Forte fcp_rsp->rspStatus2 |= RESID_UNDER; 269582527734SSukumar Swaminathan fcp_rsp->rspResId = LE_SWAP32(fct_task->task_resid); 2696fcf3ce44SJohn Forte 2697fcf3ce44SJohn Forte } 2698fcf3ce44SJohn Forte } 2699291a2b48SSukumar Swaminathan 2700fcf3ce44SJohn Forte if (fct_task->task_scsi_status) { 2701fcf3ce44SJohn Forte if (fct_task->task_scsi_status == SCSI_STAT_QUE_FULL) { 2702fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiQfullErr++; 2703fcf3ce44SJohn Forte } else { 2704fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiStatusErr++; 2705fcf3ce44SJohn Forte } 2706fcf3ce44SJohn Forte 2707291a2b48SSukumar Swaminathan /* Make sure residual reported on non-SCSI_GOOD READ status */ 2708fcf3ce44SJohn Forte if ((fct_task->task_flags & TF_READ_DATA) && 2709fcf3ce44SJohn Forte (fcp_rsp->rspResId == 0)) { 2710fcf3ce44SJohn Forte fcp_rsp->rspStatus2 |= RESID_UNDER; 2711291a2b48SSukumar Swaminathan fcp_rsp->rspResId = 2712291a2b48SSukumar Swaminathan fct_task->task_expected_xfer_length; 2713fcf3ce44SJohn Forte } 2714fcf3ce44SJohn Forte } 2715291a2b48SSukumar Swaminathan 2716291a2b48SSukumar Swaminathan 2717fcf3ce44SJohn Forte if (fct_task->task_sense_length) { 2718fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiSenseErr++; 2719fcf3ce44SJohn Forte fcp_rsp->rspStatus2 |= SNS_LEN_VALID; 272082527734SSukumar Swaminathan fcp_rsp->rspSnsLen = LE_SWAP32(fct_task->task_sense_length); 2721fcf3ce44SJohn Forte 2722fcf3ce44SJohn Forte bcopy((uint8_t *)fct_task->task_sense_data, 2723291a2b48SSukumar Swaminathan (uint8_t *)&fcp_rsp->rspInfo0, 2724291a2b48SSukumar Swaminathan fct_task->task_sense_length); 2725fcf3ce44SJohn Forte } 2726291a2b48SSukumar Swaminathan 2727fcf3ce44SJohn Forte fcp_rsp->rspStatus3 = fct_task->task_scsi_status; 2728fcf3ce44SJohn Forte fcp_rsp->rspRspLen = 0; 272982527734SSukumar Swaminathan 2730291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP; 273182527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, EMLXS_FCT_STATUS_PENDING); 273282527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2733fcf3ce44SJohn Forte 2734fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 273582527734SSukumar Swaminathan 2736fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 2737fcf3ce44SJohn Forte "emlxs_fct_send_fcp_status: Unable to send packet."); 2738fcf3ce44SJohn Forte 273982527734SSukumar Swaminathan /* Reacquire ownership of the fct_cmd */ 274082527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, 0); 274182527734SSukumar Swaminathan if (rval) { 274282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 274382527734SSukumar Swaminathan "emlxs_fct_send_fcp_status: " 274482527734SSukumar Swaminathan "Unable to acquire fct_cmd."); 274582527734SSukumar Swaminathan return (rval); 2746fcf3ce44SJohn Forte } 274782527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 2748291a2b48SSukumar Swaminathan 2749fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 275082527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2751291a2b48SSukumar Swaminathan 2752291a2b48SSukumar Swaminathan return (FCT_BUSY); 2753fcf3ce44SJohn Forte } 2754291a2b48SSukumar Swaminathan 2755fcf3ce44SJohn Forte return (FCT_SUCCESS); 2756fcf3ce44SJohn Forte 275782527734SSukumar Swaminathan } /* emlxs_fct_send_fcp_status() */ 2758fcf3ce44SJohn Forte 2759fcf3ce44SJohn Forte 2760fcf3ce44SJohn Forte static fct_status_t 2761291a2b48SSukumar Swaminathan emlxs_fct_send_qfull_reply(emlxs_port_t *port, emlxs_node_t *ndlp, 2762291a2b48SSukumar Swaminathan uint16_t xid, uint32_t class, emlxs_fcp_cmd_t *fcp_cmd) 2763fcf3ce44SJohn Forte { 2764fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 2765fcf3ce44SJohn Forte emlxs_buf_t *sbp; 2766fcf3ce44SJohn Forte fc_packet_t *pkt; 2767fcf3ce44SJohn Forte emlxs_fcp_rsp *fcp_rsp; 2768fcf3ce44SJohn Forte uint32_t size; 276982527734SSukumar Swaminathan CHANNEL *cp = &hba->chan[hba->CHANNEL_FCT]; 2770fcf3ce44SJohn Forte uint8_t lun[8]; 2771fcf3ce44SJohn Forte 2772fcf3ce44SJohn Forte bcopy((void *)&fcp_cmd->fcpLunMsl, lun, 8); 2773fcf3ce44SJohn Forte size = 24; 2774fcf3ce44SJohn Forte 2775fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, size, 0, 0, KM_NOSLEEP))) { 2776fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 2777fcf3ce44SJohn Forte "emlxs_fct_send_qfull_reply: Unable to allocate packet."); 2778fcf3ce44SJohn Forte return (FCT_FAILURE); 2779fcf3ce44SJohn Forte } 2780291a2b48SSukumar Swaminathan 2781291a2b48SSukumar Swaminathan 2782fcf3ce44SJohn Forte sbp = PKT2PRIV(pkt); 2783fcf3ce44SJohn Forte sbp->node = ndlp; 278482527734SSukumar Swaminathan sbp->channel = cp; 2785fcf3ce44SJohn Forte sbp->did = ndlp->nlp_DID; 2786fcf3ce44SJohn Forte sbp->lun = (lun[0] << 8) | lun[1]; 2787fcf3ce44SJohn Forte sbp->class = class; 2788fcf3ce44SJohn Forte 2789fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND; 2790fcf3ce44SJohn Forte pkt->pkt_timeout = 2791fcf3ce44SJohn Forte ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov); 2792fcf3ce44SJohn Forte 2793fcf3ce44SJohn Forte /* Build the fc header */ 279482527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(ndlp->nlp_DID); 2795fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_STATUS; 279682527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did); 2797fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_SCSI_FCP; 2798fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = 2799fcf3ce44SJohn Forte F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ; 2800fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 2801fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 2802fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 2803fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xFFFF; 2804fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = xid; 2805fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 2806fcf3ce44SJohn Forte 2807fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 2808fcf3ce44SJohn Forte "emlxs_fct_send_qfull_reply: Sending QFULL: x%x lun x%x: %d %d", 2809fcf3ce44SJohn Forte xid, sbp->lun, TGTPORTSTAT.FctOutstandingIO, 2810fcf3ce44SJohn Forte port->fct_port->port_max_xchges); 2811fcf3ce44SJohn Forte 2812fcf3ce44SJohn Forte /* Build the status payload */ 2813fcf3ce44SJohn Forte fcp_rsp = (emlxs_fcp_rsp *)pkt->pkt_cmd; 2814fcf3ce44SJohn Forte 2815fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiQfullErr++; 2816fcf3ce44SJohn Forte fcp_rsp->rspStatus3 = SCSI_STAT_QUE_FULL; 2817fcf3ce44SJohn Forte fcp_rsp->rspStatus2 |= RESID_UNDER; 281882527734SSukumar Swaminathan fcp_rsp->rspResId = LE_SWAP32(fcp_cmd->fcpDl); 2819fcf3ce44SJohn Forte 2820fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 2821fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 2822fcf3ce44SJohn Forte "emlxs_fct_send_qfull_reply: Unable to send packet."); 2823fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 2824fcf3ce44SJohn Forte return (FCT_FAILURE); 2825fcf3ce44SJohn Forte } 2826fcf3ce44SJohn Forte 2827291a2b48SSukumar Swaminathan return (FCT_SUCCESS); 2828fcf3ce44SJohn Forte 282982527734SSukumar Swaminathan } /* emlxs_fct_send_qfull_reply() */ 2830fcf3ce44SJohn Forte 2831fcf3ce44SJohn Forte 2832fcf3ce44SJohn Forte /* ARGSUSED */ 2833fcf3ce44SJohn Forte extern int 283482527734SSukumar Swaminathan emlxs_fct_handle_fcp_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq) 2835fcf3ce44SJohn Forte { 2836fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 2837fcf3ce44SJohn Forte IOCB *iocb; 2838fcf3ce44SJohn Forte emlxs_buf_t *sbp; 2839fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 2840fcf3ce44SJohn Forte uint32_t status; 2841fcf3ce44SJohn Forte fct_cmd_t *fct_cmd; 2842fcf3ce44SJohn Forte stmf_data_buf_t *dbuf; 2843fcf3ce44SJohn Forte scsi_task_t *fct_task; 2844291a2b48SSukumar Swaminathan fc_packet_t *pkt; 284582527734SSukumar Swaminathan uint32_t fct_flags; 284682527734SSukumar Swaminathan stmf_data_buf_t *fct_buf; 284782527734SSukumar Swaminathan fct_status_t rval; 2848fcf3ce44SJohn Forte 2849fcf3ce44SJohn Forte iocb = &iocbq->iocb; 2850fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)iocbq->sbp; 2851fcf3ce44SJohn Forte 2852fcf3ce44SJohn Forte TGTPORTSTAT.FctEvent++; 2853fcf3ce44SJohn Forte 2854fcf3ce44SJohn Forte if (!sbp) { 2855fcf3ce44SJohn Forte /* completion with missing xmit command */ 2856fcf3ce44SJohn Forte TGTPORTSTAT.FctStray++; 2857fcf3ce44SJohn Forte 2858fcf3ce44SJohn Forte /* emlxs_stray_fcp_completion_msg */ 2859fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 2860291a2b48SSukumar Swaminathan "FCP event cmd=%x status=%x error=%x iotag=%x", 286182527734SSukumar Swaminathan iocb->ULPCOMMAND, iocb->ULPSTATUS, 286282527734SSukumar Swaminathan iocb->un.grsp.perr.statLocalError, iocb->ULPIOTAG); 2863fcf3ce44SJohn Forte 2864fcf3ce44SJohn Forte return (1); 2865fcf3ce44SJohn Forte } 2866291a2b48SSukumar Swaminathan 2867fcf3ce44SJohn Forte TGTPORTSTAT.FctCompleted++; 2868fcf3ce44SJohn Forte 2869fcf3ce44SJohn Forte port = sbp->iocbq.port; 2870fcf3ce44SJohn Forte fct_cmd = sbp->fct_cmd; 287182527734SSukumar Swaminathan status = iocb->ULPSTATUS; 2872fcf3ce44SJohn Forte 2873fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2874fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 287582527734SSukumar Swaminathan "emlxs_fct_handle_fcp_event: %p: cmd=%x status=%x, %x", 287682527734SSukumar Swaminathan fct_cmd, iocb->ULPCOMMAND, status, iocb->ULPCT); 2877291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 2878fcf3ce44SJohn Forte 2879fcf3ce44SJohn Forte if (fct_cmd == NULL) { 2880291a2b48SSukumar Swaminathan /* For driver generated QFULL response */ 288182527734SSukumar Swaminathan if (((iocb->ULPCOMMAND == CMD_FCP_TRSP_CX) || 288282527734SSukumar Swaminathan (iocb->ULPCOMMAND == CMD_FCP_TRSP64_CX)) && sbp->pkt) { 2883fcf3ce44SJohn Forte emlxs_pkt_free(sbp->pkt); 2884fcf3ce44SJohn Forte } 2885fcf3ce44SJohn Forte return (0); 2886fcf3ce44SJohn Forte } 2887291a2b48SSukumar Swaminathan 288882527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, EMLXS_FCT_REQ_COMPLETE); 288982527734SSukumar Swaminathan if (rval) { 289082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 289182527734SSukumar Swaminathan "emlxs_fct_handle_fcp_event: " 289282527734SSukumar Swaminathan "Unable to reacquire fct_cmd. type=%x", 289382527734SSukumar Swaminathan fct_cmd->cmd_type); 289482527734SSukumar Swaminathan 289582527734SSukumar Swaminathan return (1); 2896291a2b48SSukumar Swaminathan } 289782527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 2898291a2b48SSukumar Swaminathan 2899fcf3ce44SJohn Forte cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 290082527734SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP; 2901291a2b48SSukumar Swaminathan 2902291a2b48SSukumar Swaminathan pkt = cmd_sbp->fct_pkt; 290382527734SSukumar Swaminathan cmd_sbp->fct_pkt = NULL; 2904fcf3ce44SJohn Forte 290582527734SSukumar Swaminathan dbuf = sbp->fct_buf; 2906fcf3ce44SJohn Forte 2907291a2b48SSukumar Swaminathan fct_cmd->cmd_comp_status = FCT_SUCCESS; 2908291a2b48SSukumar Swaminathan 2909291a2b48SSukumar Swaminathan if (status) { 2910*b3660a96SSukumar Swaminathan emlxs_dma_error: 2911fcf3ce44SJohn Forte /* 2912291a2b48SSukumar Swaminathan * The error indicates this IO should be terminated 2913291a2b48SSukumar Swaminathan * immediately. 2914fcf3ce44SJohn Forte */ 2915291a2b48SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_SEND_STATUS; 291682527734SSukumar Swaminathan fct_cmd->cmd_comp_status = FCT_FAILURE; 2917291a2b48SSukumar Swaminathan 291882527734SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED); 291982527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2920291a2b48SSukumar Swaminathan 2921291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE 2922291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2923291a2b48SSukumar Swaminathan "fct_queue_cmd_for_termination:1 %p: x%x", 2924291a2b48SSukumar Swaminathan fct_cmd, fct_cmd->cmd_comp_status); 2925291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 292682527734SSukumar Swaminathan 2927291a2b48SSukumar Swaminathan MODSYM(fct_queue_cmd_for_termination) (fct_cmd, 2928291a2b48SSukumar Swaminathan FCT_ABTS_RECEIVED); 292982527734SSukumar Swaminathan 2930291a2b48SSukumar Swaminathan goto done; 2931291a2b48SSukumar Swaminathan } 2932291a2b48SSukumar Swaminathan 293382527734SSukumar Swaminathan switch (iocb->ULPCOMMAND) { 2934291a2b48SSukumar Swaminathan 2935291a2b48SSukumar Swaminathan /* 2936291a2b48SSukumar Swaminathan * FCP Data completion 2937291a2b48SSukumar Swaminathan */ 2938fcf3ce44SJohn Forte case CMD_FCP_TSEND_CX: 2939fcf3ce44SJohn Forte case CMD_FCP_TSEND64_CX: 2940fcf3ce44SJohn Forte case CMD_FCP_TRECEIVE_CX: 2941fcf3ce44SJohn Forte case CMD_FCP_TRECEIVE64_CX: 2942fcf3ce44SJohn Forte 294382527734SSukumar Swaminathan if (dbuf->db_flags & DB_DIRECTION_FROM_RPORT) { 2944*b3660a96SSukumar Swaminathan if (emlxs_fct_dbuf_dma_sync(hba, dbuf, 2945*b3660a96SSukumar Swaminathan DDI_DMA_SYNC_FORCPU)) { 2946*b3660a96SSukumar Swaminathan goto emlxs_dma_error; 2947*b3660a96SSukumar Swaminathan } 294882527734SSukumar Swaminathan } 2949fcf3ce44SJohn Forte 295082527734SSukumar Swaminathan if ((cmd_sbp->fct_flags & EMLXS_FCT_SEND_STATUS) && 295182527734SSukumar Swaminathan (iocb->ULPCT != 1)) { 2952291a2b48SSukumar Swaminathan 295382527734SSukumar Swaminathan dbuf->db_flags |= DB_STATUS_GOOD_SENT; 2954fcf3ce44SJohn Forte 295582527734SSukumar Swaminathan fct_task = 295682527734SSukumar Swaminathan (scsi_task_t *)fct_cmd->cmd_specific; 295782527734SSukumar Swaminathan fct_task->task_scsi_status = 0; 2958fcf3ce44SJohn Forte 295982527734SSukumar Swaminathan (void) emlxs_fct_send_fcp_status(fct_cmd); 296082527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 2961fcf3ce44SJohn Forte 296282527734SSukumar Swaminathan break; 296382527734SSukumar Swaminathan 296482527734SSukumar Swaminathan } else if ((cmd_sbp->fct_flags & 296582527734SSukumar Swaminathan EMLXS_FCT_SEND_STATUS) && 296682527734SSukumar Swaminathan (iocb->ULPCT == 1)) { 296782527734SSukumar Swaminathan /* Auto-resp has been sent out by firmware */ 296882527734SSukumar Swaminathan /* We can assume this is really a FC_TRSP_CX */ 296982527734SSukumar Swaminathan 297082527734SSukumar Swaminathan dbuf->db_flags |= DB_STATUS_GOOD_SENT; 297182527734SSukumar Swaminathan fct_task = 297282527734SSukumar Swaminathan (scsi_task_t *)fct_cmd->cmd_specific; 297382527734SSukumar Swaminathan fct_task->task_scsi_status = 0; 297482527734SSukumar Swaminathan 297582527734SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_SEND_STATUS; 297682527734SSukumar Swaminathan 297782527734SSukumar Swaminathan goto auto_resp; 2978fcf3ce44SJohn Forte } 2979291a2b48SSukumar Swaminathan 2980fcf3ce44SJohn Forte cmd_sbp->fct_flags &= ~EMLXS_FCT_SEND_STATUS; 2981fcf3ce44SJohn Forte 2982fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 298382527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 298482527734SSukumar Swaminathan 2985fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 2986fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 2987fcf3ce44SJohn Forte "fct_scsi_data_xfer_done:1 %p %p", fct_cmd, dbuf); 2988291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 298982527734SSukumar Swaminathan 2990fcf3ce44SJohn Forte MODSYM(fct_scsi_data_xfer_done) (fct_cmd, dbuf, 0); 2991fcf3ce44SJohn Forte 2992fcf3ce44SJohn Forte break; 2993fcf3ce44SJohn Forte 2994fcf3ce44SJohn Forte /* FCP Status completion */ 2995fcf3ce44SJohn Forte case CMD_FCP_TRSP_CX: 2996fcf3ce44SJohn Forte case CMD_FCP_TRSP64_CX: 2997fcf3ce44SJohn Forte 299882527734SSukumar Swaminathan auto_resp: 299982527734SSukumar Swaminathan /* Copy these before calling emlxs_fct_cmd_done */ 300082527734SSukumar Swaminathan fct_flags = cmd_sbp->fct_flags; 300182527734SSukumar Swaminathan fct_buf = cmd_sbp->fct_buf; 3002fcf3ce44SJohn Forte 300382527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_IO_DONE); 300482527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3005fcf3ce44SJohn Forte 300682527734SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--; 3007fcf3ce44SJohn Forte 300882527734SSukumar Swaminathan if (fct_flags & EMLXS_FCT_SEND_STATUS) { 3009fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 3010fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3011fcf3ce44SJohn Forte "fct_scsi_data_xfer_done:2 %p %p", 301282527734SSukumar Swaminathan fct_cmd, fct_buf); 3013291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 301482527734SSukumar Swaminathan 3015fcf3ce44SJohn Forte MODSYM(fct_scsi_data_xfer_done) (fct_cmd, 301682527734SSukumar Swaminathan fct_buf, FCT_IOF_FCA_DONE); 3017fcf3ce44SJohn Forte } else { 3018fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 3019fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3020fcf3ce44SJohn Forte "fct_send_response_done:1 %p: x%x", 3021fcf3ce44SJohn Forte fct_cmd, fct_cmd->cmd_comp_status); 3022291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 302382527734SSukumar Swaminathan 3024fcf3ce44SJohn Forte MODSYM(fct_send_response_done) (fct_cmd, 3025fcf3ce44SJohn Forte fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE); 3026fcf3ce44SJohn Forte } 3027fcf3ce44SJohn Forte break; 3028fcf3ce44SJohn Forte 3029fcf3ce44SJohn Forte default: 303082527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, 0); 303182527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3032291a2b48SSukumar Swaminathan 3033fcf3ce44SJohn Forte TGTPORTSTAT.FctStray++; 3034fcf3ce44SJohn Forte TGTPORTSTAT.FctCompleted--; 3035fcf3ce44SJohn Forte 3036fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 303782527734SSukumar Swaminathan "Invalid iocb: cmd=0x%x", iocb->ULPCOMMAND); 3038fcf3ce44SJohn Forte 3039291a2b48SSukumar Swaminathan if (pkt) { 3040291a2b48SSukumar Swaminathan emlxs_pkt_complete(sbp, status, 3041291a2b48SSukumar Swaminathan iocb->un.grsp.perr.statLocalError, 1); 3042291a2b48SSukumar Swaminathan } 3043fcf3ce44SJohn Forte 304482527734SSukumar Swaminathan } /* switch(iocb->ULPCOMMAND) */ 3045fcf3ce44SJohn Forte 3046fcf3ce44SJohn Forte 3047291a2b48SSukumar Swaminathan done: 3048291a2b48SSukumar Swaminathan if (pkt) { 3049291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt); 3050291a2b48SSukumar Swaminathan } 3051291a2b48SSukumar Swaminathan 3052fcf3ce44SJohn Forte if (status == IOSTAT_SUCCESS) { 3053fcf3ce44SJohn Forte TGTPORTSTAT.FctCmplGood++; 3054fcf3ce44SJohn Forte } else { 3055fcf3ce44SJohn Forte TGTPORTSTAT.FctCmplError++; 3056fcf3ce44SJohn Forte } 3057fcf3ce44SJohn Forte 3058fcf3ce44SJohn Forte return (0); 3059fcf3ce44SJohn Forte 306082527734SSukumar Swaminathan } /* emlxs_fct_handle_fcp_event() */ 3061291a2b48SSukumar Swaminathan 3062291a2b48SSukumar Swaminathan 3063291a2b48SSukumar Swaminathan /* ARGSUSED */ 3064291a2b48SSukumar Swaminathan extern int 306582527734SSukumar Swaminathan emlxs_fct_handle_abort(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq) 3066291a2b48SSukumar Swaminathan { 3067291a2b48SSukumar Swaminathan emlxs_port_t *port = &PPORT; 3068291a2b48SSukumar Swaminathan IOCB *iocb; 3069291a2b48SSukumar Swaminathan emlxs_buf_t *sbp; 3070291a2b48SSukumar Swaminathan fc_packet_t *pkt; 3071291a2b48SSukumar Swaminathan 3072291a2b48SSukumar Swaminathan iocb = &iocbq->iocb; 3073291a2b48SSukumar Swaminathan sbp = (emlxs_buf_t *)iocbq->sbp; 3074291a2b48SSukumar Swaminathan 3075291a2b48SSukumar Swaminathan TGTPORTSTAT.FctEvent++; 3076291a2b48SSukumar Swaminathan 3077291a2b48SSukumar Swaminathan if (!sbp) { 3078291a2b48SSukumar Swaminathan /* completion with missing xmit command */ 3079291a2b48SSukumar Swaminathan TGTPORTSTAT.FctStray++; 3080291a2b48SSukumar Swaminathan 3081291a2b48SSukumar Swaminathan /* emlxs_stray_fcp_completion_msg */ 3082291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3083291a2b48SSukumar Swaminathan "ABORT event cmd=%x status=%x error=%x iotag=%x", 308482527734SSukumar Swaminathan iocb->ULPCOMMAND, iocb->ULPSTATUS, 308582527734SSukumar Swaminathan iocb->un.grsp.perr.statLocalError, iocb->ULPIOTAG); 3086291a2b48SSukumar Swaminathan 3087291a2b48SSukumar Swaminathan return (1); 3088291a2b48SSukumar Swaminathan } 3089291a2b48SSukumar Swaminathan 3090291a2b48SSukumar Swaminathan pkt = PRIV2PKT(sbp); 3091291a2b48SSukumar Swaminathan 3092291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE 3093291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 309482527734SSukumar Swaminathan "emlxs_fct_handle_abort: %p: xri=%x status=%x", iocb->ULPCONTEXT, 309582527734SSukumar Swaminathan iocb->ULPCOMMAND, iocb->ULPSTATUS); 3096291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 3097291a2b48SSukumar Swaminathan 3098291a2b48SSukumar Swaminathan 3099291a2b48SSukumar Swaminathan if (pkt) { 3100291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt); 3101291a2b48SSukumar Swaminathan } 3102291a2b48SSukumar Swaminathan return (0); 3103fcf3ce44SJohn Forte 310482527734SSukumar Swaminathan } /* emlxs_fct_handle_abort() */ 3105fcf3ce44SJohn Forte 3106fcf3ce44SJohn Forte 3107fcf3ce44SJohn Forte extern int 310882527734SSukumar Swaminathan emlxs_fct_handle_unsol_els(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 3109fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 3110fcf3ce44SJohn Forte { 3111fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 3112fcf3ce44SJohn Forte IOCB *iocb; 3113fcf3ce44SJohn Forte uint32_t cmd_code; 3114fcf3ce44SJohn Forte fct_cmd_t *fct_cmd; 3115fcf3ce44SJohn Forte fct_els_t *els; 3116fcf3ce44SJohn Forte uint32_t sid; 3117fcf3ce44SJohn Forte uint32_t padding; 3118fcf3ce44SJohn Forte uint8_t *bp; 3119fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 3120fcf3ce44SJohn Forte uint32_t rval; 3121fcf3ce44SJohn Forte 3122fcf3ce44SJohn Forte HBASTATS.ElsCmdReceived++; 3123fcf3ce44SJohn Forte 3124fcf3ce44SJohn Forte bp = mp->virt; 3125fcf3ce44SJohn Forte cmd_code = (*(uint32_t *)bp) & ELS_CMD_MASK; 3126fcf3ce44SJohn Forte iocb = &iocbq->iocb; 3127fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID; 3128fcf3ce44SJohn Forte 3129fcf3ce44SJohn Forte if (!port->fct_port) { 3130fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 3131fcf3ce44SJohn Forte "%s: sid=%x. Target unbound. Rejecting...", 3132fcf3ce44SJohn Forte emlxs_elscmd_xlate(cmd_code), sid); 3133fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code, 3134fcf3ce44SJohn Forte LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 3135fcf3ce44SJohn Forte 3136fcf3ce44SJohn Forte goto done; 3137fcf3ce44SJohn Forte } 3138291a2b48SSukumar Swaminathan 3139fcf3ce44SJohn Forte if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) { 3140fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 3141fcf3ce44SJohn Forte "%s: sid=%x. Target offline. Rejecting...", 3142fcf3ce44SJohn Forte emlxs_elscmd_xlate(cmd_code), sid); 3143fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code, 3144fcf3ce44SJohn Forte LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE); 3145fcf3ce44SJohn Forte 3146fcf3ce44SJohn Forte goto done; 3147fcf3ce44SJohn Forte } 3148291a2b48SSukumar Swaminathan 3149fcf3ce44SJohn Forte /* Process the request */ 3150fcf3ce44SJohn Forte switch (cmd_code) { 3151fcf3ce44SJohn Forte case ELS_CMD_FLOGI: 3152e2ca2865SSukumar Swaminathan rval = emlxs_fct_process_unsol_flogi(port, cp, iocbq, mp, size); 3153291a2b48SSukumar Swaminathan 3154291a2b48SSukumar Swaminathan if (!rval) { 3155291a2b48SSukumar Swaminathan ELS_PKT *els_pkt = (ELS_PKT *)bp; 3156e2ca2865SSukumar Swaminathan fct_flogi_xchg_t fx; 3157e2ca2865SSukumar Swaminathan 3158e2ca2865SSukumar Swaminathan bzero((uint8_t *)&fx, sizeof (fct_flogi_xchg_t)); 3159291a2b48SSukumar Swaminathan 3160291a2b48SSukumar Swaminathan /* Save the FLOGI exchange information */ 3161e2ca2865SSukumar Swaminathan fx.rsvd2 = iocb->ULPCONTEXT; 3162291a2b48SSukumar Swaminathan bcopy((caddr_t)&els_pkt->un.logi.nodeName, 3163e2ca2865SSukumar Swaminathan (caddr_t)fx.fx_nwwn, 8); 3164291a2b48SSukumar Swaminathan bcopy((caddr_t)&els_pkt->un.logi.portName, 3165e2ca2865SSukumar Swaminathan (caddr_t)fx.fx_pwwn, 8); 3166e2ca2865SSukumar Swaminathan fx.fx_sid = sid; 3167e2ca2865SSukumar Swaminathan fx.fx_did = iocb->un.elsreq.myID; 3168e2ca2865SSukumar Swaminathan fx.fx_fport = els_pkt->un.logi.cmn.fPort; 3169e2ca2865SSukumar Swaminathan fx.fx_op = ELS_OP_FLOGI; 3170e2ca2865SSukumar Swaminathan 3171e2ca2865SSukumar Swaminathan emlxs_fct_handle_unsol_flogi(port, &fx, 1); 3172291a2b48SSukumar Swaminathan } 3173e2ca2865SSukumar Swaminathan 3174291a2b48SSukumar Swaminathan goto done; 3175fcf3ce44SJohn Forte 3176fcf3ce44SJohn Forte case ELS_CMD_PLOGI: 3177291a2b48SSukumar Swaminathan rval = 317882527734SSukumar Swaminathan emlxs_fct_process_unsol_plogi(port, cp, iocbq, mp, size); 3179fcf3ce44SJohn Forte break; 3180fcf3ce44SJohn Forte 3181fcf3ce44SJohn Forte default: 3182fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 3183fcf3ce44SJohn Forte "%s: sid=0x%x", emlxs_elscmd_xlate(cmd_code), sid); 3184fcf3ce44SJohn Forte rval = 0; 3185fcf3ce44SJohn Forte break; 3186fcf3ce44SJohn Forte } 3187fcf3ce44SJohn Forte 3188fcf3ce44SJohn Forte if (rval) { 3189fcf3ce44SJohn Forte goto done; 3190fcf3ce44SJohn Forte } 3191291a2b48SSukumar Swaminathan 3192fcf3ce44SJohn Forte padding = (8 - (size & 7)) & 7; 3193fcf3ce44SJohn Forte 3194fcf3ce44SJohn Forte fct_cmd = (fct_cmd_t *)MODSYM(fct_alloc) (FCT_STRUCT_CMD_RCVD_ELS, 3195291a2b48SSukumar Swaminathan (size + padding + GET_STRUCT_SIZE(emlxs_buf_t)), 3196291a2b48SSukumar Swaminathan AF_FORCE_NOSLEEP); 3197fcf3ce44SJohn Forte 3198fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 3199fcf3ce44SJohn Forte { 3200fcf3ce44SJohn Forte uint32_t *ptr = (uint32_t *)bp; 3201fcf3ce44SJohn Forte 3202fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3203fcf3ce44SJohn Forte "fct_alloc %p: ELS rcvd: rxid=%x payload: x%x x%x", 320482527734SSukumar Swaminathan fct_cmd, iocb->ULPCONTEXT, *ptr, *(ptr + 1)); 3205fcf3ce44SJohn Forte } 3206291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 3207fcf3ce44SJohn Forte 3208fcf3ce44SJohn Forte if (fct_cmd == NULL) { 3209fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 3210fcf3ce44SJohn Forte "%s: sid=%x. Out of memory. Rejecting...", 3211fcf3ce44SJohn Forte emlxs_elscmd_xlate(cmd_code), sid); 3212fcf3ce44SJohn Forte 3213fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code, 3214fcf3ce44SJohn Forte LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE); 3215fcf3ce44SJohn Forte goto done; 3216fcf3ce44SJohn Forte } 3217291a2b48SSukumar Swaminathan 3218fcf3ce44SJohn Forte /* Initialize fct_cmd */ 3219fcf3ce44SJohn Forte fct_cmd->cmd_oxid = (cmd_code >> ELS_CMD_SHIFT) & 0xff; 322082527734SSukumar Swaminathan fct_cmd->cmd_rxid = iocb->ULPCONTEXT; 3221fcf3ce44SJohn Forte fct_cmd->cmd_rportid = sid; 3222fcf3ce44SJohn Forte fct_cmd->cmd_lportid = port->did; 322382527734SSukumar Swaminathan fct_cmd->cmd_rp_handle = iocb->ULPIOTAG; /* RPI */ 3224fcf3ce44SJohn Forte fct_cmd->cmd_port = port->fct_port; 3225fcf3ce44SJohn Forte 322682527734SSukumar Swaminathan cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd, EMLXS_FCT_ELS_CMD_RECEIVED); 322782527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 3228fcf3ce44SJohn Forte 3229291a2b48SSukumar Swaminathan /* Initialize cmd_sbp */ 323082527734SSukumar Swaminathan cmd_sbp->channel = cp; 323182527734SSukumar Swaminathan cmd_sbp->class = iocb->ULPCLASS; 3232fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_ELS_CMD; 3233291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_PLOGI_RECEIVED; 3234291a2b48SSukumar Swaminathan 3235fcf3ce44SJohn Forte bcopy((uint8_t *)iocb, (uint8_t *)&cmd_sbp->iocbq, 3236fcf3ce44SJohn Forte sizeof (emlxs_iocb_t)); 3237fcf3ce44SJohn Forte 3238fcf3ce44SJohn Forte els = (fct_els_t *)fct_cmd->cmd_specific; 3239fcf3ce44SJohn Forte els->els_req_size = size; 3240291a2b48SSukumar Swaminathan els->els_req_payload = 3241291a2b48SSukumar Swaminathan GET_BYTE_OFFSET(fct_cmd->cmd_fca_private, 3242fcf3ce44SJohn Forte GET_STRUCT_SIZE(emlxs_buf_t)); 3243fcf3ce44SJohn Forte bcopy(bp, els->els_req_payload, size); 3244fcf3ce44SJohn Forte 3245e2ca2865SSukumar Swaminathan 3246e2ca2865SSukumar Swaminathan /* Check if Offline */ 3247e2ca2865SSukumar Swaminathan if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) { 3248e2ca2865SSukumar Swaminathan 3249e2ca2865SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 3250e2ca2865SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3251e2ca2865SSukumar Swaminathan 3252e2ca2865SSukumar Swaminathan #ifdef FCT_API_TRACE 3253e2ca2865SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3254e2ca2865SSukumar Swaminathan "fct_post_rcvd_cmd:4 %p: portid x%x", fct_cmd, 3255e2ca2865SSukumar Swaminathan fct_cmd->cmd_lportid); 3256e2ca2865SSukumar Swaminathan #endif /* FCT_API_TRACE */ 3257e2ca2865SSukumar Swaminathan 3258e2ca2865SSukumar Swaminathan MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0); 3259e2ca2865SSukumar Swaminathan 3260e2ca2865SSukumar Swaminathan goto done; 3261e2ca2865SSukumar Swaminathan } 3262e2ca2865SSukumar Swaminathan 3263e2ca2865SSukumar Swaminathan /* Online */ 3264e2ca2865SSukumar Swaminathan /* Check if Link up is acked */ 3265e2ca2865SSukumar Swaminathan if (port->fct_flags & FCT_STATE_LINK_UP_ACKED) { 3266e2ca2865SSukumar Swaminathan 3267e2ca2865SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 3268e2ca2865SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3269e2ca2865SSukumar Swaminathan 3270e2ca2865SSukumar Swaminathan #ifdef FCT_API_TRACE 3271e2ca2865SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3272e2ca2865SSukumar Swaminathan "fct_post_rcvd_cmd:1 %p: portid x%x", fct_cmd, 3273e2ca2865SSukumar Swaminathan fct_cmd->cmd_lportid); 3274e2ca2865SSukumar Swaminathan #endif /* FCT_API_TRACE */ 3275e2ca2865SSukumar Swaminathan 3276e2ca2865SSukumar Swaminathan MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0); 3277e2ca2865SSukumar Swaminathan 3278e2ca2865SSukumar Swaminathan goto done; 3279e2ca2865SSukumar Swaminathan 3280e2ca2865SSukumar Swaminathan } 3281e2ca2865SSukumar Swaminathan 3282e2ca2865SSukumar Swaminathan /* Defer processing of fct_cmd till later (after link up ack). */ 3283e2ca2865SSukumar Swaminathan 3284e2ca2865SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, EMLXS_FCT_CMD_WAITQ); 3285e2ca2865SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3286e2ca2865SSukumar Swaminathan 3287e2ca2865SSukumar Swaminathan /* Add cmd_sbp to queue tail */ 3288e2ca2865SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 3289e2ca2865SSukumar Swaminathan 3290e2ca2865SSukumar Swaminathan if (port->fct_wait_tail) { 3291e2ca2865SSukumar Swaminathan port->fct_wait_tail->next = cmd_sbp; 3292e2ca2865SSukumar Swaminathan } 3293e2ca2865SSukumar Swaminathan port->fct_wait_tail = cmd_sbp; 3294e2ca2865SSukumar Swaminathan 3295e2ca2865SSukumar Swaminathan if (!port->fct_wait_head) { 3296e2ca2865SSukumar Swaminathan port->fct_wait_head = cmd_sbp; 3297e2ca2865SSukumar Swaminathan } 3298e2ca2865SSukumar Swaminathan 3299e2ca2865SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 3300fcf3ce44SJohn Forte 3301fcf3ce44SJohn Forte done: 3302fcf3ce44SJohn Forte 3303fcf3ce44SJohn Forte return (0); 3304fcf3ce44SJohn Forte 330582527734SSukumar Swaminathan } /* emlxs_fct_handle_unsol_els() */ 3306fcf3ce44SJohn Forte 3307fcf3ce44SJohn Forte 3308fcf3ce44SJohn Forte /* ARGSUSED */ 3309fcf3ce44SJohn Forte static uint32_t 331082527734SSukumar Swaminathan emlxs_fct_process_unsol_flogi(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 3311fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 3312fcf3ce44SJohn Forte { 3313fcf3ce44SJohn Forte IOCB *iocb; 3314fcf3ce44SJohn Forte char buffer[64]; 3315fcf3ce44SJohn Forte 3316fcf3ce44SJohn Forte buffer[0] = 0; 3317fcf3ce44SJohn Forte 3318fcf3ce44SJohn Forte iocb = &iocbq->iocb; 3319fcf3ce44SJohn Forte 3320fcf3ce44SJohn Forte /* Perform processing of FLOGI payload */ 3321fcf3ce44SJohn Forte if (emlxs_process_unsol_flogi(port, iocbq, mp, size, buffer)) { 3322fcf3ce44SJohn Forte return (1); 3323fcf3ce44SJohn Forte } 3324291a2b48SSukumar Swaminathan 3325fe199829SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 3326fe199829SSukumar Swaminathan "FLOGI: sid=0x%x xid=%x %s", 3327fe199829SSukumar Swaminathan iocb->un.elsreq.remoteID, iocb->ULPIOTAG, buffer); 3328fcf3ce44SJohn Forte 3329fcf3ce44SJohn Forte return (0); 3330fcf3ce44SJohn Forte 333182527734SSukumar Swaminathan } /* emlxs_fct_process_unsol_flogi() */ 3332fcf3ce44SJohn Forte 3333fcf3ce44SJohn Forte 3334fcf3ce44SJohn Forte /* ARGSUSED */ 3335fcf3ce44SJohn Forte static uint32_t 333682527734SSukumar Swaminathan emlxs_fct_process_unsol_plogi(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq, 3337fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size) 3338fcf3ce44SJohn Forte { 3339fcf3ce44SJohn Forte IOCB *iocb; 3340fcf3ce44SJohn Forte char buffer[64]; 3341fcf3ce44SJohn Forte 3342fcf3ce44SJohn Forte buffer[0] = 0; 3343fcf3ce44SJohn Forte 3344fcf3ce44SJohn Forte iocb = &iocbq->iocb; 3345fcf3ce44SJohn Forte 3346fcf3ce44SJohn Forte /* Perform processing of PLOGI payload */ 3347fcf3ce44SJohn Forte if (emlxs_process_unsol_plogi(port, iocbq, mp, size, buffer)) { 3348fcf3ce44SJohn Forte return (1); 3349fcf3ce44SJohn Forte } 3350291a2b48SSukumar Swaminathan 3351fe199829SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 3352fe199829SSukumar Swaminathan "PLOGI: sid=0x%x xid=%x %s", 3353fe199829SSukumar Swaminathan iocb->un.elsreq.remoteID, iocb->ULPIOTAG, buffer); 3354fcf3ce44SJohn Forte 3355fcf3ce44SJohn Forte return (0); 3356fcf3ce44SJohn Forte 335782527734SSukumar Swaminathan } /* emlxs_fct_process_unsol_plogi() */ 3358fcf3ce44SJohn Forte 3359fcf3ce44SJohn Forte 3360fcf3ce44SJohn Forte /* ARGSUSED */ 3361fcf3ce44SJohn Forte static emlxs_buf_t * 3362291a2b48SSukumar Swaminathan emlxs_fct_pkt_init(emlxs_port_t *port, fct_cmd_t *fct_cmd, 3363291a2b48SSukumar Swaminathan fc_packet_t *pkt) 3364fcf3ce44SJohn Forte { 3365fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 3366fcf3ce44SJohn Forte emlxs_buf_t *sbp; 3367fcf3ce44SJohn Forte 3368fcf3ce44SJohn Forte cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 3369fcf3ce44SJohn Forte 3370fcf3ce44SJohn Forte sbp = PKT2PRIV(pkt); 3371fcf3ce44SJohn Forte sbp->fct_cmd = cmd_sbp->fct_cmd; 3372fcf3ce44SJohn Forte sbp->node = cmd_sbp->node; 337382527734SSukumar Swaminathan sbp->channel = cmd_sbp->channel; 3374fcf3ce44SJohn Forte sbp->did = cmd_sbp->did; 3375fcf3ce44SJohn Forte sbp->lun = cmd_sbp->lun; 3376fcf3ce44SJohn Forte sbp->class = cmd_sbp->class; 3377fcf3ce44SJohn Forte sbp->fct_type = cmd_sbp->fct_type; 3378fcf3ce44SJohn Forte sbp->fct_state = cmd_sbp->fct_state; 3379fcf3ce44SJohn Forte 3380fcf3ce44SJohn Forte return (sbp); 3381fcf3ce44SJohn Forte 338282527734SSukumar Swaminathan } /* emlxs_fct_pkt_init() */ 3383fcf3ce44SJohn Forte 3384fcf3ce44SJohn Forte 3385fcf3ce44SJohn Forte /* Mutex will be acquired */ 3386fcf3ce44SJohn Forte static emlxs_buf_t * 338782527734SSukumar Swaminathan emlxs_fct_cmd_init(emlxs_port_t *port, fct_cmd_t *fct_cmd, uint32_t fct_state) 3388fcf3ce44SJohn Forte { 3389fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 3390fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 3391fcf3ce44SJohn Forte 3392fcf3ce44SJohn Forte bzero((void *)cmd_sbp, sizeof (emlxs_buf_t)); 3393291a2b48SSukumar Swaminathan mutex_init(&cmd_sbp->fct_mtx, NULL, MUTEX_DRIVER, 3394291a2b48SSukumar Swaminathan (void *)hba->intr_arg); 3395fcf3ce44SJohn Forte mutex_init(&cmd_sbp->mtx, NULL, MUTEX_DRIVER, (void *)hba->intr_arg); 3396fcf3ce44SJohn Forte 3397291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->fct_mtx); 3398fcf3ce44SJohn Forte cmd_sbp->pkt_flags = PACKET_VALID; 3399fcf3ce44SJohn Forte cmd_sbp->port = port; 3400fcf3ce44SJohn Forte cmd_sbp->fct_cmd = fct_cmd; 3401fcf3ce44SJohn Forte cmd_sbp->node = (fct_cmd->cmd_rp) ? 3402fcf3ce44SJohn Forte *(emlxs_node_t **)fct_cmd->cmd_rp->rp_fca_private : NULL; 3403fcf3ce44SJohn Forte cmd_sbp->iocbq.sbp = cmd_sbp; 3404291a2b48SSukumar Swaminathan cmd_sbp->iocbq.port = port; 340582527734SSukumar Swaminathan cmd_sbp->did = fct_cmd->cmd_rportid; 340682527734SSukumar Swaminathan 340782527734SSukumar Swaminathan /* Flags fct_cmd as inuse */ 340882527734SSukumar Swaminathan if ((fct_cmd->cmd_oxid == 0) && (fct_cmd->cmd_rxid == 0)) { 340982527734SSukumar Swaminathan fct_cmd->cmd_oxid = 0xffff; 341082527734SSukumar Swaminathan fct_cmd->cmd_rxid = 0xffff; 341182527734SSukumar Swaminathan } 341282527734SSukumar Swaminathan 341382527734SSukumar Swaminathan if (fct_state) { 341482527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, fct_state); 341582527734SSukumar Swaminathan } 3416fcf3ce44SJohn Forte 3417fcf3ce44SJohn Forte return (cmd_sbp); 3418fcf3ce44SJohn Forte 341982527734SSukumar Swaminathan } /* emlxs_fct_cmd_init() */ 3420fcf3ce44SJohn Forte 3421fcf3ce44SJohn Forte 342282527734SSukumar Swaminathan /* Called after receiving fct_cmd from COMSTAR */ 342382527734SSukumar Swaminathan static fct_status_t 342482527734SSukumar Swaminathan emlxs_fct_cmd_accept(emlxs_port_t *port, fct_cmd_t *fct_cmd, uint16_t fct_state) 3425fcf3ce44SJohn Forte { 3426fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 3427fcf3ce44SJohn Forte 342882527734SSukumar Swaminathan if (!(cmd_sbp->pkt_flags & PACKET_VALID)) { 342982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 343082527734SSukumar Swaminathan "emlxs_fct_cmd_accept: " 343182527734SSukumar Swaminathan "Invalid fct_cmd found! fct_cmd=%p state=%x", 343282527734SSukumar Swaminathan fct_cmd, fct_state); 343382527734SSukumar Swaminathan 343482527734SSukumar Swaminathan return (FCT_NOT_FOUND); 343582527734SSukumar Swaminathan } 343682527734SSukumar Swaminathan 343782527734SSukumar Swaminathan mutex_enter(&cmd_sbp->fct_mtx); 343882527734SSukumar Swaminathan 343982527734SSukumar Swaminathan if (!(cmd_sbp->pkt_flags & PACKET_VALID)) { 344082527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 344182527734SSukumar Swaminathan 344282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 344382527734SSukumar Swaminathan "emlxs_fct_cmd_accept:2 " 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 if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT_INP) { 345182527734SSukumar Swaminathan 345282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 345382527734SSukumar Swaminathan "emlxs_fct_cmd_accept: " 345482527734SSukumar Swaminathan "Aborted fct_cmd found! fct_cmd=%p state=%x", 345582527734SSukumar Swaminathan fct_cmd, fct_state); 345682527734SSukumar Swaminathan 345782527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_ABORT_DONE); 345882527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 345982527734SSukumar Swaminathan 346082527734SSukumar Swaminathan MODSYM(fct_cmd_fca_aborted) (fct_cmd, 346182527734SSukumar Swaminathan FCT_ABORT_SUCCESS, FCT_IOF_FCA_DONE); 346282527734SSukumar Swaminathan 346382527734SSukumar Swaminathan return (FCT_NOT_FOUND); 346482527734SSukumar Swaminathan } 346582527734SSukumar Swaminathan 346682527734SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx); 346782527734SSukumar Swaminathan if (!(cmd_sbp->pkt_flags & PACKET_ULP_OWNED)) { 346882527734SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx); 346982527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 347082527734SSukumar Swaminathan 347182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 347282527734SSukumar Swaminathan "emlxs_fct_cmd_accept: " 347382527734SSukumar Swaminathan "Busy fct_cmd found! fct_cmd=%p state=%x", 347482527734SSukumar Swaminathan fct_cmd, fct_state); 347582527734SSukumar Swaminathan 347682527734SSukumar Swaminathan return (FCT_BUSY); 347782527734SSukumar Swaminathan } 347882527734SSukumar Swaminathan cmd_sbp->pkt_flags &= ~PACKET_ULP_OWNED; 347982527734SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx); 348082527734SSukumar Swaminathan 348182527734SSukumar Swaminathan if (fct_state) { 348282527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, fct_state); 348382527734SSukumar Swaminathan } 348482527734SSukumar Swaminathan 348582527734SSukumar Swaminathan return (FCT_SUCCESS); 348682527734SSukumar Swaminathan 348782527734SSukumar Swaminathan } /* emlxs_fct_cmd_accept() */ 348882527734SSukumar Swaminathan 348982527734SSukumar Swaminathan 349082527734SSukumar Swaminathan /* Called after receiving fct_cmd from driver */ 349182527734SSukumar Swaminathan static fct_status_t 349282527734SSukumar Swaminathan emlxs_fct_cmd_acquire(emlxs_port_t *port, fct_cmd_t *fct_cmd, 349382527734SSukumar Swaminathan uint16_t fct_state) 349482527734SSukumar Swaminathan { 349582527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 349682527734SSukumar Swaminathan 349782527734SSukumar Swaminathan if ((fct_cmd->cmd_oxid == 0) && (fct_cmd->cmd_rxid == 0)) { 349882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 349982527734SSukumar Swaminathan "emlxs_fct_cmd_acquire: " 350082527734SSukumar Swaminathan "Bad fct_cmd found! fct_cmd=%p state=%x", 350182527734SSukumar Swaminathan fct_cmd, fct_state); 350282527734SSukumar Swaminathan 350382527734SSukumar Swaminathan return (FCT_NOT_FOUND); 350482527734SSukumar Swaminathan } 350582527734SSukumar Swaminathan 350682527734SSukumar Swaminathan if (!(cmd_sbp->pkt_flags & PACKET_VALID)) { 350782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 350882527734SSukumar Swaminathan "emlxs_fct_cmd_acquire: " 350982527734SSukumar Swaminathan "Invalid fct_cmd found! fct_cmd=%p state=%x", 351082527734SSukumar Swaminathan fct_cmd, fct_state); 351182527734SSukumar Swaminathan 351282527734SSukumar Swaminathan return (FCT_NOT_FOUND); 351382527734SSukumar Swaminathan } 351482527734SSukumar Swaminathan 351582527734SSukumar Swaminathan if ((cmd_sbp->pkt_flags & PACKET_ULP_OWNED)) { 351682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 351782527734SSukumar Swaminathan "emlxs_fct_cmd_acquire: " 351882527734SSukumar Swaminathan "Returned fct_cmd found! fct_cmd=%p state=%x", 351982527734SSukumar Swaminathan fct_cmd, fct_state); 352082527734SSukumar Swaminathan 352182527734SSukumar Swaminathan return (FCT_NOT_FOUND); 352282527734SSukumar Swaminathan } 352382527734SSukumar Swaminathan 352482527734SSukumar Swaminathan mutex_enter(&cmd_sbp->fct_mtx); 352582527734SSukumar Swaminathan 352682527734SSukumar Swaminathan if ((fct_cmd->cmd_oxid == 0) && (fct_cmd->cmd_rxid == 0)) { 352782527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 352882527734SSukumar Swaminathan 352982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 353082527734SSukumar Swaminathan "emlxs_fct_cmd_acquire:2 " 353182527734SSukumar Swaminathan "Bad fct_cmd found! fct_cmd=%p state=%x", 353282527734SSukumar Swaminathan fct_cmd, fct_state); 3533291a2b48SSukumar Swaminathan 353482527734SSukumar Swaminathan return (FCT_NOT_FOUND); 353582527734SSukumar Swaminathan } 3536291a2b48SSukumar Swaminathan 3537fcf3ce44SJohn Forte if (!(cmd_sbp->pkt_flags & PACKET_VALID)) { 353882527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 353982527734SSukumar Swaminathan 354082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 354182527734SSukumar Swaminathan "emlxs_fct_cmd_acquire:2 " 354282527734SSukumar Swaminathan "Invalid fct_cmd found! fct_cmd=%p state=%x", 354382527734SSukumar Swaminathan fct_cmd, fct_state); 354482527734SSukumar Swaminathan 354582527734SSukumar Swaminathan return (FCT_NOT_FOUND); 354682527734SSukumar Swaminathan } 354782527734SSukumar Swaminathan 354882527734SSukumar Swaminathan if ((cmd_sbp->pkt_flags & PACKET_ULP_OWNED)) { 354982527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 355082527734SSukumar Swaminathan 355182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 355282527734SSukumar Swaminathan "emlxs_fct_cmd_acquire:2 " 355382527734SSukumar Swaminathan "Returned fct_cmd found! fct_cmd=%p state=%x", 355482527734SSukumar Swaminathan fct_cmd, fct_state); 355582527734SSukumar Swaminathan 355682527734SSukumar Swaminathan return (FCT_NOT_FOUND); 355782527734SSukumar Swaminathan } 355882527734SSukumar Swaminathan 355982527734SSukumar Swaminathan if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT_INP) { 356082527734SSukumar Swaminathan 356182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 356282527734SSukumar Swaminathan "emlxs_fct_cmd_acquire: " 356382527734SSukumar Swaminathan "Aborting cmd. fct_cmd=%p state=%x", 356482527734SSukumar Swaminathan fct_cmd, fct_state); 356582527734SSukumar Swaminathan 356682527734SSukumar Swaminathan if (fct_cmd->cmd_type == FCT_CMD_FCP_XCHG) { 356782527734SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--; 356882527734SSukumar Swaminathan } 356982527734SSukumar Swaminathan 357082527734SSukumar Swaminathan fct_cmd->cmd_comp_status = FCT_FAILURE; 357182527734SSukumar Swaminathan 357282527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_ABORT_DONE); 357382527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 357482527734SSukumar Swaminathan 357582527734SSukumar Swaminathan MODSYM(fct_cmd_fca_aborted) (fct_cmd, 357682527734SSukumar Swaminathan FCT_ABORT_SUCCESS, FCT_IOF_FCA_DONE); 357782527734SSukumar Swaminathan 357882527734SSukumar Swaminathan return (FCT_NOT_FOUND); 357982527734SSukumar Swaminathan } 358082527734SSukumar Swaminathan 358182527734SSukumar Swaminathan if (fct_state) { 358282527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, fct_state); 358382527734SSukumar Swaminathan } 358482527734SSukumar Swaminathan 358582527734SSukumar Swaminathan return (FCT_SUCCESS); 358682527734SSukumar Swaminathan 358782527734SSukumar Swaminathan } /* emlxs_fct_cmd_acquire() */ 358882527734SSukumar Swaminathan 358982527734SSukumar Swaminathan 359082527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be held to enter */ 359182527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be released before exiting */ 359282527734SSukumar Swaminathan /* Called before transitionally sending fct_cmd to driver */ 359382527734SSukumar Swaminathan /*ARGSUSED*/ 359482527734SSukumar Swaminathan static void 359582527734SSukumar Swaminathan emlxs_fct_cmd_release(emlxs_port_t *port, fct_cmd_t *fct_cmd, 359682527734SSukumar Swaminathan uint16_t fct_state) 359782527734SSukumar Swaminathan { 359882527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 359982527734SSukumar Swaminathan 360082527734SSukumar Swaminathan if (fct_state) { 360182527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, fct_state); 3602fcf3ce44SJohn Forte } 3603291a2b48SSukumar Swaminathan 360482527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 360582527734SSukumar Swaminathan 360682527734SSukumar Swaminathan return; 360782527734SSukumar Swaminathan 360882527734SSukumar Swaminathan } /* emlxs_fct_cmd_release() */ 360982527734SSukumar Swaminathan 361082527734SSukumar Swaminathan 361182527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be held to enter */ 361282527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be released before exiting */ 361382527734SSukumar Swaminathan /* Called before posting fct_cmd back to COMSTAR */ 361482527734SSukumar Swaminathan /*ARGSUSED*/ 361582527734SSukumar Swaminathan static void 361682527734SSukumar Swaminathan emlxs_fct_cmd_post(emlxs_port_t *port, fct_cmd_t *fct_cmd, 361782527734SSukumar Swaminathan uint16_t fct_state) 361882527734SSukumar Swaminathan { 361982527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 362082527734SSukumar Swaminathan fc_packet_t *pkt; 362182527734SSukumar Swaminathan 362282527734SSukumar Swaminathan pkt = cmd_sbp->fct_pkt; 362382527734SSukumar Swaminathan cmd_sbp->fct_pkt = NULL; 362482527734SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP; 362582527734SSukumar Swaminathan 362682527734SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx); 362782527734SSukumar Swaminathan cmd_sbp->pkt_flags |= PACKET_ULP_OWNED; 362882527734SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx); 362982527734SSukumar Swaminathan 363082527734SSukumar Swaminathan if (fct_state) { 363182527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, fct_state); 363282527734SSukumar Swaminathan } 363382527734SSukumar Swaminathan 363482527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 363582527734SSukumar Swaminathan 363682527734SSukumar Swaminathan if (pkt) { 363782527734SSukumar Swaminathan emlxs_pkt_free(pkt); 363882527734SSukumar Swaminathan } 363982527734SSukumar Swaminathan 364082527734SSukumar Swaminathan return; 364182527734SSukumar Swaminathan 364282527734SSukumar Swaminathan } /* emlxs_fct_cmd_post() */ 364382527734SSukumar Swaminathan 364482527734SSukumar Swaminathan 364582527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be held to enter */ 364682527734SSukumar Swaminathan /* Called before completing fct_cmd back to COMSTAR */ 364782527734SSukumar Swaminathan static void 364882527734SSukumar Swaminathan emlxs_fct_cmd_done(emlxs_port_t *port, fct_cmd_t *fct_cmd, uint16_t fct_state) 364982527734SSukumar Swaminathan { 365082527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 365182527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 365282527734SSukumar Swaminathan fc_packet_t *pkt; 365382527734SSukumar Swaminathan 365482527734SSukumar Swaminathan /* Flags fct_cmd is no longer used */ 365582527734SSukumar Swaminathan fct_cmd->cmd_oxid = 0; 365682527734SSukumar Swaminathan fct_cmd->cmd_rxid = 0; 365782527734SSukumar Swaminathan 3658fcf3ce44SJohn Forte if (cmd_sbp->iotag != 0) { 3659fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 366082527734SSukumar Swaminathan "Pkt still registered! channel=%d iotag=%d sbp=%p", 366182527734SSukumar Swaminathan cmd_sbp->channel, cmd_sbp->iotag, cmd_sbp); 366282527734SSukumar Swaminathan 366382527734SSukumar Swaminathan if (cmd_sbp->channel) { 366482527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 366582527734SSukumar Swaminathan hba->fc_table[cmd_sbp->iotag] = NULL; 366682527734SSukumar Swaminathan emlxs_sli4_free_xri(hba, cmd_sbp, cmd_sbp->xp); 366782527734SSukumar Swaminathan } else { 366882527734SSukumar Swaminathan (void) emlxs_unregister_pkt(cmd_sbp->channel, 366982527734SSukumar Swaminathan cmd_sbp->iotag, 0); 367082527734SSukumar Swaminathan } 3671fcf3ce44SJohn Forte 3672fcf3ce44SJohn Forte } 3673fcf3ce44SJohn Forte } 3674291a2b48SSukumar Swaminathan 367582527734SSukumar Swaminathan pkt = cmd_sbp->fct_pkt; 367682527734SSukumar Swaminathan cmd_sbp->fct_pkt = NULL; 367782527734SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP; 367882527734SSukumar Swaminathan 367982527734SSukumar Swaminathan if (fct_state) { 368082527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, fct_state); 368182527734SSukumar Swaminathan } 3682fcf3ce44SJohn Forte 368382527734SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx); 368482527734SSukumar Swaminathan cmd_sbp->pkt_flags |= PACKET_ULP_OWNED; 368582527734SSukumar Swaminathan cmd_sbp->pkt_flags &= ~PACKET_VALID; 368682527734SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx); 3687291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 368882527734SSukumar Swaminathan 368982527734SSukumar Swaminathan 3690291a2b48SSukumar Swaminathan mutex_destroy(&cmd_sbp->fct_mtx); 369182527734SSukumar Swaminathan mutex_destroy(&cmd_sbp->mtx); 369282527734SSukumar Swaminathan 369382527734SSukumar Swaminathan if (pkt) { 369482527734SSukumar Swaminathan emlxs_pkt_free(pkt); 369582527734SSukumar Swaminathan } 3696fcf3ce44SJohn Forte 369782527734SSukumar Swaminathan return; 3698fcf3ce44SJohn Forte 369982527734SSukumar Swaminathan } /* emlxs_fct_cmd_done() */ 3700fcf3ce44SJohn Forte 3701fcf3ce44SJohn Forte 3702fcf3ce44SJohn Forte static void 3703fcf3ce44SJohn Forte emlxs_fct_pkt_comp(fc_packet_t *pkt) 3704fcf3ce44SJohn Forte { 3705fcf3ce44SJohn Forte emlxs_port_t *port; 3706291a2b48SSukumar Swaminathan #ifdef FMA_SUPPORT 3707291a2b48SSukumar Swaminathan emlxs_hba_t *hba; 3708291a2b48SSukumar Swaminathan #endif /* FMA_SUPPORT */ 3709fcf3ce44SJohn Forte emlxs_buf_t *sbp; 3710fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 3711fcf3ce44SJohn Forte fct_cmd_t *fct_cmd; 3712fcf3ce44SJohn Forte fct_els_t *fct_els; 3713fcf3ce44SJohn Forte fct_sol_ct_t *fct_ct; 371482527734SSukumar Swaminathan fct_status_t rval; 3715fcf3ce44SJohn Forte 3716fcf3ce44SJohn Forte sbp = PKT2PRIV(pkt); 3717fcf3ce44SJohn Forte port = sbp->port; 3718291a2b48SSukumar Swaminathan #ifdef FMA_SUPPORT 3719291a2b48SSukumar Swaminathan hba = HBA; 3720291a2b48SSukumar Swaminathan #endif /* FMA_SUPPORT */ 3721fcf3ce44SJohn Forte fct_cmd = sbp->fct_cmd; 3722291a2b48SSukumar Swaminathan 372382527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, EMLXS_FCT_PKT_COMPLETE); 372482527734SSukumar Swaminathan if (rval) { 372582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 372682527734SSukumar Swaminathan "emlxs_fct_pkt_comp: " 372782527734SSukumar Swaminathan "Unable to reacquire fct_cmd."); 372882527734SSukumar Swaminathan return; 3729291a2b48SSukumar Swaminathan } 373082527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 3731fcf3ce44SJohn Forte 373282527734SSukumar Swaminathan cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 373382527734SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP; 3734fcf3ce44SJohn Forte cmd_sbp->fct_pkt = NULL; 3735fcf3ce44SJohn Forte 3736291a2b48SSukumar Swaminathan switch (fct_cmd->cmd_type) { 3737291a2b48SSukumar Swaminathan case FCT_CMD_FCP_XCHG: 3738291a2b48SSukumar Swaminathan if ((pkt->pkt_reason == FC_REASON_ABORTED) || 3739291a2b48SSukumar Swaminathan (pkt->pkt_reason == FC_REASON_XCHG_DROPPED) || 3740291a2b48SSukumar Swaminathan (pkt->pkt_reason == FC_REASON_OFFLINE)) { 3741291a2b48SSukumar Swaminathan /* 3742291a2b48SSukumar Swaminathan * The error indicates this IO should be terminated 3743291a2b48SSukumar Swaminathan * immediately. 3744291a2b48SSukumar Swaminathan */ 3745291a2b48SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_SEND_STATUS; 3746fcf3ce44SJohn Forte 374782527734SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED); 374882527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3749fcf3ce44SJohn Forte 3750291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE 3751291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3752291a2b48SSukumar Swaminathan "fct_queue_cmd_for_termination:2 %p: x%x", 3753291a2b48SSukumar Swaminathan fct_cmd, fct_cmd->cmd_comp_status); 3754291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 375582527734SSukumar Swaminathan 3756291a2b48SSukumar Swaminathan MODSYM(fct_queue_cmd_for_termination) (fct_cmd, 3757291a2b48SSukumar Swaminathan FCT_ABTS_RECEIVED); 375882527734SSukumar Swaminathan 375982527734SSukumar Swaminathan break; 3760291a2b48SSukumar Swaminathan } 3761fcf3ce44SJohn Forte 376282527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, 3763291a2b48SSukumar Swaminathan EMLXS_FCT_PKT_FCPRSP_COMPLETE); 3764291a2b48SSukumar Swaminathan 376582527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_IO_DONE); 3766291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3767fcf3ce44SJohn Forte 3768fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 3769fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3770fcf3ce44SJohn Forte "fct_send_response_done:2 %p: x%x", 3771fcf3ce44SJohn Forte fct_cmd, fct_cmd->cmd_comp_status); 3772fcf3ce44SJohn Forte #else 3773fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3774fcf3ce44SJohn Forte "emlxs_fct_pkt_comp: fct_send_response_done. dbuf=%p", 3775fcf3ce44SJohn Forte sbp->fct_buf); 3776291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 3777291a2b48SSukumar Swaminathan 3778291a2b48SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--; 3779fcf3ce44SJohn Forte 3780fcf3ce44SJohn Forte MODSYM(fct_send_response_done) (fct_cmd, 3781fcf3ce44SJohn Forte fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE); 3782fcf3ce44SJohn Forte 3783fcf3ce44SJohn Forte break; 3784fcf3ce44SJohn Forte 3785fcf3ce44SJohn Forte case FCT_CMD_RCVD_ELS: 3786fcf3ce44SJohn Forte 378782527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, 3788291a2b48SSukumar Swaminathan EMLXS_FCT_PKT_ELSRSP_COMPLETE); 3789291a2b48SSukumar Swaminathan 379082527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_IO_DONE); 3791291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3792fcf3ce44SJohn Forte 3793fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 3794fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3795fcf3ce44SJohn Forte "fct_send_response_done:3 %p: x%x", 3796fcf3ce44SJohn Forte fct_cmd, fct_cmd->cmd_comp_status); 3797291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 379882527734SSukumar Swaminathan 3799fcf3ce44SJohn Forte MODSYM(fct_send_response_done) (fct_cmd, 3800fcf3ce44SJohn Forte fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE); 3801fcf3ce44SJohn Forte 3802fcf3ce44SJohn Forte break; 3803fcf3ce44SJohn Forte 3804fcf3ce44SJohn Forte case FCT_CMD_SOL_ELS: 3805291a2b48SSukumar Swaminathan 380682527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, 3807291a2b48SSukumar Swaminathan EMLXS_FCT_PKT_ELSCMD_COMPLETE); 3808291a2b48SSukumar Swaminathan 3809fcf3ce44SJohn Forte fct_els = (fct_els_t *)fct_cmd->cmd_specific; 3810fcf3ce44SJohn Forte 3811fcf3ce44SJohn Forte if (fct_els->els_resp_payload) { 381282527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, 3813291a2b48SSukumar Swaminathan pkt->pkt_rsplen, DDI_DMA_SYNC_FORKERNEL); 3814fcf3ce44SJohn Forte 3815fcf3ce44SJohn Forte bcopy((uint8_t *)pkt->pkt_resp, 3816fcf3ce44SJohn Forte (uint8_t *)fct_els->els_resp_payload, 3817fcf3ce44SJohn Forte fct_els->els_resp_size); 3818fcf3ce44SJohn Forte } 3819291a2b48SSukumar Swaminathan 382082527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_IO_DONE); 3821291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3822fcf3ce44SJohn Forte 3823fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 3824fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3825fcf3ce44SJohn Forte "fct_send_cmd_done:1 %p: x%x", 3826fcf3ce44SJohn Forte fct_cmd, fct_cmd->cmd_comp_status); 3827291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 382882527734SSukumar Swaminathan 3829*b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 3830*b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, pkt->pkt_resp_dma) 3831*b3660a96SSukumar Swaminathan != DDI_FM_OK) { 3832*b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 3833*b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 3834*b3660a96SSukumar Swaminathan "emlxs_fct_pkt_comp: hdl=%p", 3835*b3660a96SSukumar Swaminathan pkt->pkt_resp_dma); 3836*b3660a96SSukumar Swaminathan MODSYM(fct_send_cmd_done) (fct_cmd, FCT_FAILURE, 3837*b3660a96SSukumar Swaminathan FCT_IOF_FCA_DONE); 3838*b3660a96SSukumar Swaminathan 3839*b3660a96SSukumar Swaminathan break; 3840*b3660a96SSukumar Swaminathan } 3841*b3660a96SSukumar Swaminathan #endif /* FMA_SUPPORT */ 3842*b3660a96SSukumar Swaminathan 3843291a2b48SSukumar Swaminathan MODSYM(fct_send_cmd_done) (fct_cmd, FCT_SUCCESS, 3844291a2b48SSukumar Swaminathan FCT_IOF_FCA_DONE); 3845fcf3ce44SJohn Forte 3846fcf3ce44SJohn Forte break; 3847fcf3ce44SJohn Forte 3848fcf3ce44SJohn Forte case FCT_CMD_SOL_CT: 3849291a2b48SSukumar Swaminathan 385082527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, 3851291a2b48SSukumar Swaminathan EMLXS_FCT_PKT_CTCMD_COMPLETE); 3852291a2b48SSukumar Swaminathan 3853fcf3ce44SJohn Forte fct_ct = (fct_sol_ct_t *)fct_cmd->cmd_specific; 3854fcf3ce44SJohn Forte 3855fcf3ce44SJohn Forte if (fct_ct->ct_resp_payload) { 385682527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, 3857291a2b48SSukumar Swaminathan pkt->pkt_rsplen, DDI_DMA_SYNC_FORKERNEL); 3858fcf3ce44SJohn Forte 3859fcf3ce44SJohn Forte bcopy((uint8_t *)pkt->pkt_resp, 3860fcf3ce44SJohn Forte (uint8_t *)fct_ct->ct_resp_payload, 3861fcf3ce44SJohn Forte fct_ct->ct_resp_size); 3862fcf3ce44SJohn Forte } 3863291a2b48SSukumar Swaminathan 386482527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_IO_DONE); 3865291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3866fcf3ce44SJohn Forte 3867fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 3868fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 3869fcf3ce44SJohn Forte "fct_send_cmd_done:2 %p: x%x", 3870fcf3ce44SJohn Forte fct_cmd, fct_cmd->cmd_comp_status); 3871291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 387282527734SSukumar Swaminathan 3873*b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 3874*b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, pkt->pkt_resp_dma) 3875*b3660a96SSukumar Swaminathan != DDI_FM_OK) { 3876*b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 3877*b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 3878*b3660a96SSukumar Swaminathan "emlxs_fct_pkt_comp: hdl=%p", 3879*b3660a96SSukumar Swaminathan pkt->pkt_resp_dma); 3880*b3660a96SSukumar Swaminathan MODSYM(fct_send_cmd_done) (fct_cmd, FCT_FAILURE, 3881*b3660a96SSukumar Swaminathan FCT_IOF_FCA_DONE); 3882*b3660a96SSukumar Swaminathan 3883*b3660a96SSukumar Swaminathan break; 3884*b3660a96SSukumar Swaminathan } 3885*b3660a96SSukumar Swaminathan #endif /* FMA_SUPPORT */ 3886291a2b48SSukumar Swaminathan MODSYM(fct_send_cmd_done) (fct_cmd, FCT_SUCCESS, 3887291a2b48SSukumar Swaminathan FCT_IOF_FCA_DONE); 388882527734SSukumar Swaminathan 3889fcf3ce44SJohn Forte break; 3890fcf3ce44SJohn Forte 3891fcf3ce44SJohn Forte default: 3892fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3893fcf3ce44SJohn Forte "emlxs_fct_pkt_comp: Invalid cmd type found. type=%x", 3894fcf3ce44SJohn Forte fct_cmd->cmd_type); 3895fcf3ce44SJohn Forte 389682527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_IO_DONE); 389782527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 389882527734SSukumar Swaminathan 389982527734SSukumar Swaminathan break; 3900fcf3ce44SJohn Forte } 3901fcf3ce44SJohn Forte 3902fcf3ce44SJohn Forte emlxs_pkt_free(pkt); 3903fcf3ce44SJohn Forte return; 3904fcf3ce44SJohn Forte 390582527734SSukumar Swaminathan } /* emlxs_fct_pkt_comp() */ 3906fcf3ce44SJohn Forte 3907fcf3ce44SJohn Forte 3908291a2b48SSukumar Swaminathan static void 3909291a2b48SSukumar Swaminathan emlxs_fct_abort_pkt_comp(fc_packet_t *pkt) 3910fcf3ce44SJohn Forte { 391182527734SSukumar Swaminathan #ifdef FCT_API_TRACE_11 3912291a2b48SSukumar Swaminathan emlxs_buf_t *sbp; 3913291a2b48SSukumar Swaminathan IOCBQ *iocbq; 3914291a2b48SSukumar Swaminathan IOCB *iocb; 3915291a2b48SSukumar Swaminathan 3916291a2b48SSukumar Swaminathan sbp = PKT2PRIV(pkt); 3917291a2b48SSukumar Swaminathan iocbq = &sbp->iocbq; 3918291a2b48SSukumar Swaminathan iocb = &iocbq->iocb; 3919291a2b48SSukumar Swaminathan 3920291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 392182527734SSukumar Swaminathan "emlxs_fct_handle_abort: %p: xri=%x status=%x", iocb->ULPCONTEXT, 392282527734SSukumar Swaminathan iocb->ULPCOMMAND, iocb->ULPSTATUS); 3923291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 3924291a2b48SSukumar Swaminathan 3925291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt); 3926291a2b48SSukumar Swaminathan return; 3927291a2b48SSukumar Swaminathan 392882527734SSukumar Swaminathan } /* emlxs_fct_abort_pkt_comp() */ 3929291a2b48SSukumar Swaminathan 3930291a2b48SSukumar Swaminathan 393182527734SSukumar Swaminathan /* COMSTAR ENTER POINT (INDIRECT) */ 3932291a2b48SSukumar Swaminathan static fct_status_t 3933291a2b48SSukumar Swaminathan emlxs_fct_send_els_cmd(fct_cmd_t *fct_cmd) 3934291a2b48SSukumar Swaminathan { 3935291a2b48SSukumar Swaminathan emlxs_port_t *port = 3936291a2b48SSukumar Swaminathan (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 3937fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 3938fcf3ce44SJohn Forte uint32_t did; 3939fcf3ce44SJohn Forte fct_els_t *fct_els; 3940fcf3ce44SJohn Forte fc_packet_t *pkt; 3941fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 394282527734SSukumar Swaminathan fct_status_t rval; 3943fcf3ce44SJohn Forte 3944fcf3ce44SJohn Forte did = fct_cmd->cmd_rportid; 3945fcf3ce44SJohn Forte fct_els = (fct_els_t *)fct_cmd->cmd_specific; 3946fcf3ce44SJohn Forte 3947fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, fct_els->els_req_size, 3948fcf3ce44SJohn Forte fct_els->els_resp_size, 0, KM_NOSLEEP))) { 3949fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 3950fcf3ce44SJohn Forte "emlxs_fct_send_els_cmd: Unable to allocate packet."); 395182527734SSukumar Swaminathan 395282527734SSukumar Swaminathan return (FCT_BUSY); 3953fcf3ce44SJohn Forte } 3954291a2b48SSukumar Swaminathan 395582527734SSukumar Swaminathan cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd, EMLXS_FCT_SEND_ELS_REQ); 3956291a2b48SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 3957291a2b48SSukumar Swaminathan 395882527734SSukumar Swaminathan cmd_sbp->channel = &hba->chan[hba->channel_els]; 3959fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_ELS_REQ; 3960fcf3ce44SJohn Forte 3961fcf3ce44SJohn Forte (void) emlxs_fct_pkt_init(port, fct_cmd, pkt); 3962291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = pkt; 3963fcf3ce44SJohn Forte 3964fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE; 3965fcf3ce44SJohn Forte pkt->pkt_timeout = 3966fcf3ce44SJohn Forte ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov); 3967fcf3ce44SJohn Forte pkt->pkt_comp = emlxs_fct_pkt_comp; 3968fcf3ce44SJohn Forte 3969fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 3970fcf3ce44SJohn Forte "emlxs_fct_send_els_cmd: pkt_timeout=%d ratov=%d", 3971fcf3ce44SJohn Forte pkt->pkt_timeout, hba->fc_ratov); 3972fcf3ce44SJohn Forte 3973fcf3ce44SJohn Forte /* Build the fc header */ 397482527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(did); 3975fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_ELS_REQ; 397682527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did); 3977fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 3978fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = 3979fcf3ce44SJohn Forte F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE; 3980fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 3981fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 3982fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 3983fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xFFFF; 3984fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xFFFF; 3985fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 3986fcf3ce44SJohn Forte 3987fcf3ce44SJohn Forte /* Copy the cmd payload */ 3988fcf3ce44SJohn Forte bcopy((uint8_t *)fct_els->els_req_payload, (uint8_t *)pkt->pkt_cmd, 3989fcf3ce44SJohn Forte fct_els->els_req_size); 399082527734SSukumar Swaminathan 3991291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP; 399282527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, EMLXS_FCT_REQ_PENDING); 399382527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 3994fcf3ce44SJohn Forte 3995fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 399682527734SSukumar Swaminathan 3997fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 3998fcf3ce44SJohn Forte "emlxs_fct_send_els_cmd: Unable to send packet."); 3999fcf3ce44SJohn Forte 400082527734SSukumar Swaminathan /* Reacquire ownership of the fct_cmd */ 400182527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, 0); 400282527734SSukumar Swaminathan if (rval) { 400382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 400482527734SSukumar Swaminathan "emlxs_fct_send_els_cmd: " 400582527734SSukumar Swaminathan "Unable to reacquire fct_cmd."); 400682527734SSukumar Swaminathan return (rval); 4007fcf3ce44SJohn Forte } 400882527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 4009fcf3ce44SJohn Forte 401082527734SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED); 401182527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 4012fcf3ce44SJohn Forte 401382527734SSukumar Swaminathan return (FCT_BUSY); 4014fcf3ce44SJohn Forte } 4015fcf3ce44SJohn Forte 4016fcf3ce44SJohn Forte return (FCT_SUCCESS); 4017fcf3ce44SJohn Forte 401882527734SSukumar Swaminathan } /* emlxs_fct_send_els_cmd() */ 4019fcf3ce44SJohn Forte 4020fcf3ce44SJohn Forte 402182527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be held to enter */ 402282527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be released before exiting */ 4023fcf3ce44SJohn Forte static fct_status_t 4024fcf3ce44SJohn Forte emlxs_fct_send_els_rsp(fct_cmd_t *fct_cmd) 4025fcf3ce44SJohn Forte { 4026fcf3ce44SJohn Forte emlxs_port_t *port = 4027fcf3ce44SJohn Forte (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 4028fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 4029fcf3ce44SJohn Forte uint32_t did; 4030fcf3ce44SJohn Forte fct_els_t *fct_els; 4031fcf3ce44SJohn Forte fc_packet_t *pkt; 4032fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 403382527734SSukumar Swaminathan fct_status_t rval; 4034fcf3ce44SJohn Forte 4035fcf3ce44SJohn Forte fct_els = (fct_els_t *)fct_cmd->cmd_specific; 4036fcf3ce44SJohn Forte did = fct_cmd->cmd_rportid; 403782527734SSukumar Swaminathan cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 4038fcf3ce44SJohn Forte 4039291a2b48SSukumar Swaminathan if (!(pkt = emlxs_pkt_alloc(port, fct_els->els_resp_size, 0, 0, 4040291a2b48SSukumar Swaminathan KM_NOSLEEP))) { 4041fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 4042fcf3ce44SJohn Forte "emlxs_fct_send_els_rsp: Unable to allocate packet."); 4043291a2b48SSukumar Swaminathan 4044fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 404582527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 4046fcf3ce44SJohn Forte 404782527734SSukumar Swaminathan return (FCT_FAILURE); 404882527734SSukumar Swaminathan } 4049291a2b48SSukumar Swaminathan 405082527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, EMLXS_FCT_SEND_ELS_RSP); 4051fcf3ce44SJohn Forte 4052fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_ELS_RSP; 4053fcf3ce44SJohn Forte 4054fcf3ce44SJohn Forte (void) emlxs_fct_pkt_init(port, fct_cmd, pkt); 4055291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = pkt; 4056fcf3ce44SJohn Forte 4057fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND; 4058fcf3ce44SJohn Forte pkt->pkt_timeout = 4059fcf3ce44SJohn Forte ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov); 4060fcf3ce44SJohn Forte pkt->pkt_comp = emlxs_fct_pkt_comp; 4061fcf3ce44SJohn Forte 4062fcf3ce44SJohn Forte /* Build the fc header */ 406382527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(did); 4064fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_ELS_RSP; 406582527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did); 4066fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 4067fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = 4068fcf3ce44SJohn Forte F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ; 4069fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 4070fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 4071fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 4072fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = fct_cmd->cmd_oxid; 4073fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = fct_cmd->cmd_rxid; 4074fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 4075fcf3ce44SJohn Forte 4076fcf3ce44SJohn Forte /* Copy the resp payload to pkt_cmd buffer */ 4077fcf3ce44SJohn Forte bcopy((uint8_t *)fct_els->els_resp_payload, (uint8_t *)pkt->pkt_cmd, 4078fcf3ce44SJohn Forte fct_els->els_resp_size); 407982527734SSukumar Swaminathan 4080291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP; 408182527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, EMLXS_FCT_RSP_PENDING); 408282527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 4083fcf3ce44SJohn Forte 4084fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 408582527734SSukumar Swaminathan 4086fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 4087fcf3ce44SJohn Forte "emlxs_fct_send_els_rsp: Unable to send packet."); 4088fcf3ce44SJohn Forte 408982527734SSukumar Swaminathan /* Reacquire ownership of the fct_cmd */ 409082527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, 0); 409182527734SSukumar Swaminathan if (rval) { 409282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 409382527734SSukumar Swaminathan "emlxs_fct_send_els_rsp: " 409482527734SSukumar Swaminathan "Unable to reacquire fct_cmd."); 409582527734SSukumar Swaminathan return (rval); 4096fcf3ce44SJohn Forte } 409782527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 4098291a2b48SSukumar Swaminathan 4099fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED); 410082527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 4101291a2b48SSukumar Swaminathan 4102fcf3ce44SJohn Forte return (FCT_FAILURE); 4103fcf3ce44SJohn Forte } 4104fcf3ce44SJohn Forte 4105291a2b48SSukumar Swaminathan return (FCT_SUCCESS); 4106fcf3ce44SJohn Forte 410782527734SSukumar Swaminathan } /* emlxs_fct_send_els_rsp() */ 4108fcf3ce44SJohn Forte 4109fcf3ce44SJohn Forte 411082527734SSukumar Swaminathan /* COMSTAR ENTER POINT (INDIRECT) */ 4111fcf3ce44SJohn Forte static fct_status_t 4112fcf3ce44SJohn Forte emlxs_fct_send_ct_cmd(fct_cmd_t *fct_cmd) 4113fcf3ce44SJohn Forte { 4114fcf3ce44SJohn Forte emlxs_port_t *port = 4115fcf3ce44SJohn Forte (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private; 4116fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 4117fcf3ce44SJohn Forte uint32_t did; 4118fcf3ce44SJohn Forte fct_sol_ct_t *fct_ct; 4119fcf3ce44SJohn Forte fc_packet_t *pkt; 4120fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp; 412182527734SSukumar Swaminathan fct_status_t rval; 4122fcf3ce44SJohn Forte 4123fcf3ce44SJohn Forte did = fct_cmd->cmd_rportid; 4124fcf3ce44SJohn Forte fct_ct = (fct_sol_ct_t *)fct_cmd->cmd_specific; 4125fcf3ce44SJohn Forte 4126fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, fct_ct->ct_req_size, 4127fcf3ce44SJohn Forte fct_ct->ct_resp_size, 0, KM_NOSLEEP))) { 4128fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 4129fcf3ce44SJohn Forte "emlxs_fct_send_ct_cmd: Unable to allocate packet."); 413082527734SSukumar Swaminathan return (FCT_BUSY); 4131fcf3ce44SJohn Forte } 4132291a2b48SSukumar Swaminathan 413382527734SSukumar Swaminathan cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd, EMLXS_FCT_SEND_CT_REQ); 4134291a2b48SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 4135fcf3ce44SJohn Forte 413682527734SSukumar Swaminathan cmd_sbp->channel = &hba->chan[hba->channel_ct]; 4137fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_CT_REQ; 4138fcf3ce44SJohn Forte 4139fcf3ce44SJohn Forte (void) emlxs_fct_pkt_init(port, fct_cmd, pkt); 4140291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = pkt; 4141fcf3ce44SJohn Forte 4142fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE; 4143fcf3ce44SJohn Forte pkt->pkt_timeout = 4144fcf3ce44SJohn Forte ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov); 4145fcf3ce44SJohn Forte pkt->pkt_comp = emlxs_fct_pkt_comp; 4146fcf3ce44SJohn Forte 4147fcf3ce44SJohn Forte /* Build the fc header */ 414882527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(did); 4149fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_UNSOL_CONTROL; 415082527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did); 4151fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_FC_SERVICES; 4152fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = 4153fcf3ce44SJohn Forte F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE; 4154fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0; 4155fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0; 4156fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0; 4157fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xFFFF; 4158fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xFFFF; 4159fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0; 4160fcf3ce44SJohn Forte 4161fcf3ce44SJohn Forte /* Copy the cmd payload */ 4162fcf3ce44SJohn Forte bcopy((uint8_t *)fct_ct->ct_req_payload, (uint8_t *)pkt->pkt_cmd, 4163fcf3ce44SJohn Forte fct_ct->ct_req_size); 416482527734SSukumar Swaminathan 4165291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP; 416682527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, EMLXS_FCT_REQ_PENDING); 416782527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 4168fcf3ce44SJohn Forte 4169fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 417082527734SSukumar Swaminathan 4171fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 4172fcf3ce44SJohn Forte "emlxs_fct_send_ct_cmd: Unable to send packet."); 4173fcf3ce44SJohn Forte 417482527734SSukumar Swaminathan /* Reacquire ownership of the fct_cmd */ 417582527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, 0); 417682527734SSukumar Swaminathan if (rval) { 417782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 417882527734SSukumar Swaminathan "emlxs_fct_send_ct_cmd: " 417982527734SSukumar Swaminathan "Unable to reacquire fct_cmd."); 418082527734SSukumar Swaminathan 418182527734SSukumar Swaminathan return (rval); 4182fcf3ce44SJohn Forte } 418382527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */ 4184fcf3ce44SJohn Forte 418582527734SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED); 418682527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 4187fcf3ce44SJohn Forte 418882527734SSukumar Swaminathan return (FCT_BUSY); 4189fcf3ce44SJohn Forte } 4190fcf3ce44SJohn Forte 4191fcf3ce44SJohn Forte return (FCT_SUCCESS); 4192fcf3ce44SJohn Forte 419382527734SSukumar Swaminathan } /* emlxs_fct_send_ct_cmd() */ 4194fcf3ce44SJohn Forte 4195fcf3ce44SJohn Forte 419682527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be held to enter */ 4197fe199829SSukumar Swaminathan static uint32_t 4198291a2b48SSukumar Swaminathan emlxs_fct_pkt_abort_txq(emlxs_port_t *port, emlxs_buf_t *cmd_sbp) 4199fcf3ce44SJohn Forte { 4200fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 4201fcf3ce44SJohn Forte NODELIST *nlp; 4202291a2b48SSukumar Swaminathan fc_packet_t *pkt; 4203291a2b48SSukumar Swaminathan emlxs_buf_t *sbp; 4204291a2b48SSukumar Swaminathan emlxs_buf_t *iocb_sbp; 420582527734SSukumar Swaminathan uint8_t channelno; 420682527734SSukumar Swaminathan CHANNEL *cp; 4207fcf3ce44SJohn Forte IOCBQ *iocbq; 4208fcf3ce44SJohn Forte IOCBQ *next; 4209fcf3ce44SJohn Forte IOCBQ *prev; 4210fcf3ce44SJohn Forte uint32_t found; 4211291a2b48SSukumar Swaminathan uint32_t pkt_flags; 4212fcf3ce44SJohn Forte 4213291a2b48SSukumar Swaminathan /* Check the transmit queue */ 421482527734SSukumar Swaminathan mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 4215fcf3ce44SJohn Forte 4216291a2b48SSukumar Swaminathan /* The IOCB could point to a cmd_sbp (no packet) or a sbp (packet) */ 4217291a2b48SSukumar Swaminathan pkt = cmd_sbp->fct_pkt; 4218291a2b48SSukumar Swaminathan if (pkt) { 4219291a2b48SSukumar Swaminathan sbp = PKT2PRIV(pkt); 4220291a2b48SSukumar Swaminathan if (sbp == NULL) { 4221291a2b48SSukumar Swaminathan goto done; 4222291a2b48SSukumar Swaminathan } 4223291a2b48SSukumar Swaminathan iocb_sbp = sbp; 4224291a2b48SSukumar Swaminathan iocbq = &sbp->iocbq; 4225291a2b48SSukumar Swaminathan pkt_flags = sbp->pkt_flags; 4226291a2b48SSukumar Swaminathan } else { 4227291a2b48SSukumar Swaminathan sbp = NULL; 4228291a2b48SSukumar Swaminathan iocb_sbp = cmd_sbp; 4229291a2b48SSukumar Swaminathan iocbq = &cmd_sbp->iocbq; 4230291a2b48SSukumar Swaminathan pkt_flags = cmd_sbp->pkt_flags; 4231fcf3ce44SJohn Forte } 4232fcf3ce44SJohn Forte 4233291a2b48SSukumar Swaminathan nlp = (NODELIST *)cmd_sbp->node; 423482527734SSukumar Swaminathan cp = (CHANNEL *)cmd_sbp->channel; 423582527734SSukumar Swaminathan channelno = (cp) ? cp->channelno : 0; 4236fcf3ce44SJohn Forte 4237291a2b48SSukumar Swaminathan if (pkt_flags & PACKET_IN_TXQ) { 4238fcf3ce44SJohn Forte /* Find it on the queue */ 4239fcf3ce44SJohn Forte found = 0; 4240fcf3ce44SJohn Forte if (iocbq->flag & IOCB_PRIORITY) { 4241fcf3ce44SJohn Forte /* Search the priority queue */ 4242fcf3ce44SJohn Forte prev = NULL; 424382527734SSukumar Swaminathan next = (IOCBQ *)nlp->nlp_ptx[channelno].q_first; 4244fcf3ce44SJohn Forte 4245fcf3ce44SJohn Forte while (next) { 4246fcf3ce44SJohn Forte if (next == iocbq) { 4247fcf3ce44SJohn Forte /* Remove it */ 4248fcf3ce44SJohn Forte if (prev) { 4249fcf3ce44SJohn Forte prev->next = iocbq->next; 4250fcf3ce44SJohn Forte } 4251291a2b48SSukumar Swaminathan 425282527734SSukumar Swaminathan if (nlp->nlp_ptx[channelno].q_last == 4253fcf3ce44SJohn Forte (void *)iocbq) { 425482527734SSukumar Swaminathan nlp->nlp_ptx[channelno].q_last = 4255fcf3ce44SJohn Forte (void *)prev; 4256fcf3ce44SJohn Forte } 4257291a2b48SSukumar Swaminathan 425882527734SSukumar Swaminathan if (nlp->nlp_ptx[channelno].q_first == 4259fcf3ce44SJohn Forte (void *)iocbq) { 426082527734SSukumar Swaminathan nlp->nlp_ptx[channelno]. 426182527734SSukumar Swaminathan q_first = 4262fcf3ce44SJohn Forte (void *)iocbq->next; 4263fcf3ce44SJohn Forte } 4264291a2b48SSukumar Swaminathan 426582527734SSukumar Swaminathan nlp->nlp_ptx[channelno].q_cnt--; 4266fcf3ce44SJohn Forte iocbq->next = NULL; 4267fcf3ce44SJohn Forte found = 1; 4268fcf3ce44SJohn Forte break; 4269fcf3ce44SJohn Forte } 4270291a2b48SSukumar Swaminathan 4271fcf3ce44SJohn Forte prev = next; 4272fcf3ce44SJohn Forte next = next->next; 4273fcf3ce44SJohn Forte } 4274fcf3ce44SJohn Forte } else { 4275fcf3ce44SJohn Forte /* Search the normal queue */ 4276fcf3ce44SJohn Forte prev = NULL; 427782527734SSukumar Swaminathan next = (IOCBQ *)nlp->nlp_tx[channelno].q_first; 4278fcf3ce44SJohn Forte 4279fcf3ce44SJohn Forte while (next) { 4280fcf3ce44SJohn Forte if (next == iocbq) { 4281fcf3ce44SJohn Forte /* Remove it */ 4282fcf3ce44SJohn Forte if (prev) { 4283fcf3ce44SJohn Forte prev->next = iocbq->next; 4284fcf3ce44SJohn Forte } 4285291a2b48SSukumar Swaminathan 428682527734SSukumar Swaminathan if (nlp->nlp_tx[channelno].q_last == 4287fcf3ce44SJohn Forte (void *)iocbq) { 428882527734SSukumar Swaminathan nlp->nlp_tx[channelno].q_last = 4289fcf3ce44SJohn Forte (void *)prev; 4290fcf3ce44SJohn Forte } 4291291a2b48SSukumar Swaminathan 429282527734SSukumar Swaminathan if (nlp->nlp_tx[channelno].q_first == 4293fcf3ce44SJohn Forte (void *)iocbq) { 429482527734SSukumar Swaminathan nlp->nlp_tx[channelno].q_first = 4295fcf3ce44SJohn Forte (void *)iocbq->next; 4296fcf3ce44SJohn Forte } 4297291a2b48SSukumar Swaminathan 429882527734SSukumar Swaminathan nlp->nlp_tx[channelno].q_cnt--; 4299fcf3ce44SJohn Forte iocbq->next = NULL; 4300fcf3ce44SJohn Forte found = 1; 4301fcf3ce44SJohn Forte break; 4302fcf3ce44SJohn Forte } 4303291a2b48SSukumar Swaminathan 4304fcf3ce44SJohn Forte prev = next; 4305fcf3ce44SJohn Forte next = (IOCBQ *)next->next; 4306fcf3ce44SJohn Forte } 4307fcf3ce44SJohn Forte } 4308fcf3ce44SJohn Forte 4309fcf3ce44SJohn Forte if (!found) { 4310fcf3ce44SJohn Forte goto done; 4311fcf3ce44SJohn Forte } 4312291a2b48SSukumar Swaminathan 4313fcf3ce44SJohn Forte /* Check if node still needs servicing */ 431482527734SSukumar Swaminathan if ((nlp->nlp_ptx[channelno].q_first) || 431582527734SSukumar Swaminathan (nlp->nlp_tx[channelno].q_first && 431682527734SSukumar Swaminathan !(nlp->nlp_flag[channelno] & NLP_CLOSED))) { 4317fcf3ce44SJohn Forte 4318fcf3ce44SJohn Forte /* 4319291a2b48SSukumar Swaminathan * If this is the base node, don't shift the pointers 4320fcf3ce44SJohn Forte */ 4321fcf3ce44SJohn Forte /* We want to drain the base node before moving on */ 4322fcf3ce44SJohn Forte if (!nlp->nlp_base) { 432382527734SSukumar Swaminathan /* Shift channel queue pointers to next node */ 432482527734SSukumar Swaminathan cp->nodeq.q_last = (void *)nlp; 432582527734SSukumar Swaminathan cp->nodeq.q_first = nlp->nlp_next[channelno]; 4326fcf3ce44SJohn Forte } 4327fcf3ce44SJohn Forte } else { 432882527734SSukumar Swaminathan /* Remove node from channel queue */ 4329fcf3ce44SJohn Forte 4330fcf3ce44SJohn Forte /* If this is the last node on list */ 433182527734SSukumar Swaminathan if (cp->nodeq.q_last == (void *)nlp) { 433282527734SSukumar Swaminathan cp->nodeq.q_last = NULL; 433382527734SSukumar Swaminathan cp->nodeq.q_first = NULL; 433482527734SSukumar Swaminathan cp->nodeq.q_cnt = 0; 4335fcf3ce44SJohn Forte } else { 4336fcf3ce44SJohn Forte /* Remove node from head */ 433782527734SSukumar Swaminathan cp->nodeq.q_first = nlp->nlp_next[channelno]; 433882527734SSukumar Swaminathan ((NODELIST *)cp->nodeq.q_last)-> 433982527734SSukumar Swaminathan nlp_next[channelno] = cp->nodeq.q_first; 434082527734SSukumar Swaminathan cp->nodeq.q_cnt--; 4341fcf3ce44SJohn Forte } 4342fcf3ce44SJohn Forte 4343fcf3ce44SJohn Forte /* Clear node */ 434482527734SSukumar Swaminathan nlp->nlp_next[channelno] = NULL; 4345fcf3ce44SJohn Forte } 4346fcf3ce44SJohn Forte 434782527734SSukumar Swaminathan /* The IOCB points to iocb_sbp (no packet) or a sbp (packet) */ 434882527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 434982527734SSukumar Swaminathan hba->fc_table[iocb_sbp->iotag] = NULL; 435082527734SSukumar Swaminathan emlxs_sli4_free_xri(hba, iocb_sbp, iocb_sbp->xp); 435182527734SSukumar Swaminathan } else { 435282527734SSukumar Swaminathan (void) emlxs_unregister_pkt(cp, iocb_sbp->iotag, 0); 4353fcf3ce44SJohn Forte } 4354fcf3ce44SJohn Forte 435582527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 4356fcf3ce44SJohn Forte 4357291a2b48SSukumar Swaminathan if (pkt) { 4358291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt); 4359291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = NULL; 4360fcf3ce44SJohn Forte } 436182527734SSukumar Swaminathan return (1); 4362fcf3ce44SJohn Forte } 4363291a2b48SSukumar Swaminathan done: 436482527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 436582527734SSukumar Swaminathan return (0); 436682527734SSukumar Swaminathan 436782527734SSukumar Swaminathan } /* emlxs_fct_pkt_abort_txq() */ 4368fcf3ce44SJohn Forte 4369fcf3ce44SJohn Forte 437082527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 4371291a2b48SSukumar Swaminathan /* FCT_NOT_FOUND & FCT_ABORT_SUCCESS indicates IO is done */ 4372291a2b48SSukumar Swaminathan /* FCT_SUCCESS indicates abort will occur asyncronously */ 4373291a2b48SSukumar Swaminathan static fct_status_t 4374291a2b48SSukumar Swaminathan emlxs_fct_abort(fct_local_port_t *fct_port, fct_cmd_t *fct_cmd, 4375291a2b48SSukumar Swaminathan uint32_t flags) 4376291a2b48SSukumar Swaminathan { 4377291a2b48SSukumar Swaminathan emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 4378291a2b48SSukumar Swaminathan emlxs_hba_t *hba = HBA; 4379291a2b48SSukumar Swaminathan emlxs_buf_t *cmd_sbp; 438082527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp2; 438182527734SSukumar Swaminathan emlxs_buf_t *prev; 4382291a2b48SSukumar Swaminathan fc_packet_t *pkt; 4383291a2b48SSukumar Swaminathan emlxs_buf_t *sbp = NULL; 438482527734SSukumar Swaminathan kmutex_t *fct_mtx; 438582527734SSukumar Swaminathan uint32_t fct_state; 438682527734SSukumar Swaminathan 438782527734SSukumar Swaminathan cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 438882527734SSukumar Swaminathan fct_mtx = &cmd_sbp->fct_mtx; 4389fcf3ce44SJohn Forte 4390291a2b48SSukumar Swaminathan top: 439182527734SSukumar Swaminathan 4392291a2b48SSukumar Swaminathan /* Sanity check */ 4393291a2b48SSukumar Swaminathan if ((fct_cmd->cmd_oxid == 0) && (fct_cmd->cmd_rxid == 0)) { 4394291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 439582527734SSukumar Swaminathan "emlxs_fct_abort: Bad fct_cmd=%p.", fct_cmd); 4396fcf3ce44SJohn Forte 4397291a2b48SSukumar Swaminathan return (FCT_NOT_FOUND); 4398291a2b48SSukumar Swaminathan } 4399fcf3ce44SJohn Forte 4400291a2b48SSukumar Swaminathan if (!(cmd_sbp->pkt_flags & PACKET_VALID)) { 4401291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 440282527734SSukumar Swaminathan "emlxs_fct_abort: Pkt invalid. cmd_sbp=%p", 440382527734SSukumar Swaminathan cmd_sbp); 4404fcf3ce44SJohn Forte 4405291a2b48SSukumar Swaminathan return (FCT_NOT_FOUND); 4406fcf3ce44SJohn Forte } 4407fcf3ce44SJohn Forte 440882527734SSukumar Swaminathan if (mutex_tryenter(fct_mtx) == 0) { 4409fcf3ce44SJohn Forte /* 4410291a2b48SSukumar Swaminathan * This code path handles a race condition if 4411291a2b48SSukumar Swaminathan * an IO completes, in emlxs_fct_handle_fcp_event(), 4412291a2b48SSukumar Swaminathan * and we get an abort at the same time. 4413fcf3ce44SJohn Forte */ 4414291a2b48SSukumar Swaminathan delay(drv_usectohz(100000)); /* 100 msec */ 4415291a2b48SSukumar Swaminathan goto top; 4416fcf3ce44SJohn Forte } 4417291a2b48SSukumar Swaminathan /* At this point, we have entered the mutex */ 4418fcf3ce44SJohn Forte 441982527734SSukumar Swaminathan /* Sanity check */ 442082527734SSukumar Swaminathan if ((fct_cmd->cmd_oxid == 0) && (fct_cmd->cmd_rxid == 0)) { 4421291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 442282527734SSukumar Swaminathan "emlxs_fct_abort: Bad fct_cmd=%p.", fct_cmd); 4423fcf3ce44SJohn Forte 442482527734SSukumar Swaminathan mutex_exit(fct_mtx); 4425291a2b48SSukumar Swaminathan return (FCT_NOT_FOUND); 4426fcf3ce44SJohn Forte } 4427fcf3ce44SJohn Forte 442882527734SSukumar Swaminathan if (!(cmd_sbp->pkt_flags & PACKET_VALID)) { 442982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 443082527734SSukumar Swaminathan "emlxs_fct_abort: Pkt invalid. cmd_sbp=%p", 443182527734SSukumar Swaminathan cmd_sbp); 443282527734SSukumar Swaminathan 443382527734SSukumar Swaminathan mutex_exit(fct_mtx); 443482527734SSukumar Swaminathan return (FCT_NOT_FOUND); 4435fcf3ce44SJohn Forte } 4436fcf3ce44SJohn Forte 4437291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4438fe199829SSukumar Swaminathan "emlxs_fct_abort: hbastate=%x. " 4439fe199829SSukumar Swaminathan "xid=%x,%x cmd_sbp=%p fctstate=%d flags=%x,%x,%x", 4440fe199829SSukumar Swaminathan hba->state, fct_cmd->cmd_oxid, fct_cmd->cmd_rxid, cmd_sbp, 4441fe199829SSukumar Swaminathan cmd_sbp->fct_state, flags, cmd_sbp->fct_flags, cmd_sbp->pkt_flags); 4442291a2b48SSukumar Swaminathan 4443291a2b48SSukumar Swaminathan if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT_INP) { 444482527734SSukumar Swaminathan EMLXS_SLI_ISSUE_IOCB_CMD(hba, cmd_sbp->channel, 0); 444582527734SSukumar Swaminathan 4446291a2b48SSukumar Swaminathan /* If Abort is already in progress */ 444782527734SSukumar Swaminathan mutex_exit(fct_mtx); 444882527734SSukumar Swaminathan return (FCT_SUCCESS); 444982527734SSukumar Swaminathan } 445082527734SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_ABORT_INP; 445182527734SSukumar Swaminathan 445282527734SSukumar Swaminathan if (flags & FCT_IOF_FORCE_FCA_DONE) { 445382527734SSukumar Swaminathan fct_cmd->cmd_handle = 0; 4454291a2b48SSukumar Swaminathan } 4455fcf3ce44SJohn Forte 4456291a2b48SSukumar Swaminathan TGTPORTSTAT.FctAbortSent++; 4457fcf3ce44SJohn Forte 445882527734SSukumar Swaminathan switch (cmd_sbp->fct_state) { 445982527734SSukumar Swaminathan /* These are currently owned by COMSTAR. */ 446082527734SSukumar Swaminathan /* They were last processed by emlxs_fct_cmd_post() */ 4461fe199829SSukumar Swaminathan /* We have NO exchange resources associated with this IO. */ 446282527734SSukumar Swaminathan case EMLXS_FCT_OWNED: 4463fe199829SSukumar Swaminathan goto abort_done; 446482527734SSukumar Swaminathan 446582527734SSukumar Swaminathan /* These are on the unsol waitQ in the driver */ 446682527734SSukumar Swaminathan case EMLXS_FCT_CMD_WAITQ: 446782527734SSukumar Swaminathan /* Find and remove it */ 446882527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 446982527734SSukumar Swaminathan cmd_sbp2 = port->fct_wait_head; 447082527734SSukumar Swaminathan prev = NULL; 447182527734SSukumar Swaminathan while (cmd_sbp2) { 447282527734SSukumar Swaminathan if (cmd_sbp2 == cmd_sbp) { 447382527734SSukumar Swaminathan /* Remove it */ 447482527734SSukumar Swaminathan if (prev) { 447582527734SSukumar Swaminathan prev->next = cmd_sbp2->next; 447682527734SSukumar Swaminathan } 447782527734SSukumar Swaminathan 447882527734SSukumar Swaminathan if (port->fct_wait_head == cmd_sbp2) { 447982527734SSukumar Swaminathan port->fct_wait_head = cmd_sbp2->next; 448082527734SSukumar Swaminathan } 448182527734SSukumar Swaminathan 448282527734SSukumar Swaminathan if (port->fct_wait_tail == cmd_sbp2) { 448382527734SSukumar Swaminathan port->fct_wait_tail = prev; 448482527734SSukumar Swaminathan } 448582527734SSukumar Swaminathan 448682527734SSukumar Swaminathan cmd_sbp2->next = NULL; 448782527734SSukumar Swaminathan break; 448882527734SSukumar Swaminathan } 448982527734SSukumar Swaminathan prev = cmd_sbp2; 449082527734SSukumar Swaminathan cmd_sbp2 = cmd_sbp2->next; 449182527734SSukumar Swaminathan } 449282527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 449382527734SSukumar Swaminathan 4494fe199829SSukumar Swaminathan /*FALLTHROUGH*/ 4495fe199829SSukumar Swaminathan 4496fe199829SSukumar Swaminathan /* These are currently owned by COMSTAR. */ 4497fe199829SSukumar Swaminathan /* They were last processed by emlxs_fct_cmd_post() */ 4498fe199829SSukumar Swaminathan /* We have residual exchange resources associated with this IO */ 4499fe199829SSukumar Swaminathan case EMLXS_FCT_CMD_POSTED: 4500fe199829SSukumar Swaminathan switch (fct_cmd->cmd_type) { 4501fe199829SSukumar Swaminathan case FCT_CMD_FCP_XCHG: /* Unsol */ 4502fe199829SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--; 4503fe199829SSukumar Swaminathan emlxs_abort_fct_exchange(hba, port, fct_cmd->cmd_rxid); 4504fe199829SSukumar Swaminathan break; 4505fe199829SSukumar Swaminathan 4506fe199829SSukumar Swaminathan case FCT_CMD_RCVD_ELS: /* Unsol */ 4507fe199829SSukumar Swaminathan emlxs_abort_els_exchange(hba, port, fct_cmd->cmd_rxid); 4508fe199829SSukumar Swaminathan break; 4509fe199829SSukumar Swaminathan } 4510fe199829SSukumar Swaminathan 4511fe199829SSukumar Swaminathan goto abort_done; 451282527734SSukumar Swaminathan 451382527734SSukumar Swaminathan /* These are active in the driver */ 451482527734SSukumar Swaminathan /* They were last processed by emlxs_fct_cmd_release() */ 4515291a2b48SSukumar Swaminathan case EMLXS_FCT_RSP_PENDING: 4516291a2b48SSukumar Swaminathan case EMLXS_FCT_REQ_PENDING: 4517291a2b48SSukumar Swaminathan case EMLXS_FCT_REG_PENDING: 4518291a2b48SSukumar Swaminathan case EMLXS_FCT_DATA_PENDING: 4519291a2b48SSukumar Swaminathan case EMLXS_FCT_STATUS_PENDING: 452082527734SSukumar Swaminathan 452182527734SSukumar Swaminathan /* Abort anything pending */ 4522291a2b48SSukumar Swaminathan if (emlxs_fct_pkt_abort_txq(port, cmd_sbp)) { 4523fcf3ce44SJohn Forte 4524291a2b48SSukumar Swaminathan if (fct_cmd->cmd_type == FCT_CMD_FCP_XCHG) { 4525291a2b48SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--; 4526fcf3ce44SJohn Forte } 452782527734SSukumar Swaminathan 4528fe199829SSukumar Swaminathan goto abort_done; 4529291a2b48SSukumar Swaminathan } 4530fcf3ce44SJohn Forte 453182527734SSukumar Swaminathan /* If we're not online, then all IO will be flushed anyway */ 4532291a2b48SSukumar Swaminathan if (!(hba->flag & FC_ONLINE_MODE)) { 453382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 453482527734SSukumar Swaminathan "emlxs_fct_abort: Not online. fct_cmd=%p.", 453582527734SSukumar Swaminathan fct_cmd); 4536291a2b48SSukumar Swaminathan 453782527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, 0); 453882527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 453982527734SSukumar Swaminathan 454082527734SSukumar Swaminathan /* The cmd will be aborted on the */ 454182527734SSukumar Swaminathan /* next emlxs_fct_cmd_acquire */ 454282527734SSukumar Swaminathan /* because EMLXS_FCT_ABORT_INP is set. */ 454382527734SSukumar Swaminathan break; 4544fcf3ce44SJohn Forte } 4545fcf3ce44SJohn Forte 454682527734SSukumar Swaminathan /* Try to send abort request */ 4547291a2b48SSukumar Swaminathan if (!(pkt = emlxs_pkt_alloc(port, 0, 0, 0, KM_NOSLEEP))) { 4548291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 454982527734SSukumar Swaminathan "emlxs_fct_abort: Unable to allocate packet. " 455082527734SSukumar Swaminathan "fct_cmd=%p", 455182527734SSukumar Swaminathan fct_cmd); 455282527734SSukumar Swaminathan 455382527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, 0); 455482527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 455582527734SSukumar Swaminathan 455682527734SSukumar Swaminathan /* The cmd will be aborted on the */ 455782527734SSukumar Swaminathan /* next emlxs_fct_cmd_acquire anyway */ 455882527734SSukumar Swaminathan /* because EMLXS_FCT_ABORT_INP is set. */ 455982527734SSukumar Swaminathan break; 4560fcf3ce44SJohn Forte } 4561fcf3ce44SJohn Forte 4562291a2b48SSukumar Swaminathan sbp = emlxs_fct_pkt_init(port, fct_cmd, pkt); 4563291a2b48SSukumar Swaminathan 4564291a2b48SSukumar Swaminathan pkt->pkt_tran_type = FC_PKT_OUTBOUND; 4565291a2b48SSukumar Swaminathan pkt->pkt_timeout = 4566291a2b48SSukumar Swaminathan ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov); 4567291a2b48SSukumar Swaminathan pkt->pkt_comp = emlxs_fct_abort_pkt_comp; 4568291a2b48SSukumar Swaminathan 4569291a2b48SSukumar Swaminathan /* Build the fc header */ 457082527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(fct_cmd->cmd_rportid); 4571291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.r_ctl = R_CTL_STATUS; 457282527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did); 4573291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.type = FC_TYPE_BASIC_LS; 4574291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.f_ctl = 4575291a2b48SSukumar Swaminathan (F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ); 4576291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.seq_id = 0; 4577291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.df_ctl = 0; 4578291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.seq_cnt = 0; 4579291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.ox_id = fct_cmd->cmd_oxid; 4580291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id = fct_cmd->cmd_rxid; 4581291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.ro = 0; 4582291a2b48SSukumar Swaminathan 4583291a2b48SSukumar Swaminathan cmd_sbp->fct_cmd = fct_cmd; 4584291a2b48SSukumar Swaminathan cmd_sbp->abort_attempts++; 4585fcf3ce44SJohn Forte 4586291a2b48SSukumar Swaminathan /* Now disassociate the sbp / pkt from the fct_cmd */ 4587291a2b48SSukumar Swaminathan sbp->fct_cmd = NULL; 4588fcf3ce44SJohn Forte 458982527734SSukumar Swaminathan if (hba->state >= FC_LINK_UP) { 4590291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4591291a2b48SSukumar Swaminathan "emlxs_fct_abort: ABORT: %p xri x%x", 4592291a2b48SSukumar Swaminathan fct_cmd, fct_cmd->cmd_rxid); 4593fcf3ce44SJohn Forte 459482527734SSukumar Swaminathan fct_state = EMLXS_FCT_ABORT_PENDING; 459582527734SSukumar Swaminathan 459682527734SSukumar Swaminathan } else { 4597291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4598291a2b48SSukumar Swaminathan "emlxs_fct_abort: CLOSE: %p xri x%x", 4599291a2b48SSukumar Swaminathan fct_cmd, fct_cmd->cmd_rxid); 4600fcf3ce44SJohn Forte 460182527734SSukumar Swaminathan fct_state = EMLXS_FCT_CLOSE_PENDING; 4602291a2b48SSukumar Swaminathan } 4603fcf3ce44SJohn Forte 460482527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, fct_state); 460582527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 460682527734SSukumar Swaminathan 4607291a2b48SSukumar Swaminathan if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) { 4608291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 460982527734SSukumar Swaminathan "emlxs_fct_abort: Unable to send abort packet."); 4610fcf3ce44SJohn Forte 4611291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt); 4612fcf3ce44SJohn Forte 461382527734SSukumar Swaminathan /* The cmd will be aborted on the */ 461482527734SSukumar Swaminathan /* next emlxs_fct_cmd_acquire anyway */ 461582527734SSukumar Swaminathan /* because EMLXS_FCT_ABORT_INP is set. */ 4616291a2b48SSukumar Swaminathan } 461782527734SSukumar Swaminathan 4618291a2b48SSukumar Swaminathan break; 4619fcf3ce44SJohn Forte 4620291a2b48SSukumar Swaminathan default: 462182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 462282527734SSukumar Swaminathan "emlxs_fct_abort: Unexpected fct_state. " 462382527734SSukumar Swaminathan "fct_cmd=%p state=%x", 462482527734SSukumar Swaminathan fct_cmd, cmd_sbp->fct_state); 462582527734SSukumar Swaminathan 462682527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, 0); 462782527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 462882527734SSukumar Swaminathan 462982527734SSukumar Swaminathan /* The cmd will be aborted on the */ 463082527734SSukumar Swaminathan /* next emlxs_fct_cmd_acquire anyway */ 463182527734SSukumar Swaminathan /* because EMLXS_FCT_ABORT_INP is set. */ 4632fcf3ce44SJohn Forte 4633291a2b48SSukumar Swaminathan } /* switch */ 4634fcf3ce44SJohn Forte 463582527734SSukumar Swaminathan return (FCT_SUCCESS); 4636fcf3ce44SJohn Forte 4637fe199829SSukumar Swaminathan abort_done: 463882527734SSukumar Swaminathan 463982527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, 464082527734SSukumar Swaminathan EMLXS_FCT_ABORT_DONE); 464182527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */ 464282527734SSukumar Swaminathan 464382527734SSukumar Swaminathan return (FCT_ABORT_SUCCESS); 464482527734SSukumar Swaminathan 464582527734SSukumar Swaminathan } /* emlxs_fct_abort() */ 4646fcf3ce44SJohn Forte 4647fcf3ce44SJohn Forte 4648fcf3ce44SJohn Forte extern void 4649fcf3ce44SJohn Forte emlxs_fct_link_up(emlxs_port_t *port) 4650fcf3ce44SJohn Forte { 4651fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 4652fcf3ce44SJohn Forte 4653fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 4654fcf3ce44SJohn Forte 4655fcf3ce44SJohn Forte if (port->fct_port && 4656fcf3ce44SJohn Forte (port->fct_flags & FCT_STATE_PORT_ONLINE) && 4657fcf3ce44SJohn Forte !(port->fct_flags & FCT_STATE_LINK_UP)) { 4658fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4659fcf3ce44SJohn Forte "emlxs_fct_link_up event."); 4660fcf3ce44SJohn Forte 4661e2ca2865SSukumar Swaminathan port->fct_flags &= ~FCT_STATE_LINK_UP_ACKED; 4662fcf3ce44SJohn Forte port->fct_flags |= FCT_STATE_LINK_UP; 4663fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 4664fcf3ce44SJohn Forte 4665fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 4666fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 4667fcf3ce44SJohn Forte "fct_handle_event LINK_UP"); 4668291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 4669291a2b48SSukumar Swaminathan MODSYM(fct_handle_event) (port->fct_port, FCT_EVENT_LINK_UP, 4670291a2b48SSukumar Swaminathan 0, 0); 4671fcf3ce44SJohn Forte } else { 4672fcf3ce44SJohn Forte if (!hba->ini_mode && 4673fcf3ce44SJohn Forte !(port->fct_flags & FCT_STATE_PORT_ONLINE)) { 4674fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 4675fcf3ce44SJohn Forte 4676fcf3ce44SJohn Forte /* Take link down and hold it down */ 467782527734SSukumar Swaminathan (void) emlxs_reset_link(hba, 0, 1); 4678fcf3ce44SJohn Forte } else { 4679fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 4680fcf3ce44SJohn Forte } 4681fcf3ce44SJohn Forte } 4682fcf3ce44SJohn Forte 4683fcf3ce44SJohn Forte return; 4684fcf3ce44SJohn Forte 468582527734SSukumar Swaminathan } /* emlxs_fct_link_up() */ 4686291a2b48SSukumar Swaminathan 4687fcf3ce44SJohn Forte 4688fcf3ce44SJohn Forte extern void 4689fcf3ce44SJohn Forte emlxs_fct_link_down(emlxs_port_t *port) 4690fcf3ce44SJohn Forte { 4691fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 4692fcf3ce44SJohn Forte 4693fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 4694fcf3ce44SJohn Forte 4695fcf3ce44SJohn Forte if (port->fct_port && 4696fcf3ce44SJohn Forte (port->fct_flags & FCT_STATE_PORT_ONLINE) && 4697fcf3ce44SJohn Forte (port->fct_flags & FCT_STATE_LINK_UP)) { 4698fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4699fcf3ce44SJohn Forte "emlxs_fct_link_down event."); 4700fcf3ce44SJohn Forte 4701e2ca2865SSukumar Swaminathan port->fct_flags &= ~FCT_STATE_LINK_UP_ACKED; 4702fcf3ce44SJohn Forte port->fct_flags &= ~FCT_STATE_LINK_UP; 4703fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 4704fcf3ce44SJohn Forte 4705fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 4706fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 4707fcf3ce44SJohn Forte "fct_handle_event LINK_DOWN"); 4708291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 470982527734SSukumar Swaminathan 4710291a2b48SSukumar Swaminathan MODSYM(fct_handle_event) (port->fct_port, FCT_EVENT_LINK_DOWN, 4711291a2b48SSukumar Swaminathan 0, 0); 4712fcf3ce44SJohn Forte } else { 4713fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 4714fcf3ce44SJohn Forte } 4715fcf3ce44SJohn Forte 4716fcf3ce44SJohn Forte return; 4717fcf3ce44SJohn Forte 471882527734SSukumar Swaminathan } /* emlxs_fct_link_down() */ 4719fcf3ce44SJohn Forte 4720fcf3ce44SJohn Forte 4721291a2b48SSukumar Swaminathan /* DMA FUNCTIONS */ 4722fcf3ce44SJohn Forte 4723fcf3ce44SJohn Forte fct_status_t 4724fcf3ce44SJohn Forte emlxs_fct_dmem_init(emlxs_port_t *port) 4725fcf3ce44SJohn Forte { 4726fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 4727fcf3ce44SJohn Forte emlxs_fct_dmem_bucket_t *p; 4728fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *bctl; 4729fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *bc; 4730fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *prev; 4731fcf3ce44SJohn Forte int32_t j; 4732fcf3ce44SJohn Forte int32_t i; 4733fcf3ce44SJohn Forte uint32_t total_mem; 4734fcf3ce44SJohn Forte uint8_t *addr; 4735fcf3ce44SJohn Forte uint8_t *host_addr; 4736fcf3ce44SJohn Forte uint64_t dev_addr; 4737fcf3ce44SJohn Forte ddi_dma_cookie_t cookie; 4738fcf3ce44SJohn Forte uint32_t ncookie; 4739fcf3ce44SJohn Forte uint32_t bsize; 4740fcf3ce44SJohn Forte size_t len; 4741fcf3ce44SJohn Forte char buf[64]; 4742fcf3ce44SJohn Forte ddi_device_acc_attr_t acc; 4743fcf3ce44SJohn Forte 4744fcf3ce44SJohn Forte bzero(&acc, sizeof (acc)); 4745fcf3ce44SJohn Forte acc.devacc_attr_version = DDI_DEVICE_ATTR_V0; 4746fcf3ce44SJohn Forte acc.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC; 4747fcf3ce44SJohn Forte acc.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 4748fcf3ce44SJohn Forte 4749fcf3ce44SJohn Forte p = port->dmem_bucket; 4750fcf3ce44SJohn Forte for (i = 0; i < FCT_MAX_BUCKETS; i++, p++) { 4751fcf3ce44SJohn Forte if (!p->dmem_nbufs) { 4752fcf3ce44SJohn Forte continue; 4753fcf3ce44SJohn Forte } 4754291a2b48SSukumar Swaminathan 4755fcf3ce44SJohn Forte bctl = (emlxs_fct_dmem_bctl_t *)kmem_zalloc(p->dmem_nbufs * 475682527734SSukumar Swaminathan sizeof (emlxs_fct_dmem_bctl_t), KM_NOSLEEP); 4757fcf3ce44SJohn Forte 4758fcf3ce44SJohn Forte if (bctl == NULL) { 4759fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4760fcf3ce44SJohn Forte "emlxs_fct_dmem_init: Unable to allocate bctl."); 4761fcf3ce44SJohn Forte goto alloc_bctl_failed; 4762fcf3ce44SJohn Forte } 4763291a2b48SSukumar Swaminathan 4764fcf3ce44SJohn Forte p->dmem_bctls_mem = bctl; 4765fcf3ce44SJohn Forte 476662379b58SSukumar Swaminathan if (ddi_dma_alloc_handle(hba->dip, &hba->dma_attr_1sg, 4767fcf3ce44SJohn Forte DDI_DMA_SLEEP, 0, &p->dmem_dma_handle) != DDI_SUCCESS) { 4768fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4769fcf3ce44SJohn Forte "emlxs_fct_dmem_init: Unable to allocate handle."); 4770fcf3ce44SJohn Forte goto alloc_handle_failed; 4771fcf3ce44SJohn Forte } 4772fcf3ce44SJohn Forte 4773fcf3ce44SJohn Forte total_mem = p->dmem_buf_size * p->dmem_nbufs; 4774fcf3ce44SJohn Forte 4775fcf3ce44SJohn Forte if (ddi_dma_mem_alloc(p->dmem_dma_handle, total_mem, &acc, 477682527734SSukumar Swaminathan DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, 0, 4777291a2b48SSukumar Swaminathan (caddr_t *)&addr, &len, 4778291a2b48SSukumar Swaminathan &p->dmem_acc_handle) != DDI_SUCCESS) { 4779fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4780fcf3ce44SJohn Forte "emlxs_fct_dmem_init: Unable to allocate memory."); 4781fcf3ce44SJohn Forte goto mem_alloc_failed; 4782fcf3ce44SJohn Forte } 4783fcf3ce44SJohn Forte 4784fcf3ce44SJohn Forte if (ddi_dma_addr_bind_handle(p->dmem_dma_handle, NULL, 4785291a2b48SSukumar Swaminathan (caddr_t)addr, total_mem, 478682527734SSukumar Swaminathan DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, 0, 4787291a2b48SSukumar Swaminathan &cookie, &ncookie) != DDI_SUCCESS) { 4788fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4789fcf3ce44SJohn Forte "emlxs_fct_dmem_init: Unable to bind handle."); 4790fcf3ce44SJohn Forte goto addr_bind_handle_failed; 4791fcf3ce44SJohn Forte } 4792fcf3ce44SJohn Forte 4793fcf3ce44SJohn Forte if (ncookie != 1) { 4794fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4795fcf3ce44SJohn Forte "emlxs_fct_dmem_init: DMEM init failed."); 4796fcf3ce44SJohn Forte goto dmem_init_failed; 4797fcf3ce44SJohn Forte } 4798fcf3ce44SJohn Forte (void) sprintf(buf, "%s%d_bucket%d mutex", DRIVER_NAME, 4799fcf3ce44SJohn Forte hba->ddiinst, i); 4800fcf3ce44SJohn Forte mutex_init(&p->dmem_lock, buf, MUTEX_DRIVER, 4801fcf3ce44SJohn Forte (void *)hba->intr_arg); 4802fcf3ce44SJohn Forte 4803fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4804fcf3ce44SJohn Forte "bufsize=%d cnt=%d", p->dmem_buf_size, p->dmem_nbufs); 4805fcf3ce44SJohn Forte 4806fcf3ce44SJohn Forte host_addr = addr; 4807fcf3ce44SJohn Forte dev_addr = (uint64_t)cookie.dmac_laddress; 4808fcf3ce44SJohn Forte 4809fcf3ce44SJohn Forte p->dmem_host_addr = addr; 4810fcf3ce44SJohn Forte p->dmem_dev_addr = dev_addr; 4811fcf3ce44SJohn Forte p->dmem_bctl_free_list = bctl; 4812fcf3ce44SJohn Forte p->dmem_nbufs_free = p->dmem_nbufs; 4813fcf3ce44SJohn Forte bsize = p->dmem_buf_size; 4814fcf3ce44SJohn Forte 4815fcf3ce44SJohn Forte for (j = 0; j < p->dmem_nbufs; j++) { 4816fcf3ce44SJohn Forte stmf_data_buf_t *db; 4817fcf3ce44SJohn Forte 4818fcf3ce44SJohn Forte db = MODSYM(stmf_alloc) (STMF_STRUCT_DATA_BUF, 0, 0); 4819fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 4820fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 4821fcf3ce44SJohn Forte "stmf_alloc data_buf %p", db); 4822291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 4823fcf3ce44SJohn Forte if (db == NULL) { 4824fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4825291a2b48SSukumar Swaminathan "emlxs_fct_dmem_init: alloc failed."); 4826fcf3ce44SJohn Forte goto dmem_init_failed; 4827fcf3ce44SJohn Forte } 4828fcf3ce44SJohn Forte db->db_port_private = bctl; 4829fcf3ce44SJohn Forte db->db_sglist[0].seg_addr = host_addr; 4830fcf3ce44SJohn Forte db->db_sglist[0].seg_length = bsize; 4831fcf3ce44SJohn Forte db->db_buf_size = bsize; 4832fcf3ce44SJohn Forte db->db_sglist_length = 1; 4833fcf3ce44SJohn Forte 4834fcf3ce44SJohn Forte bctl->bctl_bucket = p; 4835fcf3ce44SJohn Forte bctl->bctl_buf = db; 4836fcf3ce44SJohn Forte bctl->bctl_dev_addr = dev_addr; 4837fcf3ce44SJohn Forte 4838fcf3ce44SJohn Forte host_addr += bsize; 4839fcf3ce44SJohn Forte dev_addr += bsize; 4840fcf3ce44SJohn Forte 4841fcf3ce44SJohn Forte prev = bctl; 4842fcf3ce44SJohn Forte bctl++; 4843fcf3ce44SJohn Forte prev->bctl_next = bctl; 4844fcf3ce44SJohn Forte } 4845fcf3ce44SJohn Forte 4846fcf3ce44SJohn Forte prev->bctl_next = NULL; 4847fcf3ce44SJohn Forte } 4848fcf3ce44SJohn Forte 4849fcf3ce44SJohn Forte return (FCT_SUCCESS); 4850fcf3ce44SJohn Forte 4851fcf3ce44SJohn Forte dmem_failure_loop: 4852fcf3ce44SJohn Forte mutex_destroy(&p->dmem_lock); 4853fcf3ce44SJohn Forte bc = bctl; 4854fcf3ce44SJohn Forte while (bc) { 4855fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 4856fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 4857fcf3ce44SJohn Forte "stmf_free:3 %p", bctl->bctl_buf); 4858291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 4859fcf3ce44SJohn Forte MODSYM(stmf_free) (bc->bctl_buf); 4860fcf3ce44SJohn Forte bc = bc->bctl_next; 4861fcf3ce44SJohn Forte } 4862fcf3ce44SJohn Forte 4863fcf3ce44SJohn Forte dmem_init_failed: 4864fcf3ce44SJohn Forte (void) ddi_dma_unbind_handle(p->dmem_dma_handle); 4865fcf3ce44SJohn Forte 4866fcf3ce44SJohn Forte addr_bind_handle_failed: 4867fcf3ce44SJohn Forte (void) ddi_dma_mem_free(&p->dmem_acc_handle); 4868fcf3ce44SJohn Forte 4869fcf3ce44SJohn Forte mem_alloc_failed: 4870fcf3ce44SJohn Forte (void) ddi_dma_free_handle(&p->dmem_dma_handle); 4871fcf3ce44SJohn Forte 4872fcf3ce44SJohn Forte alloc_handle_failed: 4873fcf3ce44SJohn Forte kmem_free(p->dmem_bctls_mem, 4874fcf3ce44SJohn Forte p->dmem_nbufs * sizeof (emlxs_fct_dmem_bctl_t)); 4875fcf3ce44SJohn Forte 4876fcf3ce44SJohn Forte alloc_bctl_failed: 4877fcf3ce44SJohn Forte if (--i >= 0) { 4878fcf3ce44SJohn Forte p = &port->dmem_bucket[i]; 4879fcf3ce44SJohn Forte bctl = p->dmem_bctl_free_list; 4880fcf3ce44SJohn Forte goto dmem_failure_loop; 4881fcf3ce44SJohn Forte } 4882fcf3ce44SJohn Forte 4883291a2b48SSukumar Swaminathan return (FCT_FAILURE); 4884fcf3ce44SJohn Forte 488582527734SSukumar Swaminathan } /* emlxs_fct_dmem_init() */ 4886fcf3ce44SJohn Forte 4887fcf3ce44SJohn Forte 4888fcf3ce44SJohn Forte void 4889fcf3ce44SJohn Forte emlxs_fct_dmem_fini(emlxs_port_t *port) 4890fcf3ce44SJohn Forte { 4891fcf3ce44SJohn Forte emlxs_fct_dmem_bucket_t *p; 4892fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *bctl; 4893fcf3ce44SJohn Forte uint32_t i; 4894fcf3ce44SJohn Forte 4895fcf3ce44SJohn Forte p = port->dmem_bucket; 4896fcf3ce44SJohn Forte for (i = 0; i < FCT_MAX_BUCKETS; i++, p++) { 4897fcf3ce44SJohn Forte if (!p->dmem_nbufs) { 4898fcf3ce44SJohn Forte continue; 4899fcf3ce44SJohn Forte } 4900291a2b48SSukumar Swaminathan 4901fcf3ce44SJohn Forte bctl = p->dmem_bctl_free_list; 4902fcf3ce44SJohn Forte 4903fcf3ce44SJohn Forte while (bctl) { 4904fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 4905fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 4906fcf3ce44SJohn Forte "stmf_free:4 %p", bctl->bctl_buf); 4907291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 4908fcf3ce44SJohn Forte MODSYM(stmf_free) (bctl->bctl_buf); 4909fcf3ce44SJohn Forte bctl = bctl->bctl_next; 4910fcf3ce44SJohn Forte } 4911fcf3ce44SJohn Forte 4912fcf3ce44SJohn Forte bctl = p->dmem_bctl_free_list; 4913fcf3ce44SJohn Forte 4914fcf3ce44SJohn Forte (void) ddi_dma_unbind_handle(p->dmem_dma_handle); 4915fcf3ce44SJohn Forte (void) ddi_dma_mem_free(&p->dmem_acc_handle); 4916fcf3ce44SJohn Forte (void) ddi_dma_free_handle(&p->dmem_dma_handle); 4917fcf3ce44SJohn Forte 4918fcf3ce44SJohn Forte kmem_free(p->dmem_bctls_mem, 4919fcf3ce44SJohn Forte (p->dmem_nbufs * sizeof (emlxs_fct_dmem_bctl_t))); 4920fcf3ce44SJohn Forte mutex_destroy(&p->dmem_lock); 4921fcf3ce44SJohn Forte } 4922fcf3ce44SJohn Forte 4923fcf3ce44SJohn Forte bzero((uint8_t *)port->dmem_bucket, sizeof (port->dmem_bucket)); 4924fcf3ce44SJohn Forte 4925fcf3ce44SJohn Forte return; 4926fcf3ce44SJohn Forte 492782527734SSukumar Swaminathan } /* emlxs_fct_dmem_fini() */ 4928fcf3ce44SJohn Forte 4929fcf3ce44SJohn Forte 493082527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 4931fcf3ce44SJohn Forte /* ARGSUSED */ 4932fcf3ce44SJohn Forte static stmf_data_buf_t * 4933fcf3ce44SJohn Forte emlxs_fct_dbuf_alloc(fct_local_port_t *fct_port, uint32_t size, 4934fcf3ce44SJohn Forte uint32_t *pminsize, uint32_t flags) 4935fcf3ce44SJohn Forte { 4936fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private; 4937fcf3ce44SJohn Forte emlxs_fct_dmem_bucket_t *p; 4938fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *bctl; 4939fcf3ce44SJohn Forte uint32_t i; 4940fcf3ce44SJohn Forte 4941fcf3ce44SJohn Forte if (size > FCT_DMEM_MAX_BUF_SIZE) { 4942fcf3ce44SJohn Forte size = FCT_DMEM_MAX_BUF_SIZE; 4943fcf3ce44SJohn Forte } 4944291a2b48SSukumar Swaminathan 4945fcf3ce44SJohn Forte p = port->dmem_bucket; 4946fcf3ce44SJohn Forte for (i = 0; i < FCT_MAX_BUCKETS; i++, p++) { 4947fcf3ce44SJohn Forte if (!p->dmem_nbufs) { 4948fcf3ce44SJohn Forte continue; 4949fcf3ce44SJohn Forte } 4950291a2b48SSukumar Swaminathan 4951fcf3ce44SJohn Forte if (p->dmem_buf_size >= size) { 4952fcf3ce44SJohn Forte mutex_enter(&p->dmem_lock); 4953fcf3ce44SJohn Forte if (p->dmem_nbufs_free) { 4954fcf3ce44SJohn Forte if (p->dmem_buf_size < *pminsize) { 4955fcf3ce44SJohn Forte *pminsize = p->dmem_buf_size; 4956fcf3ce44SJohn Forte TGTPORTSTAT.FctNoBuffer++; 4957fcf3ce44SJohn Forte 4958fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, 4959fcf3ce44SJohn Forte &emlxs_fct_api_msg, 4960fcf3ce44SJohn Forte "emlxs_fct_dbuf_alloc: Failed(1)."); 4961fcf3ce44SJohn Forte mutex_exit(&p->dmem_lock); 4962fcf3ce44SJohn Forte return (NULL); 4963fcf3ce44SJohn Forte } 4964291a2b48SSukumar Swaminathan 4965fcf3ce44SJohn Forte bctl = p->dmem_bctl_free_list; 4966fcf3ce44SJohn Forte if (bctl == NULL) { 4967fcf3ce44SJohn Forte mutex_exit(&p->dmem_lock); 4968fcf3ce44SJohn Forte continue; 4969fcf3ce44SJohn Forte } 4970291a2b48SSukumar Swaminathan 4971fcf3ce44SJohn Forte p->dmem_bctl_free_list = bctl->bctl_next; 4972fcf3ce44SJohn Forte p->dmem_nbufs_free--; 4973fcf3ce44SJohn Forte bctl->bctl_buf->db_data_size = size; 4974fcf3ce44SJohn Forte mutex_exit(&p->dmem_lock); 4975fcf3ce44SJohn Forte 4976fcf3ce44SJohn Forte #ifdef FCT_API_TRACE 4977fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 497882527734SSukumar Swaminathan "emlx_fct_buf_alloc: bctl_buf %p: size %d", 4979fcf3ce44SJohn Forte bctl->bctl_buf, size); 4980291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 4981fcf3ce44SJohn Forte 4982fcf3ce44SJohn Forte return (bctl->bctl_buf); 4983fcf3ce44SJohn Forte } 4984fcf3ce44SJohn Forte mutex_exit(&p->dmem_lock); 4985fcf3ce44SJohn Forte 4986fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, 4987fcf3ce44SJohn Forte "emlx_fct_buf_alloc size %d Nothing free bck %d", 4988fcf3ce44SJohn Forte size, i); 4989fcf3ce44SJohn Forte } 4990fcf3ce44SJohn Forte } 4991fcf3ce44SJohn Forte 4992fcf3ce44SJohn Forte *pminsize = 0; 4993fcf3ce44SJohn Forte TGTPORTSTAT.FctNoBuffer++; 4994fcf3ce44SJohn Forte 4995fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 4996fcf3ce44SJohn Forte "emlxs_fct_dbuf_alloc: Failed(2)."); 4997fcf3ce44SJohn Forte 4998fcf3ce44SJohn Forte return (NULL); 4999fcf3ce44SJohn Forte 500082527734SSukumar Swaminathan } /* emlxs_fct_dbuf_alloc() */ 5001fcf3ce44SJohn Forte 5002fcf3ce44SJohn Forte 500382527734SSukumar Swaminathan /* COMSTAR ENTER POINT */ 5004291a2b48SSukumar Swaminathan /*ARGSUSED*/ 5005fcf3ce44SJohn Forte static void 5006fcf3ce44SJohn Forte emlxs_fct_dbuf_free(fct_dbuf_store_t *fds, stmf_data_buf_t *dbuf) 5007fcf3ce44SJohn Forte { 5008fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *bctl = 5009fcf3ce44SJohn Forte (emlxs_fct_dmem_bctl_t *)dbuf->db_port_private; 5010fcf3ce44SJohn Forte emlxs_fct_dmem_bucket_t *p = bctl->bctl_bucket; 5011fcf3ce44SJohn Forte 501282527734SSukumar Swaminathan #ifdef FCT_API_TRACE_1 5013fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg, 5014fcf3ce44SJohn Forte "emlx_fct_buf_free %p", dbuf); 5015291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */ 5016fcf3ce44SJohn Forte 5017fcf3ce44SJohn Forte mutex_enter(&p->dmem_lock); 5018fcf3ce44SJohn Forte bctl->bctl_next = p->dmem_bctl_free_list; 5019fcf3ce44SJohn Forte p->dmem_bctl_free_list = bctl; 5020fcf3ce44SJohn Forte p->dmem_nbufs_free++; 5021fcf3ce44SJohn Forte mutex_exit(&p->dmem_lock); 5022fcf3ce44SJohn Forte 502382527734SSukumar Swaminathan } /* emlxs_fct_dbuf_free() */ 5024fcf3ce44SJohn Forte 5025fcf3ce44SJohn Forte 5026*b3660a96SSukumar Swaminathan static int 5027*b3660a96SSukumar Swaminathan emlxs_fct_dbuf_dma_sync(emlxs_hba_t *hba, stmf_data_buf_t *dbuf, 5028*b3660a96SSukumar Swaminathan uint_t sync_type) 5029fcf3ce44SJohn Forte { 5030fcf3ce44SJohn Forte emlxs_fct_dmem_bctl_t *bctl = 5031fcf3ce44SJohn Forte (emlxs_fct_dmem_bctl_t *)dbuf->db_port_private; 5032fcf3ce44SJohn Forte emlxs_fct_dmem_bucket_t *p = bctl->bctl_bucket; 5033*b3660a96SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5034*b3660a96SSukumar Swaminathan int retval = 0; 5035fcf3ce44SJohn Forte 5036fcf3ce44SJohn Forte (void) ddi_dma_sync(p->dmem_dma_handle, 5037fcf3ce44SJohn Forte (unsigned long)(bctl->bctl_dev_addr - p->dmem_dev_addr), 5038fcf3ce44SJohn Forte dbuf->db_data_size, sync_type); 5039fcf3ce44SJohn Forte 5040*b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 5041*b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, p->dmem_dma_handle) 5042*b3660a96SSukumar Swaminathan != DDI_FM_OK) { 5043*b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 5044*b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 5045*b3660a96SSukumar Swaminathan "emlxs_fct_dbuf_dma_sync: hdl=%p", 5046*b3660a96SSukumar Swaminathan p->dmem_dma_handle); 5047*b3660a96SSukumar Swaminathan retval = 1; 5048*b3660a96SSukumar Swaminathan } 5049*b3660a96SSukumar Swaminathan #endif /* FMA_SUPPORT */ 5050*b3660a96SSukumar Swaminathan 5051*b3660a96SSukumar Swaminathan return (retval); 5052*b3660a96SSukumar Swaminathan 505382527734SSukumar Swaminathan } /* emlxs_fct_dbuf_dma_sync() */ 5054fcf3ce44SJohn Forte 5055fcf3ce44SJohn Forte 5056291a2b48SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 5057