emlxs_fct.c (fcf3ce44) emlxs_fct.c (291a2b48)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 6 unchanged lines hidden (view full) ---

15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 6 unchanged lines hidden (view full) ---

15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2008 Emulex. All rights reserved.
23 * Copyright 2009 Emulex. All rights reserved.
24 * Use is subject to License terms.
25 */
26
24 * Use is subject to License terms.
25 */
26
27#include <emlxs.h>
27
28
28#include "emlxs.h"
29
30#ifdef SFCT_SUPPORT
31
29#ifdef SFCT_SUPPORT
30
32/* #define FCT_API_TRACE Extra debug */
33
34/* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
35EMLXS_MSG_DEF(EMLXS_FCT_C);
36
37#ifndef PORT_SPEED_10G
38#define PORT_SPEED_10G 0x10
31
32/* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
33EMLXS_MSG_DEF(EMLXS_FCT_C);
34
35#ifndef PORT_SPEED_10G
36#define PORT_SPEED_10G 0x10
39#endif /* PORT_SPEED_10G */
37#endif /* PORT_SPEED_10G */
40
38
41static uint32_t emlxs_fct_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp);
42static uint32_t emlxs_fct_sli2_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp);
43static uint32_t emlxs_fct_sli3_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp);
44static void emlxs_fct_handle_acc(emlxs_port_t *port, emlxs_buf_t *sbp,
45 IOCBQ *iocbq);
46static void emlxs_fct_handle_reject(emlxs_port_t *port, emlxs_buf_t *sbp,
47 IOCBQ *iocbq);
39static void emlxs_fct_handle_acc(emlxs_port_t *port, emlxs_buf_t *sbp,
40 IOCBQ *iocbq);
41static void emlxs_fct_handle_reject(emlxs_port_t *port, emlxs_buf_t *sbp,
42 IOCBQ *iocbq);
48static emlxs_buf_t *emlxs_fct_cmd_init(emlxs_port_t *port, fct_cmd_t *fct_cmd);
43static emlxs_buf_t *emlxs_fct_cmd_init(emlxs_port_t *port,
44 fct_cmd_t *fct_cmd);
49static int emlxs_fct_cmd_uninit(emlxs_port_t *port, fct_cmd_t *fct_cmd);
50
51static fct_status_t emlxs_flogi_xchg(struct fct_local_port *fct_port,
52 struct fct_flogi_xchg *fx);
53static fct_status_t emlxs_fct_get_link_info(fct_local_port_t *fct_port,
54 fct_link_info_t *link);
55static fct_status_t emlxs_fct_deregister_remote_port(fct_local_port_t *fct_port,
56 fct_remote_port_t *port_handle);
57static fct_status_t emlxs_fct_send_cmd(fct_cmd_t *fct_cmd);
58static fct_status_t emlxs_fct_send_fcp_data(fct_cmd_t *fct_cmd,
59 stmf_data_buf_t *dbuf, uint32_t ioflags);
45static int emlxs_fct_cmd_uninit(emlxs_port_t *port, fct_cmd_t *fct_cmd);
46
47static fct_status_t emlxs_flogi_xchg(struct fct_local_port *fct_port,
48 struct fct_flogi_xchg *fx);
49static fct_status_t emlxs_fct_get_link_info(fct_local_port_t *fct_port,
50 fct_link_info_t *link);
51static fct_status_t emlxs_fct_deregister_remote_port(fct_local_port_t *fct_port,
52 fct_remote_port_t *port_handle);
53static fct_status_t emlxs_fct_send_cmd(fct_cmd_t *fct_cmd);
54static fct_status_t emlxs_fct_send_fcp_data(fct_cmd_t *fct_cmd,
55 stmf_data_buf_t *dbuf, uint32_t ioflags);
60static fct_status_t emlxs_fct_send_cmd_rsp(fct_cmd_t *fct_cmd,
61 uint32_t ioflags);
62static fct_status_t emlxs_fct_abort(fct_local_port_t *fct_port, fct_cmd_t *cmd,
63 uint32_t flags);
56static fct_status_t emlxs_fct_send_cmd_rsp(fct_cmd_t *fct_cmd, uint32_t flags);
57static fct_status_t emlxs_fct_abort(fct_local_port_t *fct_port,
58 fct_cmd_t *cmd, uint32_t flags);
64static void emlxs_fct_ctl(fct_local_port_t *fct_port, int cmd, void *arg);
65static fct_status_t emlxs_fct_register_remote_port(fct_local_port_t *fct_port,
66 fct_remote_port_t *port_handle, fct_cmd_t *plogi);
67static fct_status_t emlxs_fct_send_els_cmd(fct_cmd_t *fct_cmd);
68static fct_status_t emlxs_fct_send_ct_cmd(fct_cmd_t *fct_cmd);
69static fct_status_t emlxs_fct_send_fcp_status(fct_cmd_t *fct_cmd);
70static fct_status_t emlxs_fct_send_els_rsp(fct_cmd_t *fct_cmd);
59static void emlxs_fct_ctl(fct_local_port_t *fct_port, int cmd, void *arg);
60static fct_status_t emlxs_fct_register_remote_port(fct_local_port_t *fct_port,
61 fct_remote_port_t *port_handle, fct_cmd_t *plogi);
62static fct_status_t emlxs_fct_send_els_cmd(fct_cmd_t *fct_cmd);
63static fct_status_t emlxs_fct_send_ct_cmd(fct_cmd_t *fct_cmd);
64static fct_status_t emlxs_fct_send_fcp_status(fct_cmd_t *fct_cmd);
65static fct_status_t emlxs_fct_send_els_rsp(fct_cmd_t *fct_cmd);
71static fct_status_t emlxs_fct_send_abts_rsp(fct_cmd_t *fct_cmd);
72static void emlxs_fct_pkt_comp(fc_packet_t *pkt);
73static void emlxs_populate_hba_details(fct_local_port_t *fct_port,
74 fct_port_attrs_t *port_attrs);
75
76static fct_status_t emlxs_fct_dmem_init(emlxs_port_t *port);
77static void emlxs_fct_dmem_fini(emlxs_port_t *port);
78
79static stmf_data_buf_t *emlxs_fct_dbuf_alloc(fct_local_port_t *fct_port,
80 uint32_t size, uint32_t *pminsize, uint32_t flags);
81static void emlxs_fct_dbuf_free(fct_dbuf_store_t *fds, stmf_data_buf_t *dbuf);
82
83static void emlxs_fct_dbuf_dma_sync(stmf_data_buf_t *dbuf, uint_t sync_type);
66static void emlxs_fct_pkt_comp(fc_packet_t *pkt);
67static void emlxs_populate_hba_details(fct_local_port_t *fct_port,
68 fct_port_attrs_t *port_attrs);
69
70static fct_status_t emlxs_fct_dmem_init(emlxs_port_t *port);
71static void emlxs_fct_dmem_fini(emlxs_port_t *port);
72
73static stmf_data_buf_t *emlxs_fct_dbuf_alloc(fct_local_port_t *fct_port,
74 uint32_t size, uint32_t *pminsize, uint32_t flags);
75static void emlxs_fct_dbuf_free(fct_dbuf_store_t *fds, stmf_data_buf_t *dbuf);
76
77static void emlxs_fct_dbuf_dma_sync(stmf_data_buf_t *dbuf, uint_t sync_type);
84static emlxs_buf_t *emlxs_fct_pkt_init(emlxs_port_t *port, fct_cmd_t *fct_cmd,
85 fc_packet_t *pkt);
78static emlxs_buf_t *emlxs_fct_pkt_init(emlxs_port_t *port,
79 fct_cmd_t *fct_cmd, fc_packet_t *pkt);
86
87static void emlxs_fct_unsol_flush(emlxs_port_t *port);
88static uint32_t emlxs_fct_process_unsol_flogi(emlxs_port_t *port, RING *rp,
89 IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
90static uint32_t emlxs_fct_process_unsol_plogi(emlxs_port_t *port, RING *rp,
91 IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
80
81static void emlxs_fct_unsol_flush(emlxs_port_t *port);
82static uint32_t emlxs_fct_process_unsol_flogi(emlxs_port_t *port, RING *rp,
83 IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
84static uint32_t emlxs_fct_process_unsol_plogi(emlxs_port_t *port, RING *rp,
85 IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
92static void emlxs_fct_handle_rcvd_flogi(emlxs_port_t *port, fct_cmd_t *fct_cmd);
93static fct_status_t emlxs_fct_pkt_abort(emlxs_port_t *port, emlxs_buf_t *sbp);
94static fct_status_t emlxs_fct_send_qfull_reply(emlxs_port_t *port,
95 emlxs_node_t *ndlp, uint16_t xid, uint32_t class, emlxs_fcp_cmd_t *fcp_cmd);
86static fct_status_t emlxs_fct_pkt_abort(emlxs_port_t *port, emlxs_buf_t *sbp);
87static fct_status_t emlxs_fct_send_qfull_reply(emlxs_port_t *port,
88 emlxs_node_t *ndlp, uint16_t xid, uint32_t class, emlxs_fcp_cmd_t *fcp_cmd);
89static void emlxs_fct_dbuf_dma_sync(stmf_data_buf_t *dbuf, uint_t sync_type);
96
90
91#ifdef FCT_IO_TRACE
92uint8_t *emlxs_iotrace = 0; /* global for mdb */
93int emlxs_iotrace_cnt = 0;
94
95void
96emlxs_fct_io_trace(emlxs_port_t *port, fct_cmd_t *fct_cmd, uint32_t data)
97{
98 emlxs_iotrace_t *iop = port->iotrace;
99 uint16_t iotrace_cnt;
100 uint16_t iotrace_index;
101 int i;
102
103 if (!iop) {
104 return;
105 }
106
107 mutex_enter(&port->iotrace_mtx);
108 iotrace_cnt = port->iotrace_cnt;
109 iotrace_index = port->iotrace_index;
110
111 switch (data) {
112
113 /* New entry */
114 case EMLXS_FCT_ELS_CMD_RECEIVED:
115 case EMLXS_FCT_FCP_CMD_RECEIVED:
116 case EMLXS_FCT_SEND_ELS_REQ:
117 case EMLXS_FCT_SEND_CT_REQ:
118 for (i = 0; i < iotrace_cnt; i++) {
119 if ((iop->fct_cmd == fct_cmd) &&
120 (iop->trc[0] != (uint8_t)(0)))
121 break;
122 iop++;
123 }
124 if (i < iotrace_cnt) {
125 /* New entry already exists */
126 mutex_exit(&port->iotrace_mtx);
127 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
128 "IOTRACE: New entry already exists: fct_cmd: %p",
129 fct_cmd);
130 return;
131 }
132 iop = port->iotrace + iotrace_index;
133 for (i = 0; i < iotrace_cnt; i++) {
134 if (iop->trc[0] == (uint8_t)(0))
135 break;
136
137 iop++;
138 if (iop == (port->iotrace + iotrace_cnt))
139 iop = port->iotrace;
140 }
141 if (i >= iotrace_cnt) {
142 /* No new slots available */
143 mutex_exit(&port->iotrace_mtx);
144 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
145 "IOTRACE: No new slots: fct_cmd: %p data: %d",
146 fct_cmd, data);
147 return;
148 }
149 port->iotrace_index++;
150 if (port->iotrace_index >= iotrace_cnt)
151 port->iotrace_index = 0;
152
153 bzero((uint8_t *)iop, sizeof (emlxs_iotrace_t));
154 iop->fct_cmd = fct_cmd;
155 iop->xri = fct_cmd->cmd_rxid;
156 iop->marker = 0xff;
157 iop->trc[0] = 2;
158 iop->trc[1] = data;
159 mutex_exit(&port->iotrace_mtx);
160 return;
161 }
162
163 for (i = 0; i < iotrace_cnt; i++) {
164 if ((iop->fct_cmd == fct_cmd) &&
165 (iop->trc[0] != (uint8_t)(0)))
166 break;
167 iop++;
168 }
169 if (i >= iotrace_cnt) {
170 /* Cannot find existing slot for fct_cmd */
171 mutex_exit(&port->iotrace_mtx);
172
173 if ((data != EMLXS_FCT_REG_PENDING) &&
174 (data != EMLXS_FCT_REG_COMPLETE)) {
175 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
176 "IOTRACE: Missing slot: fct_cmd: %p data: %d",
177 fct_cmd, data);
178 }
179 return;
180 }
181
182 if (iop->trc[0] >= MAX_IO_TRACE) {
183 /* trc overrun for fct_cmd */
184 mutex_exit(&port->iotrace_mtx);
185 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
186 "IOTRACE: trc overrun slot: fct_cmd: %p data: %d",
187 fct_cmd, data);
188 return;
189 }
190
191 if (iop->xri != fct_cmd->cmd_rxid) {
192 /* xri mismatch for fct_cmd */
193 mutex_exit(&port->iotrace_mtx);
194 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
195 "IOTRACE: xri mismatch %x != %x: fct_cmd: %p data: %d",
196 iop->xri, fct_cmd->cmd_rxid, fct_cmd, data);
197 return;
198 }
199
200 iop->trc[iop->trc[0]] = data;
201 if ((data == EMLXS_FCT_IO_DONE) || (data == EMLXS_FCT_ABORT_DONE)) {
202 /* IOCB ulpCommand is saved after EMLXS_FCT_IOCB_ISSUED */
203 if (iop->trc[iop->trc[0]-1] == EMLXS_FCT_IOCB_ISSUED)
204 iop->trc[0]++;
205 else
206 iop->trc[0] = 0;
207 }
208 else
209 iop->trc[0]++;
210 mutex_exit(&port->iotrace_mtx);
211}
212#endif /* FCT_IO_TRACE */
213
97#ifdef MODSYM_SUPPORT
98
99static int
100emlxs_fct_modopen()
101{
102 int err;
103
104 if (emlxs_modsym.mod_fct) {
105 return (1);
106 }
214#ifdef MODSYM_SUPPORT
215
216static int
217emlxs_fct_modopen()
218{
219 int err;
220
221 if (emlxs_modsym.mod_fct) {
222 return (1);
223 }
224
107 /* Comstar (fct) */
108 err = 0;
109 emlxs_modsym.mod_fct = ddi_modopen("drv/fct", KRTLD_MODE_FIRST, &err);
110 if (!emlxs_modsym.mod_fct) {
111
112 cmn_err(CE_WARN, "?%s: ddi_modopen drv/fct failed: err %d",
113 DRIVER_NAME, err);
114 goto failed;
115 }
225 /* Comstar (fct) */
226 err = 0;
227 emlxs_modsym.mod_fct = ddi_modopen("drv/fct", KRTLD_MODE_FIRST, &err);
228 if (!emlxs_modsym.mod_fct) {
229
230 cmn_err(CE_WARN, "?%s: ddi_modopen drv/fct failed: err %d",
231 DRIVER_NAME, err);
232 goto failed;
233 }
234
116 /* Comstar (stmf) */
117 err = 0;
235 /* Comstar (stmf) */
236 err = 0;
118 emlxs_modsym.mod_stmf = ddi_modopen("drv/stmf", KRTLD_MODE_FIRST, &err);
237 emlxs_modsym.mod_stmf =
238 ddi_modopen("drv/stmf", KRTLD_MODE_FIRST, &err);
119 if (!emlxs_modsym.mod_stmf) {
120
121 cmn_err(CE_WARN, "?%s: ddi_modopen drv/stmf failed: err %d",
122 DRIVER_NAME, err);
123 goto failed;
124 }
239 if (!emlxs_modsym.mod_stmf) {
240
241 cmn_err(CE_WARN, "?%s: ddi_modopen drv/stmf failed: err %d",
242 DRIVER_NAME, err);
243 goto failed;
244 }
245
125 err = 0;
126 /* Check if the fct fct_alloc is present */
246 err = 0;
247 /* Check if the fct fct_alloc is present */
127 emlxs_modsym.fct_alloc = (void *(*) ()) ddi_modsym(emlxs_modsym.mod_fct,
248 emlxs_modsym.fct_alloc = (void *(*)())ddi_modsym(emlxs_modsym.mod_fct,
128 "fct_alloc", &err);
129 if ((void *)emlxs_modsym.fct_alloc == NULL) {
130 cmn_err(CE_WARN,
131 "?%s: drv/fct: fct_alloc not present", DRIVER_NAME);
132 goto failed;
133 }
249 "fct_alloc", &err);
250 if ((void *)emlxs_modsym.fct_alloc == NULL) {
251 cmn_err(CE_WARN,
252 "?%s: drv/fct: fct_alloc not present", DRIVER_NAME);
253 goto failed;
254 }
255
134 err = 0;
135 /* Check if the fct fct_free is present */
256 err = 0;
257 /* Check if the fct fct_free is present */
136 emlxs_modsym.fct_free = (void (*) ())ddi_modsym(emlxs_modsym.mod_fct,
258 emlxs_modsym.fct_free = (void (*)())ddi_modsym(emlxs_modsym.mod_fct,
137 "fct_free", &err);
138 if ((void *)emlxs_modsym.fct_free == NULL) {
139 cmn_err(CE_WARN,
140 "?%s: drv/fct: fct_free not present", DRIVER_NAME);
141 goto failed;
142 }
259 "fct_free", &err);
260 if ((void *)emlxs_modsym.fct_free == NULL) {
261 cmn_err(CE_WARN,
262 "?%s: drv/fct: fct_free not present", DRIVER_NAME);
263 goto failed;
264 }
265
143 err = 0;
144 /* Check if the fct fct_scsi_task_alloc is present */
266 err = 0;
267 /* Check if the fct fct_scsi_task_alloc is present */
145 emlxs_modsym.fct_scsi_task_alloc = (void *(*) ())
146 ddi_modsym(emlxs_modsym.mod_fct, "fct_scsi_task_alloc", &err);
268 emlxs_modsym.fct_scsi_task_alloc =
269 (void *(*)(void *, uint16_t, uint32_t, uint8_t *,
270 uint16_t, uint16_t))ddi_modsym(emlxs_modsym.mod_fct,
271 "fct_scsi_task_alloc", &err);
147 if ((void *)emlxs_modsym.fct_scsi_task_alloc == NULL) {
148 cmn_err(CE_WARN,
149 "?%s: drv/fct: fct_scsi_task_alloc not present",
150 DRIVER_NAME);
151 goto failed;
152 }
272 if ((void *)emlxs_modsym.fct_scsi_task_alloc == NULL) {
273 cmn_err(CE_WARN,
274 "?%s: drv/fct: fct_scsi_task_alloc not present",
275 DRIVER_NAME);
276 goto failed;
277 }
278
153 err = 0;
154 /* Check if the fct fct_register_local_port is present */
279 err = 0;
280 /* Check if the fct fct_register_local_port is present */
155 emlxs_modsym.fct_register_local_port = (int (*) ())
156 ddi_modsym(emlxs_modsym.mod_fct, "fct_register_local_port", &err);
281 emlxs_modsym.fct_register_local_port =
282 (int (*)())ddi_modsym(emlxs_modsym.mod_fct,
283 "fct_register_local_port", &err);
157 if ((void *)emlxs_modsym.fct_register_local_port == NULL) {
158 cmn_err(CE_WARN,
159 "?%s: drv/fct: fct_register_local_port not present",
160 DRIVER_NAME);
161 goto failed;
162 }
284 if ((void *)emlxs_modsym.fct_register_local_port == NULL) {
285 cmn_err(CE_WARN,
286 "?%s: drv/fct: fct_register_local_port not present",
287 DRIVER_NAME);
288 goto failed;
289 }
290
163 err = 0;
164 /* Check if the fct fct_deregister_local_port is present */
291 err = 0;
292 /* Check if the fct fct_deregister_local_port is present */
165 emlxs_modsym.fct_deregister_local_port = (void (*) ())
166 ddi_modsym(emlxs_modsym.mod_fct, "fct_deregister_local_port", &err);
293 emlxs_modsym.fct_deregister_local_port =
294 (void (*)())ddi_modsym(emlxs_modsym.mod_fct,
295 "fct_deregister_local_port", &err);
167 if ((void *)emlxs_modsym.fct_deregister_local_port == NULL) {
168 cmn_err(CE_WARN,
169 "?%s: drv/fct: fct_deregister_local_port not present",
170 DRIVER_NAME);
171 goto failed;
172 }
296 if ((void *)emlxs_modsym.fct_deregister_local_port == NULL) {
297 cmn_err(CE_WARN,
298 "?%s: drv/fct: fct_deregister_local_port not present",
299 DRIVER_NAME);
300 goto failed;
301 }
302
173 err = 0;
174 /* Check if the fct fct_handle_event is present */
303 err = 0;
304 /* Check if the fct fct_handle_event is present */
175 emlxs_modsym.fct_handle_event = (void (*) ())
176 ddi_modsym(emlxs_modsym.mod_fct, "fct_handle_event", &err);
305 emlxs_modsym.fct_handle_event =
306 (void (*)())ddi_modsym(emlxs_modsym.mod_fct, "fct_handle_event",
307 &err);
177 if ((void *)emlxs_modsym.fct_handle_event == NULL) {
178 cmn_err(CE_WARN,
308 if ((void *)emlxs_modsym.fct_handle_event == NULL) {
309 cmn_err(CE_WARN,
179 "?%s: drv/fct: fct_handle_event not present", DRIVER_NAME);
310 "?%s: drv/fct: fct_handle_event not present",
311 DRIVER_NAME);
180 goto failed;
181 }
312 goto failed;
313 }
314
182 err = 0;
183 /* Check if the fct fct_post_rcvd_cmd is present */
315 err = 0;
316 /* Check if the fct fct_post_rcvd_cmd is present */
184 emlxs_modsym.fct_post_rcvd_cmd = (void (*) ())
185 ddi_modsym(emlxs_modsym.mod_fct, "fct_post_rcvd_cmd", &err);
317 emlxs_modsym.fct_post_rcvd_cmd =
318 (void (*)())ddi_modsym(emlxs_modsym.mod_fct, "fct_post_rcvd_cmd",
319 &err);
186 if ((void *)emlxs_modsym.fct_post_rcvd_cmd == NULL) {
187 cmn_err(CE_WARN,
320 if ((void *)emlxs_modsym.fct_post_rcvd_cmd == NULL) {
321 cmn_err(CE_WARN,
188 "?%s: drv/fct: fct_post_rcvd_cmd not present", DRIVER_NAME);
322 "?%s: drv/fct: fct_post_rcvd_cmd not present",
323 DRIVER_NAME);
189 goto failed;
190 }
191 err = 0;
192 /* Check if the fct fct_alloc is present */
324 goto failed;
325 }
326 err = 0;
327 /* Check if the fct fct_alloc is present */
193 emlxs_modsym.fct_ctl = (void (*) ())ddi_modsym(emlxs_modsym.mod_fct,
328 emlxs_modsym.fct_ctl = (void (*)())ddi_modsym(emlxs_modsym.mod_fct,
194 "fct_ctl", &err);
195 if ((void *)emlxs_modsym.fct_ctl == NULL) {
196 cmn_err(CE_WARN,
197 "?%s: drv/fct: fct_ctl not present", DRIVER_NAME);
198 goto failed;
199 }
200 err = 0;
329 "fct_ctl", &err);
330 if ((void *)emlxs_modsym.fct_ctl == NULL) {
331 cmn_err(CE_WARN,
332 "?%s: drv/fct: fct_ctl not present", DRIVER_NAME);
333 goto failed;
334 }
335 err = 0;
336 /* Check if the fct fct_queue_cmd_for_termination is present */
337 emlxs_modsym.fct_queue_cmd_for_termination =
338 (void (*)())ddi_modsym(emlxs_modsym.mod_fct,
339 "fct_queue_cmd_for_termination", &err);
340 if ((void *)emlxs_modsym.fct_queue_cmd_for_termination == NULL) {
341 cmn_err(CE_WARN,
342 "?%s: drv/fct: fct_queue_cmd_for_termination not present",
343 DRIVER_NAME);
344 goto failed;
345 }
346 err = 0;
201 /* Check if the fct fct_send_response_done is present */
347 /* Check if the fct fct_send_response_done is present */
202 emlxs_modsym.fct_send_response_done = (void (*) ())
203 ddi_modsym(emlxs_modsym.mod_fct, "fct_send_response_done", &err);
348 emlxs_modsym.fct_send_response_done =
349 (void (*)())ddi_modsym(emlxs_modsym.mod_fct,
350 "fct_send_response_done", &err);
204 if ((void *)emlxs_modsym.fct_send_response_done == NULL) {
205 cmn_err(CE_WARN,
206 "?%s: drv/fct: fct_send_response_done not present",
207 DRIVER_NAME);
208 goto failed;
209 }
210 err = 0;
211 /* Check if the fct fct_send_cmd_done is present */
351 if ((void *)emlxs_modsym.fct_send_response_done == NULL) {
352 cmn_err(CE_WARN,
353 "?%s: drv/fct: fct_send_response_done not present",
354 DRIVER_NAME);
355 goto failed;
356 }
357 err = 0;
358 /* Check if the fct fct_send_cmd_done is present */
212 emlxs_modsym.fct_send_cmd_done = (void (*) ())
213 ddi_modsym(emlxs_modsym.mod_fct, "fct_send_cmd_done", &err);
359 emlxs_modsym.fct_send_cmd_done =
360 (void (*)())ddi_modsym(emlxs_modsym.mod_fct, "fct_send_cmd_done",
361 &err);
214 if ((void *)emlxs_modsym.fct_send_cmd_done == NULL) {
215 cmn_err(CE_WARN,
362 if ((void *)emlxs_modsym.fct_send_cmd_done == NULL) {
363 cmn_err(CE_WARN,
216 "?%s: drv/fct: fct_send_cmd_done not present", DRIVER_NAME);
364 "?%s: drv/fct: fct_send_cmd_done not present",
365 DRIVER_NAME);
217 goto failed;
218 }
219 err = 0;
220 /* Check if the fct fct_scsi_xfer_data_done is present */
366 goto failed;
367 }
368 err = 0;
369 /* Check if the fct fct_scsi_xfer_data_done is present */
221 emlxs_modsym.fct_scsi_data_xfer_done = (void (*) ())
222 ddi_modsym(emlxs_modsym.mod_fct, "fct_scsi_data_xfer_done", &err);
370 emlxs_modsym.fct_scsi_data_xfer_done =
371 (void (*)())ddi_modsym(emlxs_modsym.mod_fct,
372 "fct_scsi_data_xfer_done", &err);
223 if ((void *)emlxs_modsym.fct_scsi_data_xfer_done == NULL) {
224 cmn_err(CE_WARN,
225 "?%s: drv/fct: fct_scsi_data_xfer_done not present",
226 DRIVER_NAME);
227 goto failed;
228 }
229 err = 0;
230 /* Check if the fct fct_port_shutdown is present */
373 if ((void *)emlxs_modsym.fct_scsi_data_xfer_done == NULL) {
374 cmn_err(CE_WARN,
375 "?%s: drv/fct: fct_scsi_data_xfer_done not present",
376 DRIVER_NAME);
377 goto failed;
378 }
379 err = 0;
380 /* Check if the fct fct_port_shutdown is present */
231 emlxs_modsym.fct_port_shutdown = (fct_status_t(*) ())
232 ddi_modsym(emlxs_modsym.mod_fct, "fct_port_shutdown", &err);
381 emlxs_modsym.fct_port_shutdown =
382 (fct_status_t(*)())ddi_modsym(emlxs_modsym.mod_fct,
383 "fct_port_shutdown", &err);
233 if ((void *)emlxs_modsym.fct_port_shutdown == NULL) {
234 cmn_err(CE_WARN,
384 if ((void *)emlxs_modsym.fct_port_shutdown == NULL) {
385 cmn_err(CE_WARN,
235 "?%s: drv/fct: fct_port_shutdown not present", DRIVER_NAME);
386 "?%s: drv/fct: fct_port_shutdown not present",
387 DRIVER_NAME);
236 goto failed;
237 }
388 goto failed;
389 }
390
238 err = 0;
239 /* Check if the fct fct_port_initialize is present */
391 err = 0;
392 /* Check if the fct fct_port_initialize is present */
240 emlxs_modsym.fct_port_initialize = (fct_status_t(*) ())
241 ddi_modsym(emlxs_modsym.mod_fct, "fct_port_initialize", &err);
393 emlxs_modsym.fct_port_initialize =
394 (fct_status_t(*)())ddi_modsym(emlxs_modsym.mod_fct,
395 "fct_port_initialize", &err);
242 if ((void *)emlxs_modsym.fct_port_initialize == NULL) {
243 cmn_err(CE_WARN,
244 "?%s: drv/fct: fct_port_initialize not present",
245 DRIVER_NAME);
246 goto failed;
247 }
396 if ((void *)emlxs_modsym.fct_port_initialize == NULL) {
397 cmn_err(CE_WARN,
398 "?%s: drv/fct: fct_port_initialize not present",
399 DRIVER_NAME);
400 goto failed;
401 }
402
248 err = 0;
403 err = 0;
404 /* Check if the fct fct_cmd_fca_aborted is present */
405 emlxs_modsym.fct_cmd_fca_aborted =
406 (void (*)())ddi_modsym(emlxs_modsym.mod_fct,
407 "fct_cmd_fca_aborted", &err);
408 if ((void *)emlxs_modsym.fct_cmd_fca_aborted == NULL) {
409 cmn_err(CE_WARN,
410 "?%s: drv/fct: fct_cmd_fca_aborted not present",
411 DRIVER_NAME);
412 goto failed;
413 }
414
415 err = 0;
249 /* Check if the fct fct_handle_rcvd_flogi is present */
416 /* Check if the fct fct_handle_rcvd_flogi is present */
250 emlxs_modsym.fct_handle_rcvd_flogi = (fct_status_t(*) ())
251 ddi_modsym(emlxs_modsym.mod_fct, "fct_handle_rcvd_flogi", &err);
417 emlxs_modsym.fct_handle_rcvd_flogi =
418 (fct_status_t(*)())ddi_modsym(emlxs_modsym.mod_fct,
419 "fct_handle_rcvd_flogi", &err);
252 if ((void *)emlxs_modsym.fct_handle_rcvd_flogi == NULL) {
253 cmn_err(CE_WARN,
254 "?%s: drv/fct: fct_handle_rcvd_flogi not present",
255 DRIVER_NAME);
256 goto failed;
257 }
420 if ((void *)emlxs_modsym.fct_handle_rcvd_flogi == NULL) {
421 cmn_err(CE_WARN,
422 "?%s: drv/fct: fct_handle_rcvd_flogi not present",
423 DRIVER_NAME);
424 goto failed;
425 }
426
258 /* Comstar (stmf) */
259 err = 0;
260 /* Check if the stmf stmf_alloc is present */
427 /* Comstar (stmf) */
428 err = 0;
429 /* Check if the stmf stmf_alloc is present */
261 emlxs_modsym.stmf_alloc = (void *(*) ())
262 ddi_modsym(emlxs_modsym.mod_stmf, "stmf_alloc", &err);
430 emlxs_modsym.stmf_alloc =
431 (void *(*)())ddi_modsym(emlxs_modsym.mod_stmf, "stmf_alloc",
432 &err);
263 if ((void *)emlxs_modsym.stmf_alloc == NULL) {
264 cmn_err(CE_WARN,
265 "?%s: drv/stmf: stmf_alloc not present", DRIVER_NAME);
266 goto failed;
267 }
433 if ((void *)emlxs_modsym.stmf_alloc == NULL) {
434 cmn_err(CE_WARN,
435 "?%s: drv/stmf: stmf_alloc not present", DRIVER_NAME);
436 goto failed;
437 }
438
268 err = 0;
269 /* Check if the stmf stmf_free is present */
439 err = 0;
440 /* Check if the stmf stmf_free is present */
270 emlxs_modsym.stmf_free = (void (*) ())ddi_modsym(emlxs_modsym.mod_stmf,
441 emlxs_modsym.stmf_free = (void (*)())ddi_modsym(emlxs_modsym.mod_stmf,
271 "stmf_free", &err);
272 if ((void *)emlxs_modsym.stmf_free == NULL) {
273 cmn_err(CE_WARN,
274 "?%s: drv/stmf: stmf_free not present", DRIVER_NAME);
275 goto failed;
276 }
442 "stmf_free", &err);
443 if ((void *)emlxs_modsym.stmf_free == NULL) {
444 cmn_err(CE_WARN,
445 "?%s: drv/stmf: stmf_free not present", DRIVER_NAME);
446 goto failed;
447 }
448
277 err = 0;
278 /* Check if the stmf stmf_deregister_port_provider is present */
279 emlxs_modsym.stmf_deregister_port_provider =
449 err = 0;
450 /* Check if the stmf stmf_deregister_port_provider is present */
451 emlxs_modsym.stmf_deregister_port_provider =
280 (void (*) ())ddi_modsym(emlxs_modsym.mod_stmf,
452 (void (*)())ddi_modsym(emlxs_modsym.mod_stmf,
281 "stmf_deregister_port_provider", &err);
282 if ((void *)emlxs_modsym.stmf_deregister_port_provider == NULL) {
283 cmn_err(CE_WARN,
284 "?%s: drv/stmf: stmf_deregister_port_provider not present",
285 DRIVER_NAME);
286 goto failed;
287 }
453 "stmf_deregister_port_provider", &err);
454 if ((void *)emlxs_modsym.stmf_deregister_port_provider == NULL) {
455 cmn_err(CE_WARN,
456 "?%s: drv/stmf: stmf_deregister_port_provider not present",
457 DRIVER_NAME);
458 goto failed;
459 }
460
288 err = 0;
289 /* Check if the stmf stmf_register_port_provider is present */
290 emlxs_modsym.stmf_register_port_provider =
461 err = 0;
462 /* Check if the stmf stmf_register_port_provider is present */
463 emlxs_modsym.stmf_register_port_provider =
291 (int (*) ())ddi_modsym(emlxs_modsym.mod_stmf,
464 (int (*)())ddi_modsym(emlxs_modsym.mod_stmf,
292 "stmf_register_port_provider", &err);
293 if ((void *)emlxs_modsym.stmf_register_port_provider == NULL) {
294 cmn_err(CE_WARN,
295 "?%s: drv/stmf: stmf_register_port_provider not present",
296 DRIVER_NAME);
297 goto failed;
298 }
299 return (1);
300
301failed:
465 "stmf_register_port_provider", &err);
466 if ((void *)emlxs_modsym.stmf_register_port_provider == NULL) {
467 cmn_err(CE_WARN,
468 "?%s: drv/stmf: stmf_register_port_provider not present",
469 DRIVER_NAME);
470 goto failed;
471 }
472 return (1);
473
474failed:
302
303 emlxs_fct_modclose();
475 emlxs_fct_modclose();
304
305 return (0);
306
476 return (0);
477
307} /* emlxs_fct_modopen() */
478} /* emlxs_fct_modopen() */
308
309
310extern void
311emlxs_fct_modclose()
312{
313
314 if (emlxs_modsym.mod_fct) {
315 (void) ddi_modclose(emlxs_modsym.mod_fct);
316 emlxs_modsym.mod_fct = 0;
317 }
479
480
481extern void
482emlxs_fct_modclose()
483{
484
485 if (emlxs_modsym.mod_fct) {
486 (void) ddi_modclose(emlxs_modsym.mod_fct);
487 emlxs_modsym.mod_fct = 0;
488 }
489
318 if (emlxs_modsym.mod_stmf) {
319 (void) ddi_modclose(emlxs_modsym.mod_stmf);
320 emlxs_modsym.mod_stmf = 0;
321 }
490 if (emlxs_modsym.mod_stmf) {
491 (void) ddi_modclose(emlxs_modsym.mod_stmf);
492 emlxs_modsym.mod_stmf = 0;
493 }
494
322 emlxs_modsym.fct_alloc = NULL;
323 emlxs_modsym.fct_free = NULL;
324 emlxs_modsym.fct_scsi_task_alloc = NULL;
325 emlxs_modsym.fct_register_local_port = NULL;
326 emlxs_modsym.fct_deregister_local_port = NULL;
327 emlxs_modsym.fct_handle_event = NULL;
328 emlxs_modsym.fct_ctl = NULL;
495 emlxs_modsym.fct_alloc = NULL;
496 emlxs_modsym.fct_free = NULL;
497 emlxs_modsym.fct_scsi_task_alloc = NULL;
498 emlxs_modsym.fct_register_local_port = NULL;
499 emlxs_modsym.fct_deregister_local_port = NULL;
500 emlxs_modsym.fct_handle_event = NULL;
501 emlxs_modsym.fct_ctl = NULL;
502 emlxs_modsym.fct_queue_cmd_for_termination = NULL;
329 emlxs_modsym.fct_send_response_done = NULL;
330 emlxs_modsym.fct_send_cmd_done = NULL;
331 emlxs_modsym.fct_scsi_data_xfer_done = NULL;
332 emlxs_modsym.fct_port_shutdown = NULL;
333 emlxs_modsym.fct_port_initialize = NULL;
503 emlxs_modsym.fct_send_response_done = NULL;
504 emlxs_modsym.fct_send_cmd_done = NULL;
505 emlxs_modsym.fct_scsi_data_xfer_done = NULL;
506 emlxs_modsym.fct_port_shutdown = NULL;
507 emlxs_modsym.fct_port_initialize = NULL;
508 emlxs_modsym.fct_cmd_fca_aborted = NULL;
334 emlxs_modsym.fct_handle_rcvd_flogi = NULL;
335
336 emlxs_modsym.stmf_alloc = NULL;
337 emlxs_modsym.stmf_free = NULL;
338 emlxs_modsym.stmf_deregister_port_provider = NULL;
339 emlxs_modsym.stmf_register_port_provider = NULL;
340
509 emlxs_modsym.fct_handle_rcvd_flogi = NULL;
510
511 emlxs_modsym.stmf_alloc = NULL;
512 emlxs_modsym.stmf_free = NULL;
513 emlxs_modsym.stmf_deregister_port_provider = NULL;
514 emlxs_modsym.stmf_register_port_provider = NULL;
515
341} /* emlxs_fct_modclose() */
516} /* emlxs_fct_modclose() */
342
517
343#endif /* MODSYM_SUPPORT */
518#endif /* MODSYM_SUPPORT */
344
345
519
520
521/* This routine is called to process a FLOGI ELS command that been recieved. */
522static void
523emlxs_fct_handle_rcvd_flogi(emlxs_port_t *port)
524{
525 fct_status_t status;
526 IOCBQ iocbq;
346
527
528 /*
529 * If FCT has been notified of a Link Up event, process the
530 * FLOGI now. Otherwise, defer processing till the Link Up happens.
531 */
532 if (port->fct_flags & FCT_STATE_LINK_UP) {
533 /* Setup for call to emlxs_els_reply() */
534 bzero((uint8_t *)&iocbq, sizeof (IOCBQ));
535 iocbq.iocb.un.elsreq.remoteID = port->fx.fx_sid;
536 iocbq.iocb.un.elsreq.myID = port->fx.fx_did;
537 iocbq.iocb.ulpContext = port->fx_context;
538
539 status =
540 MODSYM(fct_handle_rcvd_flogi) (port->fct_port, &port->fx);
541
542#ifdef FCT_API_TRACE
543 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
544 "fct_handle_rcvd_flogi %p: x%x", port->fct_port, status);
545#endif /* FCT_API_TRACE */
546
547 if (status == FCT_SUCCESS) {
548 if (port->fx.fx_op == ELS_OP_ACC) {
549 (void) emlxs_els_reply(port, &iocbq,
550 ELS_CMD_ACC, ELS_CMD_FLOGI, 0, 0);
551 } else { /* ELS_OP_LSRJT */
552
553 (void) emlxs_els_reply(port, &iocbq,
554 ELS_CMD_LS_RJT,
555 ELS_CMD_FLOGI, port->fx.fx_rjt_reason,
556 port->fx.fx_rjt_expl);
557 }
558 } else {
559 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
560 "FLOGI: sid=%x. fct_handle_rcvd_flogi failed. "
561 "Rejecting.",
562 port->fx.fx_sid);
563
564 (void) emlxs_els_reply(port, &iocbq, ELS_CMD_LS_RJT,
565 ELS_CMD_FLOGI, LSRJT_UNABLE_TPC,
566 LSEXP_NOTHING_MORE);
567 }
568
569 port->fx.fx_op = 0;
570 }
571
572 return;
573
574} /* emlxs_fct_handle_rcvd_flogi() */
575
576
347extern void
348emlxs_fct_unsol_callback(emlxs_port_t *port, fct_cmd_t *fct_cmd)
349{
350 emlxs_hba_t *hba = HBA;
351 emlxs_buf_t *cmd_sbp;
352
353 cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
354
355 if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) {
356 mutex_enter(&cmd_sbp->mtx);
577extern void
578emlxs_fct_unsol_callback(emlxs_port_t *port, fct_cmd_t *fct_cmd)
579{
580 emlxs_hba_t *hba = HBA;
581 emlxs_buf_t *cmd_sbp;
582
583 cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
584
585 if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) {
586 mutex_enter(&cmd_sbp->mtx);
357 /* mutex_exit(&cmd_sbp->mtx); */
358 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
587 cmd_sbp->pkt_flags |= PACKET_RETURNED;
588 mutex_exit(&cmd_sbp->mtx);
359
589
590 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_CMD_POSTED);
591 mutex_exit(&cmd_sbp->fct_mtx);
592
360#ifdef FCT_API_TRACE
361 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
593#ifdef FCT_API_TRACE
594 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
362 "fct_free:1 %p", cmd_sbp->fct_cmd);
363#endif /* FCT_API_TRACE */
364 MODSYM(fct_free) (cmd_sbp->fct_cmd);
595 "fct_post_rcvd_cmd:4 %p: portid x%x", fct_cmd,
596 fct_cmd->cmd_lportid);
597#endif /* FCT_API_TRACE */
598 MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0);
599 return;
365 }
600 }
601
366 /* Online & Link up */
602 /* Online & Link up */
367 else if (port->fct_flags & FCT_STATE_LINK_UP) {
368 if (cmd_sbp->fct_flags & EMLXS_FCT_FLOGI) {
603 if (port->fct_flags & FCT_STATE_LINK_UP) {
604 mutex_enter(&cmd_sbp->mtx);
605 cmd_sbp->pkt_flags |= PACKET_RETURNED;
606 mutex_exit(&cmd_sbp->mtx);
369
607
370 emlxs_fct_handle_rcvd_flogi(port, fct_cmd);
371 } else {
372 mutex_enter(&cmd_sbp->mtx);
373 cmd_sbp->pkt_flags |= PACKET_RETURNED;
374 mutex_exit(&cmd_sbp->mtx);
608 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_CMD_POSTED);
609 mutex_exit(&cmd_sbp->fct_mtx);
375
376#ifdef FCT_API_TRACE
610
611#ifdef FCT_API_TRACE
377 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
378 "fct_post_rcvd_cmd:1 %p: portid x%x",
379 fct_cmd, fct_cmd->cmd_lportid);
380#endif /* FCT_API_TRACE */
381 MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0);
382 }
612 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
613 "fct_post_rcvd_cmd:1 %p: portid x%x", fct_cmd,
614 fct_cmd->cmd_lportid);
615#endif /* FCT_API_TRACE */
616 MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0);
383 } else { /* Online & Link down */
617 } else { /* Online & Link down */
384 /* Add buffer to queue tail */
618
619 /*
620 * Defer processing of fct_cmd till later (after link up).
621 * Add buffer to queue tail
622 */
385 mutex_enter(&EMLXS_PORT_LOCK);
386
387 if (port->fct_wait_tail) {
388 port->fct_wait_tail->next = cmd_sbp;
389 }
390 port->fct_wait_tail = cmd_sbp;
391
392 if (!port->fct_wait_head) {
393 port->fct_wait_head = cmd_sbp;
394 }
623 mutex_enter(&EMLXS_PORT_LOCK);
624
625 if (port->fct_wait_tail) {
626 port->fct_wait_tail->next = cmd_sbp;
627 }
628 port->fct_wait_tail = cmd_sbp;
629
630 if (!port->fct_wait_head) {
631 port->fct_wait_head = cmd_sbp;
632 }
633
395 mutex_exit(&EMLXS_PORT_LOCK);
634 mutex_exit(&EMLXS_PORT_LOCK);
396 }
397
635
636 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_CMD_WAITQ);
637 mutex_exit(&cmd_sbp->fct_mtx);
638
639 }
398 return;
399
640 return;
641
400} /* emlxs_fct_unsol_callback() */
642} /* emlxs_fct_unsol_callback() */
401
402
403/* This is called at port online and offline */
404static void
405emlxs_fct_unsol_flush(emlxs_port_t *port)
406{
407 emlxs_hba_t *hba = HBA;
408 emlxs_buf_t *cmd_sbp;
409 emlxs_buf_t *next;
410 fct_cmd_t *fct_cmd;
411
412 if (!port->fct_port) {
413 return;
414 }
643
644
645/* This is called at port online and offline */
646static void
647emlxs_fct_unsol_flush(emlxs_port_t *port)
648{
649 emlxs_hba_t *hba = HBA;
650 emlxs_buf_t *cmd_sbp;
651 emlxs_buf_t *next;
652 fct_cmd_t *fct_cmd;
653
654 if (!port->fct_port) {
655 return;
656 }
657
415 /* Return if nothing to do */
416 if (!port->fct_wait_head) {
417 return;
418 }
658 /* Return if nothing to do */
659 if (!port->fct_wait_head) {
660 return;
661 }
662
419 mutex_enter(&EMLXS_PORT_LOCK);
420 cmd_sbp = port->fct_wait_head;
421 port->fct_wait_head = NULL;
422 port->fct_wait_tail = NULL;
423 mutex_exit(&EMLXS_PORT_LOCK);
424
663 mutex_enter(&EMLXS_PORT_LOCK);
664 cmd_sbp = port->fct_wait_head;
665 port->fct_wait_head = NULL;
666 port->fct_wait_tail = NULL;
667 mutex_exit(&EMLXS_PORT_LOCK);
668
669 /* First, see if there is an outstanding FLOGI to process */
670 if (port->fx.fx_op == ELS_OP_FLOGI) {
671 if (port->fct_flags & FCT_STATE_LINK_UP) {
672 /* Process Deferred FLOGI now */
673 emlxs_fct_handle_rcvd_flogi(port);
674 } else {
675 port->fx.fx_op = 0; /* Flush delayed FLOGI */
676 }
677 }
678
679 /*
680 * Next process any outstanding ELS commands. It doesn't
681 * matter if the Link is up or not, always post them to FCT.
682 */
425 while (cmd_sbp) {
426 next = cmd_sbp->next;
427 fct_cmd = cmd_sbp->fct_cmd;
428
683 while (cmd_sbp) {
684 next = cmd_sbp->next;
685 fct_cmd = cmd_sbp->fct_cmd;
686
429 if (port->fct_flags & FCT_STATE_LINK_UP) {
430 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
431 "Completing fct_cmd: %p", fct_cmd);
687 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
688 "Completing fct_cmd: %p", fct_cmd);
432
689
433 if (cmd_sbp->fct_flags & EMLXS_FCT_FLOGI) {
434 emlxs_fct_handle_rcvd_flogi(port, fct_cmd);
435 } else {
436 mutex_enter(&cmd_sbp->mtx);
437 cmd_sbp->pkt_flags |= PACKET_RETURNED;
438 mutex_exit(&cmd_sbp->mtx);
690 mutex_enter(&cmd_sbp->mtx);
691 cmd_sbp->pkt_flags |= PACKET_RETURNED;
692 mutex_exit(&cmd_sbp->mtx);
439
440#ifdef FCT_API_TRACE
693
694#ifdef FCT_API_TRACE
441 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
442 "fct_post_rcvd_cmd:2 %p: portid x%x",
443 fct_cmd, fct_cmd->cmd_lportid);
444#endif /* FCT_API_TRACE */
445 MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0);
446 }
447 } else { /* Drop the cmd */
448 mutex_enter(&cmd_sbp->mtx);
449 /* mutex_exit(&cmd_sbp->mtx); */
450 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
695 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
696 "fct_post_rcvd_cmd:2 %p: portid x%x", fct_cmd,
697 fct_cmd->cmd_lportid);
698#endif /* FCT_API_TRACE */
699 MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0);
451
700
452#ifdef FCT_API_TRACE
453 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
454 "fct_free:2 %p", fct_cmd);
455#endif /* FCT_API_TRACE */
456 MODSYM(fct_free) (fct_cmd);
457 }
458
459 cmd_sbp = next;
460
461 } /* while() */
462
463 return;
464
701 cmd_sbp = next;
702
703 } /* while() */
704
705 return;
706
465} /* emlxs_fct_unsol_flush() */
707} /* emlxs_fct_unsol_flush() */
466
467
468int
469emlxs_is_digit(uint8_t chr)
470{
471 if ((chr >= '0') && (chr <= '9')) {
472 return (1);
473 }
708
709
710int
711emlxs_is_digit(uint8_t chr)
712{
713 if ((chr >= '0') && (chr <= '9')) {
714 return (1);
715 }
716
474 return (0);
475
717 return (0);
718
476} /* emlxs_is_digit */
719} /* emlxs_is_digit */
477
478
479/*
480 * Convert an ASCII decimal numeric string to integer.
481 * Negation character '-' is not handled.
482 */
483uint32_t
484emlxs_str_atoi(uint8_t *string)
485{
486 uint32_t num = 0;
487 int i = 0;
488
489 while (string[i]) {
490 if (!emlxs_is_digit(string[i])) {
491 return (num);
492 }
720
721
722/*
723 * Convert an ASCII decimal numeric string to integer.
724 * Negation character '-' is not handled.
725 */
726uint32_t
727emlxs_str_atoi(uint8_t *string)
728{
729 uint32_t num = 0;
730 int i = 0;
731
732 while (string[i]) {
733 if (!emlxs_is_digit(string[i])) {
734 return (num);
735 }
736
493 num = num * 10 + (string[i++] - '0');
494 }
495
496 return (num);
497
737 num = num * 10 + (string[i++] - '0');
738 }
739
740 return (num);
741
498} /* emlxs_str_atoi() */
742} /* emlxs_str_atoi() */
499
500
501static void
502emlxs_init_fct_bufpool(emlxs_hba_t *hba, char **arrayp, uint32_t cnt)
503{
504 emlxs_port_t *port = &PPORT;
505 uint8_t *datap;
506 int i;
743
744
745static void
746emlxs_init_fct_bufpool(emlxs_hba_t *hba, char **arrayp, uint32_t cnt)
747{
748 emlxs_port_t *port = &PPORT;
749 uint8_t *datap;
750 int i;
751 int bck;
752 int nbufs;
753 int maxbufs;
754 int size;
507
508 bzero((uint8_t *)port->dmem_bucket, sizeof (port->dmem_bucket));
755
756 bzero((uint8_t *)port->dmem_bucket, sizeof (port->dmem_bucket));
757 bck = 0;
509 for (i = 0; i < cnt; i++) {
510 datap = (uint8_t *)arrayp[i];
511 if (datap == 0)
512 break;
513
514 while (*datap == ' ') /* Skip spaces */
515 datap++;
516
758 for (i = 0; i < cnt; i++) {
759 datap = (uint8_t *)arrayp[i];
760 if (datap == 0)
761 break;
762
763 while (*datap == ' ') /* Skip spaces */
764 datap++;
765
517 port->dmem_bucket[i].dmem_buf_size = emlxs_str_atoi(datap);
766 size = emlxs_str_atoi(datap);
518
519 while ((*datap != ':') && (*datap != 0))
520 datap++;
521 if (*datap == ':') /* Skip past delimeter */
522 datap++;
523 while (*datap == ' ') /* Skip spaces */
524 datap++;
525
767
768 while ((*datap != ':') && (*datap != 0))
769 datap++;
770 if (*datap == ':') /* Skip past delimeter */
771 datap++;
772 while (*datap == ' ') /* Skip spaces */
773 datap++;
774
526 port->dmem_bucket[i].dmem_nbufs = emlxs_str_atoi(datap);
775 nbufs = emlxs_str_atoi(datap);
527
528 /* Check for a bad entry */
776
777 /* Check for a bad entry */
529 if (!port->dmem_bucket[i].dmem_buf_size ||
530 !port->dmem_bucket[i].dmem_nbufs) {
778 if (!size || !nbufs) {
531 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
779 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
532 "Bad fct-bufpool entry %d %d",
533 port->dmem_bucket[i].dmem_buf_size,
534 port->dmem_bucket[i].dmem_nbufs);
780 "Bad fct-bufpool entry %d %d", size, nbufs);
535
781
536 port->dmem_bucket[i].dmem_buf_size = 0;
537 port->dmem_bucket[i].dmem_nbufs = 0;
782 port->dmem_bucket[bck].dmem_buf_size = 0;
783 port->dmem_bucket[bck].dmem_nbufs = 0;
784 size = 0;
785 nbufs = 0;
538 }
786 }
539 if (i >= FCT_MAX_BUCKETS)
787
788 while (nbufs) {
789 port->dmem_bucket[bck].dmem_buf_size = size;
790 port->dmem_bucket[bck].dmem_nbufs = nbufs;
791
792 /*
793 * We are not going to try to allocate a chunk
794 * of memory > FCT_DMEM_MAX_BUF_SEGMENT
795 * to accomidate the buffer pool of the
796 * requested size.
797 */
798 maxbufs = (FCT_DMEM_MAX_BUF_SEGMENT / size);
799
800 if (nbufs > maxbufs) {
801 port->dmem_bucket[bck].dmem_nbufs = maxbufs;
802 nbufs -= maxbufs;
803 bck++;
804 if (bck >= FCT_MAX_BUCKETS)
805 break;
806 } else {
807 bck++;
808 nbufs = 0;
809 }
810 }
811
812 if (bck >= FCT_MAX_BUCKETS) {
813 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
814 "fct-bufpool entry %d %d Exceeds available buckets",
815 size, nbufs);
540 break;
816 break;
817 }
541 }
542}
543
544
545static void
546emlxs_fct_cfg_init(emlxs_hba_t *hba)
547{
548 emlxs_port_t *port = &PPORT;
549 char **arrayp;
550 uint32_t cnt;
551 char buf[32];
552 int status;
553
818 }
819}
820
821
822static void
823emlxs_fct_cfg_init(emlxs_hba_t *hba)
824{
825 emlxs_port_t *port = &PPORT;
826 char **arrayp;
827 uint32_t cnt;
828 char buf[32];
829 int status;
830
554 bzero((void *) buf, 32);
831 bzero((void *)buf, 32);
555 cnt = 0;
556 arrayp = NULL;
557
558 (void) sprintf(buf, "emlxs%d-fct-bufpool", ddi_get_instance(hba->dip));
559 status = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, hba->dip,
560 (DDI_PROP_DONTPASS), buf, &arrayp, &cnt);
561
562 if ((status == DDI_PROP_SUCCESS) && cnt && arrayp) {

--- 4 unchanged lines hidden (view full) ---

567
568 if ((status == DDI_PROP_SUCCESS) && cnt && arrayp) {
569 emlxs_init_fct_bufpool(hba, arrayp, cnt);
570 } else {
571 bzero((uint8_t *)port->dmem_bucket,
572 sizeof (port->dmem_bucket));
573 port->dmem_bucket[0].dmem_buf_size = 512;
574 port->dmem_bucket[0].dmem_nbufs = FCT_BUF_COUNT_512;
832 cnt = 0;
833 arrayp = NULL;
834
835 (void) sprintf(buf, "emlxs%d-fct-bufpool", ddi_get_instance(hba->dip));
836 status = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, hba->dip,
837 (DDI_PROP_DONTPASS), buf, &arrayp, &cnt);
838
839 if ((status == DDI_PROP_SUCCESS) && cnt && arrayp) {

--- 4 unchanged lines hidden (view full) ---

844
845 if ((status == DDI_PROP_SUCCESS) && cnt && arrayp) {
846 emlxs_init_fct_bufpool(hba, arrayp, cnt);
847 } else {
848 bzero((uint8_t *)port->dmem_bucket,
849 sizeof (port->dmem_bucket));
850 port->dmem_bucket[0].dmem_buf_size = 512;
851 port->dmem_bucket[0].dmem_nbufs = FCT_BUF_COUNT_512;
575 port->dmem_bucket[1].dmem_buf_size = 8192;
576 port->dmem_bucket[1].dmem_nbufs = FCT_BUF_COUNT_8K;
577 port->dmem_bucket[2].dmem_buf_size = 65536;
578 port->dmem_bucket[2].dmem_nbufs = FCT_BUF_COUNT_64K;
579 port->dmem_bucket[3].dmem_buf_size = (2 * 65536);
580 port->dmem_bucket[3].dmem_nbufs = FCT_BUF_COUNT_128K;
852 port->dmem_bucket[1].dmem_buf_size = (2 * 65536);
853 port->dmem_bucket[1].dmem_nbufs = FCT_BUF_COUNT_128K;
581 }
582 }
583
584 bzero((void *)buf, 32);
585 cnt = 0;
586
854 }
855 }
856
857 bzero((void *)buf, 32);
858 cnt = 0;
859
860 /*
861 * 0 means use HBA throttle for target queue depth,
862 * non-0 value is the actual target queue depth,
863 * default is EMLXS_FCT_DFLT_QDEPTH.
864 */
587 (void) sprintf(buf, "emlxs%d-fct-queue-depth",
588 ddi_get_instance(hba->dip));
589 cnt = ddi_prop_get_int(DDI_DEV_T_ANY, hba->dip,
865 (void) sprintf(buf, "emlxs%d-fct-queue-depth",
866 ddi_get_instance(hba->dip));
867 cnt = ddi_prop_get_int(DDI_DEV_T_ANY, hba->dip,
590 (DDI_PROP_DONTPASS), buf, 0);
868 (DDI_PROP_DONTPASS), buf, EMLXS_FCT_DFLT_QDEPTH);
591
869
592 if ((cnt == DDI_PROP_NOT_FOUND) || (cnt == 0)) {
870 if ((cnt == DDI_PROP_NOT_FOUND) || (cnt == EMLXS_FCT_DFLT_QDEPTH)) {
593 cnt = ddi_prop_get_int(DDI_DEV_T_ANY, hba->dip,
871 cnt = ddi_prop_get_int(DDI_DEV_T_ANY, hba->dip,
594 (DDI_PROP_DONTPASS), "fct-queue-depth", 0);
872 (DDI_PROP_DONTPASS), "fct-queue-depth",
873 EMLXS_FCT_DFLT_QDEPTH);
595
596 if (cnt == DDI_PROP_NOT_FOUND) {
874
875 if (cnt == DDI_PROP_NOT_FOUND) {
597 cnt = 64;
876 cnt = EMLXS_FCT_DFLT_QDEPTH;
598 }
599 }
877 }
878 }
879
600 port->fct_queue_depth = cnt;
880 port->fct_queue_depth = cnt;
881
882#ifdef FCT_IO_TRACE
883 port->iotrace_cnt = 1024;
884 port->iotrace_index = 0;
885 if (cnt)
886 port->iotrace_cnt = (2 * cnt);
887 port->iotrace =
888 kmem_zalloc(port->iotrace_cnt * sizeof (emlxs_iotrace_t),
889 KM_SLEEP);
890 mutex_init(&port->iotrace_mtx, NULL, MUTEX_DRIVER,
891 (void *)hba->intr_arg);
892 emlxs_iotrace = (uint8_t *)port->iotrace;
893 emlxs_iotrace_cnt = port->iotrace_cnt;
894 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
895 "IOTRACE: init:%p cnt:%d", emlxs_iotrace, emlxs_iotrace_cnt);
896 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
897 "FCT_ABORT_SUCCESS:%lx FCT_SUCCESS:%lx", FCT_ABORT_SUCCESS,
898 FCT_SUCCESS);
899#endif /* FCT_IO_TRACE */
601 return;
602
900 return;
901
603} /* emlxs_fct_cfg_init() */
902} /* emlxs_fct_cfg_init() */
604
605
606extern void
607emlxs_fct_init(emlxs_hba_t *hba)
608{
609 emlxs_port_t *port = &PPORT;
610 emlxs_config_t *cfg = &CFG;
611 emlxs_port_t *vport;
612 uint32_t i;
613
614 if (!hba->tgt_mode) {
615 return;
616 }
617#ifdef MODSYM_SUPPORT
618 /* Open COMSTAR */
619 (void) emlxs_fct_modopen();
903
904
905extern void
906emlxs_fct_init(emlxs_hba_t *hba)
907{
908 emlxs_port_t *port = &PPORT;
909 emlxs_config_t *cfg = &CFG;
910 emlxs_port_t *vport;
911 uint32_t i;
912
913 if (!hba->tgt_mode) {
914 return;
915 }
916#ifdef MODSYM_SUPPORT
917 /* Open COMSTAR */
918 (void) emlxs_fct_modopen();
620#endif /* MODSYM_SUPPORT */
919#endif /* MODSYM_SUPPORT */
621
622 /* Check if COMSTAR is present */
623 if (((void *)MODSYM(stmf_alloc) == NULL) ||
920
921 /* Check if COMSTAR is present */
922 if (((void *)MODSYM(stmf_alloc) == NULL) ||
624 ((void *) MODSYM(fct_alloc) == NULL)) {
923 ((void *)MODSYM(fct_alloc) == NULL)) {
625 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
626 "Comstar not present. Target mode disabled.");
627 goto failed;
628 }
924 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
925 "Comstar not present. Target mode disabled.");
926 goto failed;
927 }
928
629 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
630 "Comstar present. Target mode enabled.");
631
632#ifdef NPIV_SUPPORT
633 if (cfg[CFG_NPIV_ENABLE].current) {
634 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg,
635 "enable-npiv: Not supported in target mode. Disabling.");
636
637 /* Temporary patch to disable npiv */
638 cfg[CFG_NPIV_ENABLE].current = 0;
639 }
929 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_debug_msg,
930 "Comstar present. Target mode enabled.");
931
932#ifdef NPIV_SUPPORT
933 if (cfg[CFG_NPIV_ENABLE].current) {
934 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg,
935 "enable-npiv: Not supported in target mode. Disabling.");
936
937 /* Temporary patch to disable npiv */
938 cfg[CFG_NPIV_ENABLE].current = 0;
939 }
640#endif /* NPIV_SUPPORT */
940#endif /* NPIV_SUPPORT */
641
642#ifdef DHCHAP_SUPPORT
643 if (cfg[CFG_AUTH_ENABLE].current) {
644 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg,
645 "enable-auth: Not supported in target mode. Disabling.");
646
647 /* Temporary patch to disable auth */
648 cfg[CFG_AUTH_ENABLE].current = 0;
649 }
941
942#ifdef DHCHAP_SUPPORT
943 if (cfg[CFG_AUTH_ENABLE].current) {
944 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg,
945 "enable-auth: Not supported in target mode. Disabling.");
946
947 /* Temporary patch to disable auth */
948 cfg[CFG_AUTH_ENABLE].current = 0;
949 }
650#endif /* DHCHAP_SUPPORT */
950#endif /* DHCHAP_SUPPORT */
651
652 emlxs_fct_cfg_init(hba);
653 return;
654
655failed:
656
657 hba->tgt_mode = 0;
658 for (i = 0; i < MAX_VPORTS; i++) {
659 vport = &VPORT(i);
660 vport->tgt_mode = 0;
661 vport->fct_flags = 0;
662 }
951
952 emlxs_fct_cfg_init(hba);
953 return;
954
955failed:
956
957 hba->tgt_mode = 0;
958 for (i = 0; i < MAX_VPORTS; i++) {
959 vport = &VPORT(i);
960 vport->tgt_mode = 0;
961 vport->fct_flags = 0;
962 }
663} /* emlxs_fct_init() */
664
963
964 return;
665
965
966} /* emlxs_fct_init() */
967
968
666extern void
667emlxs_fct_attach(emlxs_hba_t *hba)
668{
669 emlxs_port_t *port = &PPORT;
670 uint32_t vpi;
671
672 if (!hba->tgt_mode) {
673 return;
674 }
969extern void
970emlxs_fct_attach(emlxs_hba_t *hba)
971{
972 emlxs_port_t *port = &PPORT;
973 uint32_t vpi;
974
975 if (!hba->tgt_mode) {
976 return;
977 }
978
675 /* Bind the physical port */
676 emlxs_fct_bind_port(port);
677
678 /* Bind virtual ports */
679 if (hba->flag & FC_NPIV_ENABLED) {
680 for (vpi = 1; vpi < hba->vpi_high; vpi++) {
681 port = &VPORT(vpi);
682
683 if (!(port->flag & EMLXS_PORT_ENABLE)) {
684 continue;
685 }
979 /* Bind the physical port */
980 emlxs_fct_bind_port(port);
981
982 /* Bind virtual ports */
983 if (hba->flag & FC_NPIV_ENABLED) {
984 for (vpi = 1; vpi < hba->vpi_high; vpi++) {
985 port = &VPORT(vpi);
986
987 if (!(port->flag & EMLXS_PORT_ENABLE)) {
988 continue;
989 }
990
686 emlxs_fct_bind_port(port);
687 }
688 }
991 emlxs_fct_bind_port(port);
992 }
993 }
994
689 return;
690
995 return;
996
691} /* emlxs_fct_attach() */
997} /* emlxs_fct_attach() */
692
693
694extern void
695emlxs_fct_detach(emlxs_hba_t *hba)
696{
697 uint32_t i;
698 emlxs_port_t *vport;
699
700 if (hba->tgt_mode) {
701 for (i = 0; i < MAX_VPORTS; i++) {
702 vport = &VPORT(i);
703
704 if (!vport->tgt_mode) {
705 continue;
706 }
998
999
1000extern void
1001emlxs_fct_detach(emlxs_hba_t *hba)
1002{
1003 uint32_t i;
1004 emlxs_port_t *vport;
1005
1006 if (hba->tgt_mode) {
1007 for (i = 0; i < MAX_VPORTS; i++) {
1008 vport = &VPORT(i);
1009
1010 if (!vport->tgt_mode) {
1011 continue;
1012 }
1013
707 emlxs_fct_unbind_port(vport);
708 vport->tgt_mode = 0;
709 }
710
711
712 hba->tgt_mode = 0;
713 }
1014 emlxs_fct_unbind_port(vport);
1015 vport->tgt_mode = 0;
1016 }
1017
1018
1019 hba->tgt_mode = 0;
1020 }
1021#ifdef FCT_IO_TRACE
1022 {
1023 emlxs_port_t *port = &PPORT;
1024
1025 mutex_destroy(&port->iotrace_mtx);
1026 if (port->iotrace)
1027 kmem_free(port->iotrace,
1028 (port->iotrace_cnt * sizeof (emlxs_iotrace_t)));
1029 port->iotrace = NULL;
1030 }
1031#endif /* FCT_IO_TRACE */
1032
714 return;
715
1033 return;
1034
716} /* emlxs_fct_detach() */
1035} /* emlxs_fct_detach() */
717
718
719extern void
720emlxs_fct_unbind_port(emlxs_port_t *port)
721{
722 emlxs_hba_t *hba = HBA;
723 char node_name[32];
724
725 if (!port->tgt_mode) {
726 return;
727 }
1036
1037
1038extern void
1039emlxs_fct_unbind_port(emlxs_port_t *port)
1040{
1041 emlxs_hba_t *hba = HBA;
1042 char node_name[32];
1043
1044 if (!port->tgt_mode) {
1045 return;
1046 }
1047
728 mutex_enter(&EMLXS_PORT_LOCK);
729 if (!(port->flag & EMLXS_PORT_BOUND)) {
730 mutex_exit(&EMLXS_PORT_LOCK);
731 return;
732 }
1048 mutex_enter(&EMLXS_PORT_LOCK);
1049 if (!(port->flag & EMLXS_PORT_BOUND)) {
1050 mutex_exit(&EMLXS_PORT_LOCK);
1051 return;
1052 }
1053
733 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
734 "emlxs_fct_unbind_port: port=%d", port->vpi);
735
736 /* Destroy & flush all port nodes, if they exist */
737 if (port->node_count) {
738 (void) emlxs_mb_unreg_rpi(port, 0xffff, 0, 0, 0);
739 }
1054 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
1055 "emlxs_fct_unbind_port: port=%d", port->vpi);
1056
1057 /* Destroy & flush all port nodes, if they exist */
1058 if (port->node_count) {
1059 (void) emlxs_mb_unreg_rpi(port, 0xffff, 0, 0, 0);
1060 }
1061
740 port->flag &= ~EMLXS_PORT_BOUND;
741 hba->num_of_ports--;
742 mutex_exit(&EMLXS_PORT_LOCK);
743
744 if (port->fct_port) {
745 emlxs_fct_link_down(port);
746 emlxs_fct_unsol_flush(port);
747
748#ifdef FCT_API_TRACE
749 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
750 "fct_deregister_local_port %p", port->fct_port);
1062 port->flag &= ~EMLXS_PORT_BOUND;
1063 hba->num_of_ports--;
1064 mutex_exit(&EMLXS_PORT_LOCK);
1065
1066 if (port->fct_port) {
1067 emlxs_fct_link_down(port);
1068 emlxs_fct_unsol_flush(port);
1069
1070#ifdef FCT_API_TRACE
1071 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1072 "fct_deregister_local_port %p", port->fct_port);
751#endif /* FCT_API_TRACE */
1073#endif /* FCT_API_TRACE */
752 MODSYM(fct_deregister_local_port) (port->fct_port);
753
754 if (port->fct_port->port_fds) {
755#ifdef FCT_API_TRACE
756 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
757 "fct_free:3 %p", port->fct_port->port_fds);
1074 MODSYM(fct_deregister_local_port) (port->fct_port);
1075
1076 if (port->fct_port->port_fds) {
1077#ifdef FCT_API_TRACE
1078 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1079 "fct_free:3 %p", port->fct_port->port_fds);
758#endif /* FCT_API_TRACE */
1080#endif /* FCT_API_TRACE */
759 MODSYM(fct_free) (port->fct_port->port_fds);
760 port->fct_port->port_fds = NULL;
761 }
762#ifdef FCT_API_TRACE
763 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
764 "fct_free:4 %p", port->fct_port);
1081 MODSYM(fct_free) (port->fct_port->port_fds);
1082 port->fct_port->port_fds = NULL;
1083 }
1084#ifdef FCT_API_TRACE
1085 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1086 "fct_free:4 %p", port->fct_port);
765#endif /* FCT_API_TRACE */
1087#endif /* FCT_API_TRACE */
766 MODSYM(fct_free) (port->fct_port);
767 port->fct_port = NULL;
768 port->fct_flags = 0;
769 }
1088 MODSYM(fct_free) (port->fct_port);
1089 port->fct_port = NULL;
1090 port->fct_flags = 0;
1091 }
1092
770 if (port->port_provider) {
771#ifdef FCT_API_TRACE
772 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1093 if (port->port_provider) {
1094#ifdef FCT_API_TRACE
1095 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
773 "stmf_deregister_port_provider:1 %p", port->port_provider);
774#endif /* FCT_API_TRACE */
1096 "stmf_deregister_port_provider:1 %p",
1097 port->port_provider);
1098#endif /* FCT_API_TRACE */
775 MODSYM(stmf_deregister_port_provider) (port->port_provider);
776
777#ifdef FCT_API_TRACE
778 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
779 "stmf_free:1 %p", port->port_provider);
1099 MODSYM(stmf_deregister_port_provider) (port->port_provider);
1100
1101#ifdef FCT_API_TRACE
1102 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1103 "stmf_free:1 %p", port->port_provider);
780#endif /* FCT_API_TRACE */
1104#endif /* FCT_API_TRACE */
781 MODSYM(stmf_free) (port->port_provider);
782 port->port_provider = NULL;
783 }
1105 MODSYM(stmf_free) (port->port_provider);
1106 port->port_provider = NULL;
1107 }
1108
784 if (port->dmem_bucket) {
785 emlxs_fct_dmem_fini(port);
786 }
1109 if (port->dmem_bucket) {
1110 emlxs_fct_dmem_fini(port);
1111 }
1112
787 (void) sprintf(node_name, "%d,%d:SFCT", hba->ddiinst, port->vpi);
788 (void) ddi_remove_minor_node(hba->dip, node_name);
789
790 return;
791
1113 (void) sprintf(node_name, "%d,%d:SFCT", hba->ddiinst, port->vpi);
1114 (void) ddi_remove_minor_node(hba->dip, node_name);
1115
1116 return;
1117
792} /* emlxs_fct_unbind_port() */
1118} /* emlxs_fct_unbind_port() */
793
794
795extern void
796emlxs_fct_bind_port(emlxs_port_t *port)
797{
798 emlxs_hba_t *hba = HBA;
799 fct_local_port_t *fct_port;
800 uint32_t flag = 0;
801 emlxs_config_t *cfg = &CFG;
802 fct_dbuf_store_t *fds;
803 char node_name[32];
804
805 mutex_enter(&EMLXS_PORT_LOCK);
806
807 if (!hba->tgt_mode || !port->tgt_mode) {
808 mutex_exit(&EMLXS_PORT_LOCK);
809 return;
810 }
1119
1120
1121extern void
1122emlxs_fct_bind_port(emlxs_port_t *port)
1123{
1124 emlxs_hba_t *hba = HBA;
1125 fct_local_port_t *fct_port;
1126 uint32_t flag = 0;
1127 emlxs_config_t *cfg = &CFG;
1128 fct_dbuf_store_t *fds;
1129 char node_name[32];
1130
1131 mutex_enter(&EMLXS_PORT_LOCK);
1132
1133 if (!hba->tgt_mode || !port->tgt_mode) {
1134 mutex_exit(&EMLXS_PORT_LOCK);
1135 return;
1136 }
1137
811 if (port->flag & EMLXS_PORT_BOUND) {
812 mutex_exit(&EMLXS_PORT_LOCK);
813 return;
814 }
1138 if (port->flag & EMLXS_PORT_BOUND) {
1139 mutex_exit(&EMLXS_PORT_LOCK);
1140 return;
1141 }
1142
815 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
816 "emlxs_fct_bind_port: port=%d", port->vpi);
817
818 /* Perform generic port initialization */
819 emlxs_port_init(port);
820
821 if (port->vpi == 0) {
822 (void) sprintf(port->cfd_name, "%s%d", DRIVER_NAME,

--- 5 unchanged lines hidden (view full) ---

828
829 if (emlxs_fct_dmem_init(port) != FCT_SUCCESS) {
830 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
831 "emlxs_fct_bind_port: Unable to allocate fct memory.");
832 goto failed;
833 }
834 flag |= 0x00000001;
835
1143 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
1144 "emlxs_fct_bind_port: port=%d", port->vpi);
1145
1146 /* Perform generic port initialization */
1147 emlxs_port_init(port);
1148
1149 if (port->vpi == 0) {
1150 (void) sprintf(port->cfd_name, "%s%d", DRIVER_NAME,

--- 5 unchanged lines hidden (view full) ---

1156
1157 if (emlxs_fct_dmem_init(port) != FCT_SUCCESS) {
1158 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
1159 "emlxs_fct_bind_port: Unable to allocate fct memory.");
1160 goto failed;
1161 }
1162 flag |= 0x00000001;
1163
836 port->port_provider = (stmf_port_provider_t *)
1164 port->port_provider =
1165 (stmf_port_provider_t *)
837 MODSYM(stmf_alloc) (STMF_STRUCT_PORT_PROVIDER, 0, 0);
838#ifdef FCT_API_TRACE
839 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
840 "stmf_alloc port_provider %p", port->port_provider);
1166 MODSYM(stmf_alloc) (STMF_STRUCT_PORT_PROVIDER, 0, 0);
1167#ifdef FCT_API_TRACE
1168 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1169 "stmf_alloc port_provider %p", port->port_provider);
841#endif /* FCT_API_TRACE */
1170#endif /* FCT_API_TRACE */
842
843 if (port->port_provider == NULL) {
844 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
1171
1172 if (port->port_provider == NULL) {
1173 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
845 "emlxs_fct_bind_port: Unable to allocate "
846 "fct port provider.");
1174 "emlxs_fct_bind_port: Unable to allocate port provider.");
847 goto failed;
848 }
849 flag |= 0x00000002;
850
851 port->port_provider->pp_portif_rev = PORTIF_REV_1;
852 port->port_provider->pp_name = port->cfd_name;
853 port->port_provider->pp_provider_private = port;
854
855#ifdef FCT_API_TRACE
856 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
857 "stmf_register_port_provider %p", port->port_provider);
1175 goto failed;
1176 }
1177 flag |= 0x00000002;
1178
1179 port->port_provider->pp_portif_rev = PORTIF_REV_1;
1180 port->port_provider->pp_name = port->cfd_name;
1181 port->port_provider->pp_provider_private = port;
1182
1183#ifdef FCT_API_TRACE
1184 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1185 "stmf_register_port_provider %p", port->port_provider);
858#endif /* FCT_API_TRACE */
1186#endif /* FCT_API_TRACE */
859 /* register port provider with framework */
1187 /* register port provider with framework */
860 if (MODSYM(stmf_register_port_provider) (port->port_provider)
861 != STMF_SUCCESS) {
1188 if (MODSYM(stmf_register_port_provider) (port->port_provider) !=
1189 STMF_SUCCESS) {
862 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
1190 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
863 "emlxs_fct_bind_port: Unable to register "
864 "fct port provider.");
1191 "emlxs_fct_bind_port: Unable to register port provider.");
865 goto failed;
866 }
867 flag |= 0x00000004;
868
1192 goto failed;
1193 }
1194 flag |= 0x00000004;
1195
869 port->fct_port = (fct_local_port_t *)
870 MODSYM(fct_alloc) (FCT_STRUCT_LOCAL_PORT, 0, 0);
1196 port->fct_port =
1197 (fct_local_port_t *)MODSYM(fct_alloc) (FCT_STRUCT_LOCAL_PORT, 0,
1198 0);
871#ifdef FCT_API_TRACE
872 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
873 "fct_alloc fct_port %p", port->fct_port);
1199#ifdef FCT_API_TRACE
1200 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1201 "fct_alloc fct_port %p", port->fct_port);
874#endif /* FCT_API_TRACE */
1202#endif /* FCT_API_TRACE */
875
876 if (port->fct_port == NULL) {
877 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
878 "emlxs_fct_bind_port: Unable to allocate fct port.");
879 goto failed;
880 }
881 flag |= 0x00000008;
882
1203
1204 if (port->fct_port == NULL) {
1205 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
1206 "emlxs_fct_bind_port: Unable to allocate fct port.");
1207 goto failed;
1208 }
1209 flag |= 0x00000008;
1210
883 port->fct_port->port_fds = (fct_dbuf_store_t *)
884 MODSYM(fct_alloc) (FCT_STRUCT_DBUF_STORE, 0, 0);
1211 port->fct_port->port_fds =
1212 (fct_dbuf_store_t *)MODSYM(fct_alloc) (FCT_STRUCT_DBUF_STORE, 0,
1213 0);
885#ifdef FCT_API_TRACE
886 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
887 "fct_alloc port_fds %p", port->fct_port->port_fds);
1214#ifdef FCT_API_TRACE
1215 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1216 "fct_alloc port_fds %p", port->fct_port->port_fds);
888#endif /* FCT_API_TRACE */
1217#endif /* FCT_API_TRACE */
889
890 if (port->fct_port->port_fds == NULL) {
891 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
892 "emlxs_fct_bind_port: Unable to allocate dbuf store.");
893 goto failed;
894 }
895 flag |= 0x00000010;
896
897 (void) sprintf(node_name, "%d,%d:SFCT", hba->ddiinst, port->vpi);
1218
1219 if (port->fct_port->port_fds == NULL) {
1220 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
1221 "emlxs_fct_bind_port: Unable to allocate dbuf store.");
1222 goto failed;
1223 }
1224 flag |= 0x00000010;
1225
1226 (void) sprintf(node_name, "%d,%d:SFCT", hba->ddiinst, port->vpi);
898 if (ddi_create_minor_node(hba->dip, node_name, S_IFCHR,
899 hba->ddiinst, NULL, 0) == DDI_FAILURE) {
1227 if (ddi_create_minor_node(hba->dip, node_name, S_IFCHR, hba->ddiinst,
1228 NULL, 0) == DDI_FAILURE) {
900 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
901 "Unable to create SFCT device node.");
902 goto failed;
903 }
904 flag |= 0x00000020;
905
906 /* Intialize */
907 fct_port = port->fct_port;

