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 /* Copyright 2009 QLogic Corporation */
23 
24 /*
25  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
26  * Use is subject to license terms.
27  */
28 
29 #pragma ident	"Copyright 2009 QLogic Corporation; ql_isr.c"
30 
31 /*
32  * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
33  *
34  * ***********************************************************************
35  * *									**
36  * *				NOTICE					**
37  * *		COPYRIGHT (C) 1996-2009 QLOGIC CORPORATION		**
38  * *			ALL RIGHTS RESERVED				**
39  * *									**
40  * ***********************************************************************
41  *
42  */
43 
44 #include <ql_apps.h>
45 #include <ql_api.h>
46 #include <ql_debug.h>
47 #include <ql_iocb.h>
48 #include <ql_isr.h>
49 #include <ql_init.h>
50 #include <ql_mbx.h>
51 #include <ql_xioctl.h>
52 
53 /*
54  * Local Function Prototypes.
55  */
56 static void ql_handle_uncommon_risc_intr(ql_adapter_state_t *, uint32_t,
57     uint32_t *);
58 static void ql_spurious_intr(ql_adapter_state_t *, int);
59 static void ql_mbx_completion(ql_adapter_state_t *, uint16_t, uint32_t *,
60     uint32_t *, int);
61 static void ql_async_event(ql_adapter_state_t *, uint32_t, ql_head_t *,
62     uint32_t *, uint32_t *, int);
63 static void ql_fast_fcp_post(ql_srb_t *);
64 static void ql_response_pkt(ql_adapter_state_t *, ql_head_t *, uint32_t *,
65     uint32_t *, int);
66 static void ql_error_entry(ql_adapter_state_t *, response_t *, ql_head_t *,
67     uint32_t *, uint32_t *);
68 static int ql_status_entry(ql_adapter_state_t *, sts_entry_t *, ql_head_t *,
69     uint32_t *, uint32_t *);
70 static int ql_24xx_status_entry(ql_adapter_state_t *, sts_24xx_entry_t *,
71     ql_head_t *, uint32_t *, uint32_t *);
72 static int ql_status_error(ql_adapter_state_t *, ql_srb_t *, sts_entry_t *,
73     ql_head_t *, uint32_t *, uint32_t *);
74 static void ql_status_cont_entry(ql_adapter_state_t *, sts_cont_entry_t *,
75     ql_head_t *, uint32_t *, uint32_t *);
76 static void ql_ip_entry(ql_adapter_state_t *, ip_entry_t *, ql_head_t *,
77     uint32_t *, uint32_t *);
78 static void ql_ip_rcv_entry(ql_adapter_state_t *, ip_rcv_entry_t *,
79     ql_head_t *, uint32_t *, uint32_t *);
80 static void ql_ip_rcv_cont_entry(ql_adapter_state_t *,
81     ip_rcv_cont_entry_t *, ql_head_t *, uint32_t *, uint32_t *);
82 static void ql_ip_24xx_rcv_entry(ql_adapter_state_t *, ip_rcv_24xx_entry_t *,
83     ql_head_t *, uint32_t *, uint32_t *);
84 static void ql_ms_entry(ql_adapter_state_t *, ms_entry_t *, ql_head_t *,
85     uint32_t *, uint32_t *);
86 static void ql_report_id_entry(ql_adapter_state_t *, report_id_1_t *,
87     ql_head_t *, uint32_t *, uint32_t *);
88 static void ql_els_passthru_entry(ql_adapter_state_t *,
89     els_passthru_entry_rsp_t *, ql_head_t *, uint32_t *, uint32_t *);
90 
91 /*
92  * ql_isr
93  *	Process all INTX intr types.
94  *
95  * Input:
96  *	arg1:	adapter state pointer.
97  *
98  * Returns:
99  *	DDI_INTR_CLAIMED or DDI_INTR_UNCLAIMED
100  *
101  * Context:
102  *	Interrupt or Kernel context, no mailbox commands allowed.
103  */
104 /* ARGSUSED */
105 uint_t
106 ql_isr(caddr_t arg1)
107 {
108 	return (ql_isr_aif(arg1, 0));
109 }
110 
111 /*
112  * ql_isr_default
113  *	Process unknown/unvectored intr types
114  *
115  * Input:
116  *	arg1:	adapter state pointer.
117  *	arg2:	interrupt vector.
118  *
119  * Returns:
120  *	DDI_INTR_CLAIMED or DDI_INTR_UNCLAIMED
121  *
122  * Context:
123  *	Interrupt or Kernel context, no mailbox commands allowed.
124  */
125 /* ARGSUSED */
126 uint_t
127 ql_isr_default(caddr_t arg1, caddr_t arg2)
128 {
129 	ql_adapter_state_t	*ha = (void *)arg1;
130 
131 	EL(ha, "isr_default called: idx=%x\n", arg2);
132 	return (ql_isr_aif(arg1, arg2));
133 }
134 
135 /*
136  * ql_isr_aif
137  *	Process mailbox and I/O command completions.
138  *
139  * Input:
140  *	arg:	adapter state pointer.
141  *	intvec:	interrupt vector.
142  *
143  * Returns:
144  *	DDI_INTR_CLAIMED or DDI_INTR_UNCLAIMED
145  *
146  * Context:
147  *	Interrupt or Kernel context, no mailbox commands allowed.
148  */
149 /* ARGSUSED */
150 uint_t
151 ql_isr_aif(caddr_t arg, caddr_t intvec)
152 {
153 	uint16_t		mbx;
154 	uint32_t		stat;
155 	ql_adapter_state_t	*ha = (void *)arg;
156 	uint32_t		set_flags = 0;
157 	uint32_t		reset_flags = 0;
158 	ql_head_t		isr_done_q = {NULL, NULL};
159 	uint_t			rval = DDI_INTR_UNCLAIMED;
160 	int			spurious_intr = 0;
161 	boolean_t		intr = B_FALSE, daemon = B_FALSE;
162 	int			intr_loop = 4;
163 
164 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
165 
166 	QL_PM_LOCK(ha);
167 	if (ha->power_level != PM_LEVEL_D0) {
168 		/*
169 		 * Looks like we are about to go down soon, exit early.
170 		 */
171 		QL_PM_UNLOCK(ha);
172 		QL_PRINT_3(CE_CONT, "(%d): power down exit\n", ha->instance);
173 		return (DDI_INTR_UNCLAIMED);
174 	}
175 	ha->busy++;
176 	QL_PM_UNLOCK(ha);
177 
178 	/* Acquire interrupt lock. */
179 	INTR_LOCK(ha);
180 
181 	if (CFG_IST(ha, CFG_CTRL_2200)) {
182 		while (RD16_IO_REG(ha, istatus) & RISC_INT) {
183 			/* Reset idle timer. */
184 			ha->idle_timer = 0;
185 			rval = DDI_INTR_CLAIMED;
186 			if (intr_loop) {
187 				intr_loop--;
188 			}
189 
190 			/* Special Fast Post 2200. */
191 			stat = 0;
192 			if (ha->task_daemon_flags & FIRMWARE_LOADED &&
193 			    ha->flags & ONLINE) {
194 				ql_srb_t	*sp;
195 
196 				mbx = RD16_IO_REG(ha, mailbox[23]);
197 
198 				if ((mbx & 3) == MBX23_SCSI_COMPLETION) {
199 					/* Release mailbox registers. */
200 					WRT16_IO_REG(ha, semaphore, 0);
201 
202 					if (intr_loop) {
203 						WRT16_IO_REG(ha, hccr,
204 						    HC_CLR_RISC_INT);
205 					}
206 
207 					/* Get handle. */
208 					mbx >>= 4;
209 					stat = mbx & OSC_INDEX_MASK;
210 
211 					/* Validate handle. */
212 					sp = stat < MAX_OUTSTANDING_COMMANDS ?
213 					    ha->outstanding_cmds[stat] : NULL;
214 
215 					if (sp != NULL && (sp->handle & 0xfff)
216 					    == mbx) {
217 						ha->outstanding_cmds[stat] =
218 						    NULL;
219 						sp->handle = 0;
220 						sp->flags &=
221 						    ~SRB_IN_TOKEN_ARRAY;
222 
223 						/* Set completed status. */
224 						sp->flags |= SRB_ISP_COMPLETED;
225 
226 						/* Set completion status */
227 						sp->pkt->pkt_reason =
228 						    CS_COMPLETE;
229 
230 						ql_fast_fcp_post(sp);
231 					} else if (mbx !=
232 					    (QL_FCA_BRAND & 0xfff)) {
233 						if (sp == NULL) {
234 							EL(ha, "unknown IOCB"
235 							    " handle=%xh\n",
236 							    mbx);
237 						} else {
238 							EL(ha, "mismatch IOCB"
239 							    " handle pkt=%xh, "
240 							    "sp=%xh\n", mbx,
241 							    sp->handle & 0xfff);
242 						}
243 
244 						(void) ql_binary_fw_dump(ha,
245 						    FALSE);
246 
247 						if (!(ha->task_daemon_flags &
248 						    (ISP_ABORT_NEEDED |
249 						    ABORT_ISP_ACTIVE))) {
250 							EL(ha, "ISP Invalid "
251 							    "handle, "
252 							    "isp_abort_needed"
253 							    "\n");
254 							set_flags |=
255 							    ISP_ABORT_NEEDED;
256 						}
257 					}
258 				}
259 			}
260 
261 			if (stat == 0) {
262 				/* Check for mailbox interrupt. */
263 				mbx = RD16_IO_REG(ha, semaphore);
264 				if (mbx & BIT_0) {
265 					/* Release mailbox registers. */
266 					WRT16_IO_REG(ha, semaphore, 0);
267 
268 					/* Get mailbox data. */
269 					mbx = RD16_IO_REG(ha, mailbox[0]);
270 					if (mbx > 0x3fff && mbx < 0x8000) {
271 						ql_mbx_completion(ha, mbx,
272 						    &set_flags, &reset_flags,
273 						    intr_loop);
274 					} else if (mbx > 0x7fff &&
275 					    mbx < 0xc000) {
276 						ql_async_event(ha, mbx,
277 						    &isr_done_q, &set_flags,
278 						    &reset_flags, intr_loop);
279 					} else {
280 						EL(ha, "UNKNOWN interrupt "
281 						    "type\n");
282 						intr = B_TRUE;
283 					}
284 				} else {
285 					ha->isp_rsp_index = RD16_IO_REG(ha,
286 					    resp_in);
287 
288 					if (ha->isp_rsp_index !=
289 					    ha->rsp_ring_index) {
290 						ql_response_pkt(ha,
291 						    &isr_done_q, &set_flags,
292 						    &reset_flags, intr_loop);
293 					} else if (++spurious_intr ==
294 					    MAX_SPURIOUS_INTR) {
295 						/*
296 						 * Process excessive
297 						 * spurious intrrupts
298 						 */
299 						ql_spurious_intr(ha,
300 						    intr_loop);
301 						EL(ha, "excessive spurious "
302 						    "interrupts, "
303 						    "isp_abort_needed\n");
304 						set_flags |= ISP_ABORT_NEEDED;
305 					} else {
306 						intr = B_TRUE;
307 					}
308 				}
309 			}
310 
311 			/* Clear RISC interrupt */
312 			if (intr || intr_loop == 0) {
313 				intr = B_FALSE;
314 				WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT);
315 			}
316 
317 			if (set_flags != 0 || reset_flags != 0) {
318 				TASK_DAEMON_LOCK(ha);
319 				ha->task_daemon_flags |= set_flags;
320 				ha->task_daemon_flags &= ~reset_flags;
321 				TASK_DAEMON_UNLOCK(ha);
322 				set_flags = 0;
323 				reset_flags = 0;
324 				daemon = B_TRUE;
325 			}
326 		}
327 	} else {
328 		while ((stat = RD32_IO_REG(ha, intr_info_lo)) & RH_RISC_INT) {
329 			/* Capture FW defined interrupt info */
330 			mbx = MSW(stat);
331 
332 			/* Reset idle timer. */
333 			ha->idle_timer = 0;
334 			rval = DDI_INTR_CLAIMED;
335 			if (intr_loop) {
336 				intr_loop--;
337 			}
338 
339 			switch (stat & 0x1ff) {
340 			case ROM_MBX_SUCCESS:
341 			case ROM_MBX_ERR:
342 				ql_mbx_completion(ha, mbx, &set_flags,
343 				    &reset_flags, intr_loop);
344 
345 				/* Release mailbox registers. */
346 				if ((CFG_IST(ha, CFG_CTRL_242581)) == 0) {
347 					WRT16_IO_REG(ha, semaphore, 0);
348 				}
349 				break;
350 
351 			case MBX_SUCCESS:
352 			case MBX_ERR:
353 				/* Sun FW, Release mailbox registers. */
354 				if ((CFG_IST(ha, CFG_CTRL_242581)) == 0) {
355 					WRT16_IO_REG(ha, semaphore, 0);
356 				}
357 				ql_mbx_completion(ha, mbx, &set_flags,
358 				    &reset_flags, intr_loop);
359 				break;
360 
361 			case ASYNC_EVENT:
362 				/* Sun FW, Release mailbox registers. */
363 				if ((CFG_IST(ha, CFG_CTRL_242581)) == 0) {
364 					WRT16_IO_REG(ha, semaphore, 0);
365 				}
366 				ql_async_event(ha, (uint32_t)mbx, &isr_done_q,
367 				    &set_flags, &reset_flags, intr_loop);
368 				break;
369 
370 			case RESP_UPDATE:
371 				if (mbx != ha->rsp_ring_index) {
372 					ha->isp_rsp_index = mbx;
373 					ql_response_pkt(ha, &isr_done_q,
374 					    &set_flags, &reset_flags,
375 					    intr_loop);
376 				} else if (++spurious_intr ==
377 				    MAX_SPURIOUS_INTR) {
378 					/* Process excessive spurious intr. */
379 					ql_spurious_intr(ha, intr_loop);
380 					EL(ha, "excessive spurious "
381 					    "interrupts, isp_abort_needed\n");
382 					set_flags |= ISP_ABORT_NEEDED;
383 				} else {
384 					intr = B_TRUE;
385 				}
386 				break;
387 
388 			case SCSI_FAST_POST_16:
389 				stat = (stat & 0xffff0000) | MBA_CMPLT_1_16BIT;
390 				ql_async_event(ha, stat, &isr_done_q,
391 				    &set_flags, &reset_flags, intr_loop);
392 				break;
393 
394 			case SCSI_FAST_POST_32:
395 				stat = (stat & 0xffff0000) | MBA_CMPLT_1_32BIT;
396 				ql_async_event(ha, stat, &isr_done_q,
397 				    &set_flags, &reset_flags, intr_loop);
398 				break;
399 
400 			case CTIO_FAST_POST:
401 				stat = (stat & 0xffff0000) |
402 				    MBA_CTIO_COMPLETION;
403 				ql_async_event(ha, stat, &isr_done_q,
404 				    &set_flags, &reset_flags, intr_loop);
405 				break;
406 
407 			case IP_FAST_POST_XMT:
408 				stat = (stat & 0xffff0000) | MBA_IP_COMPLETION;
409 				ql_async_event(ha, stat, &isr_done_q,
410 				    &set_flags, &reset_flags, intr_loop);
411 				break;
412 
413 			case IP_FAST_POST_RCV:
414 				stat = (stat & 0xffff0000) | MBA_IP_RECEIVE;
415 				ql_async_event(ha, stat, &isr_done_q,
416 				    &set_flags, &reset_flags, intr_loop);
417 				break;
418 
419 			case IP_FAST_POST_BRD:
420 				stat = (stat & 0xffff0000) | MBA_IP_BROADCAST;
421 				ql_async_event(ha, stat, &isr_done_q,
422 				    &set_flags, &reset_flags, intr_loop);
423 				break;
424 
425 			case IP_FAST_POST_RCV_ALN:
426 				stat = (stat & 0xffff0000) |
427 				    MBA_IP_HDR_DATA_SPLIT;
428 				ql_async_event(ha, stat, &isr_done_q,
429 				    &set_flags, &reset_flags, intr_loop);
430 				break;
431 
432 			case ATIO_UPDATE:
433 				EL(ha, "unsupported ATIO queue update"
434 				    " interrupt, status=%xh\n", stat);
435 				intr = B_TRUE;
436 				break;
437 
438 			case ATIO_RESP_UPDATE:
439 				EL(ha, "unsupported ATIO response queue "
440 				    "update interrupt, status=%xh\n", stat);
441 				intr = B_TRUE;
442 				break;
443 
444 			default:
445 				ql_handle_uncommon_risc_intr(ha, stat,
446 				    &set_flags);
447 				intr = B_TRUE;
448 				break;
449 			}
450 
451 			/* Clear RISC interrupt */
452 			if (intr || intr_loop == 0) {
453 				intr = B_FALSE;
454 				CFG_IST(ha, CFG_CTRL_242581) ?
455 				    WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT) :
456 				    WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT);
457 			}
458 
459 			if (set_flags != 0 || reset_flags != 0) {
460 				TASK_DAEMON_LOCK(ha);
461 				ha->task_daemon_flags |= set_flags;
462 				ha->task_daemon_flags &= ~reset_flags;
463 				TASK_DAEMON_UNLOCK(ha);
464 				set_flags = 0;
465 				reset_flags = 0;
466 				daemon = B_TRUE;
467 			}
468 
469 			if (ha->flags & PARITY_ERROR) {
470 				EL(ha, "parity/pause exit\n");
471 				mbx = RD16_IO_REG(ha, hccr); /* PCI posting */
472 				break;
473 			}
474 		}
475 	}
476 
477 	/* Process claimed interrupts during polls. */
478 	if (rval == DDI_INTR_UNCLAIMED && ha->intr_claimed == B_TRUE) {
479 		ha->intr_claimed = B_FALSE;
480 		rval = DDI_INTR_CLAIMED;
481 	}
482 
483 	/* Release interrupt lock. */
484 	INTR_UNLOCK(ha);
485 
486 	if (daemon) {
487 		ql_awaken_task_daemon(ha, NULL, 0, 0);
488 	}
489 
490 	if (isr_done_q.first != NULL) {
491 		ql_done(isr_done_q.first);
492 	}
493 
494 	if (rval == DDI_INTR_CLAIMED) {
495 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
496 		ha->xioctl->TotalInterrupts++;
497 	} else {
498 		/*EMPTY*/
499 		QL_PRINT_3(CE_CONT, "(%d): interrupt not claimed\n",
500 		    ha->instance);
501 	}
502 
503 	QL_PM_LOCK(ha);
504 	ha->busy--;
505 	QL_PM_UNLOCK(ha);
506 
507 	return (rval);
508 }
509 
510 /*
511  * ql_handle_uncommon_risc_intr
512  *	Handle an uncommon RISC interrupt.
513  *
514  * Input:
515  *	ha:		adapter state pointer.
516  *	stat:		interrupt status
517  *
518  * Context:
519  *	Interrupt or Kernel context, no mailbox commands allowed.
520  */
521 static void
522 ql_handle_uncommon_risc_intr(ql_adapter_state_t *ha, uint32_t stat,
523     uint32_t *set_flags)
524 {
525 	uint16_t	hccr_reg;
526 
527 	hccr_reg = RD16_IO_REG(ha, hccr);
528 
529 	if (stat & RH_RISC_PAUSED ||
530 	    (hccr_reg & (BIT_15 | BIT_13 | BIT_11 | BIT_8))) {
531 
532 		ADAPTER_STATE_LOCK(ha);
533 		ha->flags |= PARITY_ERROR;
534 		ADAPTER_STATE_UNLOCK(ha);
535 
536 		if (ha->parity_pause_errors == 0 ||
537 		    ha->parity_hccr_err != hccr_reg ||
538 		    ha->parity_stat_err != stat) {
539 			cmn_err(CE_WARN, "qlc(%d): isr, Internal Parity/"
540 			    "Pause Error - hccr=%xh, stat=%xh, count=%d",
541 			    ha->instance, hccr_reg, stat,
542 			    ha->parity_pause_errors);
543 			ha->parity_hccr_err = hccr_reg;
544 			ha->parity_stat_err = stat;
545 		}
546 
547 		EL(ha, "parity/pause error, isp_abort_needed\n");
548 
549 		if (ql_binary_fw_dump(ha, FALSE) != QL_SUCCESS) {
550 			ql_reset_chip(ha);
551 		}
552 
553 		if (ha->parity_pause_errors == 0) {
554 			(void) ql_flash_errlog(ha, FLASH_ERRLOG_PARITY_ERR,
555 			    0, MSW(stat), LSW(stat));
556 		}
557 
558 		if (ha->parity_pause_errors < 0xffffffff) {
559 			ha->parity_pause_errors++;
560 		}
561 
562 		*set_flags |= ISP_ABORT_NEEDED;
563 
564 		/* Disable ISP interrupts. */
565 		WRT16_IO_REG(ha, ictrl, 0);
566 		ADAPTER_STATE_LOCK(ha);
567 		ha->flags &= ~INTERRUPTS_ENABLED;
568 		ADAPTER_STATE_UNLOCK(ha);
569 	} else {
570 		EL(ha, "UNKNOWN interrupt status=%xh, hccr=%xh\n",
571 		    stat, hccr_reg);
572 	}
573 }
574 
575 /*
576  * ql_spurious_intr
577  *	Inform Solaris of spurious interrupts.
578  *
579  * Input:
580  *	ha:		adapter state pointer.
581  *	intr_clr:	early interrupt clear
582  *
583  * Context:
584  *	Interrupt or Kernel context, no mailbox commands allowed.
585  */
586 static void
587 ql_spurious_intr(ql_adapter_state_t *ha, int intr_clr)
588 {
589 	ddi_devstate_t	state;
590 
591 	EL(ha, "Spurious interrupt\n");
592 
593 	/* Disable ISP interrupts. */
594 	WRT16_IO_REG(ha, ictrl, 0);
595 	ADAPTER_STATE_LOCK(ha);
596 	ha->flags &= ~INTERRUPTS_ENABLED;
597 	ADAPTER_STATE_UNLOCK(ha);
598 
599 	/* Clear RISC interrupt */
600 	if (intr_clr) {
601 		CFG_IST(ha, CFG_CTRL_242581) ?
602 		    WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT) :
603 		    WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT);
604 	}
605 
606 	state = ddi_get_devstate(ha->dip);
607 	if (state == DDI_DEVSTATE_UP) {
608 		/*EMPTY*/
609 		ddi_dev_report_fault(ha->dip, DDI_SERVICE_DEGRADED,
610 		    DDI_DEVICE_FAULT, "spurious interrupts");
611 	}
612 }
613 
614 /*
615  * ql_mbx_completion
616  *	Processes mailbox completions.
617  *
618  * Input:
619  *	ha:		adapter state pointer.
620  *	mb0:		Mailbox 0 contents.
621  *	set_flags:	task daemon flags to set.
622  *	reset_flags:	task daemon flags to reset.
623  *	intr_clr:	early interrupt clear
624  *
625  * Context:
626  *	Interrupt context.
627  */
628 /* ARGSUSED */
629 static void
630 ql_mbx_completion(ql_adapter_state_t *ha, uint16_t mb0, uint32_t *set_flags,
631     uint32_t *reset_flags, int intr_clr)
632 {
633 	uint32_t	index;
634 	uint16_t	cnt;
635 
636 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
637 
638 	/* Load return mailbox registers. */
639 	MBX_REGISTER_LOCK(ha);
640 
641 	if (ha->mcp != NULL) {
642 		ha->mcp->mb[0] = mb0;
643 		index = ha->mcp->in_mb & ~MBX_0;
644 
645 		for (cnt = 1; cnt < MAX_MBOX_COUNT && index != 0; cnt++) {
646 			index >>= 1;
647 			if (index & MBX_0) {
648 				ha->mcp->mb[cnt] = RD16_IO_REG(ha,
649 				    mailbox[cnt]);
650 			}
651 		}
652 
653 	} else {
654 		EL(ha, "mcp == NULL\n");
655 	}
656 
657 	if (intr_clr) {
658 		/* Clear RISC interrupt. */
659 		CFG_IST(ha, CFG_CTRL_242581) ?
660 		    WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT) :
661 		    WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT);
662 	}
663 
664 	ha->mailbox_flags = (uint8_t)(ha->mailbox_flags | MBX_INTERRUPT);
665 	if (ha->flags & INTERRUPTS_ENABLED) {
666 		cv_broadcast(&ha->cv_mbx_intr);
667 	}
668 
669 	MBX_REGISTER_UNLOCK(ha);
670 
671 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
672 }
673 
674 /*
675  * ql_async_event
676  *	Processes asynchronous events.
677  *
678  * Input:
679  *	ha:		adapter state pointer.
680  *	mbx:		Mailbox 0 register.
681  *	done_q:		head pointer to done queue.
682  *	set_flags:	task daemon flags to set.
683  *	reset_flags:	task daemon flags to reset.
684  *	intr_clr:	early interrupt clear
685  *
686  * Context:
687  *	Interrupt or Kernel context, no mailbox commands allowed.
688  */
689 static void
690 ql_async_event(ql_adapter_state_t *ha, uint32_t mbx, ql_head_t *done_q,
691     uint32_t *set_flags, uint32_t *reset_flags, int intr_clr)
692 {
693 	uint32_t		handle;
694 	uint32_t		index;
695 	uint16_t		cnt;
696 	uint16_t		mb[MAX_MBOX_COUNT];
697 	ql_srb_t		*sp;
698 	port_id_t		s_id;
699 	ql_tgt_t		*tq;
700 	boolean_t		intr = B_TRUE;
701 	ql_adapter_state_t	*vha;
702 
703 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
704 
705 	/* Setup to process fast completion. */
706 	mb[0] = LSW(mbx);
707 	switch (mb[0]) {
708 	case MBA_SCSI_COMPLETION:
709 		handle = SHORT_TO_LONG(RD16_IO_REG(ha, mailbox[1]),
710 		    RD16_IO_REG(ha, mailbox[2]));
711 		break;
712 
713 	case MBA_CMPLT_1_16BIT:
714 		handle = MSW(mbx);
715 		mb[0] = MBA_SCSI_COMPLETION;
716 		break;
717 
718 	case MBA_CMPLT_1_32BIT:
719 		handle = SHORT_TO_LONG(MSW(mbx), RD16_IO_REG(ha, mailbox[2]));
720 		mb[0] = MBA_SCSI_COMPLETION;
721 		break;
722 
723 	case MBA_CTIO_COMPLETION:
724 	case MBA_IP_COMPLETION:
725 		handle = CFG_IST(ha, CFG_CTRL_2200) ? SHORT_TO_LONG(
726 		    RD16_IO_REG(ha, mailbox[1]), RD16_IO_REG(ha, mailbox[2])) :
727 		    SHORT_TO_LONG(MSW(mbx), RD16_IO_REG(ha, mailbox[2]));
728 		mb[0] = MBA_SCSI_COMPLETION;
729 		break;
730 
731 	default:
732 		break;
733 	}
734 
735 	/* Handle asynchronous event */
736 	switch (mb[0]) {
737 	case MBA_SCSI_COMPLETION:
738 		QL_PRINT_5(CE_CONT, "(%d): Fast post completion\n",
739 		    ha->instance);
740 
741 		if (intr_clr) {
742 			/* Clear RISC interrupt */
743 			CFG_IST(ha, CFG_CTRL_242581) ?
744 			    WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT) :
745 			    WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT);
746 			intr = B_FALSE;
747 		}
748 
749 		if ((ha->flags & ONLINE) == 0) {
750 			break;
751 		}
752 
753 		/* Get handle. */
754 		index = handle & OSC_INDEX_MASK;
755 
756 		/* Validate handle. */
757 		sp = index < MAX_OUTSTANDING_COMMANDS ?
758 		    ha->outstanding_cmds[index] : NULL;
759 
760 		if (sp != NULL && sp->handle == handle) {
761 			ha->outstanding_cmds[index] = NULL;
762 			sp->handle = 0;
763 			sp->flags &= ~SRB_IN_TOKEN_ARRAY;
764 
765 			/* Set completed status. */
766 			sp->flags |= SRB_ISP_COMPLETED;
767 
768 			/* Set completion status */
769 			sp->pkt->pkt_reason = CS_COMPLETE;
770 
771 			if (!(sp->flags & SRB_FCP_CMD_PKT)) {
772 				/* Place block on done queue */
773 				ql_add_link_b(done_q, &sp->cmd);
774 			} else {
775 				ql_fast_fcp_post(sp);
776 			}
777 		} else if (handle != QL_FCA_BRAND) {
778 			if (sp == NULL) {
779 				EL(ha, "%xh unknown IOCB handle=%xh\n",
780 				    mb[0], handle);
781 			} else {
782 				EL(ha, "%xh mismatch IOCB handle pkt=%xh, "
783 				    "sp=%xh\n", mb[0], handle, sp->handle);
784 			}
785 
786 			EL(ha, "%xh Fast post, mbx1=%xh, mbx2=%xh, mbx3=%xh,"
787 			    "mbx6=%xh, mbx7=%xh\n", mb[0],
788 			    RD16_IO_REG(ha, mailbox[1]),
789 			    RD16_IO_REG(ha, mailbox[2]),
790 			    RD16_IO_REG(ha, mailbox[3]),
791 			    RD16_IO_REG(ha, mailbox[6]),
792 			    RD16_IO_REG(ha, mailbox[7]));
793 
794 			(void) ql_binary_fw_dump(ha, FALSE);
795 
796 			if (!(ha->task_daemon_flags &
797 			    (ISP_ABORT_NEEDED | ABORT_ISP_ACTIVE))) {
798 				EL(ha, "%xh ISP Invalid handle, "
799 				    "isp_abort_needed\n", mb[0]);
800 				*set_flags |= ISP_ABORT_NEEDED;
801 			}
802 		}
803 		break;
804 
805 	case MBA_RESET:		/* Reset */
806 		EL(ha, "%xh Reset received\n", mb[0]);
807 		*set_flags |= RESET_MARKER_NEEDED;
808 		break;
809 
810 	case MBA_SYSTEM_ERR:		/* System Error */
811 		mb[1] = RD16_IO_REG(ha, mailbox[1]);
812 		mb[2] = RD16_IO_REG(ha, mailbox[2]);
813 		mb[3] = RD16_IO_REG(ha, mailbox[3]);
814 		mb[7] = RD16_IO_REG(ha, mailbox[7]);
815 
816 		EL(ha, "%xh ISP System Error, isp_abort_needed\n mbx1=%xh, "
817 		    "mbx2=%xh, mbx3=%xh, mbx4=%xh, mbx5=%xh, mbx6=%xh,\n "
818 		    "mbx7=%xh, mbx8=%xh, mbx9=%xh, mbx10=%xh, mbx11=%xh, "
819 		    "mbx12=%xh,\n", mb[0], mb[1], mb[2], mb[3],
820 		    RD16_IO_REG(ha, mailbox[4]), RD16_IO_REG(ha, mailbox[5]),
821 		    RD16_IO_REG(ha, mailbox[6]), mb[7],
822 		    RD16_IO_REG(ha, mailbox[8]), RD16_IO_REG(ha, mailbox[9]),
823 		    RD16_IO_REG(ha, mailbox[10]), RD16_IO_REG(ha, mailbox[11]),
824 		    RD16_IO_REG(ha, mailbox[12]));
825 
826 		EL(ha, "%xh ISP System Error, isp_abort_needed\n mbx13=%xh, "
827 		    "mbx14=%xh, mbx15=%xh, mbx16=%xh, mbx17=%xh, mbx18=%xh,\n"
828 		    "mbx19=%xh, mbx20=%xh, mbx21=%xh, mbx22=%xh, mbx23=%xh\n",
829 		    mb[0], RD16_IO_REG(ha, mailbox[13]),
830 		    RD16_IO_REG(ha, mailbox[14]), RD16_IO_REG(ha, mailbox[15]),
831 		    RD16_IO_REG(ha, mailbox[16]), RD16_IO_REG(ha, mailbox[17]),
832 		    RD16_IO_REG(ha, mailbox[18]), RD16_IO_REG(ha, mailbox[19]),
833 		    RD16_IO_REG(ha, mailbox[20]), RD16_IO_REG(ha, mailbox[21]),
834 		    RD16_IO_REG(ha, mailbox[22]),
835 		    RD16_IO_REG(ha, mailbox[23]));
836 
837 		if (ha->reg_off->mbox_cnt > 24) {
838 			EL(ha, "%xh ISP System Error, mbx24=%xh, mbx25=%xh, "
839 			    "mbx26=%xh,\n mbx27=%xh, mbx28=%xh, mbx29=%xh, "
840 			    "mbx30=%xh, mbx31=%xh\n", mb[0],
841 			    RD16_IO_REG(ha, mailbox[24]),
842 			    RD16_IO_REG(ha, mailbox[25]),
843 			    RD16_IO_REG(ha, mailbox[26]),
844 			    RD16_IO_REG(ha, mailbox[27]),
845 			    RD16_IO_REG(ha, mailbox[28]),
846 			    RD16_IO_REG(ha, mailbox[29]),
847 			    RD16_IO_REG(ha, mailbox[30]),
848 			    RD16_IO_REG(ha, mailbox[31]));
849 		}
850 
851 		(void) ql_binary_fw_dump(ha, FALSE);
852 
853 		(void) ql_flash_errlog(ha, FLASH_ERRLOG_AEN_8002, mb[1],
854 		    mb[2], mb[3]);
855 
856 		if (CFG_IST(ha, CFG_CTRL_81XX) && mb[7] & SE_MPI_RISC) {
857 			ADAPTER_STATE_LOCK(ha);
858 			ha->flags |= MPI_RESET_NEEDED;
859 			ADAPTER_STATE_UNLOCK(ha);
860 		}
861 
862 		*set_flags |= ISP_ABORT_NEEDED;
863 		ha->xioctl->ControllerErrorCount++;
864 		break;
865 
866 	case MBA_REQ_TRANSFER_ERR:  /* Request Transfer Error */
867 		EL(ha, "%xh Request Transfer Error received, "
868 		    "isp_abort_needed\n", mb[0]);
869 
870 		(void) ql_flash_errlog(ha, FLASH_ERRLOG_AEN_8003,
871 		    RD16_IO_REG(ha, mailbox[1]), RD16_IO_REG(ha, mailbox[2]),
872 		    RD16_IO_REG(ha, mailbox[3]));
873 
874 		*set_flags |= ISP_ABORT_NEEDED;
875 		ha->xioctl->ControllerErrorCount++;
876 		break;
877 
878 	case MBA_RSP_TRANSFER_ERR:  /* Response Xfer Err */
879 		EL(ha, "%xh Response Transfer Error received,"
880 		    " isp_abort_needed\n", mb[0]);
881 
882 		(void) ql_flash_errlog(ha, FLASH_ERRLOG_AEN_8004,
883 		    RD16_IO_REG(ha, mailbox[1]), RD16_IO_REG(ha, mailbox[2]),
884 		    RD16_IO_REG(ha, mailbox[3]));
885 
886 		*set_flags |= ISP_ABORT_NEEDED;
887 		ha->xioctl->ControllerErrorCount++;
888 		break;
889 
890 	case MBA_WAKEUP_THRES: /* Request Queue Wake-up */
891 		EL(ha, "%xh Request Queue Wake-up received\n",
892 		    mb[0]);
893 		break;
894 
895 	case MBA_MENLO_ALERT:	/* Menlo Alert Notification */
896 		mb[1] = RD16_IO_REG(ha, mailbox[1]);
897 		mb[2] = RD16_IO_REG(ha, mailbox[2]);
898 		mb[3] = RD16_IO_REG(ha, mailbox[3]);
899 
900 		EL(ha, "%xh Menlo Alert Notification received, mbx1=%xh,"
901 		    " mbx2=%xh, mbx3=%xh\n", mb[0], mb[1], mb[2], mb[3]);
902 
903 		switch (mb[1]) {
904 		case MLA_LOGIN_OPERATIONAL_FW:
905 			ADAPTER_STATE_LOCK(ha);
906 			ha->flags |= MENLO_LOGIN_OPERATIONAL;
907 			ADAPTER_STATE_UNLOCK(ha);
908 			break;
909 		case MLA_PANIC_RECOVERY:
910 		case MLA_LOGIN_DIAGNOSTIC_FW:
911 		case MLA_LOGIN_GOLDEN_FW:
912 		case MLA_REJECT_RESPONSE:
913 		default:
914 			break;
915 		}
916 		break;
917 
918 	case MBA_LIP_F8:	/* Received a LIP F8. */
919 	case MBA_LIP_RESET:	/* LIP reset occurred. */
920 	case MBA_LIP_OCCURRED:	/* Loop Initialization Procedure */
921 		if (CFG_IST(ha, CFG_CTRL_81XX)) {
922 			EL(ha, "%xh DCBX_STARTED received, mbx1=%xh, mbx2=%xh"
923 			    "\n", mb[0], RD16_IO_REG(ha, mailbox[1]),
924 			    RD16_IO_REG(ha, mailbox[2]));
925 		} else {
926 			EL(ha, "%xh LIP received\n", mb[0]);
927 		}
928 
929 		ADAPTER_STATE_LOCK(ha);
930 		ha->flags &= ~POINT_TO_POINT;
931 		ADAPTER_STATE_UNLOCK(ha);
932 
933 		if (!(ha->task_daemon_flags & LOOP_DOWN)) {
934 			*set_flags |= LOOP_DOWN;
935 		}
936 		ql_port_state(ha, FC_STATE_OFFLINE,
937 		    FC_STATE_CHANGE | COMMAND_WAIT_NEEDED | LOOP_DOWN);
938 
939 		if (ha->loop_down_timer == LOOP_DOWN_TIMER_OFF) {
940 			ha->loop_down_timer = LOOP_DOWN_TIMER_START;
941 		}
942 
943 		ha->adapter_stats->lip_count++;
944 
945 		/* Update AEN queue. */
946 		ha->xioctl->TotalLipResets++;
947 		if (ha->xioctl->flags & QL_AEN_TRACKING_ENABLE) {
948 			ql_enqueue_aen(ha, mb[0], NULL);
949 		}
950 		break;
951 
952 	case MBA_LOOP_UP:
953 		if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322 |
954 		    CFG_CTRL_242581))) {
955 			mb[1] = RD16_IO_REG(ha, mailbox[1]);
956 			if (mb[1] == IIDMA_RATE_1GB) {		/* 1GB */
957 				ha->state = FC_PORT_STATE_MASK(
958 				    ha->state) | FC_STATE_1GBIT_SPEED;
959 				index = 1;
960 			} else if (mb[1] == IIDMA_RATE_2GB) {	/* 2GB */
961 				ha->state = FC_PORT_STATE_MASK(
962 				    ha->state) | FC_STATE_2GBIT_SPEED;
963 				index = 2;
964 			} else if (mb[1] == IIDMA_RATE_4GB) {	/* 4GB */
965 				ha->state = FC_PORT_STATE_MASK(
966 				    ha->state) | FC_STATE_4GBIT_SPEED;
967 				index = 4;
968 			} else if (mb[1] == IIDMA_RATE_8GB) {	/* 8GB */
969 				ha->state = FC_PORT_STATE_MASK(
970 				    ha->state) | FC_STATE_8GBIT_SPEED;
971 				index = 8;
972 			} else if (mb[1] == IIDMA_RATE_10GB) {	/* 10GB */
973 				ha->state = FC_PORT_STATE_MASK(
974 				    ha->state) | FC_STATE_10GBIT_SPEED;
975 				index = 10;
976 			} else {
977 				ha->state = FC_PORT_STATE_MASK(
978 				    ha->state);
979 				index = 0;
980 			}
981 		} else {
982 			ha->state = FC_PORT_STATE_MASK(ha->state) |
983 			    FC_STATE_FULL_SPEED;
984 			index = 1;
985 		}
986 
987 		for (vha = ha; vha != NULL; vha = vha->vp_next) {
988 			vha->state = FC_PORT_STATE_MASK(vha->state) |
989 			    FC_PORT_SPEED_MASK(ha->state);
990 		}
991 		EL(ha, "%d GB %xh Loop Up received\n", index, mb[0]);
992 
993 		/* Update AEN queue. */
994 		if (ha->xioctl->flags & QL_AEN_TRACKING_ENABLE) {
995 			ql_enqueue_aen(ha, mb[0], NULL);
996 		}
997 		break;
998 
999 	case MBA_LOOP_DOWN:
1000 		EL(ha, "%xh Loop Down received, mbx1=%xh, mbx2=%xh, mbx3=%xh, "
1001 		    "mbx4=%xh\n", mb[0], RD16_IO_REG(ha, mailbox[1]),
1002 		    RD16_IO_REG(ha, mailbox[2]), RD16_IO_REG(ha, mailbox[3]),
1003 		    RD16_IO_REG(ha, mailbox[4]));
1004 
1005 		if (!(ha->task_daemon_flags & LOOP_DOWN)) {
1006 			*set_flags |= LOOP_DOWN;
1007 		}
1008 		ql_port_state(ha, FC_STATE_OFFLINE,
1009 		    FC_STATE_CHANGE | COMMAND_WAIT_NEEDED | LOOP_DOWN);
1010 
1011 		if (ha->loop_down_timer == LOOP_DOWN_TIMER_OFF) {
1012 			ha->loop_down_timer = LOOP_DOWN_TIMER_START;
1013 		}
1014 
1015 		if (CFG_IST(ha, CFG_CTRL_2581)) {
1016 			ha->sfp_stat = RD16_IO_REG(ha, mailbox[2]);
1017 		}
1018 
1019 		/* Update AEN queue. */
1020 		if (ha->xioctl->flags & QL_AEN_TRACKING_ENABLE) {
1021 			ql_enqueue_aen(ha, mb[0], NULL);
1022 		}
1023 		break;
1024 
1025 	case MBA_PORT_UPDATE:
1026 		mb[1] = RD16_IO_REG(ha, mailbox[1]);
1027 		mb[2] = RD16_IO_REG(ha, mailbox[2]);
1028 		mb[3] = (uint16_t)(ha->flags & VP_ENABLED ?
1029 		    RD16_IO_REG(ha, mailbox[3]) : 0);
1030 
1031 		/* Locate port state structure. */
1032 		for (vha = ha; vha != NULL; vha = vha->vp_next) {
1033 			if (vha->vp_index == LSB(mb[3])) {
1034 				break;
1035 			}
1036 		}
1037 		if (vha == NULL) {
1038 			break;
1039 		}
1040 		/*
1041 		 * In N port 2 N port topology the FW provides a port
1042 		 * database entry at loop_id 0x7fe which we use to
1043 		 * acquire the Ports WWPN.
1044 		 */
1045 		if ((mb[1] != 0x7fe) &&
1046 		    ((FC_PORT_STATE_MASK(vha->state) != FC_STATE_OFFLINE ||
1047 		    (CFG_IST(ha, CFG_CTRL_242581) &&
1048 		    (mb[1] != 0xffff || mb[2] != 6 || mb[3] != 0))))) {
1049 			EL(ha, "%xh Port Database Update, Login/Logout "
1050 			    "received, mbx1=%xh, mbx2=%xh, mbx3=%xh\n",
1051 			    mb[0], mb[1], mb[2], mb[3]);
1052 		} else {
1053 			EL(ha, "%xh Port Database Update received, mbx1=%xh,"
1054 			    " mbx2=%xh, mbx3=%xh\n", mb[0], mb[1], mb[2],
1055 			    mb[3]);
1056 			*set_flags |= LOOP_RESYNC_NEEDED;
1057 			*set_flags &= ~LOOP_DOWN;
1058 			*reset_flags |= LOOP_DOWN;
1059 			*reset_flags &= ~LOOP_RESYNC_NEEDED;
1060 			vha->loop_down_timer = LOOP_DOWN_TIMER_OFF;
1061 			TASK_DAEMON_LOCK(ha);
1062 			vha->task_daemon_flags |= LOOP_RESYNC_NEEDED;
1063 			vha->task_daemon_flags &= ~LOOP_DOWN;
1064 			TASK_DAEMON_UNLOCK(ha);
1065 			ADAPTER_STATE_LOCK(ha);
1066 			vha->flags &= ~ABORT_CMDS_LOOP_DOWN_TMO;
1067 			ADAPTER_STATE_UNLOCK(ha);
1068 		}
1069 
1070 		/* Update AEN queue. */
1071 		if (ha->xioctl->flags & QL_AEN_TRACKING_ENABLE) {
1072 			ql_enqueue_aen(ha, mb[0], NULL);
1073 		}
1074 		break;
1075 
1076 	case MBA_RSCN_UPDATE:
1077 		mb[1] = RD16_IO_REG(ha, mailbox[1]);
1078 		mb[2] = RD16_IO_REG(ha, mailbox[2]);
1079 		mb[3] = (uint16_t)(ha->flags & VP_ENABLED ?
1080 		    RD16_IO_REG(ha, mailbox[3]) : 0);
1081 
1082 		/* Locate port state structure. */
1083 		for (vha = ha; vha != NULL; vha = vha->vp_next) {
1084 			if (vha->vp_index == LSB(mb[3])) {
1085 				break;
1086 			}
1087 		}
1088 
1089 		if (vha == NULL) {
1090 			break;
1091 		}
1092 
1093 		if (LSB(mb[1]) == vha->d_id.b.domain &&
1094 		    MSB(mb[2]) == vha->d_id.b.area &&
1095 		    LSB(mb[2]) == vha->d_id.b.al_pa) {
1096 			EL(ha, "%xh RSCN match adapter, mbx1=%xh, mbx2=%xh, "
1097 			    "mbx3=%xh\n", mb[0], mb[1], mb[2], mb[3]);
1098 		} else {
1099 			EL(ha, "%xh RSCN received, mbx1=%xh, mbx2=%xh, "
1100 			    "mbx3=%xh\n", mb[0], mb[1], mb[2], mb[3]);
1101 			if (FC_PORT_STATE_MASK(vha->state) !=
1102 			    FC_STATE_OFFLINE) {
1103 				ql_rcv_rscn_els(vha, &mb[0], done_q);
1104 				TASK_DAEMON_LOCK(ha);
1105 				vha->task_daemon_flags |= RSCN_UPDATE_NEEDED;
1106 				TASK_DAEMON_UNLOCK(ha);
1107 				*set_flags |= RSCN_UPDATE_NEEDED;
1108 			}
1109 		}
1110 
1111 		/* Update AEN queue. */
1112 		if (ha->xioctl->flags & QL_AEN_TRACKING_ENABLE) {
1113 			ql_enqueue_aen(ha, mb[0], NULL);
1114 		}
1115 		break;
1116 
1117 	case MBA_LIP_ERROR:	/* Loop initialization errors. */
1118 		EL(ha, "%xh LIP error received, mbx1=%xh\n", mb[0],
1119 		    RD16_IO_REG(ha, mailbox[1]));
1120 		break;
1121 
1122 	case MBA_IP_RECEIVE:
1123 	case MBA_IP_BROADCAST:
1124 		mb[1] = RD16_IO_REG(ha, mailbox[1]);
1125 		mb[2] = RD16_IO_REG(ha, mailbox[2]);
1126 		mb[3] = RD16_IO_REG(ha, mailbox[3]);
1127 
1128 		EL(ha, "%xh IP packet/broadcast received, mbx1=%xh, "
1129 		    "mbx2=%xh, mbx3=%xh\n", mb[0], mb[1], mb[2], mb[3]);
1130 
1131 		/* Locate device queue. */
1132 		s_id.b.al_pa = LSB(mb[2]);
1133 		s_id.b.area = MSB(mb[2]);
1134 		s_id.b.domain = LSB(mb[1]);
1135 		if ((tq = ql_d_id_to_queue(ha, s_id)) == NULL) {
1136 			EL(ha, "Unknown IP device=%xh\n", s_id.b24);
1137 			break;
1138 		}
1139 
1140 		cnt = (uint16_t)(CFG_IST(ha, CFG_CTRL_242581) ?
1141 		    CHAR_TO_SHORT(ha->ip_init_ctrl_blk.cb24.buf_size[0],
1142 		    ha->ip_init_ctrl_blk.cb24.buf_size[1]) :
1143 		    CHAR_TO_SHORT(ha->ip_init_ctrl_blk.cb.buf_size[0],
1144 		    ha->ip_init_ctrl_blk.cb.buf_size[1]));
1145 
1146 		tq->ub_sequence_length = mb[3];
1147 		tq->ub_total_seg_cnt = (uint8_t)(mb[3] / cnt);
1148 		if (mb[3] % cnt) {
1149 			tq->ub_total_seg_cnt++;
1150 		}
1151 		cnt = (uint16_t)(tq->ub_total_seg_cnt + 10);
1152 
1153 		for (index = 10; index < ha->reg_off->mbox_cnt && index < cnt;
1154 		    index++) {
1155 			mb[index] = RD16_IO_REG(ha, mailbox[index]);
1156 		}
1157 
1158 		tq->ub_seq_id = ++ha->ub_seq_id;
1159 		tq->ub_seq_cnt = 0;
1160 		tq->ub_frame_ro = 0;
1161 		tq->ub_loop_id = (uint16_t)(mb[0] == MBA_IP_BROADCAST ?
1162 		    (CFG_IST(ha, CFG_CTRL_242581) ? BROADCAST_24XX_HDL :
1163 		    IP_BROADCAST_LOOP_ID) : tq->loop_id);
1164 		ha->rcv_dev_q = tq;
1165 
1166 		for (cnt = 10; cnt < ha->reg_off->mbox_cnt &&
1167 		    tq->ub_seq_cnt < tq->ub_total_seg_cnt; cnt++) {
1168 			if (ql_ub_frame_hdr(ha, tq, mb[cnt], done_q) !=
1169 			    QL_SUCCESS) {
1170 				EL(ha, "ql_ub_frame_hdr failed, "
1171 				    "isp_abort_needed\n");
1172 				*set_flags |= ISP_ABORT_NEEDED;
1173 				break;
1174 			}
1175 		}
1176 		break;
1177 
1178 	case MBA_IP_LOW_WATER_MARK:
1179 	case MBA_IP_RCV_BUFFER_EMPTY:
1180 		EL(ha, "%xh IP low water mark / RCV buffer empty received\n",
1181 		    mb[0]);
1182 		*set_flags |= NEED_UNSOLICITED_BUFFERS;
1183 		break;
1184 
1185 	case MBA_IP_HDR_DATA_SPLIT:
1186 		EL(ha, "%xh IP HDR data split received\n", mb[0]);
1187 		break;
1188 
1189 	case MBA_ERROR_LOGGING_DISABLED:
1190 		EL(ha, "%xh error logging disabled received, "
1191 		    "mbx1=%xh\n", mb[0], RD16_IO_REG(ha, mailbox[1]));
1192 		break;
1193 
1194 	case MBA_POINT_TO_POINT:
1195 	/* case MBA_DCBX_COMPLETED: */
1196 		if (CFG_IST(ha, CFG_CTRL_81XX)) {
1197 			EL(ha, "%xh DCBX completed received\n", mb[0]);
1198 		} else {
1199 			EL(ha, "%xh Point to Point Mode received\n", mb[0]);
1200 		}
1201 		ADAPTER_STATE_LOCK(ha);
1202 		ha->flags |= POINT_TO_POINT;
1203 		ADAPTER_STATE_UNLOCK(ha);
1204 		break;
1205 
1206 	case MBA_FCF_CONFIG_ERROR:
1207 		EL(ha, "%xh FCF configuration Error received, mbx1=%xh\n",
1208 		    mb[0], RD16_IO_REG(ha, mailbox[1]));
1209 		break;
1210 
1211 	case MBA_DCBX_PARAM_CHANGED:
1212 		EL(ha, "%xh DCBX parameters changed received, mbx1=%xh\n",
1213 		    mb[0], RD16_IO_REG(ha, mailbox[1]));
1214 		break;
1215 
1216 	case MBA_CHG_IN_CONNECTION:
1217 		mb[1] = RD16_IO_REG(ha, mailbox[1]);
1218 		if (mb[1] == 2) {
1219 			EL(ha, "%xh Change In Connection received, "
1220 			    "mbx1=%xh\n",  mb[0], mb[1]);
1221 			ADAPTER_STATE_LOCK(ha);
1222 			ha->flags &= ~POINT_TO_POINT;
1223 			ADAPTER_STATE_UNLOCK(ha);
1224 			if (ha->topology & QL_N_PORT) {
1225 				ha->topology = (uint8_t)(ha->topology &
1226 				    ~QL_N_PORT);
1227 				ha->topology = (uint8_t)(ha->topology |
1228 				    QL_NL_PORT);
1229 			}
1230 		} else {
1231 			EL(ha, "%xh Change In Connection received, "
1232 			    "mbx1=%xh, isp_abort_needed\n", mb[0], mb[1]);
1233 			*set_flags |= ISP_ABORT_NEEDED;
1234 		}
1235 		break;
1236 
1237 	case MBA_ZIO_UPDATE:
1238 		EL(ha, "%xh ZIO response received\n", mb[0]);
1239 
1240 		ha->isp_rsp_index = RD16_IO_REG(ha, resp_in);
1241 		ql_response_pkt(ha, done_q, set_flags, reset_flags, intr_clr);
1242 		intr = B_FALSE;
1243 		break;
1244 
1245 	case MBA_PORT_BYPASS_CHANGED:
1246 		EL(ha, "%xh Port Bypass Changed received, mbx1=%xh\n",
1247 		    mb[0], RD16_IO_REG(ha, mailbox[1]));
1248 		/*
1249 		 * Event generated when there is a transition on
1250 		 * port bypass of crystal+.
1251 		 * Mailbox 1:	Bit 0 - External.
1252 		 *		Bit 2 - Internal.
1253 		 * When the bit is 0, the port is bypassed.
1254 		 *
1255 		 * For now we will generate a LIP for all cases.
1256 		 */
1257 		*set_flags |= HANDLE_PORT_BYPASS_CHANGE;
1258 		break;
1259 
1260 	case MBA_RECEIVE_ERROR:
1261 		EL(ha, "%xh Receive Error received, mbx1=%xh, mbx2=%xh\n",
1262 		    mb[0], RD16_IO_REG(ha, mailbox[1]),
1263 		    RD16_IO_REG(ha, mailbox[2]));
1264 		break;
1265 
1266 	case MBA_LS_RJT_SENT:
1267 		EL(ha, "%xh LS_RJT Response Sent ELS=%xh\n", mb[0],
1268 		    RD16_IO_REG(ha, mailbox[1]));
1269 		break;
1270 
1271 	case MBA_FW_RESTART_COMP:
1272 		EL(ha, "%xh firmware restart complete received mb1=%xh\n",
1273 		    mb[0], RD16_IO_REG(ha, mailbox[1]));
1274 		break;
1275 
1276 	case MBA_IDC_COMPLETE:
1277 		EL(ha, "%xh Inter-driver communication complete received, "
1278 		    "mbx1=%xh, mbx2=%xh\n", mb[0],
1279 		    RD16_IO_REG(ha, mailbox[1]), RD16_IO_REG(ha, mailbox[2]));
1280 		break;
1281 
1282 	case MBA_IDC_NOTIFICATION:
1283 		ha->idc_mb[1] = RD16_IO_REG(ha, mailbox[1]);
1284 		ha->idc_mb[2] = RD16_IO_REG(ha, mailbox[2]);
1285 		ha->idc_mb[3] = RD16_IO_REG(ha, mailbox[3]);
1286 		ha->idc_mb[4] = RD16_IO_REG(ha, mailbox[4]);
1287 		ha->idc_mb[5] = RD16_IO_REG(ha, mailbox[5]);
1288 		ha->idc_mb[6] = RD16_IO_REG(ha, mailbox[6]);
1289 		ha->idc_mb[7] = RD16_IO_REG(ha, mailbox[7]);
1290 		EL(ha, "%xh Inter-driver communication request notification "
1291 		    "received, mbx1=%xh, mbx2=%xh, mbx3=%xh, mbx4=%xh, "
1292 		    "mbx5=%xh, mbx6=%xh, mbx7=%xh\n", mb[0], ha->idc_mb[1],
1293 		    ha->idc_mb[2], ha->idc_mb[3], ha->idc_mb[4], ha->idc_mb[5],
1294 		    ha->idc_mb[6], ha->idc_mb[7]);
1295 		*set_flags |= IDC_ACK_NEEDED;
1296 		break;
1297 
1298 	case MBA_IDC_TIME_EXTENDED:
1299 		EL(ha, "%xh Inter-driver communication time extended received,"
1300 		    " mbx1=%xh, mbx2=%xh\n", mb[0],
1301 		    RD16_IO_REG(ha, mailbox[1]), RD16_IO_REG(ha, mailbox[2]));
1302 		break;
1303 
1304 	default:
1305 		EL(ha, "%xh UNKNOWN event received, mbx1=%xh, mbx2=%xh, "
1306 		    "mbx3=%xh\n", mb[0], RD16_IO_REG(ha, mailbox[1]),
1307 		    RD16_IO_REG(ha, mailbox[2]), RD16_IO_REG(ha, mailbox[3]));
1308 		break;
1309 	}
1310 
1311 	/* Clear RISC interrupt */
1312 	if (intr && intr_clr) {
1313 		CFG_IST(ha, CFG_CTRL_242581) ?
1314 		    WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT) :
1315 		    WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT);
1316 	}
1317 
1318 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1319 }
1320 
1321 /*
1322  * ql_fast_fcp_post
1323  *	Fast path for good SCSI I/O completion.
1324  *
1325  * Input:
1326  *	sp:	SRB pointer.
1327  *
1328  * Context:
1329  *	Interrupt or Kernel context, no mailbox commands allowed.
1330  */
1331 static void
1332 ql_fast_fcp_post(ql_srb_t *sp)
1333 {
1334 	ql_adapter_state_t	*ha = sp->ha;
1335 	ql_lun_t		*lq = sp->lun_queue;
1336 	ql_tgt_t		*tq = lq->target_queue;
1337 
1338 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1339 
1340 	ASSERT(sp->flags & SRB_FCP_CMD_PKT && ha &&
1341 	    sp->pkt->pkt_reason == CS_COMPLETE);
1342 
1343 	/* Acquire device queue lock. */
1344 	DEVICE_QUEUE_LOCK(tq);
1345 
1346 	/* Decrement outstanding commands on device. */
1347 	if (tq->outcnt != 0) {
1348 		tq->outcnt--;
1349 	}
1350 
1351 	if (sp->flags & SRB_FCP_CMD_PKT) {
1352 		if (sp->fcp->fcp_cntl.cntl_qtype == FCP_QTYPE_UNTAGGED) {
1353 			/*
1354 			 * Clear the flag for this LUN so that
1355 			 * untagged commands can be submitted
1356 			 * for it.
1357 			 */
1358 			lq->flags &= ~LQF_UNTAGGED_PENDING;
1359 		}
1360 
1361 		if (lq->lun_outcnt != 0) {
1362 			lq->lun_outcnt--;
1363 		}
1364 	}
1365 
1366 	/* Reset port down retry count on good completion. */
1367 	tq->port_down_retry_count = ha->port_down_retry_count;
1368 	tq->qfull_retry_count = ha->qfull_retry_count;
1369 
1370 	/* Remove command from watchdog queue. */
1371 	if (sp->flags & SRB_WATCHDOG_ENABLED) {
1372 		ql_remove_link(&tq->wdg, &sp->wdg);
1373 		sp->flags &= ~SRB_WATCHDOG_ENABLED;
1374 	}
1375 
1376 	if (lq->cmd.first != NULL) {
1377 		ql_next(ha, lq);
1378 	} else {
1379 		/* Release LU queue specific lock. */
1380 		DEVICE_QUEUE_UNLOCK(tq);
1381 		if (ha->pha->pending_cmds.first != NULL) {
1382 			ql_start_iocb(ha, NULL);
1383 		}
1384 	}
1385 
1386 	/* Sync buffers if required.  */
1387 	if (sp->flags & SRB_MS_PKT) {
1388 		(void) ddi_dma_sync(sp->pkt->pkt_resp_dma, 0, 0,
1389 		    DDI_DMA_SYNC_FORCPU);
1390 	}
1391 
1392 	/* Map ISP completion codes. */
1393 	sp->pkt->pkt_expln = FC_EXPLN_NONE;
1394 	sp->pkt->pkt_action = FC_ACTION_RETRYABLE;
1395 	sp->pkt->pkt_state = FC_PKT_SUCCESS;
1396 
1397 	/* Now call the pkt completion callback */
1398 	if (sp->flags & SRB_POLL) {
1399 		sp->flags &= ~SRB_POLL;
1400 	} else if (sp->pkt->pkt_comp) {
1401 		INTR_UNLOCK(ha);
1402 		(*sp->pkt->pkt_comp)(sp->pkt);
1403 		INTR_LOCK(ha);
1404 	}
1405 
1406 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1407 }
1408 
1409 /*
1410  * ql_response_pkt
1411  *	Processes response entry.
1412  *
1413  * Input:
1414  *	ha:		adapter state pointer.
1415  *	done_q:		head pointer to done queue.
1416  *	set_flags:	task daemon flags to set.
1417  *	reset_flags:	task daemon flags to reset.
1418  *	intr_clr:	early interrupt clear
1419  *
1420  * Context:
1421  *	Interrupt or Kernel context, no mailbox commands allowed.
1422  */
1423 static void
1424 ql_response_pkt(ql_adapter_state_t *ha, ql_head_t *done_q, uint32_t *set_flags,
1425     uint32_t *reset_flags, int intr_clr)
1426 {
1427 	response_t	*pkt;
1428 	uint32_t	dma_sync_size_1 = 0;
1429 	uint32_t	dma_sync_size_2 = 0;
1430 	int		status = 0;
1431 
1432 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1433 
1434 	/* Clear RISC interrupt */
1435 	if (intr_clr) {
1436 		CFG_IST(ha, CFG_CTRL_242581) ?
1437 		    WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT) :
1438 		    WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT);
1439 	}
1440 
1441 	if (ha->isp_rsp_index >= RESPONSE_ENTRY_CNT) {
1442 		EL(ha, "index error = %xh, isp_abort_needed",
1443 		    ha->isp_rsp_index);
1444 		*set_flags |= ISP_ABORT_NEEDED;
1445 		return;
1446 	}
1447 
1448 	if ((ha->flags & ONLINE) == 0) {
1449 		QL_PRINT_3(CE_CONT, "(%d): not onlne, done\n", ha->instance);
1450 		return;
1451 	}
1452 
1453 	/* Calculate size of response queue entries to sync. */
1454 	if (ha->isp_rsp_index > ha->rsp_ring_index) {
1455 		dma_sync_size_1 = (uint32_t)
1456 		    ((uint32_t)(ha->isp_rsp_index - ha->rsp_ring_index) *
1457 		    RESPONSE_ENTRY_SIZE);
1458 	} else if (ha->isp_rsp_index == 0) {
1459 		dma_sync_size_1 = (uint32_t)
1460 		    ((uint32_t)(RESPONSE_ENTRY_CNT - ha->rsp_ring_index) *
1461 		    RESPONSE_ENTRY_SIZE);
1462 	} else {
1463 		/* Responses wrap around the Q */
1464 		dma_sync_size_1 = (uint32_t)
1465 		    ((uint32_t)(RESPONSE_ENTRY_CNT - ha->rsp_ring_index) *
1466 		    RESPONSE_ENTRY_SIZE);
1467 		dma_sync_size_2 = (uint32_t)
1468 		    (ha->isp_rsp_index * RESPONSE_ENTRY_SIZE);
1469 	}
1470 
1471 	/* Sync DMA buffer. */
1472 	(void) ddi_dma_sync(ha->hba_buf.dma_handle,
1473 	    (off_t)(ha->rsp_ring_index * RESPONSE_ENTRY_SIZE +
1474 	    RESPONSE_Q_BUFFER_OFFSET), dma_sync_size_1,
1475 	    DDI_DMA_SYNC_FORKERNEL);
1476 	if (dma_sync_size_2) {
1477 		(void) ddi_dma_sync(ha->hba_buf.dma_handle,
1478 		    RESPONSE_Q_BUFFER_OFFSET, dma_sync_size_2,
1479 		    DDI_DMA_SYNC_FORKERNEL);
1480 	}
1481 
1482 	while (ha->rsp_ring_index != ha->isp_rsp_index) {
1483 		pkt = ha->response_ring_ptr;
1484 
1485 		QL_PRINT_5(CE_CONT, "(%d): ha->rsp_rg_idx=%xh, mbx[5]=%xh\n",
1486 		    ha->instance, ha->rsp_ring_index, ha->isp_rsp_index);
1487 		QL_DUMP_5((uint8_t *)ha->response_ring_ptr, 8,
1488 		    RESPONSE_ENTRY_SIZE);
1489 
1490 		/* Adjust ring index. */
1491 		ha->rsp_ring_index++;
1492 		if (ha->rsp_ring_index == RESPONSE_ENTRY_CNT) {
1493 			ha->rsp_ring_index = 0;
1494 			ha->response_ring_ptr = ha->response_ring_bp;
1495 		} else {
1496 			ha->response_ring_ptr++;
1497 		}
1498 
1499 		/* Process packet. */
1500 		if (ha->status_srb != NULL && pkt->entry_type !=
1501 		    STATUS_CONT_TYPE) {
1502 			ql_add_link_b(done_q, &ha->status_srb->cmd);
1503 			ha->status_srb = NULL;
1504 		}
1505 
1506 		pkt->entry_status = (uint8_t)(CFG_IST(ha, CFG_CTRL_242581) ?
1507 		    pkt->entry_status & 0x3c : pkt->entry_status & 0x7e);
1508 
1509 		if (pkt->entry_status != 0) {
1510 			ql_error_entry(ha, pkt, done_q, set_flags,
1511 			    reset_flags);
1512 		} else {
1513 			switch (pkt->entry_type) {
1514 			case STATUS_TYPE:
1515 				status |= CFG_IST(ha, CFG_CTRL_242581) ?
1516 				    ql_24xx_status_entry(ha,
1517 				    (sts_24xx_entry_t *)pkt, done_q, set_flags,
1518 				    reset_flags) :
1519 				    ql_status_entry(ha, (sts_entry_t *)pkt,
1520 				    done_q, set_flags, reset_flags);
1521 				break;
1522 			case STATUS_CONT_TYPE:
1523 				ql_status_cont_entry(ha,
1524 				    (sts_cont_entry_t *)pkt, done_q, set_flags,
1525 				    reset_flags);
1526 				break;
1527 			case IP_TYPE:
1528 			case IP_A64_TYPE:
1529 			case IP_CMD_TYPE:
1530 				ql_ip_entry(ha, (ip_entry_t *)pkt, done_q,
1531 				    set_flags, reset_flags);
1532 				break;
1533 			case IP_RECEIVE_TYPE:
1534 				ql_ip_rcv_entry(ha,
1535 				    (ip_rcv_entry_t *)pkt, done_q, set_flags,
1536 				    reset_flags);
1537 				break;
1538 			case IP_RECEIVE_CONT_TYPE:
1539 				ql_ip_rcv_cont_entry(ha,
1540 				    (ip_rcv_cont_entry_t *)pkt,	done_q,
1541 				    set_flags, reset_flags);
1542 				break;
1543 			case IP_24XX_RECEIVE_TYPE:
1544 				ql_ip_24xx_rcv_entry(ha,
1545 				    (ip_rcv_24xx_entry_t *)pkt, done_q,
1546 				    set_flags, reset_flags);
1547 				break;
1548 			case MS_TYPE:
1549 				ql_ms_entry(ha, (ms_entry_t *)pkt, done_q,
1550 				    set_flags, reset_flags);
1551 				break;
1552 			case REPORT_ID_TYPE:
1553 				ql_report_id_entry(ha, (report_id_1_t *)pkt,
1554 				    done_q, set_flags, reset_flags);
1555 				break;
1556 			case ELS_PASSTHRU_TYPE:
1557 				ql_els_passthru_entry(ha,
1558 				    (els_passthru_entry_rsp_t *)pkt,
1559 				    done_q, set_flags, reset_flags);
1560 				break;
1561 			case IP_BUF_POOL_TYPE:
1562 			case MARKER_TYPE:
1563 			case VP_MODIFY_TYPE:
1564 			case VP_CONTROL_TYPE:
1565 				break;
1566 			default:
1567 				EL(ha, "Unknown IOCB entry type=%xh\n",
1568 				    pkt->entry_type);
1569 				break;
1570 			}
1571 		}
1572 	}
1573 
1574 	/* Inform RISC of processed responses. */
1575 	WRT16_IO_REG(ha, resp_out, ha->rsp_ring_index);
1576 
1577 	/* RESET packet received delay for possible async event. */
1578 	if (status & BIT_0) {
1579 		drv_usecwait(500000);
1580 	}
1581 
1582 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1583 }
1584 
1585 /*
1586  * ql_error_entry
1587  *	Processes error entry.
1588  *
1589  * Input:
1590  *	ha = adapter state pointer.
1591  *	pkt = entry pointer.
1592  *	done_q = head pointer to done queue.
1593  *	set_flags = task daemon flags to set.
1594  *	reset_flags = task daemon flags to reset.
1595  *
1596  * Context:
1597  *	Interrupt or Kernel context, no mailbox commands allowed.
1598  */
1599 /* ARGSUSED */
1600 static void
1601 ql_error_entry(ql_adapter_state_t *ha, response_t *pkt, ql_head_t *done_q,
1602     uint32_t *set_flags, uint32_t *reset_flags)
1603 {
1604 	ql_srb_t	*sp;
1605 	uint32_t	index, cnt;
1606 
1607 	if (pkt->entry_type == INVALID_ENTRY_TYPE) {
1608 		EL(ha, "Aborted command\n");
1609 		return;
1610 	}
1611 
1612 	QL_PRINT_2(CE_CONT, "(%d): started, packet:\n", ha->instance);
1613 	QL_DUMP_2((uint8_t *)pkt, 8, RESPONSE_ENTRY_SIZE);
1614 
1615 	if (pkt->entry_status & BIT_6) {
1616 		EL(ha, "Request Queue DMA error\n");
1617 	} else if (pkt->entry_status & BIT_5) {
1618 		EL(ha, "Invalid Entry Order\n");
1619 	} else if (pkt->entry_status & BIT_4) {
1620 		EL(ha, "Invalid Entry Count\n");
1621 	} else if (pkt->entry_status & BIT_3) {
1622 		EL(ha, "Invalid Entry Parameter\n");
1623 	} else if (pkt->entry_status & BIT_2) {
1624 		EL(ha, "Invalid Entry Type\n");
1625 	} else if (pkt->entry_status & BIT_1) {
1626 		EL(ha, "Busy\n");
1627 	} else {
1628 		EL(ha, "UNKNOWN flag = %xh error\n", pkt->entry_status);
1629 	}
1630 
1631 	/* Get handle. */
1632 	cnt = ddi_get32(ha->hba_buf.acc_handle, &pkt->handle);
1633 	index = cnt & OSC_INDEX_MASK;
1634 
1635 	/* Validate handle. */
1636 	sp = index < MAX_OUTSTANDING_COMMANDS ? ha->outstanding_cmds[index] :
1637 	    NULL;
1638 
1639 	if (sp != NULL && sp->handle == cnt) {
1640 		ha->outstanding_cmds[index] = NULL;
1641 		sp->handle = 0;
1642 		sp->flags &= ~SRB_IN_TOKEN_ARRAY;
1643 
1644 		/* Bad payload or header */
1645 		if (pkt->entry_status & (BIT_5 + BIT_4 + BIT_3 + BIT_2)) {
1646 			/* Bad payload or header, set error status. */
1647 			sp->pkt->pkt_reason = CS_BAD_PAYLOAD;
1648 		} else if (pkt->entry_status & BIT_1) /* FULL flag */ {
1649 			sp->pkt->pkt_reason = CS_QUEUE_FULL;
1650 		} else {
1651 			/* Set error status. */
1652 			sp->pkt->pkt_reason = CS_UNKNOWN;
1653 		}
1654 
1655 		/* Set completed status. */
1656 		sp->flags |= SRB_ISP_COMPLETED;
1657 
1658 		/* Place command on done queue. */
1659 		ql_add_link_b(done_q, &sp->cmd);
1660 
1661 	} else {
1662 		if (sp == NULL) {
1663 			EL(ha, "unknown IOCB handle=%xh\n", cnt);
1664 		} else {
1665 			EL(ha, "mismatch IOCB handle pkt=%xh, sp=%xh\n",
1666 			    cnt, sp->handle);
1667 		}
1668 
1669 		(void) ql_binary_fw_dump(ha, FALSE);
1670 
1671 		if (!(ha->task_daemon_flags & (ISP_ABORT_NEEDED |
1672 		    ABORT_ISP_ACTIVE))) {
1673 			EL(ha, "ISP Invalid handle, isp_abort_needed\n");
1674 			*set_flags |= ISP_ABORT_NEEDED;
1675 		}
1676 	}
1677 
1678 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1679 }
1680 
1681 /*
1682  * ql_status_entry
1683  *	Processes received ISP2200-2300 status entry.
1684  *
1685  * Input:
1686  *	ha:		adapter state pointer.
1687  *	pkt:		entry pointer.
1688  *	done_q:		done queue pointer.
1689  *	set_flags:	task daemon flags to set.
1690  *	reset_flags:	task daemon flags to reset.
1691  *
1692  * Returns:
1693  *	BIT_0 = CS_RESET status received.
1694  *
1695  * Context:
1696  *	Interrupt or Kernel context, no mailbox commands allowed.
1697  */
1698 /* ARGSUSED */
1699 static int
1700 ql_status_entry(ql_adapter_state_t *ha, sts_entry_t *pkt,
1701     ql_head_t *done_q, uint32_t *set_flags, uint32_t *reset_flags)
1702 {
1703 	ql_srb_t		*sp;
1704 	uint32_t		index, cnt;
1705 	uint16_t		comp_status;
1706 	int			rval = 0;
1707 
1708 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1709 
1710 	/* Get handle. */
1711 	cnt = ddi_get32(ha->hba_buf.acc_handle, &pkt->handle);
1712 	index = cnt & OSC_INDEX_MASK;
1713 
1714 	/* Validate handle. */
1715 	sp = index < MAX_OUTSTANDING_COMMANDS ? ha->outstanding_cmds[index] :
1716 	    NULL;
1717 
1718 	if (sp != NULL && sp->handle == cnt) {
1719 		comp_status = (uint16_t)ddi_get16(ha->hba_buf.acc_handle,
1720 		    &pkt->comp_status);
1721 
1722 		/*
1723 		 * We dont care about SCSI QFULLs.
1724 		 */
1725 		if (comp_status == CS_QUEUE_FULL) {
1726 			EL(ha, "CS_QUEUE_FULL, d_id=%xh, lun=%xh\n",
1727 			    sp->lun_queue->target_queue->d_id.b24,
1728 			    sp->lun_queue->lun_no);
1729 			comp_status = CS_COMPLETE;
1730 		}
1731 
1732 		/*
1733 		 * 2300 firmware marks completion status as data underrun
1734 		 * for scsi qfulls. Make it transport complete.
1735 		 */
1736 		if ((CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) &&
1737 		    (comp_status == CS_DATA_UNDERRUN) &&
1738 		    (pkt->scsi_status_l != 0)) {
1739 			comp_status = CS_COMPLETE;
1740 		}
1741 
1742 		/*
1743 		 * Workaround T3 issue where we do not get any data xferred
1744 		 * but get back a good status.
1745 		 */
1746 		if ((pkt->state_flags_h & SF_XFERRED_DATA) == 0 &&
1747 		    comp_status == CS_COMPLETE &&
1748 		    pkt->scsi_status_l == 0 &&
1749 		    (pkt->scsi_status_h & FCP_RSP_MASK) == 0 &&
1750 		    pkt->residual_length == 0 &&
1751 		    sp->fcp &&
1752 		    sp->fcp->fcp_data_len != 0 &&
1753 		    (pkt->state_flags_l & (SF_DATA_OUT | SF_DATA_IN)) ==
1754 		    SF_DATA_OUT) {
1755 			comp_status = CS_ABORTED;
1756 		}
1757 
1758 		if (sp->flags & SRB_MS_PKT) {
1759 			/*
1760 			 * Ideally it should never be true. But there
1761 			 * is a bug in FW which upon receiving invalid
1762 			 * parameters in MS IOCB returns it as
1763 			 * status entry and not as ms entry type.
1764 			 */
1765 			ql_ms_entry(ha, (ms_entry_t *)pkt, done_q,
1766 			    set_flags, reset_flags);
1767 			QL_PRINT_3(CE_CONT, "(%d): ql_ms_entry done\n",
1768 			    ha->instance);
1769 			return (0);
1770 		}
1771 
1772 		ha->outstanding_cmds[index] = NULL;
1773 		sp->handle = 0;
1774 		sp->flags &= ~SRB_IN_TOKEN_ARRAY;
1775 
1776 		/*
1777 		 * Fast path to good SCSI I/O completion
1778 		 */
1779 		if ((comp_status == CS_COMPLETE) &
1780 		    (!pkt->scsi_status_l) &
1781 		    (!(pkt->scsi_status_h & FCP_RSP_MASK))) {
1782 			/* Set completed status. */
1783 			sp->flags |= SRB_ISP_COMPLETED;
1784 			sp->pkt->pkt_reason = comp_status;
1785 			ql_fast_fcp_post(sp);
1786 			QL_PRINT_3(CE_CONT, "(%d): ql_fast_fcp_post done\n",
1787 			    ha->instance);
1788 			return (0);
1789 		}
1790 		rval = ql_status_error(ha, sp, pkt, done_q, set_flags,
1791 		    reset_flags);
1792 	} else {
1793 		if (sp == NULL) {
1794 			EL(ha, "unknown IOCB handle=%xh\n", cnt);
1795 		} else {
1796 			EL(ha, "mismatch IOCB handle pkt=%xh, sp=%xh\n",
1797 			    cnt, sp->handle);
1798 		}
1799 
1800 		(void) ql_binary_fw_dump(ha, FALSE);
1801 
1802 		if (!(ha->task_daemon_flags & (ISP_ABORT_NEEDED |
1803 		    ABORT_ISP_ACTIVE))) {
1804 			EL(ha, "ISP Invalid handle, isp_abort_needed\n");
1805 			*set_flags |= ISP_ABORT_NEEDED;
1806 		}
1807 	}
1808 
1809 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1810 
1811 	return (rval);
1812 }
1813 
1814 /*
1815  * ql_24xx_status_entry
1816  *	Processes received ISP24xx status entry.
1817  *
1818  * Input:
1819  *	ha:		adapter state pointer.
1820  *	pkt:		entry pointer.
1821  *	done_q:		done queue pointer.
1822  *	set_flags:	task daemon flags to set.
1823  *	reset_flags:	task daemon flags to reset.
1824  *
1825  * Returns:
1826  *	BIT_0 = CS_RESET status received.
1827  *
1828  * Context:
1829  *	Interrupt or Kernel context, no mailbox commands allowed.
1830  */
1831 /* ARGSUSED */
1832 static int
1833 ql_24xx_status_entry(ql_adapter_state_t *ha, sts_24xx_entry_t *pkt,
1834     ql_head_t *done_q, uint32_t *set_flags, uint32_t *reset_flags)
1835 {
1836 	ql_srb_t		*sp;
1837 	uint32_t		index;
1838 	uint32_t		resp_identifier;
1839 	uint16_t		comp_status;
1840 	int			rval = 0;
1841 
1842 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1843 
1844 	/* Get the response identifier. */
1845 	resp_identifier = ddi_get32(ha->hba_buf.acc_handle, &pkt->handle);
1846 
1847 	/* extract the outstanding cmds index */
1848 	index = resp_identifier & OSC_INDEX_MASK;
1849 
1850 	/* Validate the index and get the associated srb pointer */
1851 	sp = index < MAX_OUTSTANDING_COMMANDS ? ha->outstanding_cmds[index] :
1852 	    NULL;
1853 
1854 	if (sp != NULL && sp->handle == resp_identifier) {
1855 		comp_status = (uint16_t)ddi_get16(ha->hba_buf.acc_handle,
1856 		    &pkt->comp_status);
1857 
1858 		/*
1859 		 * We dont care about SCSI QFULLs.
1860 		 */
1861 		if (comp_status == CS_QUEUE_FULL) {
1862 			EL(sp->ha, "CS_QUEUE_FULL, d_id=%xh, lun=%xh\n",
1863 			    sp->lun_queue->target_queue->d_id.b24,
1864 			    sp->lun_queue->lun_no);
1865 			comp_status = CS_COMPLETE;
1866 		}
1867 
1868 		/*
1869 		 * 2300 firmware marks completion status as data underrun
1870 		 * for scsi qfulls. Make it transport complete.
1871 		 */
1872 		if ((comp_status == CS_DATA_UNDERRUN) &&
1873 		    (pkt->scsi_status_l != 0)) {
1874 			comp_status = CS_COMPLETE;
1875 		}
1876 
1877 		/*
1878 		 * Workaround T3 issue where we do not get any data xferred
1879 		 * but get back a good status.
1880 		 */
1881 		if (comp_status == CS_COMPLETE &&
1882 		    pkt->scsi_status_l == 0 &&
1883 		    (pkt->scsi_status_h & FCP_RSP_MASK) == 0 &&
1884 		    pkt->residual_length != 0 &&
1885 		    sp->fcp &&
1886 		    sp->fcp->fcp_data_len != 0 &&
1887 		    sp->fcp->fcp_cntl.cntl_write_data) {
1888 			comp_status = CS_ABORTED;
1889 		}
1890 
1891 		if (sp->flags & SRB_MS_PKT) {
1892 			/*
1893 			 * Ideally it should never be true. But there
1894 			 * is a bug in FW which upon receiving invalid
1895 			 * parameters in MS IOCB returns it as
1896 			 * status entry and not as ms entry type.
1897 			 */
1898 			ql_ms_entry(ha, (ms_entry_t *)pkt, done_q,
1899 			    set_flags, reset_flags);
1900 			QL_PRINT_3(CE_CONT, "(%d): ql_ms_entry done\n",
1901 			    ha->instance);
1902 			return (0);
1903 		}
1904 
1905 		ha->outstanding_cmds[index] = NULL;
1906 		sp->handle = 0;
1907 		sp->flags &= ~SRB_IN_TOKEN_ARRAY;
1908 
1909 		/*
1910 		 * Fast path to good SCSI I/O completion
1911 		 */
1912 		if ((comp_status == CS_COMPLETE) &
1913 		    (!pkt->scsi_status_l) &
1914 		    (!(pkt->scsi_status_h & FCP_RSP_MASK))) {
1915 			/* Set completed status. */
1916 			sp->flags |= SRB_ISP_COMPLETED;
1917 			sp->pkt->pkt_reason = comp_status;
1918 			ql_fast_fcp_post(sp);
1919 			QL_PRINT_3(CE_CONT, "(%d): ql_fast_fcp_post done\n",
1920 			    ha->instance);
1921 			return (0);
1922 		}
1923 		rval = ql_status_error(ha, sp, (sts_entry_t *)pkt, done_q,
1924 		    set_flags, reset_flags);
1925 	} else {
1926 		if (sp == NULL) {
1927 			EL(ha, "unknown IOCB handle=%xh\n", resp_identifier);
1928 		} else {
1929 			EL(sp->ha, "mismatch IOCB handle pkt=%xh, sp=%xh\n",
1930 			    resp_identifier, sp->handle);
1931 		}
1932 
1933 		(void) ql_binary_fw_dump(ha, FALSE);
1934 
1935 		if (!(ha->task_daemon_flags & (ISP_ABORT_NEEDED |
1936 		    ABORT_ISP_ACTIVE))) {
1937 			EL(ha, "ISP Invalid handle, isp_abort_needed\n");
1938 			*set_flags |= ISP_ABORT_NEEDED;
1939 		}
1940 	}
1941 
1942 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1943 
1944 	return (rval);
1945 }
1946 
1947 /*
1948  * ql_status_error
1949  *	Processes received ISP status entry error.
1950  *
1951  * Input:
1952  *	ha:		adapter state pointer.
1953  *	sp:		SRB pointer.
1954  *	pkt:		entry pointer.
1955  *	done_q:		done queue pointer.
1956  *	set_flags:	task daemon flags to set.
1957  *	reset_flags:	task daemon flags to reset.
1958  *
1959  * Returns:
1960  *	BIT_0 = CS_RESET status received.
1961  *
1962  * Context:
1963  *	Interrupt or Kernel context, no mailbox commands allowed.
1964  */
1965 /* ARGSUSED */
1966 static int
1967 ql_status_error(ql_adapter_state_t *ha, ql_srb_t *sp, sts_entry_t *pkt23,
1968     ql_head_t *done_q, uint32_t *set_flags, uint32_t *reset_flags)
1969 {
1970 	uint32_t		sense_sz = 0;
1971 	uint32_t		cnt;
1972 	ql_tgt_t		*tq;
1973 	fcp_rsp_t		*fcpr;
1974 	struct fcp_rsp_info	*rsp;
1975 	int			rval = 0;
1976 
1977 	struct {
1978 		uint8_t		*rsp_info;
1979 		uint8_t		*req_sense_data;
1980 		uint32_t	residual_length;
1981 		uint32_t	fcp_residual_length;
1982 		uint32_t	rsp_info_length;
1983 		uint32_t	req_sense_length;
1984 		uint16_t	comp_status;
1985 		uint8_t		state_flags_l;
1986 		uint8_t		state_flags_h;
1987 		uint8_t		scsi_status_l;
1988 		uint8_t		scsi_status_h;
1989 	} sts;
1990 
1991 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1992 
1993 	if (CFG_IST(ha, CFG_CTRL_242581)) {
1994 		sts_24xx_entry_t *pkt24 = (sts_24xx_entry_t *)pkt23;
1995 
1996 		/* Setup status. */
1997 		sts.comp_status = (uint16_t)ddi_get16(ha->hba_buf.acc_handle,
1998 		    &pkt24->comp_status);
1999 		sts.scsi_status_l = pkt24->scsi_status_l;
2000 		sts.scsi_status_h = pkt24->scsi_status_h;
2001 
2002 		/* Setup firmware residuals. */
2003 		sts.residual_length = sts.comp_status == CS_DATA_UNDERRUN ?
2004 		    ddi_get32(ha->hba_buf.acc_handle,
2005 		    (uint32_t *)&pkt24->residual_length) : 0;
2006 
2007 		/* Setup FCP residuals. */
2008 		sts.fcp_residual_length = sts.scsi_status_h &
2009 		    (FCP_RESID_UNDER | FCP_RESID_OVER) ?
2010 		    ddi_get32(ha->hba_buf.acc_handle,
2011 		    (uint32_t *)&pkt24->fcp_rsp_residual_count) : 0;
2012 
2013 		if ((sts.comp_status == CS_DATA_UNDERRUN) &&
2014 		    (sts.scsi_status_h & FCP_RESID_UNDER) &&
2015 		    (sts.residual_length != pkt24->fcp_rsp_residual_count)) {
2016 
2017 			EL(sp->ha, "mismatch resid's: fw=%xh, pkt=%xh\n",
2018 			    sts.residual_length,
2019 			    pkt24->fcp_rsp_residual_count);
2020 			sts.scsi_status_h = (uint8_t)
2021 			    (sts.scsi_status_h & ~FCP_RESID_UNDER);
2022 		}
2023 
2024 		/* Setup state flags. */
2025 		sts.state_flags_l = pkt24->state_flags_l;
2026 		sts.state_flags_h = pkt24->state_flags_h;
2027 
2028 		if (sp->fcp->fcp_data_len &&
2029 		    (sts.comp_status != CS_DATA_UNDERRUN ||
2030 		    sts.residual_length != sp->fcp->fcp_data_len)) {
2031 			sts.state_flags_h = (uint8_t)
2032 			    (sts.state_flags_h | SF_GOT_BUS |
2033 			    SF_GOT_TARGET | SF_SENT_CMD |
2034 			    SF_XFERRED_DATA | SF_GOT_STATUS);
2035 		} else {
2036 			sts.state_flags_h = (uint8_t)
2037 			    (sts.state_flags_h | SF_GOT_BUS |
2038 			    SF_GOT_TARGET | SF_SENT_CMD |
2039 			    SF_GOT_STATUS);
2040 		}
2041 		if (sp->fcp->fcp_cntl.cntl_write_data) {
2042 			sts.state_flags_l = (uint8_t)
2043 			    (sts.state_flags_l | SF_DATA_OUT);
2044 		} else if (sp->fcp->fcp_cntl.cntl_read_data) {
2045 			sts.state_flags_l = (uint8_t)
2046 			    (sts.state_flags_l | SF_DATA_IN);
2047 		}
2048 		if (sp->fcp->fcp_cntl.cntl_qtype == FCP_QTYPE_HEAD_OF_Q) {
2049 			sts.state_flags_l = (uint8_t)
2050 			    (sts.state_flags_l | SF_HEAD_OF_Q);
2051 		} else if (sp->fcp->fcp_cntl.cntl_qtype == FCP_QTYPE_ORDERED) {
2052 			sts.state_flags_l = (uint8_t)
2053 			    (sts.state_flags_l | SF_ORDERED_Q);
2054 		} else if (sp->fcp->fcp_cntl.cntl_qtype == FCP_QTYPE_SIMPLE) {
2055 			sts.state_flags_l = (uint8_t)
2056 			    (sts.state_flags_l | SF_SIMPLE_Q);
2057 		}
2058 
2059 		/* Setup FCP response info. */
2060 		sts.rsp_info = &pkt24->rsp_sense_data[0];
2061 		if ((sts.scsi_status_h & FCP_RSP_LEN_VALID) != 0) {
2062 			sts.rsp_info_length = ddi_get32(ha->hba_buf.acc_handle,
2063 			    (uint32_t *)&pkt24->fcp_rsp_data_length);
2064 			if (sts.rsp_info_length >
2065 			    sizeof (struct fcp_rsp_info)) {
2066 				sts.rsp_info_length =
2067 				    sizeof (struct fcp_rsp_info);
2068 			}
2069 			for (cnt = 0; cnt < sts.rsp_info_length; cnt += 4) {
2070 				ql_chg_endian(sts.rsp_info + cnt, 4);
2071 			}
2072 		} else {
2073 			sts.rsp_info_length = 0;
2074 		}
2075 
2076 		/* Setup sense data. */
2077 		sts.req_sense_data =
2078 		    &pkt24->rsp_sense_data[sts.rsp_info_length];
2079 		if (sts.scsi_status_h & FCP_SNS_LEN_VALID) {
2080 			sts.req_sense_length =
2081 			    ddi_get32(ha->hba_buf.acc_handle,
2082 			    (uint32_t *)&pkt24->fcp_sense_length);
2083 			sts.state_flags_h = (uint8_t)
2084 			    (sts.state_flags_h | SF_ARQ_DONE);
2085 			sense_sz = (uint32_t)
2086 			    (((uintptr_t)pkt24 + sizeof (sts_24xx_entry_t)) -
2087 			    (uintptr_t)sts.req_sense_data);
2088 			for (cnt = 0; cnt < sense_sz; cnt += 4) {
2089 				ql_chg_endian(sts.req_sense_data + cnt, 4);
2090 			}
2091 		} else {
2092 			sts.req_sense_length = 0;
2093 		}
2094 	} else {
2095 		/* Setup status. */
2096 		sts.comp_status = (uint16_t)ddi_get16(
2097 		    ha->hba_buf.acc_handle, &pkt23->comp_status);
2098 		sts.scsi_status_l = pkt23->scsi_status_l;
2099 		sts.scsi_status_h = pkt23->scsi_status_h;
2100 
2101 		/* Setup firmware residuals. */
2102 		sts.residual_length = sts.comp_status == CS_DATA_UNDERRUN ?
2103 		    ddi_get32(ha->hba_buf.acc_handle,
2104 		    (uint32_t *)&pkt23->residual_length) : 0;
2105 
2106 		/* Setup FCP residuals. */
2107 		sts.fcp_residual_length = sts.scsi_status_h &
2108 		    (FCP_RESID_UNDER | FCP_RESID_OVER) ?
2109 		    sts.residual_length : 0;
2110 
2111 		/* Setup state flags. */
2112 		sts.state_flags_l = pkt23->state_flags_l;
2113 		sts.state_flags_h = pkt23->state_flags_h;
2114 
2115 		/* Setup FCP response info. */
2116 		sts.rsp_info = &pkt23->rsp_info[0];
2117 		if ((sts.scsi_status_h & FCP_RSP_LEN_VALID) != 0) {
2118 			sts.rsp_info_length = ddi_get16(
2119 			    ha->hba_buf.acc_handle,
2120 			    (uint16_t *)&pkt23->rsp_info_length);
2121 			if (sts.rsp_info_length >
2122 			    sizeof (struct fcp_rsp_info)) {
2123 				sts.rsp_info_length =
2124 				    sizeof (struct fcp_rsp_info);
2125 			}
2126 		} else {
2127 			sts.rsp_info_length = 0;
2128 		}
2129 
2130 		/* Setup sense data. */
2131 		sts.req_sense_data = &pkt23->req_sense_data[0];
2132 		sts.req_sense_length = sts.scsi_status_h & FCP_SNS_LEN_VALID ?
2133 		    ddi_get16(ha->hba_buf.acc_handle,
2134 		    (uint16_t *)&pkt23->req_sense_length) : 0;
2135 	}
2136 
2137 	bzero(sp->pkt->pkt_resp, sp->pkt->pkt_rsplen);
2138 
2139 	fcpr = (fcp_rsp_t *)sp->pkt->pkt_resp;
2140 	rsp = (struct fcp_rsp_info *)(sp->pkt->pkt_resp +
2141 	    sizeof (fcp_rsp_t));
2142 
2143 	tq = sp->lun_queue->target_queue;
2144 
2145 	fcpr->fcp_u.fcp_status.scsi_status = sts.scsi_status_l;
2146 	if (sts.scsi_status_h & FCP_RSP_LEN_VALID) {
2147 		fcpr->fcp_u.fcp_status.rsp_len_set = 1;
2148 	}
2149 	if (sts.scsi_status_h & FCP_SNS_LEN_VALID) {
2150 		fcpr->fcp_u.fcp_status.sense_len_set = 1;
2151 	}
2152 	if (sts.scsi_status_h & FCP_RESID_OVER) {
2153 		fcpr->fcp_u.fcp_status.resid_over = 1;
2154 	}
2155 	if (sts.scsi_status_h & FCP_RESID_UNDER) {
2156 		fcpr->fcp_u.fcp_status.resid_under = 1;
2157 	}
2158 	fcpr->fcp_u.fcp_status.reserved_1 = 0;
2159 
2160 	/* Set ISP completion status */
2161 	sp->pkt->pkt_reason = sts.comp_status;
2162 
2163 	/* Update statistics. */
2164 	if ((sts.scsi_status_h & FCP_RSP_LEN_VALID) &&
2165 	    (sp->pkt->pkt_rsplen > sizeof (fcp_rsp_t))) {
2166 
2167 		sense_sz = sp->pkt->pkt_rsplen - (uint32_t)sizeof (fcp_rsp_t);
2168 		if (sense_sz > sts.rsp_info_length) {
2169 			sense_sz = sts.rsp_info_length;
2170 		}
2171 
2172 		/* copy response information data. */
2173 		if (sense_sz) {
2174 			ddi_rep_get8(ha->hba_buf.acc_handle, (uint8_t *)rsp,
2175 			    sts.rsp_info, sense_sz, DDI_DEV_AUTOINCR);
2176 		}
2177 		fcpr->fcp_response_len = sense_sz;
2178 
2179 		rsp = (struct fcp_rsp_info *)((caddr_t)rsp +
2180 		    fcpr->fcp_response_len);
2181 
2182 		switch (*(sts.rsp_info + 3)) {
2183 		case FCP_NO_FAILURE:
2184 			break;
2185 		case FCP_DL_LEN_MISMATCH:
2186 			ha->adapter_stats->d_stats[lobyte(
2187 			    tq->loop_id)].dl_len_mismatches++;
2188 			break;
2189 		case FCP_CMND_INVALID:
2190 			break;
2191 		case FCP_DATA_RO_MISMATCH:
2192 			ha->adapter_stats->d_stats[lobyte(
2193 			    tq->loop_id)].data_ro_mismatches++;
2194 			break;
2195 		case FCP_TASK_MGMT_NOT_SUPPTD:
2196 			break;
2197 		case FCP_TASK_MGMT_FAILED:
2198 			ha->adapter_stats->d_stats[lobyte(
2199 			    tq->loop_id)].task_mgmt_failures++;
2200 			break;
2201 		default:
2202 			break;
2203 		}
2204 	} else {
2205 		/*
2206 		 * EL(sp->ha, "scsi_h=%xh, pkt_rsplen=%xh\n",
2207 		 *   sts.scsi_status_h, sp->pkt->pkt_rsplen);
2208 		 */
2209 		fcpr->fcp_response_len = 0;
2210 	}
2211 
2212 	/* Set reset status received. */
2213 	if (sts.comp_status == CS_RESET && LOOP_READY(ha)) {
2214 		rval |= BIT_0;
2215 	}
2216 
2217 	if (!(tq->flags & TQF_TAPE_DEVICE) &&
2218 	    (!(CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING)) ||
2219 	    ha->loop_down_abort_time < LOOP_DOWN_TIMER_START) &&
2220 	    ha->task_daemon_flags & LOOP_DOWN) {
2221 		EL(sp->ha, "Loop Not Ready Retry, d_id=%xh, lun=%xh\n",
2222 		    tq->d_id.b24, sp->lun_queue->lun_no);
2223 
2224 		/* Set retry status. */
2225 		sp->flags |= SRB_RETRY;
2226 	} else if (!(tq->flags & TQF_TAPE_DEVICE) &&
2227 	    tq->port_down_retry_count != 0 &&
2228 	    (sts.comp_status == CS_INCOMPLETE ||
2229 	    sts.comp_status == CS_PORT_UNAVAILABLE ||
2230 	    sts.comp_status == CS_PORT_LOGGED_OUT ||
2231 	    sts.comp_status == CS_PORT_CONFIG_CHG ||
2232 	    sts.comp_status == CS_PORT_BUSY)) {
2233 		EL(sp->ha, "Port Down Retry=%xh, d_id=%xh, lun=%xh, count=%d"
2234 		    "\n", sts.comp_status, tq->d_id.b24, sp->lun_queue->lun_no,
2235 		    tq->port_down_retry_count);
2236 
2237 		/* Set retry status. */
2238 		sp->flags |= SRB_RETRY;
2239 
2240 		if ((tq->flags & TQF_QUEUE_SUSPENDED) == 0) {
2241 			/* Acquire device queue lock. */
2242 			DEVICE_QUEUE_LOCK(tq);
2243 
2244 			tq->flags |= TQF_QUEUE_SUSPENDED;
2245 
2246 			/* Decrement port down count. */
2247 			if (CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING)) {
2248 				tq->port_down_retry_count--;
2249 			}
2250 
2251 			DEVICE_QUEUE_UNLOCK(tq);
2252 
2253 			if ((ha->task_daemon_flags & ABORT_ISP_ACTIVE)
2254 			    == 0 &&
2255 			    (sts.comp_status == CS_PORT_LOGGED_OUT ||
2256 			    sts.comp_status == CS_PORT_UNAVAILABLE)) {
2257 				sp->ha->adapter_stats->d_stats[lobyte(
2258 				    tq->loop_id)].logouts_recvd++;
2259 				ql_send_logo(sp->ha, tq, done_q);
2260 			}
2261 
2262 			ADAPTER_STATE_LOCK(ha);
2263 			if (ha->port_retry_timer == 0) {
2264 				if ((ha->port_retry_timer =
2265 				    ha->port_down_retry_delay) == 0) {
2266 					*set_flags |=
2267 					    PORT_RETRY_NEEDED;
2268 				}
2269 			}
2270 			ADAPTER_STATE_UNLOCK(ha);
2271 		}
2272 	} else if (!(tq->flags & TQF_TAPE_DEVICE) &&
2273 	    (sts.comp_status == CS_RESET ||
2274 	    (sts.comp_status == CS_QUEUE_FULL && tq->qfull_retry_count != 0) ||
2275 	    (sts.comp_status == CS_ABORTED && !(sp->flags & SRB_ABORTING)))) {
2276 		if (sts.comp_status == CS_RESET) {
2277 			EL(sp->ha, "Reset Retry, d_id=%xh, lun=%xh\n",
2278 			    tq->d_id.b24, sp->lun_queue->lun_no);
2279 		} else if (sts.comp_status == CS_QUEUE_FULL) {
2280 			EL(sp->ha, "Queue Full Retry, d_id=%xh, lun=%xh, "
2281 			    "cnt=%d\n", tq->d_id.b24, sp->lun_queue->lun_no,
2282 			    tq->qfull_retry_count);
2283 			if ((tq->flags & TQF_QUEUE_SUSPENDED) == 0) {
2284 				tq->flags |= TQF_QUEUE_SUSPENDED;
2285 
2286 				tq->qfull_retry_count--;
2287 
2288 				ADAPTER_STATE_LOCK(ha);
2289 				if (ha->port_retry_timer == 0) {
2290 					if ((ha->port_retry_timer =
2291 					    ha->qfull_retry_delay) ==
2292 					    0) {
2293 						*set_flags |=
2294 						    PORT_RETRY_NEEDED;
2295 					}
2296 				}
2297 				ADAPTER_STATE_UNLOCK(ha);
2298 			}
2299 		} else {
2300 			EL(sp->ha, "Abort Retry, d_id=%xh, lun=%xh\n",
2301 			    tq->d_id.b24, sp->lun_queue->lun_no);
2302 		}
2303 
2304 		/* Set retry status. */
2305 		sp->flags |= SRB_RETRY;
2306 	} else {
2307 		fcpr->fcp_resid =
2308 		    sts.fcp_residual_length > sp->fcp->fcp_data_len ?
2309 		    sp->fcp->fcp_data_len : sts.fcp_residual_length;
2310 
2311 		if ((sts.comp_status == CS_DATA_UNDERRUN) &&
2312 		    (sts.scsi_status_h & FCP_RESID_UNDER) == 0) {
2313 
2314 			if (sts.scsi_status_l == STATUS_CHECK) {
2315 				sp->pkt->pkt_reason = CS_COMPLETE;
2316 			} else {
2317 				EL(ha, "transport error - "
2318 				    "underrun & invalid resid\n");
2319 				EL(ha, "ssh=%xh, ssl=%xh\n",
2320 				    sts.scsi_status_h, sts.scsi_status_l);
2321 				sp->pkt->pkt_reason = CS_FCP_RESPONSE_ERROR;
2322 			}
2323 		}
2324 
2325 		/* Ignore firmware underrun error. */
2326 		if (sts.comp_status == CS_DATA_UNDERRUN &&
2327 		    (sts.scsi_status_h & FCP_RESID_UNDER ||
2328 		    (sts.scsi_status_l != STATUS_CHECK &&
2329 		    sts.scsi_status_l != STATUS_GOOD))) {
2330 			sp->pkt->pkt_reason = CS_COMPLETE;
2331 		}
2332 
2333 		if (sp->pkt->pkt_reason != CS_COMPLETE) {
2334 			ha->xioctl->DeviceErrorCount++;
2335 			EL(sp->ha, "Cmplt status err = %xh, d_id=%xh, lun=%xh"
2336 			    "\n", sts.comp_status, tq->d_id.b24,
2337 			    sp->lun_queue->lun_no);
2338 		}
2339 
2340 		/* Set target request sense data. */
2341 		if (sts.scsi_status_l == STATUS_CHECK) {
2342 			if (sts.scsi_status_h & FCP_SNS_LEN_VALID) {
2343 
2344 				if (sp->pkt->pkt_reason == CS_COMPLETE &&
2345 				    sts.req_sense_data[2] != KEY_NO_SENSE &&
2346 				    sts.req_sense_data[2] !=
2347 				    KEY_UNIT_ATTENTION) {
2348 					ha->xioctl->DeviceErrorCount++;
2349 				}
2350 
2351 				sense_sz = sts.req_sense_length;
2352 
2353 				/* Insure data does not exceed buf. */
2354 				if (sp->pkt->pkt_rsplen <=
2355 				    (uint32_t)sizeof (fcp_rsp_t) +
2356 				    fcpr->fcp_response_len) {
2357 					sp->request_sense_length = 0;
2358 				} else {
2359 					sp->request_sense_length = (uint32_t)
2360 					    (sp->pkt->pkt_rsplen -
2361 					    sizeof (fcp_rsp_t) -
2362 					    fcpr->fcp_response_len);
2363 				}
2364 
2365 				if (sense_sz <
2366 				    sp->request_sense_length) {
2367 					sp->request_sense_length =
2368 					    sense_sz;
2369 				}
2370 
2371 				sp->request_sense_ptr = (caddr_t)rsp;
2372 
2373 				sense_sz = (uint32_t)
2374 				    (((uintptr_t)pkt23 +
2375 				    sizeof (sts_entry_t)) -
2376 				    (uintptr_t)sts.req_sense_data);
2377 				if (sp->request_sense_length <
2378 				    sense_sz) {
2379 					sense_sz =
2380 					    sp->request_sense_length;
2381 				}
2382 
2383 				fcpr->fcp_sense_len = sense_sz;
2384 
2385 				/* Move sense data. */
2386 				ddi_rep_get8(ha->hba_buf.acc_handle,
2387 				    (uint8_t *)sp->request_sense_ptr,
2388 				    sts.req_sense_data,
2389 				    (size_t)sense_sz,
2390 				    DDI_DEV_AUTOINCR);
2391 
2392 				sp->request_sense_ptr += sense_sz;
2393 				sp->request_sense_length -= sense_sz;
2394 				if (sp->request_sense_length != 0) {
2395 					ha->status_srb = sp;
2396 				}
2397 			}
2398 
2399 			if (sense_sz != 0) {
2400 				EL(sp->ha, "check condition sense data, "
2401 				    "d_id=%xh, lun=%xh\n%2xh%3xh%3xh%3xh"
2402 				    "%3xh%3xh%3xh%3xh%3xh%3xh%3xh%3xh%3xh"
2403 				    "%3xh%3xh%3xh%3xh%3xh\n", tq->d_id.b24,
2404 				    sp->lun_queue->lun_no,
2405 				    sts.req_sense_data[0],
2406 				    sts.req_sense_data[1],
2407 				    sts.req_sense_data[2],
2408 				    sts.req_sense_data[3],
2409 				    sts.req_sense_data[4],
2410 				    sts.req_sense_data[5],
2411 				    sts.req_sense_data[6],
2412 				    sts.req_sense_data[7],
2413 				    sts.req_sense_data[8],
2414 				    sts.req_sense_data[9],
2415 				    sts.req_sense_data[10],
2416 				    sts.req_sense_data[11],
2417 				    sts.req_sense_data[12],
2418 				    sts.req_sense_data[13],
2419 				    sts.req_sense_data[14],
2420 				    sts.req_sense_data[15],
2421 				    sts.req_sense_data[16],
2422 				    sts.req_sense_data[17]);
2423 			} else {
2424 				EL(sp->ha, "check condition, d_id=%xh, lun=%xh"
2425 				    "\n", tq->d_id.b24, sp->lun_queue->lun_no);
2426 			}
2427 		}
2428 	}
2429 
2430 	/* Set completed status. */
2431 	sp->flags |= SRB_ISP_COMPLETED;
2432 
2433 	/* Place command on done queue. */
2434 	if (ha->status_srb == NULL) {
2435 		ql_add_link_b(done_q, &sp->cmd);
2436 	}
2437 
2438 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2439 
2440 	return (rval);
2441 }
2442 
2443 /*
2444  * ql_status_cont_entry
2445  *	Processes status continuation entry.
2446  *
2447  * Input:
2448  *	ha:		adapter state pointer.
2449  *	pkt:		entry pointer.
2450  *	done_q:		done queue pointer.
2451  *	set_flags:	task daemon flags to set.
2452  *	reset_flags:	task daemon flags to reset.
2453  *
2454  * Context:
2455  *	Interrupt or Kernel context, no mailbox commands allowed.
2456  */
2457 /* ARGSUSED */
2458 static void
2459 ql_status_cont_entry(ql_adapter_state_t *ha, sts_cont_entry_t *pkt,
2460     ql_head_t *done_q, uint32_t *set_flags, uint32_t *reset_flags)
2461 {
2462 	uint32_t	sense_sz, index;
2463 	ql_srb_t	*sp = ha->status_srb;
2464 
2465 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2466 
2467 	if (sp != NULL && sp->request_sense_length) {
2468 		if (sp->request_sense_length > sizeof (pkt->req_sense_data)) {
2469 			sense_sz = sizeof (pkt->req_sense_data);
2470 		} else {
2471 			sense_sz = sp->request_sense_length;
2472 		}
2473 
2474 		if (CFG_IST(ha, CFG_CTRL_242581)) {
2475 			for (index = 0; index < sense_sz; index += 4) {
2476 				ql_chg_endian((uint8_t *)
2477 				    &pkt->req_sense_data[0] + index, 4);
2478 			}
2479 		}
2480 
2481 		/* Move sense data. */
2482 		ddi_rep_get8(ha->hba_buf.acc_handle,
2483 		    (uint8_t *)sp->request_sense_ptr,
2484 		    (uint8_t *)&pkt->req_sense_data[0], (size_t)sense_sz,
2485 		    DDI_DEV_AUTOINCR);
2486 
2487 		sp->request_sense_ptr += sense_sz;
2488 		sp->request_sense_length -= sense_sz;
2489 
2490 		/* Place command on done queue. */
2491 		if (sp->request_sense_length == 0) {
2492 			ql_add_link_b(done_q, &sp->cmd);
2493 			ha->status_srb = NULL;
2494 		}
2495 	}
2496 
2497 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2498 }
2499 
2500 /*
2501  * ql_ip_entry
2502  *	Processes received ISP IP entry.
2503  *
2504  * Input:
2505  *	ha:		adapter state pointer.
2506  *	pkt:		entry pointer.
2507  *	done_q:		done queue pointer.
2508  *	set_flags:	task daemon flags to set.
2509  *	reset_flags:	task daemon flags to reset.
2510  *
2511  * Context:
2512  *	Interrupt or Kernel context, no mailbox commands allowed.
2513  */
2514 /* ARGSUSED */
2515 static void
2516 ql_ip_entry(ql_adapter_state_t *ha, ip_entry_t *pkt23, ql_head_t *done_q,
2517     uint32_t *set_flags, uint32_t *reset_flags)
2518 {
2519 	ql_srb_t	*sp;
2520 	uint32_t	index, cnt;
2521 	ql_tgt_t	*tq;
2522 
2523 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2524 
2525 	/* Get handle. */
2526 	cnt = ddi_get32(ha->hba_buf.acc_handle, &pkt23->handle);
2527 	index = cnt & OSC_INDEX_MASK;
2528 
2529 	/* Validate handle. */
2530 	sp = index < MAX_OUTSTANDING_COMMANDS ? ha->outstanding_cmds[index] :
2531 	    NULL;
2532 
2533 	if (sp != NULL && sp->handle == cnt) {
2534 		ha->outstanding_cmds[index] = NULL;
2535 		sp->handle = 0;
2536 		sp->flags &= ~SRB_IN_TOKEN_ARRAY;
2537 		tq = sp->lun_queue->target_queue;
2538 
2539 		/* Set ISP completion status */
2540 		if (CFG_IST(ha, CFG_CTRL_242581)) {
2541 			ip_cmd_entry_t	*pkt24 = (ip_cmd_entry_t *)pkt23;
2542 
2543 			sp->pkt->pkt_reason = ddi_get16(
2544 			    ha->hba_buf.acc_handle, &pkt24->hdl_status);
2545 		} else {
2546 			sp->pkt->pkt_reason = ddi_get16(
2547 			    ha->hba_buf.acc_handle, &pkt23->comp_status);
2548 		}
2549 
2550 		if (ha->task_daemon_flags & LOOP_DOWN) {
2551 			EL(ha, "Loop Not Ready Retry, d_id=%xh\n",
2552 			    tq->d_id.b24);
2553 
2554 			/* Set retry status. */
2555 			sp->flags |= SRB_RETRY;
2556 
2557 		} else if (tq->port_down_retry_count &&
2558 		    (sp->pkt->pkt_reason == CS_INCOMPLETE ||
2559 		    sp->pkt->pkt_reason == CS_PORT_UNAVAILABLE ||
2560 		    sp->pkt->pkt_reason == CS_PORT_LOGGED_OUT ||
2561 		    sp->pkt->pkt_reason == CS_PORT_CONFIG_CHG ||
2562 		    sp->pkt->pkt_reason == CS_PORT_BUSY)) {
2563 			EL(ha, "Port Down Retry=%xh, d_id=%xh, count=%d\n",
2564 			    sp->pkt->pkt_reason, tq->d_id.b24,
2565 			    tq->port_down_retry_count);
2566 
2567 			/* Set retry status. */
2568 			sp->flags |= SRB_RETRY;
2569 
2570 			if (sp->pkt->pkt_reason == CS_PORT_LOGGED_OUT ||
2571 			    sp->pkt->pkt_reason == CS_PORT_UNAVAILABLE) {
2572 				ha->adapter_stats->d_stats[lobyte(
2573 				    tq->loop_id)].logouts_recvd++;
2574 				ql_send_logo(ha, tq, done_q);
2575 			}
2576 
2577 			/* Acquire device queue lock. */
2578 			DEVICE_QUEUE_LOCK(tq);
2579 
2580 			if ((tq->flags & TQF_QUEUE_SUSPENDED) == 0) {
2581 				tq->flags |= TQF_QUEUE_SUSPENDED;
2582 
2583 				tq->port_down_retry_count--;
2584 
2585 				ADAPTER_STATE_LOCK(ha);
2586 				if (ha->port_retry_timer == 0) {
2587 					if ((ha->port_retry_timer =
2588 					    ha->port_down_retry_delay) == 0) {
2589 						*set_flags |=
2590 						    PORT_RETRY_NEEDED;
2591 					}
2592 				}
2593 				ADAPTER_STATE_UNLOCK(ha);
2594 			}
2595 
2596 			/* Release device queue specific lock. */
2597 			DEVICE_QUEUE_UNLOCK(tq);
2598 
2599 		} else if (sp->pkt->pkt_reason == CS_RESET) {
2600 			EL(ha, "Reset Retry, d_id=%xh\n", tq->d_id.b24);
2601 
2602 			/* Set retry status. */
2603 			sp->flags |= SRB_RETRY;
2604 		} else {
2605 			if (sp->pkt->pkt_reason != CS_COMPLETE) {
2606 				EL(ha, "Cmplt status err=%xh, d_id=%xh\n",
2607 				    sp->pkt->pkt_reason, tq->d_id.b24);
2608 			}
2609 		}
2610 
2611 		/* Set completed status. */
2612 		sp->flags |= SRB_ISP_COMPLETED;
2613 
2614 		ql_add_link_b(done_q, &sp->cmd);
2615 
2616 	} else {
2617 		if (sp == NULL) {
2618 			EL(ha, "unknown IOCB handle=%xh\n", cnt);
2619 		} else {
2620 			EL(ha, "mismatch IOCB handle pkt=%xh, sp=%xh\n",
2621 			    cnt, sp->handle);
2622 		}
2623 
2624 		(void) ql_binary_fw_dump(ha, FALSE);
2625 
2626 		if (!(ha->task_daemon_flags & (ISP_ABORT_NEEDED |
2627 		    ABORT_ISP_ACTIVE))) {
2628 			EL(ha, "ISP Invalid handle, isp_abort_needed\n");
2629 			*set_flags |= ISP_ABORT_NEEDED;
2630 		}
2631 	}
2632 
2633 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2634 }
2635 
2636 /*
2637  * ql_ip_rcv_entry
2638  *	Processes received ISP IP buffers entry.
2639  *
2640  * Input:
2641  *	ha:		adapter state pointer.
2642  *	pkt:		entry pointer.
2643  *	done_q:		done queue pointer.
2644  *	set_flags:	task daemon flags to set.
2645  *	reset_flags:	task daemon flags to reset.
2646  *
2647  * Context:
2648  *	Interrupt or Kernel context, no mailbox commands allowed.
2649  */
2650 /* ARGSUSED */
2651 static void
2652 ql_ip_rcv_entry(ql_adapter_state_t *ha, ip_rcv_entry_t *pkt,
2653     ql_head_t *done_q, uint32_t *set_flags, uint32_t *reset_flags)
2654 {
2655 	port_id_t	s_id;
2656 	uint16_t	index;
2657 	uint8_t		cnt;
2658 	ql_tgt_t	*tq;
2659 
2660 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2661 
2662 	/* Locate device queue. */
2663 	s_id.b.al_pa = pkt->s_id[0];
2664 	s_id.b.area = pkt->s_id[1];
2665 	s_id.b.domain = pkt->s_id[2];
2666 	if ((tq = ql_d_id_to_queue(ha, s_id)) == NULL) {
2667 		EL(ha, "Unknown IP device ID=%xh\n", s_id.b24);
2668 		return;
2669 	}
2670 
2671 	tq->ub_sequence_length = (uint16_t)ddi_get16(ha->hba_buf.acc_handle,
2672 	    &pkt->seq_length);
2673 	tq->ub_total_seg_cnt = pkt->segment_count;
2674 	tq->ub_seq_id = ++ha->ub_seq_id;
2675 	tq->ub_seq_cnt = 0;
2676 	tq->ub_frame_ro = 0;
2677 	tq->ub_loop_id = pkt->loop_id;
2678 	ha->rcv_dev_q = tq;
2679 
2680 	for (cnt = 0; cnt < IP_RCVBUF_HANDLES && tq->ub_seq_cnt <
2681 	    tq->ub_total_seg_cnt; cnt++) {
2682 
2683 		index = (uint16_t)ddi_get16(ha->hba_buf.acc_handle,
2684 		    &pkt->buffer_handle[cnt]);
2685 
2686 		if (ql_ub_frame_hdr(ha, tq, index, done_q) != QL_SUCCESS) {
2687 			EL(ha, "ql_ub_frame_hdr failed, isp_abort_needed\n");
2688 			*set_flags |= ISP_ABORT_NEEDED;
2689 			break;
2690 		}
2691 	}
2692 
2693 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2694 }
2695 
2696 /*
2697  * ql_ip_rcv_cont_entry
2698  *	Processes received ISP IP buffers continuation entry.
2699  *
2700  * Input:
2701  *	ha:		adapter state pointer.
2702  *	pkt:		entry pointer.
2703  *	done_q:		done queue pointer.
2704  *	set_flags:	task daemon flags to set.
2705  *	reset_flags:	task daemon flags to reset.
2706  *
2707  * Context:
2708  *	Interrupt or Kernel context, no mailbox commands allowed.
2709  */
2710 /* ARGSUSED */
2711 static void
2712 ql_ip_rcv_cont_entry(ql_adapter_state_t *ha, ip_rcv_cont_entry_t *pkt,
2713     ql_head_t *done_q, uint32_t *set_flags, uint32_t *reset_flags)
2714 {
2715 	uint16_t	index;
2716 	uint8_t		cnt;
2717 	ql_tgt_t	*tq;
2718 
2719 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2720 
2721 	if ((tq = ha->rcv_dev_q) == NULL) {
2722 		EL(ha, "No IP receive device\n");
2723 		return;
2724 	}
2725 
2726 	for (cnt = 0; cnt < IP_RCVBUF_CONT_HANDLES &&
2727 	    tq->ub_seq_cnt < tq->ub_total_seg_cnt; cnt++) {
2728 
2729 		index = (uint16_t)ddi_get16(ha->hba_buf.acc_handle,
2730 		    &pkt->buffer_handle[cnt]);
2731 
2732 		if (ql_ub_frame_hdr(ha, tq, index, done_q) != QL_SUCCESS) {
2733 			EL(ha, "ql_ub_frame_hdr failed, isp_abort_needed\n");
2734 			*set_flags |= ISP_ABORT_NEEDED;
2735 			break;
2736 		}
2737 	}
2738 
2739 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2740 }
2741 
2742 /*
2743  * ip_rcv_24xx_entry_t
2744  *	Processes received ISP24xx IP buffers entry.
2745  *
2746  * Input:
2747  *	ha:		adapter state pointer.
2748  *	pkt:		entry pointer.
2749  *	done_q:		done queue pointer.
2750  *	set_flags:	task daemon flags to set.
2751  *	reset_flags:	task daemon flags to reset.
2752  *
2753  * Context:
2754  *	Interrupt or Kernel context, no mailbox commands allowed.
2755  */
2756 /* ARGSUSED */
2757 static void
2758 ql_ip_24xx_rcv_entry(ql_adapter_state_t *ha, ip_rcv_24xx_entry_t *pkt,
2759     ql_head_t *done_q, uint32_t *set_flags, uint32_t *reset_flags)
2760 {
2761 	port_id_t	s_id;
2762 	uint16_t	index;
2763 	uint8_t		cnt;
2764 	ql_tgt_t	*tq;
2765 
2766 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2767 
2768 	/* Locate device queue. */
2769 	s_id.b.al_pa = pkt->s_id[0];
2770 	s_id.b.area = pkt->s_id[1];
2771 	s_id.b.domain = pkt->s_id[2];
2772 	if ((tq = ql_d_id_to_queue(ha, s_id)) == NULL) {
2773 		EL(ha, "Unknown IP device ID=%xh\n", s_id.b24);
2774 		return;
2775 	}
2776 
2777 	if (tq->ub_total_seg_cnt == 0) {
2778 		tq->ub_sequence_length = (uint16_t)ddi_get16(
2779 		    ha->hba_buf.acc_handle, &pkt->seq_length);
2780 		tq->ub_total_seg_cnt = pkt->segment_count;
2781 		tq->ub_seq_id = ++ha->ub_seq_id;
2782 		tq->ub_seq_cnt = 0;
2783 		tq->ub_frame_ro = 0;
2784 		tq->ub_loop_id = (uint16_t)ddi_get16(
2785 		    ha->hba_buf.acc_handle, &pkt->n_port_hdl);
2786 	}
2787 
2788 	for (cnt = 0; cnt < IP_24XX_RCVBUF_HANDLES && tq->ub_seq_cnt <
2789 	    tq->ub_total_seg_cnt; cnt++) {
2790 
2791 		index = (uint16_t)ddi_get16(ha->hba_buf.acc_handle,
2792 		    &pkt->buffer_handle[cnt]);
2793 
2794 		if (ql_ub_frame_hdr(ha, tq, index, done_q) != QL_SUCCESS) {
2795 			EL(ha, "ql_ub_frame_hdr failed, isp_abort_needed\n");
2796 			*set_flags |= ISP_ABORT_NEEDED;
2797 			break;
2798 		}
2799 	}
2800 
2801 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2802 }
2803 
2804 /*
2805  * ql_ms_entry
2806  *	Processes received Name/Management/CT Pass-Through entry.
2807  *
2808  * Input:
2809  *	ha:		adapter state pointer.
2810  *	pkt23:		entry pointer.
2811  *	done_q:		done queue pointer.
2812  *	set_flags:	task daemon flags to set.
2813  *	reset_flags:	task daemon flags to reset.
2814  *
2815  * Context:
2816  *	Interrupt or Kernel context, no mailbox commands allowed.
2817  */
2818 /* ARGSUSED */
2819 static void
2820 ql_ms_entry(ql_adapter_state_t *ha, ms_entry_t *pkt23, ql_head_t *done_q,
2821     uint32_t *set_flags, uint32_t *reset_flags)
2822 {
2823 	ql_srb_t		*sp;
2824 	uint32_t		index, cnt;
2825 	ql_tgt_t		*tq;
2826 	ct_passthru_entry_t	*pkt24 = (ct_passthru_entry_t *)pkt23;
2827 
2828 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2829 
2830 	/* Get handle. */
2831 	cnt = ddi_get32(ha->hba_buf.acc_handle, &pkt23->handle);
2832 	index = cnt & OSC_INDEX_MASK;
2833 
2834 	/* Validate handle. */
2835 	sp = index < MAX_OUTSTANDING_COMMANDS ? ha->outstanding_cmds[index] :
2836 	    NULL;
2837 
2838 	if (sp != NULL && sp->handle == cnt) {
2839 		if (!(sp->flags & SRB_MS_PKT)) {
2840 			EL(ha, "Not SRB_MS_PKT flags=%xh, isp_abort_needed",
2841 			    sp->flags);
2842 			*set_flags |= ISP_ABORT_NEEDED;
2843 			return;
2844 		}
2845 
2846 		ha->outstanding_cmds[index] = NULL;
2847 		sp->handle = 0;
2848 		sp->flags &= ~SRB_IN_TOKEN_ARRAY;
2849 		tq = sp->lun_queue->target_queue;
2850 
2851 		/* Set ISP completion status */
2852 		if (CFG_IST(ha, CFG_CTRL_242581)) {
2853 			sp->pkt->pkt_reason = ddi_get16(
2854 			    ha->hba_buf.acc_handle, &pkt24->status);
2855 		} else {
2856 			sp->pkt->pkt_reason = ddi_get16(
2857 			    ha->hba_buf.acc_handle, &pkt23->comp_status);
2858 		}
2859 
2860 		if (sp->pkt->pkt_reason == CS_RESOUCE_UNAVAILABLE &&
2861 		    sp->retry_count) {
2862 			EL(ha, "Resouce Unavailable Retry = %d\n",
2863 			    sp->retry_count);
2864 
2865 			/* Set retry status. */
2866 			sp->retry_count--;
2867 			sp->flags |= SRB_RETRY;
2868 
2869 			/* Acquire device queue lock. */
2870 			DEVICE_QUEUE_LOCK(tq);
2871 
2872 			if (!(tq->flags & TQF_QUEUE_SUSPENDED)) {
2873 				tq->flags |= TQF_QUEUE_SUSPENDED;
2874 
2875 				ADAPTER_STATE_LOCK(ha);
2876 				if (ha->port_retry_timer == 0) {
2877 					ha->port_retry_timer = 2;
2878 				}
2879 				ADAPTER_STATE_UNLOCK(ha);
2880 			}
2881 
2882 			/* Release device queue specific lock. */
2883 			DEVICE_QUEUE_UNLOCK(tq);
2884 
2885 		} else if (tq->port_down_retry_count &&
2886 		    (sp->pkt->pkt_reason == CS_PORT_CONFIG_CHG ||
2887 		    sp->pkt->pkt_reason == CS_PORT_BUSY)) {
2888 			EL(ha, "Port Down Retry\n");
2889 
2890 			/* Set retry status. */
2891 			sp->flags |= SRB_RETRY;
2892 
2893 			/* Acquire device queue lock. */
2894 			DEVICE_QUEUE_LOCK(tq);
2895 
2896 			if ((tq->flags & TQF_QUEUE_SUSPENDED) == 0) {
2897 				tq->flags |= TQF_QUEUE_SUSPENDED;
2898 
2899 				tq->port_down_retry_count--;
2900 
2901 				ADAPTER_STATE_LOCK(ha);
2902 				if (ha->port_retry_timer == 0) {
2903 					if ((ha->port_retry_timer =
2904 					    ha->port_down_retry_delay) == 0) {
2905 						*set_flags |=
2906 						    PORT_RETRY_NEEDED;
2907 					}
2908 				}
2909 				ADAPTER_STATE_UNLOCK(ha);
2910 			}
2911 
2912 			/* Release device queue specific lock. */
2913 			DEVICE_QUEUE_UNLOCK(tq);
2914 
2915 		} else if (sp->pkt->pkt_reason == CS_RESET) {
2916 			EL(ha, "Reset Retry\n");
2917 
2918 			/* Set retry status. */
2919 			sp->flags |= SRB_RETRY;
2920 
2921 		} else if (CFG_IST(ha, CFG_CTRL_242581) &&
2922 		    sp->pkt->pkt_reason == CS_DATA_UNDERRUN) {
2923 			cnt = ddi_get32(ha->hba_buf.acc_handle,
2924 			    &pkt24->resp_byte_count);
2925 			if (cnt < sizeof (fc_ct_header_t)) {
2926 				EL(ha, "Data underrun\n");
2927 			} else {
2928 				sp->pkt->pkt_reason = CS_COMPLETE;
2929 			}
2930 
2931 		} else if (sp->pkt->pkt_reason != CS_COMPLETE) {
2932 			EL(ha, "status err=%xh\n", sp->pkt->pkt_reason);
2933 		}
2934 
2935 		if (sp->pkt->pkt_reason == CS_COMPLETE) {
2936 			/*EMPTY*/
2937 			QL_PRINT_3(CE_CONT, "(%d): ct_cmdrsp=%x%02xh resp\n",
2938 			    ha->instance, sp->pkt->pkt_cmd[8],
2939 			    sp->pkt->pkt_cmd[9]);
2940 			QL_DUMP_3(sp->pkt->pkt_resp, 8, sp->pkt->pkt_rsplen);
2941 		}
2942 
2943 		/* For nameserver restore command, management change header. */
2944 		if ((sp->flags & SRB_RETRY) == 0) {
2945 			tq->d_id.b24 == 0xfffffc ?
2946 			    ql_cthdr_endian(sp->pkt->pkt_cmd_acc,
2947 			    sp->pkt->pkt_cmd, B_TRUE) :
2948 			    ql_cthdr_endian(sp->pkt->pkt_resp_acc,
2949 			    sp->pkt->pkt_resp, B_TRUE);
2950 		}
2951 
2952 		/* Set completed status. */
2953 		sp->flags |= SRB_ISP_COMPLETED;
2954 
2955 		/* Place command on done queue. */
2956 		ql_add_link_b(done_q, &sp->cmd);
2957 
2958 	} else {
2959 		if (sp == NULL) {
2960 			EL(ha, "unknown IOCB handle=%xh\n", cnt);
2961 		} else {
2962 			EL(ha, "mismatch IOCB handle pkt=%xh, sp=%xh\n",
2963 			    cnt, sp->handle);
2964 		}
2965 
2966 		(void) ql_binary_fw_dump(ha, FALSE);
2967 
2968 		if (!(ha->task_daemon_flags & (ISP_ABORT_NEEDED |
2969 		    ABORT_ISP_ACTIVE))) {
2970 			EL(ha, "ISP Invalid handle, isp_abort_needed\n");
2971 			*set_flags |= ISP_ABORT_NEEDED;
2972 		}
2973 	}
2974 
2975 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2976 }
2977 
2978 /*
2979  * ql_report_id_entry
2980  *	Processes received Name/Management/CT Pass-Through entry.
2981  *
2982  * Input:
2983  *	ha:		adapter state pointer.
2984  *	pkt23:		entry pointer.
2985  *	done_q:		done queue pointer.
2986  *	set_flags:	task daemon flags to set.
2987  *	reset_flags:	task daemon flags to reset.
2988  *
2989  * Context:
2990  *	Interrupt or Kernel context, no mailbox commands allowed.
2991  */
2992 /* ARGSUSED */
2993 static void
2994 ql_report_id_entry(ql_adapter_state_t *ha, report_id_1_t *pkt,
2995     ql_head_t *done_q, uint32_t *set_flags, uint32_t *reset_flags)
2996 {
2997 	ql_adapter_state_t	*vha;
2998 
2999 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3000 
3001 	EL(ha, "format=%d, vp=%d, status=%d\n",
3002 	    pkt->format, pkt->vp_index, pkt->status);
3003 
3004 	if (pkt->format == 1) {
3005 		/* Locate port state structure. */
3006 		for (vha = ha; vha != NULL; vha = vha->vp_next) {
3007 			if (vha->vp_index == pkt->vp_index) {
3008 				break;
3009 			}
3010 		}
3011 		if (vha != NULL && vha->vp_index != 0 &&
3012 		    (pkt->status == CS_COMPLETE ||
3013 		    pkt->status == CS_PORT_ID_CHANGE)) {
3014 			*set_flags |= LOOP_RESYNC_NEEDED;
3015 			*reset_flags &= ~LOOP_RESYNC_NEEDED;
3016 			vha->loop_down_timer = LOOP_DOWN_TIMER_OFF;
3017 			TASK_DAEMON_LOCK(ha);
3018 			vha->task_daemon_flags |= LOOP_RESYNC_NEEDED;
3019 			vha->task_daemon_flags &= ~LOOP_DOWN;
3020 			TASK_DAEMON_UNLOCK(ha);
3021 		}
3022 	}
3023 
3024 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3025 }
3026 
3027 /*
3028  * ql_els_entry
3029  *	Processes received ELS Pass-Through entry.
3030  *
3031  * Input:
3032  *	ha:		adapter state pointer.
3033  *	pkt23:		entry pointer.
3034  *	done_q:		done queue pointer.
3035  *	set_flags:	task daemon flags to set.
3036  *	reset_flags:	task daemon flags to reset.
3037  *
3038  * Context:
3039  *	Interrupt or Kernel context, no mailbox commands allowed.
3040  */
3041 /* ARGSUSED */
3042 static void
3043 ql_els_passthru_entry(ql_adapter_state_t *ha, els_passthru_entry_rsp_t *rsp,
3044     ql_head_t *done_q, uint32_t *set_flags, uint32_t *reset_flags)
3045 {
3046 	ql_tgt_t	*tq;
3047 	port_id_t	d_id, s_id;
3048 	ql_srb_t	*srb;
3049 	uint32_t	cnt, index;
3050 
3051 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3052 	/* Get handle. */
3053 	cnt = ddi_get32(ha->hba_buf.acc_handle, &rsp->handle);
3054 	index = cnt & OSC_INDEX_MASK;
3055 
3056 	/* Validate handle. */
3057 	srb = index < MAX_OUTSTANDING_COMMANDS ? ha->outstanding_cmds[index] :
3058 	    NULL;
3059 
3060 	(void) ddi_dma_sync(srb->pkt->pkt_resp_dma, 0, 0,
3061 	    DDI_DMA_SYNC_FORKERNEL);
3062 
3063 	if (srb != NULL && srb->handle == cnt) {
3064 		if (!(srb->flags & SRB_ELS_PKT)) {
3065 			EL(ha, "Not SRB_ELS_PKT flags=%xh, isp_abort_needed",
3066 			    srb->flags);
3067 			*set_flags |= ISP_ABORT_NEEDED;
3068 			return;
3069 		}
3070 		ha->outstanding_cmds[index] = NULL;
3071 		srb->handle = 0;
3072 		srb->flags &= ~SRB_IN_TOKEN_ARRAY;
3073 
3074 		/* Set ISP completion status */
3075 		srb->pkt->pkt_reason = ddi_get16(
3076 		    ha->hba_buf.acc_handle, &rsp->comp_status);
3077 
3078 		if (srb->pkt->pkt_reason != CS_COMPLETE) {
3079 			la_els_rjt_t	rjt;
3080 			EL(ha, "status err=%xh\n", srb->pkt->pkt_reason);
3081 
3082 			if (srb->pkt->pkt_reason == CS_LOGIN_LOGOUT_ERROR) {
3083 				EL(ha, "e1=%xh e2=%xh\n",
3084 				    rsp->error_subcode1, rsp->error_subcode2);
3085 			}
3086 
3087 			srb->pkt->pkt_state = FC_PKT_TRAN_ERROR;
3088 
3089 			/* Build RJT in the response. */
3090 			rjt.ls_code.ls_code = LA_ELS_RJT;
3091 			rjt.reason = FC_REASON_NO_CONNECTION;
3092 
3093 			ddi_rep_put8(srb->pkt->pkt_resp_acc, (uint8_t *)&rjt,
3094 			    (uint8_t *)srb->pkt->pkt_resp,
3095 			    sizeof (rjt), DDI_DEV_AUTOINCR);
3096 
3097 			srb->pkt->pkt_state = FC_PKT_TRAN_ERROR;
3098 			srb->pkt->pkt_reason = FC_REASON_NO_CONNECTION;
3099 		}
3100 
3101 		if (srb->pkt->pkt_reason == CS_COMPLETE) {
3102 			uint8_t		opcode;
3103 			uint16_t	loop_id;
3104 
3105 			/* Indicate ISP completion */
3106 			srb->flags |= SRB_ISP_COMPLETED;
3107 
3108 			loop_id = ddi_get16(ha->hba_buf.acc_handle,
3109 			    &rsp->n_port_hdl);
3110 
3111 			if (ha->topology & QL_N_PORT) {
3112 				/* create a target Q if there isn't one */
3113 				tq = ql_loop_id_to_queue(ha, loop_id);
3114 				if (tq == NULL) {
3115 					d_id.b.al_pa = rsp->d_id_7_0;
3116 					d_id.b.area = rsp->d_id_15_8;
3117 					d_id.b.domain = rsp->d_id_23_16;
3118 					/* Acquire adapter state lock. */
3119 					ADAPTER_STATE_LOCK(ha);
3120 
3121 					tq = ql_dev_init(ha, d_id, loop_id);
3122 					EL(ha, " tq = %x\n", tq);
3123 
3124 					ADAPTER_STATE_UNLOCK(ha);
3125 				}
3126 
3127 				/* on plogi success assume the chosen s_id */
3128 				opcode = ddi_get8(ha->hba_buf.acc_handle,
3129 				    &rsp->els_cmd_opcode);
3130 
3131 				EL(ha, "els_cmd_opcode=%x srb->pkt=%x\n",
3132 				    opcode, srb->pkt);
3133 
3134 				if (opcode == LA_ELS_PLOGI) {
3135 					s_id.b.al_pa = rsp->s_id_7_0;
3136 					s_id.b.area = rsp->s_id_15_8;
3137 					s_id.b.domain = rsp->s_id_23_16;
3138 
3139 					ha->d_id.b24 = s_id.b24;
3140 					EL(ha, "Set port's source ID %xh\n",
3141 					    ha->d_id.b24);
3142 				}
3143 			}
3144 			ql_isp_els_handle_rsp_endian(ha, srb);
3145 
3146 			if (ha != srb->ha) {
3147 				EL(ha, "ha=%x srb->ha=%x\n", ha, srb->ha);
3148 			}
3149 
3150 			if (tq != NULL) {
3151 				tq->logout_sent = 0;
3152 				tq->flags &= ~TQF_NEED_AUTHENTICATION;
3153 
3154 				if (CFG_IST(ha, CFG_CTRL_242581)) {
3155 					tq->flags |= TQF_IIDMA_NEEDED;
3156 				}
3157 			srb->pkt->pkt_state = FC_PKT_SUCCESS;
3158 			}
3159 		}
3160 		/* invoke the callback */
3161 		ql_awaken_task_daemon(ha, srb, 0, 0);
3162 	} else {
3163 		EL(ha, "unexpected IOCB handle=%xh\n", srb);
3164 
3165 		if (!(ha->task_daemon_flags & (ISP_ABORT_NEEDED |
3166 		    ABORT_ISP_ACTIVE))) {
3167 			EL(ha, "ISP Invalid handle, isp_abort_needed\n");
3168 			*set_flags |= ISP_ABORT_NEEDED;
3169 		}
3170 	}
3171 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3172 }
3173