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.
25a988c0caSRick McNeal * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
26a3170057SPaul Winder * Copyright 2020 RackTop Systems, Inc.
27fcf3ce44SJohn Forte */
28fcf3ce44SJohn Forte
29291a2b48SSukumar Swaminathan #include <emlxs.h>
30fcf3ce44SJohn Forte
31fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT
32fcf3ce44SJohn Forte
33fcf3ce44SJohn Forte
34fcf3ce44SJohn Forte /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
35fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_FCT_C);
36fcf3ce44SJohn Forte
378f23e9faSHans Rosenfeld static void emlxs_fct_memseg_init(emlxs_hba_t *hba);
388f23e9faSHans Rosenfeld
3982527734SSukumar Swaminathan static fct_status_t emlxs_fct_cmd_acquire(emlxs_port_t *port,
4082527734SSukumar Swaminathan fct_cmd_t *fct_cmd, uint16_t fct_state);
4182527734SSukumar Swaminathan static fct_status_t emlxs_fct_cmd_accept(emlxs_port_t *port,
4282527734SSukumar Swaminathan fct_cmd_t *fct_cmd, uint16_t fct_state);
4382527734SSukumar Swaminathan static void emlxs_fct_cmd_release(emlxs_port_t *port, fct_cmd_t *fct_cmd,
4482527734SSukumar Swaminathan uint16_t fct_state);
45fcf3ce44SJohn Forte
46291a2b48SSukumar Swaminathan static emlxs_buf_t *emlxs_fct_cmd_init(emlxs_port_t *port,
47a9800bebSGarrett D'Amore fct_cmd_t *fct_cmd, uint16_t fct_state);
4882527734SSukumar Swaminathan static void emlxs_fct_cmd_done(emlxs_port_t *port, fct_cmd_t *fct_cmd,
4982527734SSukumar Swaminathan uint16_t fct_state);
5082527734SSukumar Swaminathan static void emlxs_fct_cmd_post(emlxs_port_t *port, fct_cmd_t *fct_cmd,
5182527734SSukumar Swaminathan uint16_t fct_state);
52fcf3ce44SJohn Forte
5382527734SSukumar Swaminathan static fct_status_t emlxs_fct_flogi_xchg(struct fct_local_port *fct_port,
54fcf3ce44SJohn Forte struct fct_flogi_xchg *fx);
55fcf3ce44SJohn Forte static fct_status_t emlxs_fct_get_link_info(fct_local_port_t *fct_port,
56fcf3ce44SJohn Forte fct_link_info_t *link);
57fcf3ce44SJohn Forte static fct_status_t emlxs_fct_deregister_remote_port(fct_local_port_t *fct_port,
58fcf3ce44SJohn Forte fct_remote_port_t *port_handle);
59fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_cmd(fct_cmd_t *fct_cmd);
60fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_fcp_data(fct_cmd_t *fct_cmd,
61fcf3ce44SJohn Forte stmf_data_buf_t *dbuf, uint32_t ioflags);
62291a2b48SSukumar Swaminathan static fct_status_t emlxs_fct_send_cmd_rsp(fct_cmd_t *fct_cmd, uint32_t flags);
63291a2b48SSukumar Swaminathan static fct_status_t emlxs_fct_abort(fct_local_port_t *fct_port,
64291a2b48SSukumar Swaminathan fct_cmd_t *cmd, uint32_t flags);
65fcf3ce44SJohn Forte static void emlxs_fct_ctl(fct_local_port_t *fct_port, int cmd, void *arg);
66fcf3ce44SJohn Forte static fct_status_t emlxs_fct_register_remote_port(fct_local_port_t *fct_port,
67fcf3ce44SJohn Forte fct_remote_port_t *port_handle, fct_cmd_t *plogi);
68fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_els_cmd(fct_cmd_t *fct_cmd);
69fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_ct_cmd(fct_cmd_t *fct_cmd);
70fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_fcp_status(fct_cmd_t *fct_cmd);
71fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_els_rsp(fct_cmd_t *fct_cmd);
72fcf3ce44SJohn Forte static void emlxs_fct_pkt_comp(fc_packet_t *pkt);
7382527734SSukumar Swaminathan static void emlxs_fct_populate_hba_details(fct_local_port_t *fct_port,
74fcf3ce44SJohn Forte fct_port_attrs_t *port_attrs);
7582527734SSukumar Swaminathan static fct_status_t emlxs_fct_port_info(uint32_t cmd,
7682527734SSukumar Swaminathan fct_local_port_t *fct_port, void *arg, uint8_t *buffer, uint32_t *size);
77fcf3ce44SJohn Forte
78fcf3ce44SJohn Forte static fct_status_t emlxs_fct_dmem_init(emlxs_port_t *port);
79fcf3ce44SJohn Forte static void emlxs_fct_dmem_fini(emlxs_port_t *port);
80fcf3ce44SJohn Forte
81fcf3ce44SJohn Forte static stmf_data_buf_t *emlxs_fct_dbuf_alloc(fct_local_port_t *fct_port,
82fcf3ce44SJohn Forte uint32_t size, uint32_t *pminsize, uint32_t flags);
83fcf3ce44SJohn Forte static void emlxs_fct_dbuf_free(fct_dbuf_store_t *fds, stmf_data_buf_t *dbuf);
84fcf3ce44SJohn Forte
85b3660a96SSukumar Swaminathan static int emlxs_fct_dbuf_dma_sync(emlxs_hba_t *hba, stmf_data_buf_t *dbuf,
86b3660a96SSukumar Swaminathan uint_t sync_type);
87291a2b48SSukumar Swaminathan static emlxs_buf_t *emlxs_fct_pkt_init(emlxs_port_t *port,
88291a2b48SSukumar Swaminathan fct_cmd_t *fct_cmd, fc_packet_t *pkt);
89fcf3ce44SJohn Forte
908f23e9faSHans Rosenfeld static void emlxs_fct_unsol_flush_thread(emlxs_hba_t *hba, void *arg1,
918f23e9faSHans Rosenfeld void *arg2);
92fcf3ce44SJohn Forte static void emlxs_fct_unsol_flush(emlxs_port_t *port);
9382527734SSukumar Swaminathan static uint32_t emlxs_fct_process_unsol_flogi(emlxs_port_t *port,
9482527734SSukumar Swaminathan CHANNEL *cp, IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
9582527734SSukumar Swaminathan static uint32_t emlxs_fct_process_unsol_plogi(emlxs_port_t *port,
9682527734SSukumar Swaminathan CHANNEL *cp, IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
97fe199829SSukumar Swaminathan static uint32_t emlxs_fct_pkt_abort_txq(emlxs_port_t *port,
98fe199829SSukumar Swaminathan emlxs_buf_t *cmd_sbp);
99fcf3ce44SJohn Forte static fct_status_t emlxs_fct_send_qfull_reply(emlxs_port_t *port,
100fcf3ce44SJohn Forte emlxs_node_t *ndlp, uint16_t xid, uint32_t class, emlxs_fcp_cmd_t *fcp_cmd);
101291a2b48SSukumar Swaminathan
102291a2b48SSukumar Swaminathan #ifdef FCT_IO_TRACE
103291a2b48SSukumar Swaminathan uint8_t *emlxs_iotrace = 0; /* global for mdb */
104291a2b48SSukumar Swaminathan int emlxs_iotrace_cnt = 0;
105291a2b48SSukumar Swaminathan
10682527734SSukumar Swaminathan /*
10782527734SSukumar Swaminathan *
10882527734SSukumar Swaminathan * FCT_CMD (cmd_sbp->fct_state)
10982527734SSukumar Swaminathan *
11082527734SSukumar Swaminathan * STATE LOCK STATUS OWNER
11182527734SSukumar Swaminathan * -----------------------------------------------------------------------------
11282527734SSukumar Swaminathan * EMLXS_FCT_ABORT_DONE Lock Destroyed COMSTAR
11382527734SSukumar Swaminathan * EMLXS_FCT_IO_DONE Lock Destroyed COMSTAR
11482527734SSukumar Swaminathan *
11582527734SSukumar Swaminathan * EMLXS_FCT_CMD_POSTED Lock Released COMSTAR
11682527734SSukumar Swaminathan * EMLXS_FCT_OWNED Lock Released COMSTAR
11782527734SSukumar Swaminathan *
11882527734SSukumar Swaminathan * EMLXS_FCT_CMD_WAITQ Lock Released DRIVER
11982527734SSukumar Swaminathan * EMLXS_FCT_RSP_PENDING Lock Released DRIVER
12082527734SSukumar Swaminathan * EMLXS_FCT_REQ_PENDING Lock Released DRIVER
12182527734SSukumar Swaminathan * EMLXS_FCT_REG_PENDING Lock Released DRIVER
12282527734SSukumar Swaminathan * EMLXS_FCT_DATA_PENDING Lock Released DRIVER
12382527734SSukumar Swaminathan * EMLXS_FCT_STATUS_PENDING Lock Released DRIVER
12482527734SSukumar Swaminathan * EMLXS_FCT_CLOSE_PENDING Lock Released DRIVER
12582527734SSukumar Swaminathan * EMLXS_FCT_ABORT_PENDING Lock Released DRIVER
12682527734SSukumar Swaminathan *
12782527734SSukumar Swaminathan * EMLXS_FCT_FCP_CMD_RECEIVED Transistional, lock held DRIVER
12882527734SSukumar Swaminathan * EMLXS_FCT_ELS_CMD_RECEIVED Transistional, lock held DRIVER
12982527734SSukumar Swaminathan * EMLXS_FCT_SEND_CMD_RSP Transistional, lock held DRIVER
13082527734SSukumar Swaminathan * EMLXS_FCT_SEND_ELS_RSP Transistional, lock held DRIVER
13182527734SSukumar Swaminathan * EMLXS_FCT_SEND_ELS_REQ Transistional, lock held DRIVER
13282527734SSukumar Swaminathan * EMLXS_FCT_SEND_CT_REQ Transistional, lock held DRIVER
13382527734SSukumar Swaminathan * EMLXS_FCT_REG_COMPLETE Transistional, lock held DRIVER
13482527734SSukumar Swaminathan * EMLXS_FCT_SEND_FCP_DATA Transistional, lock held DRIVER
13582527734SSukumar Swaminathan * EMLXS_FCT_SEND_FCP_STATUS Transistional, lock held DRIVER
13682527734SSukumar Swaminathan * EMLXS_FCT_PKT_COMPLETE Transistional, lock held DRIVER
13782527734SSukumar Swaminathan * EMLXS_FCT_PKT_FCPRSP_COMPLETE Transistional, lock held DRIVER
13882527734SSukumar Swaminathan * EMLXS_FCT_PKT_ELSRSP_COMPLETE Transistional, lock held DRIVER
13982527734SSukumar Swaminathan * EMLXS_FCT_PKT_ELSCMD_COMPLETE Transistional, lock held DRIVER
14082527734SSukumar Swaminathan * EMLXS_FCT_PKT_CTCMD_COMPLETE Transistional, lock held DRIVER
14182527734SSukumar Swaminathan * EMLXS_FCT_REQ_COMPLETE Transistional, lock held DRIVER
14282527734SSukumar Swaminathan *
14382527734SSukumar Swaminathan *
14482527734SSukumar Swaminathan * COMSTAR OWNED DRIVER OWNED
14582527734SSukumar Swaminathan * ------------- ---------------------------------------------------
14682527734SSukumar Swaminathan * ------- > @ Accept---- >Release @ Acquire--- >+
14782527734SSukumar Swaminathan * |
14882527734SSukumar Swaminathan * < ------- @ Post/Done< ----Acquire @ Release< ---+
14982527734SSukumar Swaminathan *
15082527734SSukumar Swaminathan * @ :Indicates COMSTAR use of emlxs_fct_abort()
15182527734SSukumar Swaminathan * Abort requests set the EMLXS_FCT_ABORT_INP flag.
15282527734SSukumar Swaminathan *
15382527734SSukumar Swaminathan * Accept :Indicates use of emlxs_fct_cmd_accept()
15482527734SSukumar Swaminathan * Acquire :Indicates use of emlxs_fct_cmd_acquire()
15582527734SSukumar Swaminathan * Post :Indicates use of emlxs_fct_cmd_post()
15682527734SSukumar Swaminathan * Done :Indicates use of emlxs_fct_cmd_done()
15782527734SSukumar Swaminathan */
15882527734SSukumar Swaminathan
159291a2b48SSukumar Swaminathan void
emlxs_fct_io_trace(emlxs_port_t * port,fct_cmd_t * fct_cmd,uint32_t data)160291a2b48SSukumar Swaminathan emlxs_fct_io_trace(emlxs_port_t *port, fct_cmd_t *fct_cmd, uint32_t data)
161291a2b48SSukumar Swaminathan {
162291a2b48SSukumar Swaminathan emlxs_iotrace_t *iop = port->iotrace;
163291a2b48SSukumar Swaminathan uint16_t iotrace_cnt;
164291a2b48SSukumar Swaminathan uint16_t iotrace_index;
165291a2b48SSukumar Swaminathan int i;
166291a2b48SSukumar Swaminathan
167291a2b48SSukumar Swaminathan if (!iop) {
168291a2b48SSukumar Swaminathan return;
169291a2b48SSukumar Swaminathan }
170291a2b48SSukumar Swaminathan
171291a2b48SSukumar Swaminathan mutex_enter(&port->iotrace_mtx);
172291a2b48SSukumar Swaminathan iotrace_cnt = port->iotrace_cnt;
173291a2b48SSukumar Swaminathan iotrace_index = port->iotrace_index;
174291a2b48SSukumar Swaminathan
175291a2b48SSukumar Swaminathan switch (data) {
176291a2b48SSukumar Swaminathan
177291a2b48SSukumar Swaminathan /* New entry */
178291a2b48SSukumar Swaminathan case EMLXS_FCT_ELS_CMD_RECEIVED:
179291a2b48SSukumar Swaminathan case EMLXS_FCT_FCP_CMD_RECEIVED:
180291a2b48SSukumar Swaminathan case EMLXS_FCT_SEND_ELS_REQ:
181291a2b48SSukumar Swaminathan case EMLXS_FCT_SEND_CT_REQ:
182291a2b48SSukumar Swaminathan for (i = 0; i < iotrace_cnt; i++) {
183291a2b48SSukumar Swaminathan if ((iop->fct_cmd == fct_cmd) &&
184291a2b48SSukumar Swaminathan (iop->trc[0] != (uint8_t)(0)))
185291a2b48SSukumar Swaminathan break;
186291a2b48SSukumar Swaminathan iop++;
187291a2b48SSukumar Swaminathan }
188291a2b48SSukumar Swaminathan if (i < iotrace_cnt) {
189291a2b48SSukumar Swaminathan /* New entry already exists */
190291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx);
191291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
192291a2b48SSukumar Swaminathan "IOTRACE: New entry already exists: fct_cmd: %p",
193291a2b48SSukumar Swaminathan fct_cmd);
194291a2b48SSukumar Swaminathan return;
195291a2b48SSukumar Swaminathan }
196291a2b48SSukumar Swaminathan iop = port->iotrace + iotrace_index;
197291a2b48SSukumar Swaminathan for (i = 0; i < iotrace_cnt; i++) {
198291a2b48SSukumar Swaminathan if (iop->trc[0] == (uint8_t)(0))
199291a2b48SSukumar Swaminathan break;
200291a2b48SSukumar Swaminathan
201291a2b48SSukumar Swaminathan iop++;
202291a2b48SSukumar Swaminathan if (iop == (port->iotrace + iotrace_cnt))
203291a2b48SSukumar Swaminathan iop = port->iotrace;
204291a2b48SSukumar Swaminathan }
205291a2b48SSukumar Swaminathan if (i >= iotrace_cnt) {
206291a2b48SSukumar Swaminathan /* No new slots available */
207291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx);
208291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
209291a2b48SSukumar Swaminathan "IOTRACE: No new slots: fct_cmd: %p data: %d",
210291a2b48SSukumar Swaminathan fct_cmd, data);
211291a2b48SSukumar Swaminathan return;
212291a2b48SSukumar Swaminathan }
213291a2b48SSukumar Swaminathan port->iotrace_index++;
214291a2b48SSukumar Swaminathan if (port->iotrace_index >= iotrace_cnt)
215291a2b48SSukumar Swaminathan port->iotrace_index = 0;
216291a2b48SSukumar Swaminathan
217291a2b48SSukumar Swaminathan bzero((uint8_t *)iop, sizeof (emlxs_iotrace_t));
218291a2b48SSukumar Swaminathan iop->fct_cmd = fct_cmd;
219291a2b48SSukumar Swaminathan iop->xri = fct_cmd->cmd_rxid;
220291a2b48SSukumar Swaminathan iop->marker = 0xff;
221291a2b48SSukumar Swaminathan iop->trc[0] = 2;
222291a2b48SSukumar Swaminathan iop->trc[1] = data;
223291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx);
224291a2b48SSukumar Swaminathan return;
225291a2b48SSukumar Swaminathan }
226291a2b48SSukumar Swaminathan
227291a2b48SSukumar Swaminathan for (i = 0; i < iotrace_cnt; i++) {
228291a2b48SSukumar Swaminathan if ((iop->fct_cmd == fct_cmd) &&
229291a2b48SSukumar Swaminathan (iop->trc[0] != (uint8_t)(0)))
230291a2b48SSukumar Swaminathan break;
231291a2b48SSukumar Swaminathan iop++;
232291a2b48SSukumar Swaminathan }
233291a2b48SSukumar Swaminathan if (i >= iotrace_cnt) {
234291a2b48SSukumar Swaminathan /* Cannot find existing slot for fct_cmd */
235291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx);
236291a2b48SSukumar Swaminathan
237291a2b48SSukumar Swaminathan if ((data != EMLXS_FCT_REG_PENDING) &&
238291a2b48SSukumar Swaminathan (data != EMLXS_FCT_REG_COMPLETE)) {
239291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
240291a2b48SSukumar Swaminathan "IOTRACE: Missing slot: fct_cmd: %p data: %d",
241291a2b48SSukumar Swaminathan fct_cmd, data);
242291a2b48SSukumar Swaminathan }
243291a2b48SSukumar Swaminathan return;
244291a2b48SSukumar Swaminathan }
245291a2b48SSukumar Swaminathan
246291a2b48SSukumar Swaminathan if (iop->trc[0] >= MAX_IO_TRACE) {
247291a2b48SSukumar Swaminathan /* trc overrun for fct_cmd */
248291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx);
249291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
250291a2b48SSukumar Swaminathan "IOTRACE: trc overrun slot: fct_cmd: %p data: %d",
251291a2b48SSukumar Swaminathan fct_cmd, data);
252291a2b48SSukumar Swaminathan return;
253291a2b48SSukumar Swaminathan }
254291a2b48SSukumar Swaminathan
255291a2b48SSukumar Swaminathan if (iop->xri != fct_cmd->cmd_rxid) {
256291a2b48SSukumar Swaminathan /* xri mismatch for fct_cmd */
257291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx);
258291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
259291a2b48SSukumar Swaminathan "IOTRACE: xri mismatch %x != %x: fct_cmd: %p data: %d",
260291a2b48SSukumar Swaminathan iop->xri, fct_cmd->cmd_rxid, fct_cmd, data);
261291a2b48SSukumar Swaminathan return;
262291a2b48SSukumar Swaminathan }
263291a2b48SSukumar Swaminathan
264291a2b48SSukumar Swaminathan iop->trc[iop->trc[0]] = data;
265291a2b48SSukumar Swaminathan if ((data == EMLXS_FCT_IO_DONE) || (data == EMLXS_FCT_ABORT_DONE)) {
26682527734SSukumar Swaminathan /* IOCB ULPCOMMAND is saved after EMLXS_FCT_IOCB_ISSUED */
26782527734SSukumar Swaminathan if (iop->trc[iop->trc[0]-1] == EMLXS_FCT_IOCB_ISSUED) {
268291a2b48SSukumar Swaminathan iop->trc[0]++;
26982527734SSukumar Swaminathan } else {
270291a2b48SSukumar Swaminathan iop->trc[0] = 0;
271*e2d1a434SCarsten Grzemba }
27282527734SSukumar Swaminathan } else {
273291a2b48SSukumar Swaminathan iop->trc[0]++;
27482527734SSukumar Swaminathan }
275291a2b48SSukumar Swaminathan mutex_exit(&port->iotrace_mtx);
27682527734SSukumar Swaminathan
27782527734SSukumar Swaminathan return;
27882527734SSukumar Swaminathan
27982527734SSukumar Swaminathan } /* emlxs_fct_io_trace() */
280291a2b48SSukumar Swaminathan #endif /* FCT_IO_TRACE */
281fcf3ce44SJohn Forte
282fcf3ce44SJohn Forte #ifdef MODSYM_SUPPORT
283fcf3ce44SJohn Forte
284e51761e0SSukumar Swaminathan extern int
emlxs_fct_modopen()285fcf3ce44SJohn Forte emlxs_fct_modopen()
286fcf3ce44SJohn Forte {
287fcf3ce44SJohn Forte int err;
288fcf3ce44SJohn Forte
28982527734SSukumar Swaminathan mutex_enter(&emlxs_device.lock);
29082527734SSukumar Swaminathan
29182527734SSukumar Swaminathan if (emlxs_modsym.fct_modopen) {
29282527734SSukumar Swaminathan mutex_exit(&emlxs_device.lock);
29382527734SSukumar Swaminathan return (0);
294fcf3ce44SJohn Forte }
295291a2b48SSukumar Swaminathan
29682527734SSukumar Swaminathan emlxs_modsym.fct_modopen++;
29782527734SSukumar Swaminathan
298fcf3ce44SJohn Forte /* Comstar (fct) */
299fcf3ce44SJohn Forte err = 0;
300fcf3ce44SJohn Forte emlxs_modsym.mod_fct = ddi_modopen("drv/fct", KRTLD_MODE_FIRST, &err);
301fcf3ce44SJohn Forte if (!emlxs_modsym.mod_fct) {
302fcf3ce44SJohn Forte
303fcf3ce44SJohn Forte cmn_err(CE_WARN, "?%s: ddi_modopen drv/fct failed: err %d",
304fcf3ce44SJohn Forte DRIVER_NAME, err);
305fcf3ce44SJohn Forte goto failed;
306fcf3ce44SJohn Forte }
307291a2b48SSukumar Swaminathan
308fcf3ce44SJohn Forte /* Comstar (stmf) */
309fcf3ce44SJohn Forte err = 0;
310291a2b48SSukumar Swaminathan emlxs_modsym.mod_stmf =
311291a2b48SSukumar Swaminathan ddi_modopen("drv/stmf", KRTLD_MODE_FIRST, &err);
312fcf3ce44SJohn Forte if (!emlxs_modsym.mod_stmf) {
313fcf3ce44SJohn Forte
314fcf3ce44SJohn Forte cmn_err(CE_WARN, "?%s: ddi_modopen drv/stmf failed: err %d",
315fcf3ce44SJohn Forte DRIVER_NAME, err);
316fcf3ce44SJohn Forte goto failed;
317fcf3ce44SJohn Forte }
318291a2b48SSukumar Swaminathan
319fcf3ce44SJohn Forte err = 0;
320fcf3ce44SJohn Forte /* Check if the fct fct_alloc is present */
321291a2b48SSukumar Swaminathan emlxs_modsym.fct_alloc = (void *(*)())ddi_modsym(emlxs_modsym.mod_fct,
322fcf3ce44SJohn Forte "fct_alloc", &err);
323fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_alloc == NULL) {
324fcf3ce44SJohn Forte cmn_err(CE_WARN,
325fcf3ce44SJohn Forte "?%s: drv/fct: fct_alloc not present", DRIVER_NAME);
326fcf3ce44SJohn Forte goto failed;
327fcf3ce44SJohn Forte }
328291a2b48SSukumar Swaminathan
329fcf3ce44SJohn Forte err = 0;
330fcf3ce44SJohn Forte /* Check if the fct fct_free is present */
331291a2b48SSukumar Swaminathan emlxs_modsym.fct_free = (void (*)())ddi_modsym(emlxs_modsym.mod_fct,
332fcf3ce44SJohn Forte "fct_free", &err);
333fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_free == NULL) {
334fcf3ce44SJohn Forte cmn_err(CE_WARN,
335fcf3ce44SJohn Forte "?%s: drv/fct: fct_free not present", DRIVER_NAME);
336fcf3ce44SJohn Forte goto failed;
337fcf3ce44SJohn Forte }
338291a2b48SSukumar Swaminathan
339fcf3ce44SJohn Forte err = 0;
340fcf3ce44SJohn Forte /* Check if the fct fct_scsi_task_alloc is present */
341291a2b48SSukumar Swaminathan emlxs_modsym.fct_scsi_task_alloc =
342291a2b48SSukumar Swaminathan (void *(*)(void *, uint16_t, uint32_t, uint8_t *,
343291a2b48SSukumar Swaminathan uint16_t, uint16_t))ddi_modsym(emlxs_modsym.mod_fct,
344291a2b48SSukumar Swaminathan "fct_scsi_task_alloc", &err);
345fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_scsi_task_alloc == NULL) {
346fcf3ce44SJohn Forte cmn_err(CE_WARN,
347fcf3ce44SJohn Forte "?%s: drv/fct: fct_scsi_task_alloc not present",
348fcf3ce44SJohn Forte DRIVER_NAME);
349fcf3ce44SJohn Forte goto failed;
350fcf3ce44SJohn Forte }
351291a2b48SSukumar Swaminathan
352fcf3ce44SJohn Forte err = 0;
353fcf3ce44SJohn Forte /* Check if the fct fct_register_local_port is present */
354291a2b48SSukumar Swaminathan emlxs_modsym.fct_register_local_port =
355291a2b48SSukumar Swaminathan (int (*)())ddi_modsym(emlxs_modsym.mod_fct,
356291a2b48SSukumar Swaminathan "fct_register_local_port", &err);
357fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_register_local_port == NULL) {
358fcf3ce44SJohn Forte cmn_err(CE_WARN,
359fcf3ce44SJohn Forte "?%s: drv/fct: fct_register_local_port not present",
360fcf3ce44SJohn Forte DRIVER_NAME);
361fcf3ce44SJohn Forte goto failed;
362fcf3ce44SJohn Forte }
363291a2b48SSukumar Swaminathan
364fcf3ce44SJohn Forte err = 0;
365fcf3ce44SJohn Forte /* Check if the fct fct_deregister_local_port is present */
366291a2b48SSukumar Swaminathan emlxs_modsym.fct_deregister_local_port =
367291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct,
368291a2b48SSukumar Swaminathan "fct_deregister_local_port", &err);
369fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_deregister_local_port == NULL) {
370fcf3ce44SJohn Forte cmn_err(CE_WARN,
371fcf3ce44SJohn Forte "?%s: drv/fct: fct_deregister_local_port not present",
372fcf3ce44SJohn Forte DRIVER_NAME);
373fcf3ce44SJohn Forte goto failed;
374fcf3ce44SJohn Forte }
375291a2b48SSukumar Swaminathan
376fcf3ce44SJohn Forte err = 0;
377fcf3ce44SJohn Forte /* Check if the fct fct_handle_event is present */
378291a2b48SSukumar Swaminathan emlxs_modsym.fct_handle_event =
379291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, "fct_handle_event",
380291a2b48SSukumar Swaminathan &err);
381fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_handle_event == NULL) {
382fcf3ce44SJohn Forte cmn_err(CE_WARN,
383291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_handle_event not present",
384291a2b48SSukumar Swaminathan DRIVER_NAME);
385fcf3ce44SJohn Forte goto failed;
386fcf3ce44SJohn Forte }
387291a2b48SSukumar Swaminathan
388fcf3ce44SJohn Forte err = 0;
389fcf3ce44SJohn Forte /* Check if the fct fct_post_rcvd_cmd is present */
390291a2b48SSukumar Swaminathan emlxs_modsym.fct_post_rcvd_cmd =
391291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, "fct_post_rcvd_cmd",
392291a2b48SSukumar Swaminathan &err);
393fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_post_rcvd_cmd == NULL) {
394fcf3ce44SJohn Forte cmn_err(CE_WARN,
395291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_post_rcvd_cmd not present",
396291a2b48SSukumar Swaminathan DRIVER_NAME);
397fcf3ce44SJohn Forte goto failed;
398fcf3ce44SJohn Forte }
399fcf3ce44SJohn Forte err = 0;
400fcf3ce44SJohn Forte /* Check if the fct fct_alloc is present */
401291a2b48SSukumar Swaminathan emlxs_modsym.fct_ctl = (void (*)())ddi_modsym(emlxs_modsym.mod_fct,
402fcf3ce44SJohn Forte "fct_ctl", &err);
403fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_ctl == NULL) {
404fcf3ce44SJohn Forte cmn_err(CE_WARN,
405fcf3ce44SJohn Forte "?%s: drv/fct: fct_ctl not present", DRIVER_NAME);
406fcf3ce44SJohn Forte goto failed;
407fcf3ce44SJohn Forte }
408fcf3ce44SJohn Forte err = 0;
409291a2b48SSukumar Swaminathan /* Check if the fct fct_queue_cmd_for_termination is present */
410291a2b48SSukumar Swaminathan emlxs_modsym.fct_queue_cmd_for_termination =
411291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct,
412291a2b48SSukumar Swaminathan "fct_queue_cmd_for_termination", &err);
413291a2b48SSukumar Swaminathan if ((void *)emlxs_modsym.fct_queue_cmd_for_termination == NULL) {
414291a2b48SSukumar Swaminathan cmn_err(CE_WARN,
415291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_queue_cmd_for_termination not present",
416291a2b48SSukumar Swaminathan DRIVER_NAME);
417291a2b48SSukumar Swaminathan goto failed;
418291a2b48SSukumar Swaminathan }
419291a2b48SSukumar Swaminathan err = 0;
420fcf3ce44SJohn Forte /* Check if the fct fct_send_response_done is present */
421291a2b48SSukumar Swaminathan emlxs_modsym.fct_send_response_done =
422291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct,
423291a2b48SSukumar Swaminathan "fct_send_response_done", &err);
424fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_send_response_done == NULL) {
425fcf3ce44SJohn Forte cmn_err(CE_WARN,
426fcf3ce44SJohn Forte "?%s: drv/fct: fct_send_response_done not present",
427fcf3ce44SJohn Forte DRIVER_NAME);
428fcf3ce44SJohn Forte goto failed;
429fcf3ce44SJohn Forte }
430fcf3ce44SJohn Forte err = 0;
431fcf3ce44SJohn Forte /* Check if the fct fct_send_cmd_done is present */
432291a2b48SSukumar Swaminathan emlxs_modsym.fct_send_cmd_done =
433291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct, "fct_send_cmd_done",
434291a2b48SSukumar Swaminathan &err);
435fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_send_cmd_done == NULL) {
436fcf3ce44SJohn Forte cmn_err(CE_WARN,
437291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_send_cmd_done not present",
438291a2b48SSukumar Swaminathan DRIVER_NAME);
439fcf3ce44SJohn Forte goto failed;
440fcf3ce44SJohn Forte }
441fcf3ce44SJohn Forte err = 0;
442fcf3ce44SJohn Forte /* Check if the fct fct_scsi_xfer_data_done is present */
443291a2b48SSukumar Swaminathan emlxs_modsym.fct_scsi_data_xfer_done =
444291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct,
445291a2b48SSukumar Swaminathan "fct_scsi_data_xfer_done", &err);
446fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_scsi_data_xfer_done == NULL) {
447fcf3ce44SJohn Forte cmn_err(CE_WARN,
448fcf3ce44SJohn Forte "?%s: drv/fct: fct_scsi_data_xfer_done not present",
449fcf3ce44SJohn Forte DRIVER_NAME);
450fcf3ce44SJohn Forte goto failed;
451fcf3ce44SJohn Forte }
452fcf3ce44SJohn Forte err = 0;
453fcf3ce44SJohn Forte /* Check if the fct fct_port_shutdown is present */
454291a2b48SSukumar Swaminathan emlxs_modsym.fct_port_shutdown =
455291a2b48SSukumar Swaminathan (fct_status_t(*)())ddi_modsym(emlxs_modsym.mod_fct,
456291a2b48SSukumar Swaminathan "fct_port_shutdown", &err);
457fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_port_shutdown == NULL) {
458fcf3ce44SJohn Forte cmn_err(CE_WARN,
459291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_port_shutdown not present",
460291a2b48SSukumar Swaminathan DRIVER_NAME);
461fcf3ce44SJohn Forte goto failed;
462fcf3ce44SJohn Forte }
463291a2b48SSukumar Swaminathan
464fcf3ce44SJohn Forte err = 0;
465fcf3ce44SJohn Forte /* Check if the fct fct_port_initialize is present */
466291a2b48SSukumar Swaminathan emlxs_modsym.fct_port_initialize =
467291a2b48SSukumar Swaminathan (fct_status_t(*)())ddi_modsym(emlxs_modsym.mod_fct,
468291a2b48SSukumar Swaminathan "fct_port_initialize", &err);
469fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_port_initialize == NULL) {
470fcf3ce44SJohn Forte cmn_err(CE_WARN,
471fcf3ce44SJohn Forte "?%s: drv/fct: fct_port_initialize not present",
472fcf3ce44SJohn Forte DRIVER_NAME);
473fcf3ce44SJohn Forte goto failed;
474fcf3ce44SJohn Forte }
475291a2b48SSukumar Swaminathan
476291a2b48SSukumar Swaminathan err = 0;
477291a2b48SSukumar Swaminathan /* Check if the fct fct_cmd_fca_aborted is present */
478291a2b48SSukumar Swaminathan emlxs_modsym.fct_cmd_fca_aborted =
479291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_fct,
480291a2b48SSukumar Swaminathan "fct_cmd_fca_aborted", &err);
481291a2b48SSukumar Swaminathan if ((void *)emlxs_modsym.fct_cmd_fca_aborted == NULL) {
482291a2b48SSukumar Swaminathan cmn_err(CE_WARN,
483291a2b48SSukumar Swaminathan "?%s: drv/fct: fct_cmd_fca_aborted not present",
484291a2b48SSukumar Swaminathan DRIVER_NAME);
485291a2b48SSukumar Swaminathan goto failed;
486291a2b48SSukumar Swaminathan }
487291a2b48SSukumar Swaminathan
488fcf3ce44SJohn Forte err = 0;
489fcf3ce44SJohn Forte /* Check if the fct fct_handle_rcvd_flogi is present */
490291a2b48SSukumar Swaminathan emlxs_modsym.fct_handle_rcvd_flogi =
491291a2b48SSukumar Swaminathan (fct_status_t(*)())ddi_modsym(emlxs_modsym.mod_fct,
492291a2b48SSukumar Swaminathan "fct_handle_rcvd_flogi", &err);
493fcf3ce44SJohn Forte if ((void *)emlxs_modsym.fct_handle_rcvd_flogi == NULL) {
494fcf3ce44SJohn Forte cmn_err(CE_WARN,
495fcf3ce44SJohn Forte "?%s: drv/fct: fct_handle_rcvd_flogi not present",
496fcf3ce44SJohn Forte DRIVER_NAME);
497fcf3ce44SJohn Forte goto failed;
498fcf3ce44SJohn Forte }
499291a2b48SSukumar Swaminathan
500fcf3ce44SJohn Forte /* Comstar (stmf) */
501fcf3ce44SJohn Forte err = 0;
502fcf3ce44SJohn Forte /* Check if the stmf stmf_alloc is present */
503291a2b48SSukumar Swaminathan emlxs_modsym.stmf_alloc =
504291a2b48SSukumar Swaminathan (void *(*)())ddi_modsym(emlxs_modsym.mod_stmf, "stmf_alloc",
505291a2b48SSukumar Swaminathan &err);
506fcf3ce44SJohn Forte if ((void *)emlxs_modsym.stmf_alloc == NULL) {
507fcf3ce44SJohn Forte cmn_err(CE_WARN,
508fcf3ce44SJohn Forte "?%s: drv/stmf: stmf_alloc not present", DRIVER_NAME);
509fcf3ce44SJohn Forte goto failed;
510fcf3ce44SJohn Forte }
511291a2b48SSukumar Swaminathan
512fcf3ce44SJohn Forte err = 0;
513fcf3ce44SJohn Forte /* Check if the stmf stmf_free is present */
514291a2b48SSukumar Swaminathan emlxs_modsym.stmf_free = (void (*)())ddi_modsym(emlxs_modsym.mod_stmf,
515fcf3ce44SJohn Forte "stmf_free", &err);
516fcf3ce44SJohn Forte if ((void *)emlxs_modsym.stmf_free == NULL) {
517fcf3ce44SJohn Forte cmn_err(CE_WARN,
518fcf3ce44SJohn Forte "?%s: drv/stmf: stmf_free not present", DRIVER_NAME);
519fcf3ce44SJohn Forte goto failed;
520fcf3ce44SJohn Forte }
521291a2b48SSukumar Swaminathan
522fcf3ce44SJohn Forte err = 0;
523fcf3ce44SJohn Forte /* Check if the stmf stmf_deregister_port_provider is present */
524fcf3ce44SJohn Forte emlxs_modsym.stmf_deregister_port_provider =
525291a2b48SSukumar Swaminathan (void (*)())ddi_modsym(emlxs_modsym.mod_stmf,
526fcf3ce44SJohn Forte "stmf_deregister_port_provider", &err);
527fcf3ce44SJohn Forte if ((void *)emlxs_modsym.stmf_deregister_port_provider == NULL) {
528fcf3ce44SJohn Forte cmn_err(CE_WARN,
529fcf3ce44SJohn Forte "?%s: drv/stmf: stmf_deregister_port_provider not present",
530fcf3ce44SJohn Forte DRIVER_NAME);
531fcf3ce44SJohn Forte goto failed;
532fcf3ce44SJohn Forte }
533291a2b48SSukumar Swaminathan
534fcf3ce44SJohn Forte err = 0;
535fcf3ce44SJohn Forte /* Check if the stmf stmf_register_port_provider is present */
536fcf3ce44SJohn Forte emlxs_modsym.stmf_register_port_provider =
537291a2b48SSukumar Swaminathan (int (*)())ddi_modsym(emlxs_modsym.mod_stmf,
538fcf3ce44SJohn Forte "stmf_register_port_provider", &err);
539fcf3ce44SJohn Forte if ((void *)emlxs_modsym.stmf_register_port_provider == NULL) {
540fcf3ce44SJohn Forte cmn_err(CE_WARN,
541fcf3ce44SJohn Forte "?%s: drv/stmf: stmf_register_port_provider not present",
542fcf3ce44SJohn Forte DRIVER_NAME);
543fcf3ce44SJohn Forte goto failed;
544fcf3ce44SJohn Forte }
54582527734SSukumar Swaminathan
54682527734SSukumar Swaminathan mutex_exit(&emlxs_device.lock);
54782527734SSukumar Swaminathan return (0);
548fcf3ce44SJohn Forte
549fcf3ce44SJohn Forte failed:
55082527734SSukumar Swaminathan
55182527734SSukumar Swaminathan mutex_exit(&emlxs_device.lock);
552fcf3ce44SJohn Forte emlxs_fct_modclose();
55382527734SSukumar Swaminathan return (1);
554fcf3ce44SJohn Forte
55582527734SSukumar Swaminathan } /* emlxs_fct_modopen() */
556fcf3ce44SJohn Forte
557fcf3ce44SJohn Forte
558fcf3ce44SJohn Forte extern void
emlxs_fct_modclose()559fcf3ce44SJohn Forte emlxs_fct_modclose()
560fcf3ce44SJohn Forte {
56182527734SSukumar Swaminathan mutex_enter(&emlxs_device.lock);
56282527734SSukumar Swaminathan
56382527734SSukumar Swaminathan if (emlxs_modsym.fct_modopen == 0) {
56482527734SSukumar Swaminathan mutex_exit(&emlxs_device.lock);
56582527734SSukumar Swaminathan return;
56682527734SSukumar Swaminathan }
56782527734SSukumar Swaminathan
56882527734SSukumar Swaminathan emlxs_modsym.fct_modopen--;
56982527734SSukumar Swaminathan
57082527734SSukumar Swaminathan if (emlxs_modsym.fct_modopen) {
57182527734SSukumar Swaminathan mutex_exit(&emlxs_device.lock);
57282527734SSukumar Swaminathan return;
57382527734SSukumar Swaminathan }
574fcf3ce44SJohn Forte
575fcf3ce44SJohn Forte if (emlxs_modsym.mod_fct) {
576fcf3ce44SJohn Forte (void) ddi_modclose(emlxs_modsym.mod_fct);
577fcf3ce44SJohn Forte emlxs_modsym.mod_fct = 0;
578fcf3ce44SJohn Forte }
579291a2b48SSukumar Swaminathan
580fcf3ce44SJohn Forte if (emlxs_modsym.mod_stmf) {
581fcf3ce44SJohn Forte (void) ddi_modclose(emlxs_modsym.mod_stmf);
582fcf3ce44SJohn Forte emlxs_modsym.mod_stmf = 0;
583fcf3ce44SJohn Forte }
584291a2b48SSukumar Swaminathan
585fcf3ce44SJohn Forte emlxs_modsym.fct_alloc = NULL;
586fcf3ce44SJohn Forte emlxs_modsym.fct_free = NULL;
587fcf3ce44SJohn Forte emlxs_modsym.fct_scsi_task_alloc = NULL;
588fcf3ce44SJohn Forte emlxs_modsym.fct_register_local_port = NULL;
589fcf3ce44SJohn Forte emlxs_modsym.fct_deregister_local_port = NULL;
590fcf3ce44SJohn Forte emlxs_modsym.fct_handle_event = NULL;
591fcf3ce44SJohn Forte emlxs_modsym.fct_ctl = NULL;
592291a2b48SSukumar Swaminathan emlxs_modsym.fct_queue_cmd_for_termination = NULL;
593fcf3ce44SJohn Forte emlxs_modsym.fct_send_response_done = NULL;
594fcf3ce44SJohn Forte emlxs_modsym.fct_send_cmd_done = NULL;
595fcf3ce44SJohn Forte emlxs_modsym.fct_scsi_data_xfer_done = NULL;
596fcf3ce44SJohn Forte emlxs_modsym.fct_port_shutdown = NULL;
597fcf3ce44SJohn Forte emlxs_modsym.fct_port_initialize = NULL;
598291a2b48SSukumar Swaminathan emlxs_modsym.fct_cmd_fca_aborted = NULL;
599fcf3ce44SJohn Forte emlxs_modsym.fct_handle_rcvd_flogi = NULL;
600fcf3ce44SJohn Forte
601fcf3ce44SJohn Forte emlxs_modsym.stmf_alloc = NULL;
602fcf3ce44SJohn Forte emlxs_modsym.stmf_free = NULL;
603fcf3ce44SJohn Forte emlxs_modsym.stmf_deregister_port_provider = NULL;
604fcf3ce44SJohn Forte emlxs_modsym.stmf_register_port_provider = NULL;
605fcf3ce44SJohn Forte
60682527734SSukumar Swaminathan mutex_exit(&emlxs_device.lock);
60782527734SSukumar Swaminathan
60882527734SSukumar Swaminathan } /* emlxs_fct_modclose() */
609291a2b48SSukumar Swaminathan
610291a2b48SSukumar Swaminathan #endif /* MODSYM_SUPPORT */
611291a2b48SSukumar Swaminathan
612e2ca2865SSukumar Swaminathan /*
613e2ca2865SSukumar Swaminathan * This routine is called to handle an unsol FLOGI exchange
614e2ca2865SSukumar Swaminathan * fx save
615e2ca2865SSukumar Swaminathan * 0 1 Process or save port->fx
616e2ca2865SSukumar Swaminathan * 0 0 Process or reject port->fx
617e2ca2865SSukumar Swaminathan * 1 1 Process port->fx, Process or save fx
618e2ca2865SSukumar Swaminathan * 1 0 Process or reject port->fx, Process or reject fx
619e2ca2865SSukumar Swaminathan */
620291a2b48SSukumar Swaminathan static void
emlxs_fct_handle_unsol_flogi(emlxs_port_t * port,fct_flogi_xchg_t * fx,uint32_t save)621e2ca2865SSukumar Swaminathan emlxs_fct_handle_unsol_flogi(emlxs_port_t *port, fct_flogi_xchg_t *fx,
622e2ca2865SSukumar Swaminathan uint32_t save)
623291a2b48SSukumar Swaminathan {
624e2ca2865SSukumar Swaminathan emlxs_hba_t *hba = HBA;
625291a2b48SSukumar Swaminathan fct_status_t status;
626291a2b48SSukumar Swaminathan IOCBQ iocbq;
627e2ca2865SSukumar Swaminathan fct_flogi_xchg_t fxchg;
628e2ca2865SSukumar Swaminathan
629e2ca2865SSukumar Swaminathan begin:
630e2ca2865SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK);
631e2ca2865SSukumar Swaminathan
632e2ca2865SSukumar Swaminathan /* Check if there is an old saved FLOGI */
633e2ca2865SSukumar Swaminathan if (port->fx.fx_op) {
634e2ca2865SSukumar Swaminathan /* Get it now */
635e2ca2865SSukumar Swaminathan bcopy(&port->fx, &fxchg, sizeof (fct_flogi_xchg_t));
636e2ca2865SSukumar Swaminathan
637e2ca2865SSukumar Swaminathan if (fx) {
638e2ca2865SSukumar Swaminathan /* Save new FLOGI */
639e2ca2865SSukumar Swaminathan bcopy(fx, &port->fx, sizeof (fct_flogi_xchg_t));
640e2ca2865SSukumar Swaminathan
641e2ca2865SSukumar Swaminathan /* Reject old stale FLOGI */
642e2ca2865SSukumar Swaminathan fx = &fxchg;
643e2ca2865SSukumar Swaminathan goto reject_it;
644e2ca2865SSukumar Swaminathan
645e2ca2865SSukumar Swaminathan } else {
646e2ca2865SSukumar Swaminathan bzero(&port->fx, sizeof (fct_flogi_xchg_t));
647e2ca2865SSukumar Swaminathan fx = &fxchg;
648e2ca2865SSukumar Swaminathan }
649e2ca2865SSukumar Swaminathan
650e2ca2865SSukumar Swaminathan } else if (!fx) {
651e2ca2865SSukumar Swaminathan /* Nothing to do, just return */
652e2ca2865SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK);
653e2ca2865SSukumar Swaminathan return;
654e2ca2865SSukumar Swaminathan }
655e2ca2865SSukumar Swaminathan
656e2ca2865SSukumar Swaminathan /* We have a valid FLOGI here */
657e2ca2865SSukumar Swaminathan /* There is no saved FLOGI at this point either */
658e2ca2865SSukumar Swaminathan
659e2ca2865SSukumar Swaminathan /* Check if COMSTAR is ready to accept it */
660e2ca2865SSukumar Swaminathan if (port->fct_flags & FCT_STATE_LINK_UP_ACKED) {
661e2ca2865SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK);
662291a2b48SSukumar Swaminathan
663291a2b48SSukumar Swaminathan bzero((uint8_t *)&iocbq, sizeof (IOCBQ));
664e2ca2865SSukumar Swaminathan iocbq.iocb.un.elsreq.remoteID = fx->fx_sid;
665e2ca2865SSukumar Swaminathan iocbq.iocb.un.elsreq.myID = fx->fx_did;
666e2ca2865SSukumar Swaminathan iocbq.iocb.ULPCONTEXT = (uint16_t)fx->rsvd2;
667e2ca2865SSukumar Swaminathan fx->rsvd2 = 0; /* Clear the reserved field now */
668291a2b48SSukumar Swaminathan
669e2ca2865SSukumar Swaminathan status = MODSYM(fct_handle_rcvd_flogi) (port->fct_port, fx);
670291a2b48SSukumar Swaminathan
671291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE
672291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
673e2ca2865SSukumar Swaminathan "fct_handle_rcvd_flogi %p: status=%x",
674e2ca2865SSukumar Swaminathan port->fct_port, status);
675291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
676291a2b48SSukumar Swaminathan
677291a2b48SSukumar Swaminathan if (status == FCT_SUCCESS) {
678e2ca2865SSukumar Swaminathan if (fx->fx_op == ELS_OP_ACC) {
679291a2b48SSukumar Swaminathan (void) emlxs_els_reply(port, &iocbq,
680291a2b48SSukumar Swaminathan ELS_CMD_ACC, ELS_CMD_FLOGI, 0, 0);
681291a2b48SSukumar Swaminathan
682e2ca2865SSukumar Swaminathan } else { /* ELS_OP_LSRJT */
683291a2b48SSukumar Swaminathan (void) emlxs_els_reply(port, &iocbq,
684e2ca2865SSukumar Swaminathan ELS_CMD_LS_RJT, ELS_CMD_FLOGI,
685e2ca2865SSukumar Swaminathan fx->fx_rjt_reason, fx->fx_rjt_expl);
686291a2b48SSukumar Swaminathan }
687291a2b48SSukumar Swaminathan } else {
688291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
689e2ca2865SSukumar Swaminathan "FLOGI: sid=%x xid=%x. "
690e2ca2865SSukumar Swaminathan "fct_handle_rcvd_flogi failed. Rejecting.",
691e2ca2865SSukumar Swaminathan fx->fx_sid, iocbq.iocb.ULPCONTEXT);
692291a2b48SSukumar Swaminathan
693e2ca2865SSukumar Swaminathan (void) emlxs_els_reply(port, &iocbq,
694e2ca2865SSukumar Swaminathan ELS_CMD_LS_RJT, ELS_CMD_FLOGI,
695e2ca2865SSukumar Swaminathan LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
696291a2b48SSukumar Swaminathan }
697291a2b48SSukumar Swaminathan
698e2ca2865SSukumar Swaminathan return;
699291a2b48SSukumar Swaminathan }
700fcf3ce44SJohn Forte
701e2ca2865SSukumar Swaminathan if (save) {
702e2ca2865SSukumar Swaminathan /* Save FLOGI for later */
703e2ca2865SSukumar Swaminathan bcopy(fx, &port->fx, sizeof (fct_flogi_xchg_t));
704e2ca2865SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK);
705291a2b48SSukumar Swaminathan return;
706fcf3ce44SJohn Forte }
707291a2b48SSukumar Swaminathan
708e2ca2865SSukumar Swaminathan reject_it:
709291a2b48SSukumar Swaminathan
710e2ca2865SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK);
711fcf3ce44SJohn Forte
712e2ca2865SSukumar Swaminathan if (port->fct_flags & FCT_STATE_LINK_UP) {
713e2ca2865SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
714e2ca2865SSukumar Swaminathan "FLOGI: sid=%x xid=%x. Stale. Rejecting.",
715e2ca2865SSukumar Swaminathan fx->fx_sid, fx->rsvd2);
716fcf3ce44SJohn Forte
717e2ca2865SSukumar Swaminathan bzero((uint8_t *)&iocbq, sizeof (IOCBQ));
718e2ca2865SSukumar Swaminathan iocbq.iocb.un.elsreq.remoteID = fx->fx_sid;
719e2ca2865SSukumar Swaminathan iocbq.iocb.un.elsreq.myID = fx->fx_did;
720e2ca2865SSukumar Swaminathan iocbq.iocb.ULPCONTEXT = fx->rsvd2;
721291a2b48SSukumar Swaminathan
722e2ca2865SSukumar Swaminathan (void) emlxs_els_reply(port, &iocbq,
723e2ca2865SSukumar Swaminathan ELS_CMD_LS_RJT, ELS_CMD_FLOGI,
724e2ca2865SSukumar Swaminathan LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
725fcf3ce44SJohn Forte
726e2ca2865SSukumar Swaminathan /* If we have an FLOGI saved, try sending it now */
727e2ca2865SSukumar Swaminathan if (port->fx.fx_op) {
728e2ca2865SSukumar Swaminathan fx = NULL;
729e2ca2865SSukumar Swaminathan goto begin;
730e2ca2865SSukumar Swaminathan }
731291a2b48SSukumar Swaminathan
732e2ca2865SSukumar Swaminathan } else {
733e2ca2865SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
734e2ca2865SSukumar Swaminathan "FLOGI: sid=%x xid=%x. Link down. "
735e2ca2865SSukumar Swaminathan "Dropping.",
736e2ca2865SSukumar Swaminathan fx->fx_sid, fx->rsvd2);
737291a2b48SSukumar Swaminathan }
73882527734SSukumar Swaminathan
739fcf3ce44SJohn Forte return;
740fcf3ce44SJohn Forte
741e2ca2865SSukumar Swaminathan } /* emlxs_fct_handle_unsol_flogi() */
742fcf3ce44SJohn Forte
743fcf3ce44SJohn Forte
7448f23e9faSHans Rosenfeld /* ARGSUSED */
7458f23e9faSHans Rosenfeld static void
emlxs_fct_unsol_flush_thread(emlxs_hba_t * hba,void * arg1,void * arg2)7468f23e9faSHans Rosenfeld emlxs_fct_unsol_flush_thread(emlxs_hba_t *hba, void *arg1, void *arg2)
7478f23e9faSHans Rosenfeld {
7488f23e9faSHans Rosenfeld emlxs_port_t *port = (emlxs_port_t *)arg1;
7498f23e9faSHans Rosenfeld
7508f23e9faSHans Rosenfeld emlxs_fct_unsol_flush(port);
7518f23e9faSHans Rosenfeld return;
7528f23e9faSHans Rosenfeld
7538f23e9faSHans Rosenfeld } /* emlxs_fct_unsol_flush_thread() */
7548f23e9faSHans Rosenfeld
7558f23e9faSHans Rosenfeld
756fcf3ce44SJohn Forte /* This is called at port online and offline */
757fcf3ce44SJohn Forte static void
emlxs_fct_unsol_flush(emlxs_port_t * port)758fcf3ce44SJohn Forte emlxs_fct_unsol_flush(emlxs_port_t *port)
759fcf3ce44SJohn Forte {
760fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
761fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp;
762fcf3ce44SJohn Forte emlxs_buf_t *next;
763fcf3ce44SJohn Forte fct_cmd_t *fct_cmd;
76482527734SSukumar Swaminathan fct_status_t rval;
765e2ca2865SSukumar Swaminathan uint32_t cmd_code;
766fcf3ce44SJohn Forte
767fcf3ce44SJohn Forte if (!port->fct_port) {
768fcf3ce44SJohn Forte return;
769fcf3ce44SJohn Forte }
770291a2b48SSukumar Swaminathan
771e2ca2865SSukumar Swaminathan /* First handle any pending FLOGI */
772e2ca2865SSukumar Swaminathan emlxs_fct_handle_unsol_flogi(port, NULL, 0);
773291a2b48SSukumar Swaminathan
7748f23e9faSHans Rosenfeld if ((port->fct_flags & FCT_STATE_LINK_UP_ACKED) &&
7758f23e9faSHans Rosenfeld !(port->fct_flags & FCT_STATE_FLOGI_CMPL)) {
7768f23e9faSHans Rosenfeld return;
7778f23e9faSHans Rosenfeld }
7788f23e9faSHans Rosenfeld
779e2ca2865SSukumar Swaminathan /* Wait queue */
780fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK);
781fcf3ce44SJohn Forte cmd_sbp = port->fct_wait_head;
782fcf3ce44SJohn Forte port->fct_wait_head = NULL;
783fcf3ce44SJohn Forte port->fct_wait_tail = NULL;
784fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK);
785fcf3ce44SJohn Forte
786291a2b48SSukumar Swaminathan /*
787291a2b48SSukumar Swaminathan * Next process any outstanding ELS commands. It doesn't
788291a2b48SSukumar Swaminathan * matter if the Link is up or not, always post them to FCT.
789291a2b48SSukumar Swaminathan */
790fcf3ce44SJohn Forte while (cmd_sbp) {
791fcf3ce44SJohn Forte next = cmd_sbp->next;
792fcf3ce44SJohn Forte fct_cmd = cmd_sbp->fct_cmd;
793fcf3ce44SJohn Forte
794e2ca2865SSukumar Swaminathan cmd_code = (fct_cmd->cmd_oxid << ELS_CMD_SHIFT);
795e2ca2865SSukumar Swaminathan
79682527734SSukumar Swaminathan /* Reacquire ownership of the fct_cmd */
79782527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, 0);
79882527734SSukumar Swaminathan if (rval) {
79982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
8008f23e9faSHans Rosenfeld "fct_unsol_flush: %s: sid=%x xid=%x "
801e2ca2865SSukumar Swaminathan "Unable to reacquire fct_cmd.",
802e2ca2865SSukumar Swaminathan emlxs_elscmd_xlate(cmd_code),
803e2ca2865SSukumar Swaminathan fct_cmd->cmd_rxid, fct_cmd->cmd_rportid);
80482527734SSukumar Swaminathan
80582527734SSukumar Swaminathan cmd_sbp = next;
80682527734SSukumar Swaminathan continue;
80782527734SSukumar Swaminathan }
80882527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */
80982527734SSukumar Swaminathan
810291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
8118f23e9faSHans Rosenfeld "Posting %s: sid=%x xid=%x %p",
812e2ca2865SSukumar Swaminathan emlxs_elscmd_xlate(cmd_code),
813e2ca2865SSukumar Swaminathan fct_cmd->cmd_rportid, fct_cmd->cmd_rxid,
814e2ca2865SSukumar Swaminathan fct_cmd);
815fcf3ce44SJohn Forte
81682527734SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
81782527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
818fcf3ce44SJohn Forte
819fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
820291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
8218f23e9faSHans Rosenfeld "fct_post_rcvd_cmd:2 %p:%p portid x%x", fct_cmd, cmd_sbp,
822291a2b48SSukumar Swaminathan fct_cmd->cmd_lportid);
823291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
82482527734SSukumar Swaminathan
825291a2b48SSukumar Swaminathan MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0);
826fcf3ce44SJohn Forte
827fcf3ce44SJohn Forte cmd_sbp = next;
828fcf3ce44SJohn Forte
82982527734SSukumar Swaminathan } /* while () */
830fcf3ce44SJohn Forte
831fcf3ce44SJohn Forte return;
832fcf3ce44SJohn Forte
83382527734SSukumar Swaminathan } /* emlxs_fct_unsol_flush() */
834fcf3ce44SJohn Forte
835fcf3ce44SJohn Forte
836fcf3ce44SJohn Forte int
emlxs_is_digit(uint8_t chr)837fcf3ce44SJohn Forte emlxs_is_digit(uint8_t chr)
838fcf3ce44SJohn Forte {
839fcf3ce44SJohn Forte if ((chr >= '0') && (chr <= '9')) {
840fcf3ce44SJohn Forte return (1);
841fcf3ce44SJohn Forte }
842291a2b48SSukumar Swaminathan
843fcf3ce44SJohn Forte return (0);
844fcf3ce44SJohn Forte
84582527734SSukumar Swaminathan } /* emlxs_is_digit */
846fcf3ce44SJohn Forte
847fcf3ce44SJohn Forte
848fcf3ce44SJohn Forte /*
849fcf3ce44SJohn Forte * Convert an ASCII decimal numeric string to integer.
850fcf3ce44SJohn Forte * Negation character '-' is not handled.
851fcf3ce44SJohn Forte */
8528f23e9faSHans Rosenfeld static uint32_t
emlxs_str_atoi(uint8_t * string)853fcf3ce44SJohn Forte emlxs_str_atoi(uint8_t *string)
854fcf3ce44SJohn Forte {
855fcf3ce44SJohn Forte uint32_t num = 0;
856fcf3ce44SJohn Forte int i = 0;
857fcf3ce44SJohn Forte
858fcf3ce44SJohn Forte while (string[i]) {
859fcf3ce44SJohn Forte if (!emlxs_is_digit(string[i])) {
860fcf3ce44SJohn Forte return (num);
861fcf3ce44SJohn Forte }
862291a2b48SSukumar Swaminathan
863fcf3ce44SJohn Forte num = num * 10 + (string[i++] - '0');
864fcf3ce44SJohn Forte }
865fcf3ce44SJohn Forte
866fcf3ce44SJohn Forte return (num);
867fcf3ce44SJohn Forte
86882527734SSukumar Swaminathan } /* emlxs_str_atoi() */
869fcf3ce44SJohn Forte
870fcf3ce44SJohn Forte
8718f23e9faSHans Rosenfeld extern uint32_t
emlxs_fct_init(emlxs_hba_t * hba)872fcf3ce44SJohn Forte emlxs_fct_init(emlxs_hba_t *hba)
873fcf3ce44SJohn Forte {
874fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT;
875fcf3ce44SJohn Forte
876fcf3ce44SJohn Forte /* Check if COMSTAR is present */
877fcf3ce44SJohn Forte if (((void *)MODSYM(stmf_alloc) == NULL) ||
878291a2b48SSukumar Swaminathan ((void *)MODSYM(fct_alloc) == NULL)) {
879fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
8808f23e9faSHans Rosenfeld "Comstar not present.");
8818f23e9faSHans Rosenfeld return (1);
882fcf3ce44SJohn Forte }
883291a2b48SSukumar Swaminathan
8848f23e9faSHans Rosenfeld return (0);
885291a2b48SSukumar Swaminathan
88682527734SSukumar Swaminathan } /* emlxs_fct_init() */
887fcf3ce44SJohn Forte
888fcf3ce44SJohn Forte
889fcf3ce44SJohn Forte extern void
emlxs_fct_attach(emlxs_hba_t * hba)890fcf3ce44SJohn Forte emlxs_fct_attach(emlxs_hba_t *hba)
891fcf3ce44SJohn Forte {
892fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT;
893fcf3ce44SJohn Forte uint32_t vpi;
894fcf3ce44SJohn Forte
8958f23e9faSHans Rosenfeld if (!(port->flag & EMLXS_TGT_ENABLED)) {
896fcf3ce44SJohn Forte return;
897fcf3ce44SJohn Forte }
898291a2b48SSukumar Swaminathan
899fcf3ce44SJohn Forte /* Bind the physical port */
900fcf3ce44SJohn Forte emlxs_fct_bind_port(port);
901fcf3ce44SJohn Forte
902fcf3ce44SJohn Forte /* Bind virtual ports */
903fcf3ce44SJohn Forte if (hba->flag & FC_NPIV_ENABLED) {
90482527734SSukumar Swaminathan for (vpi = 1; vpi <= hba->vpi_high; vpi++) {
905fcf3ce44SJohn Forte port = &VPORT(vpi);
906fcf3ce44SJohn Forte
9078f23e9faSHans Rosenfeld if (!(port->flag & EMLXS_PORT_ENABLED)) {
908fcf3ce44SJohn Forte continue;
909fcf3ce44SJohn Forte }
910291a2b48SSukumar Swaminathan
911fcf3ce44SJohn Forte emlxs_fct_bind_port(port);
912fcf3ce44SJohn Forte }
913fcf3ce44SJohn Forte }
914291a2b48SSukumar Swaminathan
915fcf3ce44SJohn Forte return;
916fcf3ce44SJohn Forte
91782527734SSukumar Swaminathan } /* emlxs_fct_attach() */
918fcf3ce44SJohn Forte
919fcf3ce44SJohn Forte
920fcf3ce44SJohn Forte extern void
emlxs_fct_detach(emlxs_hba_t * hba)921fcf3ce44SJohn Forte emlxs_fct_detach(emlxs_hba_t *hba)
922fcf3ce44SJohn Forte {
923fcf3ce44SJohn Forte uint32_t i;
924fcf3ce44SJohn Forte emlxs_port_t *vport;
925fcf3ce44SJohn Forte
9268f23e9faSHans Rosenfeld for (i = 0; i < MAX_VPORTS; i++) {
9278f23e9faSHans Rosenfeld vport = &VPORT(i);
928291a2b48SSukumar Swaminathan
9298f23e9faSHans Rosenfeld if (!(vport->flag & EMLXS_PORT_ENABLED)) {
9308f23e9faSHans Rosenfeld continue;
931fcf3ce44SJohn Forte }
932fcf3ce44SJohn Forte
9338f23e9faSHans Rosenfeld emlxs_fct_unbind_port(vport);
934fcf3ce44SJohn Forte }
9358f23e9faSHans Rosenfeld
936291a2b48SSukumar Swaminathan #ifdef FCT_IO_TRACE
9378f23e9faSHans Rosenfeld {
9388f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT;
939291a2b48SSukumar Swaminathan
9408f23e9faSHans Rosenfeld mutex_destroy(&port->iotrace_mtx);
9418f23e9faSHans Rosenfeld if (port->iotrace) {
9428f23e9faSHans Rosenfeld kmem_free(port->iotrace,
9438f23e9faSHans Rosenfeld (port->iotrace_cnt * sizeof (emlxs_iotrace_t)));
944291a2b48SSukumar Swaminathan }
9458f23e9faSHans Rosenfeld port->iotrace = NULL;
9468f23e9faSHans Rosenfeld }
947291a2b48SSukumar Swaminathan #endif /* FCT_IO_TRACE */
948291a2b48SSukumar Swaminathan
949fcf3ce44SJohn Forte return;
950fcf3ce44SJohn Forte
95182527734SSukumar Swaminathan } /* emlxs_fct_detach() */
952fcf3ce44SJohn Forte
953fcf3ce44SJohn Forte
954fcf3ce44SJohn Forte extern void
emlxs_fct_unbind_port(emlxs_port_t * port)955fcf3ce44SJohn Forte emlxs_fct_unbind_port(emlxs_port_t *port)
956fcf3ce44SJohn Forte {
957fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
958fcf3ce44SJohn Forte char node_name[32];
959fcf3ce44SJohn Forte
960fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK);
9618f23e9faSHans Rosenfeld
9628f23e9faSHans Rosenfeld if (!(port->flag & EMLXS_TGT_BOUND)) {
963fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK);
964fcf3ce44SJohn Forte return;
965fcf3ce44SJohn Forte }
966291a2b48SSukumar Swaminathan
967fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
9688f23e9faSHans Rosenfeld "fct_unbind_port: port=%d", port->vpi);
969fcf3ce44SJohn Forte
970fcf3ce44SJohn Forte /* Destroy & flush all port nodes, if they exist */
971fcf3ce44SJohn Forte if (port->node_count) {
9728f23e9faSHans Rosenfeld (void) EMLXS_SLI_UNREG_NODE(port, NULL, NULL, NULL, NULL);
973fcf3ce44SJohn Forte }
974291a2b48SSukumar Swaminathan
9758f23e9faSHans Rosenfeld port->flag &= ~EMLXS_TGT_BOUND;
9768f23e9faSHans Rosenfeld port->flag &= ~EMLXS_TGT_ENABLED;
977fcf3ce44SJohn Forte hba->num_of_ports--;
978fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK);
979fcf3ce44SJohn Forte
980fcf3ce44SJohn Forte if (port->fct_port) {
981fcf3ce44SJohn Forte emlxs_fct_link_down(port);
982fcf3ce44SJohn Forte emlxs_fct_unsol_flush(port);
983fcf3ce44SJohn Forte
984fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
985fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
986fcf3ce44SJohn Forte "fct_deregister_local_port %p", port->fct_port);
987291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
988fcf3ce44SJohn Forte MODSYM(fct_deregister_local_port) (port->fct_port);
989fcf3ce44SJohn Forte
990fcf3ce44SJohn Forte if (port->fct_port->port_fds) {
991fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
992fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
993fcf3ce44SJohn Forte "fct_free:3 %p", port->fct_port->port_fds);
994291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
995fcf3ce44SJohn Forte MODSYM(fct_free) (port->fct_port->port_fds);
996fcf3ce44SJohn Forte port->fct_port->port_fds = NULL;
997fcf3ce44SJohn Forte }
998fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
999fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1000fcf3ce44SJohn Forte "fct_free:4 %p", port->fct_port);
1001291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
1002fcf3ce44SJohn Forte MODSYM(fct_free) (port->fct_port);
1003fcf3ce44SJohn Forte port->fct_port = NULL;
1004fcf3ce44SJohn Forte port->fct_flags = 0;
1005fcf3ce44SJohn Forte }
1006291a2b48SSukumar Swaminathan
1007fcf3ce44SJohn Forte if (port->port_provider) {
1008fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
1009fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1010291a2b48SSukumar Swaminathan "stmf_deregister_port_provider:1 %p",
1011291a2b48SSukumar Swaminathan port->port_provider);
1012291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
1013fcf3ce44SJohn Forte MODSYM(stmf_deregister_port_provider) (port->port_provider);
1014fcf3ce44SJohn Forte
1015fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
1016fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1017fcf3ce44SJohn Forte "stmf_free:1 %p", port->port_provider);
1018291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
1019fcf3ce44SJohn Forte MODSYM(stmf_free) (port->port_provider);
1020fcf3ce44SJohn Forte port->port_provider = NULL;
1021fcf3ce44SJohn Forte }
1022291a2b48SSukumar Swaminathan
10238f23e9faSHans Rosenfeld if (port->fct_memseg) {
1024fcf3ce44SJohn Forte emlxs_fct_dmem_fini(port);
1025fcf3ce44SJohn Forte }
1026291a2b48SSukumar Swaminathan
10278f23e9faSHans Rosenfeld (void) snprintf(node_name, sizeof (node_name), "%d,%d:SFCT",
10288f23e9faSHans Rosenfeld hba->ddiinst, port->vpi);
1029fcf3ce44SJohn Forte (void) ddi_remove_minor_node(hba->dip, node_name);
1030fcf3ce44SJohn Forte
1031fcf3ce44SJohn Forte return;
1032fcf3ce44SJohn Forte
103382527734SSukumar Swaminathan } /* emlxs_fct_unbind_port() */
1034fcf3ce44SJohn Forte
1035fcf3ce44SJohn Forte
1036fcf3ce44SJohn Forte extern void
emlxs_fct_bind_port(emlxs_port_t * port)1037fcf3ce44SJohn Forte emlxs_fct_bind_port(emlxs_port_t *port)
1038fcf3ce44SJohn Forte {
1039fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
1040fcf3ce44SJohn Forte fct_local_port_t *fct_port;
1041fcf3ce44SJohn Forte uint32_t flag = 0;
1042fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG;
1043fcf3ce44SJohn Forte fct_dbuf_store_t *fds;
1044fcf3ce44SJohn Forte char node_name[32];
104582527734SSukumar Swaminathan uint8_t *bptr;
1046fcf3ce44SJohn Forte
10478f23e9faSHans Rosenfeld if (!(port->flag & EMLXS_TGT_ENABLED)) {
1048fcf3ce44SJohn Forte return;
1049fcf3ce44SJohn Forte }
1050291a2b48SSukumar Swaminathan
10518f23e9faSHans Rosenfeld mutex_enter(&EMLXS_PORT_LOCK);
10528f23e9faSHans Rosenfeld
10538f23e9faSHans Rosenfeld if (port->flag & EMLXS_TGT_BOUND) {
1054fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK);
1055fcf3ce44SJohn Forte return;
1056fcf3ce44SJohn Forte }
1057291a2b48SSukumar Swaminathan
1058fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
10598f23e9faSHans Rosenfeld "fct_bind_port: port=%d", port->vpi);
1060fcf3ce44SJohn Forte
1061fcf3ce44SJohn Forte /* Perform generic port initialization */
1062fcf3ce44SJohn Forte emlxs_port_init(port);
1063fcf3ce44SJohn Forte
1064fcf3ce44SJohn Forte if (port->vpi == 0) {
10658f23e9faSHans Rosenfeld (void) snprintf(port->cfd_name, sizeof (port->cfd_name),
10668f23e9faSHans Rosenfeld "%s%d", DRIVER_NAME, hba->ddiinst);
1067fcf3ce44SJohn Forte } else {
10688f23e9faSHans Rosenfeld (void) snprintf(port->cfd_name, sizeof (port->cfd_name),
10698f23e9faSHans Rosenfeld "%s%d.%d", DRIVER_NAME, hba->ddiinst, port->vpi);
1070fcf3ce44SJohn Forte }
1071fcf3ce44SJohn Forte
1072fcf3ce44SJohn Forte if (emlxs_fct_dmem_init(port) != FCT_SUCCESS) {
1073fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
10748f23e9faSHans Rosenfeld "fct_bind_port: Unable to allocate fct memory.");
1075fcf3ce44SJohn Forte goto failed;
1076fcf3ce44SJohn Forte }
1077fcf3ce44SJohn Forte flag |= 0x00000001;
1078fcf3ce44SJohn Forte
1079291a2b48SSukumar Swaminathan port->port_provider =
1080291a2b48SSukumar Swaminathan (stmf_port_provider_t *)
1081fcf3ce44SJohn Forte MODSYM(stmf_alloc) (STMF_STRUCT_PORT_PROVIDER, 0, 0);
1082fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
1083fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1084fcf3ce44SJohn Forte "stmf_alloc port_provider %p", port->port_provider);
1085291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
1086fcf3ce44SJohn Forte
1087fcf3ce44SJohn Forte if (port->port_provider == NULL) {
1088fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
10898f23e9faSHans Rosenfeld "fct_bind_port: Unable to allocate port provider.");
1090fcf3ce44SJohn Forte goto failed;
1091fcf3ce44SJohn Forte }
1092fcf3ce44SJohn Forte flag |= 0x00000002;
1093fcf3ce44SJohn Forte
1094fcf3ce44SJohn Forte port->port_provider->pp_portif_rev = PORTIF_REV_1;
1095fcf3ce44SJohn Forte port->port_provider->pp_name = port->cfd_name;
1096fcf3ce44SJohn Forte port->port_provider->pp_provider_private = port;
1097fcf3ce44SJohn Forte
1098fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
1099fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1100fcf3ce44SJohn Forte "stmf_register_port_provider %p", port->port_provider);
1101291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
1102fcf3ce44SJohn Forte /* register port provider with framework */
1103291a2b48SSukumar Swaminathan if (MODSYM(stmf_register_port_provider) (port->port_provider) !=
1104291a2b48SSukumar Swaminathan STMF_SUCCESS) {
1105fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
11068f23e9faSHans Rosenfeld "fct_bind_port: Unable to register port provider.");
1107fcf3ce44SJohn Forte goto failed;
1108fcf3ce44SJohn Forte }
1109fcf3ce44SJohn Forte flag |= 0x00000004;
1110fcf3ce44SJohn Forte
1111291a2b48SSukumar Swaminathan port->fct_port =
1112291a2b48SSukumar Swaminathan (fct_local_port_t *)MODSYM(fct_alloc) (FCT_STRUCT_LOCAL_PORT, 0,
1113291a2b48SSukumar Swaminathan 0);
1114fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
1115fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1116fcf3ce44SJohn Forte "fct_alloc fct_port %p", port->fct_port);
1117291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
1118fcf3ce44SJohn Forte
1119fcf3ce44SJohn Forte if (port->fct_port == NULL) {
1120fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
11218f23e9faSHans Rosenfeld "fct_bind_port: Unable to allocate fct port.");
1122fcf3ce44SJohn Forte goto failed;
1123fcf3ce44SJohn Forte }
1124fcf3ce44SJohn Forte flag |= 0x00000008;
1125fcf3ce44SJohn Forte
1126291a2b48SSukumar Swaminathan port->fct_port->port_fds =
1127291a2b48SSukumar Swaminathan (fct_dbuf_store_t *)MODSYM(fct_alloc) (FCT_STRUCT_DBUF_STORE, 0,
1128291a2b48SSukumar Swaminathan 0);
1129fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
1130fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1131fcf3ce44SJohn Forte "fct_alloc port_fds %p", port->fct_port->port_fds);
1132291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
1133fcf3ce44SJohn Forte
1134fcf3ce44SJohn Forte if (port->fct_port->port_fds == NULL) {
1135fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
11368f23e9faSHans Rosenfeld "fct_bind_port: Unable to allocate dbuf store.");
1137fcf3ce44SJohn Forte goto failed;
1138fcf3ce44SJohn Forte }
1139fcf3ce44SJohn Forte flag |= 0x00000010;
1140fcf3ce44SJohn Forte
11418f23e9faSHans Rosenfeld (void) snprintf(node_name, sizeof (node_name), "%d,%d:SFCT",
11428f23e9faSHans Rosenfeld hba->ddiinst, port->vpi);
1143291a2b48SSukumar Swaminathan if (ddi_create_minor_node(hba->dip, node_name, S_IFCHR, hba->ddiinst,
1144291a2b48SSukumar Swaminathan NULL, 0) == DDI_FAILURE) {
1145fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
1146fcf3ce44SJohn Forte "Unable to create SFCT device node.");
1147fcf3ce44SJohn Forte goto failed;
1148fcf3ce44SJohn Forte }
1149fcf3ce44SJohn Forte flag |= 0x00000020;
1150fcf3ce44SJohn Forte
1151fcf3ce44SJohn Forte /* Intialize */
1152fcf3ce44SJohn Forte fct_port = port->fct_port;
1153162fafd3Sallan fct_port->port_fca_version = FCT_FCA_MODREV_1;
1154fcf3ce44SJohn Forte fct_port->port_fca_private = port;
1155fcf3ce44SJohn Forte fct_port->port_fca_abort_timeout = 30 * 1000; /* 30 seconds */
1156fcf3ce44SJohn Forte
1157fcf3ce44SJohn Forte bcopy((uint8_t *)&port->wwpn, (uint8_t *)fct_port->port_pwwn, 8);
1158fcf3ce44SJohn Forte bcopy((uint8_t *)&port->wwnn, (uint8_t *)fct_port->port_nwwn, 8);
1159fcf3ce44SJohn Forte
116082527734SSukumar Swaminathan bptr = (uint8_t *)&port->wwnn;
11618f23e9faSHans Rosenfeld (void) snprintf(fct_port->port_nwwn_str, FC_WWN_BUFLEN,
116282527734SSukumar Swaminathan "%02x%02x%02x%02x%02x%02x%02x%02x",
116382527734SSukumar Swaminathan bptr[0], bptr[1], bptr[2], bptr[3],
116482527734SSukumar Swaminathan bptr[4], bptr[5], bptr[6], bptr[7]);
116582527734SSukumar Swaminathan
116682527734SSukumar Swaminathan bptr = (uint8_t *)&port->wwpn;
11678f23e9faSHans Rosenfeld (void) snprintf(fct_port->port_pwwn_str, FC_WWN_BUFLEN,
116882527734SSukumar Swaminathan "%02x%02x%02x%02x%02x%02x%02x%02x",
116982527734SSukumar Swaminathan bptr[0], bptr[1], bptr[2], bptr[3],
117082527734SSukumar Swaminathan bptr[4], bptr[5], bptr[6], bptr[7]);
117182527734SSukumar Swaminathan
1172fcf3ce44SJohn Forte fct_port->port_sym_node_name = port->snn;
1173fcf3ce44SJohn Forte fct_port->port_sym_port_name = port->spn;
1174fcf3ce44SJohn Forte fct_port->port_hard_address = cfg[CFG_ASSIGN_ALPA].current;
1175fcf3ce44SJohn Forte fct_port->port_default_alias = port->cfd_name;
1176fcf3ce44SJohn Forte fct_port->port_pp = port->port_provider;
11778f23e9faSHans Rosenfeld fct_port->port_max_logins = hba->max_nodes + EMLXS_FCT_NUM_ELS_ONLY;
1178fcf3ce44SJohn Forte
1179bce54adfSSukumar Swaminathan if (cfg[CFG_FCT_QDEPTH].current &&
1180bce54adfSSukumar Swaminathan (cfg[CFG_FCT_QDEPTH].current < hba->io_throttle)) {
1181bce54adfSSukumar Swaminathan fct_port->port_max_xchges = cfg[CFG_FCT_QDEPTH].current;
1182fcf3ce44SJohn Forte } else {
1183fcf3ce44SJohn Forte fct_port->port_max_xchges = hba->io_throttle;
1184fcf3ce44SJohn Forte }
1185fcf3ce44SJohn Forte
1186fcf3ce44SJohn Forte fct_port->port_fca_fcp_cmd_size = sizeof (emlxs_buf_t);
1187fcf3ce44SJohn Forte fct_port->port_fca_rp_private_size = sizeof (uintptr_t);
1188fcf3ce44SJohn Forte fct_port->port_fca_sol_els_private_size = sizeof (emlxs_buf_t);
1189fcf3ce44SJohn Forte fct_port->port_fca_sol_ct_private_size = sizeof (emlxs_buf_t);
1190fcf3ce44SJohn Forte fct_port->port_get_link_info = emlxs_fct_get_link_info;
1191fcf3ce44SJohn Forte fct_port->port_register_remote_port = emlxs_fct_register_remote_port;
1192fcf3ce44SJohn Forte fct_port->port_deregister_remote_port =
1193fcf3ce44SJohn Forte emlxs_fct_deregister_remote_port;
1194fcf3ce44SJohn Forte fct_port->port_send_cmd = emlxs_fct_send_cmd;
1195fcf3ce44SJohn Forte fct_port->port_xfer_scsi_data = emlxs_fct_send_fcp_data;
1196fcf3ce44SJohn Forte fct_port->port_send_cmd_response = emlxs_fct_send_cmd_rsp;
1197fcf3ce44SJohn Forte fct_port->port_abort_cmd = emlxs_fct_abort;
1198fcf3ce44SJohn Forte fct_port->port_ctl = emlxs_fct_ctl;
119982527734SSukumar Swaminathan fct_port->port_flogi_xchg = emlxs_fct_flogi_xchg;
120082527734SSukumar Swaminathan fct_port->port_populate_hba_details = emlxs_fct_populate_hba_details;
120182527734SSukumar Swaminathan fct_port->port_info = emlxs_fct_port_info;
1202fcf3ce44SJohn Forte
1203fcf3ce44SJohn Forte fds = port->fct_port->port_fds;
1204fcf3ce44SJohn Forte fds->fds_fca_private = port;
1205fcf3ce44SJohn Forte fds->fds_alloc_data_buf = emlxs_fct_dbuf_alloc;
1206fcf3ce44SJohn Forte fds->fds_free_data_buf = emlxs_fct_dbuf_free;
1207fcf3ce44SJohn Forte
12088f23e9faSHans Rosenfeld /* Scatter gather list support */
12098f23e9faSHans Rosenfeld /* fds->fds_setup_dbuf = ; */
12108f23e9faSHans Rosenfeld /* fds->fds_teardown_dbuf = ; */
12118f23e9faSHans Rosenfeld /* fds->fds_max_sgl_xfer_len = ; */
12128f23e9faSHans Rosenfeld /* fds->fds_copy_threshold = ; */
12138f23e9faSHans Rosenfeld
1214fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
1215fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1216fcf3ce44SJohn Forte "fct_register_local_port %p", fct_port);
1217291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
1218fcf3ce44SJohn Forte /* register this local port with the fct module */
1219fcf3ce44SJohn Forte if (MODSYM(fct_register_local_port) (fct_port) != FCT_SUCCESS) {
1220fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
12218f23e9faSHans Rosenfeld "fct_bind_port: Unable to register fct port.");
1222fcf3ce44SJohn Forte goto failed;
1223fcf3ce44SJohn Forte }
1224291a2b48SSukumar Swaminathan
1225fcf3ce44SJohn Forte /* Set the bound flag */
12268f23e9faSHans Rosenfeld port->flag |= EMLXS_TGT_BOUND;
1227fcf3ce44SJohn Forte hba->num_of_ports++;
1228fcf3ce44SJohn Forte
1229fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK);
1230fcf3ce44SJohn Forte
1231fcf3ce44SJohn Forte return;
1232fcf3ce44SJohn Forte
1233fcf3ce44SJohn Forte failed:
1234fcf3ce44SJohn Forte
1235fcf3ce44SJohn Forte if (flag & 0x20) {
1236fcf3ce44SJohn Forte (void) ddi_remove_minor_node(hba->dip, node_name);
1237fcf3ce44SJohn Forte }
1238291a2b48SSukumar Swaminathan
1239fcf3ce44SJohn Forte if (flag & 0x10) {
1240fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
1241fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1242fcf3ce44SJohn Forte "fct_free:5 %p", port->fct_port->port_fds);
1243291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
1244fcf3ce44SJohn Forte MODSYM(fct_free) (port->fct_port->port_fds);
1245fcf3ce44SJohn Forte port->fct_port->port_fds = NULL;
1246fcf3ce44SJohn Forte }
1247291a2b48SSukumar Swaminathan
1248fcf3ce44SJohn Forte if (flag & 0x8) {
1249fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
1250fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1251fcf3ce44SJohn Forte "fct_free:6 %p", port->fct_port);
1252291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
1253fcf3ce44SJohn Forte MODSYM(fct_free) (port->fct_port);
1254fcf3ce44SJohn Forte port->fct_port = NULL;
1255fcf3ce44SJohn Forte port->fct_flags = 0;
1256fcf3ce44SJohn Forte }
1257291a2b48SSukumar Swaminathan
1258fcf3ce44SJohn Forte if (flag & 0x4) {
1259fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
1260fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1261291a2b48SSukumar Swaminathan "stmf_deregister_port_provider:2 %p",
1262291a2b48SSukumar Swaminathan port->port_provider);
1263291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
1264fcf3ce44SJohn Forte MODSYM(stmf_deregister_port_provider) (port->port_provider);
1265fcf3ce44SJohn Forte }
1266291a2b48SSukumar Swaminathan
1267fcf3ce44SJohn Forte if (flag & 0x2) {
1268fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
1269fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1270fcf3ce44SJohn Forte "stmf_free:2 %p", port->port_provider);
1271291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
1272fcf3ce44SJohn Forte MODSYM(stmf_free) (port->port_provider);
1273fcf3ce44SJohn Forte port->port_provider = NULL;
1274fcf3ce44SJohn Forte }
1275291a2b48SSukumar Swaminathan
1276fcf3ce44SJohn Forte if (flag & 0x1) {
1277fcf3ce44SJohn Forte emlxs_fct_dmem_fini(port);
1278fcf3ce44SJohn Forte }
1279291a2b48SSukumar Swaminathan
12808f23e9faSHans Rosenfeld port->flag &= ~EMLXS_TGT_ENABLED;
12818f23e9faSHans Rosenfeld
1282fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
1283fcf3ce44SJohn Forte "Target mode disabled.");
1284fcf3ce44SJohn Forte
1285fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK);
1286fcf3ce44SJohn Forte
1287fcf3ce44SJohn Forte return;
1288fcf3ce44SJohn Forte
128982527734SSukumar Swaminathan } /* emlxs_fct_bind_port() */
129082527734SSukumar Swaminathan
129182527734SSukumar Swaminathan
129282527734SSukumar Swaminathan /* COMSTAR ENTER POINT */
129382527734SSukumar Swaminathan /*ARGSUSED*/
129482527734SSukumar Swaminathan static fct_status_t
emlxs_fct_port_info(uint32_t cmd,fct_local_port_t * fct_port,void * arg,uint8_t * buffer,uint32_t * size)129582527734SSukumar Swaminathan emlxs_fct_port_info(uint32_t cmd, fct_local_port_t *fct_port, void *arg,
129682527734SSukumar Swaminathan uint8_t *buffer, uint32_t *size)
129782527734SSukumar Swaminathan {
129882527734SSukumar Swaminathan emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
129982527734SSukumar Swaminathan emlxs_hba_t *hba = HBA;
130082527734SSukumar Swaminathan fct_status_t rval = FCT_SUCCESS;
130182527734SSukumar Swaminathan fct_port_link_status_t *link_status;
130282527734SSukumar Swaminathan MAILBOX *mb;
130382527734SSukumar Swaminathan MAILBOXQ *mbq;
130482527734SSukumar Swaminathan
130582527734SSukumar Swaminathan switch (cmd) {
130682527734SSukumar Swaminathan case FC_TGT_PORT_RLS:
130782527734SSukumar Swaminathan bzero(buffer, *size);
130882527734SSukumar Swaminathan
130982527734SSukumar Swaminathan if ((*size) < sizeof (fct_port_link_status_t)) {
131082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
131182527734SSukumar Swaminathan "FC_TGT_PORT_RLS: Buffer too small. %d < %d",
131282527734SSukumar Swaminathan *size, sizeof (fct_port_link_status_t));
131382527734SSukumar Swaminathan
131482527734SSukumar Swaminathan rval = FCT_FAILURE;
131582527734SSukumar Swaminathan break;
131682527734SSukumar Swaminathan }
131782527734SSukumar Swaminathan
13188f23e9faSHans Rosenfeld if ((mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX)) == 0) {
131982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
132082527734SSukumar Swaminathan "FC_TGT_PORT_RLS: Unable to allocate mailbox.");
132182527734SSukumar Swaminathan
132282527734SSukumar Swaminathan rval = FCT_ALLOC_FAILURE;
132382527734SSukumar Swaminathan break;
132482527734SSukumar Swaminathan }
132582527734SSukumar Swaminathan mb = (MAILBOX *)mbq;
132682527734SSukumar Swaminathan
132782527734SSukumar Swaminathan emlxs_mb_read_lnk_stat(hba, mbq);
132882527734SSukumar Swaminathan if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0)
132982527734SSukumar Swaminathan != MBX_SUCCESS) {
133082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
133182527734SSukumar Swaminathan "FC_TGT_PORT_RLS: Unable to send request.");
133282527734SSukumar Swaminathan
133382527734SSukumar Swaminathan rval = FCT_BUSY;
133482527734SSukumar Swaminathan } else {
133582527734SSukumar Swaminathan link_status = (fct_port_link_status_t *)buffer;
133682527734SSukumar Swaminathan link_status->LinkFailureCount =
133782527734SSukumar Swaminathan mb->un.varRdLnk.linkFailureCnt;
133882527734SSukumar Swaminathan link_status->LossOfSyncCount =
133982527734SSukumar Swaminathan mb->un.varRdLnk.lossSyncCnt;
134082527734SSukumar Swaminathan link_status->LossOfSignalsCount =
134182527734SSukumar Swaminathan mb->un.varRdLnk.lossSignalCnt;
134282527734SSukumar Swaminathan link_status->PrimitiveSeqProtocolErrorCount =
134382527734SSukumar Swaminathan mb->un.varRdLnk.primSeqErrCnt;
134482527734SSukumar Swaminathan link_status->InvalidTransmissionWordCount =
134582527734SSukumar Swaminathan mb->un.varRdLnk.invalidXmitWord;
134682527734SSukumar Swaminathan link_status->InvalidCRCCount =
134782527734SSukumar Swaminathan mb->un.varRdLnk.crcCnt;
134882527734SSukumar Swaminathan }
134982527734SSukumar Swaminathan
1350a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
135182527734SSukumar Swaminathan break;
135282527734SSukumar Swaminathan
135382527734SSukumar Swaminathan default:
135482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
13558f23e9faSHans Rosenfeld "fct_port_info: Invalid request. cmd=%x",
135682527734SSukumar Swaminathan cmd);
135782527734SSukumar Swaminathan
135882527734SSukumar Swaminathan rval = FCT_FAILURE;
135982527734SSukumar Swaminathan break;
136082527734SSukumar Swaminathan
136182527734SSukumar Swaminathan }
1362fcf3ce44SJohn Forte
136382527734SSukumar Swaminathan return (rval);
136482527734SSukumar Swaminathan
136582527734SSukumar Swaminathan } /* emlxs_fct_port_info() */
1366fcf3ce44SJohn Forte
136782527734SSukumar Swaminathan
136882527734SSukumar Swaminathan /* COMSTAR ENTER POINT */
1369fcf3ce44SJohn Forte static void
emlxs_fct_populate_hba_details(fct_local_port_t * fct_port,fct_port_attrs_t * port_attrs)137082527734SSukumar Swaminathan emlxs_fct_populate_hba_details(fct_local_port_t *fct_port,
1371fcf3ce44SJohn Forte fct_port_attrs_t *port_attrs)
1372fcf3ce44SJohn Forte {
1373fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
1374fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
1375fcf3ce44SJohn Forte emlxs_vpd_t *vpd = &VPD;
1376fcf3ce44SJohn Forte
1377a3170057SPaul Winder (void) strncpy(port_attrs->manufacturer,
1378a3170057SPaul Winder hba->model_info.manufacturer,
13798f23e9faSHans Rosenfeld (sizeof (port_attrs->manufacturer)-1));
13808f23e9faSHans Rosenfeld (void) strncpy(port_attrs->serial_number, vpd->serial_num,
13818f23e9faSHans Rosenfeld (sizeof (port_attrs->serial_number)-1));
13828f23e9faSHans Rosenfeld (void) strncpy(port_attrs->model, hba->model_info.model,
13838f23e9faSHans Rosenfeld (sizeof (port_attrs->model)-1));
13848f23e9faSHans Rosenfeld (void) strncpy(port_attrs->model_description,
13858f23e9faSHans Rosenfeld hba->model_info.model_desc,
13868f23e9faSHans Rosenfeld (sizeof (port_attrs->model_description)-1));
13878f23e9faSHans Rosenfeld (void) snprintf(port_attrs->hardware_version,
13888f23e9faSHans Rosenfeld (sizeof (port_attrs->hardware_version)-1),
13898f23e9faSHans Rosenfeld "%x", vpd->biuRev);
13908f23e9faSHans Rosenfeld (void) snprintf(port_attrs->driver_version,
13918f23e9faSHans Rosenfeld (sizeof (port_attrs->driver_version)-1),
13928f23e9faSHans Rosenfeld "%s (%s)", emlxs_version,
1393fcf3ce44SJohn Forte emlxs_revision);
13948f23e9faSHans Rosenfeld (void) strncpy(port_attrs->option_rom_version, vpd->fcode_version,
13958f23e9faSHans Rosenfeld (sizeof (port_attrs->option_rom_version)-1));
13968f23e9faSHans Rosenfeld (void) snprintf(port_attrs->firmware_version,
13978f23e9faSHans Rosenfeld (sizeof (port_attrs->firmware_version)-1),
13988f23e9faSHans Rosenfeld "%s (%s)", vpd->fw_version,
1399fcf3ce44SJohn Forte vpd->fw_label);
14008f23e9faSHans Rosenfeld (void) strncpy(port_attrs->driver_name, DRIVER_NAME,
14018f23e9faSHans Rosenfeld (sizeof (port_attrs->driver_name)-1));
1402a3170057SPaul Winder port_attrs->vendor_specific_id = (hba->model_info.device_id << 16) |
1403a3170057SPaul Winder hba->model_info.vendor_id;
140482527734SSukumar Swaminathan port_attrs->supported_cos = LE_SWAP32(FC_NS_CLASS3);
1405fcf3ce44SJohn Forte
1406fcf3ce44SJohn Forte port_attrs->max_frame_size = FF_FRAME_SIZE;
1407fcf3ce44SJohn Forte
1408a3170057SPaul Winder if (vpd->link_speed & LMT_32GB_CAPABLE) {
1409a3170057SPaul Winder port_attrs->supported_speed |= PORT_SPEED_32G;
1410a3170057SPaul Winder }
14118f23e9faSHans Rosenfeld if (vpd->link_speed & LMT_16GB_CAPABLE) {
14128f23e9faSHans Rosenfeld port_attrs->supported_speed |= PORT_SPEED_16G;
14138f23e9faSHans Rosenfeld }
1414fcf3ce44SJohn Forte if (vpd->link_speed & LMT_10GB_CAPABLE) {
1415291a2b48SSukumar Swaminathan port_attrs->supported_speed |= PORT_SPEED_10G;
1416fcf3ce44SJohn Forte }
1417fcf3ce44SJohn Forte if (vpd->link_speed & LMT_8GB_CAPABLE) {
1418291a2b48SSukumar Swaminathan port_attrs->supported_speed |= PORT_SPEED_8G;
1419fcf3ce44SJohn Forte }
1420fcf3ce44SJohn Forte if (vpd->link_speed & LMT_4GB_CAPABLE) {
1421291a2b48SSukumar Swaminathan port_attrs->supported_speed |= PORT_SPEED_4G;
1422fcf3ce44SJohn Forte }
1423fcf3ce44SJohn Forte if (vpd->link_speed & LMT_2GB_CAPABLE) {
1424291a2b48SSukumar Swaminathan port_attrs->supported_speed |= PORT_SPEED_2G;
1425fcf3ce44SJohn Forte }
1426fcf3ce44SJohn Forte if (vpd->link_speed & LMT_1GB_CAPABLE) {
1427291a2b48SSukumar Swaminathan port_attrs->supported_speed |= PORT_SPEED_1G;
1428fcf3ce44SJohn Forte }
1429291a2b48SSukumar Swaminathan
1430fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1431fcf3ce44SJohn Forte "Port attr: manufacturer = %s", port_attrs->manufacturer);
1432fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1433fcf3ce44SJohn Forte "Port attr: serial_num = %s", port_attrs->serial_number);
1434fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1435fcf3ce44SJohn Forte "Port attr: model = %s", port_attrs->model);
1436fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1437fcf3ce44SJohn Forte "Port attr: model_description = %s",
1438fcf3ce44SJohn Forte port_attrs->model_description);
1439fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1440291a2b48SSukumar Swaminathan "Port attr: hardware_version = %s",
1441291a2b48SSukumar Swaminathan port_attrs->hardware_version);
1442fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1443fcf3ce44SJohn Forte "Port attr: driver_version = %s", port_attrs->driver_version);
1444fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1445fcf3ce44SJohn Forte "Port attr: option_rom_version = %s",
1446fcf3ce44SJohn Forte port_attrs->option_rom_version);
1447fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1448291a2b48SSukumar Swaminathan "Port attr: firmware_version = %s",
1449291a2b48SSukumar Swaminathan port_attrs->firmware_version);
1450fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1451fcf3ce44SJohn Forte "Port attr: driver_name = %s", port_attrs->driver_name);
1452fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1453fcf3ce44SJohn Forte "Port attr: vendor_specific_id = 0x%x",
1454fcf3ce44SJohn Forte port_attrs->vendor_specific_id);
1455fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1456291a2b48SSukumar Swaminathan "Port attr: supported_cos = 0x%x",
1457291a2b48SSukumar Swaminathan port_attrs->supported_cos);
1458fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1459fcf3ce44SJohn Forte "Port attr: supported_speed = 0x%x",
1460fcf3ce44SJohn Forte port_attrs->supported_speed);
1461fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1462291a2b48SSukumar Swaminathan "Port attr: max_frame_size = 0x%x",
1463291a2b48SSukumar Swaminathan port_attrs->max_frame_size);
1464fcf3ce44SJohn Forte
1465fcf3ce44SJohn Forte return;
1466fcf3ce44SJohn Forte
146782527734SSukumar Swaminathan } /* emlxs_fct_populate_hba_details() */
1468fcf3ce44SJohn Forte
1469fcf3ce44SJohn Forte
147082527734SSukumar Swaminathan /* COMSTAR ENTER POINT */
1471fcf3ce44SJohn Forte /* ARGSUSED */
1472fcf3ce44SJohn Forte static void
emlxs_fct_ctl(fct_local_port_t * fct_port,int cmd,void * arg)1473fcf3ce44SJohn Forte emlxs_fct_ctl(fct_local_port_t *fct_port, int cmd, void *arg)
1474fcf3ce44SJohn Forte {
1475fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
1476fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
1477fcf3ce44SJohn Forte stmf_change_status_t st;
1478a988c0caSRick McNeal int32_t rval;
1479fcf3ce44SJohn Forte
1480fcf3ce44SJohn Forte st.st_completion_status = FCT_SUCCESS;
1481fcf3ce44SJohn Forte st.st_additional_info = NULL;
1482fcf3ce44SJohn Forte
1483fcf3ce44SJohn Forte switch (cmd) {
1484fcf3ce44SJohn Forte case FCT_CMD_PORT_ONLINE:
1485fcf3ce44SJohn Forte /* If the HBA is offline, we cannot bring the tgtport online */
1486fcf3ce44SJohn Forte if (hba->flag & (FC_OFFLINE_MODE | FC_OFFLINING_MODE)) {
1487fcf3ce44SJohn Forte st.st_completion_status = FCT_FAILURE;
1488fcf3ce44SJohn Forte MODSYM(fct_ctl) (fct_port->port_lport,
1489fcf3ce44SJohn Forte FCT_CMD_PORT_ONLINE_COMPLETE, &st);
1490fcf3ce44SJohn Forte break;
1491fcf3ce44SJohn Forte }
1492291a2b48SSukumar Swaminathan
1493fcf3ce44SJohn Forte if (port->fct_flags & FCT_STATE_PORT_ONLINE) {
1494fcf3ce44SJohn Forte st.st_completion_status = STMF_ALREADY;
1495fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1496fcf3ce44SJohn Forte "STATE: ONLINE chk");
1497fcf3ce44SJohn Forte } else {
1498fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1499fcf3ce44SJohn Forte "STATE: OFFLINE --> ONLINE");
1500fcf3ce44SJohn Forte
1501fcf3ce44SJohn Forte port->fct_flags |= FCT_STATE_NOT_ACKED;
1502fcf3ce44SJohn Forte port->fct_flags |= FCT_STATE_PORT_ONLINE;
1503fcf3ce44SJohn Forte
15048f23e9faSHans Rosenfeld if ((port->vpi == 0) &&
15058f23e9faSHans Rosenfeld (port->mode == MODE_TARGET) &&
15068f23e9faSHans Rosenfeld (hba->state <= FC_LINK_DOWN)) {
1507fcf3ce44SJohn Forte /* Try to bring the link up */
150882527734SSukumar Swaminathan (void) emlxs_reset_link(hba, 1, 1);
1509fcf3ce44SJohn Forte }
1510291a2b48SSukumar Swaminathan
1511fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1512fcf3ce44SJohn Forte "STATE: ONLINE");
1513fcf3ce44SJohn Forte }
1514fcf3ce44SJohn Forte
1515fcf3ce44SJohn Forte MODSYM(fct_ctl) (fct_port->port_lport,
1516fcf3ce44SJohn Forte FCT_CMD_PORT_ONLINE_COMPLETE, &st);
1517fcf3ce44SJohn Forte break;
1518fcf3ce44SJohn Forte
1519fcf3ce44SJohn Forte case FCT_CMD_PORT_OFFLINE:
1520fcf3ce44SJohn Forte if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) {
1521fcf3ce44SJohn Forte st.st_completion_status = STMF_ALREADY;
1522fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1523fcf3ce44SJohn Forte "STATE: OFFLINE chk");
1524fcf3ce44SJohn Forte
1525fcf3ce44SJohn Forte } else {
1526fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1527fcf3ce44SJohn Forte "STATE: ONLINE --> OFFLINE");
1528fcf3ce44SJohn Forte
1529fcf3ce44SJohn Forte /* Take link down and flush */
1530fcf3ce44SJohn Forte emlxs_fct_link_down(port);
1531fcf3ce44SJohn Forte emlxs_fct_unsol_flush(port);
1532fcf3ce44SJohn Forte
1533fcf3ce44SJohn Forte /* Declare this port offline now */
1534fcf3ce44SJohn Forte port->fct_flags |= FCT_STATE_NOT_ACKED;
1535fcf3ce44SJohn Forte port->fct_flags &= ~FCT_STATE_PORT_ONLINE;
1536fcf3ce44SJohn Forte
15378f23e9faSHans Rosenfeld if ((port->vpi == 0) &&
15388f23e9faSHans Rosenfeld (port->mode == MODE_TARGET) &&
15398f23e9faSHans Rosenfeld !(port->flag & EMLXS_INI_ENABLED)) {
15408f23e9faSHans Rosenfeld /* Take link down and hold it down */
15418f23e9faSHans Rosenfeld (void) emlxs_reset_link(hba, 0, 1);
15428f23e9faSHans Rosenfeld }
1543fcf3ce44SJohn Forte
1544fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1545fcf3ce44SJohn Forte "STATE: OFFLINE");
1546fcf3ce44SJohn Forte }
1547fcf3ce44SJohn Forte
1548fcf3ce44SJohn Forte MODSYM(fct_ctl) (fct_port->port_lport,
1549fcf3ce44SJohn Forte FCT_CMD_PORT_OFFLINE_COMPLETE, &st);
1550fcf3ce44SJohn Forte
1551fcf3ce44SJohn Forte break;
1552fcf3ce44SJohn Forte
1553fcf3ce44SJohn Forte case FCT_ACK_PORT_OFFLINE_COMPLETE:
1554fcf3ce44SJohn Forte port->fct_flags &= ~FCT_STATE_NOT_ACKED;
1555fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1556fcf3ce44SJohn Forte "STATE: OFFLINE ack");
1557fcf3ce44SJohn Forte break;
1558fcf3ce44SJohn Forte
1559fcf3ce44SJohn Forte case FCT_ACK_PORT_ONLINE_COMPLETE:
1560fcf3ce44SJohn Forte port->fct_flags &= ~FCT_STATE_NOT_ACKED;
1561fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1562fcf3ce44SJohn Forte "STATE: ONLINE ack");
1563fcf3ce44SJohn Forte break;
1564fcf3ce44SJohn Forte
156582527734SSukumar Swaminathan case FCT_CMD_FORCE_LIP:
15668f23e9faSHans Rosenfeld if (port->mode == MODE_INITIATOR) {
15678f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
15688f23e9faSHans Rosenfeld "fct_ctl: FCT_CMD_FORCE_LIP.");
1569a988c0caSRick McNeal *((fct_status_t *)arg) = FCT_FAILURE;
15708f23e9faSHans Rosenfeld break;
15718f23e9faSHans Rosenfeld }
15728f23e9faSHans Rosenfeld
1573a9800bebSGarrett D'Amore if (hba->fw_flag & FW_UPDATE_NEEDED) {
1574a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
15758f23e9faSHans Rosenfeld "fct_ctl: FCT_CMD_FORCE_LIP -> "
1576a9800bebSGarrett D'Amore "FCT_CMD_RESET");
1577a9800bebSGarrett D'Amore
1578a9800bebSGarrett D'Amore hba->fw_flag |= FW_UPDATE_KERNEL;
15798f23e9faSHans Rosenfeld
1580a9800bebSGarrett D'Amore /* Reset the adapter */
1581a988c0caSRick McNeal rval = emlxs_reset(port, FC_FCA_RESET);
1582a9800bebSGarrett D'Amore } else {
1583a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
15848f23e9faSHans Rosenfeld "fct_ctl: FCT_CMD_FORCE_LIP");
158582527734SSukumar Swaminathan
1586a9800bebSGarrett D'Amore /* Reset the link */
1587a988c0caSRick McNeal rval = emlxs_reset(port, FC_FCA_LINK_RESET);
1588a9800bebSGarrett D'Amore }
1589a988c0caSRick McNeal *((fct_status_t *)arg) = (rval == FC_SUCCESS) ? FCT_SUCCESS:
1590a988c0caSRick McNeal FCT_FAILURE;
159182527734SSukumar Swaminathan break;
1592fcf3ce44SJohn Forte }
1593fcf3ce44SJohn Forte
1594fcf3ce44SJohn Forte return;
1595fcf3ce44SJohn Forte
159682527734SSukumar Swaminathan } /* emlxs_fct_ctl() */
1597291a2b48SSukumar Swaminathan
1598fcf3ce44SJohn Forte
1599fcf3ce44SJohn Forte extern int
emlxs_fct_port_shutdown(emlxs_port_t * port)1600fcf3ce44SJohn Forte emlxs_fct_port_shutdown(emlxs_port_t *port)
1601fcf3ce44SJohn Forte {
1602fcf3ce44SJohn Forte fct_local_port_t *fct_port;
160382527734SSukumar Swaminathan int i;
1604fcf3ce44SJohn Forte
1605fcf3ce44SJohn Forte fct_port = port->fct_port;
1606fcf3ce44SJohn Forte if (!fct_port) {
1607fcf3ce44SJohn Forte return (0);
1608fcf3ce44SJohn Forte }
16093be114edSSukumar Swaminathan
16103be114edSSukumar Swaminathan port->fct_flags |= FCT_STATE_NOT_ACKED;
16113be114edSSukumar Swaminathan
1612291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, "fct_port_shutdown");
1613fcf3ce44SJohn Forte MODSYM(fct_port_shutdown) (fct_port, STMF_RFLAG_STAY_OFFLINED,
16148f23e9faSHans Rosenfeld DRIVER_NAME" shutdown");
1615fcf3ce44SJohn Forte
161682527734SSukumar Swaminathan i = 0;
1617fcf3ce44SJohn Forte while (port->fct_flags & FCT_STATE_NOT_ACKED) {
1618fcf3ce44SJohn Forte i++;
1619fcf3ce44SJohn Forte if (i > 300) { /* 30 seconds */
1620fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1621fcf3ce44SJohn Forte "fct_port_shutdown failed to ACK");
1622fcf3ce44SJohn Forte break;
1623fcf3ce44SJohn Forte }
1624fcf3ce44SJohn Forte delay(drv_usectohz(100000)); /* 100 msec */
1625fcf3ce44SJohn Forte }
1626fcf3ce44SJohn Forte return (1);
1627fcf3ce44SJohn Forte }
1628fcf3ce44SJohn Forte
1629fcf3ce44SJohn Forte
1630fcf3ce44SJohn Forte extern int
emlxs_fct_port_initialize(emlxs_port_t * port)1631fcf3ce44SJohn Forte emlxs_fct_port_initialize(emlxs_port_t *port)
1632fcf3ce44SJohn Forte {
1633fcf3ce44SJohn Forte fct_local_port_t *fct_port;
163482527734SSukumar Swaminathan int i;
1635fcf3ce44SJohn Forte
1636fcf3ce44SJohn Forte fct_port = port->fct_port;
1637fcf3ce44SJohn Forte if (!fct_port) {
1638fcf3ce44SJohn Forte return (0);
1639fcf3ce44SJohn Forte }
16403be114edSSukumar Swaminathan
16413be114edSSukumar Swaminathan port->fct_flags |= FCT_STATE_NOT_ACKED;
16423be114edSSukumar Swaminathan
1643fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1644fcf3ce44SJohn Forte "fct_port_initialize");
1645fcf3ce44SJohn Forte MODSYM(fct_port_initialize) (fct_port, STMF_RFLAG_STAY_OFFLINED,
16468f23e9faSHans Rosenfeld DRIVER_NAME" initialize");
1647fcf3ce44SJohn Forte
164882527734SSukumar Swaminathan i = 0;
1649fcf3ce44SJohn Forte while (port->fct_flags & FCT_STATE_NOT_ACKED) {
1650fcf3ce44SJohn Forte i++;
1651fcf3ce44SJohn Forte if (i > 300) { /* 30 seconds */
1652fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1653fcf3ce44SJohn Forte "fct_port_initialize failed to ACK");
1654fcf3ce44SJohn Forte break;
1655fcf3ce44SJohn Forte }
1656fcf3ce44SJohn Forte delay(drv_usectohz(100000)); /* 100 msec */
1657fcf3ce44SJohn Forte }
1658fcf3ce44SJohn Forte return (1);
1659fcf3ce44SJohn Forte }
1660fcf3ce44SJohn Forte
1661291a2b48SSukumar Swaminathan
166282527734SSukumar Swaminathan /* COMSTAR ENTER POINT */
1663fcf3ce44SJohn Forte static fct_status_t
emlxs_fct_send_cmd(fct_cmd_t * fct_cmd)1664fcf3ce44SJohn Forte emlxs_fct_send_cmd(fct_cmd_t *fct_cmd)
1665fcf3ce44SJohn Forte {
1666fcf3ce44SJohn Forte emlxs_port_t *port;
1667fcf3ce44SJohn Forte
1668fcf3ce44SJohn Forte port = (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
1669fcf3ce44SJohn Forte
1670fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
1671fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
16728f23e9faSHans Rosenfeld "fct_send_cmd %p:%p x%x", fct_cmd,
16738f23e9faSHans Rosenfeld fct_cmd->cmd_fca_private, fct_cmd->cmd_type);
1674291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
1675fcf3ce44SJohn Forte
1676fcf3ce44SJohn Forte switch (fct_cmd->cmd_type) {
1677fcf3ce44SJohn Forte case FCT_CMD_SOL_ELS:
1678fcf3ce44SJohn Forte
1679fcf3ce44SJohn Forte return (emlxs_fct_send_els_cmd(fct_cmd));
1680fcf3ce44SJohn Forte
1681fcf3ce44SJohn Forte case FCT_CMD_SOL_CT:
1682fcf3ce44SJohn Forte
1683fcf3ce44SJohn Forte return (emlxs_fct_send_ct_cmd(fct_cmd));
1684fcf3ce44SJohn Forte
1685fcf3ce44SJohn Forte default:
1686fcf3ce44SJohn Forte
1687fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
16888f23e9faSHans Rosenfeld "fct_send_cmd: Invalid cmd type found. type=%x",
1689fcf3ce44SJohn Forte fct_cmd->cmd_type);
1690fcf3ce44SJohn Forte
1691fcf3ce44SJohn Forte return (FCT_FAILURE);
1692fcf3ce44SJohn Forte }
1693fcf3ce44SJohn Forte
169482527734SSukumar Swaminathan } /* emlxs_fct_send_cmd() */
1695fcf3ce44SJohn Forte
1696fcf3ce44SJohn Forte
169782527734SSukumar Swaminathan /* COMSTAR ENTER POINT */
1698fcf3ce44SJohn Forte static fct_status_t
emlxs_fct_send_cmd_rsp(fct_cmd_t * fct_cmd,uint32_t ioflags)1699fcf3ce44SJohn Forte emlxs_fct_send_cmd_rsp(fct_cmd_t *fct_cmd, uint32_t ioflags)
1700fcf3ce44SJohn Forte {
1701fcf3ce44SJohn Forte emlxs_port_t *port;
1702291a2b48SSukumar Swaminathan emlxs_buf_t *cmd_sbp;
1703291a2b48SSukumar Swaminathan fct_status_t rval;
170482527734SSukumar Swaminathan IOCBQ *iocbq;
170582527734SSukumar Swaminathan IOCB *iocb;
170682527734SSukumar Swaminathan uint32_t status;
1707fcf3ce44SJohn Forte
1708fcf3ce44SJohn Forte port = (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
170982527734SSukumar Swaminathan
171082527734SSukumar Swaminathan rval = emlxs_fct_cmd_accept(port, fct_cmd, EMLXS_FCT_SEND_CMD_RSP);
171182527734SSukumar Swaminathan if (rval) {
171282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
17138f23e9faSHans Rosenfeld "fct_send_cmd_rsp: "
171482527734SSukumar Swaminathan "Unable to accept fct_cmd. type=%x",
171582527734SSukumar Swaminathan fct_cmd->cmd_type);
171682527734SSukumar Swaminathan
171782527734SSukumar Swaminathan return (rval);
171882527734SSukumar Swaminathan }
171982527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */
172082527734SSukumar Swaminathan
1721291a2b48SSukumar Swaminathan cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
172282527734SSukumar Swaminathan iocbq = &cmd_sbp->iocbq;
17238f23e9faSHans Rosenfeld iocbq->sbp = cmd_sbp;
172482527734SSukumar Swaminathan iocb = &iocbq->iocb;
172582527734SSukumar Swaminathan status = iocb->ULPSTATUS;
1726fcf3ce44SJohn Forte
1727fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
1728fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
17298f23e9faSHans Rosenfeld "fct_send_cmd_rsp %p:%p x%x, %x, %x",
17308f23e9faSHans Rosenfeld fct_cmd, cmd_sbp, fct_cmd->cmd_type, iocb->ULPCT, status);
1731291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
1732fcf3ce44SJohn Forte
1733fcf3ce44SJohn Forte switch (fct_cmd->cmd_type) {
1734fcf3ce44SJohn Forte case FCT_CMD_FCP_XCHG:
1735fcf3ce44SJohn Forte
1736fcf3ce44SJohn Forte if (ioflags & FCT_IOF_FORCE_FCA_DONE) {
1737fcf3ce44SJohn Forte goto failure;
1738fcf3ce44SJohn Forte }
1739291a2b48SSukumar Swaminathan
174082527734SSukumar Swaminathan if ((iocb->ULPCT == 0x1) && (status == 0)) {
174182527734SSukumar Swaminathan
174282527734SSukumar Swaminathan /* Firmware already sent out resp */
174382527734SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_SEND_STATUS;
174482527734SSukumar Swaminathan
17458f23e9faSHans Rosenfeld TGTPORTSTAT.FctOutstandingIO--;
17468f23e9faSHans Rosenfeld
174782527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_IO_DONE);
174882527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
174982527734SSukumar Swaminathan
175082527734SSukumar Swaminathan #ifdef FCT_API_TRACE
175182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
175282527734SSukumar Swaminathan "fct_send_response_done:4 %p: x%x",
175382527734SSukumar Swaminathan fct_cmd, fct_cmd->cmd_comp_status);
175482527734SSukumar Swaminathan
175582527734SSukumar Swaminathan #endif /* FCT_API_TRACE */
175682527734SSukumar Swaminathan
175782527734SSukumar Swaminathan MODSYM(fct_send_response_done) (fct_cmd,
175882527734SSukumar Swaminathan fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE);
175982527734SSukumar Swaminathan
176082527734SSukumar Swaminathan return (FCT_SUCCESS);
176182527734SSukumar Swaminathan }
176282527734SSukumar Swaminathan
1763291a2b48SSukumar Swaminathan rval = emlxs_fct_send_fcp_status(fct_cmd);
17648f23e9faSHans Rosenfeld if (rval == FCT_NOT_FOUND) {
17658f23e9faSHans Rosenfeld goto failure;
17668f23e9faSHans Rosenfeld }
176782527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
176882527734SSukumar Swaminathan
1769291a2b48SSukumar Swaminathan return (rval);
1770fcf3ce44SJohn Forte
1771fcf3ce44SJohn Forte case FCT_CMD_RCVD_ELS:
1772fcf3ce44SJohn Forte
1773fcf3ce44SJohn Forte if (ioflags & FCT_IOF_FORCE_FCA_DONE) {
1774fcf3ce44SJohn Forte goto failure;
1775fcf3ce44SJohn Forte }
1776fcf3ce44SJohn Forte
177782527734SSukumar Swaminathan rval = emlxs_fct_send_els_rsp(fct_cmd);
177882527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
177982527734SSukumar Swaminathan
178082527734SSukumar Swaminathan return (rval);
1781fcf3ce44SJohn Forte
1782fcf3ce44SJohn Forte default:
1783fcf3ce44SJohn Forte
1784fcf3ce44SJohn Forte if (ioflags & FCT_IOF_FORCE_FCA_DONE) {
1785fcf3ce44SJohn Forte fct_cmd->cmd_handle = 0;
1786fcf3ce44SJohn Forte }
1787291a2b48SSukumar Swaminathan
1788fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
17898f23e9faSHans Rosenfeld "fct_send_cmd_rsp: Invalid cmd type found. type=%x",
1790fcf3ce44SJohn Forte fct_cmd->cmd_type);
1791fcf3ce44SJohn Forte
1792fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
179382527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
179482527734SSukumar Swaminathan
1795fcf3ce44SJohn Forte return (FCT_FAILURE);
1796fcf3ce44SJohn Forte }
1797fcf3ce44SJohn Forte
1798fcf3ce44SJohn Forte failure:
1799fcf3ce44SJohn Forte
1800fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
18018f23e9faSHans Rosenfeld "fct_send_cmd_rsp: "
1802291a2b48SSukumar Swaminathan "Unable to handle FCT_IOF_FORCE_FCA_DONE. type=%x",
1803291a2b48SSukumar Swaminathan fct_cmd->cmd_type);
1804fcf3ce44SJohn Forte
1805fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
180682527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
180782527734SSukumar Swaminathan
1808fcf3ce44SJohn Forte return (FCT_FAILURE);
1809fcf3ce44SJohn Forte
181082527734SSukumar Swaminathan } /* emlxs_fct_send_cmd_rsp() */
1811fcf3ce44SJohn Forte
1812fcf3ce44SJohn Forte
181382527734SSukumar Swaminathan /* COMSTAR ENTER POINT */
1814fcf3ce44SJohn Forte static fct_status_t
emlxs_fct_flogi_xchg(struct fct_local_port * fct_port,struct fct_flogi_xchg * fx)181582527734SSukumar Swaminathan emlxs_fct_flogi_xchg(struct fct_local_port *fct_port, struct fct_flogi_xchg *fx)
1816fcf3ce44SJohn Forte {
1817fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
1818fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
1819fcf3ce44SJohn Forte uint32_t size;
182082527734SSukumar Swaminathan fc_packet_t *pkt = NULL;
1821fcf3ce44SJohn Forte ELS_PKT *els;
182282527734SSukumar Swaminathan fct_status_t rval = FCT_SUCCESS;
1823fcf3ce44SJohn Forte
1824fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
1825fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
18268f23e9faSHans Rosenfeld "fct_flogi_xchg: Sending FLOGI: %p", fct_port);
1827fcf3ce44SJohn Forte #else
1828fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
18298f23e9faSHans Rosenfeld "fct_flogi_xchg: Sending FLOGI.");
1830291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
1831fcf3ce44SJohn Forte
1832fcf3ce44SJohn Forte if (hba->state <= FC_LINK_DOWN) {
1833fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
18348f23e9faSHans Rosenfeld "fct_flogi_xchg: FLOGI failed. Link down.");
183582527734SSukumar Swaminathan rval = FCT_FAILURE;
183682527734SSukumar Swaminathan goto done;
1837fcf3ce44SJohn Forte }
1838291a2b48SSukumar Swaminathan
18398f23e9faSHans Rosenfeld /* Use this entry point as the link up acknowledgment */
1840e2ca2865SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK);
1841e2ca2865SSukumar Swaminathan port->fct_flags |= FCT_STATE_LINK_UP_ACKED;
1842e2ca2865SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
18438f23e9faSHans Rosenfeld "fct_link_up acked.");
1844e2ca2865SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK);
1845e2ca2865SSukumar Swaminathan
18468f23e9faSHans Rosenfeld /* First handle any pending FLOGI's */
18478f23e9faSHans Rosenfeld emlxs_fct_handle_unsol_flogi(port, NULL, 0);
1848e2ca2865SSukumar Swaminathan
1849fcf3ce44SJohn Forte size = sizeof (SERV_PARM) + 4;
1850fcf3ce44SJohn Forte
1851fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, size, size, 0, KM_NOSLEEP))) {
1852fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
18538f23e9faSHans Rosenfeld "fct_flogi_xchg: FLOGI failed. "
185482527734SSukumar Swaminathan "Unable allocate packet.");
185582527734SSukumar Swaminathan rval = FCT_FAILURE;
185682527734SSukumar Swaminathan goto done;
1857fcf3ce44SJohn Forte }
1858291a2b48SSukumar Swaminathan
1859fcf3ce44SJohn Forte /* Make this a polled IO */
1860fcf3ce44SJohn Forte pkt->pkt_tran_flags &= ~FC_TRAN_INTR;
1861fcf3ce44SJohn Forte pkt->pkt_tran_flags |= FC_TRAN_NO_INTR;
1862fcf3ce44SJohn Forte pkt->pkt_comp = NULL;
1863fcf3ce44SJohn Forte
1864fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE;
1865fcf3ce44SJohn Forte pkt->pkt_timeout = fx->fx_sec_timeout;
1866fcf3ce44SJohn Forte
1867fcf3ce44SJohn Forte /* Build the fc header */
186882527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(fx->fx_did);
1869291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.r_ctl =
1870291a2b48SSukumar Swaminathan R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
187182527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(fx->fx_sid);
1872fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
1873fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl = F_CTL_FIRST_SEQ | F_CTL_SEQ_INITIATIVE;
1874fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0;
1875fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0;
1876fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0;
1877fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xffff;
1878fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xffff;
1879fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0;
1880fcf3ce44SJohn Forte
1881fcf3ce44SJohn Forte /* Build the command */
1882291a2b48SSukumar Swaminathan /* Service paramters will be added automatically later by the driver */
1883fcf3ce44SJohn Forte els = (ELS_PKT *)pkt->pkt_cmd;
1884fcf3ce44SJohn Forte els->elsCode = 0x04; /* FLOGI */
1885fcf3ce44SJohn Forte
1886fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
1887fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
18888f23e9faSHans Rosenfeld "fct_flogi_xchg: FLOGI failed. "
188982527734SSukumar Swaminathan "Unable to send packet.");
1890fcf3ce44SJohn Forte
189182527734SSukumar Swaminathan rval = FCT_FAILURE;
189282527734SSukumar Swaminathan goto done;
1893fcf3ce44SJohn Forte }
1894291a2b48SSukumar Swaminathan
1895fcf3ce44SJohn Forte if ((pkt->pkt_state != FC_PKT_SUCCESS) &&
1896fcf3ce44SJohn Forte (pkt->pkt_state != FC_PKT_LS_RJT)) {
1897fcf3ce44SJohn Forte if (pkt->pkt_state == FC_PKT_TIMEOUT) {
189882527734SSukumar Swaminathan rval = FCT_TIMEOUT;
1899fcf3ce44SJohn Forte } else if ((pkt->pkt_state == FC_PKT_LOCAL_RJT) &&
1900fcf3ce44SJohn Forte (pkt->pkt_reason == FC_REASON_FCAL_OPN_FAIL)) {
190182527734SSukumar Swaminathan rval = FCT_NOT_FOUND;
190282527734SSukumar Swaminathan } else {
190382527734SSukumar Swaminathan rval = FCT_FAILURE;
1904fcf3ce44SJohn Forte }
1905291a2b48SSukumar Swaminathan
1906fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
19078f23e9faSHans Rosenfeld "fct_flogi_xchg: FLOGI failed. state=%x reason=%x "
19088f23e9faSHans Rosenfeld "rval=%llx", pkt->pkt_state, pkt->pkt_reason, rval);
1909fcf3ce44SJohn Forte
191082527734SSukumar Swaminathan goto done;
1911fcf3ce44SJohn Forte }
1912291a2b48SSukumar Swaminathan
1913fcf3ce44SJohn Forte if (pkt->pkt_state == FC_PKT_LS_RJT) {
1914fcf3ce44SJohn Forte fx->fx_op = ELS_OP_LSRJT;
1915fcf3ce44SJohn Forte fx->fx_rjt_reason = pkt->pkt_reason;
1916fcf3ce44SJohn Forte fx->fx_rjt_expl = pkt->pkt_expln;
1917fcf3ce44SJohn Forte } else { /* FC_PKT_SUCCESS */
1918291a2b48SSukumar Swaminathan
1919fcf3ce44SJohn Forte fx->fx_op = ELS_OP_ACC;
192082527734SSukumar Swaminathan fx->fx_sid = FABRIC_DID;
1921fcf3ce44SJohn Forte fx->fx_did = port->did;
1922fcf3ce44SJohn Forte
1923291a2b48SSukumar Swaminathan els = (ELS_PKT *)pkt->pkt_resp;
1924fcf3ce44SJohn Forte bcopy((caddr_t)&els->un.logi.nodeName,
1925fcf3ce44SJohn Forte (caddr_t)fx->fx_nwwn, 8);
1926fcf3ce44SJohn Forte bcopy((caddr_t)&els->un.logi.portName,
1927fcf3ce44SJohn Forte (caddr_t)fx->fx_pwwn, 8);
1928fcf3ce44SJohn Forte fx->fx_fport = els->un.logi.cmn.fPort;
1929fcf3ce44SJohn Forte }
1930fcf3ce44SJohn Forte
193182527734SSukumar Swaminathan done:
193282527734SSukumar Swaminathan if (pkt) {
193382527734SSukumar Swaminathan emlxs_pkt_free(pkt);
193482527734SSukumar Swaminathan }
193582527734SSukumar Swaminathan
19368f23e9faSHans Rosenfeld if ((rval == FCT_SUCCESS) || (rval == FCT_NOT_FOUND)) {
19378f23e9faSHans Rosenfeld
19388f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
19398f23e9faSHans Rosenfeld "fct_flogi_xchg: FCT_STATE_FLOGI_CMPL. rval=%s",
19408f23e9faSHans Rosenfeld ((rval == FCT_SUCCESS)? "FCT_SUCCESS":"FCT_NOT_FOUND"));
19418f23e9faSHans Rosenfeld
19428f23e9faSHans Rosenfeld mutex_enter(&EMLXS_PORT_LOCK);
19438f23e9faSHans Rosenfeld port->fct_flags |= FCT_STATE_FLOGI_CMPL;
19448f23e9faSHans Rosenfeld mutex_exit(&EMLXS_PORT_LOCK);
19458f23e9faSHans Rosenfeld
19468f23e9faSHans Rosenfeld /*
19478f23e9faSHans Rosenfeld * Flush all unsolicited commands
19488f23e9faSHans Rosenfeld * Must use separate thread since
19498f23e9faSHans Rosenfeld * this thread must complete first
19508f23e9faSHans Rosenfeld */
19518f23e9faSHans Rosenfeld emlxs_thread_spawn(hba, emlxs_fct_unsol_flush_thread,
19528f23e9faSHans Rosenfeld (void *)port, 0);
19538f23e9faSHans Rosenfeld }
19548f23e9faSHans Rosenfeld
195582527734SSukumar Swaminathan return (rval);
1956fcf3ce44SJohn Forte
195782527734SSukumar Swaminathan } /* emlxs_fct_flogi_xchg() */
1958fcf3ce44SJohn Forte
1959fcf3ce44SJohn Forte
196082527734SSukumar Swaminathan /* COMSTAR ENTER POINT */
1961fcf3ce44SJohn Forte /* This is called right after we report that link has come online */
1962fcf3ce44SJohn Forte static fct_status_t
emlxs_fct_get_link_info(fct_local_port_t * fct_port,fct_link_info_t * link)1963fcf3ce44SJohn Forte emlxs_fct_get_link_info(fct_local_port_t *fct_port, fct_link_info_t *link)
1964fcf3ce44SJohn Forte {
1965fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
1966fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
1967fcf3ce44SJohn Forte
1968fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
19698f23e9faSHans Rosenfeld "fct_get_link_info %p: FCT: flg x%x HBA: ste x%x flg x%x topo x%x",
19708f23e9faSHans Rosenfeld fct_port, port->fct_flags, hba->state, hba->flag, hba->topology);
1971fcf3ce44SJohn Forte
1972fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK);
1973fcf3ce44SJohn Forte
19748f23e9faSHans Rosenfeld if (port->mode == MODE_INITIATOR) {
19758f23e9faSHans Rosenfeld link->port_topology = PORT_TOPOLOGY_UNKNOWN;
19768f23e9faSHans Rosenfeld link->port_speed = PORT_SPEED_UNKNOWN;
19778f23e9faSHans Rosenfeld link->portid = 0;
19788f23e9faSHans Rosenfeld
19798f23e9faSHans Rosenfeld mutex_exit(&EMLXS_PORT_LOCK);
19808f23e9faSHans Rosenfeld
19818f23e9faSHans Rosenfeld return (FCT_SUCCESS);
19828f23e9faSHans Rosenfeld }
19838f23e9faSHans Rosenfeld
1984fcf3ce44SJohn Forte if (!(port->fct_flags & FCT_STATE_LINK_UP) ||
1985291a2b48SSukumar Swaminathan (hba->state < FC_LINK_UP) || (hba->flag & FC_LOOPBACK_MODE)) {
1986fcf3ce44SJohn Forte link->port_topology = PORT_TOPOLOGY_UNKNOWN;
1987fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_UNKNOWN;
1988fcf3ce44SJohn Forte link->portid = 0;
1989fcf3ce44SJohn Forte
1990fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK);
1991fcf3ce44SJohn Forte
1992fcf3ce44SJohn Forte return (FCT_SUCCESS);
1993fcf3ce44SJohn Forte }
1994291a2b48SSukumar Swaminathan
1995fcf3ce44SJohn Forte if (hba->topology == TOPOLOGY_LOOP) {
1996fcf3ce44SJohn Forte link->port_topology = PORT_TOPOLOGY_PRIVATE_LOOP;
1997fcf3ce44SJohn Forte } else {
1998fcf3ce44SJohn Forte link->port_topology = PORT_TOPOLOGY_PT_TO_PT;
1999fcf3ce44SJohn Forte }
2000fcf3ce44SJohn Forte
2001fcf3ce44SJohn Forte switch (hba->linkspeed) {
2002fcf3ce44SJohn Forte case LA_1GHZ_LINK:
2003fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_1G;
2004fcf3ce44SJohn Forte break;
2005fcf3ce44SJohn Forte case LA_2GHZ_LINK:
2006fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_2G;
2007fcf3ce44SJohn Forte break;
2008fcf3ce44SJohn Forte case LA_4GHZ_LINK:
2009fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_4G;
2010fcf3ce44SJohn Forte break;
2011fcf3ce44SJohn Forte case LA_8GHZ_LINK:
2012fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_8G;
2013fcf3ce44SJohn Forte break;
2014fcf3ce44SJohn Forte case LA_10GHZ_LINK:
2015fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_10G;
2016fcf3ce44SJohn Forte break;
20178f23e9faSHans Rosenfeld case LA_16GHZ_LINK:
20188f23e9faSHans Rosenfeld link->port_speed = PORT_SPEED_16G;
20198f23e9faSHans Rosenfeld break;
2020a3170057SPaul Winder case LA_32GHZ_LINK:
2021a3170057SPaul Winder link->port_speed = PORT_SPEED_32G;
2022a3170057SPaul Winder break;
2023fcf3ce44SJohn Forte default:
2024fcf3ce44SJohn Forte link->port_speed = PORT_SPEED_UNKNOWN;
2025fcf3ce44SJohn Forte break;
2026fcf3ce44SJohn Forte }
2027fcf3ce44SJohn Forte
2028fcf3ce44SJohn Forte link->portid = port->did;
2029fcf3ce44SJohn Forte link->port_no_fct_flogi = 0;
2030fcf3ce44SJohn Forte link->port_fca_flogi_done = 0;
2031fcf3ce44SJohn Forte link->port_fct_flogi_done = 0;
2032fcf3ce44SJohn Forte
2033fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK);
2034fcf3ce44SJohn Forte
2035fcf3ce44SJohn Forte return (FCT_SUCCESS);
2036fcf3ce44SJohn Forte
203782527734SSukumar Swaminathan } /* emlxs_fct_get_link_info() */
2038fcf3ce44SJohn Forte
2039fcf3ce44SJohn Forte
204082527734SSukumar Swaminathan /* COMSTAR ENTER POINT */
2041fcf3ce44SJohn Forte static fct_status_t
emlxs_fct_register_remote_port(fct_local_port_t * fct_port,fct_remote_port_t * remote_port,fct_cmd_t * fct_cmd)2042fcf3ce44SJohn Forte emlxs_fct_register_remote_port(fct_local_port_t *fct_port,
2043fcf3ce44SJohn Forte fct_remote_port_t *remote_port, fct_cmd_t *fct_cmd)
2044fcf3ce44SJohn Forte {
2045fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
2046fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
2047fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
2048fcf3ce44SJohn Forte clock_t timeout;
2049fcf3ce44SJohn Forte int32_t pkt_ret;
2050fcf3ce44SJohn Forte fct_els_t *els;
2051fcf3ce44SJohn Forte SERV_PARM *sp;
2052fcf3ce44SJohn Forte emlxs_node_t *ndlp;
2053fcf3ce44SJohn Forte SERV_PARM sparam;
2054fcf3ce44SJohn Forte uint32_t *iptr;
20558f23e9faSHans Rosenfeld uint16_t hdl;
20563be114edSSukumar Swaminathan uint64_t addr;
205782527734SSukumar Swaminathan fct_status_t rval;
205882527734SSukumar Swaminathan fct_status_t rval2;
20598f23e9faSHans Rosenfeld uint32_t i;
2060fcf3ce44SJohn Forte
2061fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
2062fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
20638f23e9faSHans Rosenfeld "fct_register_remote_port %p", fct_port);
2064291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
2065fcf3ce44SJohn Forte
2066fcf3ce44SJohn Forte if (!(cmd_sbp->pkt_flags & PACKET_VALID)) {
206782527734SSukumar Swaminathan
206882527734SSukumar Swaminathan cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd,
206982527734SSukumar Swaminathan EMLXS_FCT_REG_PENDING);
2070291a2b48SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */
2071fcf3ce44SJohn Forte
207282527734SSukumar Swaminathan cmd_sbp->channel = &hba->chan[hba->channel_els];
2073fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_ELS_CMD;
207482527734SSukumar Swaminathan
2075fcf3ce44SJohn Forte } else {
2076fcf3ce44SJohn Forte
207782527734SSukumar Swaminathan rval = emlxs_fct_cmd_accept(port, fct_cmd,
207882527734SSukumar Swaminathan EMLXS_FCT_REG_PENDING);
207982527734SSukumar Swaminathan if (rval) {
208082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
20818f23e9faSHans Rosenfeld "fct_register_remote_port: "
20828f23e9faSHans Rosenfeld "Unable to accept fct_cmd. lid=%x rid=%x",
20838f23e9faSHans Rosenfeld fct_cmd->cmd_lportid, fct_cmd->cmd_rportid);
2084291a2b48SSukumar Swaminathan
208582527734SSukumar Swaminathan return (rval);
208682527734SSukumar Swaminathan }
208782527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */
208882527734SSukumar Swaminathan }
2089fcf3ce44SJohn Forte
2090a9800bebSGarrett D'Amore cmd_sbp->fct_flags &= ~EMLXS_FCT_REGISTERED;
20918f23e9faSHans Rosenfeld cmd_sbp->node = emlxs_node_find_did(port, fct_cmd->cmd_rportid, 1);
2092a9800bebSGarrett D'Amore
20938f23e9faSHans Rosenfeld /* Check for unsolicited PLOGI */
20948f23e9faSHans Rosenfeld if (cmd_sbp->fct_flags & EMLXS_FCT_PLOGI_RECEIVED) {
2095fcf3ce44SJohn Forte els = (fct_els_t *)fct_cmd->cmd_specific;
20968f23e9faSHans Rosenfeld sp = (SERV_PARM *)((caddr_t)els->els_req_payload +
20978f23e9faSHans Rosenfeld sizeof (uint32_t));
20988f23e9faSHans Rosenfeld
20998f23e9faSHans Rosenfeld } else { /* Solicited PLOGI */
21008f23e9faSHans Rosenfeld
21018f23e9faSHans Rosenfeld sp = &sparam;
21028f23e9faSHans Rosenfeld bcopy((caddr_t)&port->sparam, (caddr_t)sp,
21038f23e9faSHans Rosenfeld sizeof (SERV_PARM));
21048f23e9faSHans Rosenfeld
21058f23e9faSHans Rosenfeld /*
21068f23e9faSHans Rosenfeld * Create temporary WWN's from fct_cmd address
21078f23e9faSHans Rosenfeld * This simply allows us to get an RPI from the
21088f23e9faSHans Rosenfeld * adapter until we get real service params.
21098f23e9faSHans Rosenfeld * The PLOGI ACC reply will trigger a REG_LOGIN
21108f23e9faSHans Rosenfeld * update later
21118f23e9faSHans Rosenfeld */
21128f23e9faSHans Rosenfeld addr = (uint64_t)((unsigned long)fct_cmd);
21138f23e9faSHans Rosenfeld
21148f23e9faSHans Rosenfeld iptr = (uint32_t *)&sp->portName;
21158f23e9faSHans Rosenfeld iptr[0] = PADDR_HI(addr);
21168f23e9faSHans Rosenfeld iptr[1] = PADDR_LO(addr);
2117fcf3ce44SJohn Forte
21188f23e9faSHans Rosenfeld iptr = (uint32_t *)&sp->nodeName;
21198f23e9faSHans Rosenfeld iptr[0] = PADDR_HI(addr);
21208f23e9faSHans Rosenfeld iptr[1] = PADDR_LO(addr);
21218f23e9faSHans Rosenfeld }
21228f23e9faSHans Rosenfeld
21238f23e9faSHans Rosenfeld if (hba->flag & FC_PT_TO_PT) {
21248f23e9faSHans Rosenfeld mutex_enter(&EMLXS_PORT_LOCK);
21258f23e9faSHans Rosenfeld port->did = fct_cmd->cmd_lportid;
21268f23e9faSHans Rosenfeld port->rdid = fct_cmd->cmd_rportid;
21278f23e9faSHans Rosenfeld mutex_exit(&EMLXS_PORT_LOCK);
2128291a2b48SSukumar Swaminathan
21298f23e9faSHans Rosenfeld /*
21308f23e9faSHans Rosenfeld * We already received the remote port's
21318f23e9faSHans Rosenfeld * parameters in the FLOGI exchange
21328f23e9faSHans Rosenfeld */
21338f23e9faSHans Rosenfeld if (!(cmd_sbp->fct_flags & EMLXS_FCT_PLOGI_RECEIVED)) {
2134fcf3ce44SJohn Forte sp = &sparam;
21358f23e9faSHans Rosenfeld bcopy((caddr_t)&port->fabric_sparam, (caddr_t)sp,
2136fcf3ce44SJohn Forte sizeof (SERV_PARM));
2137fcf3ce44SJohn Forte
2138fcf3ce44SJohn Forte /*
21398f23e9faSHans Rosenfeld * Since this is a PLOGI, not a FLOGI, we need
21408f23e9faSHans Rosenfeld * to fix up word2 of the CSP accordingly.
2141fcf3ce44SJohn Forte */
21428f23e9faSHans Rosenfeld sp->cmn.w2.r_a_tov = port->sparam.cmn.w2.r_a_tov;
2143fcf3ce44SJohn Forte }
21448f23e9faSHans Rosenfeld }
2145fcf3ce44SJohn Forte
21468f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
21478f23e9faSHans Rosenfeld "fct_register_remote_port: Register lid=%x rid=%x. (%x,%x,%p)",
21488f23e9faSHans Rosenfeld fct_cmd->cmd_lportid, fct_cmd->cmd_rportid, cmd_sbp->fct_state,
21498f23e9faSHans Rosenfeld hba->flag, fct_cmd);
2150fcf3ce44SJohn Forte
21518f23e9faSHans Rosenfeld emlxs_fct_cmd_release(port, fct_cmd, 0);
21528f23e9faSHans Rosenfeld /* mutex_exit(&cmd_sbp->fct_mtx); */
215382527734SSukumar Swaminathan
21548f23e9faSHans Rosenfeld /* Create a new node */
21558f23e9faSHans Rosenfeld if (EMLXS_SLI_REG_DID(port, fct_cmd->cmd_rportid, sp, cmd_sbp,
21568f23e9faSHans Rosenfeld NULL, NULL) != 0) {
21578f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
21588f23e9faSHans Rosenfeld "fct_register_remote_port: "
21598f23e9faSHans Rosenfeld "Reg login failed. lid=%x rid=%x",
21608f23e9faSHans Rosenfeld fct_cmd->cmd_lportid, fct_cmd->cmd_rportid);
21618f23e9faSHans Rosenfeld } else {
2162fcf3ce44SJohn Forte
21638f23e9faSHans Rosenfeld /* Wait for completion */
21648f23e9faSHans Rosenfeld mutex_enter(&EMLXS_PKT_LOCK);
21658f23e9faSHans Rosenfeld timeout = emlxs_timeout(hba, 30);
21668f23e9faSHans Rosenfeld pkt_ret = 0;
21678f23e9faSHans Rosenfeld while ((pkt_ret != -1) &&
21688f23e9faSHans Rosenfeld (cmd_sbp->fct_state == EMLXS_FCT_REG_PENDING) &&
21698f23e9faSHans Rosenfeld !(cmd_sbp->fct_flags & EMLXS_FCT_REGISTERED)) {
21708f23e9faSHans Rosenfeld pkt_ret = cv_timedwait(&EMLXS_PKT_CV,
21718f23e9faSHans Rosenfeld &EMLXS_PKT_LOCK, timeout);
2172fcf3ce44SJohn Forte }
21738f23e9faSHans Rosenfeld mutex_exit(&EMLXS_PKT_LOCK);
21748f23e9faSHans Rosenfeld }
2175fcf3ce44SJohn Forte
21768f23e9faSHans Rosenfeld /* Reacquire ownership of the fct_cmd */
21778f23e9faSHans Rosenfeld rval2 = emlxs_fct_cmd_acquire(port, fct_cmd,
21788f23e9faSHans Rosenfeld EMLXS_FCT_REG_COMPLETE);
21798f23e9faSHans Rosenfeld if (rval2) {
21808f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
21818f23e9faSHans Rosenfeld "fct_register_remote_port: "
21828f23e9faSHans Rosenfeld "Unable to reacquire fct_cmd. lid=%x rid=%x",
21838f23e9faSHans Rosenfeld fct_cmd->cmd_lportid, fct_cmd->cmd_rportid);
218482527734SSukumar Swaminathan
21858f23e9faSHans Rosenfeld return (rval2);
2186fcf3ce44SJohn Forte }
21878f23e9faSHans Rosenfeld /* mutex_enter(&cmd_sbp->fct_mtx); */
2188291a2b48SSukumar Swaminathan
21898f23e9faSHans Rosenfeld /* Prepare response */
2190fcf3ce44SJohn Forte
2191fcf3ce44SJohn Forte ndlp = (emlxs_node_t *)cmd_sbp->node;
2192fcf3ce44SJohn Forte
2193fcf3ce44SJohn Forte if (ndlp) {
2194a9800bebSGarrett D'Amore cmd_sbp->fct_flags |= EMLXS_FCT_REGISTERED;
2195a9800bebSGarrett D'Amore
2196291a2b48SSukumar Swaminathan *((emlxs_node_t **)remote_port->rp_fca_private) =
2197291a2b48SSukumar Swaminathan cmd_sbp->node;
2198fcf3ce44SJohn Forte
21998f23e9faSHans Rosenfeld hdl = ndlp->nlp_Rpi;
22008f23e9faSHans Rosenfeld if (hdl == FABRIC_RPI) {
22018f23e9faSHans Rosenfeld if (fct_cmd->cmd_rportid == SCR_DID) {
22028f23e9faSHans Rosenfeld /* The SCR handle is hardcoded */
22038f23e9faSHans Rosenfeld remote_port->rp_handle = hba->max_nodes;
22048f23e9faSHans Rosenfeld port->fct_els_only_bmap |= 1;
22058f23e9faSHans Rosenfeld
22068f23e9faSHans Rosenfeld } else {
22078f23e9faSHans Rosenfeld for (i = 1; i < EMLXS_FCT_NUM_ELS_ONLY; i++) {
22088f23e9faSHans Rosenfeld if (port->fct_els_only_bmap & (1 << i))
22098f23e9faSHans Rosenfeld continue;
22108f23e9faSHans Rosenfeld /*
22118f23e9faSHans Rosenfeld * Bit is not set, so use this
22128f23e9faSHans Rosenfeld * for the handle
22138f23e9faSHans Rosenfeld */
22148f23e9faSHans Rosenfeld remote_port->rp_handle =
22158f23e9faSHans Rosenfeld hba->max_nodes + i;
22168f23e9faSHans Rosenfeld port->fct_els_only_bmap |= (1 << i);
22178f23e9faSHans Rosenfeld break;
22188f23e9faSHans Rosenfeld }
22198f23e9faSHans Rosenfeld if (i >= EMLXS_FCT_NUM_ELS_ONLY) {
22208f23e9faSHans Rosenfeld remote_port->rp_handle =
22218f23e9faSHans Rosenfeld FCT_HANDLE_NONE;
22228f23e9faSHans Rosenfeld }
22238f23e9faSHans Rosenfeld }
22248f23e9faSHans Rosenfeld } else {
22258f23e9faSHans Rosenfeld if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
22268f23e9faSHans Rosenfeld hdl = emlxs_sli4_rpi_to_index(hba, hdl);
22278f23e9faSHans Rosenfeld }
22288f23e9faSHans Rosenfeld remote_port->rp_handle = hdl;
22298f23e9faSHans Rosenfeld }
2230fcf3ce44SJohn Forte
22318f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
22328f23e9faSHans Rosenfeld "fct_register_remote_port: lid=%x rid=%x hdl=%x",
22338f23e9faSHans Rosenfeld fct_cmd->cmd_lportid, fct_cmd->cmd_rportid,
22348f23e9faSHans Rosenfeld remote_port->rp_handle);
2235fcf3ce44SJohn Forte
2236fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
223782527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
2238291a2b48SSukumar Swaminathan
2239fcf3ce44SJohn Forte TGTPORTSTAT.FctPortRegister++;
2240fcf3ce44SJohn Forte return (FCT_SUCCESS);
2241fcf3ce44SJohn Forte } else {
2242fcf3ce44SJohn Forte *((emlxs_node_t **)remote_port->rp_fca_private) = NULL;
2243fcf3ce44SJohn Forte
2244fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
22458f23e9faSHans Rosenfeld "fct_register_remote_port: failed. lid=%x rid=%x hdl=%x",
22468f23e9faSHans Rosenfeld fct_cmd->cmd_lportid, fct_cmd->cmd_rportid,
22478f23e9faSHans Rosenfeld remote_port->rp_handle);
2248fcf3ce44SJohn Forte
2249fcf3ce44SJohn Forte remote_port->rp_handle = FCT_HANDLE_NONE;
2250fcf3ce44SJohn Forte
2251fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
225282527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
2253291a2b48SSukumar Swaminathan
2254fcf3ce44SJohn Forte TGTPORTSTAT.FctFailedPortRegister++;
2255fcf3ce44SJohn Forte return (FCT_FAILURE);
2256fcf3ce44SJohn Forte }
2257fcf3ce44SJohn Forte
225882527734SSukumar Swaminathan } /* emlxs_fct_register_remote_port() */
2259fcf3ce44SJohn Forte
2260fcf3ce44SJohn Forte
226182527734SSukumar Swaminathan /* COMSTAR ENTER POINT */
2262fcf3ce44SJohn Forte static fct_status_t
emlxs_fct_deregister_remote_port(fct_local_port_t * fct_port,fct_remote_port_t * remote_port)2263fcf3ce44SJohn Forte emlxs_fct_deregister_remote_port(fct_local_port_t *fct_port,
2264fcf3ce44SJohn Forte fct_remote_port_t *remote_port)
2265fcf3ce44SJohn Forte {
2266fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
22678f23e9faSHans Rosenfeld emlxs_hba_t *hba = HBA;
2268a9800bebSGarrett D'Amore emlxs_node_t *ndlp;
22698f23e9faSHans Rosenfeld uint32_t i;
2270fcf3ce44SJohn Forte
2271fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
2272fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
22738f23e9faSHans Rosenfeld "fct_deregister_remote_port: did=%x hdl=%x",
2274fcf3ce44SJohn Forte remote_port->rp_id, remote_port->rp_handle);
2275fcf3ce44SJohn Forte #else
2276fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
22778f23e9faSHans Rosenfeld "fct_deregister_remote_port: did=%x hdl=%x",
2278fcf3ce44SJohn Forte remote_port->rp_id, remote_port->rp_handle);
2279291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
2280fcf3ce44SJohn Forte
22818f23e9faSHans Rosenfeld if (remote_port->rp_handle >= hba->max_nodes) {
22828f23e9faSHans Rosenfeld i = remote_port->rp_handle - hba->max_nodes;
22838f23e9faSHans Rosenfeld if ((i < EMLXS_FCT_NUM_ELS_ONLY) &&
22848f23e9faSHans Rosenfeld (port->fct_els_only_bmap & (1 << i))) {
22858f23e9faSHans Rosenfeld port->fct_els_only_bmap &= ~(1 << i);
22868f23e9faSHans Rosenfeld }
22878f23e9faSHans Rosenfeld }
22888f23e9faSHans Rosenfeld
2289a9800bebSGarrett D'Amore ndlp = *((emlxs_node_t **)remote_port->rp_fca_private);
2290fcf3ce44SJohn Forte *((emlxs_node_t **)remote_port->rp_fca_private) = NULL;
2291a9800bebSGarrett D'Amore
2292a9800bebSGarrett D'Amore if (ndlp) {
22938f23e9faSHans Rosenfeld (void) EMLXS_SLI_UNREG_NODE(port, ndlp, NULL,
2294a9800bebSGarrett D'Amore NULL, NULL);
2295a9800bebSGarrett D'Amore }
2296fcf3ce44SJohn Forte
2297fcf3ce44SJohn Forte TGTPORTSTAT.FctPortDeregister++;
2298fcf3ce44SJohn Forte return (FCT_SUCCESS);
2299fcf3ce44SJohn Forte
230082527734SSukumar Swaminathan } /* emlxs_fct_deregister_remote_port() */
2301fcf3ce44SJohn Forte
2302fcf3ce44SJohn Forte
2303fcf3ce44SJohn Forte /* ARGSUSED */
2304fcf3ce44SJohn Forte extern int
emlxs_fct_handle_unsol_req(emlxs_port_t * port,CHANNEL * cp,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size)230582527734SSukumar Swaminathan emlxs_fct_handle_unsol_req(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
2306fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size)
2307fcf3ce44SJohn Forte {
23088f23e9faSHans Rosenfeld emlxs_hba_t *hba = HBA;
2309fcf3ce44SJohn Forte IOCB *iocb;
2310fcf3ce44SJohn Forte fct_cmd_t *fct_cmd;
2311fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp;
2312fcf3ce44SJohn Forte emlxs_fcp_cmd_t *fcp_cmd;
2313fcf3ce44SJohn Forte emlxs_node_t *ndlp;
2314fcf3ce44SJohn Forte uint32_t cnt;
2315fcf3ce44SJohn Forte uint32_t tm;
23168f23e9faSHans Rosenfeld uint16_t hdl;
2317fcf3ce44SJohn Forte scsi_task_t *fct_task;
2318fcf3ce44SJohn Forte uint8_t lun[8];
2319fcf3ce44SJohn Forte uint32_t sid = 0;
2320fcf3ce44SJohn Forte
2321fcf3ce44SJohn Forte iocb = &iocbq->iocb;
232282527734SSukumar Swaminathan ndlp = emlxs_node_find_rpi(port, iocb->ULPIOTAG);
2323fcf3ce44SJohn Forte if (!ndlp) {
2324fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
23258f23e9faSHans Rosenfeld "FCP rcvd: Unknown RPI. rpi=%d rxid=%x. Dropping...",
232682527734SSukumar Swaminathan iocb->ULPIOTAG, iocb->ULPCONTEXT);
2327fcf3ce44SJohn Forte
2328fcf3ce44SJohn Forte goto dropped;
2329fcf3ce44SJohn Forte }
2330fcf3ce44SJohn Forte sid = ndlp->nlp_DID;
2331fcf3ce44SJohn Forte
2332fcf3ce44SJohn Forte fcp_cmd = (emlxs_fcp_cmd_t *)mp->virt;
2333fcf3ce44SJohn Forte
2334fcf3ce44SJohn Forte if (!port->fct_port) {
2335fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
23368f23e9faSHans Rosenfeld "FCP rcvd: Target unbound. rpi=%d rxid=%x. Dropping...",
233782527734SSukumar Swaminathan iocb->ULPIOTAG, iocb->ULPCONTEXT);
2338fcf3ce44SJohn Forte
2339fcf3ce44SJohn Forte emlxs_send_logo(port, sid);
2340fcf3ce44SJohn Forte
2341fcf3ce44SJohn Forte goto dropped;
2342fcf3ce44SJohn Forte }
2343291a2b48SSukumar Swaminathan
2344fcf3ce44SJohn Forte if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) {
2345fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
23468f23e9faSHans Rosenfeld "FCP rcvd: Target offline. rpi=%d rxid=%x. Dropping...",
234782527734SSukumar Swaminathan iocb->ULPIOTAG, iocb->ULPCONTEXT);
2348fcf3ce44SJohn Forte
2349fcf3ce44SJohn Forte emlxs_send_logo(port, sid);
2350fcf3ce44SJohn Forte
2351fcf3ce44SJohn Forte goto dropped;
2352fcf3ce44SJohn Forte }
2353291a2b48SSukumar Swaminathan
2354fcf3ce44SJohn Forte /* Get lun id */
2355fcf3ce44SJohn Forte bcopy((void *)&fcp_cmd->fcpLunMsl, lun, 8);
2356fcf3ce44SJohn Forte
2357fcf3ce44SJohn Forte if (TGTPORTSTAT.FctOutstandingIO >= port->fct_port->port_max_xchges) {
2358fcf3ce44SJohn Forte TGTPORTSTAT.FctOverQDepth++;
2359fcf3ce44SJohn Forte }
2360291a2b48SSukumar Swaminathan
23618f23e9faSHans Rosenfeld hdl = ndlp->nlp_Rpi;
23628f23e9faSHans Rosenfeld if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
23638f23e9faSHans Rosenfeld hdl = emlxs_sli4_rpi_to_index(hba, hdl);
23648f23e9faSHans Rosenfeld }
2365291a2b48SSukumar Swaminathan fct_cmd =
23668f23e9faSHans Rosenfeld MODSYM(fct_scsi_task_alloc) (port->fct_port, hdl, sid, lun, 16, 0);
2367fcf3ce44SJohn Forte
2368fcf3ce44SJohn Forte if (fct_cmd == NULL) {
2369fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2370291a2b48SSukumar Swaminathan "FCP rcvd: sid=%x xid=%x. "
2371291a2b48SSukumar Swaminathan "Unable to allocate scsi task. Returning QFULL.",
237282527734SSukumar Swaminathan sid, iocb->ULPCONTEXT);
2373fcf3ce44SJohn Forte
237482527734SSukumar Swaminathan (void) emlxs_fct_send_qfull_reply(port, ndlp, iocb->ULPCONTEXT,
237582527734SSukumar Swaminathan iocb->ULPCLASS, fcp_cmd);
2376fcf3ce44SJohn Forte
2377fcf3ce44SJohn Forte goto dropped;
2378fcf3ce44SJohn Forte }
2379291a2b48SSukumar Swaminathan
2380fcf3ce44SJohn Forte /* Initialize fct_cmd */
2381fcf3ce44SJohn Forte fct_cmd->cmd_rportid = sid;
2382fcf3ce44SJohn Forte fct_cmd->cmd_lportid = port->did;
23838f23e9faSHans Rosenfeld fct_cmd->cmd_rp_handle = hdl;
2384fcf3ce44SJohn Forte fct_cmd->cmd_port = port->fct_port;
2385fcf3ce44SJohn Forte
238682527734SSukumar Swaminathan cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd, EMLXS_FCT_FCP_CMD_RECEIVED);
238782527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */
2388fcf3ce44SJohn Forte
23898f23e9faSHans Rosenfeld #ifdef FCT_API_TRACE
23908f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
23918f23e9faSHans Rosenfeld "fct_scsi_task_alloc %p:%p FCP rcvd: "
23928f23e9faSHans Rosenfeld "cmd=%x sid=%x rxid=%x oxid=%x lun=%02x%02x dl=%d",
23938f23e9faSHans Rosenfeld fct_cmd, cmd_sbp, fcp_cmd->fcpCdb[0], sid, iocb->ULPCONTEXT,
23948f23e9faSHans Rosenfeld iocb->unsli3.ext_rcv.oxid, lun[0], lun[1],
23958f23e9faSHans Rosenfeld LE_SWAP32(fcp_cmd->fcpDl));
23968f23e9faSHans Rosenfeld #endif /* FCT_API_TRACE */
23978f23e9faSHans Rosenfeld
2398291a2b48SSukumar Swaminathan /* Initialize cmd_sbp */
239982527734SSukumar Swaminathan cmd_sbp->channel = cp;
240082527734SSukumar Swaminathan cmd_sbp->class = iocb->ULPCLASS;
2401fcf3ce44SJohn Forte cmd_sbp->lun = (lun[0] << 8) | lun[1];
2402fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_FCP_CMD;
24038f23e9faSHans Rosenfeld cmd_sbp->ticks = hba->timer_tics + (2 * hba->fc_ratov);
2404fcf3ce44SJohn Forte
24058f23e9faSHans Rosenfeld if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
24068f23e9faSHans Rosenfeld /* xrip was setup / passed in from the SLI layer */
24078f23e9faSHans Rosenfeld cmd_sbp->xrip = iocbq->sbp;
24088f23e9faSHans Rosenfeld cmd_sbp->node = iocbq->node;
24098f23e9faSHans Rosenfeld iocbq->sbp = 0;
2410fcf3ce44SJohn Forte
24118f23e9faSHans Rosenfeld fct_cmd->cmd_oxid = cmd_sbp->xrip->rx_id;
24128f23e9faSHans Rosenfeld fct_cmd->cmd_rxid = cmd_sbp->xrip->XRI;
24138f23e9faSHans Rosenfeld
24148f23e9faSHans Rosenfeld #ifdef FCT_API_TRACE
24158f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
24168f23e9faSHans Rosenfeld "FCP rcvd: oxid=%x rxid=%x iotag=%d %p ",
24178f23e9faSHans Rosenfeld fct_cmd->cmd_oxid, fct_cmd->cmd_rxid, cmd_sbp->xrip->iotag,
24188f23e9faSHans Rosenfeld hba->fc_table[cmd_sbp->xrip->iotag]);
24198f23e9faSHans Rosenfeld #endif /* FCT_API_TRACE */
24208f23e9faSHans Rosenfeld
24218f23e9faSHans Rosenfeld } else {
24228f23e9faSHans Rosenfeld fct_cmd->cmd_oxid = iocb->unsli3.ext_rcv.oxid;
24238f23e9faSHans Rosenfeld if (!fct_cmd->cmd_oxid) {
24248f23e9faSHans Rosenfeld fct_cmd->cmd_oxid = 0xFFFF;
24258f23e9faSHans Rosenfeld }
24268f23e9faSHans Rosenfeld fct_cmd->cmd_rxid = iocb->ULPCONTEXT;
24278f23e9faSHans Rosenfeld }
24288f23e9faSHans Rosenfeld
24298f23e9faSHans Rosenfeld
24308f23e9faSHans Rosenfeld fct_task = (scsi_task_t *)fct_cmd->cmd_specific;
24318f23e9faSHans Rosenfeld
24328f23e9faSHans Rosenfeld /* Set task_flags */
2433291a2b48SSukumar Swaminathan switch (fcp_cmd->fcpCntl1) {
2434291a2b48SSukumar Swaminathan case SIMPLE_Q:
2435fcf3ce44SJohn Forte fct_task->task_flags = TF_ATTR_SIMPLE_QUEUE;
2436fcf3ce44SJohn Forte break;
2437fcf3ce44SJohn Forte
2438291a2b48SSukumar Swaminathan case HEAD_OF_Q:
2439fcf3ce44SJohn Forte fct_task->task_flags = TF_ATTR_HEAD_OF_QUEUE;
2440fcf3ce44SJohn Forte break;
2441fcf3ce44SJohn Forte
2442291a2b48SSukumar Swaminathan case ORDERED_Q:
2443fcf3ce44SJohn Forte fct_task->task_flags = TF_ATTR_ORDERED_QUEUE;
2444fcf3ce44SJohn Forte break;
2445fcf3ce44SJohn Forte
2446291a2b48SSukumar Swaminathan case ACA_Q:
2447fcf3ce44SJohn Forte fct_task->task_flags = TF_ATTR_ACA;
2448fcf3ce44SJohn Forte break;
2449fcf3ce44SJohn Forte
2450291a2b48SSukumar Swaminathan case UNTAGGED:
2451fcf3ce44SJohn Forte fct_task->task_flags = TF_ATTR_UNTAGGED;
2452fcf3ce44SJohn Forte break;
2453fcf3ce44SJohn Forte }
2454fcf3ce44SJohn Forte
245582527734SSukumar Swaminathan cnt = LE_SWAP32(fcp_cmd->fcpDl);
2456fcf3ce44SJohn Forte switch (fcp_cmd->fcpCntl3) {
2457fcf3ce44SJohn Forte case 0:
2458fcf3ce44SJohn Forte TGTPORTSTAT.FctIOCmdCnt++;
2459fcf3ce44SJohn Forte break;
2460fcf3ce44SJohn Forte case 1:
246182527734SSukumar Swaminathan EMLXS_BUMP_WRIOCTR(port, cnt);
2462fcf3ce44SJohn Forte TGTPORTSTAT.FctWriteBytes += cnt;
2463fcf3ce44SJohn Forte fct_task->task_flags |= TF_WRITE_DATA;
2464fcf3ce44SJohn Forte break;
2465fcf3ce44SJohn Forte
2466fcf3ce44SJohn Forte case 2:
246782527734SSukumar Swaminathan EMLXS_BUMP_RDIOCTR(port, cnt);
2468fcf3ce44SJohn Forte TGTPORTSTAT.FctReadBytes += cnt;
2469fcf3ce44SJohn Forte fct_task->task_flags |= TF_READ_DATA;
2470fcf3ce44SJohn Forte break;
2471fcf3ce44SJohn Forte }
2472fcf3ce44SJohn Forte
2473fcf3ce44SJohn Forte fct_task->task_priority = 0;
2474fcf3ce44SJohn Forte
2475fcf3ce44SJohn Forte /* task_mgmt_function */
2476fcf3ce44SJohn Forte tm = fcp_cmd->fcpCntl2;
2477fcf3ce44SJohn Forte if (tm) {
2478fcf3ce44SJohn Forte if (tm & BIT_1) {
2479fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_ABORT_TASK_SET;
2480fcf3ce44SJohn Forte } else if (tm & BIT_2) {
2481fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_CLEAR_TASK_SET;
2482fcf3ce44SJohn Forte } else if (tm & BIT_4) {
2483fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_LUN_RESET;
2484fcf3ce44SJohn Forte } else if (tm & BIT_5) {
2485fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_TARGET_COLD_RESET;
2486fcf3ce44SJohn Forte } else if (tm & BIT_6) {
2487fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_CLEAR_ACA;
2488fcf3ce44SJohn Forte } else {
2489fcf3ce44SJohn Forte fct_task->task_mgmt_function = TM_ABORT_TASK;
2490fcf3ce44SJohn Forte }
2491fcf3ce44SJohn Forte }
2492291a2b48SSukumar Swaminathan
2493fcf3ce44SJohn Forte /* Parallel buffers support - future */
2494fcf3ce44SJohn Forte fct_task->task_max_nbufs = 1;
2495fcf3ce44SJohn Forte
2496fcf3ce44SJohn Forte fct_task->task_additional_flags = 0;
2497fcf3ce44SJohn Forte fct_task->task_cur_nbufs = 0;
2498fcf3ce44SJohn Forte fct_task->task_csn_size = 8;
2499fcf3ce44SJohn Forte fct_task->task_cmd_seq_no = 0;
2500fcf3ce44SJohn Forte fct_task->task_expected_xfer_length = cnt;
2501fcf3ce44SJohn Forte bcopy((void *)&fcp_cmd->fcpCdb, fct_task->task_cdb, 16);
2502fcf3ce44SJohn Forte
2503fcf3ce44SJohn Forte TGTPORTSTAT.FctCmdReceived++;
2504fcf3ce44SJohn Forte TGTPORTSTAT.FctOutstandingIO++;
2505fcf3ce44SJohn Forte
250682527734SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
250782527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
2508fcf3ce44SJohn Forte
2509291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE
2510291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
25118f23e9faSHans Rosenfeld "fct_post_rcvd_cmd:3 %p:%p portid x%x, %d outio %d",
25128f23e9faSHans Rosenfeld fct_cmd, cmd_sbp, fct_cmd->cmd_lportid,
25138f23e9faSHans Rosenfeld fct_task->task_expected_xfer_length,
25148f23e9faSHans Rosenfeld TGTPORTSTAT.FctOutstandingIO);
2515291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
251682527734SSukumar Swaminathan
2517291a2b48SSukumar Swaminathan MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0);
2518fcf3ce44SJohn Forte
2519fcf3ce44SJohn Forte return (0);
2520fcf3ce44SJohn Forte
2521fcf3ce44SJohn Forte dropped:
2522fcf3ce44SJohn Forte
2523fcf3ce44SJohn Forte TGTPORTSTAT.FctRcvDropped++;
2524fcf3ce44SJohn Forte return (1);
2525fcf3ce44SJohn Forte
252682527734SSukumar Swaminathan } /* emlxs_fct_handle_unsol_req() */
2527fcf3ce44SJohn Forte
2528fcf3ce44SJohn Forte
252982527734SSukumar Swaminathan /* COMSTAR ENTER POINT */
2530fcf3ce44SJohn Forte /* ARGSUSED */
2531fcf3ce44SJohn Forte static fct_status_t
emlxs_fct_send_fcp_data(fct_cmd_t * fct_cmd,stmf_data_buf_t * dbuf,uint32_t ioflags)2532fcf3ce44SJohn Forte emlxs_fct_send_fcp_data(fct_cmd_t *fct_cmd, stmf_data_buf_t *dbuf,
2533fcf3ce44SJohn Forte uint32_t ioflags)
2534fcf3ce44SJohn Forte {
2535fcf3ce44SJohn Forte emlxs_port_t *port =
2536fcf3ce44SJohn Forte (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
2537fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
2538fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp;
2539291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE
2540fcf3ce44SJohn Forte scsi_task_t *fct_task;
2541291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
2542fcf3ce44SJohn Forte IOCBQ *iocbq;
2543fcf3ce44SJohn Forte emlxs_node_t *ndlp;
2544fcf3ce44SJohn Forte
254582527734SSukumar Swaminathan int channel;
254682527734SSukumar Swaminathan int channelno;
2547b3660a96SSukumar Swaminathan fct_status_t rval = 0;
2548fcf3ce44SJohn Forte
254982527734SSukumar Swaminathan rval = emlxs_fct_cmd_accept(port, fct_cmd, EMLXS_FCT_SEND_FCP_DATA);
255082527734SSukumar Swaminathan if (rval) {
255182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
25528f23e9faSHans Rosenfeld "fct_send_fcp_data: "
255382527734SSukumar Swaminathan "Unable to accept fct_cmd. did=%x",
255482527734SSukumar Swaminathan fct_cmd->cmd_rportid);
2555fcf3ce44SJohn Forte
255682527734SSukumar Swaminathan return (rval);
2557fcf3ce44SJohn Forte }
255882527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */
2559291a2b48SSukumar Swaminathan
256082527734SSukumar Swaminathan cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
256182527734SSukumar Swaminathan #ifdef FCT_API_TRACE
256282527734SSukumar Swaminathan fct_task = (scsi_task_t *)fct_cmd->cmd_specific;
256382527734SSukumar Swaminathan #endif /* FCT_API_TRACE */
256482527734SSukumar Swaminathan ndlp = *(emlxs_node_t **)fct_cmd->cmd_rp->rp_fca_private;
2565291a2b48SSukumar Swaminathan
2566fcf3ce44SJohn Forte cmd_sbp->node = ndlp;
2567fcf3ce44SJohn Forte cmd_sbp->fct_buf = dbuf;
2568fcf3ce44SJohn Forte
256982527734SSukumar Swaminathan channelno = ((CHANNEL *)cmd_sbp->channel)->channelno;
257082527734SSukumar Swaminathan
257182527734SSukumar Swaminathan channel = channelno;
257282527734SSukumar Swaminathan
257382527734SSukumar Swaminathan
257482527734SSukumar Swaminathan
2575fcf3ce44SJohn Forte iocbq = &cmd_sbp->iocbq;
25768f23e9faSHans Rosenfeld iocbq->sbp = cmd_sbp;
2577fcf3ce44SJohn Forte
2578fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
2579fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
25808f23e9faSHans Rosenfeld "fct_send_fcp_data %p:%p flgs=%x ioflags=%x dl=%d,%d,%d,%d",
25818f23e9faSHans Rosenfeld fct_cmd, cmd_sbp, dbuf->db_flags, ioflags,
25828f23e9faSHans Rosenfeld fct_task->task_cmd_xfer_length,
258382527734SSukumar Swaminathan fct_task->task_nbytes_transferred, dbuf->db_data_size,
258482527734SSukumar Swaminathan fct_task->task_expected_xfer_length);
2585291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
2586fcf3ce44SJohn Forte
25878f23e9faSHans Rosenfeld /* Setup for I/O prep routine */
25888f23e9faSHans Rosenfeld iocbq->iocb.ULPCOMMAND = 0;
25898f23e9faSHans Rosenfeld
259082527734SSukumar Swaminathan if (EMLXS_SLI_PREP_FCT_IOCB(port, cmd_sbp, channel) != IOERR_SUCCESS) {
259182527734SSukumar Swaminathan
2592fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
259382527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
2594fcf3ce44SJohn Forte
2595fcf3ce44SJohn Forte return (FCT_BUSY);
2596fcf3ce44SJohn Forte }
2597291a2b48SSukumar Swaminathan
2598fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_FCP_DATA;
2599fcf3ce44SJohn Forte
2600fcf3ce44SJohn Forte if (dbuf->db_flags & DB_SEND_STATUS_GOOD) {
2601fcf3ce44SJohn Forte cmd_sbp->fct_flags |= EMLXS_FCT_SEND_STATUS;
2602fcf3ce44SJohn Forte }
2603fcf3ce44SJohn Forte
2604fcf3ce44SJohn Forte if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) {
2605b3660a96SSukumar Swaminathan if (emlxs_fct_dbuf_dma_sync(hba, dbuf, DDI_DMA_SYNC_FORDEV)) {
2606b3660a96SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
2607b3660a96SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
2608b3660a96SSukumar Swaminathan
26098f23e9faSHans Rosenfeld if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
26108f23e9faSHans Rosenfeld emlxs_sli4_free_xri(port, cmd_sbp, 0, 0);
26118f23e9faSHans Rosenfeld }
2612b3660a96SSukumar Swaminathan return (FCT_BUSY);
2613b3660a96SSukumar Swaminathan }
2614fcf3ce44SJohn Forte }
2615291a2b48SSukumar Swaminathan
2616291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP;
261782527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, EMLXS_FCT_DATA_PENDING);
261882527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
261982527734SSukumar Swaminathan
262082527734SSukumar Swaminathan EMLXS_SLI_ISSUE_IOCB_CMD(hba, cmd_sbp->channel, iocbq);
2621fcf3ce44SJohn Forte
2622fcf3ce44SJohn Forte return (FCT_SUCCESS);
2623fcf3ce44SJohn Forte
262482527734SSukumar Swaminathan } /* emlxs_fct_send_fcp_data() */
2625fcf3ce44SJohn Forte
2626fcf3ce44SJohn Forte
262782527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be held to enter */
262882527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be released before exiting */
2629fcf3ce44SJohn Forte static fct_status_t
emlxs_fct_send_fcp_status(fct_cmd_t * fct_cmd)2630fcf3ce44SJohn Forte emlxs_fct_send_fcp_status(fct_cmd_t *fct_cmd)
2631fcf3ce44SJohn Forte {
2632fcf3ce44SJohn Forte emlxs_port_t *port =
2633fcf3ce44SJohn Forte (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
2634fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
2635fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp;
2636fcf3ce44SJohn Forte scsi_task_t *fct_task;
2637fcf3ce44SJohn Forte fc_packet_t *pkt;
26388f23e9faSHans Rosenfeld emlxs_buf_t *sbp = NULL;
2639fcf3ce44SJohn Forte emlxs_fcp_rsp *fcp_rsp;
2640fcf3ce44SJohn Forte emlxs_node_t *ndlp;
264182527734SSukumar Swaminathan fct_status_t rval;
26428f23e9faSHans Rosenfeld uint32_t did;
26438f23e9faSHans Rosenfeld uint32_t size;
2644fcf3ce44SJohn Forte
2645fcf3ce44SJohn Forte fct_task = (scsi_task_t *)fct_cmd->cmd_specific;
2646fcf3ce44SJohn Forte ndlp = *(emlxs_node_t **)fct_cmd->cmd_rp->rp_fca_private;
2647fcf3ce44SJohn Forte did = fct_cmd->cmd_rportid;
2648fcf3ce44SJohn Forte
2649fcf3ce44SJohn Forte /* Initialize cmd_sbp */
2650fcf3ce44SJohn Forte cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
2651fcf3ce44SJohn Forte
265282527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, EMLXS_FCT_SEND_FCP_STATUS);
2653291a2b48SSukumar Swaminathan
2654fcf3ce44SJohn Forte cmd_sbp->node = ndlp;
2655fcf3ce44SJohn Forte
2656fcf3ce44SJohn Forte size = 24;
2657fcf3ce44SJohn Forte if (fct_task->task_sense_length) {
2658fcf3ce44SJohn Forte size += fct_task->task_sense_length;
2659fcf3ce44SJohn Forte }
2660fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
2661fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
26628f23e9faSHans Rosenfeld "fct_send_fcp_status %p:%p stat=%d resid=%d size=%d rx=%x ox=%x",
26638f23e9faSHans Rosenfeld fct_cmd, cmd_sbp, fct_task->task_scsi_status,
26648f23e9faSHans Rosenfeld fct_task->task_resid, size, fct_cmd->cmd_rxid, fct_cmd->cmd_oxid);
2665291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
2666fcf3ce44SJohn Forte
2667fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, size, 0, 0, KM_NOSLEEP))) {
2668fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
26698f23e9faSHans Rosenfeld "fct_send_fcp_status: Unable to allocate packet.");
2670fcf3ce44SJohn Forte
2671fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
267282527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
2673fcf3ce44SJohn Forte
2674291a2b48SSukumar Swaminathan return (FCT_BUSY);
2675fcf3ce44SJohn Forte }
2676291a2b48SSukumar Swaminathan
2677fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_FCP_STATUS;
2678fcf3ce44SJohn Forte
26798f23e9faSHans Rosenfeld sbp = emlxs_fct_pkt_init(port, fct_cmd, pkt);
2680291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = pkt;
2681fcf3ce44SJohn Forte
2682fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND;
2683fcf3ce44SJohn Forte pkt->pkt_timeout =
2684fcf3ce44SJohn Forte ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov);
26858f23e9faSHans Rosenfeld pkt->pkt_timeout = (pkt->pkt_timeout > 60)? 60: pkt->pkt_timeout;
2686fcf3ce44SJohn Forte pkt->pkt_comp = emlxs_fct_pkt_comp;
2687fcf3ce44SJohn Forte
2688fcf3ce44SJohn Forte /* Build the fc header */
268982527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(did);
2690fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_STATUS;
269182527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did);
2692fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_SCSI_FCP;
2693fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl =
2694fcf3ce44SJohn Forte F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ;
2695fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0;
2696fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0;
2697fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0;
2698fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = fct_cmd->cmd_oxid;
2699fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = fct_cmd->cmd_rxid;
2700fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0;
2701fcf3ce44SJohn Forte
2702fcf3ce44SJohn Forte /* Build the status payload */
2703fcf3ce44SJohn Forte fcp_rsp = (emlxs_fcp_rsp *)pkt->pkt_cmd;
2704fcf3ce44SJohn Forte
2705fcf3ce44SJohn Forte if (fct_task->task_resid) {
2706fcf3ce44SJohn Forte if (fct_task->task_status_ctrl & TASK_SCTRL_OVER) {
2707fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiResidOver++;
2708fcf3ce44SJohn Forte fcp_rsp->rspStatus2 |= RESID_OVER;
270982527734SSukumar Swaminathan fcp_rsp->rspResId = LE_SWAP32(fct_task->task_resid);
2710fcf3ce44SJohn Forte
2711fcf3ce44SJohn Forte } else if (fct_task->task_status_ctrl & TASK_SCTRL_UNDER) {
2712fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiResidUnder++;
2713fcf3ce44SJohn Forte fcp_rsp->rspStatus2 |= RESID_UNDER;
271482527734SSukumar Swaminathan fcp_rsp->rspResId = LE_SWAP32(fct_task->task_resid);
2715fcf3ce44SJohn Forte
2716fcf3ce44SJohn Forte }
2717fcf3ce44SJohn Forte }
2718291a2b48SSukumar Swaminathan
2719fcf3ce44SJohn Forte if (fct_task->task_scsi_status) {
2720fcf3ce44SJohn Forte if (fct_task->task_scsi_status == SCSI_STAT_QUE_FULL) {
2721fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiQfullErr++;
2722fcf3ce44SJohn Forte } else {
2723fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiStatusErr++;
2724fcf3ce44SJohn Forte }
2725fcf3ce44SJohn Forte
2726291a2b48SSukumar Swaminathan /* Make sure residual reported on non-SCSI_GOOD READ status */
2727fcf3ce44SJohn Forte if ((fct_task->task_flags & TF_READ_DATA) &&
2728fcf3ce44SJohn Forte (fcp_rsp->rspResId == 0)) {
2729fcf3ce44SJohn Forte fcp_rsp->rspStatus2 |= RESID_UNDER;
2730291a2b48SSukumar Swaminathan fcp_rsp->rspResId =
2731291a2b48SSukumar Swaminathan fct_task->task_expected_xfer_length;
2732fcf3ce44SJohn Forte }
2733fcf3ce44SJohn Forte }
2734291a2b48SSukumar Swaminathan
2735291a2b48SSukumar Swaminathan
2736fcf3ce44SJohn Forte if (fct_task->task_sense_length) {
2737fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiSenseErr++;
2738fcf3ce44SJohn Forte fcp_rsp->rspStatus2 |= SNS_LEN_VALID;
273982527734SSukumar Swaminathan fcp_rsp->rspSnsLen = LE_SWAP32(fct_task->task_sense_length);
2740fcf3ce44SJohn Forte
2741fcf3ce44SJohn Forte bcopy((uint8_t *)fct_task->task_sense_data,
2742291a2b48SSukumar Swaminathan (uint8_t *)&fcp_rsp->rspInfo0,
2743291a2b48SSukumar Swaminathan fct_task->task_sense_length);
2744fcf3ce44SJohn Forte }
2745291a2b48SSukumar Swaminathan
2746fcf3ce44SJohn Forte fcp_rsp->rspStatus3 = fct_task->task_scsi_status;
2747fcf3ce44SJohn Forte fcp_rsp->rspRspLen = 0;
274882527734SSukumar Swaminathan
27498f23e9faSHans Rosenfeld #ifdef FCT_API_TRACE
27508f23e9faSHans Rosenfeld emlxs_data_dump(port, "RESP", (uint32_t *)fcp_rsp, 36, 0);
27518f23e9faSHans Rosenfeld #endif /* FCT_API_TRACE */
27528f23e9faSHans Rosenfeld
2753291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP;
275482527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, EMLXS_FCT_STATUS_PENDING);
275582527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
2756fcf3ce44SJohn Forte
2757fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
275882527734SSukumar Swaminathan
2759fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
27608f23e9faSHans Rosenfeld "fct_send_fcp_status: Unable to send packet.");
27618f23e9faSHans Rosenfeld
27628f23e9faSHans Rosenfeld if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
27638f23e9faSHans Rosenfeld emlxs_sli4_free_xri(port, sbp, 0, 0);
27648f23e9faSHans Rosenfeld }
2765fcf3ce44SJohn Forte
276682527734SSukumar Swaminathan /* Reacquire ownership of the fct_cmd */
276782527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, 0);
276882527734SSukumar Swaminathan if (rval) {
276982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
27708f23e9faSHans Rosenfeld "fct_send_fcp_status: "
277182527734SSukumar Swaminathan "Unable to acquire fct_cmd.");
277282527734SSukumar Swaminathan return (rval);
2773fcf3ce44SJohn Forte }
277482527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */
2775291a2b48SSukumar Swaminathan
2776fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
277782527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
2778291a2b48SSukumar Swaminathan
2779291a2b48SSukumar Swaminathan return (FCT_BUSY);
2780fcf3ce44SJohn Forte }
2781291a2b48SSukumar Swaminathan
2782fcf3ce44SJohn Forte return (FCT_SUCCESS);
2783fcf3ce44SJohn Forte
278482527734SSukumar Swaminathan } /* emlxs_fct_send_fcp_status() */
2785fcf3ce44SJohn Forte
2786fcf3ce44SJohn Forte
2787fcf3ce44SJohn Forte static fct_status_t
emlxs_fct_send_qfull_reply(emlxs_port_t * port,emlxs_node_t * ndlp,uint16_t xid,uint32_t class,emlxs_fcp_cmd_t * fcp_cmd)2788291a2b48SSukumar Swaminathan emlxs_fct_send_qfull_reply(emlxs_port_t *port, emlxs_node_t *ndlp,
2789291a2b48SSukumar Swaminathan uint16_t xid, uint32_t class, emlxs_fcp_cmd_t *fcp_cmd)
2790fcf3ce44SJohn Forte {
2791fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
2792fcf3ce44SJohn Forte emlxs_buf_t *sbp;
2793fcf3ce44SJohn Forte fc_packet_t *pkt;
2794fcf3ce44SJohn Forte emlxs_fcp_rsp *fcp_rsp;
2795fcf3ce44SJohn Forte uint32_t size;
279682527734SSukumar Swaminathan CHANNEL *cp = &hba->chan[hba->CHANNEL_FCT];
2797fcf3ce44SJohn Forte uint8_t lun[8];
2798fcf3ce44SJohn Forte
2799fcf3ce44SJohn Forte bcopy((void *)&fcp_cmd->fcpLunMsl, lun, 8);
2800fcf3ce44SJohn Forte size = 24;
2801fcf3ce44SJohn Forte
2802fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, size, 0, 0, KM_NOSLEEP))) {
2803fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
28048f23e9faSHans Rosenfeld "fct_send_qfull_reply: Unable to allocate packet.");
2805fcf3ce44SJohn Forte return (FCT_FAILURE);
2806fcf3ce44SJohn Forte }
2807291a2b48SSukumar Swaminathan
2808fcf3ce44SJohn Forte sbp = PKT2PRIV(pkt);
2809fcf3ce44SJohn Forte sbp->node = ndlp;
281082527734SSukumar Swaminathan sbp->channel = cp;
2811fcf3ce44SJohn Forte sbp->did = ndlp->nlp_DID;
2812fcf3ce44SJohn Forte sbp->lun = (lun[0] << 8) | lun[1];
2813fcf3ce44SJohn Forte sbp->class = class;
2814fcf3ce44SJohn Forte
2815fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND;
2816fcf3ce44SJohn Forte pkt->pkt_timeout =
2817fcf3ce44SJohn Forte ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov);
2818fcf3ce44SJohn Forte
2819fcf3ce44SJohn Forte /* Build the fc header */
282082527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(ndlp->nlp_DID);
2821fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_STATUS;
282282527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did);
2823fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_SCSI_FCP;
2824fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl =
2825fcf3ce44SJohn Forte F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ;
2826fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0;
2827fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0;
2828fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0;
2829fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xFFFF;
2830fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = xid;
2831fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0;
2832fcf3ce44SJohn Forte
2833fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
28348f23e9faSHans Rosenfeld "fct_send_qfull_reply: Sending QFULL: x%x lun x%x: %d %d",
2835fcf3ce44SJohn Forte xid, sbp->lun, TGTPORTSTAT.FctOutstandingIO,
2836fcf3ce44SJohn Forte port->fct_port->port_max_xchges);
2837fcf3ce44SJohn Forte
2838fcf3ce44SJohn Forte /* Build the status payload */
2839fcf3ce44SJohn Forte fcp_rsp = (emlxs_fcp_rsp *)pkt->pkt_cmd;
2840fcf3ce44SJohn Forte
2841fcf3ce44SJohn Forte TGTPORTSTAT.FctScsiQfullErr++;
2842fcf3ce44SJohn Forte fcp_rsp->rspStatus3 = SCSI_STAT_QUE_FULL;
2843fcf3ce44SJohn Forte fcp_rsp->rspStatus2 |= RESID_UNDER;
284482527734SSukumar Swaminathan fcp_rsp->rspResId = LE_SWAP32(fcp_cmd->fcpDl);
2845fcf3ce44SJohn Forte
2846fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
28478f23e9faSHans Rosenfeld
28488f23e9faSHans Rosenfeld if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
28498f23e9faSHans Rosenfeld emlxs_sli4_free_xri(port, sbp, 0, 0);
28508f23e9faSHans Rosenfeld }
28518f23e9faSHans Rosenfeld
2852fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
28538f23e9faSHans Rosenfeld "fct_send_qfull_reply: Unable to send packet.");
2854fcf3ce44SJohn Forte emlxs_pkt_free(pkt);
2855fcf3ce44SJohn Forte return (FCT_FAILURE);
2856fcf3ce44SJohn Forte }
2857fcf3ce44SJohn Forte
2858291a2b48SSukumar Swaminathan return (FCT_SUCCESS);
2859fcf3ce44SJohn Forte
286082527734SSukumar Swaminathan } /* emlxs_fct_send_qfull_reply() */
2861fcf3ce44SJohn Forte
2862fcf3ce44SJohn Forte
2863fcf3ce44SJohn Forte /* ARGSUSED */
2864fcf3ce44SJohn Forte extern int
emlxs_fct_handle_fcp_event(emlxs_hba_t * hba,CHANNEL * cp,IOCBQ * iocbq)286582527734SSukumar Swaminathan emlxs_fct_handle_fcp_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
2866fcf3ce44SJohn Forte {
2867fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT;
2868fcf3ce44SJohn Forte IOCB *iocb;
2869fcf3ce44SJohn Forte emlxs_buf_t *sbp;
2870fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp;
2871fcf3ce44SJohn Forte uint32_t status;
2872fcf3ce44SJohn Forte fct_cmd_t *fct_cmd;
2873fcf3ce44SJohn Forte stmf_data_buf_t *dbuf;
2874fcf3ce44SJohn Forte scsi_task_t *fct_task;
2875291a2b48SSukumar Swaminathan fc_packet_t *pkt;
287682527734SSukumar Swaminathan uint32_t fct_flags;
287782527734SSukumar Swaminathan stmf_data_buf_t *fct_buf;
287882527734SSukumar Swaminathan fct_status_t rval;
2879fcf3ce44SJohn Forte
2880fcf3ce44SJohn Forte iocb = &iocbq->iocb;
2881fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)iocbq->sbp;
2882fcf3ce44SJohn Forte
2883fcf3ce44SJohn Forte TGTPORTSTAT.FctEvent++;
2884fcf3ce44SJohn Forte
2885fcf3ce44SJohn Forte if (!sbp) {
2886fcf3ce44SJohn Forte /* completion with missing xmit command */
2887fcf3ce44SJohn Forte TGTPORTSTAT.FctStray++;
2888fcf3ce44SJohn Forte
2889fcf3ce44SJohn Forte /* emlxs_stray_fcp_completion_msg */
2890fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
28918f23e9faSHans Rosenfeld "FCP event cmd=%x status=%x error=%x iotag=%d",
289282527734SSukumar Swaminathan iocb->ULPCOMMAND, iocb->ULPSTATUS,
289382527734SSukumar Swaminathan iocb->un.grsp.perr.statLocalError, iocb->ULPIOTAG);
2894fcf3ce44SJohn Forte
2895fcf3ce44SJohn Forte return (1);
2896fcf3ce44SJohn Forte }
2897291a2b48SSukumar Swaminathan
2898fcf3ce44SJohn Forte TGTPORTSTAT.FctCompleted++;
2899fcf3ce44SJohn Forte
2900fcf3ce44SJohn Forte port = sbp->iocbq.port;
2901fcf3ce44SJohn Forte fct_cmd = sbp->fct_cmd;
290282527734SSukumar Swaminathan status = iocb->ULPSTATUS;
2903fcf3ce44SJohn Forte
2904fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
2905fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
29068f23e9faSHans Rosenfeld "fct_handle_fcp_event: %p:%p cmd=%x status=%x, %x",
29078f23e9faSHans Rosenfeld fct_cmd, sbp, iocb->ULPCOMMAND, status, iocb->ULPCT);
2908291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
2909fcf3ce44SJohn Forte
2910fcf3ce44SJohn Forte if (fct_cmd == NULL) {
2911291a2b48SSukumar Swaminathan /* For driver generated QFULL response */
291282527734SSukumar Swaminathan if (((iocb->ULPCOMMAND == CMD_FCP_TRSP_CX) ||
291382527734SSukumar Swaminathan (iocb->ULPCOMMAND == CMD_FCP_TRSP64_CX)) && sbp->pkt) {
2914fcf3ce44SJohn Forte emlxs_pkt_free(sbp->pkt);
2915fcf3ce44SJohn Forte }
2916fcf3ce44SJohn Forte return (0);
2917fcf3ce44SJohn Forte }
2918291a2b48SSukumar Swaminathan
291982527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, EMLXS_FCT_REQ_COMPLETE);
292082527734SSukumar Swaminathan if (rval) {
292182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
29228f23e9faSHans Rosenfeld "fct_handle_fcp_event: "
292382527734SSukumar Swaminathan "Unable to reacquire fct_cmd. type=%x",
292482527734SSukumar Swaminathan fct_cmd->cmd_type);
292582527734SSukumar Swaminathan
292682527734SSukumar Swaminathan return (1);
2927291a2b48SSukumar Swaminathan }
292882527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */
2929291a2b48SSukumar Swaminathan
2930fcf3ce44SJohn Forte cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
293182527734SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP;
2932291a2b48SSukumar Swaminathan
2933291a2b48SSukumar Swaminathan pkt = cmd_sbp->fct_pkt;
293482527734SSukumar Swaminathan cmd_sbp->fct_pkt = NULL;
2935fcf3ce44SJohn Forte
293682527734SSukumar Swaminathan dbuf = sbp->fct_buf;
2937fcf3ce44SJohn Forte
2938291a2b48SSukumar Swaminathan fct_cmd->cmd_comp_status = FCT_SUCCESS;
2939291a2b48SSukumar Swaminathan
2940291a2b48SSukumar Swaminathan if (status) {
2941b3660a96SSukumar Swaminathan emlxs_dma_error:
2942fcf3ce44SJohn Forte /*
2943291a2b48SSukumar Swaminathan * The error indicates this IO should be terminated
2944291a2b48SSukumar Swaminathan * immediately.
2945fcf3ce44SJohn Forte */
2946291a2b48SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_SEND_STATUS;
294782527734SSukumar Swaminathan fct_cmd->cmd_comp_status = FCT_FAILURE;
2948291a2b48SSukumar Swaminathan
294982527734SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED);
295082527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
2951291a2b48SSukumar Swaminathan
2952291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE
2953291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2954291a2b48SSukumar Swaminathan "fct_queue_cmd_for_termination:1 %p: x%x",
2955291a2b48SSukumar Swaminathan fct_cmd, fct_cmd->cmd_comp_status);
2956291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
295782527734SSukumar Swaminathan
2958291a2b48SSukumar Swaminathan MODSYM(fct_queue_cmd_for_termination) (fct_cmd,
2959291a2b48SSukumar Swaminathan FCT_ABTS_RECEIVED);
296082527734SSukumar Swaminathan
2961291a2b48SSukumar Swaminathan goto done;
2962291a2b48SSukumar Swaminathan }
2963291a2b48SSukumar Swaminathan
296482527734SSukumar Swaminathan switch (iocb->ULPCOMMAND) {
2965291a2b48SSukumar Swaminathan
2966291a2b48SSukumar Swaminathan /*
2967291a2b48SSukumar Swaminathan * FCP Data completion
2968291a2b48SSukumar Swaminathan */
2969fcf3ce44SJohn Forte case CMD_FCP_TSEND_CX:
2970fcf3ce44SJohn Forte case CMD_FCP_TSEND64_CX:
2971fcf3ce44SJohn Forte case CMD_FCP_TRECEIVE_CX:
2972fcf3ce44SJohn Forte case CMD_FCP_TRECEIVE64_CX:
2973fcf3ce44SJohn Forte
297482527734SSukumar Swaminathan if (dbuf->db_flags & DB_DIRECTION_FROM_RPORT) {
2975b3660a96SSukumar Swaminathan if (emlxs_fct_dbuf_dma_sync(hba, dbuf,
2976b3660a96SSukumar Swaminathan DDI_DMA_SYNC_FORCPU)) {
2977b3660a96SSukumar Swaminathan goto emlxs_dma_error;
2978b3660a96SSukumar Swaminathan }
297982527734SSukumar Swaminathan }
2980fcf3ce44SJohn Forte
298182527734SSukumar Swaminathan if ((cmd_sbp->fct_flags & EMLXS_FCT_SEND_STATUS) &&
298282527734SSukumar Swaminathan (iocb->ULPCT != 1)) {
2983291a2b48SSukumar Swaminathan
298482527734SSukumar Swaminathan dbuf->db_flags |= DB_STATUS_GOOD_SENT;
2985fcf3ce44SJohn Forte
298682527734SSukumar Swaminathan fct_task =
298782527734SSukumar Swaminathan (scsi_task_t *)fct_cmd->cmd_specific;
298882527734SSukumar Swaminathan fct_task->task_scsi_status = 0;
2989fcf3ce44SJohn Forte
299082527734SSukumar Swaminathan (void) emlxs_fct_send_fcp_status(fct_cmd);
299182527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
2992fcf3ce44SJohn Forte
299382527734SSukumar Swaminathan break;
299482527734SSukumar Swaminathan
299582527734SSukumar Swaminathan } else if ((cmd_sbp->fct_flags &
299682527734SSukumar Swaminathan EMLXS_FCT_SEND_STATUS) &&
299782527734SSukumar Swaminathan (iocb->ULPCT == 1)) {
299882527734SSukumar Swaminathan /* Auto-resp has been sent out by firmware */
299982527734SSukumar Swaminathan /* We can assume this is really a FC_TRSP_CX */
300082527734SSukumar Swaminathan
300182527734SSukumar Swaminathan dbuf->db_flags |= DB_STATUS_GOOD_SENT;
300282527734SSukumar Swaminathan fct_task =
300382527734SSukumar Swaminathan (scsi_task_t *)fct_cmd->cmd_specific;
300482527734SSukumar Swaminathan fct_task->task_scsi_status = 0;
300582527734SSukumar Swaminathan
300682527734SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_SEND_STATUS;
300782527734SSukumar Swaminathan
300882527734SSukumar Swaminathan goto auto_resp;
3009fcf3ce44SJohn Forte }
3010291a2b48SSukumar Swaminathan
3011fcf3ce44SJohn Forte cmd_sbp->fct_flags &= ~EMLXS_FCT_SEND_STATUS;
3012fcf3ce44SJohn Forte
3013fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
301482527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
301582527734SSukumar Swaminathan
3016fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
3017fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
3018fcf3ce44SJohn Forte "fct_scsi_data_xfer_done:1 %p %p", fct_cmd, dbuf);
3019291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
302082527734SSukumar Swaminathan
3021fcf3ce44SJohn Forte MODSYM(fct_scsi_data_xfer_done) (fct_cmd, dbuf, 0);
3022fcf3ce44SJohn Forte
3023fcf3ce44SJohn Forte break;
3024fcf3ce44SJohn Forte
3025fcf3ce44SJohn Forte /* FCP Status completion */
3026fcf3ce44SJohn Forte case CMD_FCP_TRSP_CX:
3027fcf3ce44SJohn Forte case CMD_FCP_TRSP64_CX:
3028fcf3ce44SJohn Forte
302982527734SSukumar Swaminathan auto_resp:
303082527734SSukumar Swaminathan /* Copy these before calling emlxs_fct_cmd_done */
303182527734SSukumar Swaminathan fct_flags = cmd_sbp->fct_flags;
303282527734SSukumar Swaminathan fct_buf = cmd_sbp->fct_buf;
3033fcf3ce44SJohn Forte
303482527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_IO_DONE);
303582527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
3036fcf3ce44SJohn Forte
303782527734SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--;
3038fcf3ce44SJohn Forte
303982527734SSukumar Swaminathan if (fct_flags & EMLXS_FCT_SEND_STATUS) {
3040fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
3041fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
30428f23e9faSHans Rosenfeld "fct_scsi_data_xfer_done:2 %p %p outio %d",
30438f23e9faSHans Rosenfeld fct_cmd, fct_buf, TGTPORTSTAT.FctOutstandingIO);
3044291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
304582527734SSukumar Swaminathan
3046fcf3ce44SJohn Forte MODSYM(fct_scsi_data_xfer_done) (fct_cmd,
304782527734SSukumar Swaminathan fct_buf, FCT_IOF_FCA_DONE);
3048fcf3ce44SJohn Forte } else {
3049fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
3050fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
30518f23e9faSHans Rosenfeld "fct_send_response_done:1 %p: x%x outio %d",
30528f23e9faSHans Rosenfeld fct_cmd, fct_cmd->cmd_comp_status,
30538f23e9faSHans Rosenfeld TGTPORTSTAT.FctOutstandingIO);
3054291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
305582527734SSukumar Swaminathan
3056fcf3ce44SJohn Forte MODSYM(fct_send_response_done) (fct_cmd,
3057fcf3ce44SJohn Forte fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE);
3058fcf3ce44SJohn Forte }
3059fcf3ce44SJohn Forte break;
3060fcf3ce44SJohn Forte
3061fcf3ce44SJohn Forte default:
306282527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, 0);
306382527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
3064291a2b48SSukumar Swaminathan
3065fcf3ce44SJohn Forte TGTPORTSTAT.FctStray++;
3066fcf3ce44SJohn Forte TGTPORTSTAT.FctCompleted--;
3067fcf3ce44SJohn Forte
3068fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
306982527734SSukumar Swaminathan "Invalid iocb: cmd=0x%x", iocb->ULPCOMMAND);
3070fcf3ce44SJohn Forte
3071291a2b48SSukumar Swaminathan if (pkt) {
3072291a2b48SSukumar Swaminathan emlxs_pkt_complete(sbp, status,
3073291a2b48SSukumar Swaminathan iocb->un.grsp.perr.statLocalError, 1);
3074291a2b48SSukumar Swaminathan }
3075fcf3ce44SJohn Forte
307682527734SSukumar Swaminathan } /* switch(iocb->ULPCOMMAND) */
3077fcf3ce44SJohn Forte
3078fcf3ce44SJohn Forte
3079291a2b48SSukumar Swaminathan done:
3080291a2b48SSukumar Swaminathan if (pkt) {
3081291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt);
3082291a2b48SSukumar Swaminathan }
3083291a2b48SSukumar Swaminathan
3084fcf3ce44SJohn Forte if (status == IOSTAT_SUCCESS) {
3085fcf3ce44SJohn Forte TGTPORTSTAT.FctCmplGood++;
3086fcf3ce44SJohn Forte } else {
3087fcf3ce44SJohn Forte TGTPORTSTAT.FctCmplError++;
3088fcf3ce44SJohn Forte }
3089fcf3ce44SJohn Forte
3090fcf3ce44SJohn Forte return (0);
3091fcf3ce44SJohn Forte
309282527734SSukumar Swaminathan } /* emlxs_fct_handle_fcp_event() */
3093291a2b48SSukumar Swaminathan
3094291a2b48SSukumar Swaminathan
3095291a2b48SSukumar Swaminathan /* ARGSUSED */
3096291a2b48SSukumar Swaminathan extern int
emlxs_fct_handle_abort(emlxs_hba_t * hba,CHANNEL * cp,IOCBQ * iocbq)309782527734SSukumar Swaminathan emlxs_fct_handle_abort(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
3098291a2b48SSukumar Swaminathan {
3099291a2b48SSukumar Swaminathan emlxs_port_t *port = &PPORT;
3100291a2b48SSukumar Swaminathan IOCB *iocb;
3101291a2b48SSukumar Swaminathan emlxs_buf_t *sbp;
3102291a2b48SSukumar Swaminathan fc_packet_t *pkt;
3103291a2b48SSukumar Swaminathan
3104291a2b48SSukumar Swaminathan iocb = &iocbq->iocb;
3105291a2b48SSukumar Swaminathan sbp = (emlxs_buf_t *)iocbq->sbp;
3106291a2b48SSukumar Swaminathan
3107291a2b48SSukumar Swaminathan TGTPORTSTAT.FctEvent++;
3108291a2b48SSukumar Swaminathan
3109291a2b48SSukumar Swaminathan if (!sbp) {
3110291a2b48SSukumar Swaminathan /* completion with missing xmit command */
3111291a2b48SSukumar Swaminathan TGTPORTSTAT.FctStray++;
3112291a2b48SSukumar Swaminathan
3113291a2b48SSukumar Swaminathan /* emlxs_stray_fcp_completion_msg */
3114291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
31158f23e9faSHans Rosenfeld "ABORT event cmd=%x status=%x error=%x iotag=%d",
311682527734SSukumar Swaminathan iocb->ULPCOMMAND, iocb->ULPSTATUS,
311782527734SSukumar Swaminathan iocb->un.grsp.perr.statLocalError, iocb->ULPIOTAG);
3118291a2b48SSukumar Swaminathan
3119291a2b48SSukumar Swaminathan return (1);
3120291a2b48SSukumar Swaminathan }
3121291a2b48SSukumar Swaminathan
3122291a2b48SSukumar Swaminathan pkt = PRIV2PKT(sbp);
3123291a2b48SSukumar Swaminathan
3124291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE
3125291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
31268f23e9faSHans Rosenfeld "fct_handle_abort: %p:%p xri=%d cmd=%x status=%x",
31278f23e9faSHans Rosenfeld sbp->fct_cmd, sbp,
31288f23e9faSHans Rosenfeld iocb->ULPCONTEXT, iocb->ULPCOMMAND, iocb->ULPSTATUS);
3129291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
3130291a2b48SSukumar Swaminathan
31318f23e9faSHans Rosenfeld if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
31328f23e9faSHans Rosenfeld XRIobj_t *xrip;
31338f23e9faSHans Rosenfeld
31348f23e9faSHans Rosenfeld emlxs_sli4_free_xri(port, NULL, sbp->xrip, 1);
31358f23e9faSHans Rosenfeld xrip = emlxs_sli4_find_xri(port, iocb->ULPCONTEXT);
31368f23e9faSHans Rosenfeld if (!xrip || xrip->state == XRI_STATE_FREE) {
31378f23e9faSHans Rosenfeld goto exit;
31388f23e9faSHans Rosenfeld }
31398f23e9faSHans Rosenfeld
31408f23e9faSHans Rosenfeld if ((hba->fc_table[xrip->iotag]) &&
31418f23e9faSHans Rosenfeld (hba->fc_table[xrip->iotag] != STALE_PACKET)) {
31428f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
31438f23e9faSHans Rosenfeld "Cmd not aborted, retrying: xri=%d iotag=%d sbp=%p",
31448f23e9faSHans Rosenfeld xrip->XRI, xrip->iotag, hba->fc_table[xrip->iotag]);
31458f23e9faSHans Rosenfeld
31468f23e9faSHans Rosenfeld /* Abort retry */
31478f23e9faSHans Rosenfeld if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
31488f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
31498f23e9faSHans Rosenfeld "Abort retry failed xri=%x", xrip->XRI);
31508f23e9faSHans Rosenfeld } else {
31518f23e9faSHans Rosenfeld return (0);
31528f23e9faSHans Rosenfeld }
31538f23e9faSHans Rosenfeld }
31548f23e9faSHans Rosenfeld }
3155291a2b48SSukumar Swaminathan
31568f23e9faSHans Rosenfeld exit:
3157291a2b48SSukumar Swaminathan if (pkt) {
3158291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt);
3159291a2b48SSukumar Swaminathan }
3160291a2b48SSukumar Swaminathan return (0);
3161fcf3ce44SJohn Forte
316282527734SSukumar Swaminathan } /* emlxs_fct_handle_abort() */
3163fcf3ce44SJohn Forte
3164fcf3ce44SJohn Forte
3165fcf3ce44SJohn Forte extern int
emlxs_fct_handle_unsol_els(emlxs_port_t * port,CHANNEL * cp,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size)316682527734SSukumar Swaminathan emlxs_fct_handle_unsol_els(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
3167fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size)
3168fcf3ce44SJohn Forte {
3169fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
3170fcf3ce44SJohn Forte IOCB *iocb;
3171fcf3ce44SJohn Forte uint32_t cmd_code;
3172fcf3ce44SJohn Forte fct_cmd_t *fct_cmd;
3173fcf3ce44SJohn Forte fct_els_t *els;
3174fcf3ce44SJohn Forte uint32_t sid;
3175fcf3ce44SJohn Forte uint32_t padding;
3176fcf3ce44SJohn Forte uint8_t *bp;
3177fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp;
3178fcf3ce44SJohn Forte uint32_t rval;
3179fcf3ce44SJohn Forte
3180fcf3ce44SJohn Forte HBASTATS.ElsCmdReceived++;
3181fcf3ce44SJohn Forte
3182fcf3ce44SJohn Forte bp = mp->virt;
3183fcf3ce44SJohn Forte cmd_code = (*(uint32_t *)bp) & ELS_CMD_MASK;
3184fcf3ce44SJohn Forte iocb = &iocbq->iocb;
3185fcf3ce44SJohn Forte sid = iocb->un.elsreq.remoteID;
3186fcf3ce44SJohn Forte
3187fcf3ce44SJohn Forte if (!port->fct_port) {
31888f23e9faSHans Rosenfeld if (!(hba->flag & FC_ONLINE_MODE)) {
31898f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
31908f23e9faSHans Rosenfeld "%s: sid=%x. Adapter offline. Dropping...",
31918f23e9faSHans Rosenfeld emlxs_elscmd_xlate(cmd_code), sid);
31928f23e9faSHans Rosenfeld goto done;
31938f23e9faSHans Rosenfeld }
3194fcf3ce44SJohn Forte
31958f23e9faSHans Rosenfeld switch (cmd_code) {
31968f23e9faSHans Rosenfeld case ELS_CMD_LOGO:
31978f23e9faSHans Rosenfeld case ELS_CMD_PRLO:
31988f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
31998f23e9faSHans Rosenfeld "%s: sid=%x. Target unbound. Accepting...",
32008f23e9faSHans Rosenfeld emlxs_elscmd_xlate(cmd_code), sid);
32018f23e9faSHans Rosenfeld (void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC,
32028f23e9faSHans Rosenfeld ELS_CMD_LOGO, 0, 0);
32038f23e9faSHans Rosenfeld break;
32048f23e9faSHans Rosenfeld default:
32058f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
32068f23e9faSHans Rosenfeld "%s: sid=%x. Target unbound. Rejecting...",
32078f23e9faSHans Rosenfeld emlxs_elscmd_xlate(cmd_code), sid);
32088f23e9faSHans Rosenfeld (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
32098f23e9faSHans Rosenfeld cmd_code, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
32108f23e9faSHans Rosenfeld break;
32118f23e9faSHans Rosenfeld }
3212fcf3ce44SJohn Forte goto done;
3213fcf3ce44SJohn Forte }
3214291a2b48SSukumar Swaminathan
3215fcf3ce44SJohn Forte if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) {
3216fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
3217fcf3ce44SJohn Forte "%s: sid=%x. Target offline. Rejecting...",
3218fcf3ce44SJohn Forte emlxs_elscmd_xlate(cmd_code), sid);
3219fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code,
3220fcf3ce44SJohn Forte LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
3221fcf3ce44SJohn Forte
3222fcf3ce44SJohn Forte goto done;
3223fcf3ce44SJohn Forte }
3224291a2b48SSukumar Swaminathan
32258f23e9faSHans Rosenfeld #ifdef FCT_API_TRACE
32268f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
32278f23e9faSHans Rosenfeld "%s: sid=%x cnt=%d. Target rcv. ",
32288f23e9faSHans Rosenfeld emlxs_elscmd_xlate(cmd_code), sid, size);
32298f23e9faSHans Rosenfeld #endif /* FCT_API_TRACE */
32308f23e9faSHans Rosenfeld
3231fcf3ce44SJohn Forte /* Process the request */
3232fcf3ce44SJohn Forte switch (cmd_code) {
3233fcf3ce44SJohn Forte case ELS_CMD_FLOGI:
3234e2ca2865SSukumar Swaminathan rval = emlxs_fct_process_unsol_flogi(port, cp, iocbq, mp, size);
3235291a2b48SSukumar Swaminathan
3236291a2b48SSukumar Swaminathan if (!rval) {
3237291a2b48SSukumar Swaminathan ELS_PKT *els_pkt = (ELS_PKT *)bp;
3238e2ca2865SSukumar Swaminathan fct_flogi_xchg_t fx;
3239e2ca2865SSukumar Swaminathan
3240e2ca2865SSukumar Swaminathan bzero((uint8_t *)&fx, sizeof (fct_flogi_xchg_t));
3241291a2b48SSukumar Swaminathan
3242291a2b48SSukumar Swaminathan /* Save the FLOGI exchange information */
3243e2ca2865SSukumar Swaminathan fx.rsvd2 = iocb->ULPCONTEXT;
3244291a2b48SSukumar Swaminathan bcopy((caddr_t)&els_pkt->un.logi.nodeName,
3245e2ca2865SSukumar Swaminathan (caddr_t)fx.fx_nwwn, 8);
3246291a2b48SSukumar Swaminathan bcopy((caddr_t)&els_pkt->un.logi.portName,
3247e2ca2865SSukumar Swaminathan (caddr_t)fx.fx_pwwn, 8);
3248e2ca2865SSukumar Swaminathan fx.fx_sid = sid;
3249e2ca2865SSukumar Swaminathan fx.fx_did = iocb->un.elsreq.myID;
3250e2ca2865SSukumar Swaminathan fx.fx_fport = els_pkt->un.logi.cmn.fPort;
3251e2ca2865SSukumar Swaminathan fx.fx_op = ELS_OP_FLOGI;
3252e2ca2865SSukumar Swaminathan
3253e2ca2865SSukumar Swaminathan emlxs_fct_handle_unsol_flogi(port, &fx, 1);
3254291a2b48SSukumar Swaminathan }
3255e2ca2865SSukumar Swaminathan
3256291a2b48SSukumar Swaminathan goto done;
3257fcf3ce44SJohn Forte
3258fcf3ce44SJohn Forte case ELS_CMD_PLOGI:
3259291a2b48SSukumar Swaminathan rval =
326082527734SSukumar Swaminathan emlxs_fct_process_unsol_plogi(port, cp, iocbq, mp, size);
3261fcf3ce44SJohn Forte break;
3262fcf3ce44SJohn Forte
3263fcf3ce44SJohn Forte default:
3264fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
3265fcf3ce44SJohn Forte "%s: sid=0x%x", emlxs_elscmd_xlate(cmd_code), sid);
3266fcf3ce44SJohn Forte rval = 0;
3267fcf3ce44SJohn Forte break;
3268fcf3ce44SJohn Forte }
3269fcf3ce44SJohn Forte
3270fcf3ce44SJohn Forte if (rval) {
3271fcf3ce44SJohn Forte goto done;
3272fcf3ce44SJohn Forte }
3273291a2b48SSukumar Swaminathan
3274fcf3ce44SJohn Forte padding = (8 - (size & 7)) & 7;
3275fcf3ce44SJohn Forte
3276fcf3ce44SJohn Forte fct_cmd = (fct_cmd_t *)MODSYM(fct_alloc) (FCT_STRUCT_CMD_RCVD_ELS,
3277291a2b48SSukumar Swaminathan (size + padding + GET_STRUCT_SIZE(emlxs_buf_t)),
3278291a2b48SSukumar Swaminathan AF_FORCE_NOSLEEP);
3279fcf3ce44SJohn Forte
3280fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
3281fcf3ce44SJohn Forte {
3282fcf3ce44SJohn Forte uint32_t *ptr = (uint32_t *)bp;
3283fcf3ce44SJohn Forte
3284fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
3285fcf3ce44SJohn Forte "fct_alloc %p: ELS rcvd: rxid=%x payload: x%x x%x",
328682527734SSukumar Swaminathan fct_cmd, iocb->ULPCONTEXT, *ptr, *(ptr + 1));
3287fcf3ce44SJohn Forte }
3288291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
3289fcf3ce44SJohn Forte
3290fcf3ce44SJohn Forte if (fct_cmd == NULL) {
3291fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
3292fcf3ce44SJohn Forte "%s: sid=%x. Out of memory. Rejecting...",
3293fcf3ce44SJohn Forte emlxs_elscmd_xlate(cmd_code), sid);
3294fcf3ce44SJohn Forte
3295fcf3ce44SJohn Forte (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code,
3296fcf3ce44SJohn Forte LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
3297fcf3ce44SJohn Forte goto done;
3298fcf3ce44SJohn Forte }
3299291a2b48SSukumar Swaminathan
3300fcf3ce44SJohn Forte /* Initialize fct_cmd */
3301fcf3ce44SJohn Forte fct_cmd->cmd_oxid = (cmd_code >> ELS_CMD_SHIFT) & 0xff;
330282527734SSukumar Swaminathan fct_cmd->cmd_rxid = iocb->ULPCONTEXT;
3303fcf3ce44SJohn Forte fct_cmd->cmd_rportid = sid;
3304fcf3ce44SJohn Forte fct_cmd->cmd_lportid = port->did;
33058f23e9faSHans Rosenfeld fct_cmd->cmd_rp_handle = FCT_HANDLE_NONE;
3306fcf3ce44SJohn Forte fct_cmd->cmd_port = port->fct_port;
3307fcf3ce44SJohn Forte
330882527734SSukumar Swaminathan cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd, EMLXS_FCT_ELS_CMD_RECEIVED);
330982527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */
3310fcf3ce44SJohn Forte
3311291a2b48SSukumar Swaminathan /* Initialize cmd_sbp */
331282527734SSukumar Swaminathan cmd_sbp->channel = cp;
331382527734SSukumar Swaminathan cmd_sbp->class = iocb->ULPCLASS;
3314fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_ELS_CMD;
3315291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_PLOGI_RECEIVED;
3316291a2b48SSukumar Swaminathan
3317fcf3ce44SJohn Forte bcopy((uint8_t *)iocb, (uint8_t *)&cmd_sbp->iocbq,
3318fcf3ce44SJohn Forte sizeof (emlxs_iocb_t));
3319fcf3ce44SJohn Forte
3320fcf3ce44SJohn Forte els = (fct_els_t *)fct_cmd->cmd_specific;
3321a9800bebSGarrett D'Amore els->els_req_size = (uint16_t)size;
3322291a2b48SSukumar Swaminathan els->els_req_payload =
3323291a2b48SSukumar Swaminathan GET_BYTE_OFFSET(fct_cmd->cmd_fca_private,
3324fcf3ce44SJohn Forte GET_STRUCT_SIZE(emlxs_buf_t));
3325fcf3ce44SJohn Forte bcopy(bp, els->els_req_payload, size);
3326fcf3ce44SJohn Forte
3327e2ca2865SSukumar Swaminathan
3328e2ca2865SSukumar Swaminathan /* Check if Offline */
3329e2ca2865SSukumar Swaminathan if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) {
3330e2ca2865SSukumar Swaminathan
3331e2ca2865SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
3332e2ca2865SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
3333e2ca2865SSukumar Swaminathan
3334e2ca2865SSukumar Swaminathan #ifdef FCT_API_TRACE
3335e2ca2865SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
3336e2ca2865SSukumar Swaminathan "fct_post_rcvd_cmd:4 %p: portid x%x", fct_cmd,
3337e2ca2865SSukumar Swaminathan fct_cmd->cmd_lportid);
3338e2ca2865SSukumar Swaminathan #endif /* FCT_API_TRACE */
3339e2ca2865SSukumar Swaminathan
3340e2ca2865SSukumar Swaminathan MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0);
3341e2ca2865SSukumar Swaminathan
3342e2ca2865SSukumar Swaminathan goto done;
3343e2ca2865SSukumar Swaminathan }
3344e2ca2865SSukumar Swaminathan
3345e2ca2865SSukumar Swaminathan /* Online */
33468f23e9faSHans Rosenfeld
3347e2ca2865SSukumar Swaminathan /* Check if Link up is acked */
33488f23e9faSHans Rosenfeld if (!(port->fct_flags & FCT_STATE_LINK_UP_ACKED)) {
33498f23e9faSHans Rosenfeld goto defer;
33508f23e9faSHans Rosenfeld }
3351e2ca2865SSukumar Swaminathan
33528f23e9faSHans Rosenfeld if ((cmd_code != ELS_CMD_FLOGI) &&
33538f23e9faSHans Rosenfeld !(port->fct_flags & FCT_STATE_FLOGI_CMPL)) {
33548f23e9faSHans Rosenfeld goto defer;
33558f23e9faSHans Rosenfeld }
33568f23e9faSHans Rosenfeld
33578f23e9faSHans Rosenfeld /* Post it to COMSTAR */
33588f23e9faSHans Rosenfeld emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
33598f23e9faSHans Rosenfeld /* mutex_exit(&cmd_sbp->fct_mtx); */
3360e2ca2865SSukumar Swaminathan
3361e2ca2865SSukumar Swaminathan #ifdef FCT_API_TRACE
33628f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
33638f23e9faSHans Rosenfeld "fct_post_rcvd_cmd:1 %p: portid x%x", fct_cmd,
33648f23e9faSHans Rosenfeld fct_cmd->cmd_lportid);
3365e2ca2865SSukumar Swaminathan #endif /* FCT_API_TRACE */
3366e2ca2865SSukumar Swaminathan
33678f23e9faSHans Rosenfeld MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0);
3368e2ca2865SSukumar Swaminathan
33698f23e9faSHans Rosenfeld goto done;
3370e2ca2865SSukumar Swaminathan
33718f23e9faSHans Rosenfeld defer:
3372e2ca2865SSukumar Swaminathan /* Defer processing of fct_cmd till later (after link up ack). */
3373e2ca2865SSukumar Swaminathan
33748f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
33758f23e9faSHans Rosenfeld "%s: sid=%x. Defer Processing x%x.",
33768f23e9faSHans Rosenfeld emlxs_elscmd_xlate(cmd_code), sid, port->fct_flags);
33778f23e9faSHans Rosenfeld
3378e2ca2865SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, EMLXS_FCT_CMD_WAITQ);
3379e2ca2865SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
3380e2ca2865SSukumar Swaminathan
3381e2ca2865SSukumar Swaminathan /* Add cmd_sbp to queue tail */
3382e2ca2865SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK);
3383e2ca2865SSukumar Swaminathan
3384e2ca2865SSukumar Swaminathan if (port->fct_wait_tail) {
3385e2ca2865SSukumar Swaminathan port->fct_wait_tail->next = cmd_sbp;
3386e2ca2865SSukumar Swaminathan }
3387e2ca2865SSukumar Swaminathan port->fct_wait_tail = cmd_sbp;
3388e2ca2865SSukumar Swaminathan
3389e2ca2865SSukumar Swaminathan if (!port->fct_wait_head) {
3390e2ca2865SSukumar Swaminathan port->fct_wait_head = cmd_sbp;
3391e2ca2865SSukumar Swaminathan }
3392e2ca2865SSukumar Swaminathan
3393e2ca2865SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK);
3394fcf3ce44SJohn Forte
3395fcf3ce44SJohn Forte done:
3396fcf3ce44SJohn Forte
3397fcf3ce44SJohn Forte return (0);
3398fcf3ce44SJohn Forte
339982527734SSukumar Swaminathan } /* emlxs_fct_handle_unsol_els() */
3400fcf3ce44SJohn Forte
3401fcf3ce44SJohn Forte
3402fcf3ce44SJohn Forte /* ARGSUSED */
3403fcf3ce44SJohn Forte static uint32_t
emlxs_fct_process_unsol_flogi(emlxs_port_t * port,CHANNEL * cp,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size)340482527734SSukumar Swaminathan emlxs_fct_process_unsol_flogi(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
3405fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size)
3406fcf3ce44SJohn Forte {
3407fcf3ce44SJohn Forte IOCB *iocb;
3408fcf3ce44SJohn Forte char buffer[64];
3409fcf3ce44SJohn Forte
3410fcf3ce44SJohn Forte buffer[0] = 0;
3411fcf3ce44SJohn Forte
3412fcf3ce44SJohn Forte iocb = &iocbq->iocb;
3413fcf3ce44SJohn Forte
3414fcf3ce44SJohn Forte /* Perform processing of FLOGI payload */
34158f23e9faSHans Rosenfeld if (emlxs_process_unsol_flogi(port, iocbq, mp, size, buffer,
34168f23e9faSHans Rosenfeld sizeof (buffer))) {
3417fcf3ce44SJohn Forte return (1);
3418fcf3ce44SJohn Forte }
3419291a2b48SSukumar Swaminathan
3420fe199829SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
3421fe199829SSukumar Swaminathan "FLOGI: sid=0x%x xid=%x %s",
3422fe199829SSukumar Swaminathan iocb->un.elsreq.remoteID, iocb->ULPIOTAG, buffer);
3423fcf3ce44SJohn Forte
3424fcf3ce44SJohn Forte return (0);
3425fcf3ce44SJohn Forte
342682527734SSukumar Swaminathan } /* emlxs_fct_process_unsol_flogi() */
3427fcf3ce44SJohn Forte
3428fcf3ce44SJohn Forte
3429fcf3ce44SJohn Forte /* ARGSUSED */
3430fcf3ce44SJohn Forte static uint32_t
emlxs_fct_process_unsol_plogi(emlxs_port_t * port,CHANNEL * cp,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size)343182527734SSukumar Swaminathan emlxs_fct_process_unsol_plogi(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
3432fcf3ce44SJohn Forte MATCHMAP *mp, uint32_t size)
3433fcf3ce44SJohn Forte {
3434fcf3ce44SJohn Forte IOCB *iocb;
3435fcf3ce44SJohn Forte char buffer[64];
3436fcf3ce44SJohn Forte
3437fcf3ce44SJohn Forte buffer[0] = 0;
3438fcf3ce44SJohn Forte
3439fcf3ce44SJohn Forte iocb = &iocbq->iocb;
3440fcf3ce44SJohn Forte
3441fcf3ce44SJohn Forte /* Perform processing of PLOGI payload */
34428f23e9faSHans Rosenfeld if (emlxs_process_unsol_plogi(port, iocbq, mp, size, buffer,
34438f23e9faSHans Rosenfeld sizeof (buffer))) {
3444fcf3ce44SJohn Forte return (1);
3445fcf3ce44SJohn Forte }
3446291a2b48SSukumar Swaminathan
3447fe199829SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
3448fe199829SSukumar Swaminathan "PLOGI: sid=0x%x xid=%x %s",
3449fe199829SSukumar Swaminathan iocb->un.elsreq.remoteID, iocb->ULPIOTAG, buffer);
3450fcf3ce44SJohn Forte
3451fcf3ce44SJohn Forte return (0);
3452fcf3ce44SJohn Forte
345382527734SSukumar Swaminathan } /* emlxs_fct_process_unsol_plogi() */
3454fcf3ce44SJohn Forte
3455fcf3ce44SJohn Forte
3456fcf3ce44SJohn Forte /* ARGSUSED */
3457fcf3ce44SJohn Forte static emlxs_buf_t *
emlxs_fct_pkt_init(emlxs_port_t * port,fct_cmd_t * fct_cmd,fc_packet_t * pkt)3458291a2b48SSukumar Swaminathan emlxs_fct_pkt_init(emlxs_port_t *port, fct_cmd_t *fct_cmd,
3459291a2b48SSukumar Swaminathan fc_packet_t *pkt)
3460fcf3ce44SJohn Forte {
3461fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp;
3462fcf3ce44SJohn Forte emlxs_buf_t *sbp;
3463fcf3ce44SJohn Forte
3464fcf3ce44SJohn Forte cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
3465fcf3ce44SJohn Forte
3466fcf3ce44SJohn Forte sbp = PKT2PRIV(pkt);
3467fcf3ce44SJohn Forte sbp->fct_cmd = cmd_sbp->fct_cmd;
3468fcf3ce44SJohn Forte sbp->node = cmd_sbp->node;
346982527734SSukumar Swaminathan sbp->channel = cmd_sbp->channel;
3470fcf3ce44SJohn Forte sbp->did = cmd_sbp->did;
3471fcf3ce44SJohn Forte sbp->lun = cmd_sbp->lun;
3472fcf3ce44SJohn Forte sbp->class = cmd_sbp->class;
3473fcf3ce44SJohn Forte sbp->fct_type = cmd_sbp->fct_type;
3474fcf3ce44SJohn Forte sbp->fct_state = cmd_sbp->fct_state;
34758f23e9faSHans Rosenfeld sbp->xrip = cmd_sbp->xrip;
34768f23e9faSHans Rosenfeld sbp->iotag = cmd_sbp->iotag;
3477fcf3ce44SJohn Forte
3478fcf3ce44SJohn Forte return (sbp);
3479fcf3ce44SJohn Forte
348082527734SSukumar Swaminathan } /* emlxs_fct_pkt_init() */
3481fcf3ce44SJohn Forte
3482fcf3ce44SJohn Forte
3483fcf3ce44SJohn Forte /* Mutex will be acquired */
3484fcf3ce44SJohn Forte static emlxs_buf_t *
emlxs_fct_cmd_init(emlxs_port_t * port,fct_cmd_t * fct_cmd,uint16_t fct_state)3485a9800bebSGarrett D'Amore emlxs_fct_cmd_init(emlxs_port_t *port, fct_cmd_t *fct_cmd, uint16_t fct_state)
3486fcf3ce44SJohn Forte {
3487fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
3488fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
3489fcf3ce44SJohn Forte
3490fcf3ce44SJohn Forte bzero((void *)cmd_sbp, sizeof (emlxs_buf_t));
3491291a2b48SSukumar Swaminathan mutex_init(&cmd_sbp->fct_mtx, NULL, MUTEX_DRIVER,
3492a9800bebSGarrett D'Amore DDI_INTR_PRI(hba->intr_arg));
3493a9800bebSGarrett D'Amore mutex_init(&cmd_sbp->mtx, NULL, MUTEX_DRIVER,
3494a9800bebSGarrett D'Amore DDI_INTR_PRI(hba->intr_arg));
3495fcf3ce44SJohn Forte
3496291a2b48SSukumar Swaminathan mutex_enter(&cmd_sbp->fct_mtx);
3497fcf3ce44SJohn Forte cmd_sbp->pkt_flags = PACKET_VALID;
3498fcf3ce44SJohn Forte cmd_sbp->port = port;
3499fcf3ce44SJohn Forte cmd_sbp->fct_cmd = fct_cmd;
3500fcf3ce44SJohn Forte cmd_sbp->node = (fct_cmd->cmd_rp) ?
3501fcf3ce44SJohn Forte *(emlxs_node_t **)fct_cmd->cmd_rp->rp_fca_private : NULL;
3502fcf3ce44SJohn Forte cmd_sbp->iocbq.sbp = cmd_sbp;
3503291a2b48SSukumar Swaminathan cmd_sbp->iocbq.port = port;
350482527734SSukumar Swaminathan cmd_sbp->did = fct_cmd->cmd_rportid;
350582527734SSukumar Swaminathan
350682527734SSukumar Swaminathan /* Flags fct_cmd as inuse */
350782527734SSukumar Swaminathan if ((fct_cmd->cmd_oxid == 0) && (fct_cmd->cmd_rxid == 0)) {
350882527734SSukumar Swaminathan fct_cmd->cmd_oxid = 0xffff;
350982527734SSukumar Swaminathan fct_cmd->cmd_rxid = 0xffff;
351082527734SSukumar Swaminathan }
351182527734SSukumar Swaminathan
351282527734SSukumar Swaminathan if (fct_state) {
351382527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, fct_state);
351482527734SSukumar Swaminathan }
3515fcf3ce44SJohn Forte
3516fcf3ce44SJohn Forte return (cmd_sbp);
3517fcf3ce44SJohn Forte
351882527734SSukumar Swaminathan } /* emlxs_fct_cmd_init() */
3519fcf3ce44SJohn Forte
3520fcf3ce44SJohn Forte
352182527734SSukumar Swaminathan /* Called after receiving fct_cmd from COMSTAR */
352282527734SSukumar Swaminathan static fct_status_t
emlxs_fct_cmd_accept(emlxs_port_t * port,fct_cmd_t * fct_cmd,uint16_t fct_state)352382527734SSukumar Swaminathan emlxs_fct_cmd_accept(emlxs_port_t *port, fct_cmd_t *fct_cmd, uint16_t fct_state)
3524fcf3ce44SJohn Forte {
3525fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
3526fcf3ce44SJohn Forte
352782527734SSukumar Swaminathan if (!(cmd_sbp->pkt_flags & PACKET_VALID)) {
352882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
35298f23e9faSHans Rosenfeld "fct_cmd_accept: "
353082527734SSukumar Swaminathan "Invalid fct_cmd found! fct_cmd=%p state=%x",
353182527734SSukumar Swaminathan fct_cmd, fct_state);
353282527734SSukumar Swaminathan
353382527734SSukumar Swaminathan return (FCT_NOT_FOUND);
353482527734SSukumar Swaminathan }
353582527734SSukumar Swaminathan
353682527734SSukumar Swaminathan mutex_enter(&cmd_sbp->fct_mtx);
353782527734SSukumar Swaminathan
353882527734SSukumar Swaminathan if (!(cmd_sbp->pkt_flags & PACKET_VALID)) {
353982527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx);
354082527734SSukumar Swaminathan
354182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
35428f23e9faSHans Rosenfeld "fct_cmd_accept:2 "
354382527734SSukumar Swaminathan "Invalid fct_cmd found! fct_cmd=%p state=%x",
354482527734SSukumar Swaminathan fct_cmd, fct_state);
354582527734SSukumar Swaminathan
354682527734SSukumar Swaminathan return (FCT_NOT_FOUND);
354782527734SSukumar Swaminathan }
354882527734SSukumar Swaminathan
354982527734SSukumar Swaminathan if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT_INP) {
355082527734SSukumar Swaminathan
355182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
35528f23e9faSHans Rosenfeld "fct_cmd_accept: "
355382527734SSukumar Swaminathan "Aborted fct_cmd found! fct_cmd=%p state=%x",
355482527734SSukumar Swaminathan fct_cmd, fct_state);
355582527734SSukumar Swaminathan
355682527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_ABORT_DONE);
355782527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
355882527734SSukumar Swaminathan
355982527734SSukumar Swaminathan MODSYM(fct_cmd_fca_aborted) (fct_cmd,
356082527734SSukumar Swaminathan FCT_ABORT_SUCCESS, FCT_IOF_FCA_DONE);
356182527734SSukumar Swaminathan
356282527734SSukumar Swaminathan return (FCT_NOT_FOUND);
356382527734SSukumar Swaminathan }
356482527734SSukumar Swaminathan
356582527734SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx);
356682527734SSukumar Swaminathan if (!(cmd_sbp->pkt_flags & PACKET_ULP_OWNED)) {
356782527734SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx);
356882527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx);
356982527734SSukumar Swaminathan
357082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
35718f23e9faSHans Rosenfeld "fct_cmd_accept: "
357282527734SSukumar Swaminathan "Busy fct_cmd found! fct_cmd=%p state=%x",
357382527734SSukumar Swaminathan fct_cmd, fct_state);
357482527734SSukumar Swaminathan
357582527734SSukumar Swaminathan return (FCT_BUSY);
357682527734SSukumar Swaminathan }
357782527734SSukumar Swaminathan cmd_sbp->pkt_flags &= ~PACKET_ULP_OWNED;
357882527734SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx);
357982527734SSukumar Swaminathan
358082527734SSukumar Swaminathan if (fct_state) {
358182527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, fct_state);
358282527734SSukumar Swaminathan }
358382527734SSukumar Swaminathan
358482527734SSukumar Swaminathan return (FCT_SUCCESS);
358582527734SSukumar Swaminathan
358682527734SSukumar Swaminathan } /* emlxs_fct_cmd_accept() */
358782527734SSukumar Swaminathan
358882527734SSukumar Swaminathan
358982527734SSukumar Swaminathan /* Called after receiving fct_cmd from driver */
359082527734SSukumar Swaminathan static fct_status_t
emlxs_fct_cmd_acquire(emlxs_port_t * port,fct_cmd_t * fct_cmd,uint16_t fct_state)359182527734SSukumar Swaminathan emlxs_fct_cmd_acquire(emlxs_port_t *port, fct_cmd_t *fct_cmd,
359282527734SSukumar Swaminathan uint16_t fct_state)
359382527734SSukumar Swaminathan {
359482527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
359582527734SSukumar Swaminathan
359682527734SSukumar Swaminathan if ((fct_cmd->cmd_oxid == 0) && (fct_cmd->cmd_rxid == 0)) {
359782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
35988f23e9faSHans Rosenfeld "fct_cmd_acquire: "
359982527734SSukumar Swaminathan "Bad fct_cmd found! fct_cmd=%p state=%x",
360082527734SSukumar Swaminathan fct_cmd, fct_state);
360182527734SSukumar Swaminathan
360282527734SSukumar Swaminathan return (FCT_NOT_FOUND);
360382527734SSukumar Swaminathan }
360482527734SSukumar Swaminathan
360582527734SSukumar Swaminathan if (!(cmd_sbp->pkt_flags & PACKET_VALID)) {
360682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
36078f23e9faSHans Rosenfeld "fct_cmd_acquire: "
360882527734SSukumar Swaminathan "Invalid fct_cmd found! fct_cmd=%p state=%x",
360982527734SSukumar Swaminathan fct_cmd, fct_state);
361082527734SSukumar Swaminathan
361182527734SSukumar Swaminathan return (FCT_NOT_FOUND);
361282527734SSukumar Swaminathan }
361382527734SSukumar Swaminathan
361482527734SSukumar Swaminathan if ((cmd_sbp->pkt_flags & PACKET_ULP_OWNED)) {
361582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
36168f23e9faSHans Rosenfeld "fct_cmd_acquire: "
361782527734SSukumar Swaminathan "Returned fct_cmd found! fct_cmd=%p state=%x",
361882527734SSukumar Swaminathan fct_cmd, fct_state);
361982527734SSukumar Swaminathan
362082527734SSukumar Swaminathan return (FCT_NOT_FOUND);
362182527734SSukumar Swaminathan }
362282527734SSukumar Swaminathan
362382527734SSukumar Swaminathan mutex_enter(&cmd_sbp->fct_mtx);
362482527734SSukumar Swaminathan
362582527734SSukumar Swaminathan if ((fct_cmd->cmd_oxid == 0) && (fct_cmd->cmd_rxid == 0)) {
362682527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx);
362782527734SSukumar Swaminathan
362882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
36298f23e9faSHans Rosenfeld "fct_cmd_acquire:2 "
363082527734SSukumar Swaminathan "Bad fct_cmd found! fct_cmd=%p state=%x",
363182527734SSukumar Swaminathan fct_cmd, fct_state);
3632291a2b48SSukumar Swaminathan
363382527734SSukumar Swaminathan return (FCT_NOT_FOUND);
363482527734SSukumar Swaminathan }
3635291a2b48SSukumar Swaminathan
3636fcf3ce44SJohn Forte if (!(cmd_sbp->pkt_flags & PACKET_VALID)) {
363782527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx);
363882527734SSukumar Swaminathan
363982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
36408f23e9faSHans Rosenfeld "fct_cmd_acquire:2 "
364182527734SSukumar Swaminathan "Invalid fct_cmd found! fct_cmd=%p state=%x",
364282527734SSukumar Swaminathan fct_cmd, fct_state);
364382527734SSukumar Swaminathan
364482527734SSukumar Swaminathan return (FCT_NOT_FOUND);
364582527734SSukumar Swaminathan }
364682527734SSukumar Swaminathan
364782527734SSukumar Swaminathan if ((cmd_sbp->pkt_flags & PACKET_ULP_OWNED)) {
364882527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx);
364982527734SSukumar Swaminathan
365082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
36518f23e9faSHans Rosenfeld "fct_cmd_acquire:2 "
365282527734SSukumar Swaminathan "Returned fct_cmd found! fct_cmd=%p state=%x",
365382527734SSukumar Swaminathan fct_cmd, fct_state);
365482527734SSukumar Swaminathan
365582527734SSukumar Swaminathan return (FCT_NOT_FOUND);
365682527734SSukumar Swaminathan }
365782527734SSukumar Swaminathan
365882527734SSukumar Swaminathan if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT_INP) {
365982527734SSukumar Swaminathan
366082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
36618f23e9faSHans Rosenfeld "fct_cmd_acquire: "
366282527734SSukumar Swaminathan "Aborting cmd. fct_cmd=%p state=%x",
366382527734SSukumar Swaminathan fct_cmd, fct_state);
366482527734SSukumar Swaminathan
366582527734SSukumar Swaminathan if (fct_cmd->cmd_type == FCT_CMD_FCP_XCHG) {
366682527734SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--;
366782527734SSukumar Swaminathan }
366882527734SSukumar Swaminathan
366982527734SSukumar Swaminathan fct_cmd->cmd_comp_status = FCT_FAILURE;
367082527734SSukumar Swaminathan
367182527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_ABORT_DONE);
367282527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
367382527734SSukumar Swaminathan
367482527734SSukumar Swaminathan MODSYM(fct_cmd_fca_aborted) (fct_cmd,
367582527734SSukumar Swaminathan FCT_ABORT_SUCCESS, FCT_IOF_FCA_DONE);
367682527734SSukumar Swaminathan
367782527734SSukumar Swaminathan return (FCT_NOT_FOUND);
367882527734SSukumar Swaminathan }
367982527734SSukumar Swaminathan
368082527734SSukumar Swaminathan if (fct_state) {
368182527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, fct_state);
368282527734SSukumar Swaminathan }
368382527734SSukumar Swaminathan
368482527734SSukumar Swaminathan return (FCT_SUCCESS);
368582527734SSukumar Swaminathan
368682527734SSukumar Swaminathan } /* emlxs_fct_cmd_acquire() */
368782527734SSukumar Swaminathan
368882527734SSukumar Swaminathan
368982527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be held to enter */
369082527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be released before exiting */
369182527734SSukumar Swaminathan /* Called before transitionally sending fct_cmd to driver */
369282527734SSukumar Swaminathan /*ARGSUSED*/
369382527734SSukumar Swaminathan static void
emlxs_fct_cmd_release(emlxs_port_t * port,fct_cmd_t * fct_cmd,uint16_t fct_state)369482527734SSukumar Swaminathan emlxs_fct_cmd_release(emlxs_port_t *port, fct_cmd_t *fct_cmd,
369582527734SSukumar Swaminathan uint16_t fct_state)
369682527734SSukumar Swaminathan {
369782527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
369882527734SSukumar Swaminathan
369982527734SSukumar Swaminathan if (fct_state) {
370082527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, fct_state);
3701fcf3ce44SJohn Forte }
3702291a2b48SSukumar Swaminathan
370382527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx);
370482527734SSukumar Swaminathan
370582527734SSukumar Swaminathan return;
370682527734SSukumar Swaminathan
370782527734SSukumar Swaminathan } /* emlxs_fct_cmd_release() */
370882527734SSukumar Swaminathan
370982527734SSukumar Swaminathan
371082527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be held to enter */
371182527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be released before exiting */
371282527734SSukumar Swaminathan /* Called before posting fct_cmd back to COMSTAR */
371382527734SSukumar Swaminathan /*ARGSUSED*/
371482527734SSukumar Swaminathan static void
emlxs_fct_cmd_post(emlxs_port_t * port,fct_cmd_t * fct_cmd,uint16_t fct_state)371582527734SSukumar Swaminathan emlxs_fct_cmd_post(emlxs_port_t *port, fct_cmd_t *fct_cmd,
371682527734SSukumar Swaminathan uint16_t fct_state)
371782527734SSukumar Swaminathan {
371882527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
371982527734SSukumar Swaminathan fc_packet_t *pkt;
372082527734SSukumar Swaminathan
372182527734SSukumar Swaminathan pkt = cmd_sbp->fct_pkt;
372282527734SSukumar Swaminathan cmd_sbp->fct_pkt = NULL;
372382527734SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP;
372482527734SSukumar Swaminathan
372582527734SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx);
372682527734SSukumar Swaminathan cmd_sbp->pkt_flags |= PACKET_ULP_OWNED;
372782527734SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx);
372882527734SSukumar Swaminathan
372982527734SSukumar Swaminathan if (fct_state) {
373082527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, fct_state);
373182527734SSukumar Swaminathan }
373282527734SSukumar Swaminathan
373382527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx);
373482527734SSukumar Swaminathan
373582527734SSukumar Swaminathan if (pkt) {
373682527734SSukumar Swaminathan emlxs_pkt_free(pkt);
373782527734SSukumar Swaminathan }
373882527734SSukumar Swaminathan
373982527734SSukumar Swaminathan return;
374082527734SSukumar Swaminathan
374182527734SSukumar Swaminathan } /* emlxs_fct_cmd_post() */
374282527734SSukumar Swaminathan
374382527734SSukumar Swaminathan
374482527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be held to enter */
374582527734SSukumar Swaminathan /* Called before completing fct_cmd back to COMSTAR */
374682527734SSukumar Swaminathan static void
emlxs_fct_cmd_done(emlxs_port_t * port,fct_cmd_t * fct_cmd,uint16_t fct_state)374782527734SSukumar Swaminathan emlxs_fct_cmd_done(emlxs_port_t *port, fct_cmd_t *fct_cmd, uint16_t fct_state)
374882527734SSukumar Swaminathan {
374982527734SSukumar Swaminathan emlxs_hba_t *hba = HBA;
375082527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
375182527734SSukumar Swaminathan fc_packet_t *pkt;
375282527734SSukumar Swaminathan
375382527734SSukumar Swaminathan /* Flags fct_cmd is no longer used */
375482527734SSukumar Swaminathan fct_cmd->cmd_oxid = 0;
375582527734SSukumar Swaminathan fct_cmd->cmd_rxid = 0;
375682527734SSukumar Swaminathan
3757fcf3ce44SJohn Forte if (cmd_sbp->iotag != 0) {
3758fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
37598f23e9faSHans Rosenfeld "Pkt still registered! channel=%p iotag=%d sbp=%p",
376082527734SSukumar Swaminathan cmd_sbp->channel, cmd_sbp->iotag, cmd_sbp);
376182527734SSukumar Swaminathan
376282527734SSukumar Swaminathan if (cmd_sbp->channel) {
376382527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
37648f23e9faSHans Rosenfeld emlxs_sli4_free_xri(port, cmd_sbp,
37658f23e9faSHans Rosenfeld cmd_sbp->xrip, 1);
376682527734SSukumar Swaminathan } else {
376782527734SSukumar Swaminathan (void) emlxs_unregister_pkt(cmd_sbp->channel,
376882527734SSukumar Swaminathan cmd_sbp->iotag, 0);
376982527734SSukumar Swaminathan }
3770fcf3ce44SJohn Forte
3771fcf3ce44SJohn Forte }
3772fcf3ce44SJohn Forte }
3773291a2b48SSukumar Swaminathan
377482527734SSukumar Swaminathan pkt = cmd_sbp->fct_pkt;
377582527734SSukumar Swaminathan cmd_sbp->fct_pkt = NULL;
377682527734SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP;
377782527734SSukumar Swaminathan
377882527734SSukumar Swaminathan if (fct_state) {
377982527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, fct_state);
378082527734SSukumar Swaminathan }
3781fcf3ce44SJohn Forte
378282527734SSukumar Swaminathan mutex_enter(&cmd_sbp->mtx);
378382527734SSukumar Swaminathan cmd_sbp->pkt_flags |= PACKET_ULP_OWNED;
378482527734SSukumar Swaminathan cmd_sbp->pkt_flags &= ~PACKET_VALID;
378582527734SSukumar Swaminathan mutex_exit(&cmd_sbp->mtx);
3786291a2b48SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx);
378782527734SSukumar Swaminathan
378882527734SSukumar Swaminathan
3789291a2b48SSukumar Swaminathan mutex_destroy(&cmd_sbp->fct_mtx);
379082527734SSukumar Swaminathan mutex_destroy(&cmd_sbp->mtx);
379182527734SSukumar Swaminathan
379282527734SSukumar Swaminathan if (pkt) {
379382527734SSukumar Swaminathan emlxs_pkt_free(pkt);
379482527734SSukumar Swaminathan }
3795fcf3ce44SJohn Forte
379682527734SSukumar Swaminathan return;
3797fcf3ce44SJohn Forte
379882527734SSukumar Swaminathan } /* emlxs_fct_cmd_done() */
3799fcf3ce44SJohn Forte
3800fcf3ce44SJohn Forte
3801fcf3ce44SJohn Forte static void
emlxs_fct_pkt_comp(fc_packet_t * pkt)3802fcf3ce44SJohn Forte emlxs_fct_pkt_comp(fc_packet_t *pkt)
3803fcf3ce44SJohn Forte {
3804fcf3ce44SJohn Forte emlxs_port_t *port;
3805291a2b48SSukumar Swaminathan #ifdef FMA_SUPPORT
3806291a2b48SSukumar Swaminathan emlxs_hba_t *hba;
3807291a2b48SSukumar Swaminathan #endif /* FMA_SUPPORT */
3808fcf3ce44SJohn Forte emlxs_buf_t *sbp;
3809fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp;
3810fcf3ce44SJohn Forte fct_cmd_t *fct_cmd;
3811fcf3ce44SJohn Forte fct_els_t *fct_els;
3812fcf3ce44SJohn Forte fct_sol_ct_t *fct_ct;
381382527734SSukumar Swaminathan fct_status_t rval;
3814fcf3ce44SJohn Forte
3815fcf3ce44SJohn Forte sbp = PKT2PRIV(pkt);
3816fcf3ce44SJohn Forte port = sbp->port;
3817291a2b48SSukumar Swaminathan #ifdef FMA_SUPPORT
3818291a2b48SSukumar Swaminathan hba = HBA;
3819291a2b48SSukumar Swaminathan #endif /* FMA_SUPPORT */
3820fcf3ce44SJohn Forte fct_cmd = sbp->fct_cmd;
3821291a2b48SSukumar Swaminathan
382282527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, EMLXS_FCT_PKT_COMPLETE);
382382527734SSukumar Swaminathan if (rval) {
382482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
38258f23e9faSHans Rosenfeld "fct_pkt_comp: "
382682527734SSukumar Swaminathan "Unable to reacquire fct_cmd.");
382782527734SSukumar Swaminathan return;
3828291a2b48SSukumar Swaminathan }
382982527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */
3830fcf3ce44SJohn Forte
383182527734SSukumar Swaminathan cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
383282527734SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP;
3833fcf3ce44SJohn Forte cmd_sbp->fct_pkt = NULL;
3834fcf3ce44SJohn Forte
3835291a2b48SSukumar Swaminathan switch (fct_cmd->cmd_type) {
3836291a2b48SSukumar Swaminathan case FCT_CMD_FCP_XCHG:
3837291a2b48SSukumar Swaminathan if ((pkt->pkt_reason == FC_REASON_ABORTED) ||
3838291a2b48SSukumar Swaminathan (pkt->pkt_reason == FC_REASON_XCHG_DROPPED) ||
3839291a2b48SSukumar Swaminathan (pkt->pkt_reason == FC_REASON_OFFLINE)) {
3840291a2b48SSukumar Swaminathan /*
3841291a2b48SSukumar Swaminathan * The error indicates this IO should be terminated
3842291a2b48SSukumar Swaminathan * immediately.
3843291a2b48SSukumar Swaminathan */
3844291a2b48SSukumar Swaminathan cmd_sbp->fct_flags &= ~EMLXS_FCT_SEND_STATUS;
3845fcf3ce44SJohn Forte
384682527734SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED);
384782527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
3848fcf3ce44SJohn Forte
3849291a2b48SSukumar Swaminathan #ifdef FCT_API_TRACE
3850291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
38518f23e9faSHans Rosenfeld "fct_queue_cmd_for_termination:2 %p:%p x%x",
38528f23e9faSHans Rosenfeld fct_cmd, cmd_sbp, fct_cmd->cmd_comp_status);
3853291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
385482527734SSukumar Swaminathan
3855291a2b48SSukumar Swaminathan MODSYM(fct_queue_cmd_for_termination) (fct_cmd,
3856291a2b48SSukumar Swaminathan FCT_ABTS_RECEIVED);
385782527734SSukumar Swaminathan
385882527734SSukumar Swaminathan break;
3859291a2b48SSukumar Swaminathan }
3860fcf3ce44SJohn Forte
386182527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp,
3862291a2b48SSukumar Swaminathan EMLXS_FCT_PKT_FCPRSP_COMPLETE);
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,
38698f23e9faSHans Rosenfeld "fct_send_response_done:2 %p:%p x%x outio %d",
38708f23e9faSHans Rosenfeld fct_cmd, cmd_sbp, fct_cmd->cmd_comp_status,
38718f23e9faSHans Rosenfeld TGTPORTSTAT.FctOutstandingIO);
3872fcf3ce44SJohn Forte #else
3873fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
38748f23e9faSHans Rosenfeld "fct_pkt_comp: fct_send_response_done. dbuf=%p",
3875fcf3ce44SJohn Forte sbp->fct_buf);
3876291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
3877291a2b48SSukumar Swaminathan
3878291a2b48SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--;
3879fcf3ce44SJohn Forte
3880fcf3ce44SJohn Forte MODSYM(fct_send_response_done) (fct_cmd,
3881fcf3ce44SJohn Forte fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE);
3882fcf3ce44SJohn Forte
3883fcf3ce44SJohn Forte break;
3884fcf3ce44SJohn Forte
3885fcf3ce44SJohn Forte case FCT_CMD_RCVD_ELS:
3886fcf3ce44SJohn Forte
388782527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp,
3888291a2b48SSukumar Swaminathan EMLXS_FCT_PKT_ELSRSP_COMPLETE);
3889291a2b48SSukumar Swaminathan
389082527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_IO_DONE);
3891291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
3892fcf3ce44SJohn Forte
3893fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
3894fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
38958f23e9faSHans Rosenfeld "fct_send_response_done:3 %p:%p x%x",
38968f23e9faSHans Rosenfeld fct_cmd, cmd_sbp, fct_cmd->cmd_comp_status);
3897291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
389882527734SSukumar Swaminathan
3899fcf3ce44SJohn Forte MODSYM(fct_send_response_done) (fct_cmd,
3900fcf3ce44SJohn Forte fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE);
3901fcf3ce44SJohn Forte
3902fcf3ce44SJohn Forte break;
3903fcf3ce44SJohn Forte
3904fcf3ce44SJohn Forte case FCT_CMD_SOL_ELS:
3905291a2b48SSukumar Swaminathan
390682527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp,
3907291a2b48SSukumar Swaminathan EMLXS_FCT_PKT_ELSCMD_COMPLETE);
3908291a2b48SSukumar Swaminathan
3909fcf3ce44SJohn Forte fct_els = (fct_els_t *)fct_cmd->cmd_specific;
3910fcf3ce44SJohn Forte
3911fcf3ce44SJohn Forte if (fct_els->els_resp_payload) {
391282527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0,
3913291a2b48SSukumar Swaminathan pkt->pkt_rsplen, DDI_DMA_SYNC_FORKERNEL);
3914fcf3ce44SJohn Forte
3915fcf3ce44SJohn Forte bcopy((uint8_t *)pkt->pkt_resp,
3916fcf3ce44SJohn Forte (uint8_t *)fct_els->els_resp_payload,
3917fcf3ce44SJohn Forte fct_els->els_resp_size);
3918fcf3ce44SJohn Forte }
3919291a2b48SSukumar Swaminathan
392082527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_IO_DONE);
3921291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
3922fcf3ce44SJohn Forte
3923fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
3924fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
39258f23e9faSHans Rosenfeld "fct_send_cmd_done:1 %p:%p x%x",
39268f23e9faSHans Rosenfeld fct_cmd, cmd_sbp, fct_cmd->cmd_comp_status);
3927291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
392882527734SSukumar Swaminathan
3929b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT
3930b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, pkt->pkt_resp_dma)
3931b3660a96SSukumar Swaminathan != DDI_FM_OK) {
3932b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT,
3933b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg,
39348f23e9faSHans Rosenfeld "fct_pkt_comp: hdl=%p",
3935b3660a96SSukumar Swaminathan pkt->pkt_resp_dma);
3936b3660a96SSukumar Swaminathan MODSYM(fct_send_cmd_done) (fct_cmd, FCT_FAILURE,
3937b3660a96SSukumar Swaminathan FCT_IOF_FCA_DONE);
3938b3660a96SSukumar Swaminathan
3939b3660a96SSukumar Swaminathan break;
3940b3660a96SSukumar Swaminathan }
3941b3660a96SSukumar Swaminathan #endif /* FMA_SUPPORT */
3942b3660a96SSukumar Swaminathan
3943291a2b48SSukumar Swaminathan MODSYM(fct_send_cmd_done) (fct_cmd, FCT_SUCCESS,
3944291a2b48SSukumar Swaminathan FCT_IOF_FCA_DONE);
3945fcf3ce44SJohn Forte
3946fcf3ce44SJohn Forte break;
3947fcf3ce44SJohn Forte
3948fcf3ce44SJohn Forte case FCT_CMD_SOL_CT:
3949291a2b48SSukumar Swaminathan
395082527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp,
3951291a2b48SSukumar Swaminathan EMLXS_FCT_PKT_CTCMD_COMPLETE);
3952291a2b48SSukumar Swaminathan
3953fcf3ce44SJohn Forte fct_ct = (fct_sol_ct_t *)fct_cmd->cmd_specific;
3954fcf3ce44SJohn Forte
3955fcf3ce44SJohn Forte if (fct_ct->ct_resp_payload) {
395682527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0,
3957291a2b48SSukumar Swaminathan pkt->pkt_rsplen, DDI_DMA_SYNC_FORKERNEL);
3958fcf3ce44SJohn Forte
3959fcf3ce44SJohn Forte bcopy((uint8_t *)pkt->pkt_resp,
3960fcf3ce44SJohn Forte (uint8_t *)fct_ct->ct_resp_payload,
3961fcf3ce44SJohn Forte fct_ct->ct_resp_size);
3962fcf3ce44SJohn Forte }
3963291a2b48SSukumar Swaminathan
396482527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_IO_DONE);
3965291a2b48SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
3966fcf3ce44SJohn Forte
3967fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
3968fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
39698f23e9faSHans Rosenfeld "fct_send_cmd_done:2 %p:%p x%x",
39708f23e9faSHans Rosenfeld fct_cmd, cmd_sbp, fct_cmd->cmd_comp_status);
3971291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
397282527734SSukumar Swaminathan
3973b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT
3974b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, pkt->pkt_resp_dma)
3975b3660a96SSukumar Swaminathan != DDI_FM_OK) {
3976b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT,
3977b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg,
39788f23e9faSHans Rosenfeld "fct_pkt_comp: hdl=%p",
3979b3660a96SSukumar Swaminathan pkt->pkt_resp_dma);
3980b3660a96SSukumar Swaminathan MODSYM(fct_send_cmd_done) (fct_cmd, FCT_FAILURE,
3981b3660a96SSukumar Swaminathan FCT_IOF_FCA_DONE);
3982b3660a96SSukumar Swaminathan
3983b3660a96SSukumar Swaminathan break;
3984b3660a96SSukumar Swaminathan }
3985b3660a96SSukumar Swaminathan #endif /* FMA_SUPPORT */
3986291a2b48SSukumar Swaminathan MODSYM(fct_send_cmd_done) (fct_cmd, FCT_SUCCESS,
3987291a2b48SSukumar Swaminathan FCT_IOF_FCA_DONE);
398882527734SSukumar Swaminathan
3989fcf3ce44SJohn Forte break;
3990fcf3ce44SJohn Forte
3991fcf3ce44SJohn Forte default:
3992fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
39938f23e9faSHans Rosenfeld "fct_pkt_comp: Invalid cmd type found. type=%x",
3994fcf3ce44SJohn Forte fct_cmd->cmd_type);
3995fcf3ce44SJohn Forte
399682527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd, EMLXS_FCT_IO_DONE);
399782527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
399882527734SSukumar Swaminathan
399982527734SSukumar Swaminathan break;
4000fcf3ce44SJohn Forte }
4001fcf3ce44SJohn Forte
4002fcf3ce44SJohn Forte emlxs_pkt_free(pkt);
4003fcf3ce44SJohn Forte return;
4004fcf3ce44SJohn Forte
400582527734SSukumar Swaminathan } /* emlxs_fct_pkt_comp() */
4006fcf3ce44SJohn Forte
4007fcf3ce44SJohn Forte
4008291a2b48SSukumar Swaminathan static void
emlxs_fct_abort_pkt_comp(fc_packet_t * pkt)4009291a2b48SSukumar Swaminathan emlxs_fct_abort_pkt_comp(fc_packet_t *pkt)
4010fcf3ce44SJohn Forte {
40118f23e9faSHans Rosenfeld #ifdef FCT_API_TRACE
4012291a2b48SSukumar Swaminathan emlxs_buf_t *sbp;
4013291a2b48SSukumar Swaminathan IOCBQ *iocbq;
4014291a2b48SSukumar Swaminathan IOCB *iocb;
40158f23e9faSHans Rosenfeld emlxs_port_t *port;
4016291a2b48SSukumar Swaminathan
4017291a2b48SSukumar Swaminathan sbp = PKT2PRIV(pkt);
40188f23e9faSHans Rosenfeld port = sbp->port;
4019291a2b48SSukumar Swaminathan iocbq = &sbp->iocbq;
4020291a2b48SSukumar Swaminathan iocb = &iocbq->iocb;
4021291a2b48SSukumar Swaminathan
4022291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
40238f23e9faSHans Rosenfeld "fct_abort_pkt_comp: %p: xri=%d cmd=%x status=%x",
40248f23e9faSHans Rosenfeld sbp->fct_cmd, sbp,
40258f23e9faSHans Rosenfeld iocb->ULPCONTEXT, iocb->ULPCOMMAND, iocb->ULPSTATUS);
4026291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
4027291a2b48SSukumar Swaminathan
4028291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt);
4029291a2b48SSukumar Swaminathan return;
4030291a2b48SSukumar Swaminathan
403182527734SSukumar Swaminathan } /* emlxs_fct_abort_pkt_comp() */
4032291a2b48SSukumar Swaminathan
4033291a2b48SSukumar Swaminathan
403482527734SSukumar Swaminathan /* COMSTAR ENTER POINT (INDIRECT) */
4035291a2b48SSukumar Swaminathan static fct_status_t
emlxs_fct_send_els_cmd(fct_cmd_t * fct_cmd)4036291a2b48SSukumar Swaminathan emlxs_fct_send_els_cmd(fct_cmd_t *fct_cmd)
4037291a2b48SSukumar Swaminathan {
4038291a2b48SSukumar Swaminathan emlxs_port_t *port =
4039291a2b48SSukumar Swaminathan (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
4040fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
4041fcf3ce44SJohn Forte uint32_t did;
40428f23e9faSHans Rosenfeld uint32_t sid;
4043fcf3ce44SJohn Forte fct_els_t *fct_els;
4044fcf3ce44SJohn Forte fc_packet_t *pkt;
4045fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp;
404682527734SSukumar Swaminathan fct_status_t rval;
4047fcf3ce44SJohn Forte
4048fcf3ce44SJohn Forte did = fct_cmd->cmd_rportid;
40498f23e9faSHans Rosenfeld sid = fct_cmd->cmd_lportid;
4050fcf3ce44SJohn Forte fct_els = (fct_els_t *)fct_cmd->cmd_specific;
4051fcf3ce44SJohn Forte
4052fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, fct_els->els_req_size,
4053fcf3ce44SJohn Forte fct_els->els_resp_size, 0, KM_NOSLEEP))) {
4054fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
40558f23e9faSHans Rosenfeld "fct_send_els_cmd: Unable to allocate packet.");
405682527734SSukumar Swaminathan
405782527734SSukumar Swaminathan return (FCT_BUSY);
4058fcf3ce44SJohn Forte }
4059291a2b48SSukumar Swaminathan
406082527734SSukumar Swaminathan cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd, EMLXS_FCT_SEND_ELS_REQ);
4061291a2b48SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */
4062291a2b48SSukumar Swaminathan
406382527734SSukumar Swaminathan cmd_sbp->channel = &hba->chan[hba->channel_els];
4064fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_ELS_REQ;
4065fcf3ce44SJohn Forte
4066fcf3ce44SJohn Forte (void) emlxs_fct_pkt_init(port, fct_cmd, pkt);
4067291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = pkt;
4068fcf3ce44SJohn Forte
4069fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE;
4070fcf3ce44SJohn Forte pkt->pkt_timeout =
4071fcf3ce44SJohn Forte ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov);
40728f23e9faSHans Rosenfeld pkt->pkt_timeout = (pkt->pkt_timeout > 60)? 60: pkt->pkt_timeout;
4073fcf3ce44SJohn Forte pkt->pkt_comp = emlxs_fct_pkt_comp;
4074fcf3ce44SJohn Forte
4075fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
40768f23e9faSHans Rosenfeld "fct_send_els_cmd: pkt_timeout=%d ratov=%d",
4077fcf3ce44SJohn Forte pkt->pkt_timeout, hba->fc_ratov);
4078fcf3ce44SJohn Forte
4079fcf3ce44SJohn Forte /* Build the fc header */
408082527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(did);
4081fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_ELS_REQ;
40828f23e9faSHans Rosenfeld pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(sid);
4083fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
4084fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl =
4085fcf3ce44SJohn Forte F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE;
4086fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0;
4087fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0;
4088fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0;
4089fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xFFFF;
4090fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xFFFF;
4091fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0;
4092fcf3ce44SJohn Forte
4093fcf3ce44SJohn Forte /* Copy the cmd payload */
4094fcf3ce44SJohn Forte bcopy((uint8_t *)fct_els->els_req_payload, (uint8_t *)pkt->pkt_cmd,
4095fcf3ce44SJohn Forte fct_els->els_req_size);
409682527734SSukumar Swaminathan
4097291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP;
409882527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, EMLXS_FCT_REQ_PENDING);
409982527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
4100fcf3ce44SJohn Forte
4101fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
410282527734SSukumar Swaminathan
4103fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
41048f23e9faSHans Rosenfeld "fct_send_els_cmd: Unable to send packet.");
4105fcf3ce44SJohn Forte
410682527734SSukumar Swaminathan /* Reacquire ownership of the fct_cmd */
410782527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, 0);
410882527734SSukumar Swaminathan if (rval) {
410982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
41108f23e9faSHans Rosenfeld "fct_send_els_cmd: "
411182527734SSukumar Swaminathan "Unable to reacquire fct_cmd.");
411282527734SSukumar Swaminathan return (rval);
4113fcf3ce44SJohn Forte }
411482527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */
4115fcf3ce44SJohn Forte
411682527734SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED);
411782527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
4118fcf3ce44SJohn Forte
411982527734SSukumar Swaminathan return (FCT_BUSY);
4120fcf3ce44SJohn Forte }
4121fcf3ce44SJohn Forte
4122fcf3ce44SJohn Forte return (FCT_SUCCESS);
4123fcf3ce44SJohn Forte
412482527734SSukumar Swaminathan } /* emlxs_fct_send_els_cmd() */
4125fcf3ce44SJohn Forte
4126fcf3ce44SJohn Forte
412782527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be held to enter */
412882527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be released before exiting */
4129fcf3ce44SJohn Forte static fct_status_t
emlxs_fct_send_els_rsp(fct_cmd_t * fct_cmd)4130fcf3ce44SJohn Forte emlxs_fct_send_els_rsp(fct_cmd_t *fct_cmd)
4131fcf3ce44SJohn Forte {
4132fcf3ce44SJohn Forte emlxs_port_t *port =
4133fcf3ce44SJohn Forte (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
4134fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
4135fcf3ce44SJohn Forte uint32_t did;
41368f23e9faSHans Rosenfeld uint32_t sid;
4137fcf3ce44SJohn Forte fct_els_t *fct_els;
4138fcf3ce44SJohn Forte fc_packet_t *pkt;
4139fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp;
414082527734SSukumar Swaminathan fct_status_t rval;
4141fcf3ce44SJohn Forte
4142fcf3ce44SJohn Forte fct_els = (fct_els_t *)fct_cmd->cmd_specific;
4143fcf3ce44SJohn Forte did = fct_cmd->cmd_rportid;
41448f23e9faSHans Rosenfeld sid = fct_cmd->cmd_lportid;
414582527734SSukumar Swaminathan cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
4146fcf3ce44SJohn Forte
4147291a2b48SSukumar Swaminathan if (!(pkt = emlxs_pkt_alloc(port, fct_els->els_resp_size, 0, 0,
4148291a2b48SSukumar Swaminathan KM_NOSLEEP))) {
4149fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
41508f23e9faSHans Rosenfeld "fct_send_els_rsp: Unable to allocate packet.");
4151291a2b48SSukumar Swaminathan
4152fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
415382527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
4154fcf3ce44SJohn Forte
415582527734SSukumar Swaminathan return (FCT_FAILURE);
415682527734SSukumar Swaminathan }
4157291a2b48SSukumar Swaminathan
415882527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, EMLXS_FCT_SEND_ELS_RSP);
4159fcf3ce44SJohn Forte
4160fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_ELS_RSP;
4161fcf3ce44SJohn Forte
4162fcf3ce44SJohn Forte (void) emlxs_fct_pkt_init(port, fct_cmd, pkt);
4163291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = pkt;
4164fcf3ce44SJohn Forte
4165fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_OUTBOUND;
4166fcf3ce44SJohn Forte pkt->pkt_timeout =
4167fcf3ce44SJohn Forte ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov);
41688f23e9faSHans Rosenfeld pkt->pkt_timeout = (pkt->pkt_timeout > 60)? 60: pkt->pkt_timeout;
4169fcf3ce44SJohn Forte pkt->pkt_comp = emlxs_fct_pkt_comp;
4170fcf3ce44SJohn Forte
4171fcf3ce44SJohn Forte /* Build the fc header */
417282527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(did);
4173fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_ELS_RSP;
41748f23e9faSHans Rosenfeld pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(sid);
4175fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
4176fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl =
4177fcf3ce44SJohn Forte F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ;
4178fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0;
4179fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0;
4180fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0;
4181fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = fct_cmd->cmd_oxid;
4182fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = fct_cmd->cmd_rxid;
4183fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0;
4184fcf3ce44SJohn Forte
4185fcf3ce44SJohn Forte /* Copy the resp payload to pkt_cmd buffer */
4186fcf3ce44SJohn Forte bcopy((uint8_t *)fct_els->els_resp_payload, (uint8_t *)pkt->pkt_cmd,
4187fcf3ce44SJohn Forte fct_els->els_resp_size);
418882527734SSukumar Swaminathan
4189291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP;
419082527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, EMLXS_FCT_RSP_PENDING);
419182527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
4192fcf3ce44SJohn Forte
4193fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
419482527734SSukumar Swaminathan
4195fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
41968f23e9faSHans Rosenfeld "fct_send_els_rsp: Unable to send packet.");
4197fcf3ce44SJohn Forte
419882527734SSukumar Swaminathan /* Reacquire ownership of the fct_cmd */
419982527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, 0);
420082527734SSukumar Swaminathan if (rval) {
420182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
42028f23e9faSHans Rosenfeld "fct_send_els_rsp: "
420382527734SSukumar Swaminathan "Unable to reacquire fct_cmd.");
420482527734SSukumar Swaminathan return (rval);
4205fcf3ce44SJohn Forte }
420682527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */
4207291a2b48SSukumar Swaminathan
4208fe199829SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
420982527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
4210291a2b48SSukumar Swaminathan
4211fcf3ce44SJohn Forte return (FCT_FAILURE);
4212fcf3ce44SJohn Forte }
4213fcf3ce44SJohn Forte
4214291a2b48SSukumar Swaminathan return (FCT_SUCCESS);
4215fcf3ce44SJohn Forte
421682527734SSukumar Swaminathan } /* emlxs_fct_send_els_rsp() */
4217fcf3ce44SJohn Forte
4218fcf3ce44SJohn Forte
421982527734SSukumar Swaminathan /* COMSTAR ENTER POINT (INDIRECT) */
4220fcf3ce44SJohn Forte static fct_status_t
emlxs_fct_send_ct_cmd(fct_cmd_t * fct_cmd)4221fcf3ce44SJohn Forte emlxs_fct_send_ct_cmd(fct_cmd_t *fct_cmd)
4222fcf3ce44SJohn Forte {
4223fcf3ce44SJohn Forte emlxs_port_t *port =
4224fcf3ce44SJohn Forte (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
4225fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
4226fcf3ce44SJohn Forte uint32_t did;
4227fcf3ce44SJohn Forte fct_sol_ct_t *fct_ct;
4228fcf3ce44SJohn Forte fc_packet_t *pkt;
4229fcf3ce44SJohn Forte emlxs_buf_t *cmd_sbp;
423082527734SSukumar Swaminathan fct_status_t rval;
4231fcf3ce44SJohn Forte
4232fcf3ce44SJohn Forte did = fct_cmd->cmd_rportid;
4233fcf3ce44SJohn Forte fct_ct = (fct_sol_ct_t *)fct_cmd->cmd_specific;
4234fcf3ce44SJohn Forte
4235fcf3ce44SJohn Forte if (!(pkt = emlxs_pkt_alloc(port, fct_ct->ct_req_size,
4236fcf3ce44SJohn Forte fct_ct->ct_resp_size, 0, KM_NOSLEEP))) {
4237fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
42388f23e9faSHans Rosenfeld "fct_send_ct_cmd: Unable to allocate packet.");
423982527734SSukumar Swaminathan return (FCT_BUSY);
4240fcf3ce44SJohn Forte }
4241291a2b48SSukumar Swaminathan
424282527734SSukumar Swaminathan cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd, EMLXS_FCT_SEND_CT_REQ);
4243291a2b48SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */
4244fcf3ce44SJohn Forte
424582527734SSukumar Swaminathan cmd_sbp->channel = &hba->chan[hba->channel_ct];
4246fcf3ce44SJohn Forte cmd_sbp->fct_type = EMLXS_FCT_CT_REQ;
4247fcf3ce44SJohn Forte
4248fcf3ce44SJohn Forte (void) emlxs_fct_pkt_init(port, fct_cmd, pkt);
4249291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = pkt;
4250fcf3ce44SJohn Forte
4251fcf3ce44SJohn Forte pkt->pkt_tran_type = FC_PKT_EXCHANGE;
4252fcf3ce44SJohn Forte pkt->pkt_timeout =
4253fcf3ce44SJohn Forte ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov);
42548f23e9faSHans Rosenfeld pkt->pkt_timeout = (pkt->pkt_timeout > 60)? 60: pkt->pkt_timeout;
4255fcf3ce44SJohn Forte pkt->pkt_comp = emlxs_fct_pkt_comp;
4256fcf3ce44SJohn Forte
4257fcf3ce44SJohn Forte /* Build the fc header */
425882527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(did);
4259fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.r_ctl = R_CTL_UNSOL_CONTROL;
426082527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did);
4261fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.type = FC_TYPE_FC_SERVICES;
4262fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.f_ctl =
4263fcf3ce44SJohn Forte F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE;
4264fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_id = 0;
4265fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.df_ctl = 0;
4266fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.seq_cnt = 0;
4267fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ox_id = 0xFFFF;
4268fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.rx_id = 0xFFFF;
4269fcf3ce44SJohn Forte pkt->pkt_cmd_fhdr.ro = 0;
4270fcf3ce44SJohn Forte
4271fcf3ce44SJohn Forte /* Copy the cmd payload */
4272fcf3ce44SJohn Forte bcopy((uint8_t *)fct_ct->ct_req_payload, (uint8_t *)pkt->pkt_cmd,
4273fcf3ce44SJohn Forte fct_ct->ct_req_size);
427482527734SSukumar Swaminathan
4275291a2b48SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP;
427682527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, EMLXS_FCT_REQ_PENDING);
427782527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
4278fcf3ce44SJohn Forte
4279fcf3ce44SJohn Forte if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
428082527734SSukumar Swaminathan
4281fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
42828f23e9faSHans Rosenfeld "fct_send_ct_cmd: Unable to send packet.");
4283fcf3ce44SJohn Forte
428482527734SSukumar Swaminathan /* Reacquire ownership of the fct_cmd */
428582527734SSukumar Swaminathan rval = emlxs_fct_cmd_acquire(port, fct_cmd, 0);
428682527734SSukumar Swaminathan if (rval) {
428782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
42888f23e9faSHans Rosenfeld "fct_send_ct_cmd: "
428982527734SSukumar Swaminathan "Unable to reacquire fct_cmd.");
429082527734SSukumar Swaminathan
429182527734SSukumar Swaminathan return (rval);
4292fcf3ce44SJohn Forte }
429382527734SSukumar Swaminathan /* mutex_enter(&cmd_sbp->fct_mtx); */
4294fcf3ce44SJohn Forte
429582527734SSukumar Swaminathan emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_OWNED);
429682527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
4297fcf3ce44SJohn Forte
429882527734SSukumar Swaminathan return (FCT_BUSY);
4299fcf3ce44SJohn Forte }
4300fcf3ce44SJohn Forte
4301fcf3ce44SJohn Forte return (FCT_SUCCESS);
4302fcf3ce44SJohn Forte
430382527734SSukumar Swaminathan } /* emlxs_fct_send_ct_cmd() */
4304fcf3ce44SJohn Forte
4305fcf3ce44SJohn Forte
430682527734SSukumar Swaminathan /* cmd_sbp->fct_mtx must be held to enter */
4307fe199829SSukumar Swaminathan static uint32_t
emlxs_fct_pkt_abort_txq(emlxs_port_t * port,emlxs_buf_t * cmd_sbp)4308291a2b48SSukumar Swaminathan emlxs_fct_pkt_abort_txq(emlxs_port_t *port, emlxs_buf_t *cmd_sbp)
4309fcf3ce44SJohn Forte {
4310fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
4311fcf3ce44SJohn Forte NODELIST *nlp;
4312291a2b48SSukumar Swaminathan fc_packet_t *pkt;
4313291a2b48SSukumar Swaminathan emlxs_buf_t *sbp;
4314291a2b48SSukumar Swaminathan emlxs_buf_t *iocb_sbp;
431582527734SSukumar Swaminathan uint8_t channelno;
431682527734SSukumar Swaminathan CHANNEL *cp;
4317fcf3ce44SJohn Forte IOCBQ *iocbq;
4318fcf3ce44SJohn Forte IOCBQ *next;
4319fcf3ce44SJohn Forte IOCBQ *prev;
4320fcf3ce44SJohn Forte uint32_t found;
4321291a2b48SSukumar Swaminathan uint32_t pkt_flags;
4322fcf3ce44SJohn Forte
4323291a2b48SSukumar Swaminathan /* Check the transmit queue */
432482527734SSukumar Swaminathan mutex_enter(&EMLXS_TX_CHANNEL_LOCK);
4325fcf3ce44SJohn Forte
4326291a2b48SSukumar Swaminathan /* The IOCB could point to a cmd_sbp (no packet) or a sbp (packet) */
4327291a2b48SSukumar Swaminathan pkt = cmd_sbp->fct_pkt;
4328291a2b48SSukumar Swaminathan if (pkt) {
4329291a2b48SSukumar Swaminathan sbp = PKT2PRIV(pkt);
4330291a2b48SSukumar Swaminathan if (sbp == NULL) {
4331291a2b48SSukumar Swaminathan goto done;
4332291a2b48SSukumar Swaminathan }
4333291a2b48SSukumar Swaminathan iocb_sbp = sbp;
4334291a2b48SSukumar Swaminathan iocbq = &sbp->iocbq;
4335291a2b48SSukumar Swaminathan pkt_flags = sbp->pkt_flags;
4336291a2b48SSukumar Swaminathan } else {
4337291a2b48SSukumar Swaminathan sbp = NULL;
4338291a2b48SSukumar Swaminathan iocb_sbp = cmd_sbp;
4339291a2b48SSukumar Swaminathan iocbq = &cmd_sbp->iocbq;
4340291a2b48SSukumar Swaminathan pkt_flags = cmd_sbp->pkt_flags;
4341fcf3ce44SJohn Forte }
4342fcf3ce44SJohn Forte
4343291a2b48SSukumar Swaminathan nlp = (NODELIST *)cmd_sbp->node;
434482527734SSukumar Swaminathan cp = (CHANNEL *)cmd_sbp->channel;
434582527734SSukumar Swaminathan channelno = (cp) ? cp->channelno : 0;
4346fcf3ce44SJohn Forte
4347291a2b48SSukumar Swaminathan if (pkt_flags & PACKET_IN_TXQ) {
4348fcf3ce44SJohn Forte /* Find it on the queue */
4349fcf3ce44SJohn Forte found = 0;
4350fcf3ce44SJohn Forte if (iocbq->flag & IOCB_PRIORITY) {
4351fcf3ce44SJohn Forte /* Search the priority queue */
4352fcf3ce44SJohn Forte prev = NULL;
435382527734SSukumar Swaminathan next = (IOCBQ *)nlp->nlp_ptx[channelno].q_first;
4354fcf3ce44SJohn Forte
4355fcf3ce44SJohn Forte while (next) {
4356fcf3ce44SJohn Forte if (next == iocbq) {
4357fcf3ce44SJohn Forte /* Remove it */
4358fcf3ce44SJohn Forte if (prev) {
4359fcf3ce44SJohn Forte prev->next = iocbq->next;
4360fcf3ce44SJohn Forte }
4361291a2b48SSukumar Swaminathan
436282527734SSukumar Swaminathan if (nlp->nlp_ptx[channelno].q_last ==
4363fcf3ce44SJohn Forte (void *)iocbq) {
436482527734SSukumar Swaminathan nlp->nlp_ptx[channelno].q_last =
4365fcf3ce44SJohn Forte (void *)prev;
4366fcf3ce44SJohn Forte }
4367291a2b48SSukumar Swaminathan
436882527734SSukumar Swaminathan if (nlp->nlp_ptx[channelno].q_first ==
4369fcf3ce44SJohn Forte (void *)iocbq) {
437082527734SSukumar Swaminathan nlp->nlp_ptx[channelno].
437182527734SSukumar Swaminathan q_first =
4372fcf3ce44SJohn Forte (void *)iocbq->next;
4373fcf3ce44SJohn Forte }
4374291a2b48SSukumar Swaminathan
437582527734SSukumar Swaminathan nlp->nlp_ptx[channelno].q_cnt--;
4376fcf3ce44SJohn Forte iocbq->next = NULL;
4377fcf3ce44SJohn Forte found = 1;
4378fcf3ce44SJohn Forte break;
4379fcf3ce44SJohn Forte }
4380291a2b48SSukumar Swaminathan
4381fcf3ce44SJohn Forte prev = next;
4382fcf3ce44SJohn Forte next = next->next;
4383fcf3ce44SJohn Forte }
4384fcf3ce44SJohn Forte } else {
4385fcf3ce44SJohn Forte /* Search the normal queue */
4386fcf3ce44SJohn Forte prev = NULL;
438782527734SSukumar Swaminathan next = (IOCBQ *)nlp->nlp_tx[channelno].q_first;
4388fcf3ce44SJohn Forte
4389fcf3ce44SJohn Forte while (next) {
4390fcf3ce44SJohn Forte if (next == iocbq) {
4391fcf3ce44SJohn Forte /* Remove it */
4392fcf3ce44SJohn Forte if (prev) {
4393fcf3ce44SJohn Forte prev->next = iocbq->next;
4394fcf3ce44SJohn Forte }
4395291a2b48SSukumar Swaminathan
439682527734SSukumar Swaminathan if (nlp->nlp_tx[channelno].q_last ==
4397fcf3ce44SJohn Forte (void *)iocbq) {
439882527734SSukumar Swaminathan nlp->nlp_tx[channelno].q_last =
4399fcf3ce44SJohn Forte (void *)prev;
4400fcf3ce44SJohn Forte }
4401291a2b48SSukumar Swaminathan
440282527734SSukumar Swaminathan if (nlp->nlp_tx[channelno].q_first ==
4403fcf3ce44SJohn Forte (void *)iocbq) {
440482527734SSukumar Swaminathan nlp->nlp_tx[channelno].q_first =
4405fcf3ce44SJohn Forte (void *)iocbq->next;
4406fcf3ce44SJohn Forte }
4407291a2b48SSukumar Swaminathan
440882527734SSukumar Swaminathan nlp->nlp_tx[channelno].q_cnt--;
4409fcf3ce44SJohn Forte iocbq->next = NULL;
4410fcf3ce44SJohn Forte found = 1;
4411fcf3ce44SJohn Forte break;
4412fcf3ce44SJohn Forte }
4413291a2b48SSukumar Swaminathan
4414fcf3ce44SJohn Forte prev = next;
4415fcf3ce44SJohn Forte next = (IOCBQ *)next->next;
4416fcf3ce44SJohn Forte }
4417fcf3ce44SJohn Forte }
4418fcf3ce44SJohn Forte
4419fcf3ce44SJohn Forte if (!found) {
4420fcf3ce44SJohn Forte goto done;
4421fcf3ce44SJohn Forte }
4422291a2b48SSukumar Swaminathan
4423fcf3ce44SJohn Forte /* Check if node still needs servicing */
442482527734SSukumar Swaminathan if ((nlp->nlp_ptx[channelno].q_first) ||
442582527734SSukumar Swaminathan (nlp->nlp_tx[channelno].q_first &&
442682527734SSukumar Swaminathan !(nlp->nlp_flag[channelno] & NLP_CLOSED))) {
4427fcf3ce44SJohn Forte
4428fcf3ce44SJohn Forte /*
4429291a2b48SSukumar Swaminathan * If this is the base node, don't shift the pointers
4430fcf3ce44SJohn Forte */
4431fcf3ce44SJohn Forte /* We want to drain the base node before moving on */
4432fcf3ce44SJohn Forte if (!nlp->nlp_base) {
443382527734SSukumar Swaminathan /* Shift channel queue pointers to next node */
443482527734SSukumar Swaminathan cp->nodeq.q_last = (void *)nlp;
443582527734SSukumar Swaminathan cp->nodeq.q_first = nlp->nlp_next[channelno];
4436fcf3ce44SJohn Forte }
4437fcf3ce44SJohn Forte } else {
443882527734SSukumar Swaminathan /* Remove node from channel queue */
4439fcf3ce44SJohn Forte
4440fcf3ce44SJohn Forte /* If this is the last node on list */
444182527734SSukumar Swaminathan if (cp->nodeq.q_last == (void *)nlp) {
444282527734SSukumar Swaminathan cp->nodeq.q_last = NULL;
444382527734SSukumar Swaminathan cp->nodeq.q_first = NULL;
444482527734SSukumar Swaminathan cp->nodeq.q_cnt = 0;
4445fcf3ce44SJohn Forte } else {
4446fcf3ce44SJohn Forte /* Remove node from head */
444782527734SSukumar Swaminathan cp->nodeq.q_first = nlp->nlp_next[channelno];
444882527734SSukumar Swaminathan ((NODELIST *)cp->nodeq.q_last)->
444982527734SSukumar Swaminathan nlp_next[channelno] = cp->nodeq.q_first;
445082527734SSukumar Swaminathan cp->nodeq.q_cnt--;
4451fcf3ce44SJohn Forte }
4452fcf3ce44SJohn Forte
4453fcf3ce44SJohn Forte /* Clear node */
445482527734SSukumar Swaminathan nlp->nlp_next[channelno] = NULL;
4455fcf3ce44SJohn Forte }
4456fcf3ce44SJohn Forte
445782527734SSukumar Swaminathan /* The IOCB points to iocb_sbp (no packet) or a sbp (packet) */
445882527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
44598f23e9faSHans Rosenfeld emlxs_sli4_free_xri(port, iocb_sbp, iocb_sbp->xrip, 1);
446082527734SSukumar Swaminathan } else {
446182527734SSukumar Swaminathan (void) emlxs_unregister_pkt(cp, iocb_sbp->iotag, 0);
4462fcf3ce44SJohn Forte }
4463fcf3ce44SJohn Forte
446482527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
4465fcf3ce44SJohn Forte
4466291a2b48SSukumar Swaminathan if (pkt) {
4467291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt);
4468291a2b48SSukumar Swaminathan cmd_sbp->fct_pkt = NULL;
4469fcf3ce44SJohn Forte }
447082527734SSukumar Swaminathan return (1);
4471fcf3ce44SJohn Forte }
4472291a2b48SSukumar Swaminathan done:
447382527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
447482527734SSukumar Swaminathan return (0);
447582527734SSukumar Swaminathan
447682527734SSukumar Swaminathan } /* emlxs_fct_pkt_abort_txq() */
4477fcf3ce44SJohn Forte
4478fcf3ce44SJohn Forte
447982527734SSukumar Swaminathan /* COMSTAR ENTER POINT */
4480291a2b48SSukumar Swaminathan /* FCT_NOT_FOUND & FCT_ABORT_SUCCESS indicates IO is done */
4481291a2b48SSukumar Swaminathan /* FCT_SUCCESS indicates abort will occur asyncronously */
4482291a2b48SSukumar Swaminathan static fct_status_t
emlxs_fct_abort(fct_local_port_t * fct_port,fct_cmd_t * fct_cmd,uint32_t flags)4483291a2b48SSukumar Swaminathan emlxs_fct_abort(fct_local_port_t *fct_port, fct_cmd_t *fct_cmd,
4484291a2b48SSukumar Swaminathan uint32_t flags)
4485291a2b48SSukumar Swaminathan {
4486291a2b48SSukumar Swaminathan emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
4487291a2b48SSukumar Swaminathan emlxs_hba_t *hba = HBA;
4488291a2b48SSukumar Swaminathan emlxs_buf_t *cmd_sbp;
448982527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp2;
449082527734SSukumar Swaminathan emlxs_buf_t *prev;
4491291a2b48SSukumar Swaminathan fc_packet_t *pkt;
4492291a2b48SSukumar Swaminathan emlxs_buf_t *sbp = NULL;
449382527734SSukumar Swaminathan kmutex_t *fct_mtx;
449482527734SSukumar Swaminathan uint32_t fct_state;
449582527734SSukumar Swaminathan
449682527734SSukumar Swaminathan cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
449782527734SSukumar Swaminathan fct_mtx = &cmd_sbp->fct_mtx;
4498fcf3ce44SJohn Forte
4499291a2b48SSukumar Swaminathan top:
450082527734SSukumar Swaminathan
4501291a2b48SSukumar Swaminathan /* Sanity check */
4502291a2b48SSukumar Swaminathan if ((fct_cmd->cmd_oxid == 0) && (fct_cmd->cmd_rxid == 0)) {
4503291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
45048f23e9faSHans Rosenfeld "fct_abort: Bad fct_cmd=%p.", fct_cmd);
4505fcf3ce44SJohn Forte
4506291a2b48SSukumar Swaminathan return (FCT_NOT_FOUND);
4507291a2b48SSukumar Swaminathan }
4508fcf3ce44SJohn Forte
4509291a2b48SSukumar Swaminathan if (!(cmd_sbp->pkt_flags & PACKET_VALID)) {
4510291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
45118f23e9faSHans Rosenfeld "fct_abort: Pkt invalid. cmd_sbp=%p",
451282527734SSukumar Swaminathan cmd_sbp);
4513fcf3ce44SJohn Forte
4514291a2b48SSukumar Swaminathan return (FCT_NOT_FOUND);
4515fcf3ce44SJohn Forte }
4516fcf3ce44SJohn Forte
451782527734SSukumar Swaminathan if (mutex_tryenter(fct_mtx) == 0) {
4518fcf3ce44SJohn Forte /*
4519291a2b48SSukumar Swaminathan * This code path handles a race condition if
4520291a2b48SSukumar Swaminathan * an IO completes, in emlxs_fct_handle_fcp_event(),
4521291a2b48SSukumar Swaminathan * and we get an abort at the same time.
4522fcf3ce44SJohn Forte */
4523291a2b48SSukumar Swaminathan delay(drv_usectohz(100000)); /* 100 msec */
4524291a2b48SSukumar Swaminathan goto top;
4525fcf3ce44SJohn Forte }
4526291a2b48SSukumar Swaminathan /* At this point, we have entered the mutex */
4527fcf3ce44SJohn Forte
452882527734SSukumar Swaminathan /* Sanity check */
452982527734SSukumar Swaminathan if ((fct_cmd->cmd_oxid == 0) && (fct_cmd->cmd_rxid == 0)) {
4530291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
45318f23e9faSHans Rosenfeld "fct_abort: Bad fct_cmd=%p.", fct_cmd);
4532fcf3ce44SJohn Forte
453382527734SSukumar Swaminathan mutex_exit(fct_mtx);
4534291a2b48SSukumar Swaminathan return (FCT_NOT_FOUND);
4535fcf3ce44SJohn Forte }
4536fcf3ce44SJohn Forte
453782527734SSukumar Swaminathan if (!(cmd_sbp->pkt_flags & PACKET_VALID)) {
453882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
45398f23e9faSHans Rosenfeld "fct_abort: Pkt invalid. cmd_sbp=%p",
454082527734SSukumar Swaminathan cmd_sbp);
454182527734SSukumar Swaminathan
454282527734SSukumar Swaminathan mutex_exit(fct_mtx);
454382527734SSukumar Swaminathan return (FCT_NOT_FOUND);
4544fcf3ce44SJohn Forte }
4545fcf3ce44SJohn Forte
4546291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
45478f23e9faSHans Rosenfeld "fct_abort: hbastate=%x. "
4548fe199829SSukumar Swaminathan "xid=%x,%x cmd_sbp=%p fctstate=%d flags=%x,%x,%x",
4549fe199829SSukumar Swaminathan hba->state, fct_cmd->cmd_oxid, fct_cmd->cmd_rxid, cmd_sbp,
4550fe199829SSukumar Swaminathan cmd_sbp->fct_state, flags, cmd_sbp->fct_flags, cmd_sbp->pkt_flags);
4551291a2b48SSukumar Swaminathan
4552291a2b48SSukumar Swaminathan if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT_INP) {
455382527734SSukumar Swaminathan EMLXS_SLI_ISSUE_IOCB_CMD(hba, cmd_sbp->channel, 0);
455482527734SSukumar Swaminathan
4555291a2b48SSukumar Swaminathan /* If Abort is already in progress */
455682527734SSukumar Swaminathan mutex_exit(fct_mtx);
455782527734SSukumar Swaminathan return (FCT_SUCCESS);
455882527734SSukumar Swaminathan }
455982527734SSukumar Swaminathan cmd_sbp->fct_flags |= EMLXS_FCT_ABORT_INP;
456082527734SSukumar Swaminathan
456182527734SSukumar Swaminathan if (flags & FCT_IOF_FORCE_FCA_DONE) {
456282527734SSukumar Swaminathan fct_cmd->cmd_handle = 0;
4563291a2b48SSukumar Swaminathan }
4564fcf3ce44SJohn Forte
4565291a2b48SSukumar Swaminathan TGTPORTSTAT.FctAbortSent++;
4566fcf3ce44SJohn Forte
456782527734SSukumar Swaminathan switch (cmd_sbp->fct_state) {
456882527734SSukumar Swaminathan /* These are currently owned by COMSTAR. */
456982527734SSukumar Swaminathan /* They were last processed by emlxs_fct_cmd_post() */
4570fe199829SSukumar Swaminathan /* We have NO exchange resources associated with this IO. */
457182527734SSukumar Swaminathan case EMLXS_FCT_OWNED:
4572fe199829SSukumar Swaminathan goto abort_done;
457382527734SSukumar Swaminathan
457482527734SSukumar Swaminathan /* These are on the unsol waitQ in the driver */
457582527734SSukumar Swaminathan case EMLXS_FCT_CMD_WAITQ:
457682527734SSukumar Swaminathan /* Find and remove it */
457782527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK);
457882527734SSukumar Swaminathan cmd_sbp2 = port->fct_wait_head;
457982527734SSukumar Swaminathan prev = NULL;
458082527734SSukumar Swaminathan while (cmd_sbp2) {
458182527734SSukumar Swaminathan if (cmd_sbp2 == cmd_sbp) {
458282527734SSukumar Swaminathan /* Remove it */
458382527734SSukumar Swaminathan if (prev) {
458482527734SSukumar Swaminathan prev->next = cmd_sbp2->next;
458582527734SSukumar Swaminathan }
458682527734SSukumar Swaminathan
458782527734SSukumar Swaminathan if (port->fct_wait_head == cmd_sbp2) {
458882527734SSukumar Swaminathan port->fct_wait_head = cmd_sbp2->next;
458982527734SSukumar Swaminathan }
459082527734SSukumar Swaminathan
459182527734SSukumar Swaminathan if (port->fct_wait_tail == cmd_sbp2) {
459282527734SSukumar Swaminathan port->fct_wait_tail = prev;
459382527734SSukumar Swaminathan }
459482527734SSukumar Swaminathan
459582527734SSukumar Swaminathan cmd_sbp2->next = NULL;
459682527734SSukumar Swaminathan break;
459782527734SSukumar Swaminathan }
459882527734SSukumar Swaminathan prev = cmd_sbp2;
459982527734SSukumar Swaminathan cmd_sbp2 = cmd_sbp2->next;
460082527734SSukumar Swaminathan }
460182527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK);
460282527734SSukumar Swaminathan
4603fe199829SSukumar Swaminathan /*FALLTHROUGH*/
4604fe199829SSukumar Swaminathan
4605fe199829SSukumar Swaminathan /* These are currently owned by COMSTAR. */
4606fe199829SSukumar Swaminathan /* They were last processed by emlxs_fct_cmd_post() */
4607fe199829SSukumar Swaminathan /* We have residual exchange resources associated with this IO */
4608fe199829SSukumar Swaminathan case EMLXS_FCT_CMD_POSTED:
4609fe199829SSukumar Swaminathan switch (fct_cmd->cmd_type) {
4610fe199829SSukumar Swaminathan case FCT_CMD_FCP_XCHG: /* Unsol */
4611fe199829SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--;
4612fe199829SSukumar Swaminathan emlxs_abort_fct_exchange(hba, port, fct_cmd->cmd_rxid);
4613fe199829SSukumar Swaminathan break;
4614fe199829SSukumar Swaminathan
4615fe199829SSukumar Swaminathan case FCT_CMD_RCVD_ELS: /* Unsol */
4616fe199829SSukumar Swaminathan emlxs_abort_els_exchange(hba, port, fct_cmd->cmd_rxid);
4617fe199829SSukumar Swaminathan break;
4618fe199829SSukumar Swaminathan }
4619fe199829SSukumar Swaminathan
4620fe199829SSukumar Swaminathan goto abort_done;
462182527734SSukumar Swaminathan
462282527734SSukumar Swaminathan /* These are active in the driver */
462382527734SSukumar Swaminathan /* They were last processed by emlxs_fct_cmd_release() */
4624291a2b48SSukumar Swaminathan case EMLXS_FCT_RSP_PENDING:
4625291a2b48SSukumar Swaminathan case EMLXS_FCT_REQ_PENDING:
4626291a2b48SSukumar Swaminathan case EMLXS_FCT_REG_PENDING:
4627291a2b48SSukumar Swaminathan case EMLXS_FCT_DATA_PENDING:
4628291a2b48SSukumar Swaminathan case EMLXS_FCT_STATUS_PENDING:
462982527734SSukumar Swaminathan
463082527734SSukumar Swaminathan /* Abort anything pending */
4631291a2b48SSukumar Swaminathan if (emlxs_fct_pkt_abort_txq(port, cmd_sbp)) {
4632fcf3ce44SJohn Forte
4633291a2b48SSukumar Swaminathan if (fct_cmd->cmd_type == FCT_CMD_FCP_XCHG) {
4634291a2b48SSukumar Swaminathan TGTPORTSTAT.FctOutstandingIO--;
4635fcf3ce44SJohn Forte }
463682527734SSukumar Swaminathan
4637fe199829SSukumar Swaminathan goto abort_done;
4638291a2b48SSukumar Swaminathan }
4639fcf3ce44SJohn Forte
464082527734SSukumar Swaminathan /* If we're not online, then all IO will be flushed anyway */
4641291a2b48SSukumar Swaminathan if (!(hba->flag & FC_ONLINE_MODE)) {
464282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
46438f23e9faSHans Rosenfeld "fct_abort: Not online. fct_cmd=%p.",
464482527734SSukumar Swaminathan fct_cmd);
4645291a2b48SSukumar Swaminathan
464682527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, 0);
464782527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
464882527734SSukumar Swaminathan
464982527734SSukumar Swaminathan /* The cmd will be aborted on the */
465082527734SSukumar Swaminathan /* next emlxs_fct_cmd_acquire */
465182527734SSukumar Swaminathan /* because EMLXS_FCT_ABORT_INP is set. */
465282527734SSukumar Swaminathan break;
4653fcf3ce44SJohn Forte }
4654fcf3ce44SJohn Forte
465582527734SSukumar Swaminathan /* Try to send abort request */
4656291a2b48SSukumar Swaminathan if (!(pkt = emlxs_pkt_alloc(port, 0, 0, 0, KM_NOSLEEP))) {
4657291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
46588f23e9faSHans Rosenfeld "fct_abort: Unable to allocate packet. "
465982527734SSukumar Swaminathan "fct_cmd=%p",
466082527734SSukumar Swaminathan fct_cmd);
466182527734SSukumar Swaminathan
466282527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, 0);
466382527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
466482527734SSukumar Swaminathan
466582527734SSukumar Swaminathan /* The cmd will be aborted on the */
466682527734SSukumar Swaminathan /* next emlxs_fct_cmd_acquire anyway */
466782527734SSukumar Swaminathan /* because EMLXS_FCT_ABORT_INP is set. */
466882527734SSukumar Swaminathan break;
4669fcf3ce44SJohn Forte }
4670fcf3ce44SJohn Forte
4671291a2b48SSukumar Swaminathan sbp = emlxs_fct_pkt_init(port, fct_cmd, pkt);
4672291a2b48SSukumar Swaminathan
4673291a2b48SSukumar Swaminathan pkt->pkt_tran_type = FC_PKT_OUTBOUND;
4674291a2b48SSukumar Swaminathan pkt->pkt_timeout =
4675291a2b48SSukumar Swaminathan ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov);
4676291a2b48SSukumar Swaminathan pkt->pkt_comp = emlxs_fct_abort_pkt_comp;
4677291a2b48SSukumar Swaminathan
4678291a2b48SSukumar Swaminathan /* Build the fc header */
467982527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(fct_cmd->cmd_rportid);
4680291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.r_ctl = R_CTL_STATUS;
468182527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did);
4682291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.type = FC_TYPE_BASIC_LS;
4683291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.f_ctl =
4684291a2b48SSukumar Swaminathan (F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ);
4685291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.seq_id = 0;
4686291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.df_ctl = 0;
4687291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.seq_cnt = 0;
4688291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.ox_id = fct_cmd->cmd_oxid;
4689291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id = fct_cmd->cmd_rxid;
4690291a2b48SSukumar Swaminathan pkt->pkt_cmd_fhdr.ro = 0;
4691291a2b48SSukumar Swaminathan
46928f23e9faSHans Rosenfeld /* Make sure xrip is setup */
46938f23e9faSHans Rosenfeld if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
46948f23e9faSHans Rosenfeld if (!sbp->xrip || sbp->xrip->state == XRI_STATE_FREE) {
46958f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
46968f23e9faSHans Rosenfeld "fct_abort: "
46978f23e9faSHans Rosenfeld "Unable to acquire xri. (xid:%x,%x)",
46988f23e9faSHans Rosenfeld fct_cmd->cmd_oxid, fct_cmd->cmd_rxid);
46998f23e9faSHans Rosenfeld
47008f23e9faSHans Rosenfeld emlxs_pkt_free(pkt);
47018f23e9faSHans Rosenfeld return (FCT_NOT_FOUND);
47028f23e9faSHans Rosenfeld }
47038f23e9faSHans Rosenfeld }
47048f23e9faSHans Rosenfeld
4705291a2b48SSukumar Swaminathan cmd_sbp->fct_cmd = fct_cmd;
4706291a2b48SSukumar Swaminathan cmd_sbp->abort_attempts++;
4707fcf3ce44SJohn Forte
4708291a2b48SSukumar Swaminathan /* Now disassociate the sbp / pkt from the fct_cmd */
4709291a2b48SSukumar Swaminathan sbp->fct_cmd = NULL;
4710fcf3ce44SJohn Forte
471182527734SSukumar Swaminathan if (hba->state >= FC_LINK_UP) {
4712291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
47138f23e9faSHans Rosenfeld "fct_abort: ABORT: %p xid:%x,%x",
47148f23e9faSHans Rosenfeld fct_cmd, fct_cmd->cmd_oxid, fct_cmd->cmd_rxid);
4715fcf3ce44SJohn Forte
471682527734SSukumar Swaminathan fct_state = EMLXS_FCT_ABORT_PENDING;
471782527734SSukumar Swaminathan
471882527734SSukumar Swaminathan } else {
4719291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
47208f23e9faSHans Rosenfeld "fct_abort: CLOSE: %p xid:%x,%x",
47218f23e9faSHans Rosenfeld fct_cmd, fct_cmd->cmd_oxid, fct_cmd->cmd_rxid);
4722fcf3ce44SJohn Forte
472382527734SSukumar Swaminathan fct_state = EMLXS_FCT_CLOSE_PENDING;
4724291a2b48SSukumar Swaminathan }
4725fcf3ce44SJohn Forte
472682527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, fct_state);
472782527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
472882527734SSukumar Swaminathan
4729291a2b48SSukumar Swaminathan if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
4730291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
47318f23e9faSHans Rosenfeld "fct_abort: Unable to send abort packet.");
4732fcf3ce44SJohn Forte
4733291a2b48SSukumar Swaminathan emlxs_pkt_free(pkt);
4734fcf3ce44SJohn Forte
473582527734SSukumar Swaminathan /* The cmd will be aborted on the */
473682527734SSukumar Swaminathan /* next emlxs_fct_cmd_acquire anyway */
473782527734SSukumar Swaminathan /* because EMLXS_FCT_ABORT_INP is set. */
4738291a2b48SSukumar Swaminathan }
473982527734SSukumar Swaminathan
4740291a2b48SSukumar Swaminathan break;
4741fcf3ce44SJohn Forte
4742291a2b48SSukumar Swaminathan default:
474382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
47448f23e9faSHans Rosenfeld "fct_abort: Unexpected fct_state. "
47458f23e9faSHans Rosenfeld "fct_cmd=%p state=%d",
474682527734SSukumar Swaminathan fct_cmd, cmd_sbp->fct_state);
474782527734SSukumar Swaminathan
474882527734SSukumar Swaminathan emlxs_fct_cmd_release(port, fct_cmd, 0);
474982527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
475082527734SSukumar Swaminathan
475182527734SSukumar Swaminathan /* The cmd will be aborted on the */
475282527734SSukumar Swaminathan /* next emlxs_fct_cmd_acquire anyway */
475382527734SSukumar Swaminathan /* because EMLXS_FCT_ABORT_INP is set. */
4754fcf3ce44SJohn Forte
4755291a2b48SSukumar Swaminathan } /* switch */
4756fcf3ce44SJohn Forte
475782527734SSukumar Swaminathan return (FCT_SUCCESS);
4758fcf3ce44SJohn Forte
4759fe199829SSukumar Swaminathan abort_done:
476082527734SSukumar Swaminathan
476182527734SSukumar Swaminathan emlxs_fct_cmd_done(port, fct_cmd,
476282527734SSukumar Swaminathan EMLXS_FCT_ABORT_DONE);
476382527734SSukumar Swaminathan /* mutex_exit(&cmd_sbp->fct_mtx); */
476482527734SSukumar Swaminathan
476582527734SSukumar Swaminathan return (FCT_ABORT_SUCCESS);
476682527734SSukumar Swaminathan
476782527734SSukumar Swaminathan } /* emlxs_fct_abort() */
4768fcf3ce44SJohn Forte
4769fcf3ce44SJohn Forte
4770fcf3ce44SJohn Forte extern void
emlxs_fct_link_up(emlxs_port_t * port)4771fcf3ce44SJohn Forte emlxs_fct_link_up(emlxs_port_t *port)
4772fcf3ce44SJohn Forte {
4773fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
4774fcf3ce44SJohn Forte
4775fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK);
47768f23e9faSHans Rosenfeld #ifdef FCT_API_TRACE
47778f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
47788f23e9faSHans Rosenfeld "fct_link_up port %p fct flags x%x",
47798f23e9faSHans Rosenfeld port->fct_port, port->fct_flags);
47808f23e9faSHans Rosenfeld #endif /* FCT_API_TRACE */
4781fcf3ce44SJohn Forte
4782fcf3ce44SJohn Forte if (port->fct_port &&
4783fcf3ce44SJohn Forte (port->fct_flags & FCT_STATE_PORT_ONLINE) &&
4784fcf3ce44SJohn Forte !(port->fct_flags & FCT_STATE_LINK_UP)) {
4785fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
47868f23e9faSHans Rosenfeld "fct_link_up event.");
4787fcf3ce44SJohn Forte
4788e2ca2865SSukumar Swaminathan port->fct_flags &= ~FCT_STATE_LINK_UP_ACKED;
47898f23e9faSHans Rosenfeld port->fct_flags &= ~FCT_STATE_FLOGI_CMPL;
4790fcf3ce44SJohn Forte port->fct_flags |= FCT_STATE_LINK_UP;
4791fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK);
4792fcf3ce44SJohn Forte
4793fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
4794fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
4795fcf3ce44SJohn Forte "fct_handle_event LINK_UP");
4796291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
4797291a2b48SSukumar Swaminathan MODSYM(fct_handle_event) (port->fct_port, FCT_EVENT_LINK_UP,
4798291a2b48SSukumar Swaminathan 0, 0);
47998f23e9faSHans Rosenfeld } else if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) {
48008f23e9faSHans Rosenfeld mutex_exit(&EMLXS_PORT_LOCK);
48018f23e9faSHans Rosenfeld
48028f23e9faSHans Rosenfeld if (port->vpi == 0) {
48038f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
48048f23e9faSHans Rosenfeld "fct_link_up event. FCT port offline (%x). "
48058f23e9faSHans Rosenfeld "Disable link.",
48068f23e9faSHans Rosenfeld port->fct_flags);
4807fcf3ce44SJohn Forte
4808fcf3ce44SJohn Forte /* Take link down and hold it down */
480982527734SSukumar Swaminathan (void) emlxs_reset_link(hba, 0, 1);
4810fcf3ce44SJohn Forte } else {
48118f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
48128f23e9faSHans Rosenfeld "fct_link_up event. FCT port offline (%x).",
48138f23e9faSHans Rosenfeld port->fct_flags);
4814fcf3ce44SJohn Forte }
48158f23e9faSHans Rosenfeld } else {
48168f23e9faSHans Rosenfeld mutex_exit(&EMLXS_PORT_LOCK);
4817fcf3ce44SJohn Forte }
4818fcf3ce44SJohn Forte
4819fcf3ce44SJohn Forte return;
4820fcf3ce44SJohn Forte
482182527734SSukumar Swaminathan } /* emlxs_fct_link_up() */
4822291a2b48SSukumar Swaminathan
4823fcf3ce44SJohn Forte
4824fcf3ce44SJohn Forte extern void
emlxs_fct_link_down(emlxs_port_t * port)4825fcf3ce44SJohn Forte emlxs_fct_link_down(emlxs_port_t *port)
4826fcf3ce44SJohn Forte {
4827fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
4828fcf3ce44SJohn Forte
4829fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK);
48308f23e9faSHans Rosenfeld #ifdef FCT_API_TRACE
48318f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
48328f23e9faSHans Rosenfeld "fct_link_down port %p fct flags x%x",
48338f23e9faSHans Rosenfeld port->fct_port, port->fct_flags);
48348f23e9faSHans Rosenfeld #endif /* FCT_API_TRACE */
4835fcf3ce44SJohn Forte
4836fcf3ce44SJohn Forte if (port->fct_port &&
4837fcf3ce44SJohn Forte (port->fct_flags & FCT_STATE_PORT_ONLINE) &&
4838fcf3ce44SJohn Forte (port->fct_flags & FCT_STATE_LINK_UP)) {
4839fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
48408f23e9faSHans Rosenfeld "fct_link_down event.");
4841fcf3ce44SJohn Forte
4842e2ca2865SSukumar Swaminathan port->fct_flags &= ~FCT_STATE_LINK_UP_ACKED;
48438f23e9faSHans Rosenfeld port->fct_flags &= ~FCT_STATE_FLOGI_CMPL;
4844fcf3ce44SJohn Forte port->fct_flags &= ~FCT_STATE_LINK_UP;
4845fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK);
4846fcf3ce44SJohn Forte
4847fcf3ce44SJohn Forte #ifdef FCT_API_TRACE
4848fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
4849fcf3ce44SJohn Forte "fct_handle_event LINK_DOWN");
4850291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
485182527734SSukumar Swaminathan
4852291a2b48SSukumar Swaminathan MODSYM(fct_handle_event) (port->fct_port, FCT_EVENT_LINK_DOWN,
4853291a2b48SSukumar Swaminathan 0, 0);
4854fcf3ce44SJohn Forte } else {
4855fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK);
4856fcf3ce44SJohn Forte }
4857fcf3ce44SJohn Forte
4858fcf3ce44SJohn Forte return;
4859fcf3ce44SJohn Forte
486082527734SSukumar Swaminathan } /* emlxs_fct_link_down() */
4861fcf3ce44SJohn Forte
4862fcf3ce44SJohn Forte
48638f23e9faSHans Rosenfeld void
emlxs_abort_fct_exchange(emlxs_hba_t * hba,emlxs_port_t * port,uint32_t rxid)48648f23e9faSHans Rosenfeld emlxs_abort_fct_exchange(emlxs_hba_t *hba, emlxs_port_t *port, uint32_t rxid)
4865fcf3ce44SJohn Forte {
48668f23e9faSHans Rosenfeld CHANNEL *cp;
48678f23e9faSHans Rosenfeld IOCBQ *iocbq;
48688f23e9faSHans Rosenfeld IOCB *iocb;
48698f23e9faSHans Rosenfeld
48708f23e9faSHans Rosenfeld if (rxid == 0 || rxid == 0xFFFF) {
48718f23e9faSHans Rosenfeld return;
48728f23e9faSHans Rosenfeld }
48738f23e9faSHans Rosenfeld
48748f23e9faSHans Rosenfeld if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
48758f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
48768f23e9faSHans Rosenfeld "Aborting FCT exchange: xid=%x", rxid);
48778f23e9faSHans Rosenfeld
48788f23e9faSHans Rosenfeld if (emlxs_sli4_unreserve_xri(port, rxid, 1) == 0) {
48798f23e9faSHans Rosenfeld /* We have no way to abort unsolicited exchanges */
48808f23e9faSHans Rosenfeld /* that we have not responded to at this time */
48818f23e9faSHans Rosenfeld /* So we will return for now */
48828f23e9faSHans Rosenfeld return;
4883fcf3ce44SJohn Forte }
48848f23e9faSHans Rosenfeld }
4885291a2b48SSukumar Swaminathan
48868f23e9faSHans Rosenfeld cp = &hba->chan[hba->channel_fcp];
4887fcf3ce44SJohn Forte
48888f23e9faSHans Rosenfeld mutex_enter(&EMLXS_FCTAB_LOCK);
48898f23e9faSHans Rosenfeld
48908f23e9faSHans Rosenfeld /* Create the abort IOCB */
48918f23e9faSHans Rosenfeld if (hba->state >= FC_LINK_UP) {
48928f23e9faSHans Rosenfeld iocbq = emlxs_create_abort_xri_cx(port, NULL, rxid, cp,
48938f23e9faSHans Rosenfeld CLASS3, ABORT_TYPE_ABTS);
48948f23e9faSHans Rosenfeld } else {
48958f23e9faSHans Rosenfeld iocbq = emlxs_create_close_xri_cx(port, NULL, rxid, cp);
48968f23e9faSHans Rosenfeld }
48978f23e9faSHans Rosenfeld
48988f23e9faSHans Rosenfeld mutex_exit(&EMLXS_FCTAB_LOCK);
48998f23e9faSHans Rosenfeld
49008f23e9faSHans Rosenfeld if (iocbq) {
49018f23e9faSHans Rosenfeld iocb = &iocbq->iocb;
49028f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
49038f23e9faSHans Rosenfeld "Aborting FCT exchange: xid=%x iotag=%d", rxid,
49048f23e9faSHans Rosenfeld iocb->ULPIOTAG);
49058f23e9faSHans Rosenfeld
49068f23e9faSHans Rosenfeld EMLXS_SLI_ISSUE_IOCB_CMD(hba, cp, iocbq);
49078f23e9faSHans Rosenfeld }
49088f23e9faSHans Rosenfeld
49098f23e9faSHans Rosenfeld } /* emlxs_abort_fct_exchange() */
49108f23e9faSHans Rosenfeld
49118f23e9faSHans Rosenfeld
49128f23e9faSHans Rosenfeld extern uint32_t
emlxs_fct_stmf_alloc(emlxs_hba_t * hba,MATCHMAP * mp)49138f23e9faSHans Rosenfeld emlxs_fct_stmf_alloc(emlxs_hba_t *hba, MATCHMAP *mp)
49148f23e9faSHans Rosenfeld {
49158f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT;
49168f23e9faSHans Rosenfeld stmf_data_buf_t *db;
49178f23e9faSHans Rosenfeld
49188f23e9faSHans Rosenfeld if (mp->tag < MEM_FCTSEG) {
49198f23e9faSHans Rosenfeld return (0);
49208f23e9faSHans Rosenfeld }
49218f23e9faSHans Rosenfeld
49228f23e9faSHans Rosenfeld db = MODSYM(stmf_alloc) (STMF_STRUCT_DATA_BUF, 0, 0);
49238f23e9faSHans Rosenfeld
49248f23e9faSHans Rosenfeld #ifdef FCT_API_TRACE
49258f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
49268f23e9faSHans Rosenfeld "stmf_alloc:%p iotag=%d phys %p virt %p sz %d",
49278f23e9faSHans Rosenfeld db, mp->tag, mp->phys, mp->virt, mp->size);
49288f23e9faSHans Rosenfeld #endif /* FCT_API_TRACE */
49298f23e9faSHans Rosenfeld
49308f23e9faSHans Rosenfeld if (db == NULL) {
49318f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
49328f23e9faSHans Rosenfeld "emlxs_fct_stmf_alloc: alloc failed.");
49338f23e9faSHans Rosenfeld return (1);
49348f23e9faSHans Rosenfeld }
49358f23e9faSHans Rosenfeld
49368f23e9faSHans Rosenfeld db->db_port_private = (void*)mp;
49378f23e9faSHans Rosenfeld db->db_sglist[0].seg_addr = mp->virt;
49388f23e9faSHans Rosenfeld db->db_sglist[0].seg_length = mp->size;
49398f23e9faSHans Rosenfeld db->db_buf_size = mp->size;
49408f23e9faSHans Rosenfeld db->db_sglist_length = 1;
49418f23e9faSHans Rosenfeld
49428f23e9faSHans Rosenfeld mp->fct_private = (void*)db;
49438f23e9faSHans Rosenfeld
49448f23e9faSHans Rosenfeld return (0);
49458f23e9faSHans Rosenfeld
49468f23e9faSHans Rosenfeld } /* emlxs_fct_stmf_alloc() */
49478f23e9faSHans Rosenfeld
49488f23e9faSHans Rosenfeld
49498f23e9faSHans Rosenfeld /* ARGSUSED */
49508f23e9faSHans Rosenfeld extern void
emlxs_fct_stmf_free(emlxs_hba_t * hba,MATCHMAP * mp)49518f23e9faSHans Rosenfeld emlxs_fct_stmf_free(emlxs_hba_t *hba, MATCHMAP *mp)
49528f23e9faSHans Rosenfeld {
49538f23e9faSHans Rosenfeld #ifdef FCT_API_TRACE
49548f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT;
49558f23e9faSHans Rosenfeld #endif /* FCT_API_TRACE */
49568f23e9faSHans Rosenfeld stmf_data_buf_t *db;
49578f23e9faSHans Rosenfeld
49588f23e9faSHans Rosenfeld if (mp->tag < MEM_FCTSEG) {
49598f23e9faSHans Rosenfeld return;
49608f23e9faSHans Rosenfeld }
49618f23e9faSHans Rosenfeld
49628f23e9faSHans Rosenfeld db = (stmf_data_buf_t *)mp->fct_private;
49638f23e9faSHans Rosenfeld mp->fct_private = NULL;
49648f23e9faSHans Rosenfeld
49658f23e9faSHans Rosenfeld if (db == NULL) {
49668f23e9faSHans Rosenfeld return;
49678f23e9faSHans Rosenfeld }
49688f23e9faSHans Rosenfeld
49698f23e9faSHans Rosenfeld #ifdef FCT_API_TRACE
49708f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
49718f23e9faSHans Rosenfeld "stmf_free:%p iotag=%d",
49728f23e9faSHans Rosenfeld db, mp->tag);
49738f23e9faSHans Rosenfeld #endif /* FCT_API_TRACE */
49748f23e9faSHans Rosenfeld
49758f23e9faSHans Rosenfeld MODSYM(stmf_free) (db);
49768f23e9faSHans Rosenfeld
49778f23e9faSHans Rosenfeld return;
49788f23e9faSHans Rosenfeld
49798f23e9faSHans Rosenfeld } /* emlxs_fct_stmf_free() */
49808f23e9faSHans Rosenfeld
49818f23e9faSHans Rosenfeld
49828f23e9faSHans Rosenfeld static void
emlxs_fct_memseg_init(emlxs_hba_t * hba)49838f23e9faSHans Rosenfeld emlxs_fct_memseg_init(emlxs_hba_t *hba)
49848f23e9faSHans Rosenfeld {
49858f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT;
49868f23e9faSHans Rosenfeld char **arrayp = NULL;
49878f23e9faSHans Rosenfeld uint32_t cnt = 0;
49888f23e9faSHans Rosenfeld char buf[32];
49898f23e9faSHans Rosenfeld uint32_t rval;
49908f23e9faSHans Rosenfeld uint8_t *datap;
49918f23e9faSHans Rosenfeld int i;
49928f23e9faSHans Rosenfeld int j;
49938f23e9faSHans Rosenfeld int fct_memseg_cnt = 0;
49948f23e9faSHans Rosenfeld int numblks;
49958f23e9faSHans Rosenfeld int memsize;
49968f23e9faSHans Rosenfeld emlxs_memseg_t *fct_memseg = NULL;
49978f23e9faSHans Rosenfeld uint32_t fct_memseg_size = 0;
49988f23e9faSHans Rosenfeld emlxs_memseg_t *current;
49998f23e9faSHans Rosenfeld emlxs_memseg_t *next;
50008f23e9faSHans Rosenfeld emlxs_memseg_t *seg;
50018f23e9faSHans Rosenfeld
50028f23e9faSHans Rosenfeld port->fct_memseg = NULL;
50038f23e9faSHans Rosenfeld port->fct_memseg_cnt = 0;
50048f23e9faSHans Rosenfeld
50058f23e9faSHans Rosenfeld /* Check for the per adapter setting */
50068f23e9faSHans Rosenfeld (void) snprintf(buf, sizeof (buf), "%s%d-fct-bufpool", DRIVER_NAME,
50078f23e9faSHans Rosenfeld hba->ddiinst);
50088f23e9faSHans Rosenfeld rval = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, hba->dip,
50098f23e9faSHans Rosenfeld (DDI_PROP_DONTPASS), buf, &arrayp, &cnt);
50108f23e9faSHans Rosenfeld
50118f23e9faSHans Rosenfeld if ((rval != DDI_PROP_SUCCESS) || !cnt || !arrayp) {
50128f23e9faSHans Rosenfeld /* Check for the global setting */
50138f23e9faSHans Rosenfeld cnt = 0;
50148f23e9faSHans Rosenfeld arrayp = NULL;
50158f23e9faSHans Rosenfeld rval = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, hba->dip,
50168f23e9faSHans Rosenfeld (DDI_PROP_DONTPASS), "fct-bufpool", &arrayp, &cnt);
50178f23e9faSHans Rosenfeld }
50188f23e9faSHans Rosenfeld
50198f23e9faSHans Rosenfeld if ((rval != DDI_PROP_SUCCESS) || !cnt || !arrayp) {
50208f23e9faSHans Rosenfeld goto default_config;
50218f23e9faSHans Rosenfeld }
50228f23e9faSHans Rosenfeld
50238f23e9faSHans Rosenfeld fct_memseg_size = cnt * sizeof (emlxs_memseg_t);
50248f23e9faSHans Rosenfeld fct_memseg = kmem_zalloc(fct_memseg_size, KM_SLEEP);
50258f23e9faSHans Rosenfeld
50268f23e9faSHans Rosenfeld if (!fct_memseg) {
50278f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
50288f23e9faSHans Rosenfeld "Unable to alloc fct_memseg. cnt=%d. "
50298f23e9faSHans Rosenfeld "Trying default config.",
50308f23e9faSHans Rosenfeld cnt);
50318f23e9faSHans Rosenfeld goto default_config;
50328f23e9faSHans Rosenfeld }
50338f23e9faSHans Rosenfeld
50348f23e9faSHans Rosenfeld for (i = 0; i < cnt; i++) {
50358f23e9faSHans Rosenfeld datap = (uint8_t *)arrayp[i];
50368f23e9faSHans Rosenfeld if (datap == 0) {
50378f23e9faSHans Rosenfeld break;
5038fcf3ce44SJohn Forte }
5039291a2b48SSukumar Swaminathan
50408f23e9faSHans Rosenfeld while (*datap == ' ') { /* Skip spaces */
50418f23e9faSHans Rosenfeld datap++;
50428f23e9faSHans Rosenfeld }
5043fcf3ce44SJohn Forte
50448f23e9faSHans Rosenfeld memsize = emlxs_str_atoi(datap);
50458f23e9faSHans Rosenfeld
50468f23e9faSHans Rosenfeld while ((*datap != ':') && (*datap != 0)) {
50478f23e9faSHans Rosenfeld datap++;
50488f23e9faSHans Rosenfeld }
50498f23e9faSHans Rosenfeld if (*datap == ':') { /* Skip past delimeter */
50508f23e9faSHans Rosenfeld datap++;
50518f23e9faSHans Rosenfeld }
50528f23e9faSHans Rosenfeld while (*datap == ' ') { /* Skip spaces */
50538f23e9faSHans Rosenfeld datap++;
5054fcf3ce44SJohn Forte }
5055fcf3ce44SJohn Forte
50568f23e9faSHans Rosenfeld numblks = emlxs_str_atoi(datap);
5057fcf3ce44SJohn Forte
50588f23e9faSHans Rosenfeld /* Check for a bad entry */
50598f23e9faSHans Rosenfeld if (!memsize || !numblks) {
5060fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
50618f23e9faSHans Rosenfeld "fct-bufpool: Entry %d:%d. Invalid.",
50628f23e9faSHans Rosenfeld memsize, numblks);
50638f23e9faSHans Rosenfeld continue;
5064fcf3ce44SJohn Forte }
5065fcf3ce44SJohn Forte
50668f23e9faSHans Rosenfeld fct_memseg[fct_memseg_cnt].fc_memsize = memsize;
50678f23e9faSHans Rosenfeld fct_memseg[fct_memseg_cnt].fc_numblks = numblks;
50688f23e9faSHans Rosenfeld fct_memseg_cnt++;
50698f23e9faSHans Rosenfeld
50708f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
50718f23e9faSHans Rosenfeld "fct-bufpool: Entry:%d %d:%d",
50728f23e9faSHans Rosenfeld fct_memseg_cnt, memsize, numblks);
50738f23e9faSHans Rosenfeld }
50748f23e9faSHans Rosenfeld
50758f23e9faSHans Rosenfeld if (!fct_memseg_cnt) {
50768f23e9faSHans Rosenfeld kmem_free(fct_memseg, fct_memseg_size);
50778f23e9faSHans Rosenfeld fct_memseg_size = 0;
50788f23e9faSHans Rosenfeld fct_memseg = NULL;
50798f23e9faSHans Rosenfeld }
50808f23e9faSHans Rosenfeld
50818f23e9faSHans Rosenfeld default_config:
50828f23e9faSHans Rosenfeld /* If buffer list is empty, setup defaults */
50838f23e9faSHans Rosenfeld if (!fct_memseg) {
50848f23e9faSHans Rosenfeld
50858f23e9faSHans Rosenfeld fct_memseg_size = 8 * sizeof (emlxs_memseg_t);
50868f23e9faSHans Rosenfeld fct_memseg = kmem_zalloc(fct_memseg_size, KM_SLEEP);
50878f23e9faSHans Rosenfeld
50888f23e9faSHans Rosenfeld if (!fct_memseg) {
5089fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
50908f23e9faSHans Rosenfeld "Unable to alloc default port buffer pool. "
50918f23e9faSHans Rosenfeld "fct_memseg_cnt=%d",
50928f23e9faSHans Rosenfeld cnt);
50938f23e9faSHans Rosenfeld return;
5094fcf3ce44SJohn Forte }
5095fcf3ce44SJohn Forte
50968f23e9faSHans Rosenfeld i = 0;
50978f23e9faSHans Rosenfeld numblks = FCT_BUF_COUNT_2K;
50988f23e9faSHans Rosenfeld if (numblks) {
50998f23e9faSHans Rosenfeld fct_memseg[i].fc_memsize = 2 * 1024;
51008f23e9faSHans Rosenfeld fct_memseg[i++].fc_numblks = FCT_BUF_COUNT_2K;
51018f23e9faSHans Rosenfeld }
51028f23e9faSHans Rosenfeld numblks = FCT_BUF_COUNT_4K;
51038f23e9faSHans Rosenfeld if (numblks) {
51048f23e9faSHans Rosenfeld fct_memseg[i].fc_memsize = 4 * 1024;
51058f23e9faSHans Rosenfeld fct_memseg[i++].fc_numblks = FCT_BUF_COUNT_4K;
51068f23e9faSHans Rosenfeld }
51078f23e9faSHans Rosenfeld numblks = FCT_BUF_COUNT_8K;
51088f23e9faSHans Rosenfeld if (numblks) {
51098f23e9faSHans Rosenfeld fct_memseg[i].fc_memsize = 8 * 1024;
51108f23e9faSHans Rosenfeld fct_memseg[i++].fc_numblks = FCT_BUF_COUNT_8K;
51118f23e9faSHans Rosenfeld }
51128f23e9faSHans Rosenfeld numblks = FCT_BUF_COUNT_16K;
51138f23e9faSHans Rosenfeld if (numblks) {
51148f23e9faSHans Rosenfeld fct_memseg[i].fc_memsize = 16 * 1024;
51158f23e9faSHans Rosenfeld fct_memseg[i++].fc_numblks = FCT_BUF_COUNT_16K;
51168f23e9faSHans Rosenfeld }
51178f23e9faSHans Rosenfeld numblks = FCT_BUF_COUNT_32K;
51188f23e9faSHans Rosenfeld if (numblks) {
51198f23e9faSHans Rosenfeld fct_memseg[i].fc_memsize = 32 * 1024;
51208f23e9faSHans Rosenfeld fct_memseg[i++].fc_numblks = FCT_BUF_COUNT_32K;
5121fcf3ce44SJohn Forte }
51228f23e9faSHans Rosenfeld numblks = FCT_BUF_COUNT_64K;
51238f23e9faSHans Rosenfeld if (numblks) {
51248f23e9faSHans Rosenfeld fct_memseg[i].fc_memsize = 64 * 1024;
51258f23e9faSHans Rosenfeld fct_memseg[i++].fc_numblks = FCT_BUF_COUNT_64K;
51268f23e9faSHans Rosenfeld }
51278f23e9faSHans Rosenfeld numblks = FCT_BUF_COUNT_128K;
51288f23e9faSHans Rosenfeld if (numblks) {
51298f23e9faSHans Rosenfeld fct_memseg[i].fc_memsize = 128 * 1024;
51308f23e9faSHans Rosenfeld fct_memseg[i++].fc_numblks = FCT_BUF_COUNT_128K;
51318f23e9faSHans Rosenfeld }
51328f23e9faSHans Rosenfeld numblks = FCT_BUF_COUNT_256K;
51338f23e9faSHans Rosenfeld if (numblks) {
51348f23e9faSHans Rosenfeld fct_memseg[i].fc_memsize = 256 * 1024;
51358f23e9faSHans Rosenfeld fct_memseg[i++].fc_numblks = FCT_BUF_COUNT_256K;
51368f23e9faSHans Rosenfeld }
51378f23e9faSHans Rosenfeld fct_memseg_cnt = i;
51388f23e9faSHans Rosenfeld }
51398f23e9faSHans Rosenfeld
51408f23e9faSHans Rosenfeld port->fct_memseg = kmem_zalloc((fct_memseg_cnt *
51418f23e9faSHans Rosenfeld sizeof (emlxs_memseg_t)), KM_SLEEP);
5142fcf3ce44SJohn Forte
51438f23e9faSHans Rosenfeld if (!port->fct_memseg) {
5144fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
51458f23e9faSHans Rosenfeld "Unable to alloc port buffer pool. fct_memseg_cnt=%d",
51468f23e9faSHans Rosenfeld fct_memseg_cnt);
51478f23e9faSHans Rosenfeld kmem_free(fct_memseg, fct_memseg_size);
51488f23e9faSHans Rosenfeld return;
51498f23e9faSHans Rosenfeld }
5150fcf3ce44SJohn Forte
51518f23e9faSHans Rosenfeld /* Initalize port bucket list */
51528f23e9faSHans Rosenfeld port->fct_memseg_cnt = fct_memseg_cnt;
5153fcf3ce44SJohn Forte
51548f23e9faSHans Rosenfeld /* Sort the entries smallest to largest */
51558f23e9faSHans Rosenfeld seg = port->fct_memseg;
51568f23e9faSHans Rosenfeld for (i = 0; i < fct_memseg_cnt; i++, seg++) {
5157fcf3ce44SJohn Forte
51588f23e9faSHans Rosenfeld /* Find next smallest buffer */
51598f23e9faSHans Rosenfeld current = fct_memseg;
51608f23e9faSHans Rosenfeld next = NULL;
51618f23e9faSHans Rosenfeld for (j = 0; j < fct_memseg_cnt; j++, current++) {
51628f23e9faSHans Rosenfeld if (current->fc_memsize == 0) {
51638f23e9faSHans Rosenfeld continue;
51648f23e9faSHans Rosenfeld }
5165fcf3ce44SJohn Forte
51668f23e9faSHans Rosenfeld if (next == NULL) {
51678f23e9faSHans Rosenfeld next = current;
51688f23e9faSHans Rosenfeld continue;
51698f23e9faSHans Rosenfeld }
51708f23e9faSHans Rosenfeld
51718f23e9faSHans Rosenfeld if (current->fc_memsize < next->fc_memsize) {
51728f23e9faSHans Rosenfeld next = current;
5173fcf3ce44SJohn Forte }
5174fcf3ce44SJohn Forte }
5175fcf3ce44SJohn Forte
51768f23e9faSHans Rosenfeld /* Save next entry */
51778f23e9faSHans Rosenfeld seg->fc_memsize = next->fc_memsize;
51788f23e9faSHans Rosenfeld seg->fc_numblks = next->fc_numblks;
51798f23e9faSHans Rosenfeld next->fc_memsize = 0;
51808f23e9faSHans Rosenfeld next->fc_numblks = 0;
5181fcf3ce44SJohn Forte }
5182fcf3ce44SJohn Forte
51838f23e9faSHans Rosenfeld kmem_free(fct_memseg, fct_memseg_size);
5184fcf3ce44SJohn Forte
51858f23e9faSHans Rosenfeld /* Complete the initialization */
51868f23e9faSHans Rosenfeld seg = port->fct_memseg;
51878f23e9faSHans Rosenfeld for (i = 0; i < port->fct_memseg_cnt; i++, seg++) {
51888f23e9faSHans Rosenfeld /* seg->fc_memsize = ; Already setup */
51898f23e9faSHans Rosenfeld /* seg->fc_numblks = ; Already setup */
5190fcf3ce44SJohn Forte
51918f23e9faSHans Rosenfeld (void) snprintf(seg->fc_label, sizeof (seg->fc_label),
51928f23e9faSHans Rosenfeld "FCT_DMEM_%d", seg->fc_memsize);
5193fcf3ce44SJohn Forte
51948f23e9faSHans Rosenfeld seg->fc_memtag = MEM_FCTSEG + i;
51958f23e9faSHans Rosenfeld seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG;
51968f23e9faSHans Rosenfeld seg->fc_memalign = 32;
51978f23e9faSHans Rosenfeld seg->fc_hi_water = 0xFFFF;
51988f23e9faSHans Rosenfeld seg->fc_lo_water = seg->fc_numblks;
51998f23e9faSHans Rosenfeld seg->fc_numblks = 0;
52008f23e9faSHans Rosenfeld seg->fc_step = 1;
52018f23e9faSHans Rosenfeld }
5202fcf3ce44SJohn Forte
52038f23e9faSHans Rosenfeld return;
5204fcf3ce44SJohn Forte
52058f23e9faSHans Rosenfeld } /* emlxs_fct_memseg_init() */
5206fcf3ce44SJohn Forte
5207fcf3ce44SJohn Forte
52088f23e9faSHans Rosenfeld fct_status_t
emlxs_fct_dmem_init(emlxs_port_t * port)52098f23e9faSHans Rosenfeld emlxs_fct_dmem_init(emlxs_port_t *port)
52108f23e9faSHans Rosenfeld {
52118f23e9faSHans Rosenfeld emlxs_hba_t *hba = HBA;
52128f23e9faSHans Rosenfeld emlxs_memseg_t *seg;
52138f23e9faSHans Rosenfeld int32_t i;
5214fcf3ce44SJohn Forte
52158f23e9faSHans Rosenfeld /* Initialize the fct memseg list */
52168f23e9faSHans Rosenfeld emlxs_fct_memseg_init(hba);
5217fcf3ce44SJohn Forte
52188f23e9faSHans Rosenfeld if (!port->fct_memseg || !port->fct_memseg_cnt) {
52198f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
52208f23e9faSHans Rosenfeld "fct_dmem_init: fct_memseg list is empty.");
52218f23e9faSHans Rosenfeld return (FCT_FAILURE);
52228f23e9faSHans Rosenfeld }
5223fcf3ce44SJohn Forte
52248f23e9faSHans Rosenfeld /* Create the DMA buffer pools */
52258f23e9faSHans Rosenfeld seg = port->fct_memseg;
52268f23e9faSHans Rosenfeld for (i = 0; i < port->fct_memseg_cnt; i++, seg++) {
5227fcf3ce44SJohn Forte
52288f23e9faSHans Rosenfeld (void) emlxs_mem_pool_create(hba, seg);
52298f23e9faSHans Rosenfeld
52308f23e9faSHans Rosenfeld if (seg->fc_numblks < seg->fc_lo_water) {
52318f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_failed_msg,
52328f23e9faSHans Rosenfeld "%s: count=%d size=%d flags=%x lo=%d hi=%d",
52338f23e9faSHans Rosenfeld seg->fc_label, seg->fc_numblks,
52348f23e9faSHans Rosenfeld seg->fc_memsize, seg->fc_memflag, seg->fc_lo_water,
52358f23e9faSHans Rosenfeld seg->fc_hi_water);
5236fcf3ce44SJohn Forte }
52378f23e9faSHans Rosenfeld }
5238291a2b48SSukumar Swaminathan
52398f23e9faSHans Rosenfeld return (FCT_SUCCESS);
5240fcf3ce44SJohn Forte
52418f23e9faSHans Rosenfeld } /* emlxs_fct_dmem_init */
5242fcf3ce44SJohn Forte
5243fcf3ce44SJohn Forte
52448f23e9faSHans Rosenfeld void
emlxs_fct_dmem_fini(emlxs_port_t * port)52458f23e9faSHans Rosenfeld emlxs_fct_dmem_fini(emlxs_port_t *port)
52468f23e9faSHans Rosenfeld {
52478f23e9faSHans Rosenfeld emlxs_hba_t *hba = HBA;
52488f23e9faSHans Rosenfeld emlxs_memseg_t *seg;
52498f23e9faSHans Rosenfeld int32_t i;
52508f23e9faSHans Rosenfeld
52518f23e9faSHans Rosenfeld if (!port->fct_memseg || !port->fct_memseg_cnt) {
52528f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
52538f23e9faSHans Rosenfeld "fct_dmem_fini: fct_memseg list is empty.");
52548f23e9faSHans Rosenfeld return;
52558f23e9faSHans Rosenfeld }
5256fcf3ce44SJohn Forte
52578f23e9faSHans Rosenfeld /* Destroy the dmem buffer pools */
52588f23e9faSHans Rosenfeld seg = port->fct_memseg;
52598f23e9faSHans Rosenfeld for (i = 0; i < port->fct_memseg_cnt; i++, seg++) {
52608f23e9faSHans Rosenfeld (void) emlxs_mem_pool_destroy(hba, seg);
5261fcf3ce44SJohn Forte }
5262fcf3ce44SJohn Forte
52638f23e9faSHans Rosenfeld /* Clear the segment space */
52648f23e9faSHans Rosenfeld kmem_free(port->fct_memseg,
52658f23e9faSHans Rosenfeld (port->fct_memseg_cnt * sizeof (emlxs_memseg_t)));
52668f23e9faSHans Rosenfeld
52678f23e9faSHans Rosenfeld port->fct_memseg = 0;
52688f23e9faSHans Rosenfeld port->fct_memseg_cnt = 0;
5269fcf3ce44SJohn Forte
5270fcf3ce44SJohn Forte return;
5271fcf3ce44SJohn Forte
52728f23e9faSHans Rosenfeld } /* emlxs_fct_dmem_fini */
5273fcf3ce44SJohn Forte
5274fcf3ce44SJohn Forte
527582527734SSukumar Swaminathan /* COMSTAR ENTER POINT */
52768f23e9faSHans Rosenfeld /*ARGSUSED*/
5277fcf3ce44SJohn Forte static stmf_data_buf_t *
emlxs_fct_dbuf_alloc(fct_local_port_t * fct_port,uint32_t size,uint32_t * pminsize,uint32_t flags)5278fcf3ce44SJohn Forte emlxs_fct_dbuf_alloc(fct_local_port_t *fct_port, uint32_t size,
5279fcf3ce44SJohn Forte uint32_t *pminsize, uint32_t flags)
5280fcf3ce44SJohn Forte {
5281fcf3ce44SJohn Forte emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
52828f23e9faSHans Rosenfeld emlxs_hba_t *hba = HBA;
52838f23e9faSHans Rosenfeld emlxs_memseg_t *seg;
52848f23e9faSHans Rosenfeld stmf_data_buf_t *db;
52858f23e9faSHans Rosenfeld MATCHMAP *mp;
52868f23e9faSHans Rosenfeld int i;
52878f23e9faSHans Rosenfeld uint32_t minsize = 0;
52888f23e9faSHans Rosenfeld
52898f23e9faSHans Rosenfeld if (!port->fct_memseg || !port->fct_memseg_cnt) {
52908f23e9faSHans Rosenfeld goto failed;
52918f23e9faSHans Rosenfeld }
5292fcf3ce44SJohn Forte
52938f23e9faSHans Rosenfeld /* Check if our largest buffer is too small */
52948f23e9faSHans Rosenfeld seg = &port->fct_memseg[port->fct_memseg_cnt-1];
52958f23e9faSHans Rosenfeld if (size > seg->fc_memsize) {
52968f23e9faSHans Rosenfeld goto partial_alloc;
5297fcf3ce44SJohn Forte }
5298291a2b48SSukumar Swaminathan
52998f23e9faSHans Rosenfeld /* Find smallest available buffer >= size */
53008f23e9faSHans Rosenfeld seg = port->fct_memseg;
53018f23e9faSHans Rosenfeld for (i = 0; i < port->fct_memseg_cnt; i++, seg++) {
53028f23e9faSHans Rosenfeld if (seg->fc_memsize < size) {
5303fcf3ce44SJohn Forte continue;
5304fcf3ce44SJohn Forte }
5305291a2b48SSukumar Swaminathan
53068f23e9faSHans Rosenfeld mp = (MATCHMAP*)emlxs_mem_pool_get(hba, seg);
5307291a2b48SSukumar Swaminathan
53088f23e9faSHans Rosenfeld if (mp) {
53098f23e9faSHans Rosenfeld goto success;
53108f23e9faSHans Rosenfeld }
53118f23e9faSHans Rosenfeld }
5312291a2b48SSukumar Swaminathan
53138f23e9faSHans Rosenfeld seg = &port->fct_memseg[port->fct_memseg_cnt-1];
5314fcf3ce44SJohn Forte
53158f23e9faSHans Rosenfeld partial_alloc:
53168f23e9faSHans Rosenfeld /* Find largest available buffer >= *pminsize */
53178f23e9faSHans Rosenfeld for (i = port->fct_memseg_cnt-1; i >= 0; i--, seg--) {
53188f23e9faSHans Rosenfeld if (seg->fc_memsize < *pminsize) {
53198f23e9faSHans Rosenfeld minsize = seg->fc_memsize;
53208f23e9faSHans Rosenfeld goto failed;
53218f23e9faSHans Rosenfeld }
5322fcf3ce44SJohn Forte
53238f23e9faSHans Rosenfeld mp = (MATCHMAP*)emlxs_mem_pool_get(hba, seg);
5324fcf3ce44SJohn Forte
53258f23e9faSHans Rosenfeld if (mp) {
53268f23e9faSHans Rosenfeld goto success;
5327fcf3ce44SJohn Forte }
5328fcf3ce44SJohn Forte }
5329fcf3ce44SJohn Forte
53308f23e9faSHans Rosenfeld failed:
53318f23e9faSHans Rosenfeld *pminsize = minsize;
5332fcf3ce44SJohn Forte TGTPORTSTAT.FctNoBuffer++;
5333fcf3ce44SJohn Forte
5334fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
53358f23e9faSHans Rosenfeld "fct_dbuf_alloc:Failed. size=%d minsize=%d",
53368f23e9faSHans Rosenfeld size, *pminsize);
5337fcf3ce44SJohn Forte
5338fcf3ce44SJohn Forte return (NULL);
5339fcf3ce44SJohn Forte
53408f23e9faSHans Rosenfeld success:
53418f23e9faSHans Rosenfeld /* Setup the data buffer */
53428f23e9faSHans Rosenfeld db = (stmf_data_buf_t *)mp->fct_private;
53438f23e9faSHans Rosenfeld db->db_data_size = min(size, mp->size);
53448f23e9faSHans Rosenfeld
53458f23e9faSHans Rosenfeld #ifdef FCT_API_TRACE
53468f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
53478f23e9faSHans Rosenfeld "fct_dbuf_alloc:%p iotag=%d size=%d,%d",
53488f23e9faSHans Rosenfeld db, mp->tag, size, mp->size);
53498f23e9faSHans Rosenfeld #endif /* FCT_API_TRACE */
53508f23e9faSHans Rosenfeld
53518f23e9faSHans Rosenfeld return (db);
53528f23e9faSHans Rosenfeld
535382527734SSukumar Swaminathan } /* emlxs_fct_dbuf_alloc() */
5354fcf3ce44SJohn Forte
5355fcf3ce44SJohn Forte
535682527734SSukumar Swaminathan /* COMSTAR ENTER POINT */
5357291a2b48SSukumar Swaminathan /*ARGSUSED*/
5358fcf3ce44SJohn Forte static void
emlxs_fct_dbuf_free(fct_dbuf_store_t * fds,stmf_data_buf_t * db)53598f23e9faSHans Rosenfeld emlxs_fct_dbuf_free(fct_dbuf_store_t *fds, stmf_data_buf_t *db)
5360fcf3ce44SJohn Forte {
53618f23e9faSHans Rosenfeld emlxs_port_t *port = (emlxs_port_t *)fds->fds_fca_private;
53628f23e9faSHans Rosenfeld emlxs_hba_t *hba = HBA;
53638f23e9faSHans Rosenfeld MATCHMAP *mp = (MATCHMAP *)db->db_port_private;
53648f23e9faSHans Rosenfeld
53658f23e9faSHans Rosenfeld if (!mp) {
53668f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
53678f23e9faSHans Rosenfeld "fct_dbuf_free:%p NULL mp found!",
53688f23e9faSHans Rosenfeld db);
53698f23e9faSHans Rosenfeld return;
53708f23e9faSHans Rosenfeld }
5371fcf3ce44SJohn Forte
53728f23e9faSHans Rosenfeld #ifdef FCT_API_TRACE
5373fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
53748f23e9faSHans Rosenfeld "fct_dbuf_free:%p iotag=%d",
53758f23e9faSHans Rosenfeld db, mp->tag);
5376291a2b48SSukumar Swaminathan #endif /* FCT_API_TRACE */
5377fcf3ce44SJohn Forte
53788f23e9faSHans Rosenfeld emlxs_mem_pool_put(hba, mp->segment, (void *)mp);
5379fcf3ce44SJohn Forte
538082527734SSukumar Swaminathan } /* emlxs_fct_dbuf_free() */
5381fcf3ce44SJohn Forte
5382fcf3ce44SJohn Forte
5383b3660a96SSukumar Swaminathan static int
emlxs_fct_dbuf_dma_sync(emlxs_hba_t * hba,stmf_data_buf_t * db,uint_t sync_type)53848f23e9faSHans Rosenfeld emlxs_fct_dbuf_dma_sync(emlxs_hba_t *hba, stmf_data_buf_t *db,
5385b3660a96SSukumar Swaminathan uint_t sync_type)
5386fcf3ce44SJohn Forte {
5387b3660a96SSukumar Swaminathan emlxs_port_t *port = &PPORT;
53888f23e9faSHans Rosenfeld MATCHMAP *mp = (MATCHMAP *)db->db_port_private;
5389fcf3ce44SJohn Forte
53908f23e9faSHans Rosenfeld if (!mp) {
53918f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
53928f23e9faSHans Rosenfeld "fct_dbuf_dma_sync:%p NULL mp found!",
53938f23e9faSHans Rosenfeld db);
53948f23e9faSHans Rosenfeld return (0);
53958f23e9faSHans Rosenfeld }
53968f23e9faSHans Rosenfeld
53978f23e9faSHans Rosenfeld #ifdef FCT_API_TRACE
53988f23e9faSHans Rosenfeld {
53998f23e9faSHans Rosenfeld char buf[16];
54008f23e9faSHans Rosenfeld
54018f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
54028f23e9faSHans Rosenfeld "fct_dbuf_dma_sync:%p iotag=%d size=%d",
54038f23e9faSHans Rosenfeld db, mp->tag, db->db_data_size);
54048f23e9faSHans Rosenfeld
54058f23e9faSHans Rosenfeld (void) snprintf(buf, sizeof (buf), "TAG%d:", mp->tag);
54068f23e9faSHans Rosenfeld emlxs_data_dump(port, buf, (uint32_t *)db->db_sglist[0].seg_addr,
54078f23e9faSHans Rosenfeld 36, 0);
54088f23e9faSHans Rosenfeld }
54098f23e9faSHans Rosenfeld #endif /* FCT_API_TRACE */
54108f23e9faSHans Rosenfeld
54118f23e9faSHans Rosenfeld EMLXS_MPDATA_SYNC(mp->dma_handle, 0, db->db_data_size, sync_type);
5412fcf3ce44SJohn Forte
5413b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT
54148f23e9faSHans Rosenfeld if (emlxs_fm_check_dma_handle(hba, mp->dma_handle)
5415b3660a96SSukumar Swaminathan != DDI_FM_OK) {
5416b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT,
5417b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg,
54188f23e9faSHans Rosenfeld "fct_dbuf_dma_sync:%p iotag=%d",
54198f23e9faSHans Rosenfeld db, mp->tag);
54208f23e9faSHans Rosenfeld return (1);
5421b3660a96SSukumar Swaminathan }
5422b3660a96SSukumar Swaminathan #endif /* FMA_SUPPORT */
5423b3660a96SSukumar Swaminathan
54248f23e9faSHans Rosenfeld return (0);
5425b3660a96SSukumar Swaminathan
542682527734SSukumar Swaminathan } /* emlxs_fct_dbuf_dma_sync() */
5427fcf3ce44SJohn Forte
5428291a2b48SSukumar Swaminathan #endif /* SFCT_SUPPORT */
5429