--- 5 unchanged lines hidden (view full) ---

913
914 fct_port->port_sym_node_name = port->snn;
915 fct_port->port_sym_port_name = port->spn;
916 fct_port->port_hard_address = cfg[CFG_ASSIGN_ALPA].current;
917 fct_port->port_default_alias = port->cfd_name;
918 fct_port->port_pp = port->port_provider;
919 fct_port->port_max_logins = hba->max_nodes;
920
1229 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
1230 "Unable to create SFCT device node.");
1231 goto failed;
1232 }
1233 flag |= 0x00000020;
1234
1235 /* Intialize */
1236 fct_port = port->fct_port;

--- 5 unchanged lines hidden (view full) ---

1242
1243 fct_port->port_sym_node_name = port->snn;
1244 fct_port->port_sym_port_name = port->spn;
1245 fct_port->port_hard_address = cfg[CFG_ASSIGN_ALPA].current;
1246 fct_port->port_default_alias = port->cfd_name;
1247 fct_port->port_pp = port->port_provider;
1248 fct_port->port_max_logins = hba->max_nodes;
1249
921 if ((port->fct_queue_depth) && (port->fct_queue_depth
922 < hba->io_throttle)) {
1250 if ((port->fct_queue_depth) &&
1251 (port->fct_queue_depth < hba->io_throttle)) {
923 fct_port->port_max_xchges = port->fct_queue_depth;
924 } else {
925 fct_port->port_max_xchges = hba->io_throttle;
926 }
927
928 fct_port->port_fca_fcp_cmd_size = sizeof (emlxs_buf_t);
929 fct_port->port_fca_rp_private_size = sizeof (uintptr_t);
930 fct_port->port_fca_sol_els_private_size = sizeof (emlxs_buf_t);

--- 13 unchanged lines hidden (view full) ---

944 fds = port->fct_port->port_fds;
945 fds->fds_fca_private = port;
946 fds->fds_alloc_data_buf = emlxs_fct_dbuf_alloc;
947 fds->fds_free_data_buf = emlxs_fct_dbuf_free;
948
949#ifdef FCT_API_TRACE
950 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
951 "fct_register_local_port %p", fct_port);
1252 fct_port->port_max_xchges = port->fct_queue_depth;
1253 } else {
1254 fct_port->port_max_xchges = hba->io_throttle;
1255 }
1256
1257 fct_port->port_fca_fcp_cmd_size = sizeof (emlxs_buf_t);
1258 fct_port->port_fca_rp_private_size = sizeof (uintptr_t);
1259 fct_port->port_fca_sol_els_private_size = sizeof (emlxs_buf_t);

