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  *
88f23e9faSHans Rosenfeld  * You can obtain a copy of the license at
98f23e9faSHans Rosenfeld  * http://www.opensource.org/licenses/cddl1.txt.
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 /*
238f23e9faSHans Rosenfeld  * Copyright (c) 2004-2012 Emulex. All rights reserved.
2482527734SSukumar Swaminathan  * Use is subject to license terms.
25*a3170057SPaul Winder  * Copyright 2020 RackTop Systems, Inc.
26fcf3ce44SJohn Forte  */
27fcf3ce44SJohn Forte 
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 
368f23e9faSHans Rosenfeld static void emlxs_fct_memseg_init(emlxs_hba_t *hba);
378f23e9faSHans Rosenfeld 
3882527734SSukumar Swaminathan static fct_status_t emlxs_fct_cmd_acquire(emlxs_port_t *port,
3982527734SSukumar Swaminathan 	fct_cmd_t *fct_cmd, uint16_t fct_state);
4082527734SSukumar Swaminathan static fct_status_t emlxs_fct_cmd_accept(emlxs_port_t *port,
4182527734SSukumar Swaminathan 	fct_cmd_t *fct_cmd, uint16_t fct_state);
4282527734SSukumar Swaminathan static void emlxs_fct_cmd_release(emlxs_port_t *port, fct_cmd_t *fct_cmd,
4382527734SSukumar Swaminathan 	uint16_t fct_state);
44fcf3ce44SJohn Forte 
45291a2b48SSukumar Swaminathan static emlxs_buf_t *emlxs_fct_cmd_init(emlxs_port_t *port,
46a9800bebSGarrett D'Amore     fct_cmd_t *fct_cmd, uint16_t fct_state);
4782527734SSukumar Swaminathan static void emlxs_fct_cmd_done(emlxs_port_t *port, fct_cmd_t *fct_cmd,
4882527734SSukumar Swaminathan 	uint16_t fct_state);
4982527734SSukumar Swaminathan static void emlxs_fct_cmd_post(emlxs_port_t *port, fct_cmd_t *fct_cmd,
5082527734SSukumar Swaminathan 	uint16_t fct_state);
51fcf3ce44SJohn Forte 
5282527734SSukumar Swaminathan static fct_status_t emlxs_fct_flogi_xchg(struct fct_local_port *fct_port,
53fcf3ce44SJohn Forte     struct fct_flogi_xchg *fx);
54fcf3ce44SJohn Forte static fct_status_t emlxs_fct_get_link_info(fct_local_port_t *fct_port,
55fcf3ce44SJohn Forte     fct_link_info_t *link);
56fcf3ce44SJohn Forte static fct_status_t emlxs_fct_deregister_remote_port(fct_local_port_t *fct_port,
57fcf3ce44SJohn Forte     fct_remote_port_t *port_handle);
58fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_cmd(fct_cmd_t *fct_cmd);
59fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_fcp_data(fct_cmd_t *fct_cmd,
60fcf3ce44SJohn Forte     stmf_data_buf_t *dbuf, uint32_t ioflags);
61291a2b48SSukumar Swaminathan static fct_status_t emlxs_fct_send_cmd_rsp(fct_cmd_t *fct_cmd, uint32_t flags);
62291a2b48SSukumar Swaminathan static fct_status_t emlxs_fct_abort(fct_local_port_t *fct_port,
63291a2b48SSukumar Swaminathan     fct_cmd_t *cmd, uint32_t flags);
64fcf3ce44SJohn Forte static void emlxs_fct_ctl(fct_local_port_t *fct_port, int cmd, void *arg);
65fcf3ce44SJohn Forte static fct_status_t emlxs_fct_register_remote_port(fct_local_port_t *fct_port,
66fcf3ce44SJohn Forte     fct_remote_port_t *port_handle, fct_cmd_t *plogi);
67fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_els_cmd(fct_cmd_t *fct_cmd);
68fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_ct_cmd(fct_cmd_t *fct_cmd);
69fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_fcp_status(fct_cmd_t *fct_cmd);
70fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_els_rsp(fct_cmd_t *fct_cmd);
71fcf3ce44SJohn Forte static void emlxs_fct_pkt_comp(fc_packet_t *pkt);
7282527734SSukumar Swaminathan static void emlxs_fct_populate_hba_details(fct_local_port_t *fct_port,
73fcf3ce44SJohn Forte     fct_port_attrs_t *port_attrs);
7482527734SSukumar Swaminathan static fct_status_t emlxs_fct_port_info(uint32_t cmd,
7582527734SSukumar Swaminathan     fct_local_port_t *fct_port, void *arg, uint8_t *buffer, uint32_t *size);
76fcf3ce44SJohn Forte 
77fcf3ce44SJohn Forte static fct_status_t emlxs_fct_dmem_init(emlxs_port_t *port);
78fcf3ce44SJohn Forte static void emlxs_fct_dmem_fini(emlxs_port_t *port);
79fcf3ce44SJohn Forte 
80fcf3ce44SJohn Forte static stmf_data_buf_t *emlxs_fct_dbuf_alloc(fct_local_port_t *fct_port,
81fcf3ce44SJohn Forte     uint32_t size, uint32_t *pminsize, uint32_t flags);
82fcf3ce44SJohn Forte static void emlxs_fct_dbuf_free(fct_dbuf_store_t *fds, stmf_data_buf_t *dbuf);
83fcf3ce44SJohn Forte 
84b3660a96SSukumar Swaminathan static int emlxs_fct_dbuf_dma_sync(emlxs_hba_t *hba, stmf_data_buf_t *dbuf,
85b3660a96SSukumar Swaminathan     uint_t sync_type);
86291a2b48SSukumar Swaminathan static emlxs_buf_t *emlxs_fct_pkt_init(emlxs_port_t *port,
87291a2b48SSukumar Swaminathan     fct_cmd_t *fct_cmd, fc_packet_t *pkt);
88fcf3ce44SJohn Forte 
898f23e9faSHans Rosenfeld static void emlxs_fct_unsol_flush_thread(emlxs_hba_t *hba, void *arg1,
908f23e9faSHans Rosenfeld     void *arg2);
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
emlxs_fct_io_trace(emlxs_port_t * port,fct_cmd_t * fct_cmd,uint32_t data)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 =
523