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
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
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 2009 Emulex.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 
28 #include <emlxs.h>
29 
30 /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
31 EMLXS_MSG_DEF(EMLXS_FCP_C);
32 
33 #define	EMLXS_GET_VADDR(hba, rp, icmd) emlxs_mem_get_vaddr(hba, rp, \
34 	PADDR(icmd->un.cont64[i].addrHigh, icmd->un.cont64[i].addrLow));
35 
36 static void	emlxs_sbp_abort_add(emlxs_port_t *port, emlxs_buf_t *sbp,
37     Q *abort, uint8_t *flag, emlxs_buf_t *fpkt);
38 
39 #define	SCSI3_PERSISTENT_RESERVE_IN	0x5e
40 #define	SCSI_INQUIRY			0x12
41 #define	SCSI_RX_DIAG    		0x1C
42 
43 
44 /*
45  *  emlxs_handle_fcp_event
46  *
47  *  Description: Process an FCP Rsp Ring completion
48  *
49  */
50 /* ARGSUSED */
51 extern void
52 emlxs_handle_fcp_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
53 {
54 	emlxs_port_t *port = &PPORT;
55 	emlxs_config_t	*cfg = &CFG;
56 	IOCB *cmd;
57 	emlxs_buf_t *sbp;
58 	fc_packet_t *pkt = NULL;
59 #ifdef SAN_DIAG_SUPPORT
60 	NODELIST *ndlp;
61 #endif
62 	uint32_t iostat;
63 	uint8_t localstat;
64 	fcp_rsp_t *rsp;
65 	uint32_t rsp_data_resid;
66 	uint32_t check_underrun;
67 	uint8_t asc;
68 	uint8_t ascq;
69 	uint8_t scsi_status;
70 	uint8_t sense;
71 	uint32_t did;
72 	uint32_t fix_it;
73 	uint8_t *scsi_cmd;
74 	uint8_t scsi_opcode;
75 	uint16_t scsi_dl;
76 	uint32_t data_rx;
77 
78 	cmd = &iocbq->iocb;
79 
80 	/* Initialize the status */
81 	iostat = cmd->ULPSTATUS;
82 	localstat = 0;
83 	scsi_status = 0;
84 	asc = 0;
85 	ascq = 0;
86 	sense = 0;
87 	check_underrun = 0;
88 	fix_it = 0;
89 
90 	HBASTATS.FcpEvent++;
91 
92 	sbp = (emlxs_buf_t *)iocbq->sbp;
93 
94 	if (!sbp) {
95 		/* completion with missing xmit command */
96 		HBASTATS.FcpStray++;
97 
98 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_fcp_completion_msg,
99 		    "cmd=%x iotag=%x", cmd->ULPCOMMAND, cmd->ULPIOTAG);
100 
101 		return;
102 	}
103 
104 	HBASTATS.FcpCompleted++;
105 
106 #ifdef SAN_DIAG_SUPPORT
107 	emlxs_update_sd_bucket(sbp);
108 #endif /* SAN_DIAG_SUPPORT */
109 
110 	pkt = PRIV2PKT(sbp);
111 
112 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
113 	scsi_cmd = (uint8_t *)pkt->pkt_cmd;
114 	scsi_opcode = scsi_cmd[12];
115 	data_rx = 0;
116 
117 	/* Sync data in data buffer only on FC_PKT_FCP_READ */
118 	if (pkt->pkt_datalen && (pkt->pkt_tran_type == FC_PKT_FCP_READ)) {
119 		EMLXS_MPDATA_SYNC(pkt->pkt_data_dma, 0, pkt->pkt_datalen,
120 		    DDI_DMA_SYNC_FORKERNEL);
121 
122 #ifdef TEST_SUPPORT
123 		if (hba->underrun_counter && (iostat == IOSTAT_SUCCESS) &&
124 		    (pkt->pkt_datalen >= 512)) {
125 			hba->underrun_counter--;
126 			iostat = IOSTAT_FCP_RSP_ERROR;
127 
128 			/* Report 512 bytes missing by adapter */
129 			cmd->un.fcpi.fcpi_parm = pkt->pkt_datalen - 512;
130 
131 			/* Corrupt 512 bytes of Data buffer */
132 			bzero((uint8_t *)pkt->pkt_data, 512);
133 
134 			/* Set FCP response to STATUS_GOOD */
135 			bzero((uint8_t *)pkt->pkt_resp, pkt->pkt_rsplen);
136 		}
137 #endif /* TEST_SUPPORT */
138 	}
139 
140 	/* Process the pkt */
141 	mutex_enter(&sbp->mtx);
142 
143 	/* Check for immediate return */
144 	if ((iostat == IOSTAT_SUCCESS) &&
145 	    (pkt->pkt_comp) &&
146 	    !(sbp->pkt_flags &
147 	    (PACKET_ULP_OWNED | PACKET_COMPLETED |
148 	    PACKET_IN_COMPLETION | PACKET_IN_TXQ | PACKET_IN_CHIPQ |
149 	    PACKET_IN_DONEQ | PACKET_IN_TIMEOUT | PACKET_IN_FLUSH |
150 	    PACKET_IN_ABORT | PACKET_POLLED))) {
151 		HBASTATS.FcpGood++;
152 
153 		sbp->pkt_flags |=
154 		    (PACKET_STATE_VALID | PACKET_IN_COMPLETION |
155 		    PACKET_COMPLETED | PACKET_ULP_OWNED);
156 		mutex_exit(&sbp->mtx);
157 
158 #if (EMLXS_MODREVX == EMLXS_MODREV2X)
159 		emlxs_unswap_pkt(sbp);
160 #endif /* EMLXS_MODREV2X */
161 
162 #ifdef FMA_SUPPORT
163 		emlxs_check_dma(hba, sbp);
164 #endif  /* FMA_SUPPORT */
165 
166 		cp->ulpCmplCmd++;
167 		(*pkt->pkt_comp) (pkt);
168 
169 #ifdef FMA_SUPPORT
170 		if (hba->flag & FC_DMA_CHECK_ERROR) {
171 			emlxs_thread_spawn(hba, emlxs_restart_thread,
172 			    NULL, NULL);
173 		}
174 #endif  /* FMA_SUPPORT */
175 
176 		return;
177 	}
178 
179 	/*
180 	 * A response is only placed in the resp buffer if IOSTAT_FCP_RSP_ERROR
181 	 * is reported.
182 	 */
183 
184 	/* Check if a response buffer was provided */
185 	if ((iostat == IOSTAT_FCP_RSP_ERROR) && pkt->pkt_rsplen) {
186 		EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen,
187 		    DDI_DMA_SYNC_FORKERNEL);
188 
189 		/* Get the response buffer pointer */
190 		rsp = (fcp_rsp_t *)pkt->pkt_resp;
191 
192 		/* Set the valid response flag */
193 		sbp->pkt_flags |= PACKET_FCP_RSP_VALID;
194 
195 		scsi_status = rsp->fcp_u.fcp_status.scsi_status;
196 
197 #ifdef SAN_DIAG_SUPPORT
198 		ndlp = (NODELIST *)iocbq->node;
199 		if (scsi_status == SCSI_STAT_QUE_FULL) {
200 			emlxs_log_sd_scsi_event(port, SD_SCSI_SUBCATEGORY_QFULL,
201 			    (HBA_WWN *)&ndlp->nlp_portname, sbp->lun);
202 		} else if (scsi_status == SCSI_STAT_BUSY) {
203 			emlxs_log_sd_scsi_event(port,
204 			    SD_SCSI_SUBCATEGORY_DEVBSY,
205 			    (HBA_WWN *)&ndlp->nlp_portname, sbp->lun);
206 		}
207 #endif
208 
209 		/*
210 		 * Convert a task abort to a check condition with no data
211 		 * transferred. We saw a data corruption when Solaris received
212 		 * a Task Abort from a tape.
213 		 */
214 		if (scsi_status == SCSI_STAT_TASK_ABORT) {
215 			EMLXS_MSGF(EMLXS_CONTEXT,
216 			    &emlxs_fcp_completion_error_msg,
217 			    "Task Abort. "
218 			    "Fixed.did=0x%06x sbp=%p cmd=%02x dl=%d",
219 			    did, sbp, scsi_opcode, pkt->pkt_datalen);
220 
221 			rsp->fcp_u.fcp_status.scsi_status =
222 			    SCSI_STAT_CHECK_COND;
223 			rsp->fcp_u.fcp_status.rsp_len_set = 0;
224 			rsp->fcp_u.fcp_status.sense_len_set = 0;
225 			rsp->fcp_u.fcp_status.resid_over = 0;
226 
227 			if (pkt->pkt_datalen) {
228 				rsp->fcp_u.fcp_status.resid_under = 1;
229 				rsp->fcp_resid =
230 				    LE_SWAP32(pkt->pkt_datalen);
231 			} else {
232 				rsp->fcp_u.fcp_status.resid_under = 0;
233 				rsp->fcp_resid = 0;
234 			}
235 
236 			scsi_status = SCSI_STAT_CHECK_COND;
237 		}
238 
239 		/*
240 		 * We only need to check underrun if data could
241 		 * have been sent
242 		 */
243 
244 		/* Always check underrun if status is good */
245 		if (scsi_status == SCSI_STAT_GOOD) {
246 			check_underrun = 1;
247 		}
248 		/* Check the sense codes if this is a check condition */
249 		else if (scsi_status == SCSI_STAT_CHECK_COND) {
250 			check_underrun = 1;
251 
252 			/* Check if sense data was provided */
253 			if (LE_SWAP32(rsp->fcp_sense_len) >= 14) {
254 				sense = *((uint8_t *)rsp + 32 + 2);
255 				asc = *((uint8_t *)rsp + 32 + 12);
256 				ascq = *((uint8_t *)rsp + 32 + 13);
257 			}
258 
259 #ifdef SAN_DIAG_SUPPORT
260 			emlxs_log_sd_scsi_check_event(port,
261 			    (HBA_WWN *)&ndlp->nlp_portname, sbp->lun,
262 			    scsi_opcode, sense, asc, ascq);
263 #endif
264 		}
265 		/* Status is not good and this is not a check condition */
266 		/* No data should have been sent */
267 		else {
268 			check_underrun = 0;
269 		}
270 
271 		/* Get the residual underrun count reported by the SCSI reply */
272 		rsp_data_resid = (pkt->pkt_datalen &&
273 		    rsp->fcp_u.fcp_status.resid_under) ? LE_SWAP32(rsp->
274 		    fcp_resid) : 0;
275 
276 		/* Set the pkt resp_resid field */
277 		pkt->pkt_resp_resid = 0;
278 
279 		/* Set the pkt data_resid field */
280 		if (pkt->pkt_datalen &&
281 		    (pkt->pkt_tran_type == FC_PKT_FCP_READ)) {
282 			/*
283 			 * Get the residual underrun count reported by
284 			 * our adapter
285 			 */
286 			pkt->pkt_data_resid = cmd->un.fcpi.fcpi_parm;
287 
288 #ifdef SAN_DIAG_SUPPORT
289 			if ((rsp_data_resid == 0) && (pkt->pkt_data_resid)) {
290 				emlxs_log_sd_fc_rdchk_event(port,
291 				    (HBA_WWN *)&ndlp->nlp_portname, sbp->lun,
292 				    scsi_opcode, pkt->pkt_data_resid);
293 			}
294 #endif
295 
296 			/* Get the actual amount of data transferred */
297 			data_rx = pkt->pkt_datalen - pkt->pkt_data_resid;
298 
299 			/*
300 			 * If the residual being reported by the adapter is
301 			 * greater than the residual being reported in the
302 			 * reply, then we have a true underrun.
303 			 */
304 			if (check_underrun &&
305 			    (pkt->pkt_data_resid > rsp_data_resid)) {
306 				switch (scsi_opcode) {
307 				case SCSI_INQUIRY:
308 					scsi_dl = scsi_cmd[16];
309 					break;
310 
311 				case SCSI_RX_DIAG:
312 					scsi_dl =
313 					    (scsi_cmd[15] * 0x100) +
314 					    scsi_cmd[16];
315 					break;
316 
317 				default:
318 					scsi_dl = pkt->pkt_datalen;
319 				}
320 
321 #ifdef FCP_UNDERRUN_PATCH1
322 if (cfg[CFG_ENABLE_PATCH].current & FCP_UNDERRUN_PATCH1) {
323 				/*
324 				 * If status is not good and no data was
325 				 * actually transferred, then we must fix
326 				 * the issue
327 				 */
328 				if ((scsi_status != SCSI_STAT_GOOD) &&
329 				    (data_rx == 0)) {
330 					fix_it = 1;
331 
332 					EMLXS_MSGF(EMLXS_CONTEXT,
333 					    &emlxs_fcp_completion_error_msg,
334 					    "Underrun(1). Fixed. "
335 					    "did=0x%06x sbp=%p cmd=%02x "
336 					    "dl=%d,%d rx=%d rsp=%d",
337 					    did, sbp, scsi_opcode,
338 					    pkt->pkt_datalen, scsi_dl,
339 					    (pkt->pkt_datalen -
340 					    cmd->un.fcpi.fcpi_parm),
341 					    rsp_data_resid);
342 
343 				}
344 }
345 #endif /* FCP_UNDERRUN_PATCH1 */
346 
347 
348 #ifdef FCP_UNDERRUN_PATCH2
349 if (cfg[CFG_ENABLE_PATCH].current & FCP_UNDERRUN_PATCH2) {
350 				if ((scsi_status == SCSI_STAT_GOOD)) {
351 					emlxs_msg_t	*msg;
352 
353 					msg = &emlxs_fcp_completion_error_msg;
354 					/*
355 					 * If status is good and this is an
356 					 * inquiry request and the amount of
357 					 * data
358 					 */
359 					/*
360 					 * requested <= data received, then we
361 					 * must fix the issue.
362 					 */
363 
364 					if ((scsi_opcode == SCSI_INQUIRY) &&
365 					    (pkt->pkt_datalen >= data_rx) &&
366 					    (scsi_dl <= data_rx)) {
367 						fix_it = 1;
368 
369 						EMLXS_MSGF(EMLXS_CONTEXT, msg,
370 						    "Underrun(2). Fixed. "
371 						    "did=0x%06x sbp=%p "
372 						    "cmd=%02x dl=%d,%d "
373 						    "rx=%d rsp=%d",
374 						    did, sbp, scsi_opcode,
375 						    pkt->pkt_datalen, scsi_dl,
376 						    data_rx, rsp_data_resid);
377 
378 					}
379 
380 					/*
381 					 * If status is good and this is an
382 					 * inquiry request and the amount of
383 					 * data requested >= 128 bytes, but
384 					 * only 128 bytes were received,
385 					 * then we must fix the issue.
386 					 */
387 					else if ((scsi_opcode ==
388 					    SCSI_INQUIRY) &&
389 					    (pkt->pkt_datalen >= 128) &&
390 					    (scsi_dl >= 128) &&
391 					    (data_rx == 128)) {
392 						fix_it = 1;
393 
394 						EMLXS_MSGF(EMLXS_CONTEXT, msg,
395 						    "Underrun(3). Fixed. "
396 						    "did=0x%06x sbp=%p "
397 						    "cmd=%02x dl=%d,%d "
398 						    "rx=%d rsp=%d",
399 						    did, sbp, scsi_opcode,
400 						    pkt->pkt_datalen, scsi_dl,
401 						    data_rx, rsp_data_resid);
402 
403 					}
404 
405 				}
406 }
407 #endif /* FCP_UNDERRUN_PATCH2 */
408 
409 				/*
410 				 * Check if SCSI response payload should be
411 				 * fixed or if a DATA_UNDERRUN should be
412 				 * reported
413 				 */
414 				if (fix_it) {
415 					/*
416 					 * Fix the SCSI response payload itself
417 					 */
418 					rsp->fcp_u.fcp_status.resid_under = 1;
419 					rsp->fcp_resid =
420 					    LE_SWAP32(pkt->pkt_data_resid);
421 				} else {
422 					/*
423 					 * Change the status from
424 					 * IOSTAT_FCP_RSP_ERROR to
425 					 * IOSTAT_DATA_UNDERRUN
426 					 */
427 					iostat = IOSTAT_DATA_UNDERRUN;
428 					pkt->pkt_data_resid =
429 					    pkt->pkt_datalen;
430 				}
431 			}
432 
433 			/*
434 			 * If the residual being reported by the adapter is
435 			 * less than the residual being reported in the reply,
436 			 * then we have a true overrun. Since we don't know
437 			 * where the extra data came from or went to then we
438 			 * cannot trust anything we received
439 			 */
440 			else if (rsp_data_resid > pkt->pkt_data_resid) {
441 				/*
442 				 * Change the status from
443 				 * IOSTAT_FCP_RSP_ERROR to
444 				 * IOSTAT_DATA_OVERRUN
445 				 */
446 				iostat = IOSTAT_DATA_OVERRUN;
447 				pkt->pkt_data_resid = pkt->pkt_datalen;
448 			}
449 		} else {	/* pkt->pkt_datalen==0 or FC_PKT_FCP_WRITE */
450 
451 			/* Report whatever the target reported */
452 			pkt->pkt_data_resid = rsp_data_resid;
453 		}
454 	}
455 
456 	/* Print completion message */
457 	switch (iostat) {
458 	case IOSTAT_SUCCESS:
459 		/* Build SCSI GOOD status */
460 		if (pkt->pkt_rsplen) {
461 			bzero((uint8_t *)pkt->pkt_resp, pkt->pkt_rsplen);
462 		}
463 		break;
464 
465 	case IOSTAT_FCP_RSP_ERROR:
466 		break;
467 
468 	case IOSTAT_REMOTE_STOP:
469 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
470 		    "Remote Stop. did=0x%06x sbp=%p cmd=%02x", did, sbp,
471 		    scsi_opcode);
472 		break;
473 
474 	case IOSTAT_LOCAL_REJECT:
475 		localstat = cmd->un.grsp.perr.statLocalError;
476 
477 		switch (localstat) {
478 		case IOERR_SEQUENCE_TIMEOUT:
479 			EMLXS_MSGF(EMLXS_CONTEXT,
480 			    &emlxs_fcp_completion_error_msg,
481 			    "Local reject. "
482 			    "%s did=0x%06x sbp=%p cmd=%02x tmo=%d ",
483 			    emlxs_error_xlate(localstat), did, sbp,
484 			    scsi_opcode, pkt->pkt_timeout);
485 			break;
486 
487 		default:
488 			EMLXS_MSGF(EMLXS_CONTEXT,
489 			    &emlxs_fcp_completion_error_msg,
490 			    "Local reject. %s did=0x%06x sbp=%p cmd=%02x",
491 			    emlxs_error_xlate(localstat), did, sbp,
492 			    scsi_opcode);
493 		}
494 
495 		break;
496 
497 	case IOSTAT_NPORT_RJT:
498 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
499 		    "Nport reject. did=0x%06x sbp=%p cmd=%02x", did, sbp,
500 		    scsi_opcode);
501 		break;
502 
503 	case IOSTAT_FABRIC_RJT:
504 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
505 		    "Fabric reject. did=0x%06x sbp=%p cmd=%02x", did, sbp,
506 		    scsi_opcode);
507 		break;
508 
509 	case IOSTAT_NPORT_BSY:
510 #ifdef SAN_DIAG_SUPPORT
511 		ndlp = (NODELIST *)iocbq->node;
512 		emlxs_log_sd_fc_bsy_event(port, (HBA_WWN *)&ndlp->nlp_portname);
513 #endif
514 
515 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
516 		    "Nport busy. did=0x%06x sbp=%p cmd=%02x", did, sbp,
517 		    scsi_opcode);
518 		break;
519 
520 	case IOSTAT_FABRIC_BSY:
521 #ifdef SAN_DIAG_SUPPORT
522 		ndlp = (NODELIST *)iocbq->node;
523 		emlxs_log_sd_fc_bsy_event(port, NULL);
524 #endif
525 
526 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
527 		    "Fabric busy. did=0x%06x sbp=%p cmd=%02x", did, sbp,
528 		    scsi_opcode);
529 		break;
530 
531 	case IOSTAT_INTERMED_RSP:
532 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
533 		    "Intermediate response. did=0x%06x sbp=%p cmd=%02x", did,
534 		    sbp, scsi_opcode);
535 		break;
536 
537 	case IOSTAT_LS_RJT:
538 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
539 		    "LS Reject. did=0x%06x sbp=%p cmd=%02x", did, sbp,
540 		    scsi_opcode);
541 		break;
542 
543 	case IOSTAT_DATA_UNDERRUN:
544 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
545 		    "Underrun. did=0x%06x sbp=%p cmd=%02x "
546 		    "dl=%d,%d rx=%d rsp=%d (%02x,%02x,%02x,%02x)",
547 		    did, sbp, scsi_opcode, pkt->pkt_datalen, scsi_dl, data_rx,
548 		    rsp_data_resid, scsi_status, sense, asc, ascq);
549 		break;
550 
551 	case IOSTAT_DATA_OVERRUN:
552 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
553 		    "Overrun. did=0x%06x sbp=%p cmd=%02x "
554 		    "dl=%d,%d rx=%d rsp=%d (%02x,%02x,%02x,%02x)",
555 		    did, sbp, scsi_opcode, pkt->pkt_datalen, scsi_dl, data_rx,
556 		    rsp_data_resid, scsi_status, sense, asc, ascq);
557 		break;
558 
559 	default:
560 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
561 		    "Unknown status=%x reason=%x did=0x%06x sbp=%p cmd=%02x",
562 		    iostat, cmd->un.grsp.perr.statLocalError, did, sbp,
563 		    scsi_opcode);
564 		break;
565 	}
566 
567 done:
568 
569 	if (iostat == IOSTAT_SUCCESS) {
570 		HBASTATS.FcpGood++;
571 	} else {
572 		HBASTATS.FcpError++;
573 	}
574 
575 	mutex_exit(&sbp->mtx);
576 
577 	emlxs_pkt_complete(sbp, iostat, localstat, 0);
578 
579 	return;
580 
581 } /* emlxs_handle_fcp_event() */
582 
583 
584 
585 /*
586  *  emlxs_post_buffer
587  *
588  *  This routine will post count buffers to the
589  *  ring with the QUE_RING_BUF_CN command. This
590  *  allows 2 buffers / command to be posted.
591  *  Returns the number of buffers NOT posted.
592  */
593 /* SLI3 */
594 extern int
595 emlxs_post_buffer(emlxs_hba_t *hba, RING *rp, int16_t cnt)
596 {
597 	emlxs_port_t *port = &PPORT;
598 	IOCB *icmd;
599 	IOCBQ *iocbq;
600 	MATCHMAP *mp;
601 	uint16_t tag;
602 	uint32_t maxqbuf;
603 	int32_t i;
604 	int32_t j;
605 	uint32_t seg;
606 	uint32_t size;
607 
608 	mp = 0;
609 	maxqbuf = 2;
610 	tag = (uint16_t)cnt;
611 	cnt += rp->fc_missbufcnt;
612 
613 	if (rp->ringno == hba->channel_els) {
614 		seg = MEM_BUF;
615 		size = MEM_ELSBUF_SIZE;
616 	} else if (rp->ringno == hba->channel_ip) {
617 		seg = MEM_IPBUF;
618 		size = MEM_IPBUF_SIZE;
619 	} else if (rp->ringno == hba->channel_ct) {
620 		seg = MEM_CTBUF;
621 		size = MEM_CTBUF_SIZE;
622 	}
623 #ifdef SFCT_SUPPORT
624 	else if (rp->ringno == hba->CHANNEL_FCT) {
625 		seg = MEM_FCTBUF;
626 		size = MEM_FCTBUF_SIZE;
627 	}
628 #endif /* SFCT_SUPPORT */
629 	else {
630 		return (0);
631 	}
632 
633 	/*
634 	 * While there are buffers to post
635 	 */
636 	while (cnt) {
637 		if ((iocbq = (IOCBQ *)emlxs_mem_get(hba, MEM_IOCB, 0)) == 0) {
638 			rp->fc_missbufcnt = cnt;
639 			return (cnt);
640 		}
641 
642 		iocbq->channel = (void *)&hba->chan[rp->ringno];
643 		iocbq->port = (void *)port;
644 		iocbq->flag |= (IOCB_PRIORITY | IOCB_SPECIAL);
645 
646 		icmd = &iocbq->iocb;
647 
648 		/*
649 		 * Max buffers can be posted per command
650 		 */
651 		for (i = 0; i < maxqbuf; i++) {
652 			if (cnt <= 0)
653 				break;
654 
655 			/* fill in BDEs for command */
656 			if ((mp = (MATCHMAP *)emlxs_mem_get(hba, seg, 1))
657 			    == 0) {
658 				icmd->ULPBDECOUNT = i;
659 				for (j = 0; j < i; j++) {
660 					mp = EMLXS_GET_VADDR(hba, rp, icmd);
661 					if (mp) {
662 						(void) emlxs_mem_put(hba, seg,
663 						    (uint8_t *)mp);
664 					}
665 				}
666 
667 				rp->fc_missbufcnt = cnt + i;
668 
669 				(void) emlxs_mem_put(hba, MEM_IOCB,
670 				    (uint8_t *)iocbq);
671 
672 				return (cnt + i);
673 			}
674 
675 			/*
676 			 * map that page and save the address pair for lookup
677 			 * later
678 			 */
679 			emlxs_mem_map_vaddr(hba,
680 			    rp,
681 			    mp,
682 			    (uint32_t *)&icmd->un.cont64[i].addrHigh,
683 			    (uint32_t *)&icmd->un.cont64[i].addrLow);
684 
685 			icmd->un.cont64[i].tus.f.bdeSize = size;
686 			icmd->ULPCOMMAND = CMD_QUE_RING_BUF64_CN;
687 
688 			/*
689 			 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
690 			 *    "UB Post: ring=%d addr=%08x%08x size=%d",
691 			 *    rp->ringno, icmd->un.cont64[i].addrHigh,
692 			 *    icmd->un.cont64[i].addrLow, size);
693 			 */
694 
695 			cnt--;
696 		}
697 
698 		icmd->ULPIOTAG = tag;
699 		icmd->ULPBDECOUNT = i;
700 		icmd->ULPLE = 1;
701 		icmd->ULPOWNER = OWN_CHIP;
702 		/* used for delimiter between commands */
703 		iocbq->bp = (uint8_t *)mp;
704 
705 		EMLXS_SLI_ISSUE_IOCB_CMD(hba, &hba->chan[rp->ringno], iocbq);
706 	}
707 
708 	rp->fc_missbufcnt = 0;
709 
710 	return (0);
711 
712 } /* emlxs_post_buffer() */
713 
714 
715 extern int
716 emlxs_port_offline(emlxs_port_t *port, uint32_t scope)
717 {
718 	emlxs_hba_t *hba = HBA;
719 	emlxs_config_t *cfg;
720 	NODELIST *nlp;
721 	fc_affected_id_t *aid;
722 	uint32_t mask;
723 	uint32_t aff_d_id;
724 	uint32_t linkdown;
725 	uint32_t vlinkdown;
726 	uint32_t action;
727 	int i;
728 	uint32_t unreg_vpi;
729 	uint32_t update;
730 	uint32_t adisc_support;
731 	uint8_t format;
732 
733 	/* Target mode only uses this routine for linkdowns */
734 	if (port->tgt_mode && (scope != 0xffffffff) && (scope != 0xfeffffff)) {
735 		return (0);
736 	}
737 
738 	cfg = &CFG;
739 	aid = (fc_affected_id_t *)&scope;
740 	linkdown = 0;
741 	vlinkdown = 0;
742 	unreg_vpi = 0;
743 	update = 0;
744 
745 	if (!(port->flag & EMLXS_PORT_BOUND)) {
746 		return (0);
747 	}
748 
749 	format = aid->aff_format;
750 
751 	switch (format) {
752 	case 0:	/* Port */
753 		mask = 0x00ffffff;
754 		break;
755 
756 	case 1:	/* Area */
757 		mask = 0x00ffff00;
758 		break;
759 
760 	case 2:	/* Domain */
761 		mask = 0x00ff0000;
762 		break;
763 
764 	case 3:	/* Network */
765 		mask = 0x00000000;
766 		break;
767 
768 #ifdef DHCHAP_SUPPORT
769 	case 0xfe:	/* Virtual link down */
770 		mask = 0x00000000;
771 		vlinkdown = 1;
772 		break;
773 #endif /* DHCHAP_SUPPORT */
774 
775 	case 0xff:	/* link is down */
776 		mask = 0x00000000;
777 		linkdown = 1;
778 		break;
779 
780 	}
781 
782 	aff_d_id = aid->aff_d_id & mask;
783 
784 
785 	/*
786 	 * If link is down then this is a hard shutdown and flush
787 	 * If link not down then this is a soft shutdown and flush
788 	 * (e.g. RSCN)
789 	 */
790 	if (linkdown) {
791 		mutex_enter(&EMLXS_PORT_LOCK);
792 
793 		port->flag &= EMLXS_PORT_LINKDOWN_MASK;
794 		port->prev_did = port->did;
795 		port->did = 0;
796 
797 		if (port->ulp_statec != FC_STATE_OFFLINE) {
798 			port->ulp_statec = FC_STATE_OFFLINE;
799 			update = 1;
800 		}
801 
802 		mutex_exit(&EMLXS_PORT_LOCK);
803 
804 		/* Tell ULP about it */
805 		if (update) {
806 			if (port->flag & EMLXS_PORT_BOUND) {
807 				if (port->vpi == 0) {
808 					EMLXS_MSGF(EMLXS_CONTEXT,
809 					    &emlxs_link_down_msg, NULL);
810 				}
811 
812 				if (port->ini_mode) {
813 					port->ulp_statec_cb(port->ulp_handle,
814 					    FC_STATE_OFFLINE);
815 				}
816 #ifdef SFCT_SUPPORT
817 				else if (port->tgt_mode) {
818 					emlxs_fct_link_down(port);
819 				}
820 #endif /* SFCT_SUPPORT */
821 
822 			} else {
823 				if (port->vpi == 0) {
824 					EMLXS_MSGF(EMLXS_CONTEXT,
825 					    &emlxs_link_down_msg, "*");
826 				}
827 			}
828 
829 
830 		}
831 
832 		unreg_vpi = 1;
833 
834 #ifdef DHCHAP_SUPPORT
835 		/* Stop authentication with all nodes */
836 		emlxs_dhc_auth_stop(port, NULL);
837 #endif /* DHCHAP_SUPPORT */
838 
839 		/* Flush the base node */
840 		(void) emlxs_tx_node_flush(port, &port->node_base, 0, 0, 0);
841 		(void) emlxs_chipq_node_flush(port, 0, &port->node_base, 0);
842 
843 		/* Flush any pending ub buffers */
844 		emlxs_ub_flush(port);
845 	}
846 #ifdef DHCHAP_SUPPORT
847 	/* virtual link down */
848 	else if (vlinkdown) {
849 		mutex_enter(&EMLXS_PORT_LOCK);
850 
851 		if (port->ulp_statec != FC_STATE_OFFLINE) {
852 			port->ulp_statec = FC_STATE_OFFLINE;
853 			update = 1;
854 		}
855 
856 		mutex_exit(&EMLXS_PORT_LOCK);
857 
858 		/* Tell ULP about it */
859 		if (update) {
860 			if (port->flag & EMLXS_PORT_BOUND) {
861 				if (port->vpi == 0) {
862 					EMLXS_MSGF(EMLXS_CONTEXT,
863 					    &emlxs_link_down_msg,
864 					    "Switch authentication failed.");
865 				}
866 
867 #ifdef SFCT_SUPPORT
868 				if (port->tgt_mode) {
869 					emlxs_fct_link_down(port);
870 
871 				} else if (port->ini_mode) {
872 					port->ulp_statec_cb(port->ulp_handle,
873 					    FC_STATE_OFFLINE);
874 				}
875 #else
876 				port->ulp_statec_cb(port->ulp_handle,
877 				    FC_STATE_OFFLINE);
878 #endif	/* SFCT_SUPPORT */
879 			} else {
880 				if (port->vpi == 0) {
881 					EMLXS_MSGF(EMLXS_CONTEXT,
882 					    &emlxs_link_down_msg,
883 					    "Switch authentication failed. *");
884 				}
885 			}
886 
887 
888 		}
889 
890 		/* Flush the base node */
891 		(void) emlxs_tx_node_flush(port, &port->node_base, 0, 0, 0);
892 		(void) emlxs_chipq_node_flush(port, 0, &port->node_base, 0);
893 	}
894 #endif /* DHCHAP_SUPPORT */
895 
896 	if (port->tgt_mode) {
897 		goto done;
898 	}
899 
900 	/* Set the node tags */
901 	/* We will process all nodes with this tag */
902 	rw_enter(&port->node_rwlock, RW_READER);
903 	for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) {
904 		nlp = port->node_table[i];
905 		while (nlp != NULL) {
906 			nlp->nlp_tag = 1;
907 			nlp = nlp->nlp_list_next;
908 		}
909 	}
910 	rw_exit(&port->node_rwlock);
911 
912 	if (hba->flag & FC_ONLINE_MODE) {
913 		adisc_support = cfg[CFG_ADISC_SUPPORT].current;
914 	} else {
915 		adisc_support = 0;
916 	}
917 
918 	/* Check ADISC support level */
919 	switch (adisc_support) {
920 	case 0:	/* No support - Flush all IO to all matching nodes */
921 
922 		for (;;) {
923 			/*
924 			 * We need to hold the locks this way because
925 			 * emlxs_mb_unreg_did and the flush routines enter the
926 			 * same locks. Also, when we release the lock the list
927 			 * can change out from under us.
928 			 */
929 
930 			/* Find first node */
931 			rw_enter(&port->node_rwlock, RW_READER);
932 			action = 0;
933 			for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) {
934 				nlp = port->node_table[i];
935 				while (nlp != NULL) {
936 					if (!nlp->nlp_tag) {
937 						nlp = nlp->nlp_list_next;
938 						continue;
939 					}
940 					nlp->nlp_tag = 0;
941 
942 					/*
943 					 * Check for any device that matches
944 					 * our mask
945 					 */
946 					if ((nlp->nlp_DID & mask) == aff_d_id) {
947 						if (linkdown) {
948 							action = 1;
949 							break;
950 						} else { /* Must be an RCSN */
951 
952 							action = 2;
953 							break;
954 						}
955 					}
956 					nlp = nlp->nlp_list_next;
957 				}
958 
959 				if (action) {
960 					break;
961 				}
962 			}
963 			rw_exit(&port->node_rwlock);
964 
965 
966 			/* Check if nothing was found */
967 			if (action == 0) {
968 				break;
969 			} else if (action == 1) {
970 				(void) emlxs_mb_unreg_did(port, nlp->nlp_DID,
971 				    NULL, NULL, NULL);
972 			} else if (action == 2) {
973 #ifdef DHCHAP_SUPPORT
974 				emlxs_dhc_auth_stop(port, nlp);
975 #endif /* DHCHAP_SUPPORT */
976 
977 				/*
978 				 * Close the node for any further normal IO
979 				 * A PLOGI with reopen the node
980 				 */
981 				emlxs_node_close(port, nlp,
982 				    hba->channel_fcp, 60);
983 				emlxs_node_close(port, nlp,
984 				    hba->channel_ip, 60);
985 
986 				/* Flush tx queue */
987 				(void) emlxs_tx_node_flush(port, nlp, 0, 0, 0);
988 
989 				/* Flush chip queue */
990 				(void) emlxs_chipq_node_flush(port, 0, nlp, 0);
991 			}
992 
993 		}
994 
995 		break;
996 
997 	case 1:	/* Partial support - Flush IO for non-FCP2 matching nodes */
998 
999 		for (;;) {
1000 
1001 			/*
1002 			 * We need to hold the locks this way because
1003 			 * emlxs_mb_unreg_did and the flush routines enter the
1004 			 * same locks. Also, when we release the lock the list
1005 			 * can change out from under us.
1006 			 */
1007 			rw_enter(&port->node_rwlock, RW_READER);
1008 			action = 0;
1009 			for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) {
1010 				nlp = port->node_table[i];
1011 				while (nlp != NULL) {
1012 					if (!nlp->nlp_tag) {
1013 						nlp = nlp->nlp_list_next;
1014 						continue;
1015 					}
1016 					nlp->nlp_tag = 0;
1017 
1018 					/*
1019 					 * Check for special FCP2 target device
1020 					 * that matches our mask
1021 					 */
1022 					if ((nlp->nlp_fcp_info &
1023 					    NLP_FCP_TGT_DEVICE) &&
1024 					    (nlp-> nlp_fcp_info &
1025 					    NLP_FCP_2_DEVICE) &&
1026 					    (nlp->nlp_DID & mask) ==
1027 					    aff_d_id) {
1028 						action = 3;
1029 						break;
1030 					}
1031 
1032 					/*
1033 					 * Check for any other device that
1034 					 * matches our mask
1035 					 */
1036 					else if ((nlp->nlp_DID & mask) ==
1037 					    aff_d_id) {
1038 						if (linkdown) {
1039 							action = 1;
1040 							break;
1041 						} else { /* Must be an RSCN */
1042 
1043 							action = 2;
1044 							break;
1045 						}
1046 					}
1047 
1048 					nlp = nlp->nlp_list_next;
1049 				}
1050 
1051 				if (action) {
1052 					break;
1053 				}
1054 			}
1055 			rw_exit(&port->node_rwlock);
1056 
1057 			/* Check if nothing was found */
1058 			if (action == 0) {
1059 				break;
1060 			} else if (action == 1) {
1061 				(void) emlxs_mb_unreg_did(port, nlp->nlp_DID,
1062 				    NULL, NULL, NULL);
1063 			} else if (action == 2) {
1064 #ifdef DHCHAP_SUPPORT
1065 				emlxs_dhc_auth_stop(port, nlp);
1066 #endif /* DHCHAP_SUPPORT */
1067 
1068 				/*
1069 				 * Close the node for any further normal IO
1070 				 * A PLOGI with reopen the node
1071 				 */
1072 				emlxs_node_close(port, nlp,
1073 				    hba->channel_fcp, 60);
1074 				emlxs_node_close(port, nlp,
1075 				    hba->channel_ip, 60);
1076 
1077 				/* Flush tx queue */
1078 				(void) emlxs_tx_node_flush(port, nlp, 0, 0, 0);
1079 
1080 				/* Flush chip queue */
1081 				(void) emlxs_chipq_node_flush(port, 0, nlp, 0);
1082 
1083 			} else if (action == 3) {	/* FCP2 devices */
1084 				unreg_vpi = 0;
1085 
1086 #ifdef DHCHAP_SUPPORT
1087 				emlxs_dhc_auth_stop(port, nlp);
1088 #endif /* DHCHAP_SUPPORT */
1089 
1090 				/*
1091 				 * Close the node for any further normal IO
1092 				 * An ADISC or a PLOGI with reopen the node
1093 				 */
1094 				emlxs_node_close(port, nlp,
1095 				    hba->channel_fcp, -1);
1096 				emlxs_node_close(port, nlp, hba->channel_ip,
1097 				    ((linkdown) ? 0 : 60));
1098 
1099 				/* Flush tx queues except for FCP ring */
1100 				(void) emlxs_tx_node_flush(port, nlp,
1101 				    &hba->chan[hba->channel_ct], 0, 0);
1102 				(void) emlxs_tx_node_flush(port, nlp,
1103 				    &hba->chan[hba->channel_els], 0, 0);
1104 				(void) emlxs_tx_node_flush(port, nlp,
1105 				    &hba->chan[hba->channel_ip], 0, 0);
1106 
1107 				/* Flush chip queues except for FCP ring */
1108 				(void) emlxs_chipq_node_flush(port,
1109 				    &hba->chan[hba->channel_ct], nlp, 0);
1110 				(void) emlxs_chipq_node_flush(port,
1111 				    &hba->chan[hba->channel_els], nlp, 0);
1112 				(void) emlxs_chipq_node_flush(port,
1113 				    &hba->chan[hba->channel_ip], nlp, 0);
1114 			}
1115 		}
1116 		break;
1117 
1118 	case 2:	/* Full support - Hold FCP IO to FCP target matching nodes */
1119 
1120 		if (!linkdown && !vlinkdown) {
1121 			break;
1122 		}
1123 
1124 		for (;;) {
1125 			/*
1126 			 * We need to hold the locks this way because
1127 			 * emlxs_mb_unreg_did and the flush routines enter the
1128 			 * same locks. Also, when we release the lock the list
1129 			 * can change out from under us.
1130 			 */
1131 			rw_enter(&port->node_rwlock, RW_READER);
1132 			action = 0;
1133 			for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) {
1134 				nlp = port->node_table[i];
1135 				while (nlp != NULL) {
1136 					if (!nlp->nlp_tag) {
1137 						nlp = nlp->nlp_list_next;
1138 						continue;
1139 					}
1140 					nlp->nlp_tag = 0;
1141 
1142 					/*
1143 					 * Check for FCP target device that
1144 					 * matches our mask
1145 					 */
1146 					if ((nlp-> nlp_fcp_info &
1147 					    NLP_FCP_TGT_DEVICE) &&
1148 					    (nlp->nlp_DID & mask) ==
1149 					    aff_d_id) {
1150 						action = 3;
1151 						break;
1152 					}
1153 
1154 					/*
1155 					 * Check for any other device that
1156 					 * matches our mask
1157 					 */
1158 					else if ((nlp->nlp_DID & mask) ==
1159 					    aff_d_id) {
1160 						if (linkdown) {
1161 							action = 1;
1162 							break;
1163 						} else { /* Must be an RSCN */
1164 
1165 							action = 2;
1166 							break;
1167 						}
1168 					}
1169 
1170 					nlp = nlp->nlp_list_next;
1171 				}
1172 				if (action) {
1173 					break;
1174 				}
1175 			}
1176 			rw_exit(&port->node_rwlock);
1177 
1178 			/* Check if nothing was found */
1179 			if (action == 0) {
1180 				break;
1181 			} else if (action == 1) {
1182 				(void) emlxs_mb_unreg_did(port, nlp->nlp_DID,
1183 				    NULL, NULL, NULL);
1184 			} else if (action == 2) {
1185 				/*
1186 				 * Close the node for any further normal IO
1187 				 * A PLOGI with reopen the node
1188 				 */
1189 				emlxs_node_close(port, nlp,
1190 				    hba->channel_fcp, 60);
1191 				emlxs_node_close(port, nlp,
1192 				    hba->channel_ip, 60);
1193 
1194 				/* Flush tx queue */
1195 				(void) emlxs_tx_node_flush(port, nlp, 0, 0, 0);
1196 
1197 				/* Flush chip queue */
1198 				(void) emlxs_chipq_node_flush(port, 0, nlp, 0);
1199 
1200 			} else if (action == 3) {	/* FCP2 devices */
1201 				unreg_vpi = 0;
1202 
1203 				/*
1204 				 * Close the node for any further normal IO
1205 				 * An ADISC or a PLOGI with reopen the node
1206 				 */
1207 				emlxs_node_close(port, nlp,
1208 				    hba->channel_fcp, -1);
1209 				emlxs_node_close(port, nlp, hba->channel_ip,
1210 				    ((linkdown) ? 0 : 60));
1211 
1212 				/* Flush tx queues except for FCP ring */
1213 				(void) emlxs_tx_node_flush(port, nlp,
1214 				    &hba->chan[hba->channel_ct], 0, 0);
1215 				(void) emlxs_tx_node_flush(port, nlp,
1216 				    &hba->chan[hba->channel_els], 0, 0);
1217 				(void) emlxs_tx_node_flush(port, nlp,
1218 				    &hba->chan[hba->channel_ip], 0, 0);
1219 
1220 				/* Flush chip queues except for FCP ring */
1221 				(void) emlxs_chipq_node_flush(port,
1222 				    &hba->chan[hba->channel_ct], nlp, 0);
1223 				(void) emlxs_chipq_node_flush(port,
1224 				    &hba->chan[hba->channel_els], nlp, 0);
1225 				(void) emlxs_chipq_node_flush(port,
1226 				    &hba->chan[hba->channel_ip], nlp, 0);
1227 			}
1228 		}
1229 
1230 		break;
1231 
1232 	}	/* switch() */
1233 
1234 done:
1235 
1236 	if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) {
1237 		if (unreg_vpi) {
1238 			(void) emlxs_mb_unreg_vpi(port);
1239 		}
1240 	}
1241 
1242 	return (0);
1243 
1244 } /* emlxs_port_offline() */
1245 
1246 
1247 extern void
1248 emlxs_port_online(emlxs_port_t *vport)
1249 {
1250 	emlxs_hba_t *hba = vport->hba;
1251 	emlxs_port_t *port = &PPORT;
1252 	uint32_t state;
1253 	uint32_t update;
1254 	uint32_t npiv_linkup;
1255 	char topology[32];
1256 	char linkspeed[32];
1257 	char mode[32];
1258 
1259 	/*
1260 	 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_up_msg,
1261 	 *    "linkup_callback. vpi=%d fc_flag=%x", vport->vpi, hba->flag);
1262 	 */
1263 
1264 	if ((vport->vpi > 0) &&
1265 	    (!(hba->flag & FC_NPIV_ENABLED) ||
1266 	    !(hba->flag & FC_NPIV_SUPPORTED))) {
1267 		return;
1268 	}
1269 
1270 	if (!(vport->flag & EMLXS_PORT_BOUND) ||
1271 	    !(vport->flag & EMLXS_PORT_ENABLE)) {
1272 		return;
1273 	}
1274 
1275 	mutex_enter(&EMLXS_PORT_LOCK);
1276 
1277 	/* Check for mode */
1278 	if (port->tgt_mode) {
1279 		(void) strcpy(mode, ", target");
1280 	} else if (port->ini_mode) {
1281 		(void) strcpy(mode, ", initiator");
1282 	} else {
1283 		(void) strcpy(mode, "");
1284 	}
1285 
1286 	/* Check for loop topology */
1287 	if (hba->topology == TOPOLOGY_LOOP) {
1288 		state = FC_STATE_LOOP;
1289 		(void) strcpy(topology, ", loop");
1290 	} else {
1291 		state = FC_STATE_ONLINE;
1292 		(void) strcpy(topology, ", fabric");
1293 	}
1294 
1295 	/* Set the link speed */
1296 	switch (hba->linkspeed) {
1297 	case 0:
1298 		(void) strcpy(linkspeed, "Gb");
1299 		state |= FC_STATE_1GBIT_SPEED;
1300 		break;
1301 
1302 	case LA_1GHZ_LINK:
1303 		(void) strcpy(linkspeed, "1Gb");
1304 		state |= FC_STATE_1GBIT_SPEED;
1305 		break;
1306 	case LA_2GHZ_LINK:
1307 		(void) strcpy(linkspeed, "2Gb");
1308 		state |= FC_STATE_2GBIT_SPEED;
1309 		break;
1310 	case LA_4GHZ_LINK:
1311 		(void) strcpy(linkspeed, "4Gb");
1312 		state |= FC_STATE_4GBIT_SPEED;
1313 		break;
1314 	case LA_8GHZ_LINK:
1315 		(void) strcpy(linkspeed, "8Gb");
1316 		state |= FC_STATE_8GBIT_SPEED;
1317 		break;
1318 	case LA_10GHZ_LINK:
1319 		(void) strcpy(linkspeed, "10Gb");
1320 		state |= FC_STATE_10GBIT_SPEED;
1321 		break;
1322 	default:
1323 		(void) sprintf(linkspeed, "unknown(0x%x)", hba->linkspeed);
1324 		break;
1325 	}
1326 
1327 	npiv_linkup = 0;
1328 	update = 0;
1329 
1330 	if ((hba->state >= FC_LINK_UP) &&
1331 	    !(hba->flag & FC_LOOPBACK_MODE) && (vport->ulp_statec != state)) {
1332 		update = 1;
1333 		vport->ulp_statec = state;
1334 
1335 		if ((vport->vpi > 0) && !(hba->flag & FC_NPIV_LINKUP)) {
1336 			hba->flag |= FC_NPIV_LINKUP;
1337 			npiv_linkup = 1;
1338 		}
1339 	}
1340 
1341 	mutex_exit(&EMLXS_PORT_LOCK);
1342 
1343 
1344 	/*
1345 	 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_up_msg,
1346 	 *    "linkup_callback: update=%d vpi=%d flag=%d fc_flag=%x state=%x"
1347 	 *    "statec=%x", update, vport->vpi, npiv_linkup, hba->flag,
1348 	 *    hba->state, vport->ulp_statec);
1349 	 */
1350 
1351 	if (update) {
1352 		if (vport->flag & EMLXS_PORT_BOUND) {
1353 			if (vport->vpi == 0) {
1354 				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_up_msg,
1355 				    "%s%s%s", linkspeed, topology, mode);
1356 			} else if (npiv_linkup) {
1357 				EMLXS_MSGF(EMLXS_CONTEXT,
1358 				    &emlxs_npiv_link_up_msg, "%s%s%s",
1359 				    linkspeed, topology, mode);
1360 			}
1361 
1362 			if (vport->ini_mode) {
1363 				vport->ulp_statec_cb(vport->ulp_handle,
1364 				    state);
1365 			}
1366 #ifdef SFCT_SUPPORT
1367 			else if (vport->tgt_mode) {
1368 				emlxs_fct_link_up(vport);
1369 			}
1370 #endif /* SFCT_SUPPORT */
1371 		} else {
1372 			if (vport->vpi == 0) {
1373 				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_up_msg,
1374 				    "%s%s%s *", linkspeed, topology, mode);
1375 			} else if (npiv_linkup) {
1376 				EMLXS_MSGF(EMLXS_CONTEXT,
1377 				    &emlxs_npiv_link_up_msg, "%s%s%s *",
1378 				    linkspeed, topology, mode);
1379 			}
1380 		}
1381 
1382 		/* Check for waiting threads */
1383 		if (vport->vpi == 0) {
1384 			mutex_enter(&EMLXS_LINKUP_LOCK);
1385 			if (hba->linkup_wait_flag == TRUE) {
1386 				hba->linkup_wait_flag = FALSE;
1387 				cv_broadcast(&EMLXS_LINKUP_CV);
1388 			}
1389 			mutex_exit(&EMLXS_LINKUP_LOCK);
1390 		}
1391 
1392 		/* Flush any pending ub buffers */
1393 		emlxs_ub_flush(vport);
1394 	}
1395 
1396 	return;
1397 
1398 } /* emlxs_port_online() */
1399 
1400 
1401 extern void
1402 emlxs_linkdown(emlxs_hba_t *hba)
1403 {
1404 	emlxs_port_t *port = &PPORT;
1405 	RPIobj_t *rp;
1406 	int i;
1407 
1408 	mutex_enter(&EMLXS_PORT_LOCK);
1409 
1410 	if (hba->state > FC_LINK_DOWN) {
1411 		HBASTATS.LinkDown++;
1412 		EMLXS_STATE_CHANGE_LOCKED(hba, FC_LINK_DOWN);
1413 	}
1414 
1415 	/* Filter hba flags */
1416 	hba->flag &= FC_LINKDOWN_MASK;
1417 	hba->discovery_timer = 0;
1418 	hba->linkup_timer = 0;
1419 
1420 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
1421 		rp = hba->sli.sli4.RPIp;
1422 		for (i = 0; i < hba->sli.sli4.RPICount; i++) {
1423 			if (rp->state & RESOURCE_ALLOCATED) {
1424 				rp->state |= RESOURCE_RPI_PAUSED;
1425 			}
1426 			rp++;
1427 		}
1428 	}
1429 
1430 	mutex_exit(&EMLXS_PORT_LOCK);
1431 
1432 	for (i = 0; i < MAX_VPORTS; i++) {
1433 		port = &VPORT(i);
1434 
1435 		if (!(port->flag & EMLXS_PORT_BOUND)) {
1436 			continue;
1437 		}
1438 
1439 		(void) emlxs_port_offline(port, 0xffffffff);
1440 
1441 	}
1442 
1443 	return;
1444 
1445 } /* emlxs_linkdown() */
1446 
1447 
1448 extern void
1449 emlxs_linkup(emlxs_hba_t *hba)
1450 {
1451 	emlxs_port_t *port = &PPORT;
1452 	emlxs_config_t *cfg = &CFG;
1453 
1454 	mutex_enter(&EMLXS_PORT_LOCK);
1455 
1456 	HBASTATS.LinkUp++;
1457 	EMLXS_STATE_CHANGE_LOCKED(hba, FC_LINK_UP);
1458 
1459 #ifdef MENLO_SUPPORT
1460 	if (hba->flag & FC_MENLO_MODE) {
1461 		mutex_exit(&EMLXS_PORT_LOCK);
1462 
1463 		/*
1464 		 * Trigger linkup CV and don't start linkup & discovery
1465 		 * timers
1466 		 */
1467 		mutex_enter(&EMLXS_LINKUP_LOCK);
1468 		cv_broadcast(&EMLXS_LINKUP_CV);
1469 		mutex_exit(&EMLXS_LINKUP_LOCK);
1470 
1471 		return;
1472 	}
1473 #endif /* MENLO_SUPPORT */
1474 
1475 	/* Set the linkup & discovery timers */
1476 	hba->linkup_timer = hba->timer_tics + cfg[CFG_LINKUP_TIMEOUT].current;
1477 	hba->discovery_timer =
1478 	    hba->timer_tics + cfg[CFG_LINKUP_TIMEOUT].current +
1479 	    cfg[CFG_DISC_TIMEOUT].current;
1480 
1481 	mutex_exit(&EMLXS_PORT_LOCK);
1482 
1483 	return;
1484 
1485 } /* emlxs_linkup() */
1486 
1487 
1488 /*
1489  *  emlxs_reset_link
1490  *
1491  *  Description:
1492  *  Called to reset the link with an init_link
1493  *
1494  *    Returns:
1495  *
1496  */
1497 extern int
1498 emlxs_reset_link(emlxs_hba_t *hba, uint32_t linkup, uint32_t wait)
1499 {
1500 	emlxs_port_t *port = &PPORT;
1501 	emlxs_config_t *cfg;
1502 	MAILBOXQ *mbq = NULL;
1503 	MAILBOX *mb = NULL;
1504 	int rval = 0;
1505 	int rc;
1506 
1507 	/*
1508 	 * Get a buffer to use for the mailbox command
1509 	 */
1510 	if ((mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))
1511 	    == NULL) {
1512 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_reset_failed_msg,
1513 		    "Unable to allocate mailbox buffer.");
1514 		rval = 1;
1515 		goto reset_link_fail;
1516 	}
1517 
1518 	mb = (MAILBOX *)mbq;
1519 
1520 	/* Bring link down first */
1521 	emlxs_mb_down_link(hba, mbq);
1522 
1523 #define	MBXERR_LINK_DOWN	0x33
1524 
1525 	if (wait) {
1526 		wait = MBX_WAIT;
1527 	} else {
1528 		wait = MBX_NOWAIT;
1529 	}
1530 	rc =  EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, wait, 0);
1531 	if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS) &&
1532 	    (rc != MBXERR_LINK_DOWN)) {
1533 		rval = 1;
1534 		goto reset_link_fail;
1535 	}
1536 
1537 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_reset_msg,
1538 	    "Disabling link...");
1539 
1540 	if (linkup) {
1541 		/*
1542 		 * Setup and issue mailbox INITIALIZE LINK command
1543 		 */
1544 
1545 		if (wait == MBX_NOWAIT) {
1546 			if ((mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))
1547 			    == NULL) {
1548 				EMLXS_MSGF(EMLXS_CONTEXT,
1549 				    &emlxs_link_reset_failed_msg,
1550 				    "Unable to allocate mailbox buffer.");
1551 				rval = 1;
1552 				goto reset_link_fail;
1553 			}
1554 			mb = (MAILBOX *)mbq;
1555 		} else {
1556 			/* Reuse mbq from previous mbox */
1557 			mb = (MAILBOX *)mbq;
1558 		}
1559 		cfg = &CFG;
1560 
1561 		emlxs_mb_init_link(hba, mbq,
1562 		    cfg[CFG_TOPOLOGY].current, cfg[CFG_LINK_SPEED].current);
1563 
1564 		mb->un.varInitLnk.lipsr_AL_PA = 0;
1565 
1566 		/* Clear the loopback mode */
1567 		mutex_enter(&EMLXS_PORT_LOCK);
1568 		hba->flag &= ~FC_LOOPBACK_MODE;
1569 		hba->loopback_tics = 0;
1570 		mutex_exit(&EMLXS_PORT_LOCK);
1571 
1572 		rc =  EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, wait, 0);
1573 		if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
1574 			rval = 1;
1575 			goto reset_link_fail;
1576 		}
1577 
1578 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_reset_msg, NULL);
1579 	}
1580 
1581 reset_link_fail:
1582 
1583 	if ((wait == MBX_WAIT) && mbq) {
1584 		(void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
1585 	}
1586 
1587 	return (rval);
1588 } /* emlxs_reset_link() */
1589 
1590 
1591 extern int
1592 emlxs_online(emlxs_hba_t *hba)
1593 {
1594 	emlxs_port_t *port = &PPORT;
1595 	int32_t rval = 0;
1596 	uint32_t i = 0;
1597 
1598 	/* Make sure adapter is offline or exit trying (30 seconds) */
1599 	while (i++ < 30) {
1600 		/* Check if adapter is already going online */
1601 		if (hba->flag & (FC_ONLINE_MODE | FC_ONLINING_MODE)) {
1602 			return (0);
1603 		}
1604 
1605 		mutex_enter(&EMLXS_PORT_LOCK);
1606 
1607 		/* Check again */
1608 		if (hba->flag & (FC_ONLINE_MODE | FC_ONLINING_MODE)) {
1609 			mutex_exit(&EMLXS_PORT_LOCK);
1610 			return (0);
1611 		}
1612 
1613 		/* Check if adapter is offline */
1614 		if (hba->flag & FC_OFFLINE_MODE) {
1615 			/* Mark it going online */
1616 			hba->flag &= ~FC_OFFLINE_MODE;
1617 			hba->flag |= FC_ONLINING_MODE;
1618 
1619 			/* Currently !FC_ONLINE_MODE and !FC_OFFLINE_MODE */
1620 			mutex_exit(&EMLXS_PORT_LOCK);
1621 			break;
1622 		}
1623 
1624 		mutex_exit(&EMLXS_PORT_LOCK);
1625 
1626 		DELAYMS(1000);
1627 	}
1628 
1629 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_adapter_trans_msg,
1630 	    "Going online...");
1631 
1632 	if (rval = EMLXS_SLI_ONLINE(hba)) {
1633 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, "status=%x",
1634 		    rval);
1635 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_offline_msg, NULL);
1636 
1637 		/* Set FC_OFFLINE_MODE */
1638 		mutex_enter(&EMLXS_PORT_LOCK);
1639 		emlxs_diag_state = DDI_OFFDI;
1640 		hba->flag |= FC_OFFLINE_MODE;
1641 		hba->flag &= ~FC_ONLINING_MODE;
1642 		mutex_exit(&EMLXS_PORT_LOCK);
1643 
1644 		return (rval);
1645 	}
1646 
1647 	/* Start the timer */
1648 	emlxs_timer_start(hba);
1649 
1650 	/* Set FC_ONLINE_MODE */
1651 	mutex_enter(&EMLXS_PORT_LOCK);
1652 	emlxs_diag_state = DDI_ONDI;
1653 	hba->flag |= FC_ONLINE_MODE;
1654 	hba->flag &= ~FC_ONLINING_MODE;
1655 	mutex_exit(&EMLXS_PORT_LOCK);
1656 
1657 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_online_msg, NULL);
1658 
1659 #ifdef SFCT_SUPPORT
1660 	(void) emlxs_fct_port_initialize(port);
1661 #endif /* SFCT_SUPPORT */
1662 
1663 	return (rval);
1664 
1665 } /* emlxs_online() */
1666 
1667 
1668 extern int
1669 emlxs_offline(emlxs_hba_t *hba)
1670 {
1671 	emlxs_port_t *port = &PPORT;
1672 	uint32_t i = 0;
1673 	int rval = 1;
1674 
1675 	/* Make sure adapter is online or exit trying (30 seconds) */
1676 	while (i++ < 30) {
1677 		/* Check if adapter is already going offline */
1678 		if (hba->flag & (FC_OFFLINE_MODE | FC_OFFLINING_MODE)) {
1679 			return (0);
1680 		}
1681 
1682 		mutex_enter(&EMLXS_PORT_LOCK);
1683 
1684 		/* Check again */
1685 		if (hba->flag & (FC_OFFLINE_MODE | FC_OFFLINING_MODE)) {
1686 			mutex_exit(&EMLXS_PORT_LOCK);
1687 			return (0);
1688 		}
1689 
1690 		/* Check if adapter is online */
1691 		if (hba->flag & FC_ONLINE_MODE) {
1692 			/* Mark it going offline */
1693 			hba->flag &= ~FC_ONLINE_MODE;
1694 			hba->flag |= FC_OFFLINING_MODE;
1695 
1696 			/* Currently !FC_ONLINE_MODE and !FC_OFFLINE_MODE */
1697 			mutex_exit(&EMLXS_PORT_LOCK);
1698 			break;
1699 		}
1700 
1701 		mutex_exit(&EMLXS_PORT_LOCK);
1702 
1703 		DELAYMS(1000);
1704 	}
1705 
1706 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_adapter_trans_msg,
1707 	    "Going offline...");
1708 
1709 	if (port->ini_mode) {
1710 		/* Flush all IO */
1711 		emlxs_linkdown(hba);
1712 	}
1713 #ifdef SFCT_SUPPORT
1714 	else {
1715 		(void) emlxs_fct_port_shutdown(port);
1716 	}
1717 #endif /* SFCT_SUPPORT */
1718 
1719 	/* Check if adapter was shutdown */
1720 	if (hba->flag & FC_HARDWARE_ERROR) {
1721 		/*
1722 		 * Force mailbox cleanup
1723 		 * This will wake any sleeping or polling threads
1724 		 */
1725 		emlxs_mb_fini(hba, NULL, MBX_HARDWARE_ERROR);
1726 	}
1727 
1728 	/* Pause here for the IO to settle */
1729 	delay(drv_usectohz(1000000));	/* 1 sec */
1730 
1731 	/* Unregister all nodes */
1732 	emlxs_ffcleanup(hba);
1733 
1734 	if (hba->bus_type == SBUS_FC) {
1735 		WRITE_SBUS_CSR_REG(hba, FC_SHS_REG(hba), 0x9A);
1736 #ifdef FMA_SUPPORT
1737 		/* Access handle validation */
1738 		EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.sbus_csr_handle);
1739 #endif  /* FMA_SUPPORT */
1740 	}
1741 
1742 	/* Stop the timer */
1743 	emlxs_timer_stop(hba);
1744 
1745 	/* For safety flush every iotag list */
1746 	if (emlxs_iotag_flush(hba)) {
1747 		/* Pause here for the IO to flush */
1748 		delay(drv_usectohz(1000));
1749 	}
1750 
1751 	/* Wait for poll command request to settle */
1752 	while (hba->io_poll_count > 0) {
1753 		delay(drv_usectohz(2000000));   /* 2 sec */
1754 	}
1755 
1756 	/* Shutdown the adapter interface */
1757 	EMLXS_SLI_OFFLINE(hba);
1758 
1759 	mutex_enter(&EMLXS_PORT_LOCK);
1760 	hba->flag |= FC_OFFLINE_MODE;
1761 	hba->flag &= ~FC_OFFLINING_MODE;
1762 	emlxs_diag_state = DDI_OFFDI;
1763 	mutex_exit(&EMLXS_PORT_LOCK);
1764 
1765 	rval = 0;
1766 
1767 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_offline_msg, NULL);
1768 
1769 done:
1770 
1771 	return (rval);
1772 
1773 } /* emlxs_offline() */
1774 
1775 
1776 
1777 extern int
1778 emlxs_power_down(emlxs_hba_t *hba)
1779 {
1780 #ifdef FMA_SUPPORT
1781 	emlxs_port_t *port = &PPORT;
1782 #endif  /* FMA_SUPPORT */
1783 	int32_t rval = 0;
1784 	uint32_t *ptr;
1785 	uint32_t i;
1786 
1787 	if ((rval = emlxs_offline(hba))) {
1788 		return (rval);
1789 	}
1790 	EMLXS_SLI_HBA_RESET(hba, 1, 1, 0);
1791 
1792 	/* Save pci config space */
1793 	ptr = (uint32_t *)hba->pm_config;
1794 	for (i = 0; i < PCI_CONFIG_SIZE; i += 4, ptr++) {
1795 		*ptr =
1796 		    ddi_get32(hba->pci_acc_handle,
1797 		    (uint32_t *)(hba->pci_addr + i));
1798 	}
1799 
1800 	/* Put chip in D3 state */
1801 	(void) ddi_put8(hba->pci_acc_handle,
1802 	    (uint8_t *)(hba->pci_addr + PCI_PM_CONTROL_REGISTER),
1803 	    (uint8_t)PCI_PM_D3_STATE);
1804 
1805 #ifdef FMA_SUPPORT
1806 	if (emlxs_fm_check_acc_handle(hba, hba->pci_acc_handle)
1807 	    != DDI_FM_OK) {
1808 		EMLXS_MSGF(EMLXS_CONTEXT,
1809 		    &emlxs_invalid_access_handle_msg, NULL);
1810 		return (1);
1811 	}
1812 #endif  /* FMA_SUPPORT */
1813 
1814 	return (0);
1815 
1816 } /* End emlxs_power_down */
1817 
1818 
1819 extern int
1820 emlxs_power_up(emlxs_hba_t *hba)
1821 {
1822 #ifdef FMA_SUPPORT
1823 	emlxs_port_t *port = &PPORT;
1824 #endif  /* FMA_SUPPORT */
1825 	int32_t rval = 0;
1826 	uint32_t *ptr;
1827 	uint32_t i;
1828 
1829 
1830 	/* Take chip out of D3 state */
1831 	(void) ddi_put8(hba->pci_acc_handle,
1832 	    (uint8_t *)(hba->pci_addr + PCI_PM_CONTROL_REGISTER),
1833 	    (uint8_t)PCI_PM_D0_STATE);
1834 
1835 	/* Must have at least 10 ms delay here */
1836 	DELAYMS(100);
1837 
1838 	/* Restore pci config space */
1839 	ptr = (uint32_t *)hba->pm_config;
1840 	for (i = 0; i < PCI_CONFIG_SIZE; i += 4, ptr++) {
1841 		(void) ddi_put32(hba->pci_acc_handle,
1842 		    (uint32_t *)(hba->pci_addr + i), *ptr);
1843 	}
1844 
1845 #ifdef FMA_SUPPORT
1846 	if (emlxs_fm_check_acc_handle(hba, hba->pci_acc_handle)
1847 	    != DDI_FM_OK) {
1848 		EMLXS_MSGF(EMLXS_CONTEXT,
1849 		    &emlxs_invalid_access_handle_msg, NULL);
1850 		return (1);
1851 	}
1852 #endif  /* FMA_SUPPORT */
1853 
1854 	/* Bring adapter online */
1855 	if ((rval = emlxs_online(hba))) {
1856 		(void) ddi_put8(hba->pci_acc_handle,
1857 		    (uint8_t *)(hba->pci_addr + PCI_PM_CONTROL_REGISTER),
1858 		    (uint8_t)PCI_PM_D3_STATE);
1859 
1860 		return (rval);
1861 	}
1862 
1863 	return (rval);
1864 
1865 } /* End emlxs_power_up */
1866 
1867 
1868 /*
1869  *
1870  * NAME:     emlxs_ffcleanup
1871  *
1872  * FUNCTION: Cleanup all the Firefly resources used by configuring the adapter
1873  *
1874  * EXECUTION ENVIRONMENT: process only
1875  *
1876  * CALLED FROM: CFG_TERM
1877  *
1878  * INPUT: hba       - pointer to the dev_ctl area.
1879  *
1880  * RETURNS: none
1881  */
1882 extern void
1883 emlxs_ffcleanup(emlxs_hba_t *hba)
1884 {
1885 	emlxs_port_t *port = &PPORT;
1886 	uint32_t i;
1887 
1888 	/* Disable all but the mailbox interrupt */
1889 	EMLXS_SLI_DISABLE_INTR(hba, HC_MBINT_ENA);
1890 
1891 	/* Make sure all port nodes are destroyed */
1892 	for (i = 0; i < MAX_VPORTS; i++) {
1893 		port = &VPORT(i);
1894 
1895 		if (port->node_count) {
1896 			if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
1897 				(void) emlxs_sli4_unreg_all_rpi_by_port(port);
1898 			} else {
1899 				(void) emlxs_mb_unreg_rpi(port, 0xffff, 0, 0,
1900 				    0);
1901 			}
1902 		}
1903 	}
1904 
1905 	/* Clear all interrupt enable conditions */
1906 	EMLXS_SLI_DISABLE_INTR(hba, 0);
1907 
1908 	return;
1909 
1910 } /* emlxs_ffcleanup() */
1911 
1912 
1913 extern uint16_t
1914 emlxs_register_pkt(CHANNEL *cp, emlxs_buf_t *sbp)
1915 {
1916 	emlxs_hba_t *hba;
1917 	emlxs_port_t *port;
1918 	uint16_t iotag;
1919 	uint32_t i;
1920 
1921 	hba = cp->hba;
1922 
1923 	mutex_enter(&EMLXS_FCTAB_LOCK);
1924 
1925 	if (sbp->iotag != 0) {
1926 		port = &PPORT;
1927 
1928 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
1929 		    "Pkt already registered! channel=%d iotag=%d sbp=%p",
1930 		    sbp->channel, sbp->iotag, sbp);
1931 	}
1932 
1933 	iotag = 0;
1934 	for (i = 0; i < hba->max_iotag; i++) {
1935 		if (!hba->fc_iotag || hba->fc_iotag >= hba->max_iotag) {
1936 			hba->fc_iotag = 1;
1937 		}
1938 		iotag = hba->fc_iotag++;
1939 
1940 		if (hba->fc_table[iotag] == 0 ||
1941 		    hba->fc_table[iotag] == STALE_PACKET) {
1942 			hba->io_count++;
1943 			hba->fc_table[iotag] = sbp;
1944 
1945 			sbp->iotag = iotag;
1946 			sbp->channel = cp;
1947 
1948 			break;
1949 		}
1950 		iotag = 0;
1951 	}
1952 
1953 	mutex_exit(&EMLXS_FCTAB_LOCK);
1954 
1955 	/*
1956 	 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
1957 	 *    "emlxs_register_pkt: channel=%d iotag=%d sbp=%p",
1958 	 *    cp->channelno, iotag, sbp);
1959 	 */
1960 
1961 	return (iotag);
1962 
1963 } /* emlxs_register_pkt() */
1964 
1965 
1966 
1967 extern emlxs_buf_t *
1968 emlxs_unregister_pkt(CHANNEL *cp, uint16_t iotag, uint32_t forced)
1969 {
1970 	emlxs_hba_t *hba;
1971 	emlxs_buf_t *sbp;
1972 
1973 	sbp = NULL;
1974 	hba = cp->hba;
1975 
1976 	/* Check the iotag range */
1977 	if ((iotag == 0) || (iotag >= hba->max_iotag)) {
1978 		return (NULL);
1979 	}
1980 
1981 	/* Remove the sbp from the table */
1982 	mutex_enter(&EMLXS_FCTAB_LOCK);
1983 	sbp = hba->fc_table[iotag];
1984 
1985 	if (!sbp || (sbp == STALE_PACKET)) {
1986 		mutex_exit(&EMLXS_FCTAB_LOCK);
1987 		return (sbp);
1988 	}
1989 
1990 	hba->fc_table[iotag] = ((forced) ? STALE_PACKET : NULL);
1991 	hba->io_count--;
1992 	sbp->iotag = 0;
1993 
1994 	mutex_exit(&EMLXS_FCTAB_LOCK);
1995 
1996 
1997 	/* Clean up the sbp */
1998 	mutex_enter(&sbp->mtx);
1999 
2000 	if (sbp->pkt_flags & PACKET_IN_TXQ) {
2001 		sbp->pkt_flags &= ~PACKET_IN_TXQ;
2002 		hba->channel_tx_count--;
2003 	}
2004 
2005 	if (sbp->pkt_flags & PACKET_IN_CHIPQ) {
2006 		sbp->pkt_flags &= ~PACKET_IN_CHIPQ;
2007 	}
2008 
2009 	if (sbp->bmp) {
2010 		(void) emlxs_mem_put(hba, MEM_BPL, (uint8_t *)sbp->bmp);
2011 		sbp->bmp = 0;
2012 	}
2013 
2014 	mutex_exit(&sbp->mtx);
2015 
2016 	return (sbp);
2017 
2018 } /* emlxs_unregister_pkt() */
2019 
2020 
2021 
2022 /* Flush all IO's to all nodes for a given IO Channel */
2023 extern uint32_t
2024 emlxs_tx_channel_flush(emlxs_hba_t *hba, CHANNEL *cp, emlxs_buf_t *fpkt)
2025 {
2026 	emlxs_port_t *port = &PPORT;
2027 	emlxs_buf_t *sbp;
2028 	IOCBQ *iocbq;
2029 	IOCBQ *next;
2030 	IOCB *iocb;
2031 	uint32_t channelno;
2032 	Q abort;
2033 	NODELIST *ndlp;
2034 	IOCB *icmd;
2035 	MATCHMAP *mp;
2036 	uint32_t i;
2037 	uint8_t flag[MAX_CHANNEL];
2038 
2039 	channelno = cp->channelno;
2040 	bzero((void *)&abort, sizeof (Q));
2041 	bzero((void *)flag, MAX_CHANNEL * sizeof (uint8_t));
2042 
2043 	mutex_enter(&EMLXS_TX_CHANNEL_LOCK);
2044 
2045 	/* While a node needs servicing */
2046 	while (cp->nodeq.q_first) {
2047 		ndlp = (NODELIST *) cp->nodeq.q_first;
2048 
2049 		/* Check if priority queue is not empty */
2050 		if (ndlp->nlp_ptx[channelno].q_first) {
2051 			/* Transfer all iocb's to local queue */
2052 			if (abort.q_first == 0) {
2053 				abort.q_first =
2054 				    ndlp->nlp_ptx[channelno].q_first;
2055 			} else {
2056 				((IOCBQ *)abort.q_last)->next =
2057 				    (IOCBQ *)ndlp->nlp_ptx[channelno].q_first;
2058 			}
2059 			flag[channelno] = 1;
2060 
2061 			abort.q_last = ndlp->nlp_ptx[channelno].q_last;
2062 			abort.q_cnt += ndlp->nlp_ptx[channelno].q_cnt;
2063 		}
2064 
2065 		/* Check if tx queue is not empty */
2066 		if (ndlp->nlp_tx[channelno].q_first) {
2067 			/* Transfer all iocb's to local queue */
2068 			if (abort.q_first == 0) {
2069 				abort.q_first = ndlp->nlp_tx[channelno].q_first;
2070 			} else {
2071 				((IOCBQ *)abort.q_last)->next =
2072 				    (IOCBQ *)ndlp->nlp_tx[channelno].q_first;
2073 			}
2074 
2075 			abort.q_last = ndlp->nlp_tx[channelno].q_last;
2076 			abort.q_cnt += ndlp->nlp_tx[channelno].q_cnt;
2077 		}
2078 
2079 		/* Clear the queue pointers */
2080 		ndlp->nlp_ptx[channelno].q_first = NULL;
2081 		ndlp->nlp_ptx[channelno].q_last = NULL;
2082 		ndlp->nlp_ptx[channelno].q_cnt = 0;
2083 
2084 		ndlp->nlp_tx[channelno].q_first = NULL;
2085 		ndlp->nlp_tx[channelno].q_last = NULL;
2086 		ndlp->nlp_tx[channelno].q_cnt = 0;
2087 
2088 		/* Remove node from service queue */
2089 
2090 		/* If this is the last node on list */
2091 		if (cp->nodeq.q_last == (void *)ndlp) {
2092 			cp->nodeq.q_last = NULL;
2093 			cp->nodeq.q_first = NULL;
2094 			cp->nodeq.q_cnt = 0;
2095 		} else {
2096 			/* Remove node from head */
2097 			cp->nodeq.q_first = ndlp->nlp_next[channelno];
2098 			((NODELIST *)cp->nodeq.q_last)->nlp_next[channelno] =
2099 			    cp->nodeq.q_first;
2100 			cp->nodeq.q_cnt--;
2101 		}
2102 
2103 		/* Clear node */
2104 		ndlp->nlp_next[channelno] = NULL;
2105 	}
2106 
2107 	/* First cleanup the iocb's while still holding the lock */
2108 	iocbq = (IOCBQ *) abort.q_first;
2109 	while (iocbq) {
2110 		/* Free the IoTag and the bmp */
2111 		iocb = &iocbq->iocb;
2112 
2113 		if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
2114 			sbp = iocbq->sbp;
2115 			if (sbp) {
2116 				hba->fc_table[sbp->iotag] = NULL;
2117 				emlxs_sli4_free_xri(hba, sbp, sbp->xp);
2118 			}
2119 		} else {
2120 			sbp = emlxs_unregister_pkt((CHANNEL *)iocbq->channel,
2121 			    iocb->ULPIOTAG, 0);
2122 		}
2123 
2124 		if (sbp && (sbp != STALE_PACKET)) {
2125 			mutex_enter(&sbp->mtx);
2126 
2127 			sbp->pkt_flags |= PACKET_IN_FLUSH;
2128 			/*
2129 			 * If the fpkt is already set, then we will leave it
2130 			 * alone. This ensures that this pkt is only accounted
2131 			 * for on one fpkt->flush_count
2132 			 */
2133 			if (!sbp->fpkt && fpkt) {
2134 				mutex_enter(&fpkt->mtx);
2135 				sbp->fpkt = fpkt;
2136 				fpkt->flush_count++;
2137 				mutex_exit(&fpkt->mtx);
2138 			}
2139 
2140 			mutex_exit(&sbp->mtx);
2141 		}
2142 
2143 		iocbq = (IOCBQ *)iocbq->next;
2144 	}	/* end of while */
2145 
2146 	mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
2147 
2148 	/* Now abort the iocb's */
2149 	iocbq = (IOCBQ *)abort.q_first;
2150 	while (iocbq) {
2151 		/* Save the next iocbq for now */
2152 		next = (IOCBQ *)iocbq->next;
2153 
2154 		/* Unlink this iocbq */
2155 		iocbq->next = NULL;
2156 
2157 		/* Get the pkt */
2158 		sbp = (emlxs_buf_t *)iocbq->sbp;
2159 
2160 		if (sbp) {
2161 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_flush_msg,
2162 			    "tx: sbp=%p node=%p", sbp, sbp->node);
2163 
2164 			if (hba->state >= FC_LINK_UP) {
2165 				emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
2166 				    IOERR_ABORT_REQUESTED, 1);
2167 			} else {
2168 				emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
2169 				    IOERR_LINK_DOWN, 1);
2170 			}
2171 
2172 		}
2173 		/* Free the iocb and its associated buffers */
2174 		else {
2175 			icmd = &iocbq->iocb;
2176 
2177 			/* SLI3 */
2178 			if (icmd->ULPCOMMAND == CMD_QUE_RING_BUF64_CN ||
2179 			    icmd->ULPCOMMAND == CMD_QUE_RING_BUF_CN ||
2180 			    icmd->ULPCOMMAND == CMD_QUE_RING_LIST64_CN) {
2181 				if ((hba->flag &
2182 				    (FC_ONLINE_MODE | FC_ONLINING_MODE)) == 0) {
2183 					/* HBA is detaching or offlining */
2184 					if (icmd->ULPCOMMAND !=
2185 					    CMD_QUE_RING_LIST64_CN) {
2186 						uint8_t	*tmp;
2187 						RING *rp;
2188 
2189 						rp = &hba->sli.sli3.
2190 						    ring[channelno];
2191 						for (i = 0;
2192 						    i < icmd->ULPBDECOUNT;
2193 						    i++) {
2194 							mp = EMLXS_GET_VADDR(
2195 							    hba, rp, icmd);
2196 
2197 							tmp = (uint8_t *)mp;
2198 							if (mp) {
2199 							(void) emlxs_mem_put(
2200 							    hba, MEM_BUF, tmp);
2201 							}
2202 						}
2203 					}
2204 
2205 					(void) emlxs_mem_put(hba, MEM_IOCB,
2206 					    (uint8_t *)iocbq);
2207 				} else {
2208 					/* repost the unsolicited buffer */
2209 					EMLXS_SLI_ISSUE_IOCB_CMD(hba, cp,
2210 					    iocbq);
2211 				}
2212 			} else if (icmd->ULPCOMMAND == CMD_CLOSE_XRI_CN ||
2213 			    icmd->ULPCOMMAND == CMD_CLOSE_XRI_CX) {
2214 
2215 				emlxs_tx_put(iocbq, 1);
2216 			}
2217 		}
2218 
2219 		iocbq = next;
2220 
2221 	}	/* end of while */
2222 
2223 	/* Now trigger channel service */
2224 	for (channelno = 0; channelno < hba->chan_count; channelno++) {
2225 		if (!flag[channelno]) {
2226 			continue;
2227 		}
2228 
2229 		EMLXS_SLI_ISSUE_IOCB_CMD(hba, &hba->chan[channelno], 0);
2230 	}
2231 
2232 	return (abort.q_cnt);
2233 
2234 } /* emlxs_tx_channel_flush() */
2235 
2236 
2237 /* Flush all IO's on all or a given ring for a given node */
2238 extern uint32_t
2239 emlxs_tx_node_flush(emlxs_port_t *port, NODELIST *ndlp, CHANNEL *chan,
2240     uint32_t shutdown, emlxs_buf_t *fpkt)
2241 {
2242 	emlxs_hba_t *hba = HBA;
2243 	emlxs_buf_t *sbp;
2244 	uint32_t channelno;
2245 	CHANNEL *cp;
2246 	IOCB *icmd;
2247 	IOCBQ *iocbq;
2248 	NODELIST *prev;
2249 	IOCBQ *next;
2250 	IOCB *iocb;
2251 	Q abort;
2252 	uint32_t i;
2253 	MATCHMAP *mp;
2254 	uint8_t flag[MAX_CHANNEL];
2255 
2256 	bzero((void *)&abort, sizeof (Q));
2257 
2258 	/* Flush all I/O's on tx queue to this target */
2259 	mutex_enter(&EMLXS_TX_CHANNEL_LOCK);
2260 
2261 	if (!ndlp->nlp_base && shutdown) {
2262 		ndlp->nlp_active = 0;
2263 	}
2264 
2265 	for (channelno = 0; channelno < hba->chan_count; channelno++) {
2266 		cp = &hba->chan[channelno];
2267 
2268 		if (chan && cp != chan) {
2269 			continue;
2270 		}
2271 
2272 		if (!ndlp->nlp_base || shutdown) {
2273 			/* Check if priority queue is not empty */
2274 			if (ndlp->nlp_ptx[channelno].q_first) {
2275 				/* Transfer all iocb's to local queue */
2276 				if (abort.q_first == 0) {
2277 					abort.q_first =
2278 					    ndlp->nlp_ptx[channelno].q_first;
2279 				} else {
2280 					((IOCBQ *)(abort.q_last))->next =
2281 					    (IOCBQ *)ndlp->nlp_ptx[channelno].
2282 					    q_first;
2283 				}
2284 
2285 				flag[channelno] = 1;
2286 
2287 				abort.q_last = ndlp->nlp_ptx[channelno].q_last;
2288 				abort.q_cnt += ndlp->nlp_ptx[channelno].q_cnt;
2289 			}
2290 		}
2291 
2292 		/* Check if tx queue is not empty */
2293 		if (ndlp->nlp_tx[channelno].q_first) {
2294 
2295 			/* Transfer all iocb's to local queue */
2296 			if (abort.q_first == 0) {
2297 				abort.q_first = ndlp->nlp_tx[channelno].q_first;
2298 			} else {
2299 				((IOCBQ *)abort.q_last)->next =
2300 				    (IOCBQ *)ndlp->nlp_tx[channelno].q_first;
2301 			}
2302 
2303 			abort.q_last = ndlp->nlp_tx[channelno].q_last;
2304 			abort.q_cnt += ndlp->nlp_tx[channelno].q_cnt;
2305 		}
2306 
2307 		/* Clear the queue pointers */
2308 		ndlp->nlp_ptx[channelno].q_first = NULL;
2309 		ndlp->nlp_ptx[channelno].q_last = NULL;
2310 		ndlp->nlp_ptx[channelno].q_cnt = 0;
2311 
2312 		ndlp->nlp_tx[channelno].q_first = NULL;
2313 		ndlp->nlp_tx[channelno].q_last = NULL;
2314 		ndlp->nlp_tx[channelno].q_cnt = 0;
2315 
2316 		/* If this node was on the channel queue, remove it */
2317 		if (ndlp->nlp_next[channelno]) {
2318 			/* If this is the only node on list */
2319 			if (cp->nodeq.q_first == (void *)ndlp &&
2320 			    cp->nodeq.q_last == (void *)ndlp) {
2321 				cp->nodeq.q_last = NULL;
2322 				cp->nodeq.q_first = NULL;
2323 				cp->nodeq.q_cnt = 0;
2324 			} else if (cp->nodeq.q_first == (void *)ndlp) {
2325 				cp->nodeq.q_first = ndlp->nlp_next[channelno];
2326 				((NODELIST *) cp->nodeq.q_last)->
2327 				    nlp_next[channelno] = cp->nodeq.q_first;
2328 				cp->nodeq.q_cnt--;
2329 			} else {
2330 				/*
2331 				 * This is a little more difficult find the
2332 				 * previous node in the circular channel queue
2333 				 */
2334 				prev = ndlp;
2335 				while (prev->nlp_next[channelno] != ndlp) {
2336 					prev = prev->nlp_next[channelno];
2337 				}
2338 
2339 				prev->nlp_next[channelno] =
2340 				    ndlp->nlp_next[channelno];
2341 
2342 				if (cp->nodeq.q_last == (void *)ndlp) {
2343 					cp->nodeq.q_last = (void *)prev;
2344 				}
2345 				cp->nodeq.q_cnt--;
2346 
2347 			}
2348 
2349 			/* Clear node */
2350 			ndlp->nlp_next[channelno] = NULL;
2351 		}
2352 
2353 	}
2354 
2355 	/* First cleanup the iocb's while still holding the lock */
2356 	iocbq = (IOCBQ *) abort.q_first;
2357 	while (iocbq) {
2358 		/* Free the IoTag and the bmp */
2359 		iocb = &iocbq->iocb;
2360 
2361 		if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
2362 			sbp = iocbq->sbp;
2363 			if (sbp) {
2364 				hba->fc_table[sbp->iotag] = NULL;
2365 				emlxs_sli4_free_xri(hba, sbp, sbp->xp);
2366 			}
2367 		} else {
2368 			sbp = emlxs_unregister_pkt((CHANNEL *)iocbq->channel,
2369 			    iocb->ULPIOTAG, 0);
2370 		}
2371 
2372 		if (sbp && (sbp != STALE_PACKET)) {
2373 			mutex_enter(&sbp->mtx);
2374 			sbp->pkt_flags |= PACKET_IN_FLUSH;
2375 			/*
2376 			 * If the fpkt is already set, then we will leave it
2377 			 * alone. This ensures that this pkt is only accounted
2378 			 * for on one fpkt->flush_count
2379 			 */
2380 			if (!sbp->fpkt && fpkt) {
2381 				mutex_enter(&fpkt->mtx);
2382 				sbp->fpkt = fpkt;
2383 				fpkt->flush_count++;
2384 				mutex_exit(&fpkt->mtx);
2385 			}
2386 
2387 			mutex_exit(&sbp->mtx);
2388 		}
2389 
2390 		iocbq = (IOCBQ *) iocbq->next;
2391 
2392 	}	/* end of while */
2393 
2394 	mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
2395 
2396 	/* Now abort the iocb's outside the locks */
2397 	iocbq = (IOCBQ *)abort.q_first;
2398 	while (iocbq) {
2399 		/* Save the next iocbq for now */
2400 		next = (IOCBQ *)iocbq->next;
2401 
2402 		/* Unlink this iocbq */
2403 		iocbq->next = NULL;
2404 
2405 		/* Get the pkt */
2406 		sbp = (emlxs_buf_t *)iocbq->sbp;
2407 
2408 		if (sbp) {
2409 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_flush_msg,
2410 			    "tx: sbp=%p node=%p", sbp, sbp->node);
2411 
2412 			if (hba->state >= FC_LINK_UP) {
2413 				emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
2414 				    IOERR_ABORT_REQUESTED, 1);
2415 			} else {
2416 				emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
2417 				    IOERR_LINK_DOWN, 1);
2418 			}
2419 
2420 		}
2421 		/* Free the iocb and its associated buffers */
2422 		else {
2423 			/* CMD_CLOSE_XRI_CN should also free the memory */
2424 			icmd = &iocbq->iocb;
2425 
2426 			/* SLI3 */
2427 			if (icmd->ULPCOMMAND == CMD_QUE_RING_BUF64_CN ||
2428 			    icmd->ULPCOMMAND == CMD_QUE_RING_BUF_CN ||
2429 			    icmd->ULPCOMMAND == CMD_QUE_RING_LIST64_CN) {
2430 				if ((hba->flag &
2431 				    (FC_ONLINE_MODE | FC_ONLINING_MODE)) == 0) {
2432 					/* HBA is detaching or offlining */
2433 					if (icmd->ULPCOMMAND !=
2434 					    CMD_QUE_RING_LIST64_CN) {
2435 						uint8_t	*tmp;
2436 						RING *rp;
2437 						int ch;
2438 
2439 						ch = ((CHANNEL *)
2440 						    iocbq->channel)->channelno;
2441 						rp = &hba->sli.sli3.ring[ch];
2442 						for (i = 0;
2443 						    i < icmd->ULPBDECOUNT;
2444 						    i++) {
2445 							mp = EMLXS_GET_VADDR(
2446 							    hba, rp, icmd);
2447 
2448 							tmp = (uint8_t *)mp;
2449 							if (mp) {
2450 							(void) emlxs_mem_put(
2451 							    hba, MEM_BUF, tmp);
2452 							}
2453 						}
2454 					}
2455 
2456 					(void) emlxs_mem_put(hba, MEM_IOCB,
2457 					    (uint8_t *)iocbq);
2458 				} else {
2459 					/* repost the unsolicited buffer */
2460 					EMLXS_SLI_ISSUE_IOCB_CMD(hba,
2461 					    (CHANNEL *)iocbq->channel, iocbq);
2462 				}
2463 			} else if (icmd->ULPCOMMAND == CMD_CLOSE_XRI_CN ||
2464 			    icmd->ULPCOMMAND == CMD_CLOSE_XRI_CX) {
2465 				/*
2466 				 * Resend the abort iocbq if any
2467 				 */
2468 				emlxs_tx_put(iocbq, 1);
2469 			}
2470 		}
2471 
2472 		iocbq = next;
2473 
2474 	}	/* end of while */
2475 
2476 	/* Now trigger channel service */
2477 	for (channelno = 0; channelno < hba->chan_count; channelno++) {
2478 		if (!flag[channelno]) {
2479 			continue;
2480 		}
2481 
2482 		EMLXS_SLI_ISSUE_IOCB_CMD(hba, &hba->chan[channelno], 0);
2483 	}
2484 
2485 	return (abort.q_cnt);
2486 
2487 } /* emlxs_tx_node_flush() */
2488 
2489 
2490 /* Check for IO's on all or a given ring for a given node */
2491 extern uint32_t
2492 emlxs_tx_node_check(emlxs_port_t *port, NODELIST *ndlp, CHANNEL *chan)
2493 {
2494 	emlxs_hba_t *hba = HBA;
2495 	uint32_t channelno;
2496 	CHANNEL *cp;
2497 	uint32_t count;
2498 
2499 	count = 0;
2500 
2501 	/* Flush all I/O's on tx queue to this target */
2502 	mutex_enter(&EMLXS_TX_CHANNEL_LOCK);
2503 
2504 	for (channelno = 0; channelno < hba->chan_count; channelno++) {
2505 		cp = &hba->chan[channelno];
2506 
2507 		if (chan && cp != chan) {
2508 			continue;
2509 		}
2510 
2511 		/* Check if priority queue is not empty */
2512 		if (ndlp->nlp_ptx[channelno].q_first) {
2513 			count += ndlp->nlp_ptx[channelno].q_cnt;
2514 		}
2515 
2516 		/* Check if tx queue is not empty */
2517 		if (ndlp->nlp_tx[channelno].q_first) {
2518 			count += ndlp->nlp_tx[channelno].q_cnt;
2519 		}
2520 
2521 	}
2522 
2523 	mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
2524 
2525 	return (count);
2526 
2527 } /* emlxs_tx_node_check() */
2528 
2529 
2530 
2531 /* Flush all IO's on the any ring for a given node's lun */
2532 extern uint32_t
2533 emlxs_tx_lun_flush(emlxs_port_t *port, NODELIST *ndlp, uint32_t lun,
2534     emlxs_buf_t *fpkt)
2535 {
2536 	emlxs_hba_t *hba = HBA;
2537 	emlxs_buf_t *sbp;
2538 	uint32_t channelno;
2539 	IOCBQ *iocbq;
2540 	IOCBQ *prev;
2541 	IOCBQ *next;
2542 	IOCB *iocb;
2543 	IOCB *icmd;
2544 	Q abort;
2545 	uint32_t i;
2546 	MATCHMAP *mp;
2547 	CHANNEL *cp;
2548 	CHANNEL *channel;
2549 	uint8_t flag[MAX_CHANNEL];
2550 
2551 	bzero((void *)&abort, sizeof (Q));
2552 
2553 	/* Flush I/O's on txQ to this target's lun */
2554 	mutex_enter(&EMLXS_TX_CHANNEL_LOCK);
2555 
2556 	channel = &hba->chan[hba->channel_fcp];
2557 
2558 	for (channelno = 0; channelno < hba->chan_count; channelno++) {
2559 		cp = &hba->chan[channelno];
2560 
2561 		if (channel && cp != channel) {
2562 			continue;
2563 		}
2564 
2565 		/* Scan the priority queue first */
2566 		prev = NULL;
2567 		iocbq = (IOCBQ *) ndlp->nlp_ptx[channelno].q_first;
2568 
2569 		while (iocbq) {
2570 			next = (IOCBQ *)iocbq->next;
2571 			iocb = &iocbq->iocb;
2572 			sbp = (emlxs_buf_t *)iocbq->sbp;
2573 
2574 			/* Check if this IO is for our lun */
2575 			if (sbp && (sbp->lun == lun)) {
2576 				/* Remove iocb from the node's ptx queue */
2577 				if (next == 0) {
2578 					ndlp->nlp_ptx[channelno].q_last =
2579 					    (uint8_t *)prev;
2580 				}
2581 
2582 				if (prev == 0) {
2583 					ndlp->nlp_ptx[channelno].q_first =
2584 					    (uint8_t *)next;
2585 				} else {
2586 					prev->next = next;
2587 				}
2588 
2589 				iocbq->next = NULL;
2590 				ndlp->nlp_ptx[channelno].q_cnt--;
2591 
2592 				/*
2593 				 * Add this iocb to our local abort Q
2594 				 */
2595 				if (abort.q_first) {
2596 					((IOCBQ *)abort.q_last)->next = iocbq;
2597 					abort.q_last = (uint8_t *)iocbq;
2598 					abort.q_cnt++;
2599 				} else {
2600 					abort.q_first = (uint8_t *)iocbq;
2601 					abort.q_last = (uint8_t *)iocbq;
2602 					abort.q_cnt = 1;
2603 				}
2604 				iocbq->next = NULL;
2605 				flag[channelno] = 1;
2606 
2607 			} else {
2608 				prev = iocbq;
2609 			}
2610 
2611 			iocbq = next;
2612 
2613 		}	/* while (iocbq) */
2614 
2615 
2616 		/* Scan the regular queue */
2617 		prev = NULL;
2618 		iocbq = (IOCBQ *)ndlp->nlp_tx[channelno].q_first;
2619 
2620 		while (iocbq) {
2621 			next = (IOCBQ *)iocbq->next;
2622 			iocb = &iocbq->iocb;
2623 			sbp = (emlxs_buf_t *)iocbq->sbp;
2624 
2625 			/* Check if this IO is for our lun */
2626 			if (sbp && (sbp->lun == lun)) {
2627 				/* Remove iocb from the node's tx queue */
2628 				if (next == 0) {
2629 					ndlp->nlp_tx[channelno].q_last =
2630 					    (uint8_t *)prev;
2631 				}
2632 
2633 				if (prev == 0) {
2634 					ndlp->nlp_tx[channelno].q_first =
2635 					    (uint8_t *)next;
2636 				} else {
2637 					prev->next = next;
2638 				}
2639 
2640 				iocbq->next = NULL;
2641 				ndlp->nlp_tx[channelno].q_cnt--;
2642 
2643 				/*
2644 				 * Add this iocb to our local abort Q
2645 				 */
2646 				if (abort.q_first) {
2647 					((IOCBQ *) abort.q_last)->next = iocbq;
2648 					abort.q_last = (uint8_t *)iocbq;
2649 					abort.q_cnt++;
2650 				} else {
2651 					abort.q_first = (uint8_t *)iocbq;
2652 					abort.q_last = (uint8_t *)iocbq;
2653 					abort.q_cnt = 1;
2654 				}
2655 				iocbq->next = NULL;
2656 			} else {
2657 				prev = iocbq;
2658 			}
2659 
2660 			iocbq = next;
2661 
2662 		}	/* while (iocbq) */
2663 	}	/* for loop */
2664 
2665 	/* First cleanup the iocb's while still holding the lock */
2666 	iocbq = (IOCBQ *)abort.q_first;
2667 	while (iocbq) {
2668 		/* Free the IoTag and the bmp */
2669 		iocb = &iocbq->iocb;
2670 
2671 		if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
2672 			sbp = iocbq->sbp;
2673 			if (sbp) {
2674 				hba->fc_table[sbp->iotag] = NULL;
2675 				emlxs_sli4_free_xri(hba, sbp, sbp->xp);
2676 			}
2677 		} else {
2678 			sbp = emlxs_unregister_pkt((CHANNEL *)iocbq->channel,
2679 			    iocb->ULPIOTAG, 0);
2680 		}
2681 
2682 		if (sbp && (sbp != STALE_PACKET)) {
2683 			mutex_enter(&sbp->mtx);
2684 			sbp->pkt_flags |= PACKET_IN_FLUSH;
2685 			/*
2686 			 * If the fpkt is already set, then we will leave it
2687 			 * alone. This ensures that this pkt is only accounted
2688 			 * for on one fpkt->flush_count
2689 			 */
2690 			if (!sbp->fpkt && fpkt) {
2691 				mutex_enter(&fpkt->mtx);
2692 				sbp->fpkt = fpkt;
2693 				fpkt->flush_count++;
2694 				mutex_exit(&fpkt->mtx);
2695 			}
2696 
2697 			mutex_exit(&sbp->mtx);
2698 		}
2699 
2700 		iocbq = (IOCBQ *) iocbq->next;
2701 
2702 	}	/* end of while */
2703 
2704 	mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
2705 
2706 	/* Now abort the iocb's outside the locks */
2707 	iocbq = (IOCBQ *)abort.q_first;
2708 	while (iocbq) {
2709 		/* Save the next iocbq for now */
2710 		next = (IOCBQ *)iocbq->next;
2711 
2712 		/* Unlink this iocbq */
2713 		iocbq->next = NULL;
2714 
2715 		/* Get the pkt */
2716 		sbp = (emlxs_buf_t *)iocbq->sbp;
2717 
2718 		if (sbp) {
2719 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_flush_msg,
2720 			    "tx: sbp=%p node=%p", sbp, sbp->node);
2721 
2722 			if (hba->state >= FC_LINK_UP) {
2723 				emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
2724 				    IOERR_ABORT_REQUESTED, 1);
2725 			} else {
2726 				emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
2727 				    IOERR_LINK_DOWN, 1);
2728 			}
2729 		}
2730 
2731 		/* Free the iocb and its associated buffers */
2732 		else {
2733 			/* Should never happen! */
2734 			icmd = &iocbq->iocb;
2735 
2736 			/* SLI3 */
2737 			if (icmd->ULPCOMMAND == CMD_QUE_RING_BUF64_CN ||
2738 			    icmd->ULPCOMMAND == CMD_QUE_RING_BUF_CN ||
2739 			    icmd->ULPCOMMAND == CMD_QUE_RING_LIST64_CN) {
2740 				if ((hba->flag &
2741 				    (FC_ONLINE_MODE | FC_ONLINING_MODE)) == 0) {
2742 					/* HBA is detaching or offlining */
2743 					if (icmd->ULPCOMMAND !=
2744 					    CMD_QUE_RING_LIST64_CN) {
2745 						uint8_t	*tmp;
2746 						RING *rp;
2747 						int ch;
2748 
2749 						ch = ((CHANNEL *)
2750 						    iocbq->channel)->channelno;
2751 						rp = &hba->sli.sli3.ring[ch];
2752 						for (i = 0;
2753 						    i < icmd->ULPBDECOUNT;
2754 						    i++) {
2755 							mp = EMLXS_GET_VADDR(
2756 							    hba, rp, icmd);
2757 
2758 							tmp = (uint8_t *)mp;
2759 							if (mp) {
2760 							(void) emlxs_mem_put(
2761 							    hba, MEM_BUF, tmp);
2762 							}
2763 						}
2764 					}
2765 
2766 					(void) emlxs_mem_put(hba, MEM_IOCB,
2767 					    (uint8_t *)iocbq);
2768 				} else {
2769 					/* repost the unsolicited buffer */
2770 					EMLXS_SLI_ISSUE_IOCB_CMD(hba,
2771 					    (CHANNEL *)iocbq->channel, iocbq);
2772 				}
2773 			} else if (icmd->ULPCOMMAND == CMD_CLOSE_XRI_CN ||
2774 			    icmd->ULPCOMMAND == CMD_CLOSE_XRI_CX) {
2775 				/*
2776 				 * Resend the abort iocbq if any
2777 				 */
2778 				emlxs_tx_put(iocbq, 1);
2779 			}
2780 		}
2781 
2782 		iocbq = next;
2783 
2784 	}	/* end of while */
2785 
2786 	/* Now trigger channel service */
2787 	for (channelno = 0; channelno < hba->chan_count; channelno++) {
2788 		if (!flag[channelno]) {
2789 			continue;
2790 		}
2791 
2792 		EMLXS_SLI_ISSUE_IOCB_CMD(hba, &hba->chan[channelno], 0);
2793 	}
2794 
2795 	return (abort.q_cnt);
2796 
2797 } /* emlxs_tx_lun_flush() */
2798 
2799 
2800 extern void
2801 emlxs_tx_put(IOCBQ *iocbq, uint32_t lock)
2802 {
2803 	emlxs_hba_t *hba;
2804 	emlxs_port_t *port;
2805 	uint32_t channelno;
2806 	NODELIST *nlp;
2807 	CHANNEL *cp;
2808 	emlxs_buf_t *sbp;
2809 
2810 	port = (emlxs_port_t *)iocbq->port;
2811 	hba = HBA;
2812 	cp = (CHANNEL *)iocbq->channel;
2813 	nlp = (NODELIST *)iocbq->node;
2814 	channelno = cp->channelno;
2815 	sbp = (emlxs_buf_t *)iocbq->sbp;
2816 
2817 	/* under what cases, nlp is NULL */
2818 	if (nlp == NULL) {
2819 		/* Set node to base node by default */
2820 		nlp = &port->node_base;
2821 
2822 		iocbq->node = (void *)nlp;
2823 
2824 		if (sbp) {
2825 			sbp->node = (void *)nlp;
2826 		}
2827 	}
2828 
2829 	if (lock) {
2830 		mutex_enter(&EMLXS_TX_CHANNEL_LOCK);
2831 	}
2832 
2833 	if (!nlp->nlp_active || (sbp && (sbp->pkt_flags & PACKET_IN_ABORT))) {
2834 		if (sbp) {
2835 			mutex_enter(&sbp->mtx);
2836 			sbp->pkt_flags |= PACKET_IN_FLUSH;
2837 			mutex_exit(&sbp->mtx);
2838 
2839 			if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
2840 				hba->fc_table[sbp->iotag] = NULL;
2841 				emlxs_sli4_free_xri(hba, sbp, sbp->xp);
2842 			} else {
2843 				(void) emlxs_unregister_pkt(cp, sbp->iotag, 0);
2844 			}
2845 
2846 			if (lock) {
2847 				mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
2848 			}
2849 
2850 			if (hba->state >= FC_LINK_UP) {
2851 				emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
2852 				    IOERR_ABORT_REQUESTED, 1);
2853 			} else {
2854 				emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
2855 				    IOERR_LINK_DOWN, 1);
2856 			}
2857 			return;
2858 		} else {
2859 			if (lock) {
2860 				mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
2861 			}
2862 
2863 			(void) emlxs_mem_put(hba, MEM_IOCB, (uint8_t *)iocbq);
2864 		}
2865 
2866 		return;
2867 	}
2868 
2869 	if (sbp) {
2870 
2871 		mutex_enter(&sbp->mtx);
2872 
2873 		if (sbp->pkt_flags &
2874 		    (PACKET_IN_COMPLETION | PACKET_IN_CHIPQ | PACKET_IN_TXQ)) {
2875 			mutex_exit(&sbp->mtx);
2876 			if (lock) {
2877 				mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
2878 			}
2879 			return;
2880 		}
2881 
2882 		sbp->pkt_flags |= PACKET_IN_TXQ;
2883 		hba->channel_tx_count++;
2884 
2885 		mutex_exit(&sbp->mtx);
2886 	}
2887 
2888 
2889 	/* Check iocbq priority */
2890 	/* Some IOCB has the high priority like reset/close xri etc */
2891 	if (iocbq->flag & IOCB_PRIORITY) {
2892 		/* Add the iocb to the bottom of the node's ptx queue */
2893 		if (nlp->nlp_ptx[channelno].q_first) {
2894 			((IOCBQ *)nlp->nlp_ptx[channelno].q_last)->next = iocbq;
2895 			nlp->nlp_ptx[channelno].q_last = (uint8_t *)iocbq;
2896 			nlp->nlp_ptx[channelno].q_cnt++;
2897 		} else {
2898 			nlp->nlp_ptx[channelno].q_first = (uint8_t *)iocbq;
2899 			nlp->nlp_ptx[channelno].q_last = (uint8_t *)iocbq;
2900 			nlp->nlp_ptx[channelno].q_cnt = 1;
2901 		}
2902 
2903 		iocbq->next = NULL;
2904 	} else {	/* Normal priority */
2905 
2906 
2907 		/* Add the iocb to the bottom of the node's tx queue */
2908 		if (nlp->nlp_tx[channelno].q_first) {
2909 			((IOCBQ *)nlp->nlp_tx[channelno].q_last)->next = iocbq;
2910 			nlp->nlp_tx[channelno].q_last = (uint8_t *)iocbq;
2911 			nlp->nlp_tx[channelno].q_cnt++;
2912 		} else {
2913 			nlp->nlp_tx[channelno].q_first = (uint8_t *)iocbq;
2914 			nlp->nlp_tx[channelno].q_last = (uint8_t *)iocbq;
2915 			nlp->nlp_tx[channelno].q_cnt = 1;
2916 		}
2917 
2918 		iocbq->next = NULL;
2919 	}
2920 
2921 
2922 	/*
2923 	 * Check if the node is not already on channel queue and
2924 	 * (is not closed or  is a priority request)
2925 	 */
2926 	if (!nlp->nlp_next[channelno] &&
2927 	    (!(nlp->nlp_flag[channelno] & NLP_CLOSED) ||
2928 	    (iocbq->flag & IOCB_PRIORITY))) {
2929 		/* If so, then add it to the channel queue */
2930 		if (cp->nodeq.q_first) {
2931 			((NODELIST *)cp->nodeq.q_last)->nlp_next[channelno] =
2932 			    (uint8_t *)nlp;
2933 			nlp->nlp_next[channelno] = cp->nodeq.q_first;
2934 
2935 			/*
2936 			 * If this is not the base node then add it
2937 			 * to the tail
2938 			 */
2939 			if (!nlp->nlp_base) {
2940 				cp->nodeq.q_last = (uint8_t *)nlp;
2941 			} else {	/* Otherwise, add it to the head */
2942 
2943 				/* The command node always gets priority */
2944 				cp->nodeq.q_first = (uint8_t *)nlp;
2945 			}
2946 
2947 			cp->nodeq.q_cnt++;
2948 		} else {
2949 			cp->nodeq.q_first = (uint8_t *)nlp;
2950 			cp->nodeq.q_last = (uint8_t *)nlp;
2951 			nlp->nlp_next[channelno] = nlp;
2952 			cp->nodeq.q_cnt = 1;
2953 		}
2954 	}
2955 
2956 	HBASTATS.IocbTxPut[channelno]++;
2957 
2958 	/* Adjust the channel timeout timer */
2959 	cp->timeout = hba->timer_tics + 5;
2960 
2961 	if (lock) {
2962 		mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
2963 	}
2964 
2965 	return;
2966 
2967 } /* emlxs_tx_put() */
2968 
2969 
2970 extern IOCBQ *
2971 emlxs_tx_get(CHANNEL *cp, uint32_t lock)
2972 {
2973 	emlxs_hba_t *hba;
2974 	uint32_t channelno;
2975 	IOCBQ *iocbq;
2976 	NODELIST *nlp;
2977 	emlxs_buf_t *sbp;
2978 
2979 	hba = cp->hba;
2980 	channelno = cp->channelno;
2981 
2982 	if (lock) {
2983 		mutex_enter(&EMLXS_TX_CHANNEL_LOCK);
2984 	}
2985 
2986 begin:
2987 
2988 	iocbq = NULL;
2989 
2990 	/* Check if a node needs servicing */
2991 	if (cp->nodeq.q_first) {
2992 		nlp = (NODELIST *)cp->nodeq.q_first;
2993 
2994 		/* Get next iocb from node's priority queue */
2995 
2996 		if (nlp->nlp_ptx[channelno].q_first) {
2997 			iocbq = (IOCBQ *)nlp->nlp_ptx[channelno].q_first;
2998 
2999 			/* Check if this is last entry */
3000 			if (nlp->nlp_ptx[channelno].q_last == (void *)iocbq) {
3001 				nlp->nlp_ptx[channelno].q_first = NULL;
3002 				nlp->nlp_ptx[channelno].q_last = NULL;
3003 				nlp->nlp_ptx[channelno].q_cnt = 0;
3004 			} else {
3005 				/* Remove iocb from head */
3006 				nlp->nlp_ptx[channelno].q_first =
3007 				    (void *)iocbq->next;
3008 				nlp->nlp_ptx[channelno].q_cnt--;
3009 			}
3010 
3011 			iocbq->next = NULL;
3012 		}
3013 
3014 		/* Get next iocb from node tx queue if node not closed */
3015 		else if (nlp->nlp_tx[channelno].q_first &&
3016 		    !(nlp->nlp_flag[channelno] & NLP_CLOSED)) {
3017 			iocbq = (IOCBQ *)nlp->nlp_tx[channelno].q_first;
3018 
3019 			/* Check if this is last entry */
3020 			if (nlp->nlp_tx[channelno].q_last == (void *)iocbq) {
3021 				nlp->nlp_tx[channelno].q_first = NULL;
3022 				nlp->nlp_tx[channelno].q_last = NULL;
3023 				nlp->nlp_tx[channelno].q_cnt = 0;
3024 			} else {
3025 				/* Remove iocb from head */
3026 				nlp->nlp_tx[channelno].q_first =
3027 				    (void *)iocbq->next;
3028 				nlp->nlp_tx[channelno].q_cnt--;
3029 			}
3030 
3031 			iocbq->next = NULL;
3032 		}
3033 
3034 		/* Now deal with node itself */
3035 
3036 		/* Check if node still needs servicing */
3037 		if ((nlp->nlp_ptx[channelno].q_first) ||
3038 		    (nlp->nlp_tx[channelno].q_first &&
3039 		    !(nlp->nlp_flag[channelno] & NLP_CLOSED))) {
3040 
3041 			/*
3042 			 * If this is the base node, then don't shift the
3043 			 * pointers. We want to drain the base node before
3044 			 * moving on
3045 			 */
3046 			if (!nlp->nlp_base) {
3047 				/*
3048 				 * Just shift channel queue pointers to next
3049 				 * node
3050 				 */
3051 				cp->nodeq.q_last = (void *)nlp;
3052 				cp->nodeq.q_first = nlp->nlp_next[channelno];
3053 			}
3054 		} else {
3055 			/* Remove node from channel queue */
3056 
3057 			/* If this is the last node on list */
3058 			if (cp->nodeq.q_last == (void *)nlp) {
3059 				cp->nodeq.q_last = NULL;
3060 				cp->nodeq.q_first = NULL;
3061 				cp->nodeq.q_cnt = 0;
3062 			} else {
3063 				/* Remove node from head */
3064 				cp->nodeq.q_first = nlp->nlp_next[channelno];
3065 				((NODELIST *)cp->nodeq.q_last)->
3066 				    nlp_next[channelno] = cp->nodeq.q_first;
3067 				cp->nodeq.q_cnt--;
3068 
3069 			}
3070 
3071 			/* Clear node */
3072 			nlp->nlp_next[channelno] = NULL;
3073 		}
3074 
3075 		/*
3076 		 * If no iocbq was found on this node, then it will have
3077 		 * been removed. So try again.
3078 		 */
3079 		if (!iocbq) {
3080 			goto begin;
3081 		}
3082 
3083 		sbp = (emlxs_buf_t *)iocbq->sbp;
3084 
3085 		if (sbp) {
3086 			/*
3087 			 * Check flags before we enter mutex in case this
3088 			 * has been flushed and destroyed
3089 			 */
3090 			if ((sbp->pkt_flags &
3091 			    (PACKET_IN_COMPLETION | PACKET_IN_CHIPQ)) ||
3092 			    !(sbp->pkt_flags & PACKET_IN_TXQ)) {
3093 				goto begin;
3094 			}
3095 
3096 			mutex_enter(&sbp->mtx);
3097 
3098 			if ((sbp->pkt_flags &
3099 			    (PACKET_IN_COMPLETION | PACKET_IN_CHIPQ)) ||
3100 			    !(sbp->pkt_flags & PACKET_IN_TXQ)) {
3101 				mutex_exit(&sbp->mtx);
3102 				goto begin;
3103 			}
3104 
3105 			sbp->pkt_flags &= ~PACKET_IN_TXQ;
3106 			hba->channel_tx_count--;
3107 
3108 			mutex_exit(&sbp->mtx);
3109 		}
3110 	}
3111 
3112 	if (iocbq) {
3113 		HBASTATS.IocbTxGet[channelno]++;
3114 	}
3115 
3116 	/* Adjust the ring timeout timer */
3117 	cp->timeout = (cp->nodeq.q_first) ? (hba->timer_tics + 5) : 0;
3118 
3119 	if (lock) {
3120 		mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
3121 	}
3122 
3123 	return (iocbq);
3124 
3125 } /* emlxs_tx_get() */
3126 
3127 
3128 /*
3129  * Remove all cmd from from_rp's txq to to_rp's txq for ndlp.
3130  * The old IoTag has to be released, the new one has to be
3131  * allocated.  Others no change
3132  * TX_CHANNEL lock is held
3133  */
3134 extern void
3135 emlxs_tx_move(NODELIST *ndlp, CHANNEL *from_chan, CHANNEL *to_chan,
3136     uint32_t cmd, emlxs_buf_t *fpkt, uint32_t lock)
3137 {
3138 	emlxs_hba_t *hba;
3139 	emlxs_port_t *port;
3140 	uint32_t fchanno, tchanno, i;
3141 
3142 	IOCBQ *iocbq;
3143 	IOCBQ *prev;
3144 	IOCBQ *next;
3145 	IOCB *iocb, *icmd;
3146 	Q tbm;		/* To Be Moved Q */
3147 	MATCHMAP *mp;
3148 
3149 	NODELIST *nlp = ndlp;
3150 	emlxs_buf_t *sbp;
3151 
3152 	NODELIST *n_prev = NULL;
3153 	NODELIST *n_next = NULL;
3154 	uint16_t count = 0;
3155 
3156 	hba = from_chan->hba;
3157 	port = &PPORT;
3158 	cmd = cmd; /* To pass lint */
3159 
3160 	fchanno = from_chan->channelno;
3161 	tchanno = to_chan->channelno;
3162 
3163 	if (lock) {
3164 		mutex_enter(&EMLXS_TX_CHANNEL_LOCK);
3165 	}
3166 
3167 	bzero((void *)&tbm, sizeof (Q));
3168 
3169 	/* Scan the ndlp's fchanno txq to get the iocb of fcp cmd */
3170 	prev = NULL;
3171 	iocbq = (IOCBQ *)nlp->nlp_tx[fchanno].q_first;
3172 
3173 	while (iocbq) {
3174 		next = (IOCBQ *)iocbq->next;
3175 		/* Check if this iocb is fcp cmd */
3176 		iocb = &iocbq->iocb;
3177 
3178 		switch (iocb->ULPCOMMAND) {
3179 		/* FCP commands */
3180 		case CMD_FCP_ICMND_CR:
3181 		case CMD_FCP_ICMND_CX:
3182 		case CMD_FCP_IREAD_CR:
3183 		case CMD_FCP_IREAD_CX:
3184 		case CMD_FCP_IWRITE_CR:
3185 		case CMD_FCP_IWRITE_CX:
3186 		case CMD_FCP_ICMND64_CR:
3187 		case CMD_FCP_ICMND64_CX:
3188 		case CMD_FCP_IREAD64_CR:
3189 		case CMD_FCP_IREAD64_CX:
3190 		case CMD_FCP_IWRITE64_CR:
3191 		case CMD_FCP_IWRITE64_CX:
3192 			/* We found a fcp cmd */
3193 			break;
3194 		default:
3195 			/* this is not fcp cmd continue */
3196 			prev = iocbq;
3197 			iocbq = next;
3198 			continue;
3199 		}
3200 
3201 		/* found a fcp cmd iocb in fchanno txq, now deque it */
3202 		if (next == NULL) {
3203 			/* This is the last iocbq */
3204 			nlp->nlp_tx[fchanno].q_last =
3205 			    (uint8_t *)prev;
3206 		}
3207 
3208 		if (prev == NULL) {
3209 			/* This is the first one then remove it from head */
3210 			nlp->nlp_tx[fchanno].q_first =
3211 			    (uint8_t *)next;
3212 		} else {
3213 			prev->next = next;
3214 		}
3215 
3216 		iocbq->next = NULL;
3217 		nlp->nlp_tx[fchanno].q_cnt--;
3218 
3219 		/* Add this iocb to our local toberemovedq */
3220 		/* This way we donot hold the TX_CHANNEL lock too long */
3221 
3222 		if (tbm.q_first) {
3223 			((IOCBQ *)tbm.q_last)->next = iocbq;
3224 			tbm.q_last = (uint8_t *)iocbq;
3225 			tbm.q_cnt++;
3226 		} else {
3227 			tbm.q_first = (uint8_t *)iocbq;
3228 			tbm.q_last = (uint8_t *)iocbq;
3229 			tbm.q_cnt = 1;
3230 		}
3231 
3232 		iocbq = next;
3233 
3234 	}	/* While (iocbq) */
3235 
3236 	if ((tchanno == hba->channel_fcp) && (tbm.q_cnt != 0)) {
3237 
3238 		/* from_chan->nodeq.q_first must be non NULL */
3239 		if (from_chan->nodeq.q_first) {
3240 
3241 			/* nodeq is not empty, now deal with the node itself */
3242 			if ((nlp->nlp_tx[fchanno].q_first)) {
3243 
3244 				if (!nlp->nlp_base) {
3245 					from_chan->nodeq.q_last =
3246 					    (void *)nlp;
3247 					from_chan->nodeq.q_first =
3248 					    nlp->nlp_next[fchanno];
3249 				}
3250 
3251 			} else {
3252 				n_prev = (NODELIST *)from_chan->nodeq.q_first;
3253 				count = from_chan->nodeq.q_cnt;
3254 
3255 				if (n_prev == nlp) {
3256 
3257 					/* If this is the only node on list */
3258 					if (from_chan->nodeq.q_last ==
3259 					    (void *)nlp) {
3260 						from_chan->nodeq.q_last =
3261 						    NULL;
3262 						from_chan->nodeq.q_first =
3263 						    NULL;
3264 						from_chan->nodeq.q_cnt = 0;
3265 					} else {
3266 						from_chan->nodeq.q_first =
3267 						    nlp->nlp_next[fchanno];
3268 						((NODELIST *)from_chan->
3269 						    nodeq.q_last)->
3270 						    nlp_next[fchanno] =
3271 						    from_chan->nodeq.q_first;
3272 						from_chan->nodeq.q_cnt--;
3273 					}
3274 					/* Clear node */
3275 					nlp->nlp_next[fchanno] = NULL;
3276 				} else {
3277 					count--;
3278 					do {
3279 						n_next =
3280 						    n_prev->nlp_next[fchanno];
3281 						if (n_next == nlp) {
3282 							break;
3283 						}
3284 						n_prev = n_next;
3285 					} while (count--);
3286 
3287 					if (count != 0) {
3288 
3289 						if (n_next ==
3290 						    (NODELIST *)from_chan->
3291 						    nodeq.q_last) {
3292 							n_prev->
3293 							    nlp_next[fchanno]
3294 							    =
3295 							    ((NODELIST *)
3296 							    from_chan->
3297 							    nodeq.q_last)->
3298 							    nlp_next
3299 							    [fchanno];
3300 							from_chan->nodeq.q_last
3301 							    = (uint8_t *)n_prev;
3302 						} else {
3303 
3304 							n_prev->
3305 							    nlp_next[fchanno]
3306 							    =
3307 							    n_next-> nlp_next
3308 							    [fchanno];
3309 						}
3310 						from_chan->nodeq.q_cnt--;
3311 						/* Clear node */
3312 						nlp->nlp_next[fchanno] =
3313 						    NULL;
3314 					}
3315 				}
3316 			}
3317 		}
3318 	}
3319 
3320 	/* Now cleanup the iocb's */
3321 	prev = NULL;
3322 	iocbq = (IOCBQ *)tbm.q_first;
3323 
3324 	while (iocbq) {
3325 
3326 		next = (IOCBQ *)iocbq->next;
3327 
3328 		/* Free the IoTag and the bmp */
3329 		iocb = &iocbq->iocb;
3330 
3331 		if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
3332 			sbp = iocbq->sbp;
3333 			if (sbp) {
3334 				hba->fc_table[sbp->iotag] = NULL;
3335 				emlxs_sli4_free_xri(hba, sbp, sbp->xp);
3336 			}
3337 		} else {
3338 			sbp = emlxs_unregister_pkt((CHANNEL *)iocbq->channel,
3339 			    iocb->ULPIOTAG, 0);
3340 		}
3341 
3342 		if (sbp && (sbp != STALE_PACKET)) {
3343 			mutex_enter(&sbp->mtx);
3344 			sbp->pkt_flags |= PACKET_IN_FLUSH;
3345 
3346 			/*
3347 			 * If the fpkt is already set, then we will leave it
3348 			 * alone. This ensures that this pkt is only accounted
3349 			 * for on one fpkt->flush_count
3350 			 */
3351 			if (!sbp->fpkt && fpkt) {
3352 				mutex_enter(&fpkt->mtx);
3353 				sbp->fpkt = fpkt;
3354 				fpkt->flush_count++;
3355 				mutex_exit(&fpkt->mtx);
3356 			}
3357 			mutex_exit(&sbp->mtx);
3358 		}
3359 		iocbq = next;
3360 
3361 	}	/* end of while */
3362 
3363 	iocbq = (IOCBQ *)tbm.q_first;
3364 	while (iocbq) {
3365 		/* Save the next iocbq for now */
3366 		next = (IOCBQ *)iocbq->next;
3367 
3368 		/* Unlink this iocbq */
3369 		iocbq->next = NULL;
3370 
3371 		/* Get the pkt */
3372 		sbp = (emlxs_buf_t *)iocbq->sbp;
3373 
3374 		if (sbp) {
3375 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_flush_msg,
3376 			"tx: sbp=%p node=%p", sbp, sbp->node);
3377 
3378 			if (hba->state >= FC_LINK_UP) {
3379 				emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
3380 				    IOERR_ABORT_REQUESTED, 1);
3381 			} else {
3382 				emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
3383 				    IOERR_LINK_DOWN, 1);
3384 			}
3385 
3386 		}
3387 		/* Free the iocb and its associated buffers */
3388 		else {
3389 			icmd = &iocbq->iocb;
3390 
3391 			/* SLI3 */
3392 			if (icmd->ULPCOMMAND == CMD_QUE_RING_BUF64_CN ||
3393 			    icmd->ULPCOMMAND == CMD_QUE_RING_BUF_CN ||
3394 			    icmd->ULPCOMMAND == CMD_QUE_RING_LIST64_CN) {
3395 				if ((hba->flag &
3396 				    (FC_ONLINE_MODE | FC_ONLINING_MODE)) == 0) {
3397 					/* HBA is detaching or offlining */
3398 					if (icmd->ULPCOMMAND !=
3399 					    CMD_QUE_RING_LIST64_CN) {
3400 						uint8_t *tmp;
3401 						RING *rp;
3402 						int ch;
3403 
3404 						ch = from_chan->channelno;
3405 						rp = &hba->sli.sli3.ring[ch];
3406 
3407 						for (i = 0;
3408 						    i < icmd->ULPBDECOUNT;
3409 						    i++) {
3410 							mp = EMLXS_GET_VADDR(
3411 							    hba, rp, icmd);
3412 
3413 							tmp = (uint8_t *)mp;
3414 							if (mp) {
3415 							(void) emlxs_mem_put(
3416 							    hba,
3417 							    MEM_BUF,
3418 							    tmp);
3419 							}
3420 						}
3421 
3422 					}
3423 
3424 					(void) emlxs_mem_put(hba, MEM_IOCB,
3425 					    (uint8_t *)iocbq);
3426 				} else {
3427 					/* repost the unsolicited buffer */
3428 					EMLXS_SLI_ISSUE_IOCB_CMD(hba,
3429 					    from_chan, iocbq);
3430 				}
3431 			}
3432 		}
3433 
3434 		iocbq = next;
3435 
3436 	}	/* end of while */
3437 
3438 	/* Now flush the chipq if any */
3439 	if (!(nlp->nlp_flag[fchanno] & NLP_CLOSED)) {
3440 
3441 		mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
3442 
3443 		(void) emlxs_chipq_node_flush(port, from_chan, nlp, 0);
3444 
3445 		mutex_enter(&EMLXS_TX_CHANNEL_LOCK);
3446 	}
3447 
3448 	if (lock) {
3449 		mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
3450 	}
3451 
3452 	return;
3453 
3454 } /* emlxs_tx_move */
3455 
3456 
3457 extern uint32_t
3458 emlxs_chipq_node_flush(emlxs_port_t *port, CHANNEL *chan, NODELIST *ndlp,
3459     emlxs_buf_t *fpkt)
3460 {
3461 	emlxs_hba_t *hba = HBA;
3462 	emlxs_buf_t *sbp;
3463 	IOCBQ *iocbq;
3464 	IOCBQ *next;
3465 	Q abort;
3466 	CHANNEL *cp;
3467 	uint32_t channelno;
3468 	uint8_t flag[MAX_CHANNEL];
3469 	uint32_t iotag;
3470 
3471 	bzero((void *)&abort, sizeof (Q));
3472 	bzero((void *)flag, sizeof (flag));
3473 
3474 	for (channelno = 0; channelno < hba->chan_count; channelno++) {
3475 		cp = &hba->chan[channelno];
3476 
3477 		if (chan && cp != chan) {
3478 			continue;
3479 		}
3480 
3481 		mutex_enter(&EMLXS_FCTAB_LOCK);
3482 
3483 		for (iotag = 1; iotag < hba->max_iotag; iotag++) {
3484 			sbp = hba->fc_table[iotag];
3485 
3486 			if (sbp && (sbp != STALE_PACKET) &&
3487 			    (sbp->pkt_flags & PACKET_IN_CHIPQ) &&
3488 			    (sbp->node == ndlp) &&
3489 			    (sbp->channel == cp) &&
3490 			    !(sbp->pkt_flags & PACKET_XRI_CLOSED)) {
3491 				emlxs_sbp_abort_add(port, sbp, &abort, flag,
3492 				    fpkt);
3493 			}
3494 
3495 		}
3496 		mutex_exit(&EMLXS_FCTAB_LOCK);
3497 
3498 	}	/* for */
3499 
3500 	/* Now put the iocb's on the tx queue */
3501 	iocbq = (IOCBQ *)abort.q_first;
3502 	while (iocbq) {
3503 		/* Save the next iocbq for now */
3504 		next = (IOCBQ *)iocbq->next;
3505 
3506 		/* Unlink this iocbq */
3507 		iocbq->next = NULL;
3508 
3509 		/* Send this iocbq */
3510 		emlxs_tx_put(iocbq, 1);
3511 
3512 		iocbq = next;
3513 	}
3514 
3515 	/* Now trigger channel service */
3516 	for (channelno = 0; channelno < hba->chan_count; channelno++) {
3517 		if (!flag[channelno]) {
3518 			continue;
3519 		}
3520 
3521 		EMLXS_SLI_ISSUE_IOCB_CMD(hba, &hba->chan[channelno], 0);
3522 	}
3523 
3524 	return (abort.q_cnt);
3525 
3526 } /* emlxs_chipq_node_flush() */
3527 
3528 
3529 /* Flush all IO's left on all iotag lists */
3530 extern uint32_t
3531 emlxs_iotag_flush(emlxs_hba_t *hba)
3532 {
3533 	emlxs_port_t *port = &PPORT;
3534 	emlxs_buf_t *sbp;
3535 	IOCBQ *iocbq;
3536 	IOCB *iocb;
3537 	Q abort;
3538 	CHANNEL *cp;
3539 	uint32_t channelno;
3540 	uint32_t iotag;
3541 	uint32_t count;
3542 
3543 	count = 0;
3544 	for (channelno = 0; channelno < hba->chan_count; channelno++) {
3545 		cp = &hba->chan[channelno];
3546 
3547 		bzero((void *)&abort, sizeof (Q));
3548 
3549 		mutex_enter(&EMLXS_FCTAB_LOCK);
3550 
3551 		for (iotag = 1; iotag < hba->max_iotag; iotag++) {
3552 			sbp = hba->fc_table[iotag];
3553 
3554 			/* Check if the slot is empty */
3555 			if (!sbp || (sbp == STALE_PACKET)) {
3556 				continue;
3557 			}
3558 
3559 			/* We are building an abort list per channel */
3560 			if (sbp->channel != cp) {
3561 				continue;
3562 			}
3563 
3564 			/* Set IOCB status */
3565 			iocbq = &sbp->iocbq;
3566 			iocb = &iocbq->iocb;
3567 
3568 			iocb->ULPSTATUS = IOSTAT_LOCAL_REJECT;
3569 			iocb->un.grsp.perr.statLocalError = IOERR_LINK_DOWN;
3570 			iocb->ULPLE = 1;
3571 			iocbq->next = NULL;
3572 
3573 			if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
3574 				hba->fc_table[iotag] = NULL;
3575 				emlxs_sli4_free_xri(hba, sbp, sbp->xp);
3576 			} else {
3577 				hba->fc_table[iotag] = STALE_PACKET;
3578 				hba->io_count --;
3579 				sbp->iotag = 0;
3580 
3581 				/* Clean up the sbp */
3582 				mutex_enter(&sbp->mtx);
3583 
3584 				if (sbp->pkt_flags & PACKET_IN_TXQ) {
3585 					sbp->pkt_flags &= ~PACKET_IN_TXQ;
3586 					hba->channel_tx_count --;
3587 				}
3588 
3589 				if (sbp->pkt_flags & PACKET_IN_CHIPQ) {
3590 					sbp->pkt_flags &= ~PACKET_IN_CHIPQ;
3591 				}
3592 
3593 				if (sbp->bmp) {
3594 					(void) emlxs_mem_put(hba, MEM_BPL,
3595 					    (uint8_t *)sbp->bmp);
3596 					sbp->bmp = 0;
3597 				}
3598 
3599 				mutex_exit(&sbp->mtx);
3600 			}
3601 
3602 			/* At this point all nodes are assumed destroyed */
3603 			mutex_enter(&sbp->mtx);
3604 			sbp->node = 0;
3605 			mutex_exit(&sbp->mtx);
3606 
3607 			/* Add this iocb to our local abort Q */
3608 			if (abort.q_first) {
3609 				((IOCBQ *)abort.q_last)->next = iocbq;
3610 				abort.q_last = (uint8_t *)iocbq;
3611 				abort.q_cnt++;
3612 			} else {
3613 				abort.q_first = (uint8_t *)iocbq;
3614 				abort.q_last = (uint8_t *)iocbq;
3615 				abort.q_cnt = 1;
3616 			}
3617 		}
3618 
3619 		mutex_exit(&EMLXS_FCTAB_LOCK);
3620 
3621 		/* Trigger deferred completion */
3622 		if (abort.q_first) {
3623 			mutex_enter(&cp->rsp_lock);
3624 			if (cp->rsp_head == NULL) {
3625 				cp->rsp_head = (IOCBQ *)abort.q_first;
3626 				cp->rsp_tail = (IOCBQ *)abort.q_last;
3627 			} else {
3628 				cp->rsp_tail->next = (IOCBQ *)abort.q_first;
3629 				cp->rsp_tail = (IOCBQ *)abort.q_last;
3630 			}
3631 			mutex_exit(&cp->rsp_lock);
3632 
3633 			emlxs_thread_trigger2(&cp->intr_thread,
3634 			    emlxs_proc_channel, cp);
3635 
3636 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg,
3637 			    "Forced iotag completion. channel=%d count=%d",
3638 			    channelno, abort.q_cnt);
3639 
3640 			count += abort.q_cnt;
3641 		}
3642 	}
3643 
3644 	return (count);
3645 
3646 } /* emlxs_iotag_flush() */
3647 
3648 
3649 
3650 /* Checks for IO's on all or a given channel for a given node */
3651 extern uint32_t
3652 emlxs_chipq_node_check(emlxs_port_t *port, CHANNEL *chan, NODELIST *ndlp)
3653 {
3654 	emlxs_hba_t *hba = HBA;
3655 	emlxs_buf_t *sbp;
3656 	CHANNEL *cp;
3657 	uint32_t channelno;
3658 	uint32_t count;
3659 	uint32_t iotag;
3660 
3661 	count = 0;
3662 
3663 	for (channelno = 0; channelno < hba->chan_count; channelno++) {
3664 		cp = &hba->chan[channelno];
3665 
3666 		if (chan && cp != chan) {
3667 			continue;
3668 		}
3669 
3670 		mutex_enter(&EMLXS_FCTAB_LOCK);
3671 
3672 		for (iotag = 1; iotag < hba->max_iotag; iotag++) {
3673 			sbp = hba->fc_table[iotag];
3674 
3675 			if (sbp && (sbp != STALE_PACKET) &&
3676 			    (sbp->pkt_flags & PACKET_IN_CHIPQ) &&
3677 			    (sbp->node == ndlp) &&
3678 			    (sbp->channel == cp) &&
3679 			    !(sbp->pkt_flags & PACKET_XRI_CLOSED)) {
3680 				count++;
3681 			}
3682 
3683 		}
3684 		mutex_exit(&EMLXS_FCTAB_LOCK);
3685 
3686 	}	/* for */
3687 
3688 	return (count);
3689 
3690 } /* emlxs_chipq_node_check() */
3691 
3692 
3693 
3694 /* Flush all IO's for a given node's lun (on any channel) */
3695 extern uint32_t
3696 emlxs_chipq_lun_flush(emlxs_port_t *port, NODELIST *ndlp,
3697     uint32_t lun, emlxs_buf_t *fpkt)
3698 {
3699 	emlxs_hba_t *hba = HBA;
3700 	emlxs_buf_t *sbp;
3701 	IOCBQ *iocbq;
3702 	IOCBQ *next;
3703 	Q abort;
3704 	uint32_t iotag;
3705 	uint8_t flag[MAX_CHANNEL];
3706 	uint32_t channelno;
3707 
3708 	bzero((void *)flag, sizeof (flag));
3709 	bzero((void *)&abort, sizeof (Q));
3710 
3711 	mutex_enter(&EMLXS_FCTAB_LOCK);
3712 	for (iotag = 1; iotag < hba->max_iotag; iotag++) {
3713 		sbp = hba->fc_table[iotag];
3714 
3715 		if (sbp && (sbp != STALE_PACKET) &&
3716 		    sbp->pkt_flags & PACKET_IN_CHIPQ &&
3717 		    sbp->node == ndlp &&
3718 		    sbp->lun == lun &&
3719 		    !(sbp->pkt_flags & PACKET_XRI_CLOSED)) {
3720 			emlxs_sbp_abort_add(port, sbp,
3721 			    &abort, flag, fpkt);
3722 		}
3723 	}
3724 	mutex_exit(&EMLXS_FCTAB_LOCK);
3725 
3726 	/* Now put the iocb's on the tx queue */
3727 	iocbq = (IOCBQ *)abort.q_first;
3728 	while (iocbq) {
3729 		/* Save the next iocbq for now */
3730 		next = (IOCBQ *)iocbq->next;
3731 
3732 		/* Unlink this iocbq */
3733 		iocbq->next = NULL;
3734 
3735 		/* Send this iocbq */
3736 		emlxs_tx_put(iocbq, 1);
3737 
3738 		iocbq = next;
3739 	}
3740 
3741 	/* Now trigger channel service */
3742 	for (channelno = 0; channelno < hba->chan_count; channelno++) {
3743 		if (!flag[channelno]) {
3744 			continue;
3745 		}
3746 
3747 		EMLXS_SLI_ISSUE_IOCB_CMD(hba, &hba->chan[channelno], 0);
3748 	}
3749 
3750 	return (abort.q_cnt);
3751 
3752 } /* emlxs_chipq_lun_flush() */
3753 
3754 
3755 
3756 /*
3757  * Issue an ABORT_XRI_CN iocb command to abort an FCP command already issued.
3758  * This must be called while holding the EMLXS_FCTAB_LOCK
3759  */
3760 extern IOCBQ *
3761 emlxs_create_abort_xri_cn(emlxs_port_t *port, NODELIST *ndlp,
3762     uint16_t iotag, CHANNEL *cp, uint8_t class, int32_t flag)
3763 {
3764 	emlxs_hba_t *hba = HBA;
3765 	IOCBQ *iocbq;
3766 	IOCB *iocb;
3767 	emlxs_wqe_t *wqe;
3768 	emlxs_buf_t *sbp;
3769 	uint16_t abort_iotag;
3770 
3771 	if ((iocbq = (IOCBQ *)emlxs_mem_get(hba, MEM_IOCB, 0)) == NULL) {
3772 		return (NULL);
3773 	}
3774 
3775 	iocbq->channel = (void *)cp;
3776 	iocbq->port = (void *)port;
3777 	iocbq->node = (void *)ndlp;
3778 	iocbq->flag |= (IOCB_PRIORITY | IOCB_SPECIAL);
3779 
3780 	/*
3781 	 * set up an iotag using special Abort iotags
3782 	 */
3783 	if ((hba->fc_oor_iotag >= EMLXS_MAX_ABORT_TAG)) {
3784 		hba->fc_oor_iotag = hba->max_iotag;
3785 	}
3786 	abort_iotag = hba->fc_oor_iotag++;
3787 
3788 
3789 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
3790 		wqe = &iocbq->wqe;
3791 		sbp = hba->fc_table[iotag];
3792 
3793 		/* Try to issue abort by XRI if possible */
3794 		if (sbp == NULL || sbp == STALE_PACKET || sbp->xp == NULL) {
3795 			wqe->un.Abort.Criteria = ABORT_REQ_TAG;
3796 			wqe->AbortTag = iotag;
3797 		} else {
3798 			wqe->un.Abort.Criteria = ABORT_XRI_TAG;
3799 			wqe->AbortTag = sbp->xp->XRI;
3800 		}
3801 		wqe->un.Abort.IA = 0;
3802 		wqe->RequestTag = abort_iotag;
3803 		wqe->Command = CMD_ABORT_XRI_CX;
3804 		wqe->Class = CLASS3;
3805 		wqe->CQId = 0x3ff;
3806 		wqe->CmdType = WQE_TYPE_ABORT;
3807 	} else {
3808 		iocb = &iocbq->iocb;
3809 		iocb->ULPIOTAG = abort_iotag;
3810 		iocb->un.acxri.abortType = flag;
3811 		iocb->un.acxri.abortContextTag = ndlp->nlp_Rpi;
3812 		iocb->un.acxri.abortIoTag = iotag;
3813 		iocb->ULPLE = 1;
3814 		iocb->ULPCLASS = class;
3815 		iocb->ULPCOMMAND = CMD_ABORT_XRI_CN;
3816 		iocb->ULPOWNER = OWN_CHIP;
3817 	}
3818 
3819 	return (iocbq);
3820 
3821 } /* emlxs_create_abort_xri_cn() */
3822 
3823 
3824 /* This must be called while holding the EMLXS_FCTAB_LOCK */
3825 extern IOCBQ *
3826 emlxs_create_abort_xri_cx(emlxs_port_t *port, NODELIST *ndlp, uint16_t xid,
3827     CHANNEL *cp, uint8_t class, int32_t flag)
3828 {
3829 	emlxs_hba_t *hba = HBA;
3830 	IOCBQ *iocbq;
3831 	IOCB *iocb;
3832 	emlxs_wqe_t *wqe;
3833 	uint16_t abort_iotag;
3834 
3835 	if ((iocbq = (IOCBQ *)emlxs_mem_get(hba, MEM_IOCB, 0)) == NULL) {
3836 		return (NULL);
3837 	}
3838 
3839 	iocbq->channel = (void *)cp;
3840 	iocbq->port = (void *)port;
3841 	iocbq->node = (void *)ndlp;
3842 	iocbq->flag |= (IOCB_PRIORITY | IOCB_SPECIAL);
3843 
3844 	/*
3845 	 * set up an iotag using special Abort iotags
3846 	 */
3847 	if ((hba->fc_oor_iotag >= EMLXS_MAX_ABORT_TAG)) {
3848 		hba->fc_oor_iotag = hba->max_iotag;
3849 	}
3850 	abort_iotag = hba->fc_oor_iotag++;
3851 
3852 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
3853 		wqe = &iocbq->wqe;
3854 		wqe->un.Abort.Criteria = ABORT_XRI_TAG;
3855 		wqe->un.Abort.IA = 0;
3856 		wqe->RequestTag = abort_iotag;
3857 		wqe->AbortTag = xid;
3858 		wqe->Command = CMD_ABORT_XRI_CX;
3859 		wqe->Class = CLASS3;
3860 		wqe->CQId = 0x3ff;
3861 		wqe->CmdType = WQE_TYPE_ABORT;
3862 	} else {
3863 		iocb = &iocbq->iocb;
3864 		iocb->ULPCONTEXT = xid;
3865 		iocb->ULPIOTAG = abort_iotag;
3866 		iocb->un.acxri.abortType = flag;
3867 		iocb->ULPLE = 1;
3868 		iocb->ULPCLASS = class;
3869 		iocb->ULPCOMMAND = CMD_ABORT_XRI_CX;
3870 		iocb->ULPOWNER = OWN_CHIP;
3871 	}
3872 
3873 	return (iocbq);
3874 
3875 } /* emlxs_create_abort_xri_cx() */
3876 
3877 
3878 
3879 /* This must be called while holding the EMLXS_FCTAB_LOCK */
3880 extern IOCBQ *
3881 emlxs_create_close_xri_cn(emlxs_port_t *port, NODELIST *ndlp,
3882     uint16_t iotag, CHANNEL *cp)
3883 {
3884 	emlxs_hba_t *hba = HBA;
3885 	IOCBQ *iocbq;
3886 	IOCB *iocb;
3887 	emlxs_wqe_t *wqe;
3888 	emlxs_buf_t *sbp;
3889 	uint16_t abort_iotag;
3890 
3891 	if ((iocbq = (IOCBQ *)emlxs_mem_get(hba, MEM_IOCB, 0)) == NULL) {
3892 		return (NULL);
3893 	}
3894 
3895 	iocbq->channel = (void *)cp;
3896 	iocbq->port = (void *)port;
3897 	iocbq->node = (void *)ndlp;
3898 	iocbq->flag |= (IOCB_PRIORITY | IOCB_SPECIAL);
3899 
3900 	/*
3901 	 * set up an iotag using special Abort iotags
3902 	 */
3903 	if ((hba->fc_oor_iotag >= EMLXS_MAX_ABORT_TAG)) {
3904 		hba->fc_oor_iotag = hba->max_iotag;
3905 	}
3906 	abort_iotag = hba->fc_oor_iotag++;
3907 
3908 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
3909 		wqe = &iocbq->wqe;
3910 		sbp = hba->fc_table[iotag];
3911 
3912 		/* Try to issue close by XRI if possible */
3913 		if (sbp == NULL || sbp == STALE_PACKET || sbp->xp == NULL) {
3914 			wqe->un.Abort.Criteria = ABORT_REQ_TAG;
3915 			wqe->AbortTag = iotag;
3916 		} else {
3917 			wqe->un.Abort.Criteria = ABORT_XRI_TAG;
3918 			wqe->AbortTag = sbp->xp->XRI;
3919 		}
3920 		wqe->un.Abort.IA = 1;
3921 		wqe->RequestTag = abort_iotag;
3922 		wqe->Command = CMD_ABORT_XRI_CX;
3923 		wqe->Class = CLASS3;
3924 		wqe->CQId = 0x3ff;
3925 		wqe->CmdType = WQE_TYPE_ABORT;
3926 	} else {
3927 		iocb = &iocbq->iocb;
3928 		iocb->ULPIOTAG = abort_iotag;
3929 		iocb->un.acxri.abortType = 0;
3930 		iocb->un.acxri.abortContextTag = ndlp->nlp_Rpi;
3931 		iocb->un.acxri.abortIoTag = iotag;
3932 		iocb->ULPLE = 1;
3933 		iocb->ULPCLASS = 0;
3934 		iocb->ULPCOMMAND = CMD_CLOSE_XRI_CN;
3935 		iocb->ULPOWNER = OWN_CHIP;
3936 	}
3937 
3938 	return (iocbq);
3939 
3940 } /* emlxs_create_close_xri_cn() */
3941 
3942 
3943 /* This must be called while holding the EMLXS_FCTAB_LOCK */
3944 extern IOCBQ *
3945 emlxs_create_close_xri_cx(emlxs_port_t *port, NODELIST *ndlp, uint16_t xid,
3946     CHANNEL *cp)
3947 {
3948 	emlxs_hba_t *hba = HBA;
3949 	IOCBQ *iocbq;
3950 	IOCB *iocb;
3951 	emlxs_wqe_t *wqe;
3952 	uint16_t abort_iotag;
3953 
3954 	if ((iocbq = (IOCBQ *)emlxs_mem_get(hba, MEM_IOCB, 0)) == NULL) {
3955 		return (NULL);
3956 	}
3957 
3958 	iocbq->channel = (void *)cp;
3959 	iocbq->port = (void *)port;
3960 	iocbq->node = (void *)ndlp;
3961 	iocbq->flag |= (IOCB_PRIORITY | IOCB_SPECIAL);
3962 
3963 	/*
3964 	 * set up an iotag using special Abort iotags
3965 	 */
3966 	if ((hba->fc_oor_iotag >= EMLXS_MAX_ABORT_TAG)) {
3967 		hba->fc_oor_iotag = hba->max_iotag;
3968 	}
3969 	abort_iotag = hba->fc_oor_iotag++;
3970 
3971 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
3972 		wqe = &iocbq->wqe;
3973 		wqe->un.Abort.Criteria = ABORT_XRI_TAG;
3974 		wqe->un.Abort.IA = 1;
3975 		wqe->RequestTag = abort_iotag;
3976 		wqe->AbortTag = xid;
3977 		wqe->Command = CMD_ABORT_XRI_CX;
3978 		wqe->Class = CLASS3;
3979 		wqe->CQId = 0x3ff;
3980 		wqe->CmdType = WQE_TYPE_ABORT;
3981 	} else {
3982 		iocb = &iocbq->iocb;
3983 		iocb->ULPCONTEXT = xid;
3984 		iocb->ULPIOTAG = abort_iotag;
3985 		iocb->ULPLE = 1;
3986 		iocb->ULPCLASS = 0;
3987 		iocb->ULPCOMMAND = CMD_CLOSE_XRI_CX;
3988 		iocb->ULPOWNER = OWN_CHIP;
3989 	}
3990 
3991 	return (iocbq);
3992 
3993 } /* emlxs_create_close_xri_cx() */
3994 
3995 
3996 #ifdef SFCT_SUPPORT
3997 void
3998 emlxs_abort_fct_exchange(emlxs_hba_t *hba, emlxs_port_t *port, uint32_t rxid)
3999 {
4000 	CHANNEL *cp;
4001 	IOCBQ *iocbq;
4002 	IOCB *iocb;
4003 
4004 	if (rxid == 0 || rxid == 0xFFFF) {
4005 		return;
4006 	}
4007 
4008 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
4009 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
4010 		    "Aborting FCT exchange: xid=%x", rxid);
4011 
4012 		if (emlxs_sli4_unreserve_xri(hba, rxid) == 0) {
4013 			/* We have no way to abort unsolicited exchanges */
4014 			/* that we have not responded to at this time */
4015 			/* So we will return for now */
4016 			return;
4017 		}
4018 	}
4019 
4020 	cp = &hba->chan[hba->channel_fcp];
4021 
4022 	mutex_enter(&EMLXS_FCTAB_LOCK);
4023 
4024 	/* Create the abort IOCB */
4025 	if (hba->state >= FC_LINK_UP) {
4026 		iocbq = emlxs_create_abort_xri_cx(port, NULL, rxid, cp,
4027 		    CLASS3, ABORT_TYPE_ABTS);
4028 	} else {
4029 		iocbq = emlxs_create_close_xri_cx(port, NULL, rxid, cp);
4030 	}
4031 
4032 	mutex_exit(&EMLXS_FCTAB_LOCK);
4033 
4034 	if (iocbq) {
4035 		iocb = &iocbq->iocb;
4036 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
4037 		    "Aborting FCT exchange: xid=%x iotag=%x", rxid,
4038 		    iocb->ULPIOTAG);
4039 
4040 		EMLXS_SLI_ISSUE_IOCB_CMD(hba, cp, iocbq);
4041 	}
4042 
4043 } /* emlxs_abort_fct_exchange() */
4044 #endif /* SFCT_SUPPORT */
4045 
4046 
4047 void
4048 emlxs_abort_els_exchange(emlxs_hba_t *hba, emlxs_port_t *port, uint32_t rxid)
4049 {
4050 	CHANNEL *cp;
4051 	IOCBQ *iocbq;
4052 	IOCB *iocb;
4053 
4054 	if (rxid == 0 || rxid == 0xFFFF) {
4055 		return;
4056 	}
4057 
4058 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
4059 
4060 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
4061 		    "Aborting ELS exchange: xid=%x", rxid);
4062 
4063 		if (emlxs_sli4_unreserve_xri(hba, rxid) == 0) {
4064 			/* We have no way to abort unsolicited exchanges */
4065 			/* that we have not responded to at this time */
4066 			/* So we will return for now */
4067 			return;
4068 		}
4069 	}
4070 
4071 	cp = &hba->chan[hba->channel_els];
4072 
4073 	mutex_enter(&EMLXS_FCTAB_LOCK);
4074 
4075 	/* Create the abort IOCB */
4076 	if (hba->state >= FC_LINK_UP) {
4077 		iocbq = emlxs_create_abort_xri_cx(port, NULL, rxid, cp,
4078 		    CLASS3, ABORT_TYPE_ABTS);
4079 	} else {
4080 		iocbq = emlxs_create_close_xri_cx(port, NULL, rxid, cp);
4081 	}
4082 
4083 	mutex_exit(&EMLXS_FCTAB_LOCK);
4084 
4085 	if (iocbq) {
4086 		iocb = &iocbq->iocb;
4087 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
4088 		    "Aborting ELS exchange: xid=%x iotag=%x", rxid,
4089 		    iocb->ULPIOTAG);
4090 
4091 		EMLXS_SLI_ISSUE_IOCB_CMD(hba, cp, iocbq);
4092 	}
4093 
4094 } /* emlxs_abort_els_exchange() */
4095 
4096 
4097 void
4098 emlxs_abort_ct_exchange(emlxs_hba_t *hba, emlxs_port_t *port, uint32_t rxid)
4099 {
4100 	CHANNEL *cp;
4101 	IOCBQ *iocbq;
4102 	IOCB *iocb;
4103 
4104 	if (rxid == 0 || rxid == 0xFFFF) {
4105 		return;
4106 	}
4107 
4108 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
4109 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg,
4110 		    "Aborting CT exchange: xid=%x", rxid);
4111 
4112 		if (emlxs_sli4_unreserve_xri(hba, rxid) == 0) {
4113 			/* We have no way to abort unsolicited exchanges */
4114 			/* that we have not responded to at this time */
4115 			/* So we will return for now */
4116 			return;
4117 		}
4118 	}
4119 
4120 	cp = &hba->chan[hba->channel_ct];
4121 
4122 	mutex_enter(&EMLXS_FCTAB_LOCK);
4123 
4124 	/* Create the abort IOCB */
4125 	if (hba->state >= FC_LINK_UP) {
4126 		iocbq = emlxs_create_abort_xri_cx(port, NULL, rxid, cp,
4127 		    CLASS3, ABORT_TYPE_ABTS);
4128 	} else {
4129 		iocbq = emlxs_create_close_xri_cx(port, NULL, rxid, cp);
4130 	}
4131 
4132 	mutex_exit(&EMLXS_FCTAB_LOCK);
4133 
4134 	if (iocbq) {
4135 		iocb = &iocbq->iocb;
4136 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
4137 		    "Aborting CT exchange: xid=%x iotag=%x", rxid,
4138 		    iocb->ULPIOTAG);
4139 
4140 		EMLXS_SLI_ISSUE_IOCB_CMD(hba, cp, iocbq);
4141 	}
4142 
4143 } /* emlxs_abort_ct_exchange() */
4144 
4145 
4146 /* This must be called while holding the EMLXS_FCTAB_LOCK */
4147 static void
4148 emlxs_sbp_abort_add(emlxs_port_t *port, emlxs_buf_t *sbp, Q *abort,
4149     uint8_t *flag, emlxs_buf_t *fpkt)
4150 {
4151 	emlxs_hba_t *hba = HBA;
4152 	IOCBQ *iocbq;
4153 	CHANNEL *cp;
4154 	NODELIST *ndlp;
4155 
4156 	cp = (CHANNEL *)sbp->channel;
4157 	ndlp = sbp->node;
4158 
4159 	/* Create the close XRI IOCB */
4160 	iocbq = emlxs_create_close_xri_cn(port, ndlp, sbp->iotag, cp);
4161 
4162 	/*
4163 	 * Add this iocb to our local abort Q
4164 	 * This way we don't hold the CHIPQ lock too long
4165 	 */
4166 	if (iocbq) {
4167 		if (abort->q_first) {
4168 			((IOCBQ *)abort->q_last)->next = iocbq;
4169 			abort->q_last = (uint8_t *)iocbq;
4170 			abort->q_cnt++;
4171 		} else {
4172 			abort->q_first = (uint8_t *)iocbq;
4173 			abort->q_last = (uint8_t *)iocbq;
4174 			abort->q_cnt = 1;
4175 		}
4176 		iocbq->next = NULL;
4177 	}
4178 
4179 	/* set the flags */
4180 	mutex_enter(&sbp->mtx);
4181 
4182 	sbp->pkt_flags |= (PACKET_IN_FLUSH | PACKET_XRI_CLOSED);
4183 
4184 	sbp->ticks = hba->timer_tics + 10;
4185 	sbp->abort_attempts++;
4186 
4187 	flag[cp->channelno] = 1;
4188 
4189 	/*
4190 	 * If the fpkt is already set, then we will leave it alone
4191 	 * This ensures that this pkt is only accounted for on one
4192 	 * fpkt->flush_count
4193 	 */
4194 	if (!sbp->fpkt && fpkt) {
4195 		mutex_enter(&fpkt->mtx);
4196 		sbp->fpkt = fpkt;
4197 		fpkt->flush_count++;
4198 		mutex_exit(&fpkt->mtx);
4199 	}
4200 
4201 	mutex_exit(&sbp->mtx);
4202 
4203 	return;
4204 
4205 }	/* emlxs_sbp_abort_add() */
4206