--- 13 unchanged lines hidden (view full) ---

1273 fds = port->fct_port->port_fds;
1274 fds->fds_fca_private = port;
1275 fds->fds_alloc_data_buf = emlxs_fct_dbuf_alloc;
1276 fds->fds_free_data_buf = emlxs_fct_dbuf_free;
1277
1278#ifdef FCT_API_TRACE
1279 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1280 "fct_register_local_port %p", fct_port);
952#endif /* FCT_API_TRACE */
1281#endif /* FCT_API_TRACE */
953 /* register this local port with the fct module */
954 if (MODSYM(fct_register_local_port) (fct_port) != FCT_SUCCESS) {
955 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
956 "emlxs_fct_bind_port: Unable to register fct port.");
957 goto failed;
958 }
1282 /* register this local port with the fct module */
1283 if (MODSYM(fct_register_local_port) (fct_port) != FCT_SUCCESS) {
1284 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
1285 "emlxs_fct_bind_port: Unable to register fct port.");
1286 goto failed;
1287 }
1288
959 /* Set the bound flag */
960 port->flag |= EMLXS_PORT_BOUND;
961 hba->num_of_ports++;
962
963 mutex_exit(&EMLXS_PORT_LOCK);
964
965 return;
966
967failed:
968
969 if (flag & 0x20) {
970 (void) ddi_remove_minor_node(hba->dip, node_name);
971 }
1289 /* Set the bound flag */
1290 port->flag |= EMLXS_PORT_BOUND;
1291 hba->num_of_ports++;
1292
1293 mutex_exit(&EMLXS_PORT_LOCK);
1294
1295 return;
1296
1297failed:
1298
1299 if (flag & 0x20) {
1300 (void) ddi_remove_minor_node(hba->dip, node_name);
1301 }
1302
972 if (flag & 0x10) {
973#ifdef FCT_API_TRACE
974 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
975 "fct_free:5 %p", port->fct_port->port_fds);
1303 if (flag & 0x10) {
1304#ifdef FCT_API_TRACE
1305 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1306 "fct_free:5 %p", port->fct_port->port_fds);
976#endif /* FCT_API_TRACE */
1307#endif /* FCT_API_TRACE */
977 MODSYM(fct_free) (port->fct_port->port_fds);
978 port->fct_port->port_fds = NULL;
979 }
1308 MODSYM(fct_free) (port->fct_port->port_fds);
1309 port->fct_port->port_fds = NULL;
1310 }
1311
980 if (flag & 0x8) {
981#ifdef FCT_API_TRACE
982 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
983 "fct_free:6 %p", port->fct_port);
1312 if (flag & 0x8) {
1313#ifdef FCT_API_TRACE
1314 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1315 "fct_free:6 %p", port->fct_port);
984#endif /* FCT_API_TRACE */
1316#endif /* FCT_API_TRACE */
985 MODSYM(fct_free) (port->fct_port);
986 port->fct_port = NULL;
987 port->fct_flags = 0;
988 }
1317 MODSYM(fct_free) (port->fct_port);
1318 port->fct_port = NULL;
1319 port->fct_flags = 0;
1320 }
1321
989 if (flag & 0x4) {
990#ifdef FCT_API_TRACE
991 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1322 if (flag & 0x4) {
1323#ifdef FCT_API_TRACE
1324 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
992 "stmf_deregister_port_provider:2 %p", port->port_provider);
993#endif /* FCT_API_TRACE */
1325 "stmf_deregister_port_provider:2 %p",
1326 port->port_provider);
1327#endif /* FCT_API_TRACE */
994 MODSYM(stmf_deregister_port_provider) (port->port_provider);
995 }
1328 MODSYM(stmf_deregister_port_provider) (port->port_provider);
1329 }
1330
996 if (flag & 0x2) {
997#ifdef FCT_API_TRACE
998 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
999 "stmf_free:2 %p", port->port_provider);
1331 if (flag & 0x2) {
1332#ifdef FCT_API_TRACE
1333 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1334 "stmf_free:2 %p", port->port_provider);
1000#endif /* FCT_API_TRACE */
1335#endif /* FCT_API_TRACE */
1001 MODSYM(stmf_free) (port->port_provider);
1002 port->port_provider = NULL;
1003 }
1336 MODSYM(stmf_free) (port->port_provider);
1337 port->port_provider = NULL;
1338 }
1339
1004 if (flag & 0x1) {
1005 emlxs_fct_dmem_fini(port);
1006 }
1340 if (flag & 0x1) {
1341 emlxs_fct_dmem_fini(port);
1342 }
1343
1007 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
1008 "Target mode disabled.");
1009
1010 mutex_exit(&EMLXS_PORT_LOCK);
1011
1012 return;
1013
1344 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
1345 "Target mode disabled.");
1346
1347 mutex_exit(&EMLXS_PORT_LOCK);
1348
1349 return;
1350
1014} /* emlxs_fct_bind_port() */
1351} /* emlxs_fct_bind_port() */
1015
1016
1017static void
1018emlxs_populate_hba_details(fct_local_port_t *fct_port,
1019 fct_port_attrs_t *port_attrs)
1020{
1021 emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
1022 emlxs_hba_t *hba = HBA;

--- 13 unchanged lines hidden (view full) ---

1036 (void) strcpy(port_attrs->driver_name, DRIVER_NAME);
1037 port_attrs->vendor_specific_id =
1038 ((hba->model_info.device_id << 16) | PCI_VENDOR_ID_EMULEX);
1039 port_attrs->supported_cos = SWAP_DATA32(FC_NS_CLASS3);
1040
1041 port_attrs->max_frame_size = FF_FRAME_SIZE;
1042
1043 if (vpd->link_speed & LMT_10GB_CAPABLE) {
1352
1353
1354static void
1355emlxs_populate_hba_details(fct_local_port_t *fct_port,
1356 fct_port_attrs_t *port_attrs)
1357{
1358 emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
1359 emlxs_hba_t *hba = HBA;

--- 13 unchanged lines hidden (view full) ---

1373 (void) strcpy(port_attrs->driver_name, DRIVER_NAME);
1374 port_attrs->vendor_specific_id =
1375 ((hba->model_info.device_id << 16) | PCI_VENDOR_ID_EMULEX);
1376 port_attrs->supported_cos = SWAP_DATA32(FC_NS_CLASS3);
1377
1378 port_attrs->max_frame_size = FF_FRAME_SIZE;
1379
1380 if (vpd->link_speed & LMT_10GB_CAPABLE) {
1044 port_attrs->supported_speed |= FC_HBA_PORTSPEED_10GBIT;
1381 port_attrs->supported_speed |= PORT_SPEED_10G;
1045 }
1046 if (vpd->link_speed & LMT_8GB_CAPABLE) {
1382 }
1383 if (vpd->link_speed & LMT_8GB_CAPABLE) {
1047 port_attrs->supported_speed |= FC_HBA_PORTSPEED_8GBIT;
1384 port_attrs->supported_speed |= PORT_SPEED_8G;
1048 }
1049 if (vpd->link_speed & LMT_4GB_CAPABLE) {
1385 }
1386 if (vpd->link_speed & LMT_4GB_CAPABLE) {
1050 port_attrs->supported_speed |= FC_HBA_PORTSPEED_4GBIT;
1387 port_attrs->supported_speed |= PORT_SPEED_4G;
1051 }
1052 if (vpd->link_speed & LMT_2GB_CAPABLE) {
1388 }
1389 if (vpd->link_speed & LMT_2GB_CAPABLE) {
1053 port_attrs->supported_speed |= FC_HBA_PORTSPEED_2GBIT;
1390 port_attrs->supported_speed |= PORT_SPEED_2G;
1054 }
1055 if (vpd->link_speed & LMT_1GB_CAPABLE) {
1391 }
1392 if (vpd->link_speed & LMT_1GB_CAPABLE) {
1056 port_attrs->supported_speed |= FC_HBA_PORTSPEED_1GBIT;
1393 port_attrs->supported_speed |= PORT_SPEED_1G;
1057 }
1394 }
1395
1058 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1059 "Port attr: manufacturer = %s", port_attrs->manufacturer);
1060 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1061 "Port attr: serial_num = %s", port_attrs->serial_number);
1062 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1063 "Port attr: model = %s", port_attrs->model);
1064 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1065 "Port attr: model_description = %s",
1066 port_attrs->model_description);
1067 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1396 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1397 "Port attr: manufacturer = %s", port_attrs->manufacturer);
1398 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1399 "Port attr: serial_num = %s", port_attrs->serial_number);
1400 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1401 "Port attr: model = %s", port_attrs->model);
1402 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1403 "Port attr: model_description = %s",
1404 port_attrs->model_description);
1405 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1068 "Port attr: hardware_version = %s", port_attrs->hardware_version);
1406 "Port attr: hardware_version = %s",
1407 port_attrs->hardware_version);
1069 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1070 "Port attr: driver_version = %s", port_attrs->driver_version);
1071 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1072 "Port attr: option_rom_version = %s",
1073 port_attrs->option_rom_version);
1074 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1408 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1409 "Port attr: driver_version = %s", port_attrs->driver_version);
1410 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1411 "Port attr: option_rom_version = %s",
1412 port_attrs->option_rom_version);
1413 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1075 "Port attr: firmware_version = %s", port_attrs->firmware_version);
1414 "Port attr: firmware_version = %s",
1415 port_attrs->firmware_version);
1076 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1077 "Port attr: driver_name = %s", port_attrs->driver_name);
1078 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1079 "Port attr: vendor_specific_id = 0x%x",
1080 port_attrs->vendor_specific_id);
1081 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1416 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1417 "Port attr: driver_name = %s", port_attrs->driver_name);
1418 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1419 "Port attr: vendor_specific_id = 0x%x",
1420 port_attrs->vendor_specific_id);
1421 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1082 "Port attr: supported_cos = 0x%x", port_attrs->supported_cos);
1422 "Port attr: supported_cos = 0x%x",
1423 port_attrs->supported_cos);
1083 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1084 "Port attr: supported_speed = 0x%x",
1085 port_attrs->supported_speed);
1086 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1424 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1425 "Port attr: supported_speed = 0x%x",
1426 port_attrs->supported_speed);
1427 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1087 "Port attr: max_frame_size = 0x%x", port_attrs->max_frame_size);
1428 "Port attr: max_frame_size = 0x%x",
1429 port_attrs->max_frame_size);
1088
1089 return;
1090
1430
1431 return;
1432
1091} /* emlxs_populate_hba_details() */
1433} /* emlxs_populate_hba_details() */
1092
1093
1094/* ARGSUSED */
1095static void
1096emlxs_fct_ctl(fct_local_port_t *fct_port, int cmd, void *arg)
1097{
1098 emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
1099 emlxs_hba_t *hba = HBA;

--- 6 unchanged lines hidden (view full) ---

1106 case FCT_CMD_PORT_ONLINE:
1107 /* If the HBA is offline, we cannot bring the tgtport online */
1108 if (hba->flag & (FC_OFFLINE_MODE | FC_OFFLINING_MODE)) {
1109 st.st_completion_status = FCT_FAILURE;
1110 MODSYM(fct_ctl) (fct_port->port_lport,
1111 FCT_CMD_PORT_ONLINE_COMPLETE, &st);
1112 break;
1113 }
1434
1435
1436/* ARGSUSED */
1437static void
1438emlxs_fct_ctl(fct_local_port_t *fct_port, int cmd, void *arg)
1439{
1440 emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
1441 emlxs_hba_t *hba = HBA;

--- 6 unchanged lines hidden (view full) ---

1448 case FCT_CMD_PORT_ONLINE:
1449 /* If the HBA is offline, we cannot bring the tgtport online */
1450 if (hba->flag & (FC_OFFLINE_MODE | FC_OFFLINING_MODE)) {
1451 st.st_completion_status = FCT_FAILURE;
1452 MODSYM(fct_ctl) (fct_port->port_lport,
1453 FCT_CMD_PORT_ONLINE_COMPLETE, &st);
1454 break;
1455 }
1456
1114 if (port->fct_flags & FCT_STATE_PORT_ONLINE) {
1115 st.st_completion_status = STMF_ALREADY;
1116 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1117 "STATE: ONLINE chk");
1118 } else {
1119 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1120 "STATE: OFFLINE --> ONLINE");
1121
1122 port->fct_flags |= FCT_STATE_NOT_ACKED;
1123 port->fct_flags |= FCT_STATE_PORT_ONLINE;
1124
1125 if (hba->state <= FC_LINK_DOWN) {
1126 /* Try to bring the link up */
1127 (void) emlxs_reset_link(hba, 1);
1128 }
1457 if (port->fct_flags & FCT_STATE_PORT_ONLINE) {
1458 st.st_completion_status = STMF_ALREADY;
1459 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1460 "STATE: ONLINE chk");
1461 } else {
1462 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1463 "STATE: OFFLINE --> ONLINE");
1464
1465 port->fct_flags |= FCT_STATE_NOT_ACKED;
1466 port->fct_flags |= FCT_STATE_PORT_ONLINE;
1467
1468 if (hba->state <= FC_LINK_DOWN) {
1469 /* Try to bring the link up */
1470 (void) emlxs_reset_link(hba, 1);
1471 }
1472
1129 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1130 "STATE: ONLINE");
1131 }
1132
1133 MODSYM(fct_ctl) (fct_port->port_lport,
1134 FCT_CMD_PORT_ONLINE_COMPLETE, &st);
1135 break;
1136

--- 38 unchanged lines hidden (view full) ---

1175 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1176 "STATE: ONLINE ack");
1177 break;
1178
1179 }
1180
1181 return;
1182
1473 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1474 "STATE: ONLINE");
1475 }
1476
1477 MODSYM(fct_ctl) (fct_port->port_lport,
1478 FCT_CMD_PORT_ONLINE_COMPLETE, &st);
1479 break;
1480

--- 38 unchanged lines hidden (view full) ---

1519 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1520 "STATE: ONLINE ack");
1521 break;
1522
1523 }
1524
1525 return;
1526
1183} /* emlxs_fct_ctl() */
1527} /* emlxs_fct_ctl() */
1184
1528
1529
1185extern int
1186emlxs_fct_port_shutdown(emlxs_port_t *port)
1187{
1188 fct_local_port_t *fct_port;
1189 int i;
1190
1191 fct_port = port->fct_port;
1192 if (!fct_port) {
1193 return (0);
1194 }
1530extern int
1531emlxs_fct_port_shutdown(emlxs_port_t *port)
1532{
1533 fct_local_port_t *fct_port;
1534 int i;
1535
1536 fct_port = port->fct_port;
1537 if (!fct_port) {
1538 return (0);
1539 }
1195 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1196 "fct_port_shutdown");
1540 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg, "fct_port_shutdown");
1197 MODSYM(fct_port_shutdown) (fct_port, STMF_RFLAG_STAY_OFFLINED,
1198 "emlxs shutdown");
1199
1200 i = 0;
1201 while (port->fct_flags & FCT_STATE_NOT_ACKED) {
1202 i++;
1203 if (i > 300) { /* 30 seconds */
1204 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,

--- 29 unchanged lines hidden (view full) ---

1234 "fct_port_initialize failed to ACK");
1235 break;
1236 }
1237 delay(drv_usectohz(100000)); /* 100 msec */
1238 }
1239 return (1);
1240}
1241
1541 MODSYM(fct_port_shutdown) (fct_port, STMF_RFLAG_STAY_OFFLINED,
1542 "emlxs shutdown");
1543
1544 i = 0;
1545 while (port->fct_flags & FCT_STATE_NOT_ACKED) {
1546 i++;
1547 if (i > 300) { /* 30 seconds */
1548 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,

--- 29 unchanged lines hidden (view full) ---

1578 "fct_port_initialize failed to ACK");
1579 break;
1580 }
1581 delay(drv_usectohz(100000)); /* 100 msec */
1582 }
1583 return (1);
1584}
1585
1586
1242static fct_status_t
1243emlxs_fct_send_cmd(fct_cmd_t *fct_cmd)
1244{
1245 emlxs_port_t *port;
1246
1247 port = (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
1248
1249#ifdef FCT_API_TRACE
1250 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1251 "emlxs_fct_send_cmd %p: x%x", fct_cmd, fct_cmd->cmd_type);
1587static fct_status_t
1588emlxs_fct_send_cmd(fct_cmd_t *fct_cmd)
1589{
1590 emlxs_port_t *port;
1591
1592 port = (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
1593
1594#ifdef FCT_API_TRACE
1595 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1596 "emlxs_fct_send_cmd %p: x%x", fct_cmd, fct_cmd->cmd_type);
1252#endif /* FCT_API_TRACE */
1597#endif /* FCT_API_TRACE */
1253
1254 switch (fct_cmd->cmd_type) {
1255 case FCT_CMD_SOL_ELS:
1256
1257 return (emlxs_fct_send_els_cmd(fct_cmd));
1258
1259 case FCT_CMD_SOL_CT:
1260
1261 return (emlxs_fct_send_ct_cmd(fct_cmd));
1262
1263 default:
1264
1265 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1266 "emlxs_fct_send_cmd: Invalid cmd type found. type=%x",
1267 fct_cmd->cmd_type);
1268
1269 return (FCT_FAILURE);
1270 }
1271
1598
1599 switch (fct_cmd->cmd_type) {
1600 case FCT_CMD_SOL_ELS:
1601
1602 return (emlxs_fct_send_els_cmd(fct_cmd));
1603
1604 case FCT_CMD_SOL_CT:
1605
1606 return (emlxs_fct_send_ct_cmd(fct_cmd));
1607
1608 default:
1609
1610 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1611 "emlxs_fct_send_cmd: Invalid cmd type found. type=%x",
1612 fct_cmd->cmd_type);
1613
1614 return (FCT_FAILURE);
1615 }
1616
1272} /* emlxs_fct_send_cmd() */
1617} /* emlxs_fct_send_cmd() */
1273
1274
1618
1619
1275
1276static fct_status_t
1277emlxs_fct_send_cmd_rsp(fct_cmd_t *fct_cmd, uint32_t ioflags)
1278{
1279 emlxs_port_t *port;
1620static fct_status_t
1621emlxs_fct_send_cmd_rsp(fct_cmd_t *fct_cmd, uint32_t ioflags)
1622{
1623 emlxs_port_t *port;
1624 emlxs_buf_t *cmd_sbp;
1625 fct_status_t rval;
1280
1281 port = (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
1626
1627 port = (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
1628 cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
1282
1283#ifdef FCT_API_TRACE
1284 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1285 "emlxs_fct_send_cmd_rsp %p: x%x", fct_cmd, fct_cmd->cmd_type);
1629
1630#ifdef FCT_API_TRACE
1631 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1632 "emlxs_fct_send_cmd_rsp %p: x%x", fct_cmd, fct_cmd->cmd_type);
1286#endif /* FCT_API_TRACE */
1633#endif /* FCT_API_TRACE */
1287
1288 switch (fct_cmd->cmd_type) {
1289 case FCT_CMD_FCP_XCHG:
1290
1291 if (ioflags & FCT_IOF_FORCE_FCA_DONE) {
1292 goto failure;
1293 }
1634
1635 switch (fct_cmd->cmd_type) {
1636 case FCT_CMD_FCP_XCHG:
1637
1638 if (ioflags & FCT_IOF_FORCE_FCA_DONE) {
1639 goto failure;
1640 }
1294 return (emlxs_fct_send_fcp_status(fct_cmd));
1295
1641
1642 mutex_enter(&cmd_sbp->fct_mtx);
1643 rval = emlxs_fct_send_fcp_status(fct_cmd);
1644 mutex_exit(&cmd_sbp->fct_mtx);
1645 return (rval);
1646
1296 case FCT_CMD_RCVD_ELS:
1297
1298 if (ioflags & FCT_IOF_FORCE_FCA_DONE) {
1299 goto failure;
1300 }
1647 case FCT_CMD_RCVD_ELS:
1648
1649 if (ioflags & FCT_IOF_FORCE_FCA_DONE) {
1650 goto failure;
1651 }
1652
1301 return (emlxs_fct_send_els_rsp(fct_cmd));
1302
1653 return (emlxs_fct_send_els_rsp(fct_cmd));
1654
1303 case FCT_CMD_RCVD_ABTS:
1304
1305 if (ioflags & FCT_IOF_FORCE_FCA_DONE) {
1306 fct_cmd->cmd_handle = 0;
1307 }
1308 return (emlxs_fct_send_abts_rsp(fct_cmd));
1309
1310 default:
1311
1312 if (ioflags & FCT_IOF_FORCE_FCA_DONE) {
1313 fct_cmd->cmd_handle = 0;
1314 }
1655 default:
1656
1657 if (ioflags & FCT_IOF_FORCE_FCA_DONE) {
1658 fct_cmd->cmd_handle = 0;
1659 }
1660
1315 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1316 "emlxs_fct_send_cmd_rsp: Invalid cmd type found. type=%x",
1317 fct_cmd->cmd_type);
1318
1319 return (FCT_FAILURE);
1320 }
1321
1322failure:
1323
1324 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1661 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1662 "emlxs_fct_send_cmd_rsp: Invalid cmd type found. type=%x",
1663 fct_cmd->cmd_type);
1664
1665 return (FCT_FAILURE);
1666 }
1667
1668failure:
1669
1670 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1325 "emlxs_fct_send_cmd_rsp: Unable to handle FCT_IOF_FORCE_FCA_DONE. "
1326 "type=%x", fct_cmd->cmd_type);
1671 "emlxs_fct_send_cmd_rsp: "
1672 "Unable to handle FCT_IOF_FORCE_FCA_DONE. type=%x",
1673 fct_cmd->cmd_type);
1327
1328 return (FCT_FAILURE);
1329
1674
1675 return (FCT_FAILURE);
1676
1330} /* emlxs_fct_send_cmd_rsp() */
1677} /* emlxs_fct_send_cmd_rsp() */
1331
1332
1678
1679
1333
1334static fct_status_t
1335emlxs_flogi_xchg(struct fct_local_port *fct_port, struct fct_flogi_xchg *fx)
1336{
1337 emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
1338 emlxs_hba_t *hba = HBA;
1339 uint32_t size;
1340 fc_packet_t *pkt;
1341 ELS_PKT *els;
1342
1343#ifdef FCT_API_TRACE
1344 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1345 "emlxs_flogi_xchg: Sending FLOGI: %p", fct_port);
1346#else
1347 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1348 "emlxs_flogi_xchg: Sending FLOGI.");
1680static fct_status_t
1681emlxs_flogi_xchg(struct fct_local_port *fct_port, struct fct_flogi_xchg *fx)
1682{
1683 emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
1684 emlxs_hba_t *hba = HBA;
1685 uint32_t size;
1686 fc_packet_t *pkt;
1687 ELS_PKT *els;
1688
1689#ifdef FCT_API_TRACE
1690 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1691 "emlxs_flogi_xchg: Sending FLOGI: %p", fct_port);
1692#else
1693 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1694 "emlxs_flogi_xchg: Sending FLOGI.");
1349#endif /* FCT_API_TRACE */
1695#endif /* FCT_API_TRACE */
1350
1351 if (hba->state <= FC_LINK_DOWN) {
1352 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1353 "emlxs_flogi_xchg: FLOGI failed. Link down.");
1354 return (FCT_FAILURE);
1355 }
1696
1697 if (hba->state <= FC_LINK_DOWN) {
1698 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1699 "emlxs_flogi_xchg: FLOGI failed. Link down.");
1700 return (FCT_FAILURE);
1701 }
1702
1356 size = sizeof (SERV_PARM) + 4;
1357
1358 if (!(pkt = emlxs_pkt_alloc(port, size, size, 0, KM_NOSLEEP))) {
1359 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1360 "emlxs_flogi_xchg: FLOGI failed. Unable allocate packet.");
1361 return (FCT_FAILURE);
1362 }
1703 size = sizeof (SERV_PARM) + 4;
1704
1705 if (!(pkt = emlxs_pkt_alloc(port, size, size, 0, KM_NOSLEEP))) {
1706 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1707 "emlxs_flogi_xchg: FLOGI failed. Unable allocate packet.");
1708 return (FCT_FAILURE);
1709 }
1710
1363 /* Make this a polled IO */
1364 pkt->pkt_tran_flags &= ~FC_TRAN_INTR;
1365 pkt->pkt_tran_flags |= FC_TRAN_NO_INTR;
1366 pkt->pkt_comp = NULL;
1367
1368 pkt->pkt_tran_type = FC_PKT_EXCHANGE;
1369 pkt->pkt_timeout = fx->fx_sec_timeout;
1370
1371 /* Build the fc header */
1372 pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(fx->fx_did);
1711 /* Make this a polled IO */
1712 pkt->pkt_tran_flags &= ~FC_TRAN_INTR;
1713 pkt->pkt_tran_flags |= FC_TRAN_NO_INTR;
1714 pkt->pkt_comp = NULL;
1715
1716 pkt->pkt_tran_type = FC_PKT_EXCHANGE;
1717 pkt->pkt_timeout = fx->fx_sec_timeout;
1718
1719 /* Build the fc header */
1720 pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(fx->fx_did);
1373 pkt->pkt_cmd_fhdr.r_ctl = R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
1721 pkt->pkt_cmd_fhdr.r_ctl =
1722 R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
1374 pkt->pkt_cmd_fhdr.s_id = SWAP_DATA24_LO(fx->fx_sid);
1375 pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
1376 pkt->pkt_cmd_fhdr.f_ctl = F_CTL_FIRST_SEQ | F_CTL_SEQ_INITIATIVE;
1377 pkt->pkt_cmd_fhdr.seq_id = 0;
1378 pkt->pkt_cmd_fhdr.df_ctl = 0;
1379 pkt->pkt_cmd_fhdr.seq_cnt = 0;
1380 pkt->pkt_cmd_fhdr.ox_id = 0xffff;
1381 pkt->pkt_cmd_fhdr.rx_id = 0xffff;
1382 pkt->pkt_cmd_fhdr.ro = 0;
1383
1384 /* Build the command */
1723 pkt->pkt_cmd_fhdr.s_id = SWAP_DATA24_LO(fx->fx_sid);
1724 pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
1725 pkt->pkt_cmd_fhdr.f_ctl = F_CTL_FIRST_SEQ | F_CTL_SEQ_INITIATIVE;
1726 pkt->pkt_cmd_fhdr.seq_id = 0;
1727 pkt->pkt_cmd_fhdr.df_ctl = 0;
1728 pkt->pkt_cmd_fhdr.seq_cnt = 0;
1729 pkt->pkt_cmd_fhdr.ox_id = 0xffff;
1730 pkt->pkt_cmd_fhdr.rx_id = 0xffff;
1731 pkt->pkt_cmd_fhdr.ro = 0;
1732
1733 /* Build the command */
1385 /*
1386 * Service paramters will be added automatically later by the driver
1387 * (See emlxs_send_els())
1388 */
1734 /* Service paramters will be added automatically later by the driver */
1389 els = (ELS_PKT *)pkt->pkt_cmd;
1390 els->elsCode = 0x04; /* FLOGI */
1391
1392 if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
1393 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1394 "emlxs_flogi_xchg: FLOGI failed. Unable to send packet.");
1395
1396 emlxs_pkt_free(pkt);
1397 return (FCT_FAILURE);
1398 }
1735 els = (ELS_PKT *)pkt->pkt_cmd;
1736 els->elsCode = 0x04; /* FLOGI */
1737
1738 if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
1739 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1740 "emlxs_flogi_xchg: FLOGI failed. Unable to send packet.");
1741
1742 emlxs_pkt_free(pkt);
1743 return (FCT_FAILURE);
1744 }
1745
1399 if ((pkt->pkt_state != FC_PKT_SUCCESS) &&
1400 (pkt->pkt_state != FC_PKT_LS_RJT)) {
1401 if (pkt->pkt_state == FC_PKT_TIMEOUT) {
1402 return (FCT_TIMEOUT);
1403 } else if ((pkt->pkt_state == FC_PKT_LOCAL_RJT) &&
1404 (pkt->pkt_reason == FC_REASON_FCAL_OPN_FAIL)) {
1405 return (FCT_NOT_FOUND);
1406 }
1746 if ((pkt->pkt_state != FC_PKT_SUCCESS) &&
1747 (pkt->pkt_state != FC_PKT_LS_RJT)) {
1748 if (pkt->pkt_state == FC_PKT_TIMEOUT) {
1749 return (FCT_TIMEOUT);
1750 } else if ((pkt->pkt_state == FC_PKT_LOCAL_RJT) &&
1751 (pkt->pkt_reason == FC_REASON_FCAL_OPN_FAIL)) {
1752 return (FCT_NOT_FOUND);
1753 }
1754
1407 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1408 "emlxs_flogi_xchg: FLOGI failed. state=%x reason=%x",
1409 pkt->pkt_state, pkt->pkt_reason);
1410
1411 return (FCT_FAILURE);
1412 }
1755 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1756 "emlxs_flogi_xchg: FLOGI failed. state=%x reason=%x",
1757 pkt->pkt_state, pkt->pkt_reason);
1758
1759 return (FCT_FAILURE);
1760 }
1761
1413 if (pkt->pkt_state == FC_PKT_LS_RJT) {
1414 fx->fx_op = ELS_OP_LSRJT;
1415 fx->fx_rjt_reason = pkt->pkt_reason;
1416 fx->fx_rjt_expl = pkt->pkt_expln;
1417 } else { /* FC_PKT_SUCCESS */
1762 if (pkt->pkt_state == FC_PKT_LS_RJT) {
1763 fx->fx_op = ELS_OP_LSRJT;
1764 fx->fx_rjt_reason = pkt->pkt_reason;
1765 fx->fx_rjt_expl = pkt->pkt_expln;
1766 } else { /* FC_PKT_SUCCESS */
1767
1418 fx->fx_op = ELS_OP_ACC;
1419 fx->fx_sid = Fabric_DID;
1420 fx->fx_did = port->did;
1421
1768 fx->fx_op = ELS_OP_ACC;
1769 fx->fx_sid = Fabric_DID;
1770 fx->fx_did = port->did;
1771
1422 els = (ELS_PKT *) pkt->pkt_resp;
1772 els = (ELS_PKT *)pkt->pkt_resp;
1423 bcopy((caddr_t)&els->un.logi.nodeName,
1424 (caddr_t)fx->fx_nwwn, 8);
1425 bcopy((caddr_t)&els->un.logi.portName,
1426 (caddr_t)fx->fx_pwwn, 8);
1427 fx->fx_fport = els->un.logi.cmn.fPort;
1428 }
1429
1430 return (FCT_SUCCESS);
1431
1773 bcopy((caddr_t)&els->un.logi.nodeName,
1774 (caddr_t)fx->fx_nwwn, 8);
1775 bcopy((caddr_t)&els->un.logi.portName,
1776 (caddr_t)fx->fx_pwwn, 8);
1777 fx->fx_fport = els->un.logi.cmn.fPort;
1778 }
1779
1780 return (FCT_SUCCESS);
1781
1432} /* emlxs_flogi_xchg() */
1782} /* emlxs_flogi_xchg() */
1433
1434
1783
1784
1435
1436/* This is called right after we report that link has come online */
1437static fct_status_t
1438emlxs_fct_get_link_info(fct_local_port_t *fct_port, fct_link_info_t *link)
1439{
1440 emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
1441 emlxs_hba_t *hba = HBA;
1442
1443 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1444 "emlxs_fct_get_link_info %p", fct_port);
1445
1446 mutex_enter(&EMLXS_PORT_LOCK);
1447
1448 if (!(port->fct_flags & FCT_STATE_LINK_UP) ||
1785/* This is called right after we report that link has come online */
1786static fct_status_t
1787emlxs_fct_get_link_info(fct_local_port_t *fct_port, fct_link_info_t *link)
1788{
1789 emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
1790 emlxs_hba_t *hba = HBA;
1791
1792 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1793 "emlxs_fct_get_link_info %p", fct_port);
1794
1795 mutex_enter(&EMLXS_PORT_LOCK);
1796
1797 if (!(port->fct_flags & FCT_STATE_LINK_UP) ||
1449 (hba->state < FC_LINK_UP) ||
1450 (hba->flag & FC_LOOPBACK_MODE)) {
1798 (hba->state < FC_LINK_UP) || (hba->flag & FC_LOOPBACK_MODE)) {
1451 link->port_topology = PORT_TOPOLOGY_UNKNOWN;
1452 link->port_speed = PORT_SPEED_UNKNOWN;
1453 link->portid = 0;
1454
1455 mutex_exit(&EMLXS_PORT_LOCK);
1456
1457 return (FCT_SUCCESS);
1458 }
1799 link->port_topology = PORT_TOPOLOGY_UNKNOWN;
1800 link->port_speed = PORT_SPEED_UNKNOWN;
1801 link->portid = 0;
1802
1803 mutex_exit(&EMLXS_PORT_LOCK);
1804
1805 return (FCT_SUCCESS);
1806 }
1807
1459 if (hba->topology == TOPOLOGY_LOOP) {
1460 link->port_topology = PORT_TOPOLOGY_PRIVATE_LOOP;
1461 } else {
1462 link->port_topology = PORT_TOPOLOGY_PT_TO_PT;
1463 }
1464
1465 switch (hba->linkspeed) {
1466 case LA_1GHZ_LINK:

--- 21 unchanged lines hidden (view full) ---

1488 link->port_fca_flogi_done = 0;
1489 link->port_fct_flogi_done = 0;
1490
1491
1492 mutex_exit(&EMLXS_PORT_LOCK);
1493
1494 return (FCT_SUCCESS);
1495
1808 if (hba->topology == TOPOLOGY_LOOP) {
1809 link->port_topology = PORT_TOPOLOGY_PRIVATE_LOOP;
1810 } else {
1811 link->port_topology = PORT_TOPOLOGY_PT_TO_PT;
1812 }
1813
1814 switch (hba->linkspeed) {
1815 case LA_1GHZ_LINK:

--- 21 unchanged lines hidden (view full) ---

1837 link->port_fca_flogi_done = 0;
1838 link->port_fct_flogi_done = 0;
1839
1840
1841 mutex_exit(&EMLXS_PORT_LOCK);
1842
1843 return (FCT_SUCCESS);
1844
1496} /* emlxs_fct_get_link_info() */
1845} /* emlxs_fct_get_link_info() */
1497
1498
1846
1847
1499
1500static fct_status_t
1501emlxs_fct_register_remote_port(fct_local_port_t *fct_port,
1502 fct_remote_port_t *remote_port, fct_cmd_t *fct_cmd)
1503{
1504 emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
1505 emlxs_hba_t *hba = HBA;
1506 emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
1507 clock_t timeout;
1508 int32_t pkt_ret;
1509 fct_els_t *els;
1510 SERV_PARM *sp;
1511 emlxs_node_t *ndlp;
1512 SERV_PARM sparam;
1513 uint32_t *iptr;
1514
1515#ifdef FCT_API_TRACE
1516 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1517 "emlxs_fct_register_remote_port %p", fct_port);
1848static fct_status_t
1849emlxs_fct_register_remote_port(fct_local_port_t *fct_port,
1850 fct_remote_port_t *remote_port, fct_cmd_t *fct_cmd)
1851{
1852 emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
1853 emlxs_hba_t *hba = HBA;
1854 emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
1855 clock_t timeout;
1856 int32_t pkt_ret;
1857 fct_els_t *els;
1858 SERV_PARM *sp;
1859 emlxs_node_t *ndlp;
1860 SERV_PARM sparam;
1861 uint32_t *iptr;
1862
1863#ifdef FCT_API_TRACE
1864 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1865 "emlxs_fct_register_remote_port %p", fct_port);
1518#endif /* FCT_API_TRACE */
1866#endif /* FCT_API_TRACE */
1519
1520 if (!(cmd_sbp->pkt_flags & PACKET_VALID)) {
1521 (void) emlxs_fct_cmd_init(port, fct_cmd);
1867
1868 if (!(cmd_sbp->pkt_flags & PACKET_VALID)) {
1869 (void) emlxs_fct_cmd_init(port, fct_cmd);
1522 /* mutex_enter(&cmd_sbp->mtx); */
1870 /* mutex_enter(&cmd_sbp->fct_mtx); */
1523
1524 cmd_sbp->ring = &hba->ring[FC_ELS_RING];
1525 cmd_sbp->fct_type = EMLXS_FCT_ELS_CMD;
1871
1872 cmd_sbp->ring = &hba->ring[FC_ELS_RING];
1873 cmd_sbp->fct_type = EMLXS_FCT_ELS_CMD;
1526 cmd_sbp->fct_state = EMLXS_FCT_REQ_CREATED;
1874 cmd_sbp->did = fct_cmd->cmd_rportid;
1527 } else {
1875 } else {
1528 mutex_enter(&cmd_sbp->mtx);
1876 mutex_enter(&cmd_sbp->fct_mtx);
1529 }
1530
1877 }
1878
1879 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_REG_PENDING);
1880
1881 mutex_enter(&cmd_sbp->mtx);
1531 cmd_sbp->pkt_flags &= ~PACKET_RETURNED;
1882 cmd_sbp->pkt_flags &= ~PACKET_RETURNED;
1883 mutex_exit(&cmd_sbp->mtx);
1532
1533 if (!cmd_sbp->node) {
1884
1885 if (!cmd_sbp->node) {
1534 cmd_sbp->node = emlxs_node_find_did(port, fct_cmd->cmd_rportid);
1886 cmd_sbp->node =
1887 emlxs_node_find_did(port, fct_cmd->cmd_rportid);
1535 }
1888 }
1889
1536 if (!cmd_sbp->node) {
1537 els = (fct_els_t *)fct_cmd->cmd_specific;
1538
1539 /* Check for unsolicited PLOGI */
1890 if (!cmd_sbp->node) {
1891 els = (fct_els_t *)fct_cmd->cmd_specific;
1892
1893 /* Check for unsolicited PLOGI */
1540 if (cmd_sbp->fct_state == EMLXS_FCT_CMD_RECEIVED) {
1541 sp = (SERV_PARM *)
1542 ((caddr_t)els->els_req_payload + sizeof (uint32_t));
1894 if (cmd_sbp->fct_flags & EMLXS_FCT_PLOGI_RECEIVED) {
1895 sp = (SERV_PARM *)((caddr_t)els->els_req_payload +
1896 sizeof (uint32_t));
1543 } else { /* Solicited PLOGI */
1897 } else { /* Solicited PLOGI */
1898
1544 sp = &sparam;
1545 bcopy((caddr_t)&port->sparam, (caddr_t)sp,
1546 sizeof (SERV_PARM));
1547
1899 sp = &sparam;
1900 bcopy((caddr_t)&port->sparam, (caddr_t)sp,
1901 sizeof (SERV_PARM));
1902
1548 /* Create temporary WWN's from fct_cmd address */
1549 /*
1903 /*
1904 * Create temporary WWN's from fct_cmd address
1550 * This simply allows us to get an RPI from the
1905 * This simply allows us to get an RPI from the
1551 * adapter until we get real service params
1552 */
1553 /*
1906 * adapter until we get real service params.
1554 * The PLOGI ACC reply will trigger a REG_LOGIN
1555 * update later
1556 */
1557 iptr = (uint32_t *)&sp->portName;
1907 * The PLOGI ACC reply will trigger a REG_LOGIN
1908 * update later
1909 */
1910 iptr = (uint32_t *)&sp->portName;
1558 iptr[0] =
1559 (uint32_t)putPaddrHigh((unsigned long)fct_cmd);
1560 iptr[1] =
1561 (uint32_t)putPaddrLow((unsigned long)fct_cmd);
1911 iptr[0] = putPaddrHigh(fct_cmd);
1912 iptr[1] = putPaddrLow(fct_cmd);
1913
1562 iptr = (uint32_t *)&sp->nodeName;
1914 iptr = (uint32_t *)&sp->nodeName;
1563 iptr[0] =
1564 (uint32_t)putPaddrHigh((unsigned long)fct_cmd);
1565 iptr[1] =
1566 (uint32_t)putPaddrLow((unsigned long)fct_cmd);
1915 iptr[0] = putPaddrHigh(fct_cmd);
1916 iptr[1] = putPaddrLow(fct_cmd);
1567 }
1568
1569 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
1917 }
1918
1919 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_debug_msg,
1570 "emlxs_fct_register_remote_port: Registering did=%x. "
1571 "(%x,%p)", fct_cmd->cmd_rportid, cmd_sbp->fct_state,
1572 fct_cmd);
1920 "emlxs_fct_register_remote_port: Register did=%x. (%x,%p)",
1921 fct_cmd->cmd_rportid, cmd_sbp->fct_state, fct_cmd);
1573
1922
1574 cmd_sbp->fct_state = EMLXS_FCT_REG_PENDING;
1575
1576 /* Create a new node */
1577 if (emlxs_mb_reg_did(port, fct_cmd->cmd_rportid, sp, cmd_sbp,
1578 NULL, NULL) != 0) {
1579 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
1923 /* Create a new node */
1924 if (emlxs_mb_reg_did(port, fct_cmd->cmd_rportid, sp, cmd_sbp,
1925 NULL, NULL) != 0) {
1926 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
1580 "emlxs_fct_register_remote_port: Reg login failed. "
1581 "did=%x", fct_cmd->cmd_rportid);
1927 "emlxs_fct_register_remote_port: "
1928 "Reg login failed. did=%x",
1929 fct_cmd->cmd_rportid);
1582 goto done;
1583 }
1930 goto done;
1931 }
1584 mutex_exit(&cmd_sbp->mtx);
1585
1932
1933 mutex_exit(&cmd_sbp->fct_mtx);
1934
1586 /* Wait for completion */
1587 mutex_enter(&EMLXS_PKT_LOCK);
1588 timeout = emlxs_timeout(hba, 30);
1589 pkt_ret = 0;
1590 while ((pkt_ret != -1) &&
1591 (cmd_sbp->fct_state == EMLXS_FCT_REG_PENDING)) {
1935 /* Wait for completion */
1936 mutex_enter(&EMLXS_PKT_LOCK);
1937 timeout = emlxs_timeout(hba, 30);
1938 pkt_ret = 0;
1939 while ((pkt_ret != -1) &&
1940 (cmd_sbp->fct_state == EMLXS_FCT_REG_PENDING)) {
1592 pkt_ret = cv_timedwait(&EMLXS_PKT_CV,
1593 &EMLXS_PKT_LOCK, timeout);
1941 pkt_ret = cv_timedwait(&EMLXS_PKT_CV, &EMLXS_PKT_LOCK,
1942 timeout);
1594 }
1595 mutex_exit(&EMLXS_PKT_LOCK);
1596
1943 }
1944 mutex_exit(&EMLXS_PKT_LOCK);
1945
1597 mutex_enter(&cmd_sbp->mtx);
1946 mutex_enter(&cmd_sbp->fct_mtx);
1947 if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT_INP) {
1948 return (FCT_FAILURE);
1949 }
1598 }
1950 }
1951
1599done:
1600
1601 ndlp = (emlxs_node_t *)cmd_sbp->node;
1602
1603 if (ndlp) {
1952done:
1953
1954 ndlp = (emlxs_node_t *)cmd_sbp->node;
1955
1956 if (ndlp) {
1604 *((emlxs_node_t **)remote_port->rp_fca_private) = cmd_sbp->node;
1957 *((emlxs_node_t **)remote_port->rp_fca_private) =
1958 cmd_sbp->node;
1605 remote_port->rp_handle = ndlp->nlp_Rpi;
1606
1607 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1608 "emlxs_fct_register_remote_port: did=%x hdl=%x",
1609 fct_cmd->cmd_rportid, remote_port->rp_handle);
1610
1611 remote_port->rp_handle = ndlp->nlp_Rpi;
1612
1959 remote_port->rp_handle = ndlp->nlp_Rpi;
1960
1961 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1962 "emlxs_fct_register_remote_port: did=%x hdl=%x",
1963 fct_cmd->cmd_rportid, remote_port->rp_handle);
1964
1965 remote_port->rp_handle = ndlp->nlp_Rpi;
1966
1967 mutex_enter(&cmd_sbp->mtx);
1613 cmd_sbp->pkt_flags |= PACKET_RETURNED;
1614 mutex_exit(&cmd_sbp->mtx);
1615
1968 cmd_sbp->pkt_flags |= PACKET_RETURNED;
1969 mutex_exit(&cmd_sbp->mtx);
1970
1971 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED);
1972
1973 mutex_exit(&cmd_sbp->fct_mtx);
1616 TGTPORTSTAT.FctPortRegister++;
1617 return (FCT_SUCCESS);
1618 } else {
1619 *((emlxs_node_t **)remote_port->rp_fca_private) = NULL;
1620
1621 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1622 "emlxs_fct_register_remote_port: failed. did=%x hdl=%x",
1623 fct_cmd->cmd_rportid, remote_port->rp_handle);
1624
1625 remote_port->rp_handle = FCT_HANDLE_NONE;
1626
1974 TGTPORTSTAT.FctPortRegister++;
1975 return (FCT_SUCCESS);
1976 } else {
1977 *((emlxs_node_t **)remote_port->rp_fca_private) = NULL;
1978
1979 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1980 "emlxs_fct_register_remote_port: failed. did=%x hdl=%x",
1981 fct_cmd->cmd_rportid, remote_port->rp_handle);
1982
1983 remote_port->rp_handle = FCT_HANDLE_NONE;
1984
1985 mutex_enter(&cmd_sbp->mtx);
1627 cmd_sbp->pkt_flags |= PACKET_RETURNED;
1986 cmd_sbp->pkt_flags |= PACKET_RETURNED;
1628 cmd_sbp->fct_state = EMLXS_FCT_REQ_CREATED;
1629
1630 mutex_exit(&cmd_sbp->mtx);
1631
1987 mutex_exit(&cmd_sbp->mtx);
1988
1989 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED);
1990
1991 mutex_exit(&cmd_sbp->fct_mtx);
1632 TGTPORTSTAT.FctFailedPortRegister++;
1633 return (FCT_FAILURE);
1634 }
1635
1992 TGTPORTSTAT.FctFailedPortRegister++;
1993 return (FCT_FAILURE);
1994 }
1995
1996} /* emlxs_fct_register_remote_port() */
1636
1997
1637} /* emlxs_fct_register_remote_port() */
1638
1998
1639
1640static fct_status_t
1641emlxs_fct_deregister_remote_port(fct_local_port_t *fct_port,
1642 fct_remote_port_t *remote_port)
1643{
1644 emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
1645
1646#ifdef FCT_API_TRACE
1647 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1648 "emlxs_fct_deregister_remote_port: did=%x hdl=%x",
1649 remote_port->rp_id, remote_port->rp_handle);
1650#else
1651 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1652 "emlxs_fct_deregister_remote_port: did=%x hdl=%x",
1653 remote_port->rp_id, remote_port->rp_handle);
1999static fct_status_t
2000emlxs_fct_deregister_remote_port(fct_local_port_t *fct_port,
2001 fct_remote_port_t *remote_port)
2002{
2003 emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
2004
2005#ifdef FCT_API_TRACE
2006 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2007 "emlxs_fct_deregister_remote_port: did=%x hdl=%x",
2008 remote_port->rp_id, remote_port->rp_handle);
2009#else
2010 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2011 "emlxs_fct_deregister_remote_port: did=%x hdl=%x",
2012 remote_port->rp_id, remote_port->rp_handle);
1654#endif /* FCT_API_TRACE */
2013#endif /* FCT_API_TRACE */
1655
1656 *((emlxs_node_t **)remote_port->rp_fca_private) = NULL;
1657 (void) emlxs_mb_unreg_did(port, remote_port->rp_id, NULL, NULL, NULL);
1658
1659 TGTPORTSTAT.FctPortDeregister++;
1660 return (FCT_SUCCESS);
1661
2014
2015 *((emlxs_node_t **)remote_port->rp_fca_private) = NULL;
2016 (void) emlxs_mb_unreg_did(port, remote_port->rp_id, NULL, NULL, NULL);
2017
2018 TGTPORTSTAT.FctPortDeregister++;
2019 return (FCT_SUCCESS);
2020
1662} /* emlxs_fct_deregister_remote_port() */
2021} /* emlxs_fct_deregister_remote_port() */
1663
1664
1665/* ARGSUSED */
1666extern int
1667emlxs_fct_handle_unsol_req(emlxs_port_t *port, RING *rp, IOCBQ *iocbq,
1668 MATCHMAP *mp, uint32_t size)
1669{
1670 IOCB *iocb;

--- 24 unchanged lines hidden (view full) ---

1695 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1696 "FCP rcvd: Target unbound. rpi=%x rxid=%x. Dropping...",
1697 iocb->ulpIoTag, iocb->ulpContext);
1698
1699 emlxs_send_logo(port, sid);
1700
1701 goto dropped;
1702 }
2022
2023
2024/* ARGSUSED */
2025extern int
2026emlxs_fct_handle_unsol_req(emlxs_port_t *port, RING *rp, IOCBQ *iocbq,
2027 MATCHMAP *mp, uint32_t size)
2028{
2029 IOCB *iocb;

--- 24 unchanged lines hidden (view full) ---

2054 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2055 "FCP rcvd: Target unbound. rpi=%x rxid=%x. Dropping...",
2056 iocb->ulpIoTag, iocb->ulpContext);
2057
2058 emlxs_send_logo(port, sid);
2059
2060 goto dropped;
2061 }
2062
1703 if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) {
1704 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1705 "FCP rcvd: Target offline. rpi=%x rxid=%x. Dropping...",
1706 iocb->ulpIoTag, iocb->ulpContext);
1707
1708 emlxs_send_logo(port, sid);
1709
1710 goto dropped;
1711 }
2063 if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) {
2064 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2065 "FCP rcvd: Target offline. rpi=%x rxid=%x. Dropping...",
2066 iocb->ulpIoTag, iocb->ulpContext);
2067
2068 emlxs_send_logo(port, sid);
2069
2070 goto dropped;
2071 }
2072
1712 /* Get lun id */
1713 bcopy((void *)&fcp_cmd->fcpLunMsl, lun, 8);
1714
1715 if (TGTPORTSTAT.FctOutstandingIO >= port->fct_port->port_max_xchges) {
1716 TGTPORTSTAT.FctOverQDepth++;
1717 }
2073 /* Get lun id */
2074 bcopy((void *)&fcp_cmd->fcpLunMsl, lun, 8);
2075
2076 if (TGTPORTSTAT.FctOutstandingIO >= port->fct_port->port_max_xchges) {
2077 TGTPORTSTAT.FctOverQDepth++;
2078 }
1718 fct_cmd = MODSYM(fct_scsi_task_alloc)
1719 (port->fct_port, iocb->ulpIoTag, sid, lun, 16, 0);
2079
2080 fct_cmd =
2081 MODSYM(fct_scsi_task_alloc) (port->fct_port, iocb->ulpIoTag, sid,
2082 lun, 16, 0);
1720#ifdef FCT_API_TRACE
1721 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2083#ifdef FCT_API_TRACE
2084 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1722 "fct_scsi_task_alloc %p: FCP rcvd: cmd=%x sid=%x rxid=%x "
1723 "lun=%02x%02x dl=%d", fct_cmd, fcp_cmd->fcpCdb[0], sid,
1724 iocb->ulpContext, lun[0], lun[1], SWAP_DATA32(fcp_cmd->fcpDl));
1725#endif /* FCT_API_TRACE */
2085 "fct_scsi_task_alloc %p: FCP rcvd: "
2086 "cmd=%x sid=%x rxid=%x lun=%02x%02x dl=%d",
2087 fct_cmd, fcp_cmd->fcpCdb[0], sid, iocb->ulpContext,
2088 lun[0], lun[1], SWAP_DATA32(fcp_cmd->fcpDl));
2089#endif /* FCT_API_TRACE */
1726
1727 if (fct_cmd == NULL) {
1728 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2090
2091 if (fct_cmd == NULL) {
2092 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1729 "FCP rcvd: sid=%x xid=%x. Unable to allocate scsi task. "
1730 "Returning QFULL.", sid, iocb->ulpContext);
2093 "FCP rcvd: sid=%x xid=%x. "
2094 "Unable to allocate scsi task. Returning QFULL.",
2095 sid, iocb->ulpContext);
1731
1732 (void) emlxs_fct_send_qfull_reply(port, ndlp, iocb->ulpContext,
1733 iocb->ulpClass, fcp_cmd);
1734
1735 goto dropped;
1736 }
2096
2097 (void) emlxs_fct_send_qfull_reply(port, ndlp, iocb->ulpContext,
2098 iocb->ulpClass, fcp_cmd);
2099
2100 goto dropped;
2101 }
2102
2103 cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd);
2104 /* mutex_enter(&cmd_sbp->fct_mtx); */
2105
1737 /* Initialize fct_cmd */
1738 fct_cmd->cmd_oxid = 0xFFFF;
1739 fct_cmd->cmd_rxid = iocb->ulpContext;
1740 fct_cmd->cmd_rportid = sid;
1741 fct_cmd->cmd_lportid = port->did;
1742 fct_cmd->cmd_rp_handle = iocb->ulpIoTag; /* RPI */
1743 fct_cmd->cmd_port = port->fct_port;
1744
2106 /* Initialize fct_cmd */
2107 fct_cmd->cmd_oxid = 0xFFFF;
2108 fct_cmd->cmd_rxid = iocb->ulpContext;
2109 fct_cmd->cmd_rportid = sid;
2110 fct_cmd->cmd_lportid = port->did;
2111 fct_cmd->cmd_rp_handle = iocb->ulpIoTag; /* RPI */
2112 fct_cmd->cmd_port = port->fct_port;
2113
1745 /* Initialize cmd_sbp */
1746 cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd);
1747 /* mutex_enter(&cmd_sbp->mtx); */
2114 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_FCP_CMD_RECEIVED);
1748
2115
2116 /* Initialize cmd_sbp */
2117 cmd_sbp->did = sid;
1749 cmd_sbp->ring = rp;
1750 cmd_sbp->class = iocb->ulpClass;
1751 cmd_sbp->lun = (lun[0] << 8) | lun[1];
1752 cmd_sbp->fct_type = EMLXS_FCT_FCP_CMD;
2118 cmd_sbp->ring = rp;
2119 cmd_sbp->class = iocb->ulpClass;
2120 cmd_sbp->lun = (lun[0] << 8) | lun[1];
2121 cmd_sbp->fct_type = EMLXS_FCT_FCP_CMD;
1753 cmd_sbp->fct_state = EMLXS_FCT_CMD_RECEIVED;
1754 /*
1755 * bcopy((uint8_t*)iocb, (uint8_t*)&cmd_sbp->iocbq,
1756 * sizeof(emlxs_iocb_t));
1757 */
1758
1759 fct_task = (scsi_task_t *)fct_cmd->cmd_specific;
1760
1761 /* Set task_flags */
2122
2123 fct_task = (scsi_task_t *)fct_cmd->cmd_specific;
2124
2125 /* Set task_flags */
1762 switch (fcp_cmd->fcpCntl2) {
1763 case 0:
2126 switch (fcp_cmd->fcpCntl1) {
2127 case SIMPLE_Q:
1764 fct_task->task_flags = TF_ATTR_SIMPLE_QUEUE;
1765 break;
1766
2128 fct_task->task_flags = TF_ATTR_SIMPLE_QUEUE;
2129 break;
2130
1767 case 1:
2131 case HEAD_OF_Q:
1768 fct_task->task_flags = TF_ATTR_HEAD_OF_QUEUE;
1769 break;
1770
2132 fct_task->task_flags = TF_ATTR_HEAD_OF_QUEUE;
2133 break;
2134
1771 case 2:
2135 case ORDERED_Q:
1772 fct_task->task_flags = TF_ATTR_ORDERED_QUEUE;
1773 break;
1774
2136 fct_task->task_flags = TF_ATTR_ORDERED_QUEUE;
2137 break;
2138
1775 case 4:
2139 case ACA_Q:
1776 fct_task->task_flags = TF_ATTR_ACA;
1777 break;
1778
2140 fct_task->task_flags = TF_ATTR_ACA;
2141 break;
2142
1779 case 5:
2143 case UNTAGGED:
1780 fct_task->task_flags = TF_ATTR_UNTAGGED;
1781 break;
1782 }
1783
1784 cnt = SWAP_DATA32(fcp_cmd->fcpDl);
1785 switch (fcp_cmd->fcpCntl3) {
1786 case 0:
1787 TGTPORTSTAT.FctIOCmdCnt++;

--- 25 unchanged lines hidden (view full) ---

1813 } else if (tm & BIT_5) {
1814 fct_task->task_mgmt_function = TM_TARGET_COLD_RESET;
1815 } else if (tm & BIT_6) {
1816 fct_task->task_mgmt_function = TM_CLEAR_ACA;
1817 } else {
1818 fct_task->task_mgmt_function = TM_ABORT_TASK;
1819 }
1820 }
2144 fct_task->task_flags = TF_ATTR_UNTAGGED;
2145 break;
2146 }
2147
2148 cnt = SWAP_DATA32(fcp_cmd->fcpDl);
2149 switch (fcp_cmd->fcpCntl3) {
2150 case 0:
2151 TGTPORTSTAT.FctIOCmdCnt++;

--- 25 unchanged lines hidden (view full) ---

2177 } else if (tm & BIT_5) {
2178 fct_task->task_mgmt_function = TM_TARGET_COLD_RESET;
2179 } else if (tm & BIT_6) {
2180 fct_task->task_mgmt_function = TM_CLEAR_ACA;
2181 } else {
2182 fct_task->task_mgmt_function = TM_ABORT_TASK;
2183 }
2184 }
2185
1821 /* Parallel buffers support - future */
1822 fct_task->task_max_nbufs = 1;
1823
1824 fct_task->task_additional_flags = 0;
1825 fct_task->task_cur_nbufs = 0;
1826 fct_task->task_csn_size = 8;
1827 fct_task->task_cmd_seq_no = 0;
1828 fct_task->task_expected_xfer_length = cnt;
1829 bcopy((void *)&fcp_cmd->fcpCdb, fct_task->task_cdb, 16);
1830
1831 TGTPORTSTAT.FctCmdReceived++;
1832
1833 TGTPORTSTAT.FctOutstandingIO++;
1834
2186 /* Parallel buffers support - future */
2187 fct_task->task_max_nbufs = 1;
2188
2189 fct_task->task_additional_flags = 0;
2190 fct_task->task_cur_nbufs = 0;
2191 fct_task->task_csn_size = 8;
2192 fct_task->task_cmd_seq_no = 0;
2193 fct_task->task_expected_xfer_length = cnt;
2194 bcopy((void *)&fcp_cmd->fcpCdb, fct_task->task_cdb, 16);
2195
2196 TGTPORTSTAT.FctCmdReceived++;
2197
2198 TGTPORTSTAT.FctOutstandingIO++;
2199
2200 mutex_enter(&cmd_sbp->mtx);
1835 cmd_sbp->pkt_flags |= PACKET_RETURNED;
1836 mutex_exit(&cmd_sbp->mtx);
1837
2201 cmd_sbp->pkt_flags |= PACKET_RETURNED;
2202 mutex_exit(&cmd_sbp->mtx);
2203
1838 emlxs_fct_unsol_callback(port, fct_cmd);
2204 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_CMD_POSTED);
2205 mutex_exit(&cmd_sbp->fct_mtx);
2206#ifdef FCT_API_TRACE
2207 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2208 "fct_post_rcvd_cmd:3 %p: portid x%x", fct_cmd,
2209 fct_cmd->cmd_lportid);
2210#endif /* FCT_API_TRACE */
2211 MODSYM(fct_post_rcvd_cmd) (fct_cmd, 0);
1839
1840 return (0);
1841
1842dropped:
1843
1844 TGTPORTSTAT.FctRcvDropped++;
1845 return (1);
1846
2212
2213 return (0);
2214
2215dropped:
2216
2217 TGTPORTSTAT.FctRcvDropped++;
2218 return (1);
2219
1847} /* emlxs_fct_handle_unsol_req() */
2220} /* emlxs_fct_handle_unsol_req() */
1848
1849
1850/* ARGSUSED */
1851static fct_status_t
1852emlxs_fct_send_fcp_data(fct_cmd_t *fct_cmd, stmf_data_buf_t *dbuf,
1853 uint32_t ioflags)
1854{
1855 emlxs_port_t *port =
1856 (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
1857 emlxs_hba_t *hba = HBA;
2221
2222
2223/* ARGSUSED */
2224static fct_status_t
2225emlxs_fct_send_fcp_data(fct_cmd_t *fct_cmd, stmf_data_buf_t *dbuf,
2226 uint32_t ioflags)
2227{
2228 emlxs_port_t *port =
2229 (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
2230 emlxs_hba_t *hba = HBA;
1858 emlxs_config_t *cfg = &CFG;
1859 emlxs_buf_t *cmd_sbp;
2231 emlxs_buf_t *cmd_sbp;
2232#ifdef FCT_API_TRACE
1860 scsi_task_t *fct_task;
2233 scsi_task_t *fct_task;
2234#endif /* FCT_API_TRACE */
1861 uint32_t did;
1862 IOCBQ *iocbq;
2235 uint32_t did;
2236 IOCBQ *iocbq;
1863 IOCB *iocb;
1864 uint32_t timeout;
1865 uint32_t iotag;
1866 emlxs_node_t *ndlp;
1867
1868 cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
2237 emlxs_node_t *ndlp;
2238
2239 cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
2240#ifdef FCT_API_TRACE
1869 fct_task = (scsi_task_t *)fct_cmd->cmd_specific;
2241 fct_task = (scsi_task_t *)fct_cmd->cmd_specific;
2242#endif /* FCT_API_TRACE */
1870 ndlp = *(emlxs_node_t **)fct_cmd->cmd_rp->rp_fca_private;
1871 did = fct_cmd->cmd_rportid;
1872
1873 /* Initialize cmd_sbp */
2243 ndlp = *(emlxs_node_t **)fct_cmd->cmd_rp->rp_fca_private;
2244 did = fct_cmd->cmd_rportid;
2245
2246 /* Initialize cmd_sbp */
1874 mutex_enter(&cmd_sbp->mtx);
2247 mutex_enter(&cmd_sbp->fct_mtx);
2248 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_SEND_FCP_DATA);
1875
1876 /*
2249
2250 /*
1877 * This check is here because task_max_nbufs is set to 1. This
1878 * ensures we will only have 1 outstanding call to this routine.
2251 * This check is here because task_max_nbufs is set to 1.
2252 * This ensures we will only have 1 outstanding call
2253 * to this routine.
1879 */
1880 if (!(cmd_sbp->pkt_flags & PACKET_RETURNED)) {
1881 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg,
1882 "Adapter Busy. Processing IO. did=0x%x", did);
2254 */
2255 if (!(cmd_sbp->pkt_flags & PACKET_RETURNED)) {
2256 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg,
2257 "Adapter Busy. Processing IO. did=0x%x", did);
1883 mutex_exit(&cmd_sbp->mtx);
2258 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED);
2259 mutex_exit(&cmd_sbp->fct_mtx);
1884 return (FCT_BUSY);
1885 }
2260 return (FCT_BUSY);
2261 }
2262
2263 mutex_enter(&cmd_sbp->mtx);
1886 cmd_sbp->pkt_flags &= ~PACKET_RETURNED;
2264 cmd_sbp->pkt_flags &= ~PACKET_RETURNED;
2265 mutex_exit(&cmd_sbp->mtx);
2266
1887 cmd_sbp->node = ndlp;
1888 cmd_sbp->fct_buf = dbuf;
1889
1890 iocbq = &cmd_sbp->iocbq;
2267 cmd_sbp->node = ndlp;
2268 cmd_sbp->fct_buf = dbuf;
2269
2270 iocbq = &cmd_sbp->iocbq;
1891 iocb = &iocbq->iocb;
1892
2271
1893 if (cfg[CFG_TIMEOUT_ENABLE].current) {
1894 timeout = ((2 * hba->fc_ratov) < 60) ? 60 : (2 * hba->fc_ratov);
1895 } else {
1896 timeout = 0x80000000;
1897 }
1898
1899#ifdef FCT_API_TRACE
1900 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
1901 "emlxs_fct_send_fcp_data %p: flgs=%x ioflags=%x dl=%d,%d,%d",
1902 fct_cmd, dbuf->db_flags, ioflags, fct_task->task_cmd_xfer_length,
1903 fct_task->task_nbytes_transferred, dbuf->db_data_size);
2272#ifdef FCT_API_TRACE
2273 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2274 "emlxs_fct_send_fcp_data %p: flgs=%x ioflags=%x dl=%d,%d,%d",
2275 fct_cmd, dbuf->db_flags, ioflags, fct_task->task_cmd_xfer_length,
2276 fct_task->task_nbytes_transferred, dbuf->db_data_size);
1904#endif /* FCT_API_TRACE */
2277#endif /* FCT_API_TRACE */
1905
2278
1906 /* Get the iotag by registering the packet */
1907 iotag = emlxs_register_pkt(cmd_sbp->ring, cmd_sbp);
1908
1909 if (!iotag) {
1910 /* No more command slots available, retry later */
1911 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg,
1912 "Adapter Busy. Unable to allocate iotag. did=0x%x", did);
1913
2279 if (emlxs_sli_prep_fct_iocb(port, cmd_sbp) != IOERR_SUCCESS) {
2280 mutex_enter(&cmd_sbp->mtx);
1914 cmd_sbp->pkt_flags |= PACKET_RETURNED;
1915 mutex_exit(&cmd_sbp->mtx);
2281 cmd_sbp->pkt_flags |= PACKET_RETURNED;
2282 mutex_exit(&cmd_sbp->mtx);
1916 return (FCT_BUSY);
1917 }
1918 if (emlxs_fct_bde_setup(port, cmd_sbp)) {
1919 /* Unregister the packet */
1920 (void) emlxs_unregister_pkt(cmd_sbp->ring, iotag, 0);
1921
2283
1922 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg,
1923 "Adapter Busy. Unable to setup buffer list. did=%x", did);
1924
1925 cmd_sbp->pkt_flags |= PACKET_RETURNED;
1926 mutex_exit(&cmd_sbp->mtx);
2284 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED);
2285 mutex_exit(&cmd_sbp->fct_mtx);
1927 return (FCT_BUSY);
1928 }
2286 return (FCT_BUSY);
2287 }
1929 /* Point of no return */
2288
1930 cmd_sbp->fct_type = EMLXS_FCT_FCP_DATA;
2289 cmd_sbp->fct_type = EMLXS_FCT_FCP_DATA;
1931 cmd_sbp->fct_state = EMLXS_FCT_DATA_PENDING;
2290 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_DATA_PENDING);
1932
1933 if (dbuf->db_flags & DB_SEND_STATUS_GOOD) {
1934 cmd_sbp->fct_flags |= EMLXS_FCT_SEND_STATUS;
1935 }
2291
2292 if (dbuf->db_flags & DB_SEND_STATUS_GOOD) {
2293 cmd_sbp->fct_flags |= EMLXS_FCT_SEND_STATUS;
2294 }
1936 cmd_sbp->ticks = hba->timer_tics + timeout +
1937 ((timeout > 0xff) ? 0 : 10);
1938
2295
1939 /* Initalize iocbq */
1940 iocbq->port = (void *)port;
1941 iocbq->node = (void *)ndlp;
1942 iocbq->ring = (void *)cmd_sbp->ring;
1943
1944 /* Initalize iocb */
1945 iocb->ulpContext = (uint16_t)fct_cmd->cmd_rxid;
1946 iocb->ulpIoTag = iotag;
1947 iocb->ulpRsvdByte = ((timeout > 0xff) ? 0 : timeout);
1948 iocb->ulpOwner = OWN_CHIP;
1949 iocb->ulpClass = cmd_sbp->class;
1950
1951 iocb->ulpPU = 1; /* Wd4 is relative offset */
1952 iocb->un.fcpt64.fcpt_Offset = dbuf->db_relative_offset;
1953
1954 if (fct_task->task_flags & TF_WRITE_DATA) {
1955 iocb->ulpCommand = CMD_FCP_TRECEIVE64_CX;
1956 } else { /* TF_READ_DATA */
1957 iocb->ulpCommand = CMD_FCP_TSEND64_CX;
1958 }
1959
1960#if 0
1961 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
1962 "FCT reply: icmd=%x did=%x oxid=%x rxid=%x sbp=%p",
1963 iocb->ulpCommand, did, fct_cmd->cmd_oxid, fct_cmd->cmd_rxid,
1964 cmd_sbp);
1965#endif
1966
1967 if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) {
1968 emlxs_fct_dbuf_dma_sync(dbuf, DDI_DMA_SYNC_FORDEV);
1969 }
2296 if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) {
2297 emlxs_fct_dbuf_dma_sync(dbuf, DDI_DMA_SYNC_FORDEV);
2298 }
1970 mutex_exit(&cmd_sbp->mtx);
1971 emlxs_issue_iocb_cmd(hba, cmd_sbp->ring, iocbq);
1972
2299
2300 cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP;
2301 emlxs_sli_issue_iocb_cmd(hba, cmd_sbp->ring, iocbq);
2302 mutex_exit(&cmd_sbp->fct_mtx);
2303
1973 return (FCT_SUCCESS);
1974
2304 return (FCT_SUCCESS);
2305
1975} /* emlxs_fct_send_fcp_data() */
2306} /* emlxs_fct_send_fcp_data() */
1976
1977
1978static fct_status_t
1979emlxs_fct_send_fcp_status(fct_cmd_t *fct_cmd)
1980{
1981 emlxs_port_t *port =
1982 (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
1983 emlxs_hba_t *hba = HBA;

--- 7 unchanged lines hidden (view full) ---

1991
1992 fct_task = (scsi_task_t *)fct_cmd->cmd_specific;
1993 ndlp = *(emlxs_node_t **)fct_cmd->cmd_rp->rp_fca_private;
1994 did = fct_cmd->cmd_rportid;
1995
1996 /* Initialize cmd_sbp */
1997 cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
1998
2307
2308
2309static fct_status_t
2310emlxs_fct_send_fcp_status(fct_cmd_t *fct_cmd)
2311{
2312 emlxs_port_t *port =
2313 (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
2314 emlxs_hba_t *hba = HBA;

--- 7 unchanged lines hidden (view full) ---

2322
2323 fct_task = (scsi_task_t *)fct_cmd->cmd_specific;
2324 ndlp = *(emlxs_node_t **)fct_cmd->cmd_rp->rp_fca_private;
2325 did = fct_cmd->cmd_rportid;
2326
2327 /* Initialize cmd_sbp */
2328 cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
2329
2330 /* &cmd_sbp->fct_mtx should be already held */
2331
2332 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_SEND_FCP_STATUS);
2333
1999 mutex_enter(&cmd_sbp->mtx);
2000 cmd_sbp->pkt_flags &= ~PACKET_RETURNED;
2334 mutex_enter(&cmd_sbp->mtx);
2335 cmd_sbp->pkt_flags &= ~PACKET_RETURNED;
2336 mutex_exit(&cmd_sbp->mtx);
2001 cmd_sbp->node = ndlp;
2002
2003 size = 24;
2004 if (fct_task->task_sense_length) {
2005 size += fct_task->task_sense_length;
2006 }
2007#ifdef FCT_API_TRACE
2008 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2009 "emlxs_fct_send_fcp_status %p: stat=%d resid=%d size=%d rx=%x",
2010 fct_cmd, fct_task->task_scsi_status,
2011 fct_task->task_resid, size, fct_cmd->cmd_rxid);
2337 cmd_sbp->node = ndlp;
2338
2339 size = 24;
2340 if (fct_task->task_sense_length) {
2341 size += fct_task->task_sense_length;
2342 }
2343#ifdef FCT_API_TRACE
2344 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2345 "emlxs_fct_send_fcp_status %p: stat=%d resid=%d size=%d rx=%x",
2346 fct_cmd, fct_task->task_scsi_status,
2347 fct_task->task_resid, size, fct_cmd->cmd_rxid);
2012#endif /* FCT_API_TRACE */
2348#endif /* FCT_API_TRACE */
2013
2014 if (!(pkt = emlxs_pkt_alloc(port, size, 0, 0, KM_NOSLEEP))) {
2015 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
2016 "emlxs_fct_send_fcp_status: Unable to allocate packet.");
2017
2349
2350 if (!(pkt = emlxs_pkt_alloc(port, size, 0, 0, KM_NOSLEEP))) {
2351 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
2352 "emlxs_fct_send_fcp_status: Unable to allocate packet.");
2353
2354 mutex_enter(&cmd_sbp->mtx);
2018 cmd_sbp->pkt_flags |= PACKET_RETURNED;
2019 mutex_exit(&cmd_sbp->mtx);
2020
2355 cmd_sbp->pkt_flags |= PACKET_RETURNED;
2356 mutex_exit(&cmd_sbp->mtx);
2357
2021 return (FCT_FAILURE);
2358 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED);
2359 return (FCT_BUSY);
2022 }
2360 }
2361
2023 cmd_sbp->fct_type = EMLXS_FCT_FCP_STATUS;
2362 cmd_sbp->fct_type = EMLXS_FCT_FCP_STATUS;
2024 cmd_sbp->fct_state = EMLXS_FCT_STATUS_PENDING;
2025
2026 (void) emlxs_fct_pkt_init(port, fct_cmd, pkt);
2363
2364 (void) emlxs_fct_pkt_init(port, fct_cmd, pkt);
2365 cmd_sbp->fct_pkt = pkt;
2027
2028 pkt->pkt_tran_type = FC_PKT_OUTBOUND;
2029 pkt->pkt_timeout =
2030 ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov);
2031 pkt->pkt_comp = emlxs_fct_pkt_comp;
2032
2033 /* Build the fc header */
2034 pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(did);

--- 20 unchanged lines hidden (view full) ---

2055
2056 } else if (fct_task->task_status_ctrl & TASK_SCTRL_UNDER) {
2057 TGTPORTSTAT.FctScsiResidUnder++;
2058 fcp_rsp->rspStatus2 |= RESID_UNDER;
2059 fcp_rsp->rspResId = SWAP_DATA32(fct_task->task_resid);
2060
2061 }
2062 }
2366
2367 pkt->pkt_tran_type = FC_PKT_OUTBOUND;
2368 pkt->pkt_timeout =
2369 ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov);
2370 pkt->pkt_comp = emlxs_fct_pkt_comp;
2371
2372 /* Build the fc header */
2373 pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(did);

--- 20 unchanged lines hidden (view full) ---

2394
2395 } else if (fct_task->task_status_ctrl & TASK_SCTRL_UNDER) {
2396 TGTPORTSTAT.FctScsiResidUnder++;
2397 fcp_rsp->rspStatus2 |= RESID_UNDER;
2398 fcp_rsp->rspResId = SWAP_DATA32(fct_task->task_resid);
2399
2400 }
2401 }
2402
2063 if (fct_task->task_scsi_status) {
2064 if (fct_task->task_scsi_status == SCSI_STAT_QUE_FULL) {
2065 TGTPORTSTAT.FctScsiQfullErr++;
2066 } else {
2067 TGTPORTSTAT.FctScsiStatusErr++;
2068 }
2069
2403 if (fct_task->task_scsi_status) {
2404 if (fct_task->task_scsi_status == SCSI_STAT_QUE_FULL) {
2405 TGTPORTSTAT.FctScsiQfullErr++;
2406 } else {
2407 TGTPORTSTAT.FctScsiStatusErr++;
2408 }
2409
2070 /*
2071 * Make sure a residual is reported on non-SCSI_GOOD READ
2072 * status
2073 */
2410 /* Make sure residual reported on non-SCSI_GOOD READ status */
2074 if ((fct_task->task_flags & TF_READ_DATA) &&
2075 (fcp_rsp->rspResId == 0)) {
2076 fcp_rsp->rspStatus2 |= RESID_UNDER;
2411 if ((fct_task->task_flags & TF_READ_DATA) &&
2412 (fcp_rsp->rspResId == 0)) {
2413 fcp_rsp->rspStatus2 |= RESID_UNDER;
2077 fcp_rsp->rspResId = fct_task->task_expected_xfer_length;
2414 fcp_rsp->rspResId =
2415 fct_task->task_expected_xfer_length;
2078 }
2079 }
2416 }
2417 }
2418
2419
2080 if (fct_task->task_sense_length) {
2081 TGTPORTSTAT.FctScsiSenseErr++;
2082 fcp_rsp->rspStatus2 |= SNS_LEN_VALID;
2083 fcp_rsp->rspSnsLen = SWAP_DATA32(fct_task->task_sense_length);
2084
2085 bcopy((uint8_t *)fct_task->task_sense_data,
2420 if (fct_task->task_sense_length) {
2421 TGTPORTSTAT.FctScsiSenseErr++;
2422 fcp_rsp->rspStatus2 |= SNS_LEN_VALID;
2423 fcp_rsp->rspSnsLen = SWAP_DATA32(fct_task->task_sense_length);
2424
2425 bcopy((uint8_t *)fct_task->task_sense_data,
2086 (uint8_t *)&fcp_rsp->rspInfo0, fct_task->task_sense_length);
2426 (uint8_t *)&fcp_rsp->rspInfo0,
2427 fct_task->task_sense_length);
2087 }
2428 }
2429
2088 fcp_rsp->rspStatus3 = fct_task->task_scsi_status;
2089 fcp_rsp->rspRspLen = 0;
2430 fcp_rsp->rspStatus3 = fct_task->task_scsi_status;
2431 fcp_rsp->rspRspLen = 0;
2432 cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP;
2090
2433
2091 mutex_exit(&cmd_sbp->mtx);
2092
2093 if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
2094 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
2095 "emlxs_fct_send_fcp_status: Unable to send packet.");
2096
2097 if (cmd_sbp->pkt_flags & PACKET_VALID) {
2098 mutex_enter(&cmd_sbp->mtx);
2099 cmd_sbp->fct_pkt = NULL;
2434 if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
2435 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
2436 "emlxs_fct_send_fcp_status: Unable to send packet.");
2437
2438 if (cmd_sbp->pkt_flags & PACKET_VALID) {
2439 mutex_enter(&cmd_sbp->mtx);
2440 cmd_sbp->fct_pkt = NULL;
2100 cmd_sbp->fct_state = EMLXS_FCT_STATUS_COMPLETE;
2101 cmd_sbp->pkt_flags |= PACKET_RETURNED;
2441 cmd_sbp->pkt_flags |= PACKET_RETURNED;
2442 cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP;
2102 mutex_exit(&cmd_sbp->mtx);
2103 }
2443 mutex_exit(&cmd_sbp->mtx);
2444 }
2445
2104 emlxs_pkt_free(pkt);
2446 emlxs_pkt_free(pkt);
2105 return (FCT_FAILURE);
2447
2448 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED);
2449 return (FCT_BUSY);
2106 }
2450 }
2451
2452 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_STATUS_PENDING);
2107 return (FCT_SUCCESS);
2108
2453 return (FCT_SUCCESS);
2454
2109} /* emlxs_fct_send_fcp_status() */
2455} /* emlxs_fct_send_fcp_status() */
2110
2111
2112static fct_status_t
2456
2457
2458static fct_status_t
2113emlxs_fct_send_qfull_reply(emlxs_port_t *port, emlxs_node_t *ndlp, uint16_t xid,
2114 uint32_t class, emlxs_fcp_cmd_t *fcp_cmd)
2459emlxs_fct_send_qfull_reply(emlxs_port_t *port, emlxs_node_t *ndlp,
2460 uint16_t xid, uint32_t class, emlxs_fcp_cmd_t *fcp_cmd)
2115{
2116 emlxs_hba_t *hba = HBA;
2117 emlxs_buf_t *sbp;
2118 fc_packet_t *pkt;
2119 emlxs_fcp_rsp *fcp_rsp;
2120 uint32_t size;
2121 RING *rp = &hba->ring[FC_FCP_RING];
2122 uint8_t lun[8];
2123
2124 bcopy((void *)&fcp_cmd->fcpLunMsl, lun, 8);
2125 size = 24;
2126
2127 if (!(pkt = emlxs_pkt_alloc(port, size, 0, 0, KM_NOSLEEP))) {
2128 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
2129 "emlxs_fct_send_qfull_reply: Unable to allocate packet.");
2130 return (FCT_FAILURE);
2131 }
2461{
2462 emlxs_hba_t *hba = HBA;
2463 emlxs_buf_t *sbp;
2464 fc_packet_t *pkt;
2465 emlxs_fcp_rsp *fcp_rsp;
2466 uint32_t size;
2467 RING *rp = &hba->ring[FC_FCP_RING];
2468 uint8_t lun[8];
2469
2470 bcopy((void *)&fcp_cmd->fcpLunMsl, lun, 8);
2471 size = 24;
2472
2473 if (!(pkt = emlxs_pkt_alloc(port, size, 0, 0, KM_NOSLEEP))) {
2474 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
2475 "emlxs_fct_send_qfull_reply: Unable to allocate packet.");
2476 return (FCT_FAILURE);
2477 }
2478
2479
2132 sbp = PKT2PRIV(pkt);
2133 sbp->node = ndlp;
2134 sbp->ring = rp;
2135 sbp->did = ndlp->nlp_DID;
2136 sbp->lun = (lun[0] << 8) | lun[1];
2137 sbp->class = class;
2138
2139 pkt->pkt_tran_type = FC_PKT_OUTBOUND;

--- 28 unchanged lines hidden (view full) ---

2168 fcp_rsp->rspResId = SWAP_DATA32(fcp_cmd->fcpDl);
2169
2170 if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
2171 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
2172 "emlxs_fct_send_qfull_reply: Unable to send packet.");
2173 emlxs_pkt_free(pkt);
2174 return (FCT_FAILURE);
2175 }
2480 sbp = PKT2PRIV(pkt);
2481 sbp->node = ndlp;
2482 sbp->ring = rp;
2483 sbp->did = ndlp->nlp_DID;
2484 sbp->lun = (lun[0] << 8) | lun[1];
2485 sbp->class = class;
2486
2487 pkt->pkt_tran_type = FC_PKT_OUTBOUND;

--- 28 unchanged lines hidden (view full) ---

2516 fcp_rsp->rspResId = SWAP_DATA32(fcp_cmd->fcpDl);
2517
2518 if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
2519 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
2520 "emlxs_fct_send_qfull_reply: Unable to send packet.");
2521 emlxs_pkt_free(pkt);
2522 return (FCT_FAILURE);
2523 }
2524
2176 return (FCT_SUCCESS);
2177
2525 return (FCT_SUCCESS);
2526
2178} /* emlxs_fct_send_qfull_reply() */
2527} /* emlxs_fct_send_qfull_reply() */
2179
2180
2528
2529
2181
2182
2183/* ARGSUSED */
2184extern int
2185emlxs_fct_handle_fcp_event(emlxs_hba_t *hba, RING *rp, IOCBQ *iocbq)
2186{
2187 emlxs_port_t *port = &PPORT;
2188 IOCB *iocb;
2189 emlxs_buf_t *sbp;
2190 emlxs_buf_t *cmd_sbp;
2191 uint32_t status;
2192 fct_cmd_t *fct_cmd;
2193 stmf_data_buf_t *dbuf;
2530/* ARGSUSED */
2531extern int
2532emlxs_fct_handle_fcp_event(emlxs_hba_t *hba, RING *rp, IOCBQ *iocbq)
2533{
2534 emlxs_port_t *port = &PPORT;
2535 IOCB *iocb;
2536 emlxs_buf_t *sbp;
2537 emlxs_buf_t *cmd_sbp;
2538 uint32_t status;
2539 fct_cmd_t *fct_cmd;
2540 stmf_data_buf_t *dbuf;
2541 uint8_t term_io;
2194 scsi_task_t *fct_task;
2542 scsi_task_t *fct_task;
2543 fc_packet_t *pkt;
2195
2196 iocb = &iocbq->iocb;
2197 sbp = (emlxs_buf_t *)iocbq->sbp;
2198
2199
2200 TGTPORTSTAT.FctEvent++;
2201
2202 if (!sbp) {
2203 /* completion with missing xmit command */
2204 TGTPORTSTAT.FctStray++;
2205
2206 /* emlxs_stray_fcp_completion_msg */
2207 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2544
2545 iocb = &iocbq->iocb;
2546 sbp = (emlxs_buf_t *)iocbq->sbp;
2547
2548
2549 TGTPORTSTAT.FctEvent++;
2550
2551 if (!sbp) {
2552 /* completion with missing xmit command */
2553 TGTPORTSTAT.FctStray++;
2554
2555 /* emlxs_stray_fcp_completion_msg */
2556 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2208 "cmd=%x status=%x error=%x iotag=%x", iocb->ulpCommand,
2209 iocb->ulpStatus, iocb->un.grsp.perr.statLocalError,
2210 iocb->ulpIoTag);
2557 "FCP event cmd=%x status=%x error=%x iotag=%x",
2558 iocb->ulpCommand, iocb->ulpStatus,
2559 iocb->un.grsp.perr.statLocalError, iocb->ulpIoTag);
2211
2212 return (1);
2213 }
2560
2561 return (1);
2562 }
2563
2214 TGTPORTSTAT.FctCompleted++;
2215
2216 port = sbp->iocbq.port;
2217 fct_cmd = sbp->fct_cmd;
2218 status = iocb->ulpStatus;
2219
2220#ifdef FCT_API_TRACE
2221 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2564 TGTPORTSTAT.FctCompleted++;
2565
2566 port = sbp->iocbq.port;
2567 fct_cmd = sbp->fct_cmd;
2568 status = iocb->ulpStatus;
2569
2570#ifdef FCT_API_TRACE
2571 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2222 "emlxs_fct_handle_fcp_event: %p: cmd=%x status=%x",
2223 fct_cmd, iocb->ulpCommand, status);
2224#endif /* FCT_API_TRACE */
2572 "emlxs_fct_handle_fcp_event: %p: cmd=%x status=%x", fct_cmd,
2573 iocb->ulpCommand, status);
2574#endif /* FCT_API_TRACE */
2225
2226 if (fct_cmd == NULL) {
2575
2576 if (fct_cmd == NULL) {
2227 if ((iocb->ulpCommand == CMD_FCP_TRSP_CX) ||
2228 (iocb->ulpCommand == CMD_FCP_TRSP64_CX)) {
2577 /* For driver generated QFULL response */
2578 if (((iocb->ulpCommand == CMD_FCP_TRSP_CX) ||
2579 (iocb->ulpCommand == CMD_FCP_TRSP64_CX)) && sbp->pkt) {
2229 emlxs_pkt_free(sbp->pkt);
2230 }
2231 return (0);
2232 }
2580 emlxs_pkt_free(sbp->pkt);
2581 }
2582 return (0);
2583 }
2584
2585 /* Validate fct_cmd */
2586 if ((fct_cmd->cmd_oxid == 0) && (fct_cmd->cmd_rxid == 0)) {
2587 pkt = NULL;
2588 goto done;
2589 }
2590
2233 cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
2591 cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
2592 mutex_enter(&cmd_sbp->fct_mtx);
2593
2594 pkt = cmd_sbp->fct_pkt;
2234 dbuf = sbp->fct_buf;
2595 dbuf = sbp->fct_buf;
2235 fct_cmd->cmd_comp_status = (status) ? FCT_FAILURE : FCT_SUCCESS;
2236
2596
2597 cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP;
2598 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_REQ_COMPLETE);
2237
2599
2238 switch (iocb->ulpCommand) {
2600 fct_cmd->cmd_comp_status = FCT_SUCCESS;
2239
2601
2602 term_io = 0;
2603 if (status) {
2604 fct_cmd->cmd_comp_status = FCT_FAILURE;
2605 term_io = 1;
2606 }
2607
2608 if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT_INP) {
2609
2610 TGTPORTSTAT.FctOutstandingIO--;
2611 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_ABORT_DONE);
2612 /* mutex_exit(&cmd_sbp->fct_mtx); */
2613 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
2614 MODSYM(fct_cmd_fca_aborted) (fct_cmd,
2615 FCT_ABORT_SUCCESS, FCT_IOF_FCA_DONE);
2616 goto done;
2617 }
2618
2619 if (term_io) {
2240 /*
2620 /*
2241 * FCP Data completion
2621 * The error indicates this IO should be terminated
2622 * immediately.
2242 */
2623 */
2624
2625 mutex_enter(&cmd_sbp->mtx);
2626 cmd_sbp->fct_flags &= ~EMLXS_FCT_SEND_STATUS;
2627 cmd_sbp->pkt_flags |= PACKET_RETURNED;
2628 mutex_exit(&cmd_sbp->mtx);
2629
2630 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED);
2631 mutex_exit(&cmd_sbp->fct_mtx);
2632
2633#ifdef FCT_API_TRACE
2634 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2635 "fct_queue_cmd_for_termination:1 %p: x%x",
2636 fct_cmd, fct_cmd->cmd_comp_status);
2637#endif /* FCT_API_TRACE */
2638 MODSYM(fct_queue_cmd_for_termination) (fct_cmd,
2639 FCT_ABTS_RECEIVED);
2640 goto done;
2641 }
2642
2643 switch (iocb->ulpCommand) {
2644
2645 /*
2646 * FCP Data completion
2647 */
2243 case CMD_FCP_TSEND_CX:
2244 case CMD_FCP_TSEND64_CX:
2245 case CMD_FCP_TRECEIVE_CX:
2246 case CMD_FCP_TRECEIVE64_CX:
2247
2248 mutex_enter(&cmd_sbp->mtx);
2249 cmd_sbp->pkt_flags &= ~PACKET_RETURNED;
2648 case CMD_FCP_TSEND_CX:
2649 case CMD_FCP_TSEND64_CX:
2650 case CMD_FCP_TRECEIVE_CX:
2651 case CMD_FCP_TRECEIVE64_CX:
2652
2653 mutex_enter(&cmd_sbp->mtx);
2654 cmd_sbp->pkt_flags &= ~PACKET_RETURNED;
2250 cmd_sbp->fct_state = EMLXS_FCT_DATA_COMPLETE;
2655 mutex_exit(&cmd_sbp->mtx);
2251
2656
2252 if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT) {
2253 cmd_sbp->fct_flags |= EMLXS_FCT_ABORT_COMPLETE;
2254 mutex_exit(&cmd_sbp->mtx);
2255
2256 /* Wake up sleeping thread */
2257 mutex_enter(&EMLXS_PKT_LOCK);
2258 cv_broadcast(&EMLXS_PKT_CV);
2259 mutex_exit(&EMLXS_PKT_LOCK);
2260
2261 break;
2262 }
2263 if (status == 0) {
2264 if (dbuf->db_flags & DB_DIRECTION_FROM_RPORT) {
2265 emlxs_fct_dbuf_dma_sync(dbuf,
2266 DDI_DMA_SYNC_FORCPU);
2267 }
2657 if (status == 0) {
2658 if (dbuf->db_flags & DB_DIRECTION_FROM_RPORT) {
2659 emlxs_fct_dbuf_dma_sync(dbuf,
2660 DDI_DMA_SYNC_FORCPU);
2661 }
2662
2268 if (cmd_sbp->fct_flags & EMLXS_FCT_SEND_STATUS) {
2269 dbuf->db_flags |= DB_STATUS_GOOD_SENT;
2270
2663 if (cmd_sbp->fct_flags & EMLXS_FCT_SEND_STATUS) {
2664 dbuf->db_flags |= DB_STATUS_GOOD_SENT;
2665
2271 fct_task = (scsi_task_t *)fct_cmd->cmd_specific;
2666 fct_task =
2667 (scsi_task_t *)fct_cmd->cmd_specific;
2272 fct_task->task_scsi_status = 0;
2273
2668 fct_task->task_scsi_status = 0;
2669
2274 mutex_exit(&cmd_sbp->mtx);
2275 (void) emlxs_fct_send_fcp_status(fct_cmd);
2670 (void) emlxs_fct_send_fcp_status(fct_cmd);
2671 mutex_exit(&cmd_sbp->fct_mtx);
2276
2277 break;
2278 }
2279 }
2672
2673 break;
2674 }
2675 }
2676
2280 cmd_sbp->fct_flags &= ~EMLXS_FCT_SEND_STATUS;
2677 cmd_sbp->fct_flags &= ~EMLXS_FCT_SEND_STATUS;
2678 mutex_enter(&cmd_sbp->mtx);
2281 cmd_sbp->pkt_flags |= PACKET_RETURNED;
2282 mutex_exit(&cmd_sbp->mtx);
2283
2679 cmd_sbp->pkt_flags |= PACKET_RETURNED;
2680 mutex_exit(&cmd_sbp->mtx);
2681
2682 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED);
2683 mutex_exit(&cmd_sbp->fct_mtx);
2284#ifdef FCT_API_TRACE
2285 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2286 "fct_scsi_data_xfer_done:1 %p %p", fct_cmd, dbuf);
2684#ifdef FCT_API_TRACE
2685 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2686 "fct_scsi_data_xfer_done:1 %p %p", fct_cmd, dbuf);
2287#endif /* FCT_API_TRACE */
2687#endif /* FCT_API_TRACE */
2288 MODSYM(fct_scsi_data_xfer_done) (fct_cmd, dbuf, 0);
2289
2290 break;
2291
2292 /* FCP Status completion */
2293 case CMD_FCP_TRSP_CX:
2294 case CMD_FCP_TRSP64_CX:
2295
2296 mutex_enter(&cmd_sbp->mtx);
2297 cmd_sbp->pkt_flags &= ~PACKET_RETURNED;
2688 MODSYM(fct_scsi_data_xfer_done) (fct_cmd, dbuf, 0);
2689
2690 break;
2691
2692 /* FCP Status completion */
2693 case CMD_FCP_TRSP_CX:
2694 case CMD_FCP_TRSP64_CX:
2695
2696 mutex_enter(&cmd_sbp->mtx);
2697 cmd_sbp->pkt_flags &= ~PACKET_RETURNED;
2298 cmd_sbp->fct_state = EMLXS_FCT_STATUS_COMPLETE;
2698 cmd_sbp->fct_pkt = NULL;
2699 mutex_exit(&cmd_sbp->mtx);
2299
2700
2300 if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT) {
2301 cmd_sbp->fct_flags |= EMLXS_FCT_ABORT_COMPLETE;
2302 mutex_exit(&cmd_sbp->mtx);
2701 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_IO_DONE);
2303
2702
2304 /* Wake up sleeping thread */
2305 mutex_enter(&EMLXS_PKT_LOCK);
2306 cv_broadcast(&EMLXS_PKT_CV);
2307 mutex_exit(&EMLXS_PKT_LOCK);
2308 } else if (cmd_sbp->fct_flags & EMLXS_FCT_SEND_STATUS) {
2703 if (cmd_sbp->fct_flags & EMLXS_FCT_SEND_STATUS) {
2309
2704
2310 /* mutex_exit(&cmd_sbp->mtx); */
2705 /* mutex_exit(&cmd_sbp->fct_mtx); */
2311 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
2312 TGTPORTSTAT.FctOutstandingIO--;
2313
2314#ifdef FCT_API_TRACE
2315 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2316 "fct_scsi_data_xfer_done:2 %p %p",
2317 fct_cmd, cmd_sbp->fct_buf);
2706 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
2707 TGTPORTSTAT.FctOutstandingIO--;
2708
2709#ifdef FCT_API_TRACE
2710 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2711 "fct_scsi_data_xfer_done:2 %p %p",
2712 fct_cmd, cmd_sbp->fct_buf);
2318#endif /* FCT_API_TRACE */
2713#endif /* FCT_API_TRACE */
2319 MODSYM(fct_scsi_data_xfer_done) (fct_cmd,
2320 cmd_sbp->fct_buf, FCT_IOF_FCA_DONE);
2321 } else {
2714 MODSYM(fct_scsi_data_xfer_done) (fct_cmd,
2715 cmd_sbp->fct_buf, FCT_IOF_FCA_DONE);
2716 } else {
2322 /* mutex_exit(&cmd_sbp->mtx); */
2717 /* mutex_exit(&cmd_sbp->fct_mtx); */
2323 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
2324 TGTPORTSTAT.FctOutstandingIO--;
2325
2326#ifdef FCT_API_TRACE
2327 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2328 "fct_send_response_done:1 %p: x%x",
2329 fct_cmd, fct_cmd->cmd_comp_status);
2718 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
2719 TGTPORTSTAT.FctOutstandingIO--;
2720
2721#ifdef FCT_API_TRACE
2722 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2723 "fct_send_response_done:1 %p: x%x",
2724 fct_cmd, fct_cmd->cmd_comp_status);
2330#endif /* FCT_API_TRACE */
2725#endif /* FCT_API_TRACE */
2331 MODSYM(fct_send_response_done) (fct_cmd,
2332 fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE);
2333 }
2726 MODSYM(fct_send_response_done) (fct_cmd,
2727 fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE);
2728 }
2334
2335 emlxs_pkt_free(sbp->pkt);
2336
2337 break;
2338
2339 default:
2340
2729 break;
2730
2731 default:
2732
2733 cmd_sbp->fct_pkt = NULL;
2734
2341 TGTPORTSTAT.FctStray++;
2342
2343 TGTPORTSTAT.FctCompleted--;
2735 TGTPORTSTAT.FctStray++;
2736
2737 TGTPORTSTAT.FctCompleted--;
2738 mutex_exit(&cmd_sbp->fct_mtx);
2344
2345 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2346 "Invalid iocb: cmd=0x%x", iocb->ulpCommand);
2347
2739
2740 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2741 "Invalid iocb: cmd=0x%x", iocb->ulpCommand);
2742
2348 emlxs_pkt_complete(sbp, status,
2349 iocb->un.grsp.perr.statLocalError, 1);
2743 if (pkt) {
2744 emlxs_pkt_complete(sbp, status,
2745 iocb->un.grsp.perr.statLocalError, 1);
2746 }
2350
2747
2351 return (1);
2352 } /* switch(iocb->ulpCommand) */
2353
2354
2748 } /* switch(iocb->ulpCommand) */
2749
2750
2751done:
2752 if (pkt) {
2753 emlxs_pkt_free(pkt);
2754 }
2755
2355 if (status == IOSTAT_SUCCESS) {
2356 TGTPORTSTAT.FctCmplGood++;
2357 } else {
2358 TGTPORTSTAT.FctCmplError++;
2359 }
2360
2361 return (0);
2362
2756 if (status == IOSTAT_SUCCESS) {
2757 TGTPORTSTAT.FctCmplGood++;
2758 } else {
2759 TGTPORTSTAT.FctCmplError++;
2760 }
2761
2762 return (0);
2763
2764} /* emlxs_fct_handle_fcp_event() */
2363
2765
2364} /* emlxs_fct_handle_fcp_event() */
2365
2766
2767/* ARGSUSED */
2768extern int
2769emlxs_fct_handle_abort(emlxs_hba_t *hba, RING *rp, IOCBQ *iocbq)
2770{
2771 emlxs_port_t *port = &PPORT;
2772 IOCB *iocb;
2773 emlxs_buf_t *sbp;
2774 fc_packet_t *pkt;
2366
2775
2776 iocb = &iocbq->iocb;
2777 sbp = (emlxs_buf_t *)iocbq->sbp;
2778
2779 TGTPORTSTAT.FctEvent++;
2780
2781 if (!sbp) {
2782 /* completion with missing xmit command */
2783 TGTPORTSTAT.FctStray++;
2784
2785 /* emlxs_stray_fcp_completion_msg */
2786 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2787 "ABORT event cmd=%x status=%x error=%x iotag=%x",
2788 iocb->ulpCommand, iocb->ulpStatus,
2789 iocb->un.grsp.perr.statLocalError, iocb->ulpIoTag);
2790
2791 return (1);
2792 }
2793
2794 pkt = PRIV2PKT(sbp);
2795
2796#ifdef FCT_API_TRACE
2797 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2798 "emlxs_fct_handle_abort: %p: xri=%x status=%x", iocb->ulpContext,
2799 iocb->ulpCommand, iocb->ulpStatus);
2800#endif /* FCT_API_TRACE */
2801
2802
2803 if (pkt) {
2804 emlxs_pkt_free(pkt);
2805 }
2806 return (0);
2807
2808} /* emlxs_fct_handle_abort() */
2809
2810
2367extern int
2368emlxs_fct_handle_unsol_els(emlxs_port_t *port, RING *rp, IOCBQ *iocbq,
2369 MATCHMAP *mp, uint32_t size)
2370{
2371 emlxs_hba_t *hba = HBA;
2372 IOCB *iocb;
2373 uint32_t cmd_code;
2374 fct_cmd_t *fct_cmd;

--- 15 unchanged lines hidden (view full) ---

2390 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2391 "%s: sid=%x. Target unbound. Rejecting...",
2392 emlxs_elscmd_xlate(cmd_code), sid);
2393 (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code,
2394 LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
2395
2396 goto done;
2397 }
2811extern int
2812emlxs_fct_handle_unsol_els(emlxs_port_t *port, RING *rp, IOCBQ *iocbq,
2813 MATCHMAP *mp, uint32_t size)
2814{
2815 emlxs_hba_t *hba = HBA;
2816 IOCB *iocb;
2817 uint32_t cmd_code;
2818 fct_cmd_t *fct_cmd;

--- 15 unchanged lines hidden (view full) ---

2834 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2835 "%s: sid=%x. Target unbound. Rejecting...",
2836 emlxs_elscmd_xlate(cmd_code), sid);
2837 (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code,
2838 LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
2839
2840 goto done;
2841 }
2842
2398 if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) {
2399 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2400 "%s: sid=%x. Target offline. Rejecting...",
2401 emlxs_elscmd_xlate(cmd_code), sid);
2402 (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code,
2403 LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
2404
2405 goto done;
2406 }
2843 if (!(port->fct_flags & FCT_STATE_PORT_ONLINE)) {
2844 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2845 "%s: sid=%x. Target offline. Rejecting...",
2846 emlxs_elscmd_xlate(cmd_code), sid);
2847 (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code,
2848 LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
2849
2850 goto done;
2851 }
2852
2407 /* Process the request */
2408 switch (cmd_code) {
2409 case ELS_CMD_FLOGI:
2853 /* Process the request */
2854 switch (cmd_code) {
2855 case ELS_CMD_FLOGI:
2410 rval = emlxs_fct_process_unsol_flogi(port, rp, iocbq, mp, size);
2411 break;
2856 rval =
2857 emlxs_fct_process_unsol_flogi(port, rp, iocbq, mp, size);
2412
2858
2859 if (!rval) {
2860 ELS_PKT *els_pkt = (ELS_PKT *)bp;
2861
2862 /* Save the FLOGI exchange information */
2863 bzero((uint8_t *)&port->fx,
2864 sizeof (fct_flogi_xchg_t));
2865 port->fx_context = iocb->ulpContext;
2866 bcopy((caddr_t)&els_pkt->un.logi.nodeName,
2867 (caddr_t)port->fx.fx_nwwn, 8);
2868 bcopy((caddr_t)&els_pkt->un.logi.portName,
2869 (caddr_t)port->fx.fx_pwwn, 8);
2870 port->fx.fx_sid = sid;
2871 port->fx.fx_did = iocb->un.elsreq.myID;
2872 port->fx.fx_fport = els_pkt->un.logi.cmn.fPort;
2873 port->fx.fx_op = ELS_OP_FLOGI;
2874
2875 /* Try to handle the FLOGI now */
2876 emlxs_fct_handle_rcvd_flogi(port);
2877 }
2878 goto done;
2879
2413 case ELS_CMD_PLOGI:
2880 case ELS_CMD_PLOGI:
2414 rval = emlxs_fct_process_unsol_plogi(port, rp, iocbq, mp, size);
2881 rval =
2882 emlxs_fct_process_unsol_plogi(port, rp, iocbq, mp, size);
2415 break;
2416
2417 default:
2418 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2419 "%s: sid=0x%x", emlxs_elscmd_xlate(cmd_code), sid);
2420 rval = 0;
2421 break;
2422 }
2423
2424 if (rval) {
2425 goto done;
2426 }
2883 break;
2884
2885 default:
2886 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2887 "%s: sid=0x%x", emlxs_elscmd_xlate(cmd_code), sid);
2888 rval = 0;
2889 break;
2890 }
2891
2892 if (rval) {
2893 goto done;
2894 }
2895
2427 padding = (8 - (size & 7)) & 7;
2428
2429 fct_cmd = (fct_cmd_t *)MODSYM(fct_alloc) (FCT_STRUCT_CMD_RCVD_ELS,
2896 padding = (8 - (size & 7)) & 7;
2897
2898 fct_cmd = (fct_cmd_t *)MODSYM(fct_alloc) (FCT_STRUCT_CMD_RCVD_ELS,
2430 (size + padding + GET_STRUCT_SIZE(emlxs_buf_t)), AF_FORCE_NOSLEEP);
2899 (size + padding + GET_STRUCT_SIZE(emlxs_buf_t)),
2900 AF_FORCE_NOSLEEP);
2431
2432#ifdef FCT_API_TRACE
2433 {
2434 uint32_t *ptr = (uint32_t *)bp;
2435
2436 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2437 "fct_alloc %p: ELS rcvd: rxid=%x payload: x%x x%x",
2438 fct_cmd, iocb->ulpContext, *ptr, *(ptr + 1));
2439 }
2901
2902#ifdef FCT_API_TRACE
2903 {
2904 uint32_t *ptr = (uint32_t *)bp;
2905
2906 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2907 "fct_alloc %p: ELS rcvd: rxid=%x payload: x%x x%x",
2908 fct_cmd, iocb->ulpContext, *ptr, *(ptr + 1));
2909 }
2440#endif /* FCT_API_TRACE */
2910#endif /* FCT_API_TRACE */
2441
2442 if (fct_cmd == NULL) {
2443 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2444 "%s: sid=%x. Out of memory. Rejecting...",
2445 emlxs_elscmd_xlate(cmd_code), sid);
2446
2447 (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code,
2448 LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
2449 goto done;
2450 }
2911
2912 if (fct_cmd == NULL) {
2913 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2914 "%s: sid=%x. Out of memory. Rejecting...",
2915 emlxs_elscmd_xlate(cmd_code), sid);
2916
2917 (void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code,
2918 LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
2919 goto done;
2920 }
2921
2922 cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd);
2923 /* mutex_enter(&cmd_sbp->fct_mtx); */
2924
2451 /* Initialize fct_cmd */
2452 fct_cmd->cmd_oxid = (cmd_code >> ELS_CMD_SHIFT) & 0xff;
2453 fct_cmd->cmd_rxid = iocb->ulpContext;
2454 fct_cmd->cmd_rportid = sid;
2455 fct_cmd->cmd_lportid = port->did;
2456 fct_cmd->cmd_rp_handle = iocb->ulpIoTag; /* RPI */
2457 fct_cmd->cmd_port = port->fct_port;
2458
2925 /* Initialize fct_cmd */
2926 fct_cmd->cmd_oxid = (cmd_code >> ELS_CMD_SHIFT) & 0xff;
2927 fct_cmd->cmd_rxid = iocb->ulpContext;
2928 fct_cmd->cmd_rportid = sid;
2929 fct_cmd->cmd_lportid = port->did;
2930 fct_cmd->cmd_rp_handle = iocb->ulpIoTag; /* RPI */
2931 fct_cmd->cmd_port = port->fct_port;
2932
2459 /* Initialize cmd_sbp */
2460 cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd);
2461 /* mutex_enter(&cmd_sbp->mtx); */
2933 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_ELS_CMD_RECEIVED);
2462
2934
2935 /* Initialize cmd_sbp */
2936 cmd_sbp->did = sid;
2463 cmd_sbp->ring = rp;
2464 cmd_sbp->class = iocb->ulpClass;
2465 cmd_sbp->fct_type = EMLXS_FCT_ELS_CMD;
2937 cmd_sbp->ring = rp;
2938 cmd_sbp->class = iocb->ulpClass;
2939 cmd_sbp->fct_type = EMLXS_FCT_ELS_CMD;
2466 cmd_sbp->fct_state = EMLXS_FCT_CMD_RECEIVED;
2940 cmd_sbp->fct_flags |= EMLXS_FCT_PLOGI_RECEIVED;
2941
2467 bcopy((uint8_t *)iocb, (uint8_t *)&cmd_sbp->iocbq,
2468 sizeof (emlxs_iocb_t));
2469
2942 bcopy((uint8_t *)iocb, (uint8_t *)&cmd_sbp->iocbq,
2943 sizeof (emlxs_iocb_t));
2944
2470 if (cmd_code == ELS_CMD_FLOGI) {
2471 cmd_sbp->fct_flags |= EMLXS_FCT_FLOGI;
2472 }
2473 els = (fct_els_t *)fct_cmd->cmd_specific;
2474 els->els_req_size = size;
2945 els = (fct_els_t *)fct_cmd->cmd_specific;
2946 els->els_req_size = size;
2475 els->els_req_payload = GET_BYTE_OFFSET(fct_cmd->cmd_fca_private,
2947 els->els_req_payload =
2948 GET_BYTE_OFFSET(fct_cmd->cmd_fca_private,
2476 GET_STRUCT_SIZE(emlxs_buf_t));
2477 bcopy(bp, els->els_req_payload, size);
2478
2949 GET_STRUCT_SIZE(emlxs_buf_t));
2950 bcopy(bp, els->els_req_payload, size);
2951
2952 mutex_enter(&cmd_sbp->mtx);
2479 cmd_sbp->pkt_flags |= PACKET_RETURNED;
2480 mutex_exit(&cmd_sbp->mtx);
2481
2482 emlxs_fct_unsol_callback(port, fct_cmd);
2483
2484done:
2485
2486 return (0);
2487
2953 cmd_sbp->pkt_flags |= PACKET_RETURNED;
2954 mutex_exit(&cmd_sbp->mtx);
2955
2956 emlxs_fct_unsol_callback(port, fct_cmd);
2957
2958done:
2959
2960 return (0);
2961
2488} /* emlxs_fct_handle_unsol_els() */
2962} /* emlxs_fct_handle_unsol_els() */
2489
2490
2963
2964
2491static void
2492emlxs_fct_handle_rcvd_flogi(emlxs_port_t *port, fct_cmd_t *fct_cmd)
2493{
2494 fct_els_t *fct_els;
2495 ELS_PKT *els;
2496 fct_flogi_xchg_t fx;
2497 fct_status_t status;
2498 emlxs_buf_t *cmd_sbp;
2499
2500 cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
2501
2502 mutex_enter(&cmd_sbp->mtx);
2503 cmd_sbp->pkt_flags &= ~PACKET_RETURNED;
2504
2505 fct_els = (fct_els_t *)fct_cmd->cmd_specific;
2506 els = (ELS_PKT *)fct_els->els_req_payload;
2507
2508 /* Init the xchg object */
2509 bzero((uint8_t *)&fx, sizeof (fct_flogi_xchg_t));
2510 bcopy((caddr_t)&els->un.logi.nodeName, (caddr_t)fx.fx_nwwn, 8);
2511 bcopy((caddr_t)&els->un.logi.portName, (caddr_t)fx.fx_pwwn, 8);
2512 fx.fx_sid = fct_cmd->cmd_rportid;
2513 fx.fx_did = fct_cmd->cmd_lportid;
2514 fx.fx_fport = els->un.logi.cmn.fPort;
2515 fx.fx_op = ELS_OP_FLOGI;
2516
2517 status = MODSYM(fct_handle_rcvd_flogi) (port->fct_port, &fx);
2518#ifdef FCT_API_TRACE
2519 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2520 "fct_handle_rcvd_flogi %p: x%x", port->fct_port, status);
2521#endif /* FCT_API_TRACE */
2522
2523 if (status == FCT_SUCCESS) {
2524 if (fx.fx_op == ELS_OP_ACC) {
2525 (void) emlxs_els_reply(port, &cmd_sbp->iocbq,
2526 ELS_CMD_ACC, ELS_CMD_FLOGI, 0, 0);
2527 } else { /* ELS_OP_LSRJT */
2528 (void) emlxs_els_reply(port, &cmd_sbp->iocbq,
2529 ELS_CMD_LS_RJT, ELS_CMD_FLOGI, fx.fx_rjt_reason,
2530 fx.fx_rjt_expl);
2531 }
2532 } else {
2533 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2534 "FLOGI: sid=%x. fct_handle_rcvd_flogi failed. Rejecting.",
2535 fct_cmd->cmd_rportid);
2536
2537 (void) emlxs_els_reply(port, &cmd_sbp->iocbq, ELS_CMD_LS_RJT,
2538 ELS_CMD_FLOGI, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
2539 }
2540
2541 /* mutex_exit(&cmd_sbp->mtx); */
2542 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
2543
2544#ifdef FCT_API_TRACE
2545 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2546 "fct_free:7 %p", fct_cmd);
2547#endif /* FCT_API_TRACE */
2548 MODSYM(fct_free) (fct_cmd);
2549
2550 return;
2551
2552} /* emlxs_fct_handle_rcvd_flogi() */
2553
2554
2555/* ARGSUSED */
2556static uint32_t
2557emlxs_fct_process_unsol_flogi(emlxs_port_t *port, RING *rp, IOCBQ *iocbq,
2558 MATCHMAP *mp, uint32_t size)
2559{
2560 IOCB *iocb;
2561 char buffer[64];
2562
2563 buffer[0] = 0;
2564
2565 iocb = &iocbq->iocb;
2566
2567 /* Perform processing of FLOGI payload */
2568 if (emlxs_process_unsol_flogi(port, iocbq, mp, size, buffer)) {
2569 return (1);
2570 }
2965/* ARGSUSED */
2966static uint32_t
2967emlxs_fct_process_unsol_flogi(emlxs_port_t *port, RING *rp, IOCBQ *iocbq,
2968 MATCHMAP *mp, uint32_t size)
2969{
2970 IOCB *iocb;
2971 char buffer[64];
2972
2973 buffer[0] = 0;
2974
2975 iocb = &iocbq->iocb;
2976
2977 /* Perform processing of FLOGI payload */
2978 if (emlxs_process_unsol_flogi(port, iocbq, mp, size, buffer)) {
2979 return (1);
2980 }
2981
2571 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, "FLOGI: sid=0x%x %s",
2572 iocb->un.elsreq.remoteID, buffer);
2573
2574 return (0);
2575
2982 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, "FLOGI: sid=0x%x %s",
2983 iocb->un.elsreq.remoteID, buffer);
2984
2985 return (0);
2986
2576} /* emlxs_fct_process_unsol_flogi() */
2987} /* emlxs_fct_process_unsol_flogi() */
2577
2578
2579/* ARGSUSED */
2580static uint32_t
2581emlxs_fct_process_unsol_plogi(emlxs_port_t *port, RING *rp, IOCBQ *iocbq,
2582 MATCHMAP *mp, uint32_t size)
2583{
2584 IOCB *iocb;
2585 char buffer[64];
2586
2587 buffer[0] = 0;
2588
2589 iocb = &iocbq->iocb;
2590
2591 /* Perform processing of PLOGI payload */
2592 if (emlxs_process_unsol_plogi(port, iocbq, mp, size, buffer)) {
2593 return (1);
2594 }
2988
2989
2990/* ARGSUSED */
2991static uint32_t
2992emlxs_fct_process_unsol_plogi(emlxs_port_t *port, RING *rp, IOCBQ *iocbq,
2993 MATCHMAP *mp, uint32_t size)
2994{
2995 IOCB *iocb;
2996 char buffer[64];
2997
2998 buffer[0] = 0;
2999
3000 iocb = &iocbq->iocb;
3001
3002 /* Perform processing of PLOGI payload */
3003 if (emlxs_process_unsol_plogi(port, iocbq, mp, size, buffer)) {
3004 return (1);
3005 }
3006
2595 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, "PLOGI: sid=0x%x %s",
2596 iocb->un.elsreq.remoteID, buffer);
2597
2598 return (0);
2599
3007 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, "PLOGI: sid=0x%x %s",
3008 iocb->un.elsreq.remoteID, buffer);
3009
3010 return (0);
3011
2600} /* emlxs_fct_process_unsol_plogi() */
3012} /* emlxs_fct_process_unsol_plogi() */
2601
2602
2603/* ARGSUSED */
2604static emlxs_buf_t *
3013
3014
3015/* ARGSUSED */
3016static emlxs_buf_t *
2605emlxs_fct_pkt_init(emlxs_port_t *port, fct_cmd_t *fct_cmd, fc_packet_t *pkt)
3017emlxs_fct_pkt_init(emlxs_port_t *port, fct_cmd_t *fct_cmd,
3018 fc_packet_t *pkt)
2606{
2607 emlxs_buf_t *cmd_sbp;
2608 emlxs_buf_t *sbp;
2609
2610 cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
3019{
3020 emlxs_buf_t *cmd_sbp;
3021 emlxs_buf_t *sbp;
3022
3023 cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
2611 cmd_sbp->fct_pkt = pkt;
2612
2613 sbp = PKT2PRIV(pkt);
2614 sbp->fct_cmd = cmd_sbp->fct_cmd;
2615 sbp->node = cmd_sbp->node;
2616 sbp->ring = cmd_sbp->ring;
2617 sbp->did = cmd_sbp->did;
2618 sbp->lun = cmd_sbp->lun;
2619 sbp->class = cmd_sbp->class;
2620 sbp->fct_type = cmd_sbp->fct_type;
2621 sbp->fct_state = cmd_sbp->fct_state;
2622
2623 return (sbp);
2624
3024
3025 sbp = PKT2PRIV(pkt);
3026 sbp->fct_cmd = cmd_sbp->fct_cmd;
3027 sbp->node = cmd_sbp->node;
3028 sbp->ring = cmd_sbp->ring;
3029 sbp->did = cmd_sbp->did;
3030 sbp->lun = cmd_sbp->lun;
3031 sbp->class = cmd_sbp->class;
3032 sbp->fct_type = cmd_sbp->fct_type;
3033 sbp->fct_state = cmd_sbp->fct_state;
3034
3035 return (sbp);
3036
2625} /* emlxs_fct_pkt_init() */
3037} /* emlxs_fct_pkt_init() */
2626
2627
2628/* Mutex will be acquired */
2629static emlxs_buf_t *
2630emlxs_fct_cmd_init(emlxs_port_t *port, fct_cmd_t *fct_cmd)
2631{
2632 emlxs_hba_t *hba = HBA;
2633 emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
2634
2635 bzero((void *)cmd_sbp, sizeof (emlxs_buf_t));
3038
3039
3040/* Mutex will be acquired */
3041static emlxs_buf_t *
3042emlxs_fct_cmd_init(emlxs_port_t *port, fct_cmd_t *fct_cmd)
3043{
3044 emlxs_hba_t *hba = HBA;
3045 emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
3046
3047 bzero((void *)cmd_sbp, sizeof (emlxs_buf_t));
2636
3048 mutex_init(&cmd_sbp->fct_mtx, NULL, MUTEX_DRIVER,
3049 (void *)hba->intr_arg);
2637 mutex_init(&cmd_sbp->mtx, NULL, MUTEX_DRIVER, (void *)hba->intr_arg);
2638
3050 mutex_init(&cmd_sbp->mtx, NULL, MUTEX_DRIVER, (void *)hba->intr_arg);
3051
2639 mutex_enter(&cmd_sbp->mtx);
3052
3053 mutex_enter(&cmd_sbp->fct_mtx);
2640 cmd_sbp->pkt_flags = PACKET_VALID;
2641 cmd_sbp->port = port;
2642 cmd_sbp->fct_cmd = fct_cmd;
2643 cmd_sbp->node = (fct_cmd->cmd_rp) ?
2644 *(emlxs_node_t **)fct_cmd->cmd_rp->rp_fca_private : NULL;
3054 cmd_sbp->pkt_flags = PACKET_VALID;
3055 cmd_sbp->port = port;
3056 cmd_sbp->fct_cmd = fct_cmd;
3057 cmd_sbp->node = (fct_cmd->cmd_rp) ?
3058 *(emlxs_node_t **)fct_cmd->cmd_rp->rp_fca_private : NULL;
2645 cmd_sbp->did = fct_cmd->cmd_rportid;
2646 cmd_sbp->iocbq.sbp = cmd_sbp;
3059 cmd_sbp->iocbq.sbp = cmd_sbp;
3060 cmd_sbp->iocbq.port = port;
2647
2648 return (cmd_sbp);
2649
3061
3062 return (cmd_sbp);
3063
2650} /* emlxs_fct_cmd_init() */
3064} /* emlxs_fct_cmd_init() */
2651
2652
2653/* Mutex must be held */
2654static int
2655emlxs_fct_cmd_uninit(emlxs_port_t *port, fct_cmd_t *fct_cmd)
2656{
2657 emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
2658
3065
3066
3067/* Mutex must be held */
3068static int
3069emlxs_fct_cmd_uninit(emlxs_port_t *port, fct_cmd_t *fct_cmd)
3070{
3071 emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
3072
3073 /* Flags fct_cmd is no longer used */
3074 fct_cmd->cmd_oxid = 0;
3075 fct_cmd->cmd_rxid = 0;
3076
3077
2659 if (!(cmd_sbp->pkt_flags & PACKET_VALID)) {
2660 return (FC_FAILURE);
2661 }
3078 if (!(cmd_sbp->pkt_flags & PACKET_VALID)) {
3079 return (FC_FAILURE);
3080 }
3081
2662 if (cmd_sbp->iotag != 0) {
2663 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2664 "Pkt still registered! ringo=%d iotag=%d sbp=%p",
2665 cmd_sbp->ring, cmd_sbp->iotag, cmd_sbp);
2666
2667 if (cmd_sbp->ring) {
2668 (void) emlxs_unregister_pkt(cmd_sbp->ring,
3082 if (cmd_sbp->iotag != 0) {
3083 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3084 "Pkt still registered! ringo=%d iotag=%d sbp=%p",
3085 cmd_sbp->ring, cmd_sbp->iotag, cmd_sbp);
3086
3087 if (cmd_sbp->ring) {
3088 (void) emlxs_unregister_pkt(cmd_sbp->ring,
2669 cmd_sbp->iotag, 1);
3089 cmd_sbp->iotag, 0);
2670 }
2671 }
3090 }
3091 }
3092
2672 cmd_sbp->pkt_flags |= PACKET_RETURNED;
2673 cmd_sbp->pkt_flags &= ~PACKET_VALID;
2674
3093 cmd_sbp->pkt_flags |= PACKET_RETURNED;
3094 cmd_sbp->pkt_flags &= ~PACKET_VALID;
3095
2675 mutex_exit(&cmd_sbp->mtx);
3096 mutex_exit(&cmd_sbp->fct_mtx);
2676 mutex_destroy(&cmd_sbp->mtx);
3097 mutex_destroy(&cmd_sbp->mtx);
3098 mutex_destroy(&cmd_sbp->fct_mtx);
2677
2678 return (FC_SUCCESS);
2679
3099
3100 return (FC_SUCCESS);
3101
2680} /* emlxs_fct_cmd_uninit() */
3102} /* emlxs_fct_cmd_uninit() */
2681
2682
2683static void
2684emlxs_fct_pkt_comp(fc_packet_t *pkt)
2685{
2686 emlxs_port_t *port;
3103
3104
3105static void
3106emlxs_fct_pkt_comp(fc_packet_t *pkt)
3107{
3108 emlxs_port_t *port;
3109#ifdef FMA_SUPPORT
3110 emlxs_hba_t *hba;
3111#endif /* FMA_SUPPORT */
2687 emlxs_buf_t *sbp;
2688 emlxs_buf_t *cmd_sbp;
2689 fct_cmd_t *fct_cmd;
2690 fct_els_t *fct_els;
2691 fct_sol_ct_t *fct_ct;
2692
2693 sbp = PKT2PRIV(pkt);
2694 port = sbp->port;
3112 emlxs_buf_t *sbp;
3113 emlxs_buf_t *cmd_sbp;
3114 fct_cmd_t *fct_cmd;
3115 fct_els_t *fct_els;
3116 fct_sol_ct_t *fct_ct;
3117
3118 sbp = PKT2PRIV(pkt);
3119 port = sbp->port;
3120#ifdef FMA_SUPPORT
3121 hba = HBA;
3122#endif /* FMA_SUPPORT */
2695 fct_cmd = sbp->fct_cmd;
2696 cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
3123 fct_cmd = sbp->fct_cmd;
3124 cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
3125 mutex_enter(&cmd_sbp->fct_mtx);
3126 cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP;
3127 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_PKT_COMPLETE);
2697
3128
3129 if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT_INP) {
3130
3131 if (fct_cmd->cmd_type == FCT_CMD_FCP_XCHG) {
3132 TGTPORTSTAT.FctOutstandingIO--;
3133 }
3134 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_ABORT_DONE);
3135 /* mutex_exit(&cmd_sbp->fct_mtx); */
3136 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
3137 MODSYM(fct_cmd_fca_aborted) (fct_cmd,
3138 FCT_ABORT_SUCCESS, FCT_IOF_FCA_DONE);
3139 goto done;
3140 }
3141
2698 mutex_enter(&cmd_sbp->mtx);
2699 cmd_sbp->pkt_flags &= ~PACKET_RETURNED;
2700 cmd_sbp->fct_pkt = NULL;
3142 mutex_enter(&cmd_sbp->mtx);
3143 cmd_sbp->pkt_flags &= ~PACKET_RETURNED;
3144 cmd_sbp->fct_pkt = NULL;
3145 mutex_exit(&cmd_sbp->mtx);
2701
3146
2702 if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT) {
2703 cmd_sbp->fct_flags |= EMLXS_FCT_ABORT_COMPLETE;
2704 mutex_exit(&cmd_sbp->mtx);
3147 switch (fct_cmd->cmd_type) {
3148 case FCT_CMD_FCP_XCHG:
3149 if ((pkt->pkt_reason == FC_REASON_ABORTED) ||
3150 (pkt->pkt_reason == FC_REASON_XCHG_DROPPED) ||
3151 (pkt->pkt_reason == FC_REASON_OFFLINE)) {
3152 /*
3153 * The error indicates this IO should be terminated
3154 * immediately.
3155 */
2705
3156
2706 /* Wake up sleeping thread */
2707 mutex_enter(&EMLXS_PKT_LOCK);
2708 cv_broadcast(&EMLXS_PKT_CV);
2709 mutex_exit(&EMLXS_PKT_LOCK);
3157 cmd_sbp->fct_flags &= ~EMLXS_FCT_SEND_STATUS;
3158 mutex_enter(&cmd_sbp->mtx);
3159 cmd_sbp->pkt_flags |= PACKET_RETURNED;
3160 mutex_exit(&cmd_sbp->mtx);
2710
3161
2711 goto done;
2712 }
2713 fct_cmd->cmd_comp_status = (pkt->pkt_state) ? FCT_FAILURE : FCT_SUCCESS;
3162 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED);
3163 mutex_exit(&cmd_sbp->fct_mtx);
2714
3164
2715 switch (fct_cmd->cmd_type) {
2716 case FCT_CMD_FCP_XCHG:
2717 cmd_sbp->fct_state = EMLXS_FCT_STATUS_COMPLETE;
3165#ifdef FCT_API_TRACE
3166 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
3167 "fct_queue_cmd_for_termination:2 %p: x%x",
3168 fct_cmd, fct_cmd->cmd_comp_status);
3169#endif /* FCT_API_TRACE */
3170 MODSYM(fct_queue_cmd_for_termination) (fct_cmd,
3171 FCT_ABTS_RECEIVED);
3172 goto done;
3173 }
2718
3174
2719 /* mutex_exit(&cmd_sbp->mtx); */
3175 emlxs_fct_state_chg(fct_cmd, cmd_sbp,
3176 EMLXS_FCT_PKT_FCPRSP_COMPLETE);
3177
3178 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_IO_DONE);
3179
3180 /* mutex_exit(&cmd_sbp->fct_mtx); */
2720 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
2721
2722#ifdef FCT_API_TRACE
2723 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2724 "fct_send_response_done:2 %p: x%x",
2725 fct_cmd, fct_cmd->cmd_comp_status);
2726#else
2727 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2728 "emlxs_fct_pkt_comp: fct_send_response_done. dbuf=%p",
2729 sbp->fct_buf);
3181 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
3182
3183#ifdef FCT_API_TRACE
3184 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
3185 "fct_send_response_done:2 %p: x%x",
3186 fct_cmd, fct_cmd->cmd_comp_status);
3187#else
3188 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3189 "emlxs_fct_pkt_comp: fct_send_response_done. dbuf=%p",
3190 sbp->fct_buf);
2730#endif /* FCT_API_TRACE */
3191#endif /* FCT_API_TRACE */
2731
3192
3193 TGTPORTSTAT.FctOutstandingIO--;
3194
2732 MODSYM(fct_send_response_done) (fct_cmd,
2733 fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE);
2734
2735 break;
2736
2737 case FCT_CMD_RCVD_ELS:
3195 MODSYM(fct_send_response_done) (fct_cmd,
3196 fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE);
3197
3198 break;
3199
3200 case FCT_CMD_RCVD_ELS:
2738 cmd_sbp->fct_state = EMLXS_FCT_RSP_COMPLETE;
2739
3201
2740 /* mutex_exit(&cmd_sbp->mtx); */
3202 emlxs_fct_state_chg(fct_cmd, cmd_sbp,
3203 EMLXS_FCT_PKT_ELSRSP_COMPLETE);
3204
3205 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_IO_DONE);
3206
3207 /* mutex_exit(&cmd_sbp->fct_mtx); */
2741 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
2742
2743#ifdef FCT_API_TRACE
2744 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2745 "fct_send_response_done:3 %p: x%x",
2746 fct_cmd, fct_cmd->cmd_comp_status);
3208 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
3209
3210#ifdef FCT_API_TRACE
3211 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
3212 "fct_send_response_done:3 %p: x%x",
3213 fct_cmd, fct_cmd->cmd_comp_status);
2747#endif /* FCT_API_TRACE */
3214#endif /* FCT_API_TRACE */
2748 MODSYM(fct_send_response_done) (fct_cmd,
2749 fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE);
2750
2751 break;
2752
2753 case FCT_CMD_SOL_ELS:
3215 MODSYM(fct_send_response_done) (fct_cmd,
3216 fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE);
3217
3218 break;
3219
3220 case FCT_CMD_SOL_ELS:
2754 cmd_sbp->fct_state = EMLXS_FCT_REQ_COMPLETE;
2755
3221
3222 emlxs_fct_state_chg(fct_cmd, cmd_sbp,
3223 EMLXS_FCT_PKT_ELSCMD_COMPLETE);
3224
3225 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_IO_DONE);
3226
2756 fct_els = (fct_els_t *)fct_cmd->cmd_specific;
2757
2758 if (fct_els->els_resp_payload) {
3227 fct_els = (fct_els_t *)fct_cmd->cmd_specific;
3228
3229 if (fct_els->els_resp_payload) {
2759 emlxs_mpdata_sync(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen,
2760 DDI_DMA_SYNC_FORKERNEL);
3230 emlxs_mpdata_sync(pkt->pkt_resp_dma, 0,
3231 pkt->pkt_rsplen, DDI_DMA_SYNC_FORKERNEL);
2761
2762 bcopy((uint8_t *)pkt->pkt_resp,
2763 (uint8_t *)fct_els->els_resp_payload,
2764 fct_els->els_resp_size);
2765 }
3232
3233 bcopy((uint8_t *)pkt->pkt_resp,
3234 (uint8_t *)fct_els->els_resp_payload,
3235 fct_els->els_resp_size);
3236 }
2766 /* mutex_exit(&cmd_sbp->mtx); */
3237
3238 /* mutex_exit(&cmd_sbp->fct_mtx); */
2767 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
2768
2769#ifdef FCT_API_TRACE
2770 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2771 "fct_send_cmd_done:1 %p: x%x",
2772 fct_cmd, fct_cmd->cmd_comp_status);
3239 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
3240
3241#ifdef FCT_API_TRACE
3242 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
3243 "fct_send_cmd_done:1 %p: x%x",
3244 fct_cmd, fct_cmd->cmd_comp_status);
2773#endif /* FCT_API_TRACE */
2774 MODSYM(fct_send_cmd_done) (fct_cmd,
2775 FCT_SUCCESS, FCT_IOF_FCA_DONE);
3245#endif /* FCT_API_TRACE */
3246 MODSYM(fct_send_cmd_done) (fct_cmd, FCT_SUCCESS,
3247 FCT_IOF_FCA_DONE);
2776
2777 break;
2778
2779 case FCT_CMD_SOL_CT:
3248
3249 break;
3250
3251 case FCT_CMD_SOL_CT:
2780 cmd_sbp->fct_state = EMLXS_FCT_REQ_COMPLETE;
2781
3252
3253 emlxs_fct_state_chg(fct_cmd, cmd_sbp,
3254 EMLXS_FCT_PKT_CTCMD_COMPLETE);
3255
3256 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_IO_DONE);
3257
2782 fct_ct = (fct_sol_ct_t *)fct_cmd->cmd_specific;
2783
2784 if (fct_ct->ct_resp_payload) {
3258 fct_ct = (fct_sol_ct_t *)fct_cmd->cmd_specific;
3259
3260 if (fct_ct->ct_resp_payload) {
2785 emlxs_mpdata_sync(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen,
2786 DDI_DMA_SYNC_FORKERNEL);
3261 emlxs_mpdata_sync(pkt->pkt_resp_dma, 0,
3262 pkt->pkt_rsplen, DDI_DMA_SYNC_FORKERNEL);
2787
2788 bcopy((uint8_t *)pkt->pkt_resp,
2789 (uint8_t *)fct_ct->ct_resp_payload,
2790 fct_ct->ct_resp_size);
2791 }
3263
3264 bcopy((uint8_t *)pkt->pkt_resp,
3265 (uint8_t *)fct_ct->ct_resp_payload,
3266 fct_ct->ct_resp_size);
3267 }
2792 /* mutex_exit(&cmd_sbp->mtx); */
3268
3269 /* mutex_exit(&cmd_sbp->fct_mtx); */
2793 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
2794
2795#ifdef FCT_API_TRACE
2796 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2797 "fct_send_cmd_done:2 %p: x%x",
2798 fct_cmd, fct_cmd->cmd_comp_status);
3270 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
3271
3272#ifdef FCT_API_TRACE
3273 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
3274 "fct_send_cmd_done:2 %p: x%x",
3275 fct_cmd, fct_cmd->cmd_comp_status);
2799#endif /* FCT_API_TRACE */
2800 MODSYM(fct_send_cmd_done) (fct_cmd,
2801 FCT_SUCCESS, FCT_IOF_FCA_DONE);
3276#endif /* FCT_API_TRACE */
3277 MODSYM(fct_send_cmd_done) (fct_cmd, FCT_SUCCESS,
3278 FCT_IOF_FCA_DONE);
2802 break;
2803
2804 default:
2805 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2806 "emlxs_fct_pkt_comp: Invalid cmd type found. type=%x",
2807 fct_cmd->cmd_type);
3279 break;
3280
3281 default:
3282 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3283 "emlxs_fct_pkt_comp: Invalid cmd type found. type=%x",
3284 fct_cmd->cmd_type);
3285 cmd_sbp->fct_pkt = NULL;
2808
3286
2809 /* mutex_exit(&cmd_sbp->mtx); */
2810 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
3287 mutex_exit(&cmd_sbp->fct_mtx);
2811 }
2812
2813done:
3288 }
3289
3290done:
2814
2815 emlxs_pkt_free(pkt);
3291 emlxs_pkt_free(pkt);
2816
2817 return;
2818
3292 return;
3293
2819} /* emlxs_fct_pkt_comp() */
3294} /* emlxs_fct_pkt_comp() */
2820
2821
3295
3296
3297static void
3298emlxs_fct_abort_pkt_comp(fc_packet_t *pkt)
3299{
3300#ifdef FCT_API_TRACE
3301 emlxs_buf_t *sbp;
3302 IOCBQ *iocbq;
3303 IOCB *iocb;
2822
3304
3305 sbp = PKT2PRIV(pkt);
3306 iocbq = &sbp->iocbq;
3307 iocb = &iocbq->iocb;
3308
3309 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3310 "emlxs_fct_handle_abort: %p: xri=%x status=%x", iocb->ulpContext,
3311 iocb->ulpCommand, iocb->ulpStatus);
3312#endif /* FCT_API_TRACE */
3313
3314 emlxs_pkt_free(pkt);
3315 return;
3316
3317} /* emlxs_fct_abort_pkt_comp() */
3318
3319
2823static fct_status_t
2824emlxs_fct_send_els_cmd(fct_cmd_t *fct_cmd)
2825{
2826 emlxs_port_t *port =
2827 (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
2828 emlxs_hba_t *hba = HBA;
2829 uint32_t did;
2830 fct_els_t *fct_els;
2831 fc_packet_t *pkt;
2832 emlxs_buf_t *cmd_sbp;
2833
3320static fct_status_t
3321emlxs_fct_send_els_cmd(fct_cmd_t *fct_cmd)
3322{
3323 emlxs_port_t *port =
3324 (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
3325 emlxs_hba_t *hba = HBA;
3326 uint32_t did;
3327 fct_els_t *fct_els;
3328 fc_packet_t *pkt;
3329 emlxs_buf_t *cmd_sbp;
3330
2834#if 0
2835 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2836 "emlxs_fct_send_els_cmd() called.");
2837#endif
2838
2839 did = fct_cmd->cmd_rportid;
2840 fct_els = (fct_els_t *)fct_cmd->cmd_specific;
2841
2842 if (!(pkt = emlxs_pkt_alloc(port, fct_els->els_req_size,
2843 fct_els->els_resp_size, 0, KM_NOSLEEP))) {
2844 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
2845 "emlxs_fct_send_els_cmd: Unable to allocate packet.");
2846 return (FCT_FAILURE);
2847 }
3331 did = fct_cmd->cmd_rportid;
3332 fct_els = (fct_els_t *)fct_cmd->cmd_specific;
3333
3334 if (!(pkt = emlxs_pkt_alloc(port, fct_els->els_req_size,
3335 fct_els->els_resp_size, 0, KM_NOSLEEP))) {
3336 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
3337 "emlxs_fct_send_els_cmd: Unable to allocate packet.");
3338 return (FCT_FAILURE);
3339 }
3340
2848 cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd);
3341 cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd);
2849 /* mutex_enter(&cmd_sbp->mtx); */
3342 /* mutex_enter(&cmd_sbp->fct_mtx); */
2850
3343
3344 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_SEND_ELS_REQ);
3345
2851 cmd_sbp->ring = &hba->ring[FC_ELS_RING];
2852 cmd_sbp->fct_type = EMLXS_FCT_ELS_REQ;
3346 cmd_sbp->ring = &hba->ring[FC_ELS_RING];
3347 cmd_sbp->fct_type = EMLXS_FCT_ELS_REQ;
2853 cmd_sbp->fct_state = EMLXS_FCT_REQ_PENDING;
3348 cmd_sbp->did = fct_cmd->cmd_rportid;
2854
2855 (void) emlxs_fct_pkt_init(port, fct_cmd, pkt);
3349
3350 (void) emlxs_fct_pkt_init(port, fct_cmd, pkt);
3351 cmd_sbp->fct_pkt = pkt;
2856
2857 pkt->pkt_tran_type = FC_PKT_EXCHANGE;
2858 pkt->pkt_timeout =
2859 ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov);
2860 pkt->pkt_comp = emlxs_fct_pkt_comp;
2861
2862 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2863 "emlxs_fct_send_els_cmd: pkt_timeout=%d ratov=%d",

--- 12 unchanged lines hidden (view full) ---

2876 pkt->pkt_cmd_fhdr.seq_cnt = 0;
2877 pkt->pkt_cmd_fhdr.ox_id = 0xFFFF;
2878 pkt->pkt_cmd_fhdr.rx_id = 0xFFFF;
2879 pkt->pkt_cmd_fhdr.ro = 0;
2880
2881 /* Copy the cmd payload */
2882 bcopy((uint8_t *)fct_els->els_req_payload, (uint8_t *)pkt->pkt_cmd,
2883 fct_els->els_req_size);
3352
3353 pkt->pkt_tran_type = FC_PKT_EXCHANGE;
3354 pkt->pkt_timeout =
3355 ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov);
3356 pkt->pkt_comp = emlxs_fct_pkt_comp;
3357
3358 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3359 "emlxs_fct_send_els_cmd: pkt_timeout=%d ratov=%d",

--- 12 unchanged lines hidden (view full) ---

3372 pkt->pkt_cmd_fhdr.seq_cnt = 0;
3373 pkt->pkt_cmd_fhdr.ox_id = 0xFFFF;
3374 pkt->pkt_cmd_fhdr.rx_id = 0xFFFF;
3375 pkt->pkt_cmd_fhdr.ro = 0;
3376
3377 /* Copy the cmd payload */
3378 bcopy((uint8_t *)fct_els->els_req_payload, (uint8_t *)pkt->pkt_cmd,
3379 fct_els->els_req_size);
3380 cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP;
2884
3381
2885 mutex_exit(&cmd_sbp->mtx);
2886
2887 if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
2888 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
2889 "emlxs_fct_send_els_cmd: Unable to send packet.");
2890
2891 if (cmd_sbp->pkt_flags & PACKET_VALID) {
2892 mutex_enter(&cmd_sbp->mtx);
2893 cmd_sbp->fct_pkt = NULL;
3382 if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
3383 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
3384 "emlxs_fct_send_els_cmd: Unable to send packet.");
3385
3386 if (cmd_sbp->pkt_flags & PACKET_VALID) {
3387 mutex_enter(&cmd_sbp->mtx);
3388 cmd_sbp->fct_pkt = NULL;
2894 cmd_sbp->fct_state = EMLXS_FCT_REQ_COMPLETE;
2895 cmd_sbp->pkt_flags |= PACKET_RETURNED;
3389 cmd_sbp->pkt_flags |= PACKET_RETURNED;
3390 cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP;
2896 mutex_exit(&cmd_sbp->mtx);
2897 }
3391 mutex_exit(&cmd_sbp->mtx);
3392 }
3393
2898 emlxs_pkt_free(pkt);
3394 emlxs_pkt_free(pkt);
3395
3396 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED);
3397 mutex_exit(&cmd_sbp->fct_mtx);
2899 return (FCT_FAILURE);
2900 }
3398 return (FCT_FAILURE);
3399 }
2901 return (FCT_SUCCESS);
2902
3400
2903} /* emlxs_fct_send_els_cmd() */
2904
2905
2906static fct_status_t
2907emlxs_fct_send_abts_rsp(fct_cmd_t *fct_cmd)
2908{
2909 emlxs_port_t *port =
2910 (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
2911 emlxs_hba_t *hba = HBA;
2912 emlxs_buf_t *cmd_sbp;
2913 IOCBQ *iocbq;
2914
2915 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2916 "emlxs_fct_send_abts_rsp: cmd=%p", fct_cmd);
2917
2918 cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
2919
2920 mutex_enter(&cmd_sbp->mtx);
2921 cmd_sbp->pkt_flags &= ~PACKET_RETURNED;
2922
2923 cmd_sbp->fct_flags |= (EMLXS_FCT_ABORT | EMLXS_FCT_ABORT_COMPLETE);
2924
2925 /* Create the abort IOCB */
2926 if (hba->state >= FC_LINK_UP) {
2927 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2928 "emlxs_fct_send_abts_rsp: Aborting xid=%x. sbp=%p "
2929 "state=%d flags=%x,%x", fct_cmd->cmd_rxid, cmd_sbp,
2930 cmd_sbp->fct_state, cmd_sbp->fct_flags, cmd_sbp->pkt_flags);
2931
2932 iocbq = emlxs_create_abort_xri_cx(port, cmd_sbp->node,
2933 fct_cmd->cmd_rxid, cmd_sbp->ring, cmd_sbp->class,
2934 ABORT_TYPE_ABTS);
2935 } else {
2936 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2937 "emlxs_fct_send_abts_rsp: Closing xid=%x. sbp=%p state=%d "
2938 "flags=%x,%x", fct_cmd->cmd_rxid, cmd_sbp,
2939 cmd_sbp->fct_state, cmd_sbp->fct_flags, cmd_sbp->pkt_flags);
2940
2941 iocbq = emlxs_create_close_xri_cx(port, cmd_sbp->node,
2942 fct_cmd->cmd_rxid, cmd_sbp->ring);
2943 }
2944
2945 cmd_sbp->abort_attempts++;
2946 emlxs_issue_iocb_cmd(hba, cmd_sbp->ring, iocbq);
2947
2948 /* mutex_exit(&cmd_sbp->mtx); */
2949 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
2950
2951 fct_cmd->cmd_comp_status = FCT_SUCCESS;
2952#ifdef FCT_API_TRACE
2953 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
2954 "fct_send_response_done:4 %p: x%x",
2955 fct_cmd, fct_cmd->cmd_comp_status);
2956#endif /* FCT_API_TRACE */
2957 MODSYM(fct_send_response_done) (fct_cmd,
2958 fct_cmd->cmd_comp_status, FCT_IOF_FCA_DONE);
2959
3401 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_REQ_PENDING);
3402 mutex_exit(&cmd_sbp->fct_mtx);
2960 return (FCT_SUCCESS);
2961
3403 return (FCT_SUCCESS);
3404
2962} /* emlxs_fct_send_abts_rsp() */
3405} /* emlxs_fct_send_els_cmd() */
2963
2964
2965static fct_status_t
2966emlxs_fct_send_els_rsp(fct_cmd_t *fct_cmd)
2967{
2968 emlxs_port_t *port =
2969 (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
2970 emlxs_hba_t *hba = HBA;
2971 uint32_t did;
2972 fct_els_t *fct_els;
2973 fc_packet_t *pkt;
2974 emlxs_buf_t *cmd_sbp;
2975
3406
3407
3408static fct_status_t
3409emlxs_fct_send_els_rsp(fct_cmd_t *fct_cmd)
3410{
3411 emlxs_port_t *port =
3412 (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
3413 emlxs_hba_t *hba = HBA;
3414 uint32_t did;
3415 fct_els_t *fct_els;
3416 fc_packet_t *pkt;
3417 emlxs_buf_t *cmd_sbp;
3418
2976#if 0
2977 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2978 "emlxs_fct_send_els_rsp: cmd=%p", fct_cmd);
2979#endif
2980
2981 fct_els = (fct_els_t *)fct_cmd->cmd_specific;
2982 did = fct_cmd->cmd_rportid;
2983
3419 fct_els = (fct_els_t *)fct_cmd->cmd_specific;
3420 did = fct_cmd->cmd_rportid;
3421
2984 if (!(pkt =
2985 emlxs_pkt_alloc(port, fct_els->els_resp_size, 0, 0, KM_NOSLEEP))) {
3422 if (!(pkt = emlxs_pkt_alloc(port, fct_els->els_resp_size, 0, 0,
3423 KM_NOSLEEP))) {
2986 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
2987 "emlxs_fct_send_els_rsp: Unable to allocate packet.");
2988 return (FCT_FAILURE);
2989 }
3424 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
3425 "emlxs_fct_send_els_rsp: Unable to allocate packet.");
3426 return (FCT_FAILURE);
3427 }
3428
2990 cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
2991
3429 cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
3430
3431 mutex_enter(&cmd_sbp->fct_mtx);
3432 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_SEND_ELS_RSP);
3433
2992 mutex_enter(&cmd_sbp->mtx);
2993 cmd_sbp->pkt_flags &= ~PACKET_RETURNED;
3434 mutex_enter(&cmd_sbp->mtx);
3435 cmd_sbp->pkt_flags &= ~PACKET_RETURNED;
3436 mutex_exit(&cmd_sbp->mtx);
2994
2995 cmd_sbp->fct_type = EMLXS_FCT_ELS_RSP;
3437
3438 cmd_sbp->fct_type = EMLXS_FCT_ELS_RSP;
2996 cmd_sbp->fct_state = EMLXS_FCT_RSP_PENDING;
2997
2998 (void) emlxs_fct_pkt_init(port, fct_cmd, pkt);
3439
3440 (void) emlxs_fct_pkt_init(port, fct_cmd, pkt);
3441 cmd_sbp->fct_pkt = pkt;
2999
3000 pkt->pkt_tran_type = FC_PKT_OUTBOUND;
3001 pkt->pkt_timeout =
3002 ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov);
3003 pkt->pkt_comp = emlxs_fct_pkt_comp;
3004
3005 /* Build the fc header */
3006 pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(did);

--- 7 unchanged lines hidden (view full) ---

3014 pkt->pkt_cmd_fhdr.seq_cnt = 0;
3015 pkt->pkt_cmd_fhdr.ox_id = fct_cmd->cmd_oxid;
3016 pkt->pkt_cmd_fhdr.rx_id = fct_cmd->cmd_rxid;
3017 pkt->pkt_cmd_fhdr.ro = 0;
3018
3019 /* Copy the resp payload to pkt_cmd buffer */
3020 bcopy((uint8_t *)fct_els->els_resp_payload, (uint8_t *)pkt->pkt_cmd,
3021 fct_els->els_resp_size);
3442
3443 pkt->pkt_tran_type = FC_PKT_OUTBOUND;
3444 pkt->pkt_timeout =
3445 ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov);
3446 pkt->pkt_comp = emlxs_fct_pkt_comp;
3447
3448 /* Build the fc header */
3449 pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(did);

--- 7 unchanged lines hidden (view full) ---

3457 pkt->pkt_cmd_fhdr.seq_cnt = 0;
3458 pkt->pkt_cmd_fhdr.ox_id = fct_cmd->cmd_oxid;
3459 pkt->pkt_cmd_fhdr.rx_id = fct_cmd->cmd_rxid;
3460 pkt->pkt_cmd_fhdr.ro = 0;
3461
3462 /* Copy the resp payload to pkt_cmd buffer */
3463 bcopy((uint8_t *)fct_els->els_resp_payload, (uint8_t *)pkt->pkt_cmd,
3464 fct_els->els_resp_size);
3465 cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP;
3022
3466
3023 mutex_exit(&cmd_sbp->mtx);
3024
3025 if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
3026 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
3027 "emlxs_fct_send_els_rsp: Unable to send packet.");
3028
3029 if (cmd_sbp->pkt_flags & PACKET_VALID) {
3030 mutex_enter(&cmd_sbp->mtx);
3031 cmd_sbp->fct_pkt = NULL;
3467 if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
3468 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
3469 "emlxs_fct_send_els_rsp: Unable to send packet.");
3470
3471 if (cmd_sbp->pkt_flags & PACKET_VALID) {
3472 mutex_enter(&cmd_sbp->mtx);
3473 cmd_sbp->fct_pkt = NULL;
3032 cmd_sbp->fct_state = EMLXS_FCT_RSP_COMPLETE;
3033 cmd_sbp->pkt_flags |= PACKET_RETURNED;
3474 cmd_sbp->pkt_flags |= PACKET_RETURNED;
3475 cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP;
3034 mutex_exit(&cmd_sbp->mtx);
3035 }
3476 mutex_exit(&cmd_sbp->mtx);
3477 }
3478
3036 emlxs_pkt_free(pkt);
3479 emlxs_pkt_free(pkt);
3480
3481 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED);
3482 mutex_exit(&cmd_sbp->fct_mtx);
3037 return (FCT_FAILURE);
3038 }
3483 return (FCT_FAILURE);
3484 }
3485
3486 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_RSP_PENDING);
3487 mutex_exit(&cmd_sbp->fct_mtx);
3039 return (FCT_SUCCESS);
3040
3488 return (FCT_SUCCESS);
3489
3041} /* emlxs_fct_send_els_rsp() */
3490} /* emlxs_fct_send_els_rsp() */
3042
3043
3491
3492
3044
3045static fct_status_t
3046emlxs_fct_send_ct_cmd(fct_cmd_t *fct_cmd)
3047{
3048 emlxs_port_t *port =
3049 (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
3050 emlxs_hba_t *hba = HBA;
3051 uint32_t did;
3052 fct_sol_ct_t *fct_ct;
3053 fc_packet_t *pkt;
3054 emlxs_buf_t *cmd_sbp;
3055
3493static fct_status_t
3494emlxs_fct_send_ct_cmd(fct_cmd_t *fct_cmd)
3495{
3496 emlxs_port_t *port =
3497 (emlxs_port_t *)fct_cmd->cmd_port->port_fca_private;
3498 emlxs_hba_t *hba = HBA;
3499 uint32_t did;
3500 fct_sol_ct_t *fct_ct;
3501 fc_packet_t *pkt;
3502 emlxs_buf_t *cmd_sbp;
3503
3056#if 0
3057 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3058 "emlxs_fct_send_ct_cmd() called.");
3059#endif
3060
3061 did = fct_cmd->cmd_rportid;
3062 fct_ct = (fct_sol_ct_t *)fct_cmd->cmd_specific;
3063
3064 if (!(pkt = emlxs_pkt_alloc(port, fct_ct->ct_req_size,
3065 fct_ct->ct_resp_size, 0, KM_NOSLEEP))) {
3066 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
3067 "emlxs_fct_send_ct_cmd: Unable to allocate packet.");
3068 return (FCT_FAILURE);
3069 }
3504 did = fct_cmd->cmd_rportid;
3505 fct_ct = (fct_sol_ct_t *)fct_cmd->cmd_specific;
3506
3507 if (!(pkt = emlxs_pkt_alloc(port, fct_ct->ct_req_size,
3508 fct_ct->ct_resp_size, 0, KM_NOSLEEP))) {
3509 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
3510 "emlxs_fct_send_ct_cmd: Unable to allocate packet.");
3511 return (FCT_FAILURE);
3512 }
3513
3070 cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd);
3514 cmd_sbp = emlxs_fct_cmd_init(port, fct_cmd);
3071 /* mutex_enter(&cmd_sbp->mtx); */
3515 /* mutex_enter(&cmd_sbp->fct_mtx); */
3072
3516
3517 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_SEND_CT_REQ);
3073 cmd_sbp->ring = &hba->ring[FC_CT_RING];
3074 cmd_sbp->fct_type = EMLXS_FCT_CT_REQ;
3518 cmd_sbp->ring = &hba->ring[FC_CT_RING];
3519 cmd_sbp->fct_type = EMLXS_FCT_CT_REQ;
3075 cmd_sbp->fct_state = EMLXS_FCT_REQ_PENDING;
3520 cmd_sbp->did = fct_cmd->cmd_rportid;
3076
3077 (void) emlxs_fct_pkt_init(port, fct_cmd, pkt);
3521
3522 (void) emlxs_fct_pkt_init(port, fct_cmd, pkt);
3523 cmd_sbp->fct_pkt = pkt;
3078
3079 pkt->pkt_tran_type = FC_PKT_EXCHANGE;
3080 pkt->pkt_timeout =
3081 ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov);
3082 pkt->pkt_comp = emlxs_fct_pkt_comp;
3083
3084 /* Build the fc header */
3085 pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(did);

--- 7 unchanged lines hidden (view full) ---

3093 pkt->pkt_cmd_fhdr.seq_cnt = 0;
3094 pkt->pkt_cmd_fhdr.ox_id = 0xFFFF;
3095 pkt->pkt_cmd_fhdr.rx_id = 0xFFFF;
3096 pkt->pkt_cmd_fhdr.ro = 0;
3097
3098 /* Copy the cmd payload */
3099 bcopy((uint8_t *)fct_ct->ct_req_payload, (uint8_t *)pkt->pkt_cmd,
3100 fct_ct->ct_req_size);
3524
3525 pkt->pkt_tran_type = FC_PKT_EXCHANGE;
3526 pkt->pkt_timeout =
3527 ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov);
3528 pkt->pkt_comp = emlxs_fct_pkt_comp;
3529
3530 /* Build the fc header */
3531 pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(did);

--- 7 unchanged lines hidden (view full) ---

3539 pkt->pkt_cmd_fhdr.seq_cnt = 0;
3540 pkt->pkt_cmd_fhdr.ox_id = 0xFFFF;
3541 pkt->pkt_cmd_fhdr.rx_id = 0xFFFF;
3542 pkt->pkt_cmd_fhdr.ro = 0;
3543
3544 /* Copy the cmd payload */
3545 bcopy((uint8_t *)fct_ct->ct_req_payload, (uint8_t *)pkt->pkt_cmd,
3546 fct_ct->ct_req_size);
3547 cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP;
3101
3548
3102 mutex_exit(&cmd_sbp->mtx);
3103
3104 if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
3105 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
3106 "emlxs_fct_send_ct_cmd: Unable to send packet.");
3107
3108 if (cmd_sbp->pkt_flags & PACKET_VALID) {
3109 mutex_enter(&cmd_sbp->mtx);
3110 cmd_sbp->fct_pkt = NULL;
3549 if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
3550 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
3551 "emlxs_fct_send_ct_cmd: Unable to send packet.");
3552
3553 if (cmd_sbp->pkt_flags & PACKET_VALID) {
3554 mutex_enter(&cmd_sbp->mtx);
3555 cmd_sbp->fct_pkt = NULL;
3111 cmd_sbp->fct_state = EMLXS_FCT_REQ_COMPLETE;
3112 cmd_sbp->pkt_flags |= PACKET_RETURNED;
3556 cmd_sbp->pkt_flags |= PACKET_RETURNED;
3557 cmd_sbp->fct_flags &= ~EMLXS_FCT_IO_INP;
3113 mutex_exit(&cmd_sbp->mtx);
3114 }
3558 mutex_exit(&cmd_sbp->mtx);
3559 }
3560
3115 emlxs_pkt_free(pkt);
3561 emlxs_pkt_free(pkt);
3562
3563 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED);
3564 mutex_exit(&cmd_sbp->fct_mtx);
3116 return (FCT_FAILURE);
3117 }
3565 return (FCT_FAILURE);
3566 }
3118 return (FCT_SUCCESS);
3119
3567
3120} /* emlxs_fct_send_ct_cmd() */
3121
3122
3123/* FCT_NOT_FOUND & FCT_ABORT_SUCCESS indicates IO is done */
3124/* FCT_SUCCESS indicates abort will occur asyncronously */
3125static fct_status_t
3126emlxs_fct_abort(fct_local_port_t *fct_port, fct_cmd_t *fct_cmd, uint32_t flags)
3127{
3128 emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
3129 emlxs_hba_t *hba = HBA;
3130 emlxs_buf_t *cmd_sbp;
3131 uint32_t pkt_flags = 0;
3132 emlxs_buf_t *sbp = NULL;
3133 IOCBQ *iocbq;
3134 fct_status_t rval;
3135
3136 cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
3137
3138 if (!(cmd_sbp->pkt_flags & PACKET_VALID)) {
3139 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3140 "emlxs_fct_abort: Invalid cmd_sbp=%p.", cmd_sbp);
3141
3142 return (FCT_NOT_FOUND);
3143 }
3144 mutex_enter(&cmd_sbp->mtx);
3145
3146 if (!(cmd_sbp->pkt_flags & PACKET_VALID)) {
3147 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3148 "emlxs_fct_abort: Invalid cmd_sbp=%p.", cmd_sbp);
3149
3150 mutex_exit(&cmd_sbp->mtx);
3151 return (FCT_NOT_FOUND);
3152 }
3153 if (flags & FCT_IOF_FORCE_FCA_DONE) {
3154 fct_cmd->cmd_handle = 0;
3155 }
3156 TGTPORTSTAT.FctAbortSent++;
3157 TGTPORTSTAT.FctOutstandingIO--;
3158
3159 switch (cmd_sbp->fct_state) {
3160 case 0:
3161 case EMLXS_FCT_REQ_CREATED:
3162 case EMLXS_FCT_REG_PENDING:
3163
3164 case EMLXS_FCT_REG_COMPLETE:
3165 case EMLXS_FCT_REQ_COMPLETE:
3166 case EMLXS_FCT_DATA_COMPLETE:
3167 case EMLXS_FCT_STATUS_COMPLETE:
3168 case EMLXS_FCT_RSP_COMPLETE:
3169
3170 cmd_sbp->fct_flags |=
3171 (EMLXS_FCT_ABORT | EMLXS_FCT_ABORT_COMPLETE);
3172
3173 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3174 "emlxs_fct_abort: Aborted. cmd_sbp=%p state=%d "
3175 "flags=%x,%x,%x,%x", cmd_sbp, cmd_sbp->fct_state,
3176 flags, cmd_sbp->fct_flags, cmd_sbp->pkt_flags, pkt_flags);
3177
3178 /* mutex_exit(&cmd_sbp->mtx); */
3179 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
3180
3181 fct_cmd->cmd_comp_status = FCT_ABORT_SUCCESS;
3182 return (FCT_ABORT_SUCCESS);
3183
3184
3185 case EMLXS_FCT_CMD_RECEIVED:
3186
3187 cmd_sbp->fct_flags |=
3188 (EMLXS_FCT_ABORT | EMLXS_FCT_ABORT_COMPLETE);
3189
3190 /* Create the abort IOCB */
3191 if (hba->state >= FC_LINK_UP) {
3192 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3193 "emlxs_fct_abort: Aborted. xid=%x. cmd_sbp=%p "
3194 "state=%d flags=%x,%x,%x", fct_cmd->cmd_rxid,
3195 cmd_sbp, cmd_sbp->fct_state, flags,
3196 cmd_sbp->fct_flags, cmd_sbp->pkt_flags);
3197
3198 iocbq = emlxs_create_abort_xri_cx(port, cmd_sbp->node,
3199 fct_cmd->cmd_rxid, cmd_sbp->ring, cmd_sbp->class,
3200 ABORT_TYPE_ABTS);
3201 } else {
3202 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3203 "emlxs_fct_abort: Closed. xid=%x. cmd_sbp=%p "
3204 "state=%d flags=%x,%x,%x", fct_cmd->cmd_rxid,
3205 cmd_sbp, cmd_sbp->fct_state, flags,
3206 cmd_sbp->fct_flags, cmd_sbp->pkt_flags);
3207
3208 iocbq = emlxs_create_close_xri_cx(port, cmd_sbp->node,
3209 fct_cmd->cmd_rxid, cmd_sbp->ring);
3210 }
3211
3212 cmd_sbp->abort_attempts++;
3213 emlxs_issue_iocb_cmd(hba, cmd_sbp->ring, iocbq);
3214
3215 /* mutex_exit(&cmd_sbp->mtx); */
3216 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
3217
3218 fct_cmd->cmd_comp_status = FCT_ABORT_SUCCESS;
3219 return (FCT_ABORT_SUCCESS);
3220
3221
3222 case EMLXS_FCT_REQ_PENDING:
3223 case EMLXS_FCT_STATUS_PENDING:
3224 case EMLXS_FCT_RSP_PENDING:
3225
3226 sbp = (emlxs_buf_t *)cmd_sbp->fct_pkt->pkt_fca_private;
3227 cmd_sbp->fct_flags |= EMLXS_FCT_ABORT;
3228 mutex_exit(&cmd_sbp->mtx);
3229
3230 (void) emlxs_fct_pkt_abort(port, sbp);
3231
3232 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3233 "emlxs_fct_abort: Aborted. cmd_sbp=%p state=%d "
3234 "flags=%x,%x,%x", cmd_sbp, cmd_sbp->fct_state, flags,
3235 cmd_sbp->fct_flags, cmd_sbp->pkt_flags);
3236
3237 if (cmd_sbp->pkt_flags & PACKET_VALID) {
3238 mutex_enter(&cmd_sbp->mtx);
3239 /* mutex_exit(&cmd_sbp->mtx); */
3240 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
3241 }
3242 fct_cmd->cmd_comp_status = FCT_ABORT_SUCCESS;
3243 return (FCT_ABORT_SUCCESS);
3244
3245 case EMLXS_FCT_DATA_PENDING:
3246
3247 if ((cmd_sbp->pkt_flags & (PACKET_IN_COMPLETION |
3248 PACKET_IN_FLUSH | PACKET_IN_TIMEOUT))) {
3249 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3250 "emlxs_fct_abort: Completing. cmd_sbp=%p state=%d "
3251 "flags=%x,%x,%x", cmd_sbp, cmd_sbp->fct_state,
3252 flags, cmd_sbp->fct_flags, cmd_sbp->pkt_flags);
3253
3254 mutex_exit(&cmd_sbp->mtx);
3255 return (FCT_NOT_FOUND);
3256 }
3257 cmd_sbp->fct_flags |= EMLXS_FCT_ABORT;
3258 mutex_exit(&cmd_sbp->mtx);
3259
3260 rval = emlxs_fct_pkt_abort(port, cmd_sbp);
3261
3262 if (rval == FCT_ABORT_SUCCESS) {
3263 fct_cmd->cmd_comp_status = FCT_ABORT_SUCCESS;
3264
3265 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3266 "emlxs_fct_abort: Aborted. cmd_sbp=%p state=%d "
3267 "flags=%x,%x,%x", cmd_sbp, cmd_sbp->fct_state,
3268 flags, cmd_sbp->fct_flags, cmd_sbp->pkt_flags);
3269
3270 if (cmd_sbp->pkt_flags & PACKET_VALID) {
3271 mutex_enter(&cmd_sbp->mtx);
3272 /* mutex_exit(&cmd_sbp->mtx); */
3273 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
3274 }
3275 } else {
3276 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3277 "emlxs_fct_abort: Not found. cmd_sbp=%p state=%d "
3278 "flags=%x,%x,%x", cmd_sbp, cmd_sbp->fct_state,
3279 flags, cmd_sbp->fct_flags, cmd_sbp->pkt_flags);
3280 }
3281
3282 return (rval);
3283
3284 } /* switch */
3285
3568 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_REQ_PENDING);
3569 mutex_exit(&cmd_sbp->fct_mtx);
3286 return (FCT_SUCCESS);
3287
3570 return (FCT_SUCCESS);
3571
3288} /* emlxs_fct_abort() */
3572} /* emlxs_fct_send_ct_cmd() */
3289
3290
3573
3574
3291/* Returns FCT_ABORT_SUCCESS or FCT_NOT_FOUND */
3292static fct_status_t
3293emlxs_fct_pkt_abort(emlxs_port_t *port, emlxs_buf_t *sbp)
3575uint32_t
3576emlxs_fct_pkt_abort_txq(emlxs_port_t *port, emlxs_buf_t *cmd_sbp)
3294{
3295 emlxs_hba_t *hba = HBA;
3577{
3578 emlxs_hba_t *hba = HBA;
3296
3297 NODELIST *nlp;
3579 NODELIST *nlp;
3580 fc_packet_t *pkt;
3581 emlxs_buf_t *sbp;
3582 emlxs_buf_t *iocb_sbp;
3298 uint8_t ringno;
3299 RING *rp;
3583 uint8_t ringno;
3584 RING *rp;
3300 clock_t timeout;
3301 clock_t time;
3302 int32_t pkt_ret;
3303 IOCBQ *iocbq;
3304 IOCBQ *next;
3305 IOCBQ *prev;
3306 uint32_t found;
3585 IOCBQ *iocbq;
3586 IOCBQ *next;
3587 IOCBQ *prev;
3588 uint32_t found;
3307 uint32_t att_bit;
3308 uint32_t pass = 0;
3309 fct_cmd_t *fct_cmd;
3310 emlxs_buf_t *cmd_sbp;
3589 uint32_t pkt_flags;
3590 uint32_t rval = 0;
3311
3591
3312 fct_cmd = sbp->fct_cmd;
3313 cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
3592 /* Check the transmit queue */
3593 mutex_enter(&EMLXS_RINGTX_LOCK);
3314
3594
3315 iocbq = &sbp->iocbq;
3316 nlp = (NODELIST *)sbp->node;
3317 rp = (RING *)sbp->ring;
3318 ringno = (rp) ? rp->ringno : 0;
3319
3320 /* Check packet */
3321 if (!(sbp->pkt_flags & PACKET_VALID) ||
3322 (sbp->pkt_flags & PACKET_RETURNED)) {
3323 /*
3324 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3325 * "emlxs_fct_pkt_abort: 1. sbp=%p flags=%x,%x", sbp,
3326 * cmd_sbp->fct_flags, sbp->pkt_flags);
3327 */
3328
3329 return (FCT_NOT_FOUND);
3595 /* The IOCB could point to a cmd_sbp (no packet) or a sbp (packet) */
3596 pkt = cmd_sbp->fct_pkt;
3597 if (pkt) {
3598 sbp = PKT2PRIV(pkt);
3599 if (sbp == NULL) {
3600 goto done;
3601 }
3602 iocb_sbp = sbp;
3603 iocbq = &sbp->iocbq;
3604 pkt_flags = sbp->pkt_flags;
3605 } else {
3606 sbp = NULL;
3607 iocb_sbp = cmd_sbp;
3608 iocbq = &cmd_sbp->iocbq;
3609 pkt_flags = cmd_sbp->pkt_flags;
3330 }
3610 }
3331 mutex_enter(&sbp->mtx);
3332
3611
3333 /* Check again if we still own this */
3334 if (!(sbp->pkt_flags & PACKET_VALID) ||
3335 (sbp->pkt_flags & PACKET_RETURNED)) {
3336 /*
3337 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3338 * "emlxs_fct_pkt_abort: 2. sbp=%p flags=%x,%x", sbp,
3339 * cmd_sbp->fct_flags, sbp->pkt_flags);
3340 */
3612 nlp = (NODELIST *)cmd_sbp->node;
3613 rp = (RING *)cmd_sbp->ring;
3614 ringno = (rp) ? rp->ringno : 0;
3341
3615
3342 mutex_exit(&sbp->mtx);
3343 return (FCT_NOT_FOUND);
3344 }
3345 sbp->pkt_flags |= PACKET_IN_ABORT;
3346
3347 /* Check again if we still own this */
3348 if (sbp->pkt_flags &
3349 (PACKET_IN_COMPLETION | PACKET_IN_FLUSH | PACKET_IN_TIMEOUT)) {
3350 /*
3351 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3352 * "emlxs_fct_pkt_abort: 3. sbp=%p flags=%x,%x", sbp,
3353 * cmd_sbp->fct_flags, sbp->pkt_flags);
3354 */
3355
3356 mutex_exit(&sbp->mtx);
3357 goto done;
3358 }
3359 mutex_exit(&sbp->mtx);
3360
3361begin:
3362 pass++;
3363
3364 /* Check the transmit queue */
3365 mutex_enter(&EMLXS_RINGTX_LOCK);
3366
3367 if (sbp->pkt_flags & PACKET_IN_TXQ) {
3616 if (pkt_flags & PACKET_IN_TXQ) {
3368 /* Find it on the queue */
3369 found = 0;
3370 if (iocbq->flag & IOCB_PRIORITY) {
3371 /* Search the priority queue */
3372 prev = NULL;
3373 next = (IOCBQ *)nlp->nlp_ptx[ringno].q_first;
3374
3375 while (next) {
3376 if (next == iocbq) {
3377 /* Remove it */
3378 if (prev) {
3379 prev->next = iocbq->next;
3380 }
3617 /* Find it on the queue */
3618 found = 0;
3619 if (iocbq->flag & IOCB_PRIORITY) {
3620 /* Search the priority queue */
3621 prev = NULL;
3622 next = (IOCBQ *)nlp->nlp_ptx[ringno].q_first;
3623
3624 while (next) {
3625 if (next == iocbq) {
3626 /* Remove it */
3627 if (prev) {
3628 prev->next = iocbq->next;
3629 }
3630
3381 if (nlp->nlp_ptx[ringno].q_last ==
3382 (void *)iocbq) {
3383 nlp->nlp_ptx[ringno].q_last =
3384 (void *)prev;
3385 }
3631 if (nlp->nlp_ptx[ringno].q_last ==
3632 (void *)iocbq) {
3633 nlp->nlp_ptx[ringno].q_last =
3634 (void *)prev;
3635 }
3636
3386 if (nlp->nlp_ptx[ringno].q_first ==
3387 (void *)iocbq) {
3388 nlp->nlp_ptx[ringno].q_first =
3389 (void *)iocbq->next;
3390 }
3637 if (nlp->nlp_ptx[ringno].q_first ==
3638 (void *)iocbq) {
3639 nlp->nlp_ptx[ringno].q_first =
3640 (void *)iocbq->next;
3641 }
3642
3391 nlp->nlp_ptx[ringno].q_cnt--;
3392 iocbq->next = NULL;
3393 found = 1;
3394 break;
3395 }
3643 nlp->nlp_ptx[ringno].q_cnt--;
3644 iocbq->next = NULL;
3645 found = 1;
3646 break;
3647 }
3648
3396 prev = next;
3397 next = next->next;
3398 }
3399 } else {
3400 /* Search the normal queue */
3401 prev = NULL;
3402 next = (IOCBQ *)nlp->nlp_tx[ringno].q_first;
3403
3404 while (next) {
3405 if (next == iocbq) {
3406 /* Remove it */
3407 if (prev) {
3408 prev->next = iocbq->next;
3409 }
3649 prev = next;
3650 next = next->next;
3651 }
3652 } else {
3653 /* Search the normal queue */
3654 prev = NULL;
3655 next = (IOCBQ *)nlp->nlp_tx[ringno].q_first;
3656
3657 while (next) {
3658 if (next == iocbq) {
3659 /* Remove it */
3660 if (prev) {
3661 prev->next = iocbq->next;
3662 }
3663
3410 if (nlp->nlp_tx[ringno].q_last ==
3411 (void *)iocbq) {
3412 nlp->nlp_tx[ringno].q_last =
3413 (void *)prev;
3414 }
3664 if (nlp->nlp_tx[ringno].q_last ==
3665 (void *)iocbq) {
3666 nlp->nlp_tx[ringno].q_last =
3667 (void *)prev;
3668 }
3669
3415 if (nlp->nlp_tx[ringno].q_first ==
3416 (void *)iocbq) {
3417 nlp->nlp_tx[ringno].q_first =
3418 (void *)iocbq->next;
3419 }
3670 if (nlp->nlp_tx[ringno].q_first ==
3671 (void *)iocbq) {
3672 nlp->nlp_tx[ringno].q_first =
3673 (void *)iocbq->next;
3674 }
3675
3420 nlp->nlp_tx[ringno].q_cnt--;
3421 iocbq->next = NULL;
3422 found = 1;
3423 break;
3424 }
3676 nlp->nlp_tx[ringno].q_cnt--;
3677 iocbq->next = NULL;
3678 found = 1;
3679 break;
3680 }
3681
3425 prev = next;
3426 next = (IOCBQ *)next->next;
3427 }
3428 }
3429
3430 if (!found) {
3682 prev = next;
3683 next = (IOCBQ *)next->next;
3684 }
3685 }
3686
3687 if (!found) {
3431 /*
3432 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3433 * "emlxs_fct_pkt_abort: 4. sbp=%p flags=%x,%x", sbp,
3434 * cmd_sbp->fct_flags, sbp->pkt_flags);
3435 */
3436
3437 goto done;
3438 }
3688 goto done;
3689 }
3690
3439 /* Check if node still needs servicing */
3440 if ((nlp->nlp_ptx[ringno].q_first) ||
3441 (nlp->nlp_tx[ringno].q_first &&
3442 !(nlp->nlp_flag[ringno] & NLP_CLOSED))) {
3443
3444 /*
3691 /* Check if node still needs servicing */
3692 if ((nlp->nlp_ptx[ringno].q_first) ||
3693 (nlp->nlp_tx[ringno].q_first &&
3694 !(nlp->nlp_flag[ringno] & NLP_CLOSED))) {
3695
3696 /*
3445 * If this is the base node, then don't shift the
3446 * pointers
3697 * If this is the base node, don't shift the pointers
3447 */
3448 /* We want to drain the base node before moving on */
3449 if (!nlp->nlp_base) {
3698 */
3699 /* We want to drain the base node before moving on */
3700 if (!nlp->nlp_base) {
3450 /*
3451 * Just shift ring queue pointers to next
3452 * node
3453 */
3701 /* Shift ring queue pointers to next node */
3454 rp->nodeq.q_last = (void *)nlp;
3455 rp->nodeq.q_first = nlp->nlp_next[ringno];
3456 }
3457 } else {
3458 /* Remove node from ring queue */
3459
3460 /* If this is the last node on list */
3461 if (rp->nodeq.q_last == (void *)nlp) {

--- 7 unchanged lines hidden (view full) ---

3469 nlp_next[ringno] = rp->nodeq.q_first;
3470 rp->nodeq.q_cnt--;
3471 }
3472
3473 /* Clear node */
3474 nlp->nlp_next[ringno] = NULL;
3475 }
3476
3702 rp->nodeq.q_last = (void *)nlp;
3703 rp->nodeq.q_first = nlp->nlp_next[ringno];
3704 }
3705 } else {
3706 /* Remove node from ring queue */
3707
3708 /* If this is the last node on list */
3709 if (rp->nodeq.q_last == (void *)nlp) {

--- 7 unchanged lines hidden (view full) ---

3717 nlp_next[ringno] = rp->nodeq.q_first;
3718 rp->nodeq.q_cnt--;
3719 }
3720
3721 /* Clear node */
3722 nlp->nlp_next[ringno] = NULL;
3723 }
3724
3477 mutex_enter(&sbp->mtx);
3725 /* The IOCB points to a cmd_sbp (no packet) or a sbp (packet) */
3726 mutex_enter(&iocb_sbp->mtx);
3478
3727
3479 if (sbp->pkt_flags & PACKET_IN_TXQ) {
3480 sbp->pkt_flags &= ~PACKET_IN_TXQ;
3728 if (iocb_sbp->pkt_flags & PACKET_IN_TXQ) {
3729 iocb_sbp->pkt_flags &= ~PACKET_IN_TXQ;
3481 hba->ring_tx_count[ringno]--;
3482 }
3730 hba->ring_tx_count[ringno]--;
3731 }
3483 mutex_exit(&sbp->mtx);
3484
3732
3485 (void) emlxs_unregister_pkt(rp, sbp->iotag, 0);
3733 mutex_exit(&iocb_sbp->mtx);
3486
3734
3735 (void) emlxs_unregister_pkt(rp, iocb_sbp->iotag, 0);
3736
3487 mutex_exit(&EMLXS_RINGTX_LOCK);
3488
3737 mutex_exit(&EMLXS_RINGTX_LOCK);
3738
3489 /*
3490 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3491 * "emlxs_fct_pkt_abort: 5. sbp=%p flags=%x,%x", sbp,
3492 * cmd_sbp->fct_flags, sbp->pkt_flags);
3493 */
3739 rval = 1;
3494
3740
3495 /* Now complete it */
3496 if (sbp->pkt) {
3497 emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
3498 IOERR_ABORT_REQUESTED, 1);
3741 if (pkt) {
3742 emlxs_pkt_free(pkt);
3743 cmd_sbp->fct_pkt = NULL;
3499 }
3744 }
3500 goto done;
3745 return (rval);
3501 }
3746 }
3747done:
3502 mutex_exit(&EMLXS_RINGTX_LOCK);
3748 mutex_exit(&EMLXS_RINGTX_LOCK);
3749 return (rval);
3750}
3503
3504
3751
3752
3505 /* Check the chip queue */
3506 mutex_enter(&EMLXS_FCTAB_LOCK(ringno));
3753/* FCT_NOT_FOUND & FCT_ABORT_SUCCESS indicates IO is done */
3754/* FCT_SUCCESS indicates abort will occur asyncronously */
3755static fct_status_t
3756emlxs_fct_abort(fct_local_port_t *fct_port, fct_cmd_t *fct_cmd,
3757 uint32_t flags)
3758{
3759 emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
3760 emlxs_hba_t *hba = HBA;
3761 emlxs_buf_t *cmd_sbp;
3762 fc_packet_t *pkt;
3763 uint32_t state;
3764 emlxs_buf_t *sbp = NULL;
3765 fct_status_t rval;
3507
3766
3508 if ((sbp->pkt_flags & PACKET_IN_CHIPQ) &&
3509 !(sbp->pkt_flags & PACKET_XRI_CLOSED) &&
3510 (sbp == rp->fc_table[sbp->iotag])) {
3511 /* Create the abort IOCB */
3512 if (hba->state >= FC_LINK_UP) {
3513 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3514 "emlxs_fct_pkt_abort: Aborting. sbp=%p "
3515 "flags=%x,%x", sbp, cmd_sbp->fct_flags,
3516 sbp->pkt_flags);
3767top:
3768 /* Sanity check */
3769 if ((fct_cmd->cmd_oxid == 0) && (fct_cmd->cmd_rxid == 0)) {
3770 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3771 "emlxs_fct_abort: Invalid fct_cmd=%p.", fct_cmd);
3517
3772
3518 iocbq = emlxs_create_abort_xri_cn(port, sbp->node,
3519 sbp->iotag, rp, sbp->class, ABORT_TYPE_ABTS);
3773 return (FCT_NOT_FOUND);
3774 }
3520
3775
3521 mutex_enter(&sbp->mtx);
3522 sbp->pkt_flags |= PACKET_XRI_CLOSED;
3523 sbp->ticks = hba->timer_tics + (4 * hba->fc_ratov) + 10;
3524 sbp->abort_attempts++;
3525 mutex_exit(&sbp->mtx);
3526 } else {
3527 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3528 "emlxs_fct_pkt_abort: Closing. sbp=%p flags=%x,%x",
3529 sbp, cmd_sbp->fct_flags, sbp->pkt_flags);
3776 cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private;
3777 if (!(cmd_sbp->pkt_flags & PACKET_VALID)) {
3778 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3779 "emlxs_fct_abort: Invalid cmd_sbp=%p.", cmd_sbp);
3530
3780
3531 iocbq = emlxs_create_close_xri_cn(port, sbp->node,
3532 sbp->iotag, rp);
3533
3534 mutex_enter(&sbp->mtx);
3535 sbp->pkt_flags |= PACKET_XRI_CLOSED;
3536 sbp->ticks = hba->timer_tics + 30;
3537 sbp->abort_attempts++;
3538 mutex_exit(&sbp->mtx);
3539 }
3540
3541 mutex_exit(&EMLXS_FCTAB_LOCK(ringno));
3542
3543 /* Send this iocbq */
3544 if (iocbq) {
3545 emlxs_issue_iocb_cmd(hba, rp, iocbq);
3546 iocbq = NULL;
3547 }
3548 goto done;
3781 return (FCT_NOT_FOUND);
3549 }
3782 }
3550 mutex_exit(&EMLXS_FCTAB_LOCK(ringno));
3551
3783
3784 if (mutex_tryenter(&cmd_sbp->fct_mtx) == 0) {
3552
3785
3553 /* Pkt was not on any queues */
3554
3555 /* Check again if we still own this */
3556 if (!(sbp->pkt_flags & PACKET_VALID) ||
3557 (sbp->pkt_flags & (PACKET_RETURNED | PACKET_IN_COMPLETION |
3558 PACKET_IN_FLUSH | PACKET_IN_TIMEOUT))) {
3559 /*
3786 /*
3560 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3561 * "emlxs_fct_pkt_abort: 9. sbp=%p flags=%x,%x", sbp,
3562 * cmd_sbp->fct_flags, sbp->pkt_flags);
3787 * This code path handles a race condition if
3788 * an IO completes, in emlxs_fct_handle_fcp_event(),
3789 * and we get an abort at the same time.
3563 */
3790 */
3564
3565 goto done;
3791 delay(drv_usectohz(100000)); /* 100 msec */
3792 goto top;
3566 }
3793 }
3567 /* Apparently the pkt was not found. Let's delay and try again */
3568 if (pass < 5) {
3569 delay(drv_usectohz(5000000)); /* 5 seconds */
3794 /* At this point, we have entered the mutex */
3570
3795
3571 /* Check packet */
3572 if (!(sbp->pkt_flags & PACKET_VALID) ||
3573 (sbp->pkt_flags & (PACKET_RETURNED | PACKET_IN_COMPLETION |
3574 PACKET_IN_FLUSH | PACKET_IN_TIMEOUT))) {
3575
3796
3576 /*
3577 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3578 * "emlxs_fct_pkt_abort: 10. sbp=%p flags=%x,%x",
3579 * sbp, cmd_sbp->fct_flags, sbp->pkt_flags);
3580 */
3797 if (!(cmd_sbp->pkt_flags & PACKET_VALID)) {
3798 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3799 "emlxs_fct_abort: Invalid cmd_sbp=%p.", cmd_sbp);
3581
3800
3582 goto done;
3583 }
3584 goto begin;
3801 mutex_exit(&cmd_sbp->fct_mtx);
3802 return (FCT_NOT_FOUND);
3585 }
3803 }
3586force_it:
3587
3804
3588 /* Force the completion now */
3589 /*
3590 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3591 * "emlxs_fct_pkt_abort: 11. sbp=%p flags=%x,%x", sbp,
3592 * cmd_sbp->fct_flags, sbp->pkt_flags);
3593 */
3594
3595 /* Unregister the pkt */
3596 (void) emlxs_unregister_pkt(rp, sbp->iotag, 1);
3597
3598 /* Now complete it */
3599 if (sbp->pkt) {
3600 emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
3601 IOERR_ABORT_REQUESTED, 1);
3805 if (flags & FCT_IOF_FORCE_FCA_DONE) {
3806 fct_cmd->cmd_handle = 0;
3602 }
3807 }
3603done:
3604
3808
3605 /* Now wait for the pkt to complete */
3606 if (!(cmd_sbp->fct_flags & EMLXS_FCT_ABORT_COMPLETE)) {
3607 /* Set thread timeout */
3608 timeout = emlxs_timeout(hba, 30);
3809 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3810 "emlxs_fct_abort: HbaLink %d. "
3811 "xid=%x. cmd_sbp=%p state=%d flags=%x,%x,%x",
3812 hba->state, fct_cmd->cmd_rxid, cmd_sbp, cmd_sbp->fct_state, flags,
3813 cmd_sbp->fct_flags, cmd_sbp->pkt_flags);
3609
3814
3610 /* Check for panic situation */
3611 if (ddi_in_panic()) {
3612 /*
3613 * In panic situations there will be one thread with
3614 * no interrrupts (hard or soft) and no timers
3615 */
3815 rval = FCT_SUCCESS;
3816 state = cmd_sbp->fct_state;
3817 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_SEND_ABORT);
3616
3818
3617 /*
3618 * We must manually poll everything in this thread to
3619 * keep the driver going.
3620 */
3819 if (cmd_sbp->fct_flags & EMLXS_FCT_ABORT_INP) {
3820 emlxs_sli_issue_iocb_cmd(hba, cmd_sbp->ring, 0);
3821 /* If Abort is already in progress */
3822 mutex_exit(&cmd_sbp->fct_mtx);
3823 return (rval);
3824 }
3621
3825
3622 rp = (emlxs_ring_t *)sbp->ring;
3623 switch (rp->ringno) {
3624 case FC_FCP_RING:
3625 att_bit = HA_R0ATT;
3626 break;
3826 TGTPORTSTAT.FctAbortSent++;
3627
3827
3628 case FC_IP_RING:
3629 att_bit = HA_R1ATT;
3630 break;
3828 switch (state) {
3829 case EMLXS_FCT_CMD_POSTED:
3830 case EMLXS_FCT_SEND_ELS_RSP:
3831 case EMLXS_FCT_SEND_ELS_REQ:
3832 case EMLXS_FCT_SEND_CT_REQ:
3833 case EMLXS_FCT_RSP_PENDING:
3834 case EMLXS_FCT_REQ_PENDING:
3835 case EMLXS_FCT_REG_PENDING:
3836 case EMLXS_FCT_REG_COMPLETE:
3837 case EMLXS_FCT_OWNED:
3838 case EMLXS_FCT_SEND_FCP_DATA:
3839 case EMLXS_FCT_SEND_FCP_STATUS:
3840 case EMLXS_FCT_DATA_PENDING:
3841 case EMLXS_FCT_STATUS_PENDING:
3842 case EMLXS_FCT_IOCB_ISSUED:
3843 case EMLXS_FCT_IOCB_COMPLETE:
3844 case EMLXS_FCT_PKT_COMPLETE:
3845 case EMLXS_FCT_PKT_FCPRSP_COMPLETE:
3846 case EMLXS_FCT_PKT_ELSRSP_COMPLETE:
3847 case EMLXS_FCT_PKT_ELSCMD_COMPLETE:
3848 case EMLXS_FCT_PKT_CTCMD_COMPLETE:
3849 case EMLXS_FCT_REQ_COMPLETE:
3850 case EMLXS_FCT_ABORT_DONE:
3851 case EMLXS_FCT_IO_DONE:
3852 if (emlxs_fct_pkt_abort_txq(port, cmd_sbp)) {
3631
3853
3632 case FC_ELS_RING:
3633 att_bit = HA_R2ATT;
3634 break;
3635
3636 case FC_CT_RING:
3637 att_bit = HA_R3ATT;
3638 break;
3854 if (fct_cmd->cmd_type == FCT_CMD_FCP_XCHG) {
3855 TGTPORTSTAT.FctOutstandingIO--;
3639 }
3856 }
3857 emlxs_fct_state_chg(fct_cmd, cmd_sbp,
3858 EMLXS_FCT_ABORT_DONE);
3859 /* mutex_exit(&cmd_sbp->fct_mtx); */
3860 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
3861 MODSYM(fct_cmd_fca_aborted) (fct_cmd,
3862 FCT_ABORT_SUCCESS, FCT_IOF_FCA_DONE);
3863 return (rval);
3864 }
3640
3865
3641 /* Keep polling the chip until our IO is completed */
3642 (void) drv_getparm(LBOLT, &time);
3643 while ((time < timeout) &&
3644 !(cmd_sbp->fct_flags & EMLXS_FCT_ABORT_COMPLETE)) {
3645 emlxs_poll_intr(hba, att_bit);
3646 (void) drv_getparm(LBOLT, &time);
3866 if (!(hba->flag & FC_ONLINE_MODE)) {
3867 if ((state == EMLXS_FCT_OWNED) ||
3868 (state == EMLXS_FCT_CMD_POSTED)) {
3869
3870 if (fct_cmd->cmd_type == FCT_CMD_FCP_XCHG) {
3871 TGTPORTSTAT.FctOutstandingIO--;
3872 }
3873 emlxs_fct_state_chg(fct_cmd, cmd_sbp,
3874 EMLXS_FCT_ABORT_DONE);
3875 /* mutex_exit(&cmd_sbp->fct_mtx); */
3876 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
3877 MODSYM(fct_cmd_fca_aborted) (fct_cmd,
3878 FCT_ABORT_SUCCESS, FCT_IOF_FCA_DONE);
3879 return (rval);
3647 }
3880 }
3648 } else {
3649 /* Wait for IO completion or timeout */
3650 mutex_enter(&EMLXS_PKT_LOCK);
3651 pkt_ret = 0;
3652 while ((pkt_ret != -1) &&
3653 !(cmd_sbp->fct_flags & EMLXS_FCT_ABORT_COMPLETE)) {
3654 pkt_ret = cv_timedwait(&EMLXS_PKT_CV,
3655 &EMLXS_PKT_LOCK, timeout);
3656 }
3657 mutex_exit(&EMLXS_PKT_LOCK);
3881 cmd_sbp->fct_flags |= EMLXS_FCT_ABORT_INP;
3882 mutex_exit(&cmd_sbp->fct_mtx);
3883 return (rval);
3658 }
3659
3884 }
3885
3660 /*
3661 * Check if timeout occured. This is not good. Something
3662 * happened to our IO.
3663 */
3664 if (!(cmd_sbp->fct_flags & EMLXS_FCT_ABORT_COMPLETE)) {
3665 /* Force the completion now */
3666 goto force_it;
3886 if (!(pkt = emlxs_pkt_alloc(port, 0, 0, 0, KM_NOSLEEP))) {
3887 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
3888 "emlxs_fct_abort: Unable to allocate packet.");
3889 mutex_exit(&cmd_sbp->fct_mtx);
3890 return (rval);
3667 }
3891 }
3668 }
3669 /*
3670 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3671 * "emlxs_fct_pkt_abort: 12. sbp=%p flags=%x,%x", sbp,
3672 * cmd_sbp->fct_flags, sbp->pkt_flags);
3673 */
3674
3892
3675 return (FCT_ABORT_SUCCESS);
3893 sbp = emlxs_fct_pkt_init(port, fct_cmd, pkt);
3676
3894
3677} /* emlxs_fct_pkt_abort() */
3895 pkt->pkt_tran_type = FC_PKT_OUTBOUND;
3896 pkt->pkt_timeout =
3897 ((2 * hba->fc_ratov) < 30) ? 30 : (2 * hba->fc_ratov);
3898 pkt->pkt_comp = emlxs_fct_abort_pkt_comp;
3678
3899
3900 /* Build the fc header */
3901 pkt->pkt_cmd_fhdr.d_id = SWAP_DATA24_LO(fct_cmd->cmd_rportid);
3902 pkt->pkt_cmd_fhdr.r_ctl = R_CTL_STATUS;
3903 pkt->pkt_cmd_fhdr.s_id = SWAP_DATA24_LO(port->did);
3904 pkt->pkt_cmd_fhdr.type = FC_TYPE_BASIC_LS;
3905 pkt->pkt_cmd_fhdr.f_ctl =
3906 (F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ);
3907 pkt->pkt_cmd_fhdr.seq_id = 0;
3908 pkt->pkt_cmd_fhdr.df_ctl = 0;
3909 pkt->pkt_cmd_fhdr.seq_cnt = 0;
3910 pkt->pkt_cmd_fhdr.ox_id = fct_cmd->cmd_oxid;
3911 pkt->pkt_cmd_fhdr.rx_id = fct_cmd->cmd_rxid;
3912 pkt->pkt_cmd_fhdr.ro = 0;
3679
3913
3914 cmd_sbp->fct_flags |= EMLXS_FCT_ABORT_INP;
3915 cmd_sbp->fct_cmd = fct_cmd;
3916 cmd_sbp->abort_attempts++;
3680
3917
3681static uint32_t
3682emlxs_fct_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp)
3683{
3684 emlxs_hba_t *hba = HBA;
3685 uint32_t sgllen = 1;
3686 uint32_t rval;
3687 uint32_t size;
3688 uint32_t count;
3689 uint32_t resid;
3690 struct stmf_sglist_ent *sgl;
3918 /* Now disassociate the sbp / pkt from the fct_cmd */
3919 sbp->fct_cmd = NULL;
3920 if (hba->state >= FC_LINK_UP) {
3921 emlxs_fct_state_chg(fct_cmd, cmd_sbp,
3922 EMLXS_FCT_ABORT_PENDING);
3691
3923
3692 size = sbp->fct_buf->db_data_size;
3693 count = sbp->fct_buf->db_sglist_length;
3694 sgl = sbp->fct_buf->db_sglist;
3695 resid = size;
3924 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3925 "emlxs_fct_abort: ABORT: %p xri x%x",
3926 fct_cmd, fct_cmd->cmd_rxid);
3927 } else {
3928 emlxs_fct_state_chg(fct_cmd, cmd_sbp,
3929 EMLXS_FCT_CLOSE_PENDING);
3696
3930
3697 for (sgllen = 0; sgllen < count && resid > 0; sgllen++) {
3698 resid -= MIN(resid, sgl->seg_length);
3699 sgl++;
3700 }
3931 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3932 "emlxs_fct_abort: CLOSE: %p xri x%x",
3933 fct_cmd, fct_cmd->cmd_rxid);
3934 }
3701
3935
3702 if (resid > 0) {
3703 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
3704 "emlxs_fct_bde_setup: Not enough scatter gather buffers "
3705 "provided. size=%d resid=%d count=%d", size, resid, count);
3706 return (1);
3707 }
3708#ifdef SLI3_SUPPORT
3709 if ((hba->sli_mode < 3) || (sgllen > SLI3_MAX_BDE)) {
3710 rval = emlxs_fct_sli2_bde_setup(port, sbp);
3711 } else {
3712 rval = emlxs_fct_sli3_bde_setup(port, sbp);
3713 }
3714#else /* !SLI3_SUPPORT */
3715 rval = emlxs_fct_sli2_bde_setup(port, sbp);
3716#endif /* SLI3_SUPPORT */
3936 /*
3937 * If there isn't an outstanding IO, indicate the fct_cmd
3938 * is aborted now.
3939 */
3940 if ((state == EMLXS_FCT_OWNED) ||
3941 (state == EMLXS_FCT_CMD_POSTED)) {
3717
3942
3718 return (rval);
3943 if (fct_cmd->cmd_type == FCT_CMD_FCP_XCHG) {
3944 TGTPORTSTAT.FctOutstandingIO--;
3945 }
3946 emlxs_fct_state_chg(fct_cmd, cmd_sbp,
3947 EMLXS_FCT_ABORT_DONE);
3948 /* mutex_exit(&cmd_sbp->fct_mtx); */
3949 (void) emlxs_fct_cmd_uninit(port, fct_cmd);
3950 MODSYM(fct_cmd_fca_aborted) (fct_cmd,
3951 FCT_ABORT_SUCCESS, FCT_IOF_FCA_DONE);
3952 }
3719
3953
3720} /* emlxs_fct_bde_setup() */
3954 if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
3955 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
3956 "emlxs_fct_abort: Unable to send packet.");
3721
3957
3958 cmd_sbp->fct_flags &= ~EMLXS_FCT_ABORT_INP;
3959 emlxs_pkt_free(pkt);
3722
3960
3961 mutex_exit(&cmd_sbp->fct_mtx);
3962 return (rval);
3963 }
3964 break;
3723
3965
3724/* Only used for FCP Data xfers */
3725static uint32_t
3726emlxs_fct_sli2_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp)
3727{
3728 emlxs_hba_t *hba = HBA;
3729 scsi_task_t *fct_task;
3730 MATCHMAP *bmp;
3731 ULP_BDE64 *bpl;
3732 uint64_t bp;
3733 uint8_t bdeFlags;
3734 IOCB *iocb;
3735 uint32_t resid;
3736 uint32_t count;
3737 uint32_t size;
3738 uint32_t sgllen;
3739 struct stmf_sglist_ent *sgl;
3740 emlxs_fct_dmem_bctl_t *bctl;
3966 case EMLXS_FCT_CMD_WAITQ:
3967 case EMLXS_FCT_FCP_CMD_RECEIVED:
3968 case EMLXS_FCT_ELS_CMD_RECEIVED:
3969 case EMLXS_FCT_SEND_ABORT:
3970 case EMLXS_FCT_CLOSE_PENDING:
3971 case EMLXS_FCT_ABORT_PENDING:
3972 case EMLXS_FCT_ABORT_COMPLETE:
3973 default:
3974 emlxs_fct_state_chg(fct_cmd, cmd_sbp, EMLXS_FCT_OWNED);
3975 rval = FCT_FAILURE;
3976 break;
3741
3977
3742 iocb = (IOCB *)&sbp->iocbq;
3743 sbp->bmp = NULL;
3978 } /* switch */
3744
3979
3745 if (!sbp->fct_buf) {
3746 iocb->un.fcpt64.bdl.addrHigh = 0;
3747 iocb->un.fcpt64.bdl.addrLow = 0;
3748 iocb->un.fcpt64.bdl.bdeSize = 0;
3749 iocb->un.fcpt64.bdl.bdeFlags = 0;
3750 iocb->un.fcpt64.fcpt_Offset = 0;
3751 iocb->un.fcpt64.fcpt_Length = 0;
3752 iocb->ulpBdeCount = 0;
3753 iocb->ulpLe = 1;
3754 return (0);
3755 }
3756#ifdef EMLXS_SPARC
3757 /* Use FCP MEM_BPL table to get BPL buffer */
3758 bmp = &hba->fcp_bpl_table[sbp->iotag];
3759#else
3760 /* Use MEM_BPL pool to get BPL buffer */
3761 bmp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BPL);
3762#endif /* EMLXS_SPARC */
3980 mutex_exit(&cmd_sbp->fct_mtx);
3981 return (rval);
3763
3982
3764 if (!bmp) {
3765 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
3766 "emlxs_fct_sli2_bde_setup: Unable to BPL buffer. iotag=%x",
3767 sbp->iotag);
3983} /* emlxs_fct_abort() */
3768
3984
3769 iocb->un.fcpt64.bdl.addrHigh = 0;
3770 iocb->un.fcpt64.bdl.addrLow = 0;
3771 iocb->un.fcpt64.bdl.bdeSize = 0;
3772 iocb->un.fcpt64.bdl.bdeFlags = 0;
3773 iocb->un.fcpt64.fcpt_Offset = 0;
3774 iocb->un.fcpt64.fcpt_Length = 0;
3775 iocb->ulpBdeCount = 0;
3776 iocb->ulpLe = 1;
3777 return (1);
3778 }
3779 bpl = (ULP_BDE64 *) bmp->virt;
3780 bp = bmp->phys;
3781
3985
3782 fct_task = (scsi_task_t *)sbp->fct_cmd->cmd_specific;
3783
3784 /* size = fct_task->task_cmd_xfer_length; */
3785 size = sbp->fct_buf->db_data_size;
3786 count = sbp->fct_buf->db_sglist_length;
3787 bctl = (emlxs_fct_dmem_bctl_t *)sbp->fct_buf->db_port_private;
3788
3789 bdeFlags = (fct_task->task_flags & TF_WRITE_DATA) ? BUFF_USE_RCV : 0;
3790 sgl = sbp->fct_buf->db_sglist;
3791 resid = size;
3792
3793 /* Init the buffer list */
3794 for (sgllen = 0; sgllen < count && resid > 0; sgllen++) {
3795 bpl->addrHigh =
3796 PCIMEM_LONG((uint32_t)putPaddrHigh(bctl->bctl_dev_addr));
3797 bpl->addrLow =
3798 PCIMEM_LONG((uint32_t)putPaddrLow(bctl->bctl_dev_addr));
3799 bpl->tus.f.bdeSize = MIN(resid, sgl->seg_length);
3800 bpl->tus.f.bdeFlags = bdeFlags;
3801 bpl->tus.w = PCIMEM_LONG(bpl->tus.w);
3802 bpl++;
3803
3804 resid -= MIN(resid, sgl->seg_length);
3805 sgl++;
3806 }
3807
3808 /* Init the IOCB */
3809 iocb->un.fcpt64.bdl.addrHigh = (uint32_t)putPaddrHigh(bp);
3810 iocb->un.fcpt64.bdl.addrLow = (uint32_t)putPaddrLow(bp);
3811 iocb->un.fcpt64.bdl.bdeSize = sgllen * sizeof (ULP_BDE64);
3812 iocb->un.fcpt64.bdl.bdeFlags = BUFF_TYPE_BDL;
3813
3814 iocb->un.fcpt64.fcpt_Length =
3815 (fct_task->task_flags & TF_WRITE_DATA) ? size : 0;
3816 iocb->un.fcpt64.fcpt_Offset = 0;
3817
3818 iocb->ulpBdeCount = 1;
3819 iocb->ulpLe = 1;
3820 sbp->bmp = bmp;
3821
3822 return (0);
3823
3824} /* emlxs_fct_sli2_bde_setup */
3825
3826
3827
3828#ifdef SLI3_SUPPORT
3829
3830/* ARGSUSED */
3831static uint32_t
3832emlxs_fct_sli3_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp)
3833{
3834 scsi_task_t *fct_task;
3835 ULP_BDE64 *bde;
3836 IOCB *iocb;
3837 uint32_t size;
3838 uint32_t count;
3839 uint32_t sgllen;
3840 int32_t resid;
3841 struct stmf_sglist_ent *sgl;
3842 uint32_t bdeFlags;
3843 emlxs_fct_dmem_bctl_t *bctl;
3844
3845 iocb = (IOCB *)&sbp->iocbq;
3846
3847 if (!sbp->fct_buf) {
3848 iocb->un.fcpt64.bdl.addrHigh = 0;
3849 iocb->un.fcpt64.bdl.addrLow = 0;
3850 iocb->un.fcpt64.bdl.bdeSize = 0;
3851 iocb->un.fcpt64.bdl.bdeFlags = 0;
3852 iocb->un.fcpt64.fcpt_Offset = 0;
3853 iocb->un.fcpt64.fcpt_Length = 0;
3854 iocb->ulpBdeCount = 0;
3855 iocb->ulpLe = 0;
3856 iocb->unsli3.ext_iocb.ebde_count = 0;
3857 return (0);
3858 }
3859 fct_task = (scsi_task_t *)sbp->fct_cmd->cmd_specific;
3860
3861 size = sbp->fct_buf->db_data_size;
3862 count = sbp->fct_buf->db_sglist_length;
3863 bctl = (emlxs_fct_dmem_bctl_t *)sbp->fct_buf->db_port_private;
3864
3865 bdeFlags = (fct_task->task_flags & TF_WRITE_DATA) ? BUFF_USE_RCV : 0;
3866 sgl = sbp->fct_buf->db_sglist;
3867 resid = size;
3868
3869 /* Init first BDE */
3870 iocb->un.fcpt64.bdl.addrHigh = putPaddrHigh(bctl->bctl_dev_addr);
3871 iocb->un.fcpt64.bdl.addrLow = putPaddrLow(bctl->bctl_dev_addr);
3872 iocb->un.fcpt64.bdl.bdeSize = MIN(resid, sgl->seg_length);
3873 iocb->un.fcpt64.bdl.bdeFlags = bdeFlags;
3874 resid -= MIN(resid, sgl->seg_length);
3875 sgl++;
3876
3877 /* Init remaining BDE's */
3878 bde = (ULP_BDE64 *) & iocb->unsli3.ext_iocb.ebde1;
3879 for (sgllen = 1; sgllen < count && resid > 0; sgllen++) {
3880 bde->addrHigh = putPaddrHigh(bctl->bctl_dev_addr);
3881 bde->addrLow = putPaddrLow(bctl->bctl_dev_addr);
3882 bde->tus.f.bdeSize = MIN(resid, sgl->seg_length);
3883 bde->tus.f.bdeFlags = bdeFlags;
3884 bde++;
3885
3886 resid -= MIN(resid, sgl->seg_length);
3887 sgl++;
3888 }
3889
3890 iocb->unsli3.ext_iocb.ebde_count = sgllen - 1;
3891 iocb->un.fcpt64.fcpt_Length =
3892 (fct_task->task_flags & TF_WRITE_DATA) ? size : 0;
3893 iocb->un.fcpt64.fcpt_Offset = 0;
3894
3895 iocb->ulpBdeCount = 0;
3896 iocb->ulpLe = 0;
3897
3898 return (0);
3899
3900} /* emlxs_fct_sli3_bde_setup */
3901
3902#endif /* SLI3_SUPPORT */
3903
3904
3905extern void
3906emlxs_fct_link_up(emlxs_port_t *port)
3907{
3908 emlxs_hba_t *hba = HBA;
3909
3910 mutex_enter(&EMLXS_PORT_LOCK);
3911
3912 if (port->fct_port &&

--- 4 unchanged lines hidden (view full) ---

3917
3918 port->fct_flags |= FCT_STATE_LINK_UP;
3919
3920 mutex_exit(&EMLXS_PORT_LOCK);
3921
3922#ifdef FCT_API_TRACE
3923 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
3924 "fct_handle_event LINK_UP");
3986extern void
3987emlxs_fct_link_up(emlxs_port_t *port)
3988{
3989 emlxs_hba_t *hba = HBA;
3990
3991 mutex_enter(&EMLXS_PORT_LOCK);
3992
3993 if (port->fct_port &&

--- 4 unchanged lines hidden (view full) ---

3998
3999 port->fct_flags |= FCT_STATE_LINK_UP;
4000
4001 mutex_exit(&EMLXS_PORT_LOCK);
4002
4003#ifdef FCT_API_TRACE
4004 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
4005 "fct_handle_event LINK_UP");
3925#endif /* FCT_API_TRACE */
3926 MODSYM(fct_handle_event) (port->fct_port,
3927 FCT_EVENT_LINK_UP, 0, 0);
4006#endif /* FCT_API_TRACE */
4007 MODSYM(fct_handle_event) (port->fct_port, FCT_EVENT_LINK_UP,
4008 0, 0);
3928
3929 emlxs_fct_unsol_flush(port);
3930 } else {
3931 if (!hba->ini_mode &&
3932 !(port->fct_flags & FCT_STATE_PORT_ONLINE)) {
3933 mutex_exit(&EMLXS_PORT_LOCK);
3934
3935 /* Take link down and hold it down */
3936 (void) emlxs_reset_link(hba, 0);
3937 } else {
3938 mutex_exit(&EMLXS_PORT_LOCK);
3939 }
3940 }
3941
3942 return;
3943
4009
4010 emlxs_fct_unsol_flush(port);
4011 } else {
4012 if (!hba->ini_mode &&
4013 !(port->fct_flags & FCT_STATE_PORT_ONLINE)) {
4014 mutex_exit(&EMLXS_PORT_LOCK);
4015
4016 /* Take link down and hold it down */
4017 (void) emlxs_reset_link(hba, 0);
4018 } else {
4019 mutex_exit(&EMLXS_PORT_LOCK);
4020 }
4021 }
4022
4023 return;
4024
3944} /* emlxs_fct_link_up() */
4025} /* emlxs_fct_link_up() */
3945
4026
4027
3946extern void
3947emlxs_fct_link_down(emlxs_port_t *port)
3948{
3949 emlxs_hba_t *hba = HBA;
3950
3951 mutex_enter(&EMLXS_PORT_LOCK);
3952
3953 if (port->fct_port &&

--- 4 unchanged lines hidden (view full) ---

3958
3959 port->fct_flags &= ~FCT_STATE_LINK_UP;
3960
3961 mutex_exit(&EMLXS_PORT_LOCK);
3962
3963#ifdef FCT_API_TRACE
3964 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
3965 "fct_handle_event LINK_DOWN");
4028extern void
4029emlxs_fct_link_down(emlxs_port_t *port)
4030{
4031 emlxs_hba_t *hba = HBA;
4032
4033 mutex_enter(&EMLXS_PORT_LOCK);
4034
4035 if (port->fct_port &&

--- 4 unchanged lines hidden (view full) ---

4040
4041 port->fct_flags &= ~FCT_STATE_LINK_UP;
4042
4043 mutex_exit(&EMLXS_PORT_LOCK);
4044
4045#ifdef FCT_API_TRACE
4046 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
4047 "fct_handle_event LINK_DOWN");
3966#endif /* FCT_API_TRACE */
3967 MODSYM(fct_handle_event) (port->fct_port,
3968 FCT_EVENT_LINK_DOWN, 0, 0);
4048#endif /* FCT_API_TRACE */
4049 MODSYM(fct_handle_event) (port->fct_port, FCT_EVENT_LINK_DOWN,
4050 0, 0);
3969 } else {
3970 mutex_exit(&EMLXS_PORT_LOCK);
3971 }
3972
3973 return;
3974
4051 } else {
4052 mutex_exit(&EMLXS_PORT_LOCK);
4053 }
4054
4055 return;
4056
3975} /* emlxs_fct_link_down() */
4057} /* emlxs_fct_link_down() */
3976
3977
4058
4059
4060/* DMA FUNCTIONS */
3978
4061
3979/*
3980 * DMA FUNCTIONS
3981 */
3982
3983
3984fct_status_t
3985emlxs_fct_dmem_init(emlxs_port_t *port)
3986{
3987 emlxs_hba_t *hba = HBA;
3988 emlxs_fct_dmem_bucket_t *p;
3989 emlxs_fct_dmem_bctl_t *bctl;
3990 emlxs_fct_dmem_bctl_t *bc;
3991 emlxs_fct_dmem_bctl_t *prev;

--- 15 unchanged lines hidden (view full) ---

4007 acc.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
4008 acc.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
4009
4010 p = port->dmem_bucket;
4011 for (i = 0; i < FCT_MAX_BUCKETS; i++, p++) {
4012 if (!p->dmem_nbufs) {
4013 continue;
4014 }
4062fct_status_t
4063emlxs_fct_dmem_init(emlxs_port_t *port)
4064{
4065 emlxs_hba_t *hba = HBA;
4066 emlxs_fct_dmem_bucket_t *p;
4067 emlxs_fct_dmem_bctl_t *bctl;
4068 emlxs_fct_dmem_bctl_t *bc;
4069 emlxs_fct_dmem_bctl_t *prev;

--- 15 unchanged lines hidden (view full) ---

4085 acc.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
4086 acc.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
4087
4088 p = port->dmem_bucket;
4089 for (i = 0; i < FCT_MAX_BUCKETS; i++, p++) {
4090 if (!p->dmem_nbufs) {
4091 continue;
4092 }
4093
4015 bctl = (emlxs_fct_dmem_bctl_t *)kmem_zalloc(p->dmem_nbufs *
4016 sizeof (emlxs_fct_dmem_bctl_t), KM_NOSLEEP);
4017
4018 if (bctl == NULL) {
4019 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
4020 "emlxs_fct_dmem_init: Unable to allocate bctl.");
4021 goto alloc_bctl_failed;
4022 }
4094 bctl = (emlxs_fct_dmem_bctl_t *)kmem_zalloc(p->dmem_nbufs *
4095 sizeof (emlxs_fct_dmem_bctl_t), KM_NOSLEEP);
4096
4097 if (bctl == NULL) {
4098 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
4099 "emlxs_fct_dmem_init: Unable to allocate bctl.");
4100 goto alloc_bctl_failed;
4101 }
4102
4023 p->dmem_bctls_mem = bctl;
4024
4025 if (ddi_dma_alloc_handle(hba->dip, &emlxs_dma_attr_1sg,
4026 DDI_DMA_SLEEP, 0, &p->dmem_dma_handle) != DDI_SUCCESS) {
4027 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
4028 "emlxs_fct_dmem_init: Unable to allocate handle.");
4029 goto alloc_handle_failed;
4030 }
4031
4032 total_mem = p->dmem_buf_size * p->dmem_nbufs;
4033
4034 if (ddi_dma_mem_alloc(p->dmem_dma_handle, total_mem, &acc,
4103 p->dmem_bctls_mem = bctl;
4104
4105 if (ddi_dma_alloc_handle(hba->dip, &emlxs_dma_attr_1sg,
4106 DDI_DMA_SLEEP, 0, &p->dmem_dma_handle) != DDI_SUCCESS) {
4107 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
4108 "emlxs_fct_dmem_init: Unable to allocate handle.");
4109 goto alloc_handle_failed;
4110 }
4111
4112 total_mem = p->dmem_buf_size * p->dmem_nbufs;
4113
4114 if (ddi_dma_mem_alloc(p->dmem_dma_handle, total_mem, &acc,
4035 DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, 0, (caddr_t *)&addr,
4036 &len, &p->dmem_acc_handle) != DDI_SUCCESS) {
4115 DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, 0,
4116 (caddr_t *)&addr, &len,
4117 &p->dmem_acc_handle) != DDI_SUCCESS) {
4037 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
4038 "emlxs_fct_dmem_init: Unable to allocate memory.");
4039 goto mem_alloc_failed;
4040 }
4041
4042 if (ddi_dma_addr_bind_handle(p->dmem_dma_handle, NULL,
4118 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
4119 "emlxs_fct_dmem_init: Unable to allocate memory.");
4120 goto mem_alloc_failed;
4121 }
4122
4123 if (ddi_dma_addr_bind_handle(p->dmem_dma_handle, NULL,
4043 (caddr_t)addr, total_mem, DDI_DMA_RDWR | DDI_DMA_STREAMING,
4044 DDI_DMA_DONTWAIT, 0, &cookie, &ncookie) != DDI_SUCCESS) {
4124 (caddr_t)addr, total_mem,
4125 DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, 0,
4126 &cookie, &ncookie) != DDI_SUCCESS) {
4045 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
4046 "emlxs_fct_dmem_init: Unable to bind handle.");
4047 goto addr_bind_handle_failed;
4048 }
4049
4050 if (ncookie != 1) {
4051 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
4052 "emlxs_fct_dmem_init: DMEM init failed.");

--- 18 unchanged lines hidden (view full) ---

4071
4072 for (j = 0; j < p->dmem_nbufs; j++) {
4073 stmf_data_buf_t *db;
4074
4075 db = MODSYM(stmf_alloc) (STMF_STRUCT_DATA_BUF, 0, 0);
4076#ifdef FCT_API_TRACE
4077 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
4078 "stmf_alloc data_buf %p", db);
4127 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
4128 "emlxs_fct_dmem_init: Unable to bind handle.");
4129 goto addr_bind_handle_failed;
4130 }
4131
4132 if (ncookie != 1) {
4133 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
4134 "emlxs_fct_dmem_init: DMEM init failed.");

--- 18 unchanged lines hidden (view full) ---

4153
4154 for (j = 0; j < p->dmem_nbufs; j++) {
4155 stmf_data_buf_t *db;
4156
4157 db = MODSYM(stmf_alloc) (STMF_STRUCT_DATA_BUF, 0, 0);
4158#ifdef FCT_API_TRACE
4159 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
4160 "stmf_alloc data_buf %p", db);
4079#endif /* FCT_API_TRACE */
4161#endif /* FCT_API_TRACE */
4080 if (db == NULL) {
4081 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
4162 if (db == NULL) {
4163 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
4082 "emlxs_fct_dmem_init: DMEM init: "
4083 "alloc failed.");
4164 "emlxs_fct_dmem_init: alloc failed.");
4084 goto dmem_init_failed;
4085 }
4086 db->db_port_private = bctl;
4087 db->db_sglist[0].seg_addr = host_addr;
4088 db->db_sglist[0].seg_length = bsize;
4089 db->db_buf_size = bsize;
4090 db->db_sglist_length = 1;
4091

--- 16 unchanged lines hidden (view full) ---

4108
4109dmem_failure_loop:
4110 mutex_destroy(&p->dmem_lock);
4111 bc = bctl;
4112 while (bc) {
4113#ifdef FCT_API_TRACE
4114 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
4115 "stmf_free:3 %p", bctl->bctl_buf);
4165 goto dmem_init_failed;
4166 }
4167 db->db_port_private = bctl;
4168 db->db_sglist[0].seg_addr = host_addr;
4169 db->db_sglist[0].seg_length = bsize;
4170 db->db_buf_size = bsize;
4171 db->db_sglist_length = 1;
4172

--- 16 unchanged lines hidden (view full) ---

4189
4190dmem_failure_loop:
4191 mutex_destroy(&p->dmem_lock);
4192 bc = bctl;
4193 while (bc) {
4194#ifdef FCT_API_TRACE
4195 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
4196 "stmf_free:3 %p", bctl->bctl_buf);
4116#endif /* FCT_API_TRACE */
4197#endif /* FCT_API_TRACE */
4117 MODSYM(stmf_free) (bc->bctl_buf);
4118 bc = bc->bctl_next;
4119 }
4120
4121dmem_init_failed:
4122 (void) ddi_dma_unbind_handle(p->dmem_dma_handle);
4123
4124addr_bind_handle_failed:

--- 7 unchanged lines hidden (view full) ---

4132 p->dmem_nbufs * sizeof (emlxs_fct_dmem_bctl_t));
4133
4134alloc_bctl_failed:
4135 if (--i >= 0) {
4136 p = &port->dmem_bucket[i];
4137 bctl = p->dmem_bctl_free_list;
4138 goto dmem_failure_loop;
4139 }
4198 MODSYM(stmf_free) (bc->bctl_buf);
4199 bc = bc->bctl_next;
4200 }
4201
4202dmem_init_failed:
4203 (void) ddi_dma_unbind_handle(p->dmem_dma_handle);
4204
4205addr_bind_handle_failed:

--- 7 unchanged lines hidden (view full) ---

4213 p->dmem_nbufs * sizeof (emlxs_fct_dmem_bctl_t));
4214
4215alloc_bctl_failed:
4216 if (--i >= 0) {
4217 p = &port->dmem_bucket[i];
4218 bctl = p->dmem_bctl_free_list;
4219 goto dmem_failure_loop;
4220 }
4221
4140 return (FCT_FAILURE);
4141
4222 return (FCT_FAILURE);
4223
4142} /* emlxs_fct_dmem_init() */
4224} /* emlxs_fct_dmem_init() */
4143
4144
4225
4226
4145
4146void
4147emlxs_fct_dmem_fini(emlxs_port_t *port)
4148{
4149 emlxs_fct_dmem_bucket_t *p;
4150 emlxs_fct_dmem_bctl_t *bctl;
4151 uint32_t i;
4152
4153 p = port->dmem_bucket;
4154 for (i = 0; i < FCT_MAX_BUCKETS; i++, p++) {
4155 if (!p->dmem_nbufs) {
4156 continue;
4157 }
4227void
4228emlxs_fct_dmem_fini(emlxs_port_t *port)
4229{
4230 emlxs_fct_dmem_bucket_t *p;
4231 emlxs_fct_dmem_bctl_t *bctl;
4232 uint32_t i;
4233
4234 p = port->dmem_bucket;
4235 for (i = 0; i < FCT_MAX_BUCKETS; i++, p++) {
4236 if (!p->dmem_nbufs) {
4237 continue;
4238 }
4239
4158 bctl = p->dmem_bctl_free_list;
4159
4160 while (bctl) {
4161#ifdef FCT_API_TRACE
4162 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
4163 "stmf_free:4 %p", bctl->bctl_buf);
4240 bctl = p->dmem_bctl_free_list;
4241
4242 while (bctl) {
4243#ifdef FCT_API_TRACE
4244 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
4245 "stmf_free:4 %p", bctl->bctl_buf);
4164#endif /* FCT_API_TRACE */
4246#endif /* FCT_API_TRACE */
4165 MODSYM(stmf_free) (bctl->bctl_buf);
4166 bctl = bctl->bctl_next;
4167 }
4168
4169 bctl = p->dmem_bctl_free_list;
4170
4171 (void) ddi_dma_unbind_handle(p->dmem_dma_handle);
4172 (void) ddi_dma_mem_free(&p->dmem_acc_handle);
4173 (void) ddi_dma_free_handle(&p->dmem_dma_handle);
4174
4175 kmem_free(p->dmem_bctls_mem,
4176 (p->dmem_nbufs * sizeof (emlxs_fct_dmem_bctl_t)));
4177 mutex_destroy(&p->dmem_lock);
4178 }
4179
4180 bzero((uint8_t *)port->dmem_bucket, sizeof (port->dmem_bucket));
4181
4182 return;
4183
4247 MODSYM(stmf_free) (bctl->bctl_buf);
4248 bctl = bctl->bctl_next;
4249 }
4250
4251 bctl = p->dmem_bctl_free_list;
4252
4253 (void) ddi_dma_unbind_handle(p->dmem_dma_handle);
4254 (void) ddi_dma_mem_free(&p->dmem_acc_handle);
4255 (void) ddi_dma_free_handle(&p->dmem_dma_handle);
4256
4257 kmem_free(p->dmem_bctls_mem,
4258 (p->dmem_nbufs * sizeof (emlxs_fct_dmem_bctl_t)));
4259 mutex_destroy(&p->dmem_lock);
4260 }
4261
4262 bzero((uint8_t *)port->dmem_bucket, sizeof (port->dmem_bucket));
4263
4264 return;
4265
4184} /* emlxs_fct_dmem_fini() */
4266} /* emlxs_fct_dmem_fini() */
4185
4186
4187/* ARGSUSED */
4188static stmf_data_buf_t *
4189emlxs_fct_dbuf_alloc(fct_local_port_t *fct_port, uint32_t size,
4190 uint32_t *pminsize, uint32_t flags)
4191{
4192 emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
4193 emlxs_fct_dmem_bucket_t *p;
4194 emlxs_fct_dmem_bctl_t *bctl;
4195 uint32_t i;
4196
4267
4268
4269/* ARGSUSED */
4270static stmf_data_buf_t *
4271emlxs_fct_dbuf_alloc(fct_local_port_t *fct_port, uint32_t size,
4272 uint32_t *pminsize, uint32_t flags)
4273{
4274 emlxs_port_t *port = (emlxs_port_t *)fct_port->port_fca_private;
4275 emlxs_fct_dmem_bucket_t *p;
4276 emlxs_fct_dmem_bctl_t *bctl;
4277 uint32_t i;
4278
4197/*
4198 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
4199 * "emlxs_fct_dbuf_alloc: size=%d min=%d", size, *pminsize);
4200 */
4201
4202 if (size > FCT_DMEM_MAX_BUF_SIZE) {
4203 size = FCT_DMEM_MAX_BUF_SIZE;
4204 }
4279 if (size > FCT_DMEM_MAX_BUF_SIZE) {
4280 size = FCT_DMEM_MAX_BUF_SIZE;
4281 }
4282
4205 p = port->dmem_bucket;
4206 for (i = 0; i < FCT_MAX_BUCKETS; i++, p++) {
4207 if (!p->dmem_nbufs) {
4208 continue;
4209 }
4283 p = port->dmem_bucket;
4284 for (i = 0; i < FCT_MAX_BUCKETS; i++, p++) {
4285 if (!p->dmem_nbufs) {
4286 continue;
4287 }
4288
4210 if (p->dmem_buf_size >= size) {
4211 mutex_enter(&p->dmem_lock);
4212 if (p->dmem_nbufs_free) {
4213 if (p->dmem_buf_size < *pminsize) {
4214 *pminsize = p->dmem_buf_size;
4215 TGTPORTSTAT.FctNoBuffer++;
4216
4217 EMLXS_MSGF(EMLXS_CONTEXT,
4218 &emlxs_fct_api_msg,
4219 "emlxs_fct_dbuf_alloc: Failed(1).");
4220 mutex_exit(&p->dmem_lock);
4221 return (NULL);
4222 }
4289 if (p->dmem_buf_size >= size) {
4290 mutex_enter(&p->dmem_lock);
4291 if (p->dmem_nbufs_free) {
4292 if (p->dmem_buf_size < *pminsize) {
4293 *pminsize = p->dmem_buf_size;
4294 TGTPORTSTAT.FctNoBuffer++;
4295
4296 EMLXS_MSGF(EMLXS_CONTEXT,
4297 &emlxs_fct_api_msg,
4298 "emlxs_fct_dbuf_alloc: Failed(1).");
4299 mutex_exit(&p->dmem_lock);
4300 return (NULL);
4301 }
4302
4223 bctl = p->dmem_bctl_free_list;
4224 if (bctl == NULL) {
4225 mutex_exit(&p->dmem_lock);
4226 continue;
4227 }
4303 bctl = p->dmem_bctl_free_list;
4304 if (bctl == NULL) {
4305 mutex_exit(&p->dmem_lock);
4306 continue;
4307 }
4308
4228 p->dmem_bctl_free_list = bctl->bctl_next;
4229 p->dmem_nbufs_free--;
4230 bctl->bctl_buf->db_data_size = size;
4231 mutex_exit(&p->dmem_lock);
4232
4233#ifdef FCT_API_TRACE
4234 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
4235 "emlx_fct_buf_alloc size %p: %d",
4236 bctl->bctl_buf, size);
4309 p->dmem_bctl_free_list = bctl->bctl_next;
4310 p->dmem_nbufs_free--;
4311 bctl->bctl_buf->db_data_size = size;
4312 mutex_exit(&p->dmem_lock);
4313
4314#ifdef FCT_API_TRACE
4315 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
4316 "emlx_fct_buf_alloc size %p: %d",
4317 bctl->bctl_buf, size);
4237#endif /* FCT_API_TRACE */
4318#endif /* FCT_API_TRACE */
4238
4239 return (bctl->bctl_buf);
4240 }
4241 mutex_exit(&p->dmem_lock);
4242
4243 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
4244 "emlx_fct_buf_alloc size %d Nothing free bck %d",
4245 size, i);
4246 }
4247 }
4248
4249 *pminsize = 0;
4250 TGTPORTSTAT.FctNoBuffer++;
4251
4252 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
4253 "emlxs_fct_dbuf_alloc: Failed(2).");
4254
4255 return (NULL);
4256
4319
4320 return (bctl->bctl_buf);
4321 }
4322 mutex_exit(&p->dmem_lock);
4323
4324 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
4325 "emlx_fct_buf_alloc size %d Nothing free bck %d",
4326 size, i);
4327 }
4328 }
4329
4330 *pminsize = 0;
4331 TGTPORTSTAT.FctNoBuffer++;
4332
4333 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
4334 "emlxs_fct_dbuf_alloc: Failed(2).");
4335
4336 return (NULL);
4337
4257} /* emlxs_fct_dbuf_alloc() */
4338} /* emlxs_fct_dbuf_alloc() */
4258
4259
4339
4340
4260/* ARGSUSED */
4341/*ARGSUSED*/
4261static void
4262emlxs_fct_dbuf_free(fct_dbuf_store_t *fds, stmf_data_buf_t *dbuf)
4263{
4264 emlxs_fct_dmem_bctl_t *bctl =
4265 (emlxs_fct_dmem_bctl_t *)dbuf->db_port_private;
4266 emlxs_fct_dmem_bucket_t *p = bctl->bctl_bucket;
4267
4268#ifdef FCT_API_TRACE
4269 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
4270 "emlx_fct_buf_free %p", dbuf);
4342static void
4343emlxs_fct_dbuf_free(fct_dbuf_store_t *fds, stmf_data_buf_t *dbuf)
4344{
4345 emlxs_fct_dmem_bctl_t *bctl =
4346 (emlxs_fct_dmem_bctl_t *)dbuf->db_port_private;
4347 emlxs_fct_dmem_bucket_t *p = bctl->bctl_bucket;
4348
4349#ifdef FCT_API_TRACE
4350 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_api_msg,
4351 "emlx_fct_buf_free %p", dbuf);
4271#endif /* FCT_API_TRACE */
4352#endif /* FCT_API_TRACE */
4272
4273 mutex_enter(&p->dmem_lock);
4274 bctl->bctl_next = p->dmem_bctl_free_list;
4275 p->dmem_bctl_free_list = bctl;
4276 p->dmem_nbufs_free++;
4277 mutex_exit(&p->dmem_lock);
4278
4353
4354 mutex_enter(&p->dmem_lock);
4355 bctl->bctl_next = p->dmem_bctl_free_list;
4356 p->dmem_bctl_free_list = bctl;
4357 p->dmem_nbufs_free++;
4358 mutex_exit(&p->dmem_lock);
4359
4279} /* emlxs_fct_dbuf_free() */
4360} /* emlxs_fct_dbuf_free() */
4280
4281
4361
4362
4282void
4363static void
4283emlxs_fct_dbuf_dma_sync(stmf_data_buf_t *dbuf, uint_t sync_type)
4284{
4285 emlxs_fct_dmem_bctl_t *bctl =
4286 (emlxs_fct_dmem_bctl_t *)dbuf->db_port_private;
4287 emlxs_fct_dmem_bucket_t *p = bctl->bctl_bucket;
4288
4289 (void) ddi_dma_sync(p->dmem_dma_handle,
4290 (unsigned long)(bctl->bctl_dev_addr - p->dmem_dev_addr),
4291 dbuf->db_data_size, sync_type);
4292
4364emlxs_fct_dbuf_dma_sync(stmf_data_buf_t *dbuf, uint_t sync_type)
4365{
4366 emlxs_fct_dmem_bctl_t *bctl =
4367 (emlxs_fct_dmem_bctl_t *)dbuf->db_port_private;
4368 emlxs_fct_dmem_bucket_t *p = bctl->bctl_bucket;
4369
4370 (void) ddi_dma_sync(p->dmem_dma_handle,
4371 (unsigned long)(bctl->bctl_dev_addr - p->dmem_dev_addr),
4372 dbuf->db_data_size, sync_type);
4373
4293} /* emlxs_fct_dbuf_dma_sync() */
4374} /* emlxs_fct_dbuf_dma_sync() */
4294
4295
4375
4376
4296#endif /* SFCT_SUPPORT */
4377#endif /* SFCT_SUPPORT */