isp.c revision 104916
1/* $FreeBSD: head/sys/dev/isp/isp.c 104916 2002-10-11 17:28:01Z mjacob $ */
2/*
3 * Machine and OS Independent (well, as best as possible)
4 * code for the Qlogic ISP SCSI adapters.
5 *
6 * Copyright (c) 1997, 1998, 1999, 2000, 2001 by Matthew Jacob
7 * Feral Software
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice immediately at the beginning of the file, without modification,
15 *    this list of conditions, and the following disclaimer.
16 * 2. The name of the author may not be used to endorse or promote products
17 *    derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * Inspiration and ideas about this driver are from Erik Moe's Linux driver
34 * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some
35 * ideas dredged from the Solaris driver.
36 */
37
38/*
39 * Include header file appropriate for platform we're building on.
40 */
41
42#ifdef	__NetBSD__
43#include <dev/ic/isp_netbsd.h>
44#endif
45#ifdef	__FreeBSD__
46#include <dev/isp/isp_freebsd.h>
47#endif
48#ifdef	__OpenBSD__
49#include <dev/ic/isp_openbsd.h>
50#endif
51#ifdef	__linux__
52#include "isp_linux.h"
53#endif
54#ifdef	__svr4__
55#include "isp_solaris.h"
56#endif
57
58/*
59 * General defines
60 */
61
62#define	MBOX_DELAY_COUNT	1000000 / 100
63
64/*
65 * Local static data
66 */
67static const char portshift[] =
68    "Target %d Loop ID 0x%x (Port 0x%x) => Loop 0x%x (Port 0x%x)";
69static const char portdup[] =
70    "Target %d duplicates Target %d- killing off both";
71static const char retained[] =
72    "Retaining Loop ID 0x%x for Target %d (Port 0x%x)";
73static const char lretained[] =
74    "Retained login of Target %d (Loop ID 0x%x) Port 0x%x";
75static const char plogout[] =
76    "Logging out Target %d at Loop ID 0x%x (Port 0x%x)";
77static const char plogierr[] =
78    "Command Error in PLOGI for Port 0x%x (0x%x)";
79static const char nopdb[] =
80    "Could not get PDB for Device @ Port 0x%x";
81static const char pdbmfail1[] =
82    "PDB Loop ID info for Device @ Port 0x%x does not match up (0x%x)";
83static const char pdbmfail2[] =
84    "PDB Port info for Device @ Port 0x%x does not match up (0x%x)";
85static const char ldumped[] =
86    "Target %d (Loop ID 0x%x) Port 0x%x dumped after login info mismatch";
87static const char notresp[] =
88  "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
89static const char xact1[] =
90    "HBA attempted queued transaction with disconnect not set for %d.%d.%d";
91static const char xact2[] =
92    "HBA attempted queued transaction to target routine %d on target %d bus %d";
93static const char xact3[] =
94    "HBA attempted queued cmd for %d.%d.%d when queueing disabled";
95static const char pskip[] =
96    "SCSI phase skipped for target %d.%d.%d";
97static const char topology[] =
98    "Loop ID %d, AL_PA 0x%x, Port ID 0x%x, Loop State 0x%x, Topology '%s'";
99static const char swrej[] =
100    "Fabric Nameserver rejected %s (Reason=0x%x Expl=0x%x) for Port ID 0x%x";
101static const char finmsg[] =
102    "(%d.%d.%d): FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x";
103static const char sc0[] =
104    "%s CHAN %d FTHRSH %d IID %d RESETD %d RETRYC %d RETRYD %d ASD 0x%x";
105static const char sc1[] =
106    "%s RAAN 0x%x DLAN 0x%x DDMAB 0x%x CDMAB 0x%x SELTIME %d MQD %d";
107static const char sc2[] = "%s CHAN %d TGT %d FLAGS 0x%x 0x%x/0x%x";
108static const char sc3[] = "Generated";
109static const char sc4[] = "NVRAM";
110static const char bun[] =
111    "bad underrun for %d.%d (count %d, resid %d, status %s)";
112
113/*
114 * Local function prototypes.
115 */
116static int isp_parse_async(struct ispsoftc *, u_int16_t);
117static int isp_handle_other_response(struct ispsoftc *, int, isphdr_t *,
118    u_int16_t *);
119static void
120isp_parse_status(struct ispsoftc *, ispstatusreq_t *, XS_T *);
121static void isp_fastpost_complete(struct ispsoftc *, u_int16_t);
122static int isp_mbox_continue(struct ispsoftc *);
123static void isp_scsi_init(struct ispsoftc *);
124static void isp_scsi_channel_init(struct ispsoftc *, int);
125static void isp_fibre_init(struct ispsoftc *);
126static void isp_mark_getpdb_all(struct ispsoftc *);
127static int isp_getmap(struct ispsoftc *, fcpos_map_t *);
128static int isp_getpdb(struct ispsoftc *, int, isp_pdb_t *);
129static u_int64_t isp_get_portname(struct ispsoftc *, int, int);
130static int isp_fclink_test(struct ispsoftc *, int);
131static char *isp2100_fw_statename(int);
132static int isp_pdb_sync(struct ispsoftc *);
133static int isp_scan_loop(struct ispsoftc *);
134static int isp_fabric_mbox_cmd(struct ispsoftc *, mbreg_t *);
135static int isp_scan_fabric(struct ispsoftc *, int);
136static void isp_register_fc4_type(struct ispsoftc *);
137static void isp_fw_state(struct ispsoftc *);
138static void isp_mboxcmd_qnw(struct ispsoftc *, mbreg_t *, int);
139static void isp_mboxcmd(struct ispsoftc *, mbreg_t *, int);
140
141static void isp_update(struct ispsoftc *);
142static void isp_update_bus(struct ispsoftc *, int);
143static void isp_setdfltparm(struct ispsoftc *, int);
144static int isp_read_nvram(struct ispsoftc *);
145static void isp_rdnvram_word(struct ispsoftc *, int, u_int16_t *);
146static void isp_parse_nvram_1020(struct ispsoftc *, u_int8_t *);
147static void isp_parse_nvram_1080(struct ispsoftc *, int, u_int8_t *);
148static void isp_parse_nvram_12160(struct ispsoftc *, int, u_int8_t *);
149static void isp_parse_nvram_2100(struct ispsoftc *, u_int8_t *);
150
151/*
152 * Reset Hardware.
153 *
154 * Hit the chip over the head, download new f/w if available and set it running.
155 *
156 * Locking done elsewhere.
157 */
158
159void
160isp_reset(struct ispsoftc *isp)
161{
162	mbreg_t mbs;
163	u_int16_t code_org;
164	int loops, i, dodnld = 1;
165	char *btype = "????";
166
167	isp->isp_state = ISP_NILSTATE;
168
169	/*
170	 * Basic types (SCSI, FibreChannel and PCI or SBus)
171	 * have been set in the MD code. We figure out more
172	 * here. Possibly more refined types based upon PCI
173	 * identification. Chip revision has been gathered.
174	 *
175	 * After we've fired this chip up, zero out the conf1 register
176	 * for SCSI adapters and do other settings for the 2100.
177	 */
178
179	/*
180	 * Get the current running firmware revision out of the
181	 * chip before we hit it over the head (if this is our
182	 * first time through). Note that we store this as the
183	 * 'ROM' firmware revision- which it may not be. In any
184	 * case, we don't really use this yet, but we may in
185	 * the future.
186	 */
187	if (isp->isp_touched == 0) {
188		/*
189		 * First see whether or not we're sitting in the ISP PROM.
190		 * If we've just been reset, we'll have the string "ISP   "
191		 * spread through outgoing mailbox registers 1-3. We do
192		 * this for PCI cards because otherwise we really don't
193		 * know what state the card is in and we could hang if
194		 * we try this command otherwise.
195		 *
196		 * For SBus cards, we just do this because they almost
197		 * certainly will be running firmware by now.
198		 */
199		if (ISP_READ(isp, OUTMAILBOX1) != 0x4953 ||
200		    ISP_READ(isp, OUTMAILBOX2) != 0x5020 ||
201		    ISP_READ(isp, OUTMAILBOX3) != 0x2020) {
202			/*
203			 * Just in case it was paused...
204			 */
205			ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
206			mbs.param[0] = MBOX_ABOUT_FIRMWARE;
207			isp_mboxcmd(isp, &mbs, MBLOGNONE);
208			if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
209				isp->isp_romfw_rev[0] = mbs.param[1];
210				isp->isp_romfw_rev[1] = mbs.param[2];
211				isp->isp_romfw_rev[2] = mbs.param[3];
212			}
213		}
214		isp->isp_touched = 1;
215	}
216
217	DISABLE_INTS(isp);
218
219	/*
220	 * Set up default request/response queue in-pointer/out-pointer
221	 * register indices.
222	 */
223	if (IS_23XX(isp)) {
224		isp->isp_rqstinrp = BIU_REQINP;
225		isp->isp_rqstoutrp = BIU_REQOUTP;
226		isp->isp_respinrp = BIU_RSPINP;
227		isp->isp_respoutrp = BIU_RSPOUTP;
228	} else {
229		isp->isp_rqstinrp = INMAILBOX4;
230		isp->isp_rqstoutrp = OUTMAILBOX4;
231		isp->isp_respinrp = OUTMAILBOX5;
232		isp->isp_respoutrp = INMAILBOX5;
233	}
234
235	/*
236	 * Put the board into PAUSE mode (so we can read the SXP registers
237	 * or write FPM/FBM registers).
238	 */
239	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
240
241	if (IS_FC(isp)) {
242		switch (isp->isp_type) {
243		case ISP_HA_FC_2100:
244			btype = "2100";
245			break;
246		case ISP_HA_FC_2200:
247			btype = "2200";
248			break;
249		case ISP_HA_FC_2300:
250			btype = "2300";
251			break;
252		case ISP_HA_FC_2312:
253			btype = "2312";
254			break;
255		default:
256			break;
257		}
258		/*
259		 * While we're paused, reset the FPM module and FBM fifos.
260		 */
261		ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
262		ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
263		ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
264		ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
265		ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
266	} else if (IS_1240(isp)) {
267		sdparam *sdp = isp->isp_param;
268		btype = "1240";
269		isp->isp_clock = 60;
270		sdp->isp_ultramode = 1;
271		sdp++;
272		sdp->isp_ultramode = 1;
273		/*
274		 * XXX: Should probably do some bus sensing.
275		 */
276	} else if (IS_ULTRA2(isp)) {
277		static const char m[] = "bus %d is in %s Mode";
278		u_int16_t l;
279		sdparam *sdp = isp->isp_param;
280
281		isp->isp_clock = 100;
282
283		if (IS_1280(isp))
284			btype = "1280";
285		else if (IS_1080(isp))
286			btype = "1080";
287		else if (IS_10160(isp))
288			btype = "10160";
289		else if (IS_12160(isp))
290			btype = "12160";
291		else
292			btype = "<UNKLVD>";
293
294		l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK;
295		switch (l) {
296		case ISP1080_LVD_MODE:
297			sdp->isp_lvdmode = 1;
298			isp_prt(isp, ISP_LOGCONFIG, m, 0, "LVD");
299			break;
300		case ISP1080_HVD_MODE:
301			sdp->isp_diffmode = 1;
302			isp_prt(isp, ISP_LOGCONFIG, m, 0, "Differential");
303			break;
304		case ISP1080_SE_MODE:
305			sdp->isp_ultramode = 1;
306			isp_prt(isp, ISP_LOGCONFIG, m, 0, "Single-Ended");
307			break;
308		default:
309			isp_prt(isp, ISP_LOGERR,
310			    "unknown mode on bus %d (0x%x)", 0, l);
311			break;
312		}
313
314		if (IS_DUALBUS(isp)) {
315			sdp++;
316			l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT);
317			l &= ISP1080_MODE_MASK;
318			switch(l) {
319			case ISP1080_LVD_MODE:
320				sdp->isp_lvdmode = 1;
321				isp_prt(isp, ISP_LOGCONFIG, m, 1, "LVD");
322				break;
323			case ISP1080_HVD_MODE:
324				sdp->isp_diffmode = 1;
325				isp_prt(isp, ISP_LOGCONFIG,
326				    m, 1, "Differential");
327				break;
328			case ISP1080_SE_MODE:
329				sdp->isp_ultramode = 1;
330				isp_prt(isp, ISP_LOGCONFIG,
331				    m, 1, "Single-Ended");
332				break;
333			default:
334				isp_prt(isp, ISP_LOGERR,
335				    "unknown mode on bus %d (0x%x)", 1, l);
336				break;
337			}
338		}
339	} else {
340		sdparam *sdp = isp->isp_param;
341		i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK;
342		switch (i) {
343		default:
344			isp_prt(isp, ISP_LOGALL, "Unknown Chip Type 0x%x", i);
345			/* FALLTHROUGH */
346		case 1:
347			btype = "1020";
348			isp->isp_type = ISP_HA_SCSI_1020;
349			isp->isp_clock = 40;
350			break;
351		case 2:
352			/*
353			 * Some 1020A chips are Ultra Capable, but don't
354			 * run the clock rate up for that unless told to
355			 * do so by the Ultra Capable bits being set.
356			 */
357			btype = "1020A";
358			isp->isp_type = ISP_HA_SCSI_1020A;
359			isp->isp_clock = 40;
360			break;
361		case 3:
362			btype = "1040";
363			isp->isp_type = ISP_HA_SCSI_1040;
364			isp->isp_clock = 60;
365			break;
366		case 4:
367			btype = "1040A";
368			isp->isp_type = ISP_HA_SCSI_1040A;
369			isp->isp_clock = 60;
370			break;
371		case 5:
372			btype = "1040B";
373			isp->isp_type = ISP_HA_SCSI_1040B;
374			isp->isp_clock = 60;
375			break;
376		case 6:
377			btype = "1040C";
378			isp->isp_type = ISP_HA_SCSI_1040C;
379			isp->isp_clock = 60;
380                        break;
381		}
382		/*
383		 * Now, while we're at it, gather info about ultra
384		 * and/or differential mode.
385		 */
386		if (ISP_READ(isp, SXP_PINS_DIFF) & SXP_PINS_DIFF_MODE) {
387			isp_prt(isp, ISP_LOGCONFIG, "Differential Mode");
388			sdp->isp_diffmode = 1;
389		} else {
390			sdp->isp_diffmode = 0;
391		}
392		i = ISP_READ(isp, RISC_PSR);
393		if (isp->isp_bustype == ISP_BT_SBUS) {
394			i &= RISC_PSR_SBUS_ULTRA;
395		} else {
396			i &= RISC_PSR_PCI_ULTRA;
397		}
398		if (i != 0) {
399			isp_prt(isp, ISP_LOGCONFIG, "Ultra Mode Capable");
400			sdp->isp_ultramode = 1;
401			/*
402			 * If we're in Ultra Mode, we have to be 60Mhz clock-
403			 * even for the SBus version.
404			 */
405			isp->isp_clock = 60;
406		} else {
407			sdp->isp_ultramode = 0;
408			/*
409			 * Clock is known. Gronk.
410			 */
411		}
412
413		/*
414		 * Machine dependent clock (if set) overrides
415		 * our generic determinations.
416		 */
417		if (isp->isp_mdvec->dv_clock) {
418			if (isp->isp_mdvec->dv_clock < isp->isp_clock) {
419				isp->isp_clock = isp->isp_mdvec->dv_clock;
420			}
421		}
422
423	}
424
425	/*
426	 * Clear instrumentation
427	 */
428	isp->isp_intcnt = isp->isp_intbogus = 0;
429
430	/*
431	 * Do MD specific pre initialization
432	 */
433	ISP_RESET0(isp);
434
435again:
436
437	/*
438	 * Hit the chip over the head with hammer,
439	 * and give the ISP a chance to recover.
440	 */
441
442	if (IS_SCSI(isp)) {
443		ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET);
444		/*
445		 * A slight delay...
446		 */
447		USEC_DELAY(100);
448
449		/*
450		 * Clear data && control DMA engines.
451		 */
452		ISP_WRITE(isp, CDMA_CONTROL,
453		    DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
454		ISP_WRITE(isp, DDMA_CONTROL,
455		    DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
456
457
458	} else {
459		ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
460		/*
461		 * A slight delay...
462		 */
463		USEC_DELAY(100);
464
465		/*
466		 * Clear data && control DMA engines.
467		 */
468		ISP_WRITE(isp, CDMA2100_CONTROL,
469			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
470		ISP_WRITE(isp, TDMA2100_CONTROL,
471			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
472		ISP_WRITE(isp, RDMA2100_CONTROL,
473			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
474	}
475
476	/*
477	 * Wait for ISP to be ready to go...
478	 */
479	loops = MBOX_DELAY_COUNT;
480	for (;;) {
481		if (IS_SCSI(isp)) {
482			if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET))
483				break;
484		} else {
485			if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET))
486				break;
487		}
488		USEC_DELAY(100);
489		if (--loops < 0) {
490			ISP_DUMPREGS(isp, "chip reset timed out");
491			return;
492		}
493	}
494
495	/*
496	 * After we've fired this chip up, zero out the conf1 register
497	 * for SCSI adapters and other settings for the 2100.
498	 */
499
500	if (IS_SCSI(isp)) {
501		ISP_WRITE(isp, BIU_CONF1, 0);
502	} else {
503		ISP_WRITE(isp, BIU2100_CSR, 0);
504	}
505
506	/*
507	 * Reset RISC Processor
508	 */
509	ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
510	USEC_DELAY(100);
511	/* Clear semaphore register (just to be sure) */
512	ISP_WRITE(isp, BIU_SEMA, 0);
513
514	/*
515	 * Establish some initial burst rate stuff.
516	 * (only for the 1XX0 boards). This really should
517	 * be done later after fetching from NVRAM.
518	 */
519	if (IS_SCSI(isp)) {
520		u_int16_t tmp = isp->isp_mdvec->dv_conf1;
521		/*
522		 * Busted FIFO. Turn off all but burst enables.
523		 */
524		if (isp->isp_type == ISP_HA_SCSI_1040A) {
525			tmp &= BIU_BURST_ENABLE;
526		}
527		ISP_SETBITS(isp, BIU_CONF1, tmp);
528		if (tmp & BIU_BURST_ENABLE) {
529			ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
530			ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
531		}
532#ifdef	PTI_CARDS
533		if (((sdparam *) isp->isp_param)->isp_ultramode) {
534			while (ISP_READ(isp, RISC_MTR) != 0x1313) {
535				ISP_WRITE(isp, RISC_MTR, 0x1313);
536				ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
537			}
538		} else {
539			ISP_WRITE(isp, RISC_MTR, 0x1212);
540		}
541		/*
542		 * PTI specific register
543		 */
544		ISP_WRITE(isp, RISC_EMB, DUAL_BANK)
545#else
546		ISP_WRITE(isp, RISC_MTR, 0x1212);
547#endif
548	} else {
549		ISP_WRITE(isp, RISC_MTR2100, 0x1212);
550		if (IS_2200(isp) || IS_23XX(isp)) {
551			ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE);
552		}
553	}
554
555	ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); /* release paused processor */
556
557	/*
558	 * Do MD specific post initialization
559	 */
560	ISP_RESET1(isp);
561
562	/*
563	 * Wait for everything to finish firing up.
564	 *
565	 * Avoid doing this on the 2312 because you can generate a PCI
566	 * parity error (chip breakage).
567	 */
568	if (IS_23XX(isp)) {
569		USEC_DELAY(5);
570	} else {
571		loops = MBOX_DELAY_COUNT;
572		while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
573			USEC_DELAY(100);
574			if (--loops < 0) {
575				isp_prt(isp, ISP_LOGERR,
576				    "MBOX_BUSY never cleared on reset");
577				return;
578			}
579		}
580	}
581
582	/*
583	 * Up until this point we've done everything by just reading or
584	 * setting registers. From this point on we rely on at least *some*
585	 * kind of firmware running in the card.
586	 */
587
588	/*
589	 * Do some sanity checking.
590	 */
591	mbs.param[0] = MBOX_NO_OP;
592	isp_mboxcmd(isp, &mbs, MBLOGALL);
593	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
594		return;
595	}
596
597	if (IS_SCSI(isp)) {
598		mbs.param[0] = MBOX_MAILBOX_REG_TEST;
599		mbs.param[1] = 0xdead;
600		mbs.param[2] = 0xbeef;
601		mbs.param[3] = 0xffff;
602		mbs.param[4] = 0x1111;
603		mbs.param[5] = 0xa5a5;
604		isp_mboxcmd(isp, &mbs, MBLOGALL);
605		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
606			return;
607		}
608		if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef ||
609		    mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 ||
610		    mbs.param[5] != 0xa5a5) {
611			isp_prt(isp, ISP_LOGERR,
612			    "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)",
613			    mbs.param[1], mbs.param[2], mbs.param[3],
614			    mbs.param[4], mbs.param[5]);
615			return;
616		}
617
618	}
619
620	/*
621	 * Download new Firmware, unless requested not to do so.
622	 * This is made slightly trickier in some cases where the
623	 * firmware of the ROM revision is newer than the revision
624	 * compiled into the driver. So, where we used to compare
625	 * versions of our f/w and the ROM f/w, now we just see
626	 * whether we have f/w at all and whether a config flag
627	 * has disabled our download.
628	 */
629	if ((isp->isp_mdvec->dv_ispfw == NULL) ||
630	    (isp->isp_confopts & ISP_CFG_NORELOAD)) {
631		dodnld = 0;
632	}
633
634	if (IS_23XX(isp))
635		code_org = ISP_CODE_ORG_2300;
636	else
637		code_org = ISP_CODE_ORG;
638
639	if (dodnld) {
640		isp->isp_mbxworkp = (void *) &isp->isp_mdvec->dv_ispfw[1];
641		isp->isp_mbxwrk0 = isp->isp_mdvec->dv_ispfw[3] - 1;
642		isp->isp_mbxwrk1 = code_org + 1;
643		mbs.param[0] = MBOX_WRITE_RAM_WORD;
644		mbs.param[1] = code_org;
645		mbs.param[2] = isp->isp_mdvec->dv_ispfw[0];
646		isp_mboxcmd(isp, &mbs, MBLOGNONE);
647		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
648			isp_prt(isp, ISP_LOGERR,
649			    "F/W download failed at word %d",
650			    isp->isp_mbxwrk1 - code_org);
651			dodnld = 0;
652			goto again;
653		}
654		/*
655		 * Verify that it downloaded correctly.
656		 */
657		mbs.param[0] = MBOX_VERIFY_CHECKSUM;
658		mbs.param[1] = code_org;
659		isp_mboxcmd(isp, &mbs, MBLOGNONE);
660		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
661			isp_prt(isp, ISP_LOGERR, "Ram Checksum Failure");
662			return;
663		}
664		isp->isp_loaded_fw = 1;
665	} else {
666		isp->isp_loaded_fw = 0;
667		isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
668	}
669
670	/*
671	 * Now start it rolling.
672	 *
673	 * If we didn't actually download f/w,
674	 * we still need to (re)start it.
675	 */
676
677
678	mbs.param[0] = MBOX_EXEC_FIRMWARE;
679	mbs.param[1] = code_org;
680	isp_mboxcmd(isp, &mbs, MBLOGNONE);
681	/*
682	 * Give it a chance to start.
683	 */
684	USEC_DELAY(500);
685
686	if (IS_SCSI(isp)) {
687		/*
688		 * Set CLOCK RATE, but only if asked to.
689		 */
690		if (isp->isp_clock) {
691			mbs.param[0] = MBOX_SET_CLOCK_RATE;
692			mbs.param[1] = isp->isp_clock;
693			isp_mboxcmd(isp, &mbs, MBLOGALL);
694			/* we will try not to care if this fails */
695		}
696	}
697
698	mbs.param[0] = MBOX_ABOUT_FIRMWARE;
699	isp_mboxcmd(isp, &mbs, MBLOGALL);
700	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
701		return;
702	}
703
704	/*
705	 * The SBus firmware that we are using apparently does not return
706	 * major, minor, micro revisions in the mailbox registers, which
707	 * is really, really, annoying.
708	 */
709	if (ISP_SBUS_SUPPORTED && isp->isp_bustype == ISP_BT_SBUS) {
710		if (dodnld) {
711#ifdef	ISP_TARGET_MODE
712			isp->isp_fwrev[0] = 7;
713			isp->isp_fwrev[1] = 55;
714#else
715			isp->isp_fwrev[0] = 1;
716			isp->isp_fwrev[1] = 37;
717#endif
718			isp->isp_fwrev[2] = 0;
719		}
720	} else {
721		isp->isp_fwrev[0] = mbs.param[1];
722		isp->isp_fwrev[1] = mbs.param[2];
723		isp->isp_fwrev[2] = mbs.param[3];
724	}
725	isp_prt(isp, ISP_LOGCONFIG,
726	    "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
727	    btype, isp->isp_revision, dodnld? "loaded" : "resident",
728	    isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
729
730	if (IS_FC(isp)) {
731		/*
732		 * We do not believe firmware attributes for 2100 code less
733		 * than 1.17.0, unless it's the firmware we specifically
734		 * are loading.
735		 *
736		 * Note that all 22XX and 23XX f/w is greater than 1.X.0.
737		 */
738		if (!(ISP_FW_NEWER_THAN(isp, 1, 17, 0))) {
739#ifdef	USE_SMALLER_2100_FIRMWARE
740			FCPARAM(isp)->isp_fwattr = ISP_FW_ATTR_SCCLUN;
741#else
742			FCPARAM(isp)->isp_fwattr = 0;
743#endif
744		} else {
745			FCPARAM(isp)->isp_fwattr = mbs.param[6];
746			isp_prt(isp, ISP_LOGDEBUG0,
747			    "Firmware Attributes = 0x%x", mbs.param[6]);
748		}
749		if (ISP_READ(isp, BIU2100_CSR) & BIU2100_PCI64) {
750			isp_prt(isp, ISP_LOGCONFIG,
751			    "Installed in 64-Bit PCI slot");
752		}
753	}
754
755	if (isp->isp_romfw_rev[0] || isp->isp_romfw_rev[1] ||
756	    isp->isp_romfw_rev[2]) {
757		isp_prt(isp, ISP_LOGCONFIG, "Last F/W revision was %d.%d.%d",
758		    isp->isp_romfw_rev[0], isp->isp_romfw_rev[1],
759		    isp->isp_romfw_rev[2]);
760	}
761
762	mbs.param[0] = MBOX_GET_FIRMWARE_STATUS;
763	isp_mboxcmd(isp, &mbs, MBLOGALL);
764	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
765		return;
766	}
767	isp->isp_maxcmds = mbs.param[2];
768	isp_prt(isp, ISP_LOGINFO,
769	    "%d max I/O commands supported", mbs.param[2]);
770	isp_fw_state(isp);
771
772	/*
773	 * Set up DMA for the request and result mailboxes.
774	 */
775	if (ISP_MBOXDMASETUP(isp) != 0) {
776		isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
777		return;
778	}
779	isp->isp_state = ISP_RESETSTATE;
780
781	/*
782	 * Okay- now that we have new firmware running, we now (re)set our
783	 * notion of how many luns we support. This is somewhat tricky because
784	 * if we haven't loaded firmware, we sometimes do not have an easy way
785	 * of knowing how many luns we support.
786	 *
787	 * Expanded lun firmware gives you 32 luns for SCSI cards and
788	 * 16384 luns for Fibre Channel cards.
789	 *
790	 * It turns out that even for QLogic 2100s with ROM 1.10 and above
791	 * we do get a firmware attributes word returned in mailbox register 6.
792	 *
793	 * Because the lun is in a a different position in the Request Queue
794	 * Entry structure for Fibre Channel with expanded lun firmware, we
795	 * can only support one lun (lun zero) when we don't know what kind
796	 * of firmware we're running.
797	 *
798	 * Note that we only do this once (the first time thru isp_reset)
799	 * because we may be called again after firmware has been loaded once
800	 * and released.
801	 */
802	if (IS_SCSI(isp)) {
803		if (dodnld) {
804			if (IS_ULTRA2(isp) || IS_ULTRA3(isp)) {
805				isp->isp_maxluns = 32;
806			} else {
807				isp->isp_maxluns = 8;
808			}
809		} else {
810			isp->isp_maxluns = 8;
811		}
812	} else {
813		if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
814			isp->isp_maxluns = 16384;
815		} else {
816			isp->isp_maxluns = 16;
817		}
818	}
819}
820
821/*
822 * Initialize Parameters of Hardware to a known state.
823 *
824 * Locks are held before coming here.
825 */
826
827void
828isp_init(struct ispsoftc *isp)
829{
830	/*
831	 * Must do this first to get defaults established.
832	 */
833	isp_setdfltparm(isp, 0);
834	if (IS_DUALBUS(isp)) {
835		isp_setdfltparm(isp, 1);
836	}
837	if (IS_FC(isp)) {
838		isp_fibre_init(isp);
839	} else {
840		isp_scsi_init(isp);
841	}
842}
843
844static void
845isp_scsi_init(struct ispsoftc *isp)
846{
847	sdparam *sdp_chan0, *sdp_chan1;
848	mbreg_t mbs;
849
850	sdp_chan0 = isp->isp_param;
851	sdp_chan1 = sdp_chan0;
852	if (IS_DUALBUS(isp)) {
853		sdp_chan1++;
854	}
855
856	/*
857	 * If we have no role (neither target nor initiator), return.
858	 */
859	if (isp->isp_role == ISP_ROLE_NONE) {
860		return;
861	}
862
863	/* First do overall per-card settings. */
864
865	/*
866	 * If we have fast memory timing enabled, turn it on.
867	 */
868	if (sdp_chan0->isp_fast_mttr) {
869		ISP_WRITE(isp, RISC_MTR, 0x1313);
870	}
871
872	/*
873	 * Set Retry Delay and Count.
874	 * You set both channels at the same time.
875	 */
876	mbs.param[0] = MBOX_SET_RETRY_COUNT;
877	mbs.param[1] = sdp_chan0->isp_retry_count;
878	mbs.param[2] = sdp_chan0->isp_retry_delay;
879	mbs.param[6] = sdp_chan1->isp_retry_count;
880	mbs.param[7] = sdp_chan1->isp_retry_delay;
881
882	isp_mboxcmd(isp, &mbs, MBLOGALL);
883	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
884		return;
885	}
886
887	/*
888	 * Set ASYNC DATA SETUP time. This is very important.
889	 */
890	mbs.param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME;
891	mbs.param[1] = sdp_chan0->isp_async_data_setup;
892	mbs.param[2] = sdp_chan1->isp_async_data_setup;
893	isp_mboxcmd(isp, &mbs, MBLOGALL);
894	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
895		return;
896	}
897
898	/*
899	 * Set ACTIVE Negation State.
900	 */
901	mbs.param[0] = MBOX_SET_ACT_NEG_STATE;
902	mbs.param[1] =
903	    (sdp_chan0->isp_req_ack_active_neg << 4) |
904	    (sdp_chan0->isp_data_line_active_neg << 5);
905	mbs.param[2] =
906	    (sdp_chan1->isp_req_ack_active_neg << 4) |
907	    (sdp_chan1->isp_data_line_active_neg << 5);
908
909	isp_mboxcmd(isp, &mbs, MBLOGNONE);
910	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
911		isp_prt(isp, ISP_LOGERR,
912		    "failed to set active negation state (%d,%d), (%d,%d)",
913		    sdp_chan0->isp_req_ack_active_neg,
914		    sdp_chan0->isp_data_line_active_neg,
915		    sdp_chan1->isp_req_ack_active_neg,
916		    sdp_chan1->isp_data_line_active_neg);
917		/*
918		 * But don't return.
919		 */
920	}
921
922	/*
923	 * Set the Tag Aging limit
924	 */
925	mbs.param[0] = MBOX_SET_TAG_AGE_LIMIT;
926	mbs.param[1] = sdp_chan0->isp_tag_aging;
927	mbs.param[2] = sdp_chan1->isp_tag_aging;
928	isp_mboxcmd(isp, &mbs, MBLOGALL);
929	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
930		isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)",
931		    sdp_chan0->isp_tag_aging, sdp_chan1->isp_tag_aging);
932		return;
933	}
934
935	/*
936	 * Set selection timeout.
937	 */
938	mbs.param[0] = MBOX_SET_SELECT_TIMEOUT;
939	mbs.param[1] = sdp_chan0->isp_selection_timeout;
940	mbs.param[2] = sdp_chan1->isp_selection_timeout;
941	isp_mboxcmd(isp, &mbs, MBLOGALL);
942	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
943		return;
944	}
945
946	/* now do per-channel settings */
947	isp_scsi_channel_init(isp, 0);
948	if (IS_DUALBUS(isp))
949		isp_scsi_channel_init(isp, 1);
950
951	/*
952	 * Now enable request/response queues
953	 */
954
955	if (IS_ULTRA2(isp) || IS_1240(isp)) {
956		mbs.param[0] = MBOX_INIT_RES_QUEUE_A64;
957		mbs.param[1] = RESULT_QUEUE_LEN(isp);
958		mbs.param[2] = DMA_WD1(isp->isp_result_dma);
959		mbs.param[3] = DMA_WD0(isp->isp_result_dma);
960		mbs.param[4] = 0;
961		mbs.param[6] = DMA_WD3(isp->isp_result_dma);
962		mbs.param[7] = DMA_WD2(isp->isp_result_dma);
963		isp_mboxcmd(isp, &mbs, MBLOGALL);
964		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
965			return;
966		}
967		isp->isp_residx = mbs.param[5];
968
969		mbs.param[0] = MBOX_INIT_REQ_QUEUE_A64;
970		mbs.param[1] = RQUEST_QUEUE_LEN(isp);
971		mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
972		mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
973		mbs.param[5] = 0;
974		mbs.param[6] = DMA_WD3(isp->isp_result_dma);
975		mbs.param[7] = DMA_WD2(isp->isp_result_dma);
976		isp_mboxcmd(isp, &mbs, MBLOGALL);
977		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
978			return;
979		}
980		isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
981	} else {
982		mbs.param[0] = MBOX_INIT_RES_QUEUE;
983		mbs.param[1] = RESULT_QUEUE_LEN(isp);
984		mbs.param[2] = DMA_WD1(isp->isp_result_dma);
985		mbs.param[3] = DMA_WD0(isp->isp_result_dma);
986		mbs.param[4] = 0;
987		isp_mboxcmd(isp, &mbs, MBLOGALL);
988		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
989			return;
990		}
991		isp->isp_residx = mbs.param[5];
992
993		mbs.param[0] = MBOX_INIT_REQ_QUEUE;
994		mbs.param[1] = RQUEST_QUEUE_LEN(isp);
995		mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
996		mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
997		mbs.param[5] = 0;
998		isp_mboxcmd(isp, &mbs, MBLOGALL);
999		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1000			return;
1001		}
1002		isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
1003	}
1004
1005	/*
1006	 * Turn on Fast Posting, LVD transitions
1007	 *
1008	 * Ultra2 F/W always has had fast posting (and LVD transitions)
1009	 *
1010	 * Ultra and older (i.e., SBus) cards may not. It's just safer
1011	 * to assume not for them.
1012	 */
1013
1014	mbs.param[0] = MBOX_SET_FW_FEATURES;
1015	mbs.param[1] = 0;
1016	if (IS_ULTRA2(isp))
1017		mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
1018#ifndef	ISP_NO_RIO
1019	if (IS_ULTRA2(isp) || IS_1240(isp))
1020		mbs.param[1] |= FW_FEATURE_RIO_16BIT;
1021#else
1022#ifndef	ISP_NO_FASTPOST
1023	if (IS_ULTRA2(isp) || IS_1240(isp))
1024		mbs.param[1] |= FW_FEATURE_FAST_POST;
1025#endif
1026#endif
1027	if (mbs.param[1] != 0) {
1028		u_int16_t sfeat = mbs.param[1];
1029		isp_mboxcmd(isp, &mbs, MBLOGALL);
1030		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1031			isp_prt(isp, ISP_LOGINFO,
1032			    "Enabled FW features (0x%x)", sfeat);
1033		}
1034	}
1035
1036	/*
1037	 * Let the outer layers decide whether to issue a SCSI bus reset.
1038	 */
1039	isp->isp_state = ISP_INITSTATE;
1040}
1041
1042static void
1043isp_scsi_channel_init(struct ispsoftc *isp, int channel)
1044{
1045	sdparam *sdp;
1046	mbreg_t mbs;
1047	int tgt;
1048
1049	sdp = isp->isp_param;
1050	sdp += channel;
1051
1052	/*
1053	 * Set (possibly new) Initiator ID.
1054	 */
1055	mbs.param[0] = MBOX_SET_INIT_SCSI_ID;
1056	mbs.param[1] = (channel << 7) | sdp->isp_initiator_id;
1057	isp_mboxcmd(isp, &mbs, MBLOGALL);
1058	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1059		return;
1060	}
1061	isp_prt(isp, ISP_LOGINFO, "Initiator ID is %d on Channel %d",
1062	    sdp->isp_initiator_id, channel);
1063
1064
1065	/*
1066	 * Set current per-target parameters to an initial safe minimum.
1067	 */
1068	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
1069		int lun;
1070		u_int16_t sdf;
1071
1072		if (sdp->isp_devparam[tgt].dev_enable == 0) {
1073			continue;
1074		}
1075#ifndef	ISP_TARGET_MODE
1076		sdf = sdp->isp_devparam[tgt].goal_flags;
1077		sdf &= DPARM_SAFE_DFLT;
1078		/*
1079		 * It is not quite clear when this changed over so that
1080		 * we could force narrow and async for 1000/1020 cards,
1081		 * but assume that this is only the case for loaded
1082		 * firmware.
1083		 */
1084		if (isp->isp_loaded_fw) {
1085			sdf |= DPARM_NARROW | DPARM_ASYNC;
1086		}
1087#else
1088		/*
1089		 * The !$*!)$!$)* f/w uses the same index into some
1090		 * internal table to decide how to respond to negotiations,
1091		 * so if we've said "let's be safe" for ID X, and ID X
1092		 * selects *us*, the negotiations will back to 'safe'
1093		 * (as in narrow/async). What the f/w *should* do is
1094		 * use the initiator id settings to decide how to respond.
1095		 */
1096		sdp->isp_devparam[tgt].goal_flags = sdf = DPARM_DEFAULT;
1097#endif
1098		mbs.param[0] = MBOX_SET_TARGET_PARAMS;
1099		mbs.param[1] = (channel << 15) | (tgt << 8);
1100		mbs.param[2] = sdf;
1101		if ((sdf & DPARM_SYNC) == 0) {
1102			mbs.param[3] = 0;
1103		} else {
1104			mbs.param[3] =
1105			    (sdp->isp_devparam[tgt].goal_offset << 8) |
1106			    (sdp->isp_devparam[tgt].goal_period);
1107		}
1108		isp_prt(isp, ISP_LOGDEBUG0,
1109		    "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x",
1110		    channel, tgt, mbs.param[2], mbs.param[3] >> 8,
1111		    mbs.param[3] & 0xff);
1112		isp_mboxcmd(isp, &mbs, MBLOGNONE);
1113		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1114			sdf = DPARM_SAFE_DFLT;
1115			mbs.param[0] = MBOX_SET_TARGET_PARAMS;
1116			mbs.param[1] = (tgt << 8) | (channel << 15);
1117			mbs.param[2] = sdf;
1118			mbs.param[3] = 0;
1119			isp_mboxcmd(isp, &mbs, MBLOGALL);
1120			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1121				continue;
1122			}
1123		}
1124
1125		/*
1126		 * We don't update any information directly from the f/w
1127		 * because we need to run at least one command to cause a
1128		 * new state to be latched up. So, we just assume that we
1129		 * converge to the values we just had set.
1130		 *
1131		 * Ensure that we don't believe tagged queuing is enabled yet.
1132		 * It turns out that sometimes the ISP just ignores our
1133		 * attempts to set parameters for devices that it hasn't
1134		 * seen yet.
1135		 */
1136		sdp->isp_devparam[tgt].actv_flags = sdf & ~DPARM_TQING;
1137		for (lun = 0; lun < (int) isp->isp_maxluns; lun++) {
1138			mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS;
1139			mbs.param[1] = (channel << 15) | (tgt << 8) | lun;
1140			mbs.param[2] = sdp->isp_max_queue_depth;
1141			mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle;
1142			isp_mboxcmd(isp, &mbs, MBLOGALL);
1143			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1144				break;
1145			}
1146		}
1147	}
1148	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
1149		if (sdp->isp_devparam[tgt].dev_refresh) {
1150			isp->isp_sendmarker |= (1 << channel);
1151			isp->isp_update |= (1 << channel);
1152			break;
1153		}
1154	}
1155}
1156
1157/*
1158 * Fibre Channel specific initialization.
1159 *
1160 * Locks are held before coming here.
1161 */
1162static void
1163isp_fibre_init(struct ispsoftc *isp)
1164{
1165	fcparam *fcp;
1166	isp_icb_t local, *icbp = &local;
1167	mbreg_t mbs;
1168	int loopid;
1169	u_int64_t nwwn, pwwn;
1170
1171	fcp = isp->isp_param;
1172
1173	/*
1174	 * Do this *before* initializing the firmware.
1175	 */
1176	isp_mark_getpdb_all(isp);
1177	fcp->isp_fwstate = FW_CONFIG_WAIT;
1178	fcp->isp_loopstate = LOOP_NIL;
1179
1180	/*
1181	 * If we have no role (neither target nor initiator), return.
1182	 */
1183	if (isp->isp_role == ISP_ROLE_NONE) {
1184		return;
1185	}
1186
1187	loopid = fcp->isp_loopid;
1188	MEMZERO(icbp, sizeof (*icbp));
1189	icbp->icb_version = ICB_VERSION1;
1190
1191	/*
1192	 * Firmware Options are either retrieved from NVRAM or
1193	 * are patched elsewhere. We check them for sanity here
1194	 * and make changes based on board revision, but otherwise
1195	 * let others decide policy.
1196	 */
1197
1198	/*
1199	 * If this is a 2100 < revision 5, we have to turn off FAIRNESS.
1200	 */
1201	if ((isp->isp_type == ISP_HA_FC_2100) && isp->isp_revision < 5) {
1202		fcp->isp_fwoptions &= ~ICBOPT_FAIRNESS;
1203	}
1204
1205	/*
1206	 * We have to use FULL LOGIN even though it resets the loop too much
1207	 * because otherwise port database entries don't get updated after
1208	 * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0.
1209	 */
1210	if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
1211		fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN;
1212	}
1213
1214	/*
1215	 * Insist on Port Database Update Async notifications
1216	 */
1217	fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
1218
1219	/*
1220	 * Make sure that target role reflects into fwoptions.
1221	 */
1222	if (isp->isp_role & ISP_ROLE_TARGET) {
1223		fcp->isp_fwoptions |= ICBOPT_TGT_ENABLE;
1224	} else {
1225		fcp->isp_fwoptions &= ~ICBOPT_TGT_ENABLE;
1226	}
1227
1228	/*
1229	 * Propagate all of this into the ICB structure.
1230	 */
1231	icbp->icb_fwoptions = fcp->isp_fwoptions;
1232	icbp->icb_maxfrmlen = fcp->isp_maxfrmlen;
1233	if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN ||
1234	    icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
1235		isp_prt(isp, ISP_LOGERR,
1236		    "bad frame length (%d) from NVRAM- using %d",
1237		    fcp->isp_maxfrmlen, ICB_DFLT_FRMLEN);
1238		icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
1239	}
1240	icbp->icb_maxalloc = fcp->isp_maxalloc;
1241	if (icbp->icb_maxalloc < 1) {
1242		isp_prt(isp, ISP_LOGERR,
1243		    "bad maximum allocation (%d)- using 16", fcp->isp_maxalloc);
1244		icbp->icb_maxalloc = 16;
1245	}
1246	icbp->icb_execthrottle = fcp->isp_execthrottle;
1247	if (icbp->icb_execthrottle < 1) {
1248		isp_prt(isp, ISP_LOGERR,
1249		    "bad execution throttle of %d- using 16",
1250		    fcp->isp_execthrottle);
1251		icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
1252	}
1253	icbp->icb_retry_delay = fcp->isp_retry_delay;
1254	icbp->icb_retry_count = fcp->isp_retry_count;
1255	icbp->icb_hardaddr = loopid;
1256	/*
1257	 * Right now we just set extended options to prefer point-to-point
1258	 * over loop based upon some soft config options.
1259	 *
1260	 * NB: for the 2300, ICBOPT_EXTENDED is required.
1261	 */
1262	if (IS_2200(isp) || IS_23XX(isp)) {
1263		icbp->icb_fwoptions |= ICBOPT_EXTENDED;
1264		/*
1265		 * Prefer or force Point-To-Point instead Loop?
1266		 */
1267		switch(isp->isp_confopts & ISP_CFG_PORT_PREF) {
1268		case ISP_CFG_NPORT:
1269			icbp->icb_xfwoptions |= ICBXOPT_PTP_2_LOOP;
1270			break;
1271		case ISP_CFG_NPORT_ONLY:
1272			icbp->icb_xfwoptions |= ICBXOPT_PTP_ONLY;
1273			break;
1274		case ISP_CFG_LPORT_ONLY:
1275			icbp->icb_xfwoptions |= ICBXOPT_LOOP_ONLY;
1276			break;
1277		default:
1278			icbp->icb_xfwoptions |= ICBXOPT_LOOP_2_PTP;
1279			break;
1280		}
1281		if (IS_23XX(isp)) {
1282			/*
1283			 * QLogic recommends that FAST Posting be turned
1284			 * off for 23XX cards and instead allow the HBA
1285			 * to write response queue entries and interrupt
1286			 * after a delay (ZIO).
1287			 *
1288			 * If we set ZIO, it will disable fast posting,
1289			 * so we don't need to clear it in fwoptions.
1290			 */
1291			icbp->icb_xfwoptions |= ICBXOPT_ZIO;
1292
1293			if (isp->isp_confopts & ISP_CFG_ONEGB) {
1294				icbp->icb_zfwoptions |= ICBZOPT_RATE_ONEGB;
1295			} else if (isp->isp_confopts & ISP_CFG_TWOGB) {
1296				icbp->icb_zfwoptions |= ICBZOPT_RATE_TWOGB;
1297			} else {
1298				icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO;
1299			}
1300		}
1301	}
1302
1303#ifndef	ISP_NO_RIO_FC
1304	/*
1305	 * RIO seems to be enabled in 2100s for fw >= 1.17.0.
1306	 *
1307	 * I've had some questionable problems with RIO on 2200.
1308	 * More specifically, on a 2204 I had problems with RIO
1309	 * on a Linux system where I was dropping commands right
1310	 * and left. It's not clear to me what the actual problem
1311	 * was.
1312	 *
1313	 * 23XX Cards do not support RIO. Instead they support ZIO.
1314	 */
1315#if	0
1316	if (!IS_23XX(isp) && ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
1317		icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT;
1318		icbp->icb_racctimer = 4;
1319		icbp->icb_idelaytimer = 8;
1320	}
1321#endif
1322#endif
1323
1324	/*
1325	 * For 22XX > 2.1.26 && 23XX, set someoptions.
1326	 * XXX: Probably okay for newer 2100 f/w too.
1327	 */
1328	if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) {
1329		/*
1330		 * Turn on LIP F8 async event (1)
1331		 * Turn on generate AE 8013 on all LIP Resets (2)
1332		 * Disable LIP F7 switching (8)
1333		 */
1334		mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS;
1335		mbs.param[1] = 0xb;
1336		mbs.param[2] = 0;
1337		mbs.param[3] = 0;
1338		isp_mboxcmd(isp, &mbs, MBLOGALL);
1339	}
1340	icbp->icb_logintime = 30;	/* 30 second login timeout */
1341
1342	if (IS_23XX(isp)) {
1343		ISP_WRITE(isp, isp->isp_rqstinrp, 0);
1344        	ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
1345        	ISP_WRITE(isp, isp->isp_respinrp, 0);
1346		ISP_WRITE(isp, isp->isp_respoutrp, 0);
1347	}
1348
1349	nwwn = ISP_NODEWWN(isp);
1350	pwwn = ISP_PORTWWN(isp);
1351	if (nwwn && pwwn) {
1352		icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS;
1353		MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, nwwn);
1354		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn);
1355		isp_prt(isp, ISP_LOGDEBUG1,
1356		    "Setting ICB Node 0x%08x%08x Port 0x%08x%08x",
1357		    ((u_int32_t) (nwwn >> 32)),
1358		    ((u_int32_t) (nwwn & 0xffffffff)),
1359		    ((u_int32_t) (pwwn >> 32)),
1360		    ((u_int32_t) (pwwn & 0xffffffff)));
1361	} else {
1362		isp_prt(isp, ISP_LOGDEBUG1, "Not using any WWNs");
1363		icbp->icb_fwoptions &= ~(ICBOPT_BOTH_WWNS|ICBOPT_FULL_LOGIN);
1364	}
1365	icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
1366	icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
1367	icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
1368	icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
1369	icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
1370	icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
1371	icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
1372	icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
1373	icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
1374	icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
1375	isp_prt(isp, ISP_LOGDEBUG0,
1376	    "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x",
1377	    icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions);
1378
1379	FC_SCRATCH_ACQUIRE(isp);
1380	isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch);
1381
1382	/*
1383	 * Init the firmware
1384	 */
1385	mbs.param[0] = MBOX_INIT_FIRMWARE;
1386	mbs.param[1] = 0;
1387	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1388	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1389	mbs.param[4] = 0;
1390	mbs.param[5] = 0;
1391	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
1392	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
1393	isp_mboxcmd(isp, &mbs, MBLOGALL);
1394	FC_SCRATCH_RELEASE(isp);
1395	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1396		return;
1397	}
1398	isp->isp_reqidx = isp->isp_reqodx = 0;
1399	isp->isp_residx = 0;
1400	isp->isp_sendmarker = 1;
1401
1402	/*
1403	 * Whatever happens, we're now committed to being here.
1404	 */
1405	isp->isp_state = ISP_INITSTATE;
1406}
1407
1408/*
1409 * Fibre Channel Support- get the port database for the id.
1410 *
1411 * Locks are held before coming here. Return 0 if success,
1412 * else failure.
1413 */
1414
1415static int
1416isp_getmap(struct ispsoftc *isp, fcpos_map_t *map)
1417{
1418	fcparam *fcp = (fcparam *) isp->isp_param;
1419	mbreg_t mbs;
1420
1421	mbs.param[0] = MBOX_GET_FC_AL_POSITION_MAP;
1422	mbs.param[1] = 0;
1423	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1424	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1425	/*
1426	 * Unneeded. For the 2100, except for initializing f/w, registers
1427	 * 4/5 have to not be written to.
1428	 *	mbs.param[4] = 0;
1429	 *	mbs.param[5] = 0;
1430	 *
1431	 */
1432	mbs.param[6] = 0;
1433	mbs.param[7] = 0;
1434	FC_SCRATCH_ACQUIRE(isp);
1435	isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
1436	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1437		MEMCPY(map, fcp->isp_scratch, sizeof (fcpos_map_t));
1438		map->fwmap = mbs.param[1] != 0;
1439		FC_SCRATCH_RELEASE(isp);
1440		return (0);
1441	}
1442	FC_SCRATCH_RELEASE(isp);
1443	return (-1);
1444}
1445
1446static void
1447isp_mark_getpdb_all(struct ispsoftc *isp)
1448{
1449	fcparam *fcp = (fcparam *) isp->isp_param;
1450	int i;
1451	for (i = 0; i < MAX_FC_TARG; i++) {
1452		fcp->portdb[i].valid = fcp->portdb[i].fabric_dev = 0;
1453	}
1454}
1455
1456static int
1457isp_getpdb(struct ispsoftc *isp, int id, isp_pdb_t *pdbp)
1458{
1459	fcparam *fcp = (fcparam *) isp->isp_param;
1460	mbreg_t mbs;
1461
1462	mbs.param[0] = MBOX_GET_PORT_DB;
1463	mbs.param[1] = id << 8;
1464	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1465	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1466	/*
1467	 * Unneeded. For the 2100, except for initializing f/w, registers
1468	 * 4/5 have to not be written to.
1469	 *	mbs.param[4] = 0;
1470	 *	mbs.param[5] = 0;
1471	 *
1472	 */
1473	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
1474	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
1475	FC_SCRATCH_ACQUIRE(isp);
1476	isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
1477	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1478		isp_get_pdb(isp, (isp_pdb_t *)fcp->isp_scratch, pdbp);
1479		FC_SCRATCH_RELEASE(isp);
1480		return (0);
1481	}
1482	FC_SCRATCH_RELEASE(isp);
1483	return (-1);
1484}
1485
1486static u_int64_t
1487isp_get_portname(struct ispsoftc *isp, int loopid, int nodename)
1488{
1489	u_int64_t wwn = 0;
1490	mbreg_t mbs;
1491
1492	mbs.param[0] = MBOX_GET_PORT_NAME;
1493	mbs.param[1] = loopid << 8;
1494	if (nodename)
1495		mbs.param[1] |= 1;
1496	isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
1497	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1498		wwn =
1499		    (((u_int64_t)(mbs.param[2] & 0xff)) << 56) |
1500		    (((u_int64_t)(mbs.param[2] >> 8))	<< 48) |
1501		    (((u_int64_t)(mbs.param[3] & 0xff))	<< 40) |
1502		    (((u_int64_t)(mbs.param[3] >> 8))	<< 32) |
1503		    (((u_int64_t)(mbs.param[6] & 0xff))	<< 24) |
1504		    (((u_int64_t)(mbs.param[6] >> 8))	<< 16) |
1505		    (((u_int64_t)(mbs.param[7] & 0xff))	<<  8) |
1506		    (((u_int64_t)(mbs.param[7] >> 8)));
1507	}
1508	return (wwn);
1509}
1510
1511/*
1512 * Make sure we have good FC link and know our Loop ID.
1513 */
1514
1515static int
1516isp_fclink_test(struct ispsoftc *isp, int usdelay)
1517{
1518	static char *toponames[] = {
1519		"Private Loop",
1520		"FL Port",
1521		"N-Port to N-Port",
1522		"F Port",
1523		"F Port (no FLOGI_ACC response)"
1524	};
1525	mbreg_t mbs;
1526	int count, check_for_fabric;
1527	u_int8_t lwfs;
1528	fcparam *fcp;
1529	struct lportdb *lp;
1530	isp_pdb_t pdb;
1531
1532	fcp = isp->isp_param;
1533
1534	/*
1535	 * XXX: Here is where we would start a 'loop dead' timeout
1536	 */
1537
1538	/*
1539	 * Wait up to N microseconds for F/W to go to a ready state.
1540	 */
1541	lwfs = FW_CONFIG_WAIT;
1542	count = 0;
1543	while (count < usdelay) {
1544		u_int64_t enano;
1545		u_int32_t wrk;
1546		NANOTIME_T hra, hrb;
1547
1548		GET_NANOTIME(&hra);
1549		isp_fw_state(isp);
1550		if (lwfs != fcp->isp_fwstate) {
1551			isp_prt(isp, ISP_LOGINFO, "Firmware State <%s->%s>",
1552			    isp2100_fw_statename((int)lwfs),
1553			    isp2100_fw_statename((int)fcp->isp_fwstate));
1554			lwfs = fcp->isp_fwstate;
1555		}
1556		if (fcp->isp_fwstate == FW_READY) {
1557			break;
1558		}
1559		GET_NANOTIME(&hrb);
1560
1561		/*
1562		 * Get the elapsed time in nanoseconds.
1563		 * Always guaranteed to be non-zero.
1564		 */
1565		enano = NANOTIME_SUB(&hrb, &hra);
1566
1567		isp_prt(isp, ISP_LOGDEBUG1,
1568		    "usec%d: 0x%lx->0x%lx enano 0x%x%08x",
1569		    count, (long) GET_NANOSEC(&hra), (long) GET_NANOSEC(&hrb),
1570		    (u_int32_t)(enano >> 32), (u_int32_t)(enano & 0xffffffff));
1571
1572		/*
1573		 * If the elapsed time is less than 1 millisecond,
1574		 * delay a period of time up to that millisecond of
1575		 * waiting.
1576		 *
1577		 * This peculiar code is an attempt to try and avoid
1578		 * invoking u_int64_t math support functions for some
1579		 * platforms where linkage is a problem.
1580		 */
1581		if (enano < (1000 * 1000)) {
1582			count += 1000;
1583			enano = (1000 * 1000) - enano;
1584			while (enano > (u_int64_t) 4000000000U) {
1585				USEC_SLEEP(isp, 4000000);
1586				enano -= (u_int64_t) 4000000000U;
1587			}
1588			wrk = enano;
1589			wrk /= 1000;
1590			USEC_SLEEP(isp, wrk);
1591		} else {
1592			while (enano > (u_int64_t) 4000000000U) {
1593				count += 4000000;
1594				enano -= (u_int64_t) 4000000000U;
1595			}
1596			wrk = enano;
1597			count += (wrk / 1000);
1598		}
1599	}
1600
1601	/*
1602	 * If we haven't gone to 'ready' state, return.
1603	 */
1604	if (fcp->isp_fwstate != FW_READY) {
1605		return (-1);
1606	}
1607
1608	/*
1609	 * Get our Loop ID (if possible). We really need to have it.
1610	 */
1611	mbs.param[0] = MBOX_GET_LOOP_ID;
1612	isp_mboxcmd(isp, &mbs, MBLOGALL);
1613	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1614		return (-1);
1615	}
1616	fcp->isp_loopid = mbs.param[1];
1617	if (IS_2200(isp) || IS_23XX(isp)) {
1618		int topo = (int) mbs.param[6];
1619		if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB)
1620			topo = TOPO_PTP_STUB;
1621		fcp->isp_topo = topo;
1622	} else {
1623		fcp->isp_topo = TOPO_NL_PORT;
1624	}
1625	fcp->isp_portid = fcp->isp_alpa = mbs.param[2] & 0xff;
1626
1627	/*
1628	 * Check to see if we're on a fabric by trying to see if we
1629	 * can talk to the fabric name server. This can be a bit
1630	 * tricky because if we're a 2100, we should check always
1631	 * (in case we're connected to an server doing aliasing).
1632	 */
1633	fcp->isp_onfabric = 0;
1634
1635	if (IS_2100(isp)) {
1636		/*
1637		 * Don't bother with fabric if we are using really old
1638		 * 2100 firmware. It's just not worth it.
1639		 */
1640		if (ISP_FW_NEWER_THAN(isp, 1, 15, 37)) {
1641			check_for_fabric = 1;
1642		} else {
1643			check_for_fabric = 0;
1644		}
1645	} else if (fcp->isp_topo == TOPO_FL_PORT ||
1646	    fcp->isp_topo == TOPO_F_PORT) {
1647		check_for_fabric = 1;
1648	} else
1649		check_for_fabric = 0;
1650
1651	if (check_for_fabric && isp_getpdb(isp, FL_PORT_ID, &pdb) == 0) {
1652		int loopid = FL_PORT_ID;
1653		if (IS_2100(isp)) {
1654			fcp->isp_topo = TOPO_FL_PORT;
1655		}
1656
1657		if (BITS2WORD(pdb.pdb_portid_bits) == 0) {
1658			/*
1659			 * Crock.
1660			 */
1661			fcp->isp_topo = TOPO_NL_PORT;
1662			goto not_on_fabric;
1663		}
1664		fcp->isp_portid = mbs.param[2] | ((int) mbs.param[3] << 16);
1665
1666		/*
1667		 * Save the Fabric controller's port database entry.
1668		 */
1669		lp = &fcp->portdb[loopid];
1670		lp->node_wwn =
1671		    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
1672		    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
1673		    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
1674		    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
1675		    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
1676		    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
1677		    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
1678		    (((u_int64_t)pdb.pdb_nodename[7]));
1679		lp->port_wwn =
1680		    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
1681		    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
1682		    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
1683		    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
1684		    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
1685		    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
1686		    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
1687		    (((u_int64_t)pdb.pdb_portname[7]));
1688		lp->roles =
1689		    (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
1690		lp->portid = BITS2WORD(pdb.pdb_portid_bits);
1691		lp->loopid = pdb.pdb_loopid;
1692		lp->loggedin = lp->valid = 1;
1693		fcp->isp_onfabric = 1;
1694		(void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
1695		isp_register_fc4_type(isp);
1696	} else {
1697not_on_fabric:
1698		fcp->isp_onfabric = 0;
1699		fcp->portdb[FL_PORT_ID].valid = 0;
1700	}
1701
1702	fcp->isp_gbspeed = 1;
1703	if (IS_23XX(isp)) {
1704		mbs.param[0] = MBOX_GET_SET_DATA_RATE;
1705		mbs.param[1] = MBGSD_GET_RATE;
1706		/* mbs.param[2] undefined if we're just getting rate */
1707		isp_mboxcmd(isp, &mbs, MBLOGALL);
1708		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1709			if (mbs.param[1] == MBGSD_TWOGB) {
1710				isp_prt(isp, ISP_LOGINFO, "2Gb link speed/s");
1711				fcp->isp_gbspeed = 2;
1712			}
1713		}
1714	}
1715
1716	isp_prt(isp, ISP_LOGCONFIG, topology, fcp->isp_loopid, fcp->isp_alpa,
1717	    fcp->isp_portid, fcp->isp_loopstate, toponames[fcp->isp_topo]);
1718
1719	/*
1720	 * Announce ourselves, too. This involves synthesizing an entry.
1721	 */
1722	if (fcp->isp_iid_set == 0) {
1723		fcp->isp_iid_set = 1;
1724		fcp->isp_iid = fcp->isp_loopid;
1725		lp = &fcp->portdb[fcp->isp_iid];
1726	} else {
1727		lp = &fcp->portdb[fcp->isp_iid];
1728		if (fcp->isp_portid != lp->portid ||
1729		    fcp->isp_loopid != lp->loopid ||
1730		    fcp->isp_nodewwn != ISP_NODEWWN(isp) ||
1731		    fcp->isp_portwwn != ISP_PORTWWN(isp)) {
1732			lp->valid = 0;
1733			count = fcp->isp_iid;
1734			(void) isp_async(isp, ISPASYNC_PROMENADE, &count);
1735		}
1736	}
1737	lp->loopid = fcp->isp_loopid;
1738	lp->portid = fcp->isp_portid;
1739	lp->node_wwn = ISP_NODEWWN(isp);
1740	lp->port_wwn = ISP_PORTWWN(isp);
1741	switch (isp->isp_role) {
1742	case ISP_ROLE_NONE:
1743		lp->roles = 0;
1744		break;
1745	case ISP_ROLE_TARGET:
1746		lp->roles = SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT;
1747		break;
1748	case ISP_ROLE_INITIATOR:
1749		lp->roles = SVC3_INI_ROLE >> SVC3_ROLE_SHIFT;
1750		break;
1751	case ISP_ROLE_BOTH:
1752		lp->roles = (SVC3_INI_ROLE|SVC3_TGT_ROLE) >> SVC3_ROLE_SHIFT;
1753		break;
1754	}
1755	lp->loggedin = lp->valid = 1;
1756	count = fcp->isp_iid;
1757	(void) isp_async(isp, ISPASYNC_PROMENADE, &count);
1758	return (0);
1759}
1760
1761static char *
1762isp2100_fw_statename(int state)
1763{
1764	switch(state) {
1765	case FW_CONFIG_WAIT:	return "Config Wait";
1766	case FW_WAIT_AL_PA:	return "Waiting for AL_PA";
1767	case FW_WAIT_LOGIN:	return "Wait Login";
1768	case FW_READY:		return "Ready";
1769	case FW_LOSS_OF_SYNC:	return "Loss Of Sync";
1770	case FW_ERROR:		return "Error";
1771	case FW_REINIT:		return "Re-Init";
1772	case FW_NON_PART:	return "Nonparticipating";
1773	default:		return "?????";
1774	}
1775}
1776
1777/*
1778 * Synchronize our soft copy of the port database with what the f/w thinks
1779 * (with a view toward possibly for a specific target....)
1780 */
1781
1782static int
1783isp_pdb_sync(struct ispsoftc *isp)
1784{
1785	struct lportdb *lp;
1786	fcparam *fcp = isp->isp_param;
1787	isp_pdb_t pdb;
1788	int loopid, base, lim;
1789
1790	/*
1791	 * Make sure we're okay for doing this right now.
1792	 */
1793	if (fcp->isp_loopstate != LOOP_PDB_RCVD &&
1794	    fcp->isp_loopstate != LOOP_FSCAN_DONE &&
1795	    fcp->isp_loopstate != LOOP_LSCAN_DONE) {
1796		return (-1);
1797	}
1798
1799	if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_NL_PORT ||
1800	    fcp->isp_topo == TOPO_N_PORT) {
1801		if (fcp->isp_loopstate < LOOP_LSCAN_DONE) {
1802			if (isp_scan_loop(isp) != 0) {
1803				return (-1);
1804			}
1805		}
1806	}
1807	fcp->isp_loopstate = LOOP_SYNCING_PDB;
1808
1809	/*
1810	 * If we get this far, we've settled our differences with the f/w
1811	 * (for local loop device) and we can say that the loop state is ready.
1812	 */
1813
1814	if (fcp->isp_topo == TOPO_NL_PORT) {
1815		fcp->loop_seen_once = 1;
1816		fcp->isp_loopstate = LOOP_READY;
1817		return (0);
1818	}
1819
1820	/*
1821	 * Find all Fabric Entities that didn't make it from one scan to the
1822	 * next and let the world know they went away. Scan the whole database.
1823	 */
1824	for (lp = &fcp->portdb[0]; lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
1825		if (lp->was_fabric_dev && lp->fabric_dev == 0) {
1826			loopid = lp - fcp->portdb;
1827			lp->valid = 0;	/* should already be set */
1828			(void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
1829			MEMZERO((void *) lp, sizeof (*lp));
1830			continue;
1831		}
1832		lp->was_fabric_dev = lp->fabric_dev;
1833	}
1834
1835	if (fcp->isp_topo == TOPO_FL_PORT)
1836		base = FC_SNS_ID+1;
1837	else
1838		base = 0;
1839
1840	if (fcp->isp_topo == TOPO_N_PORT)
1841		lim = 1;
1842	else
1843		lim = MAX_FC_TARG;
1844
1845	/*
1846	 * Now log in any fabric devices that the outer layer has
1847	 * left for us to see. This seems the most sane policy
1848	 * for the moment.
1849	 */
1850	for (lp = &fcp->portdb[base]; lp < &fcp->portdb[lim]; lp++) {
1851		u_int32_t portid;
1852		mbreg_t mbs;
1853
1854		loopid = lp - fcp->portdb;
1855		if (loopid >= FL_PORT_ID && loopid <= FC_SNS_ID) {
1856			continue;
1857		}
1858
1859		/*
1860		 * Anything here?
1861		 */
1862		if (lp->port_wwn == 0) {
1863			continue;
1864		}
1865
1866		/*
1867		 * Don't try to log into yourself.
1868		 */
1869		if ((portid = lp->portid) == fcp->isp_portid) {
1870			continue;
1871		}
1872
1873
1874		/*
1875		 * If we'd been logged in- see if we still are and we haven't
1876		 * changed. If so, no need to log ourselves out, etc..
1877		 *
1878		 * Unfortunately, our charming Qlogic f/w has decided to
1879		 * return a valid port database entry for a fabric device
1880		 * that has, in fact, gone away. And it hangs trying to
1881		 * log it out.
1882		 */
1883		if (lp->loggedin && lp->force_logout == 0 &&
1884		    isp_getpdb(isp, lp->loopid, &pdb) == 0) {
1885			int nrole;
1886			u_int64_t nwwnn, nwwpn;
1887			nwwnn =
1888			    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
1889			    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
1890			    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
1891			    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
1892			    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
1893			    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
1894			    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
1895			    (((u_int64_t)pdb.pdb_nodename[7]));
1896			nwwpn =
1897			    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
1898			    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
1899			    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
1900			    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
1901			    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
1902			    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
1903			    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
1904			    (((u_int64_t)pdb.pdb_portname[7]));
1905			nrole = (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >>
1906			    SVC3_ROLE_SHIFT;
1907			if (pdb.pdb_loopid == lp->loopid && lp->portid ==
1908			    (u_int32_t) BITS2WORD(pdb.pdb_portid_bits) &&
1909			    nwwnn == lp->node_wwn && nwwpn == lp->port_wwn &&
1910			    lp->roles == nrole && lp->force_logout == 0) {
1911				lp->loggedin = lp->valid = 1;
1912				isp_prt(isp, ISP_LOGCONFIG, lretained,
1913				    (int) (lp - fcp->portdb),
1914				    (int) lp->loopid, lp->portid);
1915				continue;
1916			}
1917		}
1918
1919		if (fcp->isp_fwstate != FW_READY ||
1920		    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
1921			return (-1);
1922		}
1923
1924		/*
1925		 * Force a logout if we were logged in.
1926		 */
1927		if (lp->loggedin) {
1928			if (lp->force_logout ||
1929			    isp_getpdb(isp, lp->loopid, &pdb) == 0) {
1930				mbs.param[0] = MBOX_FABRIC_LOGOUT;
1931				mbs.param[1] = lp->loopid << 8;
1932				mbs.param[2] = 0;
1933				mbs.param[3] = 0;
1934				isp_mboxcmd(isp, &mbs, MBLOGNONE);
1935				isp_prt(isp, ISP_LOGINFO, plogout,
1936				    (int) (lp - fcp->portdb), lp->loopid,
1937				    lp->portid);
1938			}
1939			lp->force_logout = lp->loggedin = 0;
1940			if (fcp->isp_fwstate != FW_READY ||
1941			    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
1942				return (-1);
1943			}
1944		}
1945
1946		/*
1947		 * And log in....
1948		 */
1949		loopid = lp - fcp->portdb;
1950		lp->loopid = FL_PORT_ID;
1951		do {
1952			mbs.param[0] = MBOX_FABRIC_LOGIN;
1953			mbs.param[1] = loopid << 8;
1954			mbs.param[2] = portid >> 16;
1955			mbs.param[3] = portid & 0xffff;
1956			isp_mboxcmd(isp, &mbs, MBLOGALL & ~(MBOX_LOOP_ID_USED |
1957			    MBOX_PORT_ID_USED | MBOX_COMMAND_ERROR));
1958			if (fcp->isp_fwstate != FW_READY ||
1959			    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
1960				return (-1);
1961			}
1962			switch (mbs.param[0]) {
1963			case MBOX_LOOP_ID_USED:
1964				/*
1965				 * Try the next available loop id.
1966				 */
1967				loopid++;
1968				break;
1969			case MBOX_PORT_ID_USED:
1970				/*
1971				 * This port is already logged in.
1972				 * Snaffle the loop id it's using if it's
1973				 * nonzero, otherwise we're hosed.
1974				 */
1975				if (mbs.param[1] != 0) {
1976					loopid = mbs.param[1];
1977					isp_prt(isp, ISP_LOGINFO, retained,
1978					    loopid, (int) (lp - fcp->portdb),
1979					    lp->portid);
1980				} else {
1981					loopid = MAX_FC_TARG;
1982					break;
1983				}
1984				/* FALLTHROUGH */
1985			case MBOX_COMMAND_COMPLETE:
1986				lp->loggedin = 1;
1987				lp->loopid = loopid;
1988				break;
1989			case MBOX_COMMAND_ERROR:
1990				isp_prt(isp, ISP_LOGINFO, plogierr,
1991				    portid, mbs.param[1]);
1992				/* FALLTHROUGH */
1993			case MBOX_ALL_IDS_USED: /* We're outta IDs */
1994			default:
1995				loopid = MAX_FC_TARG;
1996				break;
1997			}
1998		} while (lp->loopid == FL_PORT_ID && loopid < MAX_FC_TARG);
1999
2000		/*
2001		 * If we get here and we haven't set a Loop ID,
2002		 * we failed to log into this device.
2003		 */
2004
2005		if (lp->loopid == FL_PORT_ID) {
2006			lp->loopid = 0;
2007			continue;
2008		}
2009
2010		/*
2011		 * Make sure we can get the approriate port information.
2012		 */
2013		if (isp_getpdb(isp, lp->loopid, &pdb) != 0) {
2014			isp_prt(isp, ISP_LOGWARN, nopdb, lp->portid);
2015			goto dump_em;
2016		}
2017
2018		if (fcp->isp_fwstate != FW_READY ||
2019		    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
2020			return (-1);
2021		}
2022
2023		if (pdb.pdb_loopid != lp->loopid) {
2024			isp_prt(isp, ISP_LOGWARN, pdbmfail1,
2025			    lp->portid, pdb.pdb_loopid);
2026			goto dump_em;
2027		}
2028
2029		if (lp->portid != (u_int32_t) BITS2WORD(pdb.pdb_portid_bits)) {
2030			isp_prt(isp, ISP_LOGWARN, pdbmfail2,
2031			    lp->portid, BITS2WORD(pdb.pdb_portid_bits));
2032			goto dump_em;
2033		}
2034
2035		lp->roles =
2036		    (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
2037		lp->node_wwn =
2038		    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
2039		    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
2040		    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
2041		    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
2042		    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
2043		    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
2044		    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
2045		    (((u_int64_t)pdb.pdb_nodename[7]));
2046		lp->port_wwn =
2047		    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
2048		    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
2049		    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
2050		    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
2051		    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
2052		    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
2053		    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
2054		    (((u_int64_t)pdb.pdb_portname[7]));
2055		/*
2056		 * Check to make sure this all makes sense.
2057		 */
2058		if (lp->node_wwn && lp->port_wwn) {
2059			lp->valid = 1;
2060			loopid = lp - fcp->portdb;
2061			(void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
2062			continue;
2063		}
2064dump_em:
2065		lp->valid = 0;
2066		isp_prt(isp, ISP_LOGINFO,
2067		    ldumped, loopid, lp->loopid, lp->portid);
2068		mbs.param[0] = MBOX_FABRIC_LOGOUT;
2069		mbs.param[1] = lp->loopid << 8;
2070		mbs.param[2] = 0;
2071		mbs.param[3] = 0;
2072		isp_mboxcmd(isp, &mbs, MBLOGNONE);
2073		if (fcp->isp_fwstate != FW_READY ||
2074		    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
2075			return (-1);
2076		}
2077	}
2078	/*
2079	 * If we get here, we've for sure seen not only a valid loop
2080	 * but know what is or isn't on it, so mark this for usage
2081	 * in isp_start.
2082	 */
2083	fcp->loop_seen_once = 1;
2084	fcp->isp_loopstate = LOOP_READY;
2085	return (0);
2086}
2087
2088static int
2089isp_scan_loop(struct ispsoftc *isp)
2090{
2091	struct lportdb *lp;
2092	fcparam *fcp = isp->isp_param;
2093	isp_pdb_t pdb;
2094	int loopid, lim, hival;
2095
2096	switch (fcp->isp_topo) {
2097	case TOPO_NL_PORT:
2098		hival = FL_PORT_ID;
2099		break;
2100	case TOPO_N_PORT:
2101		hival = 2;
2102		break;
2103	case TOPO_FL_PORT:
2104		hival = FC_PORT_ID;
2105		break;
2106	default:
2107		fcp->isp_loopstate = LOOP_LSCAN_DONE;
2108		return (0);
2109	}
2110	fcp->isp_loopstate = LOOP_SCANNING_LOOP;
2111
2112	/*
2113	 * make sure the temp port database is clean...
2114	 */
2115	MEMZERO((void *)fcp->tport, sizeof (fcp->tport));
2116
2117	/*
2118	 * Run through the local loop ports and get port database info
2119	 * for each loop ID.
2120	 *
2121	 * There's a somewhat unexplained situation where the f/w passes back
2122	 * the wrong database entity- if that happens, just restart (up to
2123	 * FL_PORT_ID times).
2124	 */
2125	for (lim = loopid = 0; loopid < hival; loopid++) {
2126		lp = &fcp->tport[loopid];
2127
2128		/*
2129		 * Don't even try for ourselves...
2130	 	 */
2131		if (loopid == fcp->isp_loopid)
2132			continue;
2133
2134		lp->node_wwn = isp_get_portname(isp, loopid, 1);
2135		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
2136			return (-1);
2137		if (lp->node_wwn == 0)
2138			continue;
2139		lp->port_wwn = isp_get_portname(isp, loopid, 0);
2140		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
2141			return (-1);
2142		if (lp->port_wwn == 0) {
2143			lp->node_wwn = 0;
2144			continue;
2145		}
2146
2147		/*
2148		 * Get an entry....
2149		 */
2150		if (isp_getpdb(isp, loopid, &pdb) != 0) {
2151			if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
2152				return (-1);
2153			continue;
2154		}
2155		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
2156			return (-1);
2157		}
2158
2159		/*
2160		 * If the returned database element doesn't match what we
2161		 * asked for, restart the process entirely (up to a point...).
2162		 */
2163		if (pdb.pdb_loopid != loopid) {
2164			loopid = 0;
2165			if (lim++ < hival) {
2166				continue;
2167			}
2168			isp_prt(isp, ISP_LOGWARN,
2169			    "giving up on synchronizing the port database");
2170			return (-1);
2171		}
2172
2173		/*
2174		 * Save the pertinent info locally.
2175		 */
2176		lp->node_wwn =
2177		    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
2178		    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
2179		    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
2180		    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
2181		    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
2182		    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
2183		    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
2184		    (((u_int64_t)pdb.pdb_nodename[7]));
2185		lp->port_wwn =
2186		    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
2187		    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
2188		    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
2189		    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
2190		    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
2191		    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
2192		    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
2193		    (((u_int64_t)pdb.pdb_portname[7]));
2194		lp->roles =
2195		    (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
2196		lp->portid = BITS2WORD(pdb.pdb_portid_bits);
2197		lp->loopid = pdb.pdb_loopid;
2198	}
2199
2200	/*
2201	 * Mark all of the permanent local loop database entries as invalid
2202	 * (except our own entry).
2203	 */
2204	for (loopid = 0; loopid < hival; loopid++) {
2205		if (loopid == fcp->isp_iid) {
2206			fcp->portdb[loopid].valid = 1;
2207			fcp->portdb[loopid].loopid = fcp->isp_loopid;
2208			continue;
2209		}
2210		fcp->portdb[loopid].valid = 0;
2211	}
2212
2213	/*
2214	 * Now merge our local copy of the port database into our saved copy.
2215	 * Notify the outer layers of new devices arriving.
2216	 */
2217	for (loopid = 0; loopid < hival; loopid++) {
2218		int i;
2219
2220		/*
2221		 * If we don't have a non-zero Port WWN, we're not here.
2222		 */
2223		if (fcp->tport[loopid].port_wwn == 0) {
2224			continue;
2225		}
2226
2227		/*
2228		 * Skip ourselves.
2229		 */
2230		if (loopid == fcp->isp_iid) {
2231			continue;
2232		}
2233
2234		/*
2235		 * For the purposes of deciding whether this is the
2236		 * 'same' device or not, we only search for an identical
2237		 * Port WWN. Node WWNs may or may not be the same as
2238		 * the Port WWN, and there may be multiple different
2239		 * Port WWNs with the same Node WWN. It would be chaos
2240		 * to have multiple identical Port WWNs, so we don't
2241		 * allow that.
2242		 */
2243
2244		for (i = 0; i < hival; i++) {
2245			int j;
2246			if (fcp->portdb[i].port_wwn == 0)
2247				continue;
2248			if (fcp->portdb[i].port_wwn !=
2249			    fcp->tport[loopid].port_wwn)
2250				continue;
2251			/*
2252			 * We found this WWN elsewhere- it's changed
2253			 * loopids then. We don't change it's actual
2254			 * position in our cached port database- we
2255			 * just change the actual loop ID we'd use.
2256			 */
2257			if (fcp->portdb[i].loopid != loopid) {
2258				isp_prt(isp, ISP_LOGINFO, portshift, i,
2259				    fcp->portdb[i].loopid,
2260				    fcp->portdb[i].portid, loopid,
2261				    fcp->tport[loopid].portid);
2262			}
2263			fcp->portdb[i].portid = fcp->tport[loopid].portid;
2264			fcp->portdb[i].loopid = loopid;
2265			fcp->portdb[i].valid = 1;
2266			fcp->portdb[i].roles = fcp->tport[loopid].roles;
2267
2268			/*
2269			 * Now make sure this Port WWN doesn't exist elsewhere
2270			 * in the port database.
2271			 */
2272			for (j = i+1; j < hival; j++) {
2273				if (fcp->portdb[i].port_wwn !=
2274				    fcp->portdb[j].port_wwn) {
2275					continue;
2276				}
2277				isp_prt(isp, ISP_LOGWARN, portdup, j, i);
2278				/*
2279				 * Invalidate the 'old' *and* 'new' ones.
2280				 * This is really harsh and not quite right,
2281				 * but if this happens, we really don't know
2282				 * who is what at this point.
2283				 */
2284				fcp->portdb[i].valid = 0;
2285				fcp->portdb[j].valid = 0;
2286			}
2287			break;
2288		}
2289
2290		/*
2291		 * If we didn't traverse the entire port database,
2292		 * then we found (and remapped) an existing entry.
2293		 * No need to notify anyone- go for the next one.
2294		 */
2295		if (i < hival) {
2296			isp_prt(isp, ISP_LOGINFO, retained,
2297			    fcp->portdb[i].loopid, i, fcp->portdb[i].portid);
2298			continue;
2299		}
2300
2301		/*
2302		 * We've not found this Port WWN anywhere. It's a new entry.
2303		 * See if we can leave it where it is (with target == loopid).
2304		 */
2305		if (fcp->portdb[loopid].port_wwn != 0) {
2306			for (lim = 0; lim < hival; lim++) {
2307				if (fcp->portdb[lim].port_wwn == 0)
2308					break;
2309			}
2310			/* "Cannot Happen" */
2311			if (lim == hival) {
2312				isp_prt(isp, ISP_LOGWARN, "Remap Overflow");
2313				continue;
2314			}
2315			i = lim;
2316		} else {
2317			i = loopid;
2318		}
2319
2320		/*
2321		 * NB:	The actual loopid we use here is loopid- we may
2322		 *	in fact be at a completely different index (target).
2323		 */
2324		fcp->portdb[i].loopid = loopid;
2325		fcp->portdb[i].port_wwn = fcp->tport[loopid].port_wwn;
2326		fcp->portdb[i].node_wwn = fcp->tport[loopid].node_wwn;
2327		fcp->portdb[i].roles = fcp->tport[loopid].roles;
2328		fcp->portdb[i].portid = fcp->tport[loopid].portid;
2329		fcp->portdb[i].valid = 1;
2330
2331		/*
2332		 * Tell the outside world we've arrived.
2333		 */
2334		(void) isp_async(isp, ISPASYNC_PROMENADE, &i);
2335	}
2336
2337	/*
2338	 * Now find all previously used targets that are now invalid and
2339	 * notify the outer layers that they're gone.
2340	 */
2341	for (lp = &fcp->portdb[0]; lp < &fcp->portdb[hival]; lp++) {
2342		if (lp->valid || lp->port_wwn == 0) {
2343			continue;
2344		}
2345
2346		/*
2347		 * Tell the outside world we've gone
2348		 * away and erase our pdb entry.
2349		 *
2350		 */
2351		loopid = lp - fcp->portdb;
2352		(void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
2353		MEMZERO((void *) lp, sizeof (*lp));
2354	}
2355	fcp->isp_loopstate = LOOP_LSCAN_DONE;
2356	return (0);
2357}
2358
2359
2360static int
2361isp_fabric_mbox_cmd(struct ispsoftc *isp, mbreg_t *mbp)
2362{
2363	isp_mboxcmd(isp, mbp, MBLOGNONE);
2364	if (mbp->param[0] != MBOX_COMMAND_COMPLETE) {
2365		if (FCPARAM(isp)->isp_loopstate == LOOP_SCANNING_FABRIC) {
2366			FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
2367		}
2368		if (mbp->param[0] == MBOX_COMMAND_ERROR) {
2369			char tbuf[16];
2370			char *m;
2371			switch (mbp->param[1]) {
2372			case 1:
2373				m = "No Loop";
2374				break;
2375			case 2:
2376				m = "Failed to allocate IOCB buffer";
2377				break;
2378			case 3:
2379				m = "Failed to allocate XCB buffer";
2380				break;
2381			case 4:
2382				m = "timeout or transmit failed";
2383				break;
2384			case 5:
2385				m = "no fabric loop";
2386				break;
2387			case 6:
2388				m = "remote device not a target";
2389				break;
2390			default:
2391				SNPRINTF(tbuf, sizeof tbuf, "%x",
2392				    mbp->param[1]);
2393				m = tbuf;
2394				break;
2395			}
2396			isp_prt(isp, ISP_LOGERR, "SNS Failed- %s", m);
2397		}
2398		return (-1);
2399	}
2400
2401	if (FCPARAM(isp)->isp_fwstate != FW_READY ||
2402	    FCPARAM(isp)->isp_loopstate < LOOP_SCANNING_FABRIC) {
2403		return (-1);
2404	}
2405	return(0);
2406}
2407
2408#ifdef	ISP_USE_GA_NXT
2409static int
2410isp_scan_fabric(struct ispsoftc *isp, int ftype)
2411{
2412	fcparam *fcp = isp->isp_param;
2413	u_int32_t portid, first_portid, last_portid;
2414	int hicap, last_port_same;
2415
2416	if (fcp->isp_onfabric == 0) {
2417		fcp->isp_loopstate = LOOP_FSCAN_DONE;
2418		return (0);
2419	}
2420
2421	FC_SCRATCH_ACQUIRE(isp);
2422
2423	/*
2424	 * Since Port IDs are 24 bits, we can check against having seen
2425	 * anything yet with this value.
2426	 */
2427	last_port_same = 0;
2428	last_portid = 0xffffffff;	/* not a port */
2429	first_portid = portid = fcp->isp_portid;
2430	fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
2431
2432	for (hicap = 0; hicap < GA_NXT_MAX; hicap++) {
2433		mbreg_t mbs;
2434		sns_screq_t *rq;
2435		sns_ga_nxt_rsp_t *rs0, *rs1;
2436		struct lportdb lcl;
2437		u_int8_t sc[SNS_GA_NXT_RESP_SIZE];
2438
2439		rq = (sns_screq_t *)sc;
2440		MEMZERO((void *) rq, SNS_GA_NXT_REQ_SIZE);
2441		rq->snscb_rblen = SNS_GA_NXT_RESP_SIZE >> 1;
2442		rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+0x100);
2443		rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+0x100);
2444		rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+0x100);
2445		rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+0x100);
2446		rq->snscb_sblen = 6;
2447		rq->snscb_data[0] = SNS_GA_NXT;
2448		rq->snscb_data[4] = portid & 0xffff;
2449		rq->snscb_data[5] = (portid >> 16) & 0xff;
2450		isp_put_sns_request(isp, rq, (sns_screq_t *) fcp->isp_scratch);
2451		MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GA_NXT_REQ_SIZE);
2452		mbs.param[0] = MBOX_SEND_SNS;
2453		mbs.param[1] = SNS_GA_NXT_REQ_SIZE >> 1;
2454		mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2455		mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2456		/*
2457		 * Leave 4 and 5 alone
2458		 */
2459		mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2460		mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2461		if (isp_fabric_mbox_cmd(isp, &mbs)) {
2462			if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
2463				fcp->isp_loopstate = LOOP_PDB_RCVD;
2464			}
2465			FC_SCRATCH_RELEASE(isp);
2466			return (-1);
2467		}
2468		MEMORYBARRIER(isp, SYNC_SFORCPU, 0x100, SNS_GA_NXT_RESP_SIZE);
2469		rs1 = (sns_ga_nxt_rsp_t *) sc;
2470		rs0 = (sns_ga_nxt_rsp_t *) ((u_int8_t *)fcp->isp_scratch+0x100);
2471		isp_get_ga_nxt_response(isp, rs0, rs1);
2472		if (rs1->snscb_cthdr.ct_response != FS_ACC) {
2473			int level;
2474			if (rs1->snscb_cthdr.ct_reason == 9 &&
2475			    rs1->snscb_cthdr.ct_explanation == 7)
2476				level = ISP_LOGDEBUG0;
2477			else
2478				level = ISP_LOGWARN;
2479			isp_prt(isp, level, swrej, "GA_NXT",
2480			    rs1->snscb_cthdr.ct_reason,
2481			    rs1->snscb_cthdr.ct_explanation, portid);
2482			FC_SCRATCH_RELEASE(isp);
2483			fcp->isp_loopstate = LOOP_FSCAN_DONE;
2484			return (0);
2485		}
2486		portid =
2487		    (((u_int32_t) rs1->snscb_port_id[0]) << 16) |
2488		    (((u_int32_t) rs1->snscb_port_id[1]) << 8) |
2489		    (((u_int32_t) rs1->snscb_port_id[2]));
2490
2491		/*
2492		 * XXX: We should check to make sure that this entry
2493		 * XXX: supports the type(s) we are interested in.
2494		 */
2495		/*
2496		 * Okay, we now have information about a fabric object.
2497		 * If it is the type we're interested in, tell the outer layers
2498		 * about it. The outer layer needs to  know: Port ID, WWNN,
2499		 * WWPN, FC4 type, and port type.
2500		 *
2501		 * The lportdb structure is adequate for this.
2502		 */
2503		MEMZERO(&lcl, sizeof (lcl));
2504		lcl.port_type = rs1->snscb_port_type;
2505		lcl.fc4_type = ftype;
2506		lcl.portid = portid;
2507		lcl.node_wwn =
2508		    (((u_int64_t)rs1->snscb_nodename[0]) << 56) |
2509		    (((u_int64_t)rs1->snscb_nodename[1]) << 48) |
2510		    (((u_int64_t)rs1->snscb_nodename[2]) << 40) |
2511		    (((u_int64_t)rs1->snscb_nodename[3]) << 32) |
2512		    (((u_int64_t)rs1->snscb_nodename[4]) << 24) |
2513		    (((u_int64_t)rs1->snscb_nodename[5]) << 16) |
2514		    (((u_int64_t)rs1->snscb_nodename[6]) <<  8) |
2515		    (((u_int64_t)rs1->snscb_nodename[7]));
2516		lcl.port_wwn =
2517		    (((u_int64_t)rs1->snscb_portname[0]) << 56) |
2518		    (((u_int64_t)rs1->snscb_portname[1]) << 48) |
2519		    (((u_int64_t)rs1->snscb_portname[2]) << 40) |
2520		    (((u_int64_t)rs1->snscb_portname[3]) << 32) |
2521		    (((u_int64_t)rs1->snscb_portname[4]) << 24) |
2522		    (((u_int64_t)rs1->snscb_portname[5]) << 16) |
2523		    (((u_int64_t)rs1->snscb_portname[6]) <<  8) |
2524		    (((u_int64_t)rs1->snscb_portname[7]));
2525
2526		/*
2527		 * Does this fabric object support the type we want?
2528		 * If not, skip it.
2529		 */
2530		if (rs1->snscb_fc4_types[ftype >> 5] & (1 << (ftype & 0x1f))) {
2531			if (first_portid == portid) {
2532				lcl.last_fabric_dev = 1;
2533			} else {
2534				lcl.last_fabric_dev = 0;
2535			}
2536			(void) isp_async(isp, ISPASYNC_FABRIC_DEV, &lcl);
2537		} else {
2538			isp_prt(isp, ISP_LOGDEBUG0,
2539			    "PortID 0x%x doesn't support FC4 type 0x%x",
2540			    portid, ftype);
2541		}
2542		if (first_portid == portid) {
2543			fcp->isp_loopstate = LOOP_FSCAN_DONE;
2544			FC_SCRATCH_RELEASE(isp);
2545			return (0);
2546		}
2547		if (portid == last_portid) {
2548			if (last_port_same++ > 20) {
2549				isp_prt(isp, ISP_LOGWARN,
2550				    "tangled fabric database detected");
2551				break;
2552			}
2553		} else {
2554			last_port_same = 0 ;
2555			last_portid = portid;
2556		}
2557	}
2558	FC_SCRATCH_RELEASE(isp);
2559	if (hicap >= GA_NXT_MAX) {
2560		isp_prt(isp, ISP_LOGWARN, "fabric too big (> %d)", GA_NXT_MAX);
2561	}
2562	fcp->isp_loopstate = LOOP_FSCAN_DONE;
2563	return (0);
2564}
2565#else
2566#define	GIDLEN	((ISP2100_SCRLEN >> 1) + 16)
2567#define	NGENT	((GIDLEN - 16) >> 2)
2568
2569#define	IGPOFF	(ISP2100_SCRLEN - GIDLEN)
2570#define	GXOFF	(256)
2571
2572static int
2573isp_scan_fabric(struct ispsoftc *isp, int ftype)
2574{
2575	fcparam *fcp = FCPARAM(isp);
2576	mbreg_t mbs;
2577	int i;
2578	sns_gid_ft_req_t *rq;
2579	sns_gid_ft_rsp_t *rs0, *rs1;
2580
2581	if (fcp->isp_onfabric == 0) {
2582		fcp->isp_loopstate = LOOP_FSCAN_DONE;
2583		return (0);
2584	}
2585
2586	FC_SCRATCH_ACQUIRE(isp);
2587	fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
2588
2589	rq = (sns_gid_ft_req_t *)fcp->tport;
2590	MEMZERO((void *) rq, SNS_GID_FT_REQ_SIZE);
2591	rq->snscb_rblen = GIDLEN >> 1;
2592	rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+IGPOFF);
2593	rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+IGPOFF);
2594	rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+IGPOFF);
2595	rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+IGPOFF);
2596	rq->snscb_sblen = 6;
2597	rq->snscb_cmd = SNS_GID_FT;
2598	rq->snscb_mword_div_2 = NGENT;
2599	rq->snscb_fc4_type = ftype;
2600	isp_put_gid_ft_request(isp, rq, (sns_gid_ft_req_t *) fcp->isp_scratch);
2601	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE);
2602	mbs.param[0] = MBOX_SEND_SNS;
2603	mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1;
2604	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2605	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2606
2607	/*
2608	 * Leave 4 and 5 alone
2609	 */
2610	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2611	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2612	if (isp_fabric_mbox_cmd(isp, &mbs)) {
2613		if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
2614			fcp->isp_loopstate = LOOP_PDB_RCVD;
2615		}
2616		FC_SCRATCH_RELEASE(isp);
2617		return (-1);
2618	}
2619	if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2620		FC_SCRATCH_RELEASE(isp);
2621		return (-1);
2622	}
2623	MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN);
2624	rs1 = (sns_gid_ft_rsp_t *) fcp->tport;
2625	rs0 = (sns_gid_ft_rsp_t *) ((u_int8_t *)fcp->isp_scratch+IGPOFF);
2626	isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
2627	if (rs1->snscb_cthdr.ct_response != FS_ACC) {
2628		int level;
2629		if (rs1->snscb_cthdr.ct_reason == 9 &&
2630		    rs1->snscb_cthdr.ct_explanation == 7)
2631			level = ISP_LOGDEBUG0;
2632		else
2633			level = ISP_LOGWARN;
2634		isp_prt(isp, level, swrej, "GID_FT",
2635		    rs1->snscb_cthdr.ct_reason,
2636		    rs1->snscb_cthdr.ct_explanation, 0);
2637		FC_SCRATCH_RELEASE(isp);
2638		fcp->isp_loopstate = LOOP_FSCAN_DONE;
2639		return (0);
2640	}
2641
2642	/*
2643	 * Okay, we now have a list of Port IDs for this class of device.
2644	 * Go through the list and for each one get the WWPN/WWNN for it
2645	 * and tell the outer layers about it. The outer layer needs to
2646	 * know: Port ID, WWNN, WWPN, FC4 type, and (possibly) port type.
2647	 *
2648	 * The lportdb structure is adequate for this.
2649	 */
2650	i = -1;
2651	do {
2652		sns_gxn_id_req_t grqbuf, *gq = &grqbuf;
2653		sns_gxn_id_rsp_t *gs0, grsbuf, *gs1 = &grsbuf;
2654		struct lportdb lcl;
2655#if	0
2656		sns_gff_id_rsp_t *fs0, ffsbuf, *fs1 = &ffsbuf;
2657#endif
2658
2659		i++;
2660		MEMZERO(&lcl, sizeof (lcl));
2661		lcl.fc4_type = ftype;
2662		lcl.portid =
2663		    (((u_int32_t) rs1->snscb_ports[i].portid[0]) << 16) |
2664		    (((u_int32_t) rs1->snscb_ports[i].portid[1]) << 8) |
2665		    (((u_int32_t) rs1->snscb_ports[i].portid[2]));
2666
2667		MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
2668		gq->snscb_rblen = SNS_GXN_ID_RESP_SIZE >> 1;
2669		gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
2670		gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
2671		gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
2672		gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
2673		gq->snscb_sblen = 6;
2674		gq->snscb_cmd = SNS_GPN_ID;
2675		gq->snscb_portid = lcl.portid;
2676		isp_put_gxn_id_request(isp, gq,
2677		    (sns_gxn_id_req_t *) fcp->isp_scratch);
2678		MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
2679		mbs.param[0] = MBOX_SEND_SNS;
2680		mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
2681		mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2682		mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2683		/*
2684		 * Leave 4 and 5 alone
2685		 */
2686		mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2687		mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2688		if (isp_fabric_mbox_cmd(isp, &mbs)) {
2689			if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
2690				fcp->isp_loopstate = LOOP_PDB_RCVD;
2691			}
2692			FC_SCRATCH_RELEASE(isp);
2693			return (-1);
2694		}
2695		if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2696			FC_SCRATCH_RELEASE(isp);
2697			return (-1);
2698		}
2699		MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GXN_ID_RESP_SIZE);
2700		gs0 = (sns_gxn_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
2701		isp_get_gxn_id_response(isp, gs0, gs1);
2702		if (gs1->snscb_cthdr.ct_response != FS_ACC) {
2703			isp_prt(isp, ISP_LOGWARN, swrej, "GPN_ID",
2704			    gs1->snscb_cthdr.ct_reason,
2705			    gs1->snscb_cthdr.ct_explanation, lcl.portid);
2706			if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2707				FC_SCRATCH_RELEASE(isp);
2708				return (-1);
2709			}
2710			continue;
2711		}
2712		lcl.port_wwn =
2713		    (((u_int64_t)gs1->snscb_wwn[0]) << 56) |
2714		    (((u_int64_t)gs1->snscb_wwn[1]) << 48) |
2715		    (((u_int64_t)gs1->snscb_wwn[2]) << 40) |
2716		    (((u_int64_t)gs1->snscb_wwn[3]) << 32) |
2717		    (((u_int64_t)gs1->snscb_wwn[4]) << 24) |
2718		    (((u_int64_t)gs1->snscb_wwn[5]) << 16) |
2719		    (((u_int64_t)gs1->snscb_wwn[6]) <<  8) |
2720		    (((u_int64_t)gs1->snscb_wwn[7]));
2721
2722		MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
2723		gq->snscb_rblen = SNS_GXN_ID_RESP_SIZE >> 1;
2724		gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
2725		gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
2726		gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
2727		gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
2728		gq->snscb_sblen = 6;
2729		gq->snscb_cmd = SNS_GNN_ID;
2730		gq->snscb_portid = lcl.portid;
2731		isp_put_gxn_id_request(isp, gq,
2732		    (sns_gxn_id_req_t *) fcp->isp_scratch);
2733		MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
2734		mbs.param[0] = MBOX_SEND_SNS;
2735		mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
2736		mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2737		mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2738		/*
2739		 * Leave 4 and 5 alone
2740		 */
2741		mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2742		mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2743		if (isp_fabric_mbox_cmd(isp, &mbs)) {
2744			if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
2745				fcp->isp_loopstate = LOOP_PDB_RCVD;
2746			}
2747			FC_SCRATCH_RELEASE(isp);
2748			return (-1);
2749		}
2750		if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2751			FC_SCRATCH_RELEASE(isp);
2752			return (-1);
2753		}
2754		MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GXN_ID_RESP_SIZE);
2755		gs0 = (sns_gxn_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
2756		isp_get_gxn_id_response(isp, gs0, gs1);
2757		if (gs1->snscb_cthdr.ct_response != FS_ACC) {
2758			isp_prt(isp, ISP_LOGWARN, swrej, "GNN_ID",
2759			    gs1->snscb_cthdr.ct_reason,
2760			    gs1->snscb_cthdr.ct_explanation, lcl.portid);
2761			if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2762				FC_SCRATCH_RELEASE(isp);
2763				return (-1);
2764			}
2765			continue;
2766		}
2767		lcl.node_wwn =
2768		    (((u_int64_t)gs1->snscb_wwn[0]) << 56) |
2769		    (((u_int64_t)gs1->snscb_wwn[1]) << 48) |
2770		    (((u_int64_t)gs1->snscb_wwn[2]) << 40) |
2771		    (((u_int64_t)gs1->snscb_wwn[3]) << 32) |
2772		    (((u_int64_t)gs1->snscb_wwn[4]) << 24) |
2773		    (((u_int64_t)gs1->snscb_wwn[5]) << 16) |
2774		    (((u_int64_t)gs1->snscb_wwn[6]) <<  8) |
2775		    (((u_int64_t)gs1->snscb_wwn[7]));
2776
2777		/*
2778		 * The QLogic f/w is bouncing this with a parameter error.
2779		 */
2780#if	0
2781		/*
2782		 * Try and get FC4 Features (FC-GS-3 only).
2783		 * We can use the sns_gxn_id_req_t for this request.
2784		 */
2785		MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
2786		gq->snscb_rblen = SNS_GFF_ID_RESP_SIZE >> 1;
2787		gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
2788		gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
2789		gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
2790		gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
2791		gq->snscb_sblen = 6;
2792		gq->snscb_cmd = SNS_GFF_ID;
2793		gq->snscb_portid = lcl.portid;
2794		isp_put_gxn_id_request(isp, gq,
2795		    (sns_gxn_id_req_t *) fcp->isp_scratch);
2796		MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
2797		mbs.param[0] = MBOX_SEND_SNS;
2798		mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
2799		mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2800		mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2801		/*
2802		 * Leave 4 and 5 alone
2803		 */
2804		mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2805		mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2806		if (isp_fabric_mbox_cmd(isp, &mbs)) {
2807			if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
2808				fcp->isp_loopstate = LOOP_PDB_RCVD;
2809			}
2810			FC_SCRATCH_RELEASE(isp);
2811			return (-1);
2812		}
2813		if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2814			FC_SCRATCH_RELEASE(isp);
2815			return (-1);
2816		}
2817		MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GFF_ID_RESP_SIZE);
2818		fs0 = (sns_gff_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
2819		isp_get_gff_id_response(isp, fs0, fs1);
2820		if (fs1->snscb_cthdr.ct_response != FS_ACC) {
2821			isp_prt(isp, /* ISP_LOGDEBUG0 */ ISP_LOGWARN,
2822			    swrej, "GFF_ID",
2823			    fs1->snscb_cthdr.ct_reason,
2824			    fs1->snscb_cthdr.ct_explanation, lcl.portid);
2825			if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2826				FC_SCRATCH_RELEASE(isp);
2827				return (-1);
2828			}
2829		} else {
2830			int index = (ftype >> 3);
2831			int bshft = (ftype & 0x7) * 4;
2832			int fc4_fval =
2833			    (fs1->snscb_fc4_features[index] >> bshft) & 0xf;
2834			if (fc4_fval & 0x1) {
2835				lcl.roles |=
2836				    (SVC3_INI_ROLE >> SVC3_ROLE_SHIFT);
2837			}
2838			if (fc4_fval & 0x2) {
2839				lcl.roles |=
2840				    (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT);
2841			}
2842		}
2843#endif
2844
2845		/*
2846		 * If we really want to know what kind of port type this is,
2847		 * we have to run another CT command. Otherwise, we'll leave
2848		 * it as undefined.
2849		 *
2850		lcl.port_type = 0;
2851		 */
2852		if (rs1->snscb_ports[i].control & 0x80) {
2853			lcl.last_fabric_dev = 1;
2854		} else {
2855			lcl.last_fabric_dev = 0;
2856		}
2857		(void) isp_async(isp, ISPASYNC_FABRIC_DEV, &lcl);
2858
2859	} while ((rs1->snscb_ports[i].control & 0x80) == 0 && i < NGENT-1);
2860
2861	/*
2862	 * If we're not at the last entry, our list isn't big enough.
2863	 */
2864	if ((rs1->snscb_ports[i].control & 0x80) == 0) {
2865		isp_prt(isp, ISP_LOGWARN, "fabric too big for scratch area");
2866	}
2867
2868	FC_SCRATCH_RELEASE(isp);
2869	fcp->isp_loopstate = LOOP_FSCAN_DONE;
2870	return (0);
2871}
2872#endif
2873
2874static void
2875isp_register_fc4_type(struct ispsoftc *isp)
2876{
2877	fcparam *fcp = isp->isp_param;
2878	u_int8_t local[SNS_RFT_ID_REQ_SIZE];
2879	sns_screq_t *reqp = (sns_screq_t *) local;
2880	mbreg_t mbs;
2881
2882	MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE);
2883	reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1;
2884	reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100);
2885	reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100);
2886	reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100);
2887	reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100);
2888	reqp->snscb_sblen = 22;
2889	reqp->snscb_data[0] = SNS_RFT_ID;
2890	reqp->snscb_data[4] = fcp->isp_portid & 0xffff;
2891	reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff;
2892	reqp->snscb_data[6] = (1 << FC4_SCSI);
2893#if	0
2894	reqp->snscb_data[6] |= (1 << FC4_IP);	/* ISO/IEC 8802-2 LLC/SNAP */
2895#endif
2896	FC_SCRATCH_ACQUIRE(isp);
2897	isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
2898	mbs.param[0] = MBOX_SEND_SNS;
2899	mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1;
2900	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2901	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2902	/*
2903	 * Leave 4 and 5 alone
2904	 */
2905	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2906	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2907	isp_mboxcmd(isp, &mbs, MBLOGALL);
2908	FC_SCRATCH_RELEASE(isp);
2909	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
2910		isp_prt(isp, ISP_LOGDEBUG0, "Register FC4 types succeeded");
2911	}
2912}
2913
2914/*
2915 * Start a command. Locking is assumed done in the caller.
2916 */
2917
2918int
2919isp_start(XS_T *xs)
2920{
2921	struct ispsoftc *isp;
2922	u_int16_t nxti, optr, handle;
2923	u_int8_t local[QENTRY_LEN];
2924	ispreq_t *reqp, *qep;
2925	int target, i;
2926
2927	XS_INITERR(xs);
2928	isp = XS_ISP(xs);
2929
2930	/*
2931	 * Check to make sure we're supporting initiator role.
2932	 */
2933	if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {
2934		XS_SETERR(xs, HBA_SELTIMEOUT);
2935		return (CMD_COMPLETE);
2936	}
2937
2938	/*
2939	 * Now make sure we're running.
2940	 */
2941
2942	if (isp->isp_state != ISP_RUNSTATE) {
2943		isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
2944		XS_SETERR(xs, HBA_BOTCH);
2945		return (CMD_COMPLETE);
2946	}
2947
2948	/*
2949	 * Check command CDB length, etc.. We really are limited to 16 bytes
2950	 * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
2951	 * but probably only if we're running fairly new firmware (we'll
2952	 * let the old f/w choke on an extended command queue entry).
2953	 */
2954
2955	if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) {
2956		isp_prt(isp, ISP_LOGERR,
2957		    "unsupported cdb length (%d, CDB[0]=0x%x)",
2958		    XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
2959		XS_SETERR(xs, HBA_BOTCH);
2960		return (CMD_COMPLETE);
2961	}
2962
2963	/*
2964	 * Check to see whether we have good firmware state still or
2965	 * need to refresh our port database for this target.
2966	 */
2967	target = XS_TGT(xs);
2968	if (IS_FC(isp)) {
2969		fcparam *fcp = isp->isp_param;
2970		struct lportdb *lp;
2971#ifdef	HANDLE_LOOPSTATE_IN_OUTER_LAYERS
2972		if (fcp->isp_fwstate != FW_READY ||
2973		    fcp->isp_loopstate != LOOP_READY) {
2974			return (CMD_RQLATER);
2975		}
2976
2977		/*
2978		 * If we're not on a Fabric, we can't have a target
2979		 * above FL_PORT_ID-1.
2980		 *
2981		 * If we're on a fabric and *not* connected as an F-port,
2982		 * we can't have a target less than FC_SNS_ID+1. This
2983		 * keeps us from having to sort out the difference between
2984		 * local public loop devices and those which we might get
2985		 * from a switch's database.
2986		 */
2987		if (fcp->isp_onfabric == 0) {
2988			if (target >= FL_PORT_ID) {
2989				XS_SETERR(xs, HBA_SELTIMEOUT);
2990				return (CMD_COMPLETE);
2991			}
2992		} else {
2993			if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
2994				XS_SETERR(xs, HBA_SELTIMEOUT);
2995				return (CMD_COMPLETE);
2996			}
2997			/*
2998			 * We used to exclude having local loop ports
2999			 * at the same time that we have fabric ports.
3000			 * That is, we used to exclude having ports
3001			 * at < FL_PORT_ID if we're FL-port.
3002			 *
3003			 * That's wrong. The only thing that could be
3004			 * dicey is if the switch you're connected to
3005			 * has these local loop ports appear on the
3006			 * fabric and we somehow attach them twice.
3007			 */
3008		}
3009#else
3010		/*
3011		 * Check for f/w being in ready state. If the f/w
3012		 * isn't in ready state, then we don't know our
3013		 * loop ID and the f/w hasn't completed logging
3014		 * into all targets on the loop. If this is the
3015		 * case, then bounce the command. We pretend this is
3016		 * a SELECTION TIMEOUT error if we've never gone to
3017		 * FW_READY state at all- in this case we may not
3018		 * be hooked to a loop at all and we shouldn't hang
3019		 * the machine for this. Otherwise, defer this command
3020		 * until later.
3021		 */
3022		if (fcp->isp_fwstate != FW_READY) {
3023			/*
3024			 * Give ourselves at most a 250ms delay.
3025			 */
3026			if (isp_fclink_test(isp, 250000)) {
3027				XS_SETERR(xs, HBA_SELTIMEOUT);
3028				if (fcp->loop_seen_once) {
3029					return (CMD_RQLATER);
3030				} else {
3031					return (CMD_COMPLETE);
3032				}
3033			}
3034		}
3035
3036		/*
3037		 * If we're not on a Fabric, we can't have a target
3038		 * above FL_PORT_ID-1.
3039		 *
3040		 * If we're on a fabric and *not* connected as an F-port,
3041		 * we can't have a target less than FC_SNS_ID+1. This
3042		 * keeps us from having to sort out the difference between
3043		 * local public loop devices and those which we might get
3044		 * from a switch's database.
3045		 */
3046		if (fcp->isp_onfabric == 0) {
3047			if (target >= FL_PORT_ID) {
3048				XS_SETERR(xs, HBA_SELTIMEOUT);
3049				return (CMD_COMPLETE);
3050			}
3051		} else {
3052			if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
3053				XS_SETERR(xs, HBA_SELTIMEOUT);
3054				return (CMD_COMPLETE);
3055			}
3056			if (fcp->isp_topo != TOPO_F_PORT &&
3057			    target < FL_PORT_ID) {
3058				XS_SETERR(xs, HBA_SELTIMEOUT);
3059				return (CMD_COMPLETE);
3060			}
3061		}
3062
3063		/*
3064		 * If our loop state is such that we haven't yet received
3065		 * a "Port Database Changed" notification (after a LIP or
3066		 * a Loop Reset or firmware initialization), then defer
3067		 * sending commands for a little while, but only if we've
3068		 * seen a valid loop at one point (otherwise we can get
3069		 * stuck at initialization time).
3070		 */
3071		if (fcp->isp_loopstate < LOOP_PDB_RCVD) {
3072			XS_SETERR(xs, HBA_SELTIMEOUT);
3073			if (fcp->loop_seen_once) {
3074				return (CMD_RQLATER);
3075			} else {
3076				return (CMD_COMPLETE);
3077			}
3078		}
3079
3080		/*
3081		 * If we're in the middle of loop or fabric scanning
3082		 * or merging the port databases, retry this command later.
3083		 */
3084		if (fcp->isp_loopstate == LOOP_SCANNING_FABRIC ||
3085		    fcp->isp_loopstate == LOOP_SCANNING_LOOP ||
3086		    fcp->isp_loopstate == LOOP_SYNCING_PDB) {
3087			return (CMD_RQLATER);
3088		}
3089
3090		/*
3091		 * If our loop state is now such that we've just now
3092		 * received a Port Database Change notification, then
3093		 * we have to go off and (re)scan the fabric. We back
3094		 * out and try again later if this doesn't work.
3095		 */
3096		if (fcp->isp_loopstate == LOOP_PDB_RCVD && fcp->isp_onfabric) {
3097			if (isp_scan_fabric(isp, FC4_SCSI)) {
3098				return (CMD_RQLATER);
3099			}
3100			if (fcp->isp_fwstate != FW_READY ||
3101			    fcp->isp_loopstate < LOOP_FSCAN_DONE) {
3102				return (CMD_RQLATER);
3103			}
3104		}
3105
3106		/*
3107		 * If our loop state is now such that we've just now
3108		 * received a Port Database Change notification, then
3109		 * we have to go off and (re)synchronize our port
3110		 * database.
3111		 */
3112		if (fcp->isp_loopstate < LOOP_READY) {
3113			if (isp_pdb_sync(isp)) {
3114				return (CMD_RQLATER);
3115			}
3116			if (fcp->isp_fwstate != FW_READY ||
3117			    fcp->isp_loopstate != LOOP_READY) {
3118				return (CMD_RQLATER);
3119			}
3120		}
3121
3122		/*
3123		 * XXX: Here's were we would cancel any loop_dead flag
3124		 * XXX: also cancel in dead_loop timeout that's running
3125		 */
3126#endif
3127
3128		/*
3129		 * Now check whether we should even think about pursuing this.
3130		 */
3131		lp = &fcp->portdb[target];
3132		if (lp->valid == 0) {
3133			XS_SETERR(xs, HBA_SELTIMEOUT);
3134			return (CMD_COMPLETE);
3135		}
3136		if ((lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT)) == 0) {
3137			isp_prt(isp, ISP_LOGDEBUG2,
3138			    "Target %d does not have target service", target);
3139			XS_SETERR(xs, HBA_SELTIMEOUT);
3140			return (CMD_COMPLETE);
3141		}
3142		/*
3143		 * Now turn target into what the actual Loop ID is.
3144		 */
3145		target = lp->loopid;
3146	}
3147
3148	/*
3149	 * Next check to see if any HBA or Device
3150	 * parameters need to be updated.
3151	 */
3152	if (isp->isp_update != 0) {
3153		isp_update(isp);
3154	}
3155
3156	if (isp_getrqentry(isp, &nxti, &optr, (void **)&qep)) {
3157		isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow");
3158		XS_SETERR(xs, HBA_BOTCH);
3159		return (CMD_EAGAIN);
3160	}
3161
3162	/*
3163	 * Now see if we need to synchronize the ISP with respect to anything.
3164	 * We do dual duty here (cough) for synchronizing for busses other
3165	 * than which we got here to send a command to.
3166	 */
3167	reqp = (ispreq_t *) local;
3168	if (isp->isp_sendmarker) {
3169		u_int8_t n = (IS_DUALBUS(isp)? 2: 1);
3170		/*
3171		 * Check ports to send markers for...
3172		 */
3173		for (i = 0; i < n; i++) {
3174			if ((isp->isp_sendmarker & (1 << i)) == 0) {
3175				continue;
3176			}
3177			MEMZERO((void *) reqp, QENTRY_LEN);
3178			reqp->req_header.rqs_entry_count = 1;
3179			reqp->req_header.rqs_entry_type = RQSTYPE_MARKER;
3180			reqp->req_modifier = SYNC_ALL;
3181			reqp->req_target = i << 7;	/* insert bus number */
3182			isp_put_request(isp, reqp, qep);
3183			ISP_ADD_REQUEST(isp, nxti);
3184			isp->isp_sendmarker &= ~(1 << i);
3185			if (isp_getrqentry(isp, &nxti, &optr, (void **) &qep)) {
3186				isp_prt(isp, ISP_LOGDEBUG0,
3187				    "Request Queue Overflow+");
3188				XS_SETERR(xs, HBA_BOTCH);
3189				return (CMD_EAGAIN);
3190			}
3191		}
3192	}
3193
3194	MEMZERO((void *)reqp, QENTRY_LEN);
3195	reqp->req_header.rqs_entry_count = 1;
3196	if (IS_FC(isp)) {
3197		reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
3198	} else {
3199		if (XS_CDBLEN(xs) > 12)
3200			reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY;
3201		else
3202			reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
3203	}
3204	/* reqp->req_header.rqs_flags = 0; */
3205	/* reqp->req_header.rqs_seqno = 0; */
3206	if (IS_FC(isp)) {
3207		/*
3208		 * See comment in isp_intr
3209		 */
3210		/* XS_RESID(xs) = 0; */
3211
3212		/*
3213		 * Fibre Channel always requires some kind of tag.
3214		 * The Qlogic drivers seem be happy not to use a tag,
3215		 * but this breaks for some devices (IBM drives).
3216		 */
3217		if (XS_TAG_P(xs)) {
3218			((ispreqt2_t *)reqp)->req_flags = XS_TAG_TYPE(xs);
3219		} else {
3220			/*
3221			 * If we don't know what tag to use, use HEAD OF QUEUE
3222			 * for Request Sense or Simple.
3223			 */
3224			if (XS_CDBP(xs)[0] == 0x3)	/* REQUEST SENSE */
3225				((ispreqt2_t *)reqp)->req_flags = REQFLAG_HTAG;
3226			else
3227				((ispreqt2_t *)reqp)->req_flags = REQFLAG_STAG;
3228		}
3229	} else {
3230		sdparam *sdp = (sdparam *)isp->isp_param;
3231		sdp += XS_CHANNEL(xs);
3232		if ((sdp->isp_devparam[target].actv_flags & DPARM_TQING) &&
3233		    XS_TAG_P(xs)) {
3234			reqp->req_flags = XS_TAG_TYPE(xs);
3235		}
3236	}
3237	reqp->req_target = target | (XS_CHANNEL(xs) << 7);
3238	if (IS_SCSI(isp)) {
3239		reqp->req_lun_trn = XS_LUN(xs);
3240		reqp->req_cdblen = XS_CDBLEN(xs);
3241	} else {
3242		if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN)
3243			((ispreqt2_t *)reqp)->req_scclun = XS_LUN(xs);
3244		else
3245			((ispreqt2_t *)reqp)->req_lun_trn = XS_LUN(xs);
3246	}
3247	MEMCPY(reqp->req_cdb, XS_CDBP(xs), XS_CDBLEN(xs));
3248
3249	reqp->req_time = XS_TIME(xs) / 1000;
3250	if (reqp->req_time == 0 && XS_TIME(xs)) {
3251		reqp->req_time = 1;
3252	}
3253
3254	if (isp_save_xs(isp, xs, &handle)) {
3255		isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers");
3256		XS_SETERR(xs, HBA_BOTCH);
3257		return (CMD_EAGAIN);
3258	}
3259	reqp->req_handle = handle;
3260
3261	/*
3262	 * Set up DMA and/or do any bus swizzling of the request entry
3263	 * so that the Qlogic F/W understands what is being asked of it.
3264	 */
3265	i = ISP_DMASETUP(isp, xs, reqp, &nxti, optr);
3266	if (i != CMD_QUEUED) {
3267		isp_destroy_handle(isp, handle);
3268		/*
3269		 * dmasetup sets actual error in packet, and
3270		 * return what we were given to return.
3271		 */
3272		return (i);
3273	}
3274	XS_SETERR(xs, HBA_NOERROR);
3275	isp_prt(isp, ISP_LOGDEBUG2,
3276	    "START cmd for %d.%d.%d cmd 0x%x datalen %ld",
3277	    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), XS_CDBP(xs)[0],
3278	    (long) XS_XFRLEN(xs));
3279	ISP_ADD_REQUEST(isp, nxti);
3280	isp->isp_nactive++;
3281	return (CMD_QUEUED);
3282}
3283
3284/*
3285 * isp control
3286 * Locks (ints blocked) assumed held.
3287 */
3288
3289int
3290isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
3291{
3292	XS_T *xs;
3293	mbreg_t mbs;
3294	int bus, tgt;
3295	u_int16_t handle;
3296
3297	switch (ctl) {
3298	default:
3299		isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
3300		break;
3301
3302	case ISPCTL_RESET_BUS:
3303		/*
3304		 * Issue a bus reset.
3305		 */
3306		mbs.param[0] = MBOX_BUS_RESET;
3307		mbs.param[2] = 0;
3308		if (IS_SCSI(isp)) {
3309			mbs.param[1] =
3310			    ((sdparam *) isp->isp_param)->isp_bus_reset_delay;
3311			if (mbs.param[1] < 2)
3312				mbs.param[1] = 2;
3313			bus = *((int *) arg);
3314			if (IS_DUALBUS(isp))
3315				mbs.param[2] = bus;
3316		} else {
3317			mbs.param[1] = 10;
3318			bus = 0;
3319		}
3320		isp->isp_sendmarker |= (1 << bus);
3321		isp_mboxcmd(isp, &mbs, MBLOGALL);
3322		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3323			break;
3324		}
3325		isp_prt(isp, ISP_LOGINFO,
3326		    "driver initiated bus reset of bus %d", bus);
3327		return (0);
3328
3329	case ISPCTL_RESET_DEV:
3330		tgt = (*((int *) arg)) & 0xffff;
3331		bus = (*((int *) arg)) >> 16;
3332		mbs.param[0] = MBOX_ABORT_TARGET;
3333		mbs.param[1] = (tgt << 8) | (bus << 15);
3334		mbs.param[2] = 3;	/* 'delay', in seconds */
3335		isp_mboxcmd(isp, &mbs, MBLOGALL);
3336		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3337			break;
3338		}
3339		isp_prt(isp, ISP_LOGINFO,
3340		    "Target %d on Bus %d Reset Succeeded", tgt, bus);
3341		isp->isp_sendmarker |= (1 << bus);
3342		return (0);
3343
3344	case ISPCTL_ABORT_CMD:
3345		xs = (XS_T *) arg;
3346		tgt = XS_TGT(xs);
3347		handle = isp_find_handle(isp, xs);
3348		if (handle == 0) {
3349			isp_prt(isp, ISP_LOGWARN,
3350			    "cannot find handle for command to abort");
3351			break;
3352		}
3353		bus = XS_CHANNEL(xs);
3354		mbs.param[0] = MBOX_ABORT;
3355		if (IS_FC(isp)) {
3356			if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN)  {
3357				mbs.param[1] = tgt << 8;
3358				mbs.param[4] = 0;
3359				mbs.param[5] = 0;
3360				mbs.param[6] = XS_LUN(xs);
3361			} else {
3362				mbs.param[1] = tgt << 8 | XS_LUN(xs);
3363			}
3364		} else {
3365			mbs.param[1] =
3366			    (bus << 15) | (XS_TGT(xs) << 8) | XS_LUN(xs);
3367		}
3368		mbs.param[3] = 0;
3369		mbs.param[2] = handle;
3370		isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_ERROR);
3371		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
3372			return (0);
3373		}
3374		/*
3375		 * XXX: Look for command in the REQUEST QUEUE. That is,
3376		 * XXX: It hasen't been picked up by firmware yet.
3377		 */
3378		break;
3379
3380	case ISPCTL_UPDATE_PARAMS:
3381
3382		isp_update(isp);
3383		return (0);
3384
3385	case ISPCTL_FCLINK_TEST:
3386
3387		if (IS_FC(isp)) {
3388			int usdelay = (arg)? *((int *) arg) : 250000;
3389			return (isp_fclink_test(isp, usdelay));
3390		}
3391		break;
3392
3393	case ISPCTL_SCAN_FABRIC:
3394
3395		if (IS_FC(isp)) {
3396			int ftype = (arg)? *((int *) arg) : FC4_SCSI;
3397			return (isp_scan_fabric(isp, ftype));
3398		}
3399		break;
3400
3401	case ISPCTL_SCAN_LOOP:
3402
3403		if (IS_FC(isp)) {
3404			return (isp_scan_loop(isp));
3405		}
3406		break;
3407
3408	case ISPCTL_PDB_SYNC:
3409
3410		if (IS_FC(isp)) {
3411			return (isp_pdb_sync(isp));
3412		}
3413		break;
3414
3415	case ISPCTL_SEND_LIP:
3416
3417		if (IS_FC(isp)) {
3418			mbs.param[0] = MBOX_INIT_LIP;
3419			isp_mboxcmd(isp, &mbs, MBLOGALL);
3420			if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
3421				return (0);
3422			}
3423		}
3424		break;
3425
3426	case ISPCTL_GET_POSMAP:
3427
3428		if (IS_FC(isp) && arg) {
3429			return (isp_getmap(isp, arg));
3430		}
3431		break;
3432
3433	case ISPCTL_RUN_MBOXCMD:
3434
3435		isp_mboxcmd(isp, arg, MBLOGALL);
3436		return(0);
3437
3438#ifdef	ISP_TARGET_MODE
3439	case ISPCTL_TOGGLE_TMODE:
3440	{
3441
3442		/*
3443		 * We don't check/set against role here- that's the
3444		 * responsibility for the outer layer to coordinate.
3445		 */
3446		if (IS_SCSI(isp)) {
3447			int param = *(int *)arg;
3448			mbs.param[0] = MBOX_ENABLE_TARGET_MODE;
3449			mbs.param[1] = param & 0xffff;
3450			mbs.param[2] = param >> 16;
3451			isp_mboxcmd(isp, &mbs, MBLOGALL);
3452			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3453				break;
3454			}
3455		}
3456		return (0);
3457	}
3458#endif
3459	}
3460	return (-1);
3461}
3462
3463/*
3464 * Interrupt Service Routine(s).
3465 *
3466 * External (OS) framework has done the appropriate locking,
3467 * and the locking will be held throughout this function.
3468 */
3469
3470/*
3471 * Limit our stack depth by sticking with the max likely number
3472 * of completions on a request queue at any one time.
3473 */
3474#ifndef	MAX_REQUESTQ_COMPLETIONS
3475#define	MAX_REQUESTQ_COMPLETIONS	64
3476#endif
3477
3478void
3479isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
3480{
3481	XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
3482	u_int16_t iptr, optr, junk;
3483	int i, nlooked = 0, ndone = 0;
3484
3485again:
3486	/*
3487	 * Is this a mailbox related interrupt?
3488	 * The mailbox semaphore will be nonzero if so.
3489	 */
3490	if (sema) {
3491		if (mbox & 0x4000) {
3492			isp->isp_intmboxc++;
3493			if (isp->isp_mboxbsy) {
3494				int i = 0, obits = isp->isp_obits;
3495				isp->isp_mboxtmp[i++] = mbox;
3496				for (i = 1; i < MAX_MAILBOX; i++) {
3497					if ((obits & (1 << i)) == 0) {
3498						continue;
3499					}
3500					isp->isp_mboxtmp[i] =
3501					    ISP_READ(isp, MBOX_OFF(i));
3502				}
3503				if (isp->isp_mbxwrk0) {
3504					if (isp_mbox_continue(isp) == 0) {
3505						return;
3506					}
3507				}
3508				MBOX_NOTIFY_COMPLETE(isp);
3509			} else {
3510				isp_prt(isp, ISP_LOGWARN,
3511				    "Mbox Command Async (0x%x) with no waiters",
3512				    mbox);
3513			}
3514		} else if (isp_parse_async(isp, mbox) < 0) {
3515			return;
3516		}
3517		if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) ||
3518		    isp->isp_state != ISP_RUNSTATE) {
3519			ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
3520			ISP_WRITE(isp, BIU_SEMA, 0);
3521			return;
3522		}
3523	}
3524
3525	/*
3526	 * We can't be getting this now.
3527	 */
3528	if (isp->isp_state != ISP_RUNSTATE) {
3529		isp_prt(isp, ISP_LOGWARN,
3530		    "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema);
3531		/*
3532		 * Thank you very much!  *Burrrp*!
3533		 */
3534		WRITE_RESPONSE_QUEUE_OUT_POINTER(isp,
3535		    READ_RESPONSE_QUEUE_IN_POINTER(isp));
3536
3537		ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
3538		ISP_WRITE(isp, BIU_SEMA, 0);
3539		return;
3540	}
3541
3542	/*
3543	 * Get the current Response Queue Out Pointer.
3544	 *
3545	 * If we're a 2300, we can ask what hardware what it thinks.
3546	 */
3547	if (IS_23XX(isp)) {
3548		optr = ISP_READ(isp, isp->isp_respoutrp);
3549		/*
3550		 * Debug: to be taken out eventually
3551		 */
3552		if (isp->isp_residx != optr) {
3553			isp_prt(isp, ISP_LOGWARN, "optr %x soft optr %x",
3554			    optr, isp->isp_residx);
3555		}
3556	} else {
3557		optr = isp->isp_residx;
3558	}
3559
3560	/*
3561	 * You *must* read the Response Queue In Pointer
3562	 * prior to clearing the RISC interrupt.
3563	 *
3564	 * Debounce the 2300 if revision less than 2.
3565	 */
3566	if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) {
3567		i = 0;
3568		do {
3569			iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
3570			junk = READ_RESPONSE_QUEUE_IN_POINTER(isp);
3571		} while (junk != iptr && ++i < 1000);
3572
3573		if (iptr != junk) {
3574			ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
3575			isp_prt(isp, ISP_LOGWARN,
3576			    "Response Queue Out Pointer Unstable (%x, %x)",
3577			    iptr, junk);
3578			return;
3579		}
3580	} else {
3581		iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
3582	}
3583	isp->isp_resodx = iptr;
3584
3585
3586	if (optr == iptr && sema == 0) {
3587		/*
3588		 * There are a lot of these- reasons unknown- mostly on
3589		 * faster Alpha machines.
3590		 *
3591		 * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to
3592		 * make sure the old interrupt went away (to avoid 'ringing'
3593		 * effects), but that didn't stop this from occurring.
3594		 */
3595		if (IS_23XX(isp)) {
3596			USEC_DELAY(100);
3597			iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
3598			junk = ISP_READ(isp, BIU_R2HSTSLO);
3599		} else {
3600			junk = ISP_READ(isp, BIU_ISR);
3601		}
3602		if (optr == iptr) {
3603			if (IS_23XX(isp)) {
3604				;
3605			} else {
3606				sema = ISP_READ(isp, BIU_SEMA);
3607				mbox = ISP_READ(isp, OUTMAILBOX0);
3608				if ((sema & 0x3) && (mbox & 0x8000)) {
3609					goto again;
3610				}
3611			}
3612			isp->isp_intbogus++;
3613			isp_prt(isp, ISP_LOGDEBUG1,
3614			    "bogus intr- isr %x (%x) iptr %x optr %x",
3615			    isr, junk, iptr, optr);
3616		}
3617	}
3618	isp->isp_resodx = iptr;
3619	ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
3620	ISP_WRITE(isp, BIU_SEMA, 0);
3621
3622	if (isp->isp_rspbsy) {
3623		return;
3624	}
3625	isp->isp_rspbsy = 1;
3626
3627	while (optr != iptr) {
3628		ispstatusreq_t local, *sp = &local;
3629		isphdr_t *hp;
3630		int type;
3631		u_int16_t oop;
3632		int buddaboom = 0;
3633
3634		hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
3635		oop = optr;
3636		optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
3637		nlooked++;
3638		/*
3639		 * Synchronize our view of this response queue entry.
3640		 */
3641		MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN);
3642
3643		type = isp_get_response_type(isp, hp);
3644
3645		if (type == RQSTYPE_RESPONSE) {
3646			isp_get_response(isp, (ispstatusreq_t *) hp, sp);
3647		} else if (type == RQSTYPE_RIO2) {
3648			isp_rio2_t rio;
3649			isp_get_rio2(isp, (isp_rio2_t *) hp, &rio);
3650			for (i = 0; i < rio.req_header.rqs_seqno; i++) {
3651				isp_fastpost_complete(isp, rio.req_handles[i]);
3652			}
3653			if (isp->isp_fpcchiwater < rio.req_header.rqs_seqno)
3654				isp->isp_fpcchiwater = rio.req_header.rqs_seqno;
3655			MEMZERO(hp, QENTRY_LEN);	/* PERF */
3656			continue;
3657		} else {
3658			/*
3659			 * Somebody reachable via isp_handle_other_response
3660			 * may have updated the response queue pointers for
3661			 * us, so we reload our goal index.
3662			 */
3663			if (isp_handle_other_response(isp, type, hp, &optr)) {
3664				iptr = isp->isp_resodx;
3665				MEMZERO(hp, QENTRY_LEN);	/* PERF */
3666				continue;
3667			}
3668
3669			/*
3670			 * After this point, we'll just look at the header as
3671			 * we don't know how to deal with the rest of the
3672			 * response.
3673			 */
3674			isp_get_response(isp, (ispstatusreq_t *) hp, sp);
3675
3676			/*
3677			 * It really has to be a bounced request just copied
3678			 * from the request queue to the response queue. If
3679			 * not, something bad has happened.
3680			 */
3681			if (sp->req_header.rqs_entry_type != RQSTYPE_REQUEST) {
3682				isp_prt(isp, ISP_LOGERR, notresp,
3683				    sp->req_header.rqs_entry_type, oop, optr,
3684				    nlooked);
3685				if (isp->isp_dblev & ISP_LOGDEBUG0) {
3686					isp_print_bytes(isp, "Queue Entry",
3687					    QENTRY_LEN, sp);
3688				}
3689				MEMZERO(hp, QENTRY_LEN);	/* PERF */
3690				continue;
3691			}
3692			buddaboom = 1;
3693		}
3694
3695		if (sp->req_header.rqs_flags & 0xf) {
3696#define	_RQS_OFLAGS	\
3697	~(RQSFLAG_CONTINUATION|RQSFLAG_FULL|RQSFLAG_BADHEADER|RQSFLAG_BADPACKET)
3698			if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
3699				isp_prt(isp, ISP_LOGWARN,
3700				    "continuation segment");
3701				WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
3702				continue;
3703			}
3704			if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
3705				isp_prt(isp, ISP_LOGDEBUG1,
3706				    "internal queues full");
3707				/*
3708				 * We'll synthesize a QUEUE FULL message below.
3709				 */
3710			}
3711			if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
3712				isp_prt(isp, ISP_LOGERR,  "bad header flag");
3713				buddaboom++;
3714			}
3715			if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
3716				isp_prt(isp, ISP_LOGERR, "bad request packet");
3717				buddaboom++;
3718			}
3719			if (sp->req_header.rqs_flags & _RQS_OFLAGS) {
3720				isp_prt(isp, ISP_LOGERR,
3721				    "unknown flags (0x%x) in response",
3722				    sp->req_header.rqs_flags);
3723				buddaboom++;
3724			}
3725#undef	_RQS_OFLAGS
3726		}
3727		if (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1) {
3728			MEMZERO(hp, QENTRY_LEN);	/* PERF */
3729			isp_prt(isp, ISP_LOGERR,
3730			    "bad request handle %d (type 0x%x, flags 0x%x)",
3731			    sp->req_handle, sp->req_header.rqs_entry_type,
3732			    sp->req_header.rqs_flags);
3733			WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
3734			continue;
3735		}
3736		xs = isp_find_xs(isp, sp->req_handle);
3737		if (xs == NULL) {
3738			u_int8_t ts = sp->req_completion_status & 0xff;
3739			MEMZERO(hp, QENTRY_LEN);	/* PERF */
3740			/*
3741			 * Only whine if this isn't the expected fallout of
3742			 * aborting the command.
3743			 */
3744			if (sp->req_header.rqs_entry_type != RQSTYPE_RESPONSE) {
3745				isp_prt(isp, ISP_LOGERR,
3746				    "cannot find handle 0x%x (type 0x%x)",
3747				    sp->req_handle,
3748				    sp->req_header.rqs_entry_type);
3749			} else if (ts != RQCS_ABORTED) {
3750				isp_prt(isp, ISP_LOGERR,
3751				    "cannot find handle 0x%x (status 0x%x)",
3752				    sp->req_handle, ts);
3753			}
3754			WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
3755			continue;
3756		}
3757		isp_destroy_handle(isp, sp->req_handle);
3758		if (sp->req_status_flags & RQSTF_BUS_RESET) {
3759			XS_SETERR(xs, HBA_BUSRESET);
3760			isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
3761		}
3762		if (buddaboom) {
3763			XS_SETERR(xs, HBA_BOTCH);
3764		}
3765
3766		if (IS_FC(isp) && (sp->req_scsi_status & RQCS_SV)) {
3767			/*
3768			 * Fibre Channel F/W doesn't say we got status
3769			 * if there's Sense Data instead. I guess they
3770			 * think it goes w/o saying.
3771			 */
3772			sp->req_state_flags |= RQSF_GOT_STATUS;
3773		}
3774		if (sp->req_state_flags & RQSF_GOT_STATUS) {
3775			*XS_STSP(xs) = sp->req_scsi_status & 0xff;
3776		}
3777
3778		switch (sp->req_header.rqs_entry_type) {
3779		case RQSTYPE_RESPONSE:
3780			XS_SET_STATE_STAT(isp, xs, sp);
3781			isp_parse_status(isp, sp, xs);
3782			if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) &&
3783			    (*XS_STSP(xs) == SCSI_BUSY)) {
3784				XS_SETERR(xs, HBA_TGTBSY);
3785			}
3786			if (IS_SCSI(isp)) {
3787				XS_RESID(xs) = sp->req_resid;
3788				if ((sp->req_state_flags & RQSF_GOT_STATUS) &&
3789				    (*XS_STSP(xs) == SCSI_CHECK) &&
3790				    (sp->req_state_flags & RQSF_GOT_SENSE)) {
3791					XS_SAVE_SENSE(xs, sp);
3792				}
3793				/*
3794				 * A new synchronous rate was negotiated for
3795				 * this target. Mark state such that we'll go
3796				 * look up that which has changed later.
3797				 */
3798				if (sp->req_status_flags & RQSTF_NEGOTIATION) {
3799					int t = XS_TGT(xs);
3800					sdparam *sdp = isp->isp_param;
3801					sdp += XS_CHANNEL(xs);
3802					sdp->isp_devparam[t].dev_refresh = 1;
3803					isp->isp_update |=
3804					    (1 << XS_CHANNEL(xs));
3805				}
3806			} else {
3807				if (sp->req_status_flags & RQSF_XFER_COMPLETE) {
3808					XS_RESID(xs) = 0;
3809				} else if (sp->req_scsi_status & RQCS_RESID) {
3810					XS_RESID(xs) = sp->req_resid;
3811				} else {
3812					XS_RESID(xs) = 0;
3813				}
3814				if ((sp->req_state_flags & RQSF_GOT_STATUS) &&
3815				    (*XS_STSP(xs) == SCSI_CHECK) &&
3816				    (sp->req_scsi_status & RQCS_SV)) {
3817					XS_SAVE_SENSE(xs, sp);
3818					/* solely for the benefit of debug */
3819					sp->req_state_flags |= RQSF_GOT_SENSE;
3820				}
3821			}
3822			isp_prt(isp, ISP_LOGDEBUG2,
3823			   "asked for %ld got resid %ld", (long) XS_XFRLEN(xs),
3824			   (long) sp->req_resid);
3825			break;
3826		case RQSTYPE_REQUEST:
3827			if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
3828				/*
3829				 * Force Queue Full status.
3830				 */
3831				*XS_STSP(xs) = SCSI_QFULL;
3832				XS_SETERR(xs, HBA_NOERROR);
3833			} else if (XS_NOERR(xs)) {
3834				/*
3835				 * ????
3836				 */
3837				isp_prt(isp, ISP_LOGDEBUG0,
3838				    "Request Queue Entry bounced back");
3839				XS_SETERR(xs, HBA_BOTCH);
3840			}
3841			XS_RESID(xs) = XS_XFRLEN(xs);
3842			break;
3843		default:
3844			isp_prt(isp, ISP_LOGWARN,
3845			    "unhandled response queue type 0x%x",
3846			    sp->req_header.rqs_entry_type);
3847			if (XS_NOERR(xs)) {
3848				XS_SETERR(xs, HBA_BOTCH);
3849			}
3850			break;
3851		}
3852
3853		/*
3854		 * Free any dma resources. As a side effect, this may
3855		 * also do any cache flushing necessary for data coherence.			 */
3856		if (XS_XFRLEN(xs)) {
3857			ISP_DMAFREE(isp, xs, sp->req_handle);
3858		}
3859
3860		if (((isp->isp_dblev & (ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
3861		    ((isp->isp_dblev & ISP_LOGDEBUG1) && ((!XS_NOERR(xs)) ||
3862		    (*XS_STSP(xs) != SCSI_GOOD)))) {
3863			char skey;
3864			if (sp->req_state_flags & RQSF_GOT_SENSE) {
3865				skey = XS_SNSKEY(xs) & 0xf;
3866				if (skey < 10)
3867					skey += '0';
3868				else
3869					skey += 'a' - 10;
3870			} else if (*XS_STSP(xs) == SCSI_CHECK) {
3871				skey = '?';
3872			} else {
3873				skey = '.';
3874			}
3875			isp_prt(isp, ISP_LOGALL, finmsg, XS_CHANNEL(xs),
3876			    XS_TGT(xs), XS_LUN(xs), XS_XFRLEN(xs), XS_RESID(xs),
3877			    *XS_STSP(xs), skey, XS_ERR(xs));
3878		}
3879
3880		if (isp->isp_nactive > 0)
3881		    isp->isp_nactive--;
3882		complist[ndone++] = xs;	/* defer completion call until later */
3883		MEMZERO(hp, QENTRY_LEN);	/* PERF */
3884		if (ndone == MAX_REQUESTQ_COMPLETIONS) {
3885			break;
3886		}
3887	}
3888
3889	/*
3890	 * If we looked at any commands, then it's valid to find out
3891	 * what the outpointer is. It also is a trigger to update the
3892	 * ISP's notion of what we've seen so far.
3893	 */
3894	if (nlooked) {
3895		WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
3896		/*
3897		 * While we're at it, read the requst queue out pointer.
3898		 */
3899		isp->isp_reqodx = READ_REQUEST_QUEUE_OUT_POINTER(isp);
3900		if (isp->isp_rscchiwater < ndone)
3901			isp->isp_rscchiwater = ndone;
3902	}
3903
3904	isp->isp_residx = optr;
3905	isp->isp_rspbsy = 0;
3906	for (i = 0; i < ndone; i++) {
3907		xs = complist[i];
3908		if (xs) {
3909			isp->isp_rsltccmplt++;
3910			isp_done(xs);
3911		}
3912	}
3913}
3914
3915/*
3916 * Support routines.
3917 */
3918
3919static int
3920isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
3921{
3922	int rval = 0;
3923	int bus;
3924
3925	if (IS_DUALBUS(isp)) {
3926		bus = ISP_READ(isp, OUTMAILBOX6);
3927	} else {
3928		bus = 0;
3929	}
3930	isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
3931
3932	switch (mbox) {
3933	case ASYNC_BUS_RESET:
3934		isp->isp_sendmarker |= (1 << bus);
3935#ifdef	ISP_TARGET_MODE
3936		if (isp_target_async(isp, bus, mbox))
3937			rval = -1;
3938#endif
3939		isp_async(isp, ISPASYNC_BUS_RESET, &bus);
3940		break;
3941	case ASYNC_SYSTEM_ERROR:
3942#ifdef	ISP_FW_CRASH_DUMP
3943		/*
3944		 * If we have crash dumps enabled, it's up to the handler
3945		 * for isp_async to reinit stuff and restart the firmware
3946		 * after performing the crash dump. The reason we do things
3947		 * this way is that we may need to activate a kernel thread
3948		 * to do all the crash dump goop.
3949		 */
3950		isp_async(isp, ISPASYNC_FW_CRASH, NULL);
3951#else
3952		isp_async(isp, ISPASYNC_FW_CRASH, NULL);
3953		isp_reinit(isp);
3954		isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
3955#endif
3956		rval = -1;
3957		break;
3958
3959	case ASYNC_RQS_XFER_ERR:
3960		isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
3961		break;
3962
3963	case ASYNC_RSP_XFER_ERR:
3964		isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
3965		break;
3966
3967	case ASYNC_QWAKEUP:
3968		/*
3969		 * We've just been notified that the Queue has woken up.
3970		 * We don't need to be chatty about this- just unlatch things
3971		 * and move on.
3972		 */
3973		mbox = READ_REQUEST_QUEUE_OUT_POINTER(isp);
3974		break;
3975
3976	case ASYNC_TIMEOUT_RESET:
3977		isp_prt(isp, ISP_LOGWARN,
3978		    "timeout initiated SCSI bus reset of bus %d", bus);
3979		isp->isp_sendmarker |= (1 << bus);
3980#ifdef	ISP_TARGET_MODE
3981		if (isp_target_async(isp, bus, mbox))
3982			rval = -1;
3983#endif
3984		break;
3985
3986	case ASYNC_DEVICE_RESET:
3987		isp_prt(isp, ISP_LOGINFO, "device reset on bus %d", bus);
3988		isp->isp_sendmarker |= (1 << bus);
3989#ifdef	ISP_TARGET_MODE
3990		if (isp_target_async(isp, bus, mbox))
3991			rval = -1;
3992#endif
3993		break;
3994
3995	case ASYNC_EXTMSG_UNDERRUN:
3996		isp_prt(isp, ISP_LOGWARN, "extended message underrun");
3997		break;
3998
3999	case ASYNC_SCAM_INT:
4000		isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
4001		break;
4002
4003	case ASYNC_HUNG_SCSI:
4004		isp_prt(isp, ISP_LOGERR,
4005		    "stalled SCSI Bus after DATA Overrun");
4006		/* XXX: Need to issue SCSI reset at this point */
4007		break;
4008
4009	case ASYNC_KILLED_BUS:
4010		isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
4011		break;
4012
4013	case ASYNC_BUS_TRANSIT:
4014		mbox = ISP_READ(isp, OUTMAILBOX2);
4015		switch (mbox & 0x1c00) {
4016		case SXP_PINS_LVD_MODE:
4017			isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
4018			SDPARAM(isp)->isp_diffmode = 0;
4019			SDPARAM(isp)->isp_ultramode = 0;
4020			SDPARAM(isp)->isp_lvdmode = 1;
4021			break;
4022		case SXP_PINS_HVD_MODE:
4023			isp_prt(isp, ISP_LOGINFO,
4024			    "Transition to Differential mode");
4025			SDPARAM(isp)->isp_diffmode = 1;
4026			SDPARAM(isp)->isp_ultramode = 0;
4027			SDPARAM(isp)->isp_lvdmode = 0;
4028			break;
4029		case SXP_PINS_SE_MODE:
4030			isp_prt(isp, ISP_LOGINFO,
4031			    "Transition to Single Ended mode");
4032			SDPARAM(isp)->isp_diffmode = 0;
4033			SDPARAM(isp)->isp_ultramode = 1;
4034			SDPARAM(isp)->isp_lvdmode = 0;
4035			break;
4036		default:
4037			isp_prt(isp, ISP_LOGWARN,
4038			    "Transition to Unknown Mode 0x%x", mbox);
4039			break;
4040		}
4041		/*
4042		 * XXX: Set up to renegotiate again!
4043		 */
4044		/* Can only be for a 1080... */
4045		isp->isp_sendmarker |= (1 << bus);
4046		break;
4047
4048	/*
4049	 * We can use bus, which will always be zero for FC cards,
4050	 * as a mailbox pattern accumulator to be checked below.
4051	 */
4052	case ASYNC_RIO5:
4053		bus = 0x1ce;	/* outgoing mailbox regs 1-3, 6-7 */
4054		break;
4055
4056	case ASYNC_RIO4:
4057		bus = 0x14e;	/* outgoing mailbox regs 1-3, 6 */
4058		break;
4059
4060	case ASYNC_RIO3:
4061		bus = 0x10e;	/* outgoing mailbox regs 1-3 */
4062		break;
4063
4064	case ASYNC_RIO2:
4065		bus = 0x106;	/* outgoing mailbox regs 1-2 */
4066		break;
4067
4068	case ASYNC_RIO1:
4069	case ASYNC_CMD_CMPLT:
4070		bus = 0x102;	/* outgoing mailbox regs 1 */
4071		break;
4072
4073	case ASYNC_RIO_RESP:
4074		return (rval);
4075
4076	case ASYNC_CTIO_DONE:
4077	{
4078#ifdef	ISP_TARGET_MODE
4079		int handle =
4080		    (ISP_READ(isp, OUTMAILBOX2) << 16) |
4081		    (ISP_READ(isp, OUTMAILBOX1));
4082		if (isp_target_async(isp, handle, mbox))
4083			rval = -1;
4084#else
4085		isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
4086#endif
4087		isp->isp_fphccmplt++;	/* count it as a fast posting intr */
4088		break;
4089	}
4090	case ASYNC_LIP_F8:
4091	case ASYNC_LIP_OCCURRED:
4092		FCPARAM(isp)->isp_lipseq =
4093		    ISP_READ(isp, OUTMAILBOX1);
4094		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
4095		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
4096		isp->isp_sendmarker = 1;
4097		isp_mark_getpdb_all(isp);
4098		isp_async(isp, ISPASYNC_LIP, NULL);
4099#ifdef	ISP_TARGET_MODE
4100		if (isp_target_async(isp, bus, mbox))
4101			rval = -1;
4102#endif
4103		/*
4104		 * We've had problems with data corruption occuring on
4105		 * commands that complete (with no apparent error) after
4106		 * we receive a LIP. This has been observed mostly on
4107		 * Local Loop topologies. To be safe, let's just mark
4108		 * all active commands as dead.
4109		 */
4110		if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
4111		    FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
4112			int i, j;
4113			for (i = j = 0; i < isp->isp_maxcmds; i++) {
4114				XS_T *xs;
4115				xs = isp->isp_xflist[i];
4116				if (xs != NULL) {
4117					j++;
4118					XS_SETERR(xs, HBA_BUSRESET);
4119				}
4120			}
4121			if (j) {
4122				isp_prt(isp, ISP_LOGERR,
4123				    "LIP destroyed %d active commands", j);
4124			}
4125		}
4126		break;
4127
4128	case ASYNC_LOOP_UP:
4129		isp->isp_sendmarker = 1;
4130		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
4131		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
4132		isp_mark_getpdb_all(isp);
4133		isp_async(isp, ISPASYNC_LOOP_UP, NULL);
4134#ifdef	ISP_TARGET_MODE
4135		if (isp_target_async(isp, bus, mbox))
4136			rval = -1;
4137#endif
4138		break;
4139
4140	case ASYNC_LOOP_DOWN:
4141		isp->isp_sendmarker = 1;
4142		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
4143		FCPARAM(isp)->isp_loopstate = LOOP_NIL;
4144		isp_mark_getpdb_all(isp);
4145		isp_async(isp, ISPASYNC_LOOP_DOWN, NULL);
4146#ifdef	ISP_TARGET_MODE
4147		if (isp_target_async(isp, bus, mbox))
4148			rval = -1;
4149#endif
4150		break;
4151
4152	case ASYNC_LOOP_RESET:
4153		isp->isp_sendmarker = 1;
4154		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
4155		FCPARAM(isp)->isp_loopstate = LOOP_NIL;
4156		isp_mark_getpdb_all(isp);
4157		isp_async(isp, ISPASYNC_LOOP_RESET, NULL);
4158#ifdef	ISP_TARGET_MODE
4159		if (isp_target_async(isp, bus, mbox))
4160			rval = -1;
4161#endif
4162		break;
4163
4164	case ASYNC_PDB_CHANGED:
4165		isp->isp_sendmarker = 1;
4166		FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
4167		isp_mark_getpdb_all(isp);
4168		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_PDB);
4169		break;
4170
4171	case ASYNC_CHANGE_NOTIFY:
4172		/*
4173		 * Not correct, but it will force us to rescan the loop.
4174		 */
4175		FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
4176		isp_mark_getpdb_all(isp);
4177		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_SNS);
4178		break;
4179
4180	case ASYNC_PTPMODE:
4181		if (FCPARAM(isp)->isp_onfabric)
4182			FCPARAM(isp)->isp_topo = TOPO_F_PORT;
4183		else
4184			FCPARAM(isp)->isp_topo = TOPO_N_PORT;
4185		isp_mark_getpdb_all(isp);
4186		isp->isp_sendmarker = 1;
4187		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
4188		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
4189		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
4190#ifdef	ISP_TARGET_MODE
4191		if (isp_target_async(isp, bus, mbox))
4192			rval = -1;
4193#endif
4194		isp_prt(isp, ISP_LOGINFO, "Point-to-Point mode");
4195		break;
4196
4197	case ASYNC_CONNMODE:
4198		mbox = ISP_READ(isp, OUTMAILBOX1);
4199		isp_mark_getpdb_all(isp);
4200		switch (mbox) {
4201		case ISP_CONN_LOOP:
4202			isp_prt(isp, ISP_LOGINFO,
4203			    "Point-to-Point -> Loop mode");
4204			break;
4205		case ISP_CONN_PTP:
4206			isp_prt(isp, ISP_LOGINFO,
4207			    "Loop -> Point-to-Point mode");
4208			break;
4209		case ISP_CONN_BADLIP:
4210			isp_prt(isp, ISP_LOGWARN,
4211			    "Point-to-Point -> Loop mode (BAD LIP)");
4212			break;
4213		case ISP_CONN_FATAL:
4214			isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
4215			isp_async(isp, ISPASYNC_FW_CRASH, NULL);
4216			isp_reinit(isp);
4217			isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
4218			return (-1);
4219		case ISP_CONN_LOOPBACK:
4220			isp_prt(isp, ISP_LOGWARN,
4221			    "Looped Back in Point-to-Point mode");
4222			break;
4223		default:
4224			isp_prt(isp, ISP_LOGWARN,
4225			    "Unknown connection mode (0x%x)", mbox);
4226			break;
4227		}
4228		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
4229		isp->isp_sendmarker = 1;
4230		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
4231		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
4232		break;
4233
4234	default:
4235		isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
4236		break;
4237	}
4238
4239	if (bus & 0x100) {
4240		int i, nh;
4241		u_int16_t handles[5];
4242
4243		for (nh = 0, i = 1; i < MAX_MAILBOX; i++) {
4244			if ((bus & (1 << i)) == 0) {
4245				continue;
4246			}
4247			handles[nh++] = ISP_READ(isp, MBOX_OFF(i));
4248		}
4249		for (i = 0; i < nh; i++) {
4250			isp_fastpost_complete(isp, handles[i]);
4251			isp_prt(isp,  ISP_LOGDEBUG3,
4252			    "fast post completion of %u", handles[i]);
4253		}
4254		if (isp->isp_fpcchiwater < nh)
4255			isp->isp_fpcchiwater = nh;
4256	} else {
4257		isp->isp_intoasync++;
4258	}
4259	return (rval);
4260}
4261
4262/*
4263 * Handle other response entries. A pointer to the request queue output
4264 * index is here in case we want to eat several entries at once, although
4265 * this is not used currently.
4266 */
4267
4268static int
4269isp_handle_other_response(struct ispsoftc *isp, int type,
4270    isphdr_t *hp, u_int16_t *optrp)
4271{
4272	switch (type) {
4273	case RQSTYPE_STATUS_CONT:
4274		isp_prt(isp, ISP_LOGINFO, "Ignored Continuation Response");
4275		return (1);
4276	case RQSTYPE_ATIO:
4277	case RQSTYPE_CTIO:
4278	case RQSTYPE_ENABLE_LUN:
4279	case RQSTYPE_MODIFY_LUN:
4280	case RQSTYPE_NOTIFY:
4281	case RQSTYPE_NOTIFY_ACK:
4282	case RQSTYPE_CTIO1:
4283	case RQSTYPE_ATIO2:
4284	case RQSTYPE_CTIO2:
4285	case RQSTYPE_CTIO3:
4286		isp->isp_rsltccmplt++;	/* count as a response completion */
4287#ifdef	ISP_TARGET_MODE
4288		if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
4289			return (1);
4290		}
4291#else
4292		optrp = optrp;
4293		/* FALLTHROUGH */
4294#endif
4295	case RQSTYPE_REQUEST:
4296	default:
4297		if (isp_async(isp, ISPASYNC_UNHANDLED_RESPONSE, hp)) {
4298			return (1);
4299		}
4300		isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
4301		    isp_get_response_type(isp, hp));
4302		return (0);
4303	}
4304}
4305
4306static void
4307isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs)
4308{
4309	switch (sp->req_completion_status & 0xff) {
4310	case RQCS_COMPLETE:
4311		if (XS_NOERR(xs)) {
4312			XS_SETERR(xs, HBA_NOERROR);
4313		}
4314		return;
4315
4316	case RQCS_INCOMPLETE:
4317		if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
4318			isp_prt(isp, ISP_LOGDEBUG1,
4319			    "Selection Timeout for %d.%d.%d",
4320			    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4321			if (XS_NOERR(xs)) {
4322				XS_SETERR(xs, HBA_SELTIMEOUT);
4323			}
4324			return;
4325		}
4326		isp_prt(isp, ISP_LOGERR,
4327		    "command incomplete for %d.%d.%d, state 0x%x",
4328		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
4329		    sp->req_state_flags);
4330		break;
4331
4332	case RQCS_DMA_ERROR:
4333		isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
4334		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4335		break;
4336
4337	case RQCS_TRANSPORT_ERROR:
4338	{
4339		char buf[172];
4340		SNPRINTF(buf, sizeof (buf), "states=>");
4341		if (sp->req_state_flags & RQSF_GOT_BUS) {
4342			SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
4343		}
4344		if (sp->req_state_flags & RQSF_GOT_TARGET) {
4345			SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
4346		}
4347		if (sp->req_state_flags & RQSF_SENT_CDB) {
4348			SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
4349		}
4350		if (sp->req_state_flags & RQSF_XFRD_DATA) {
4351			SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
4352		}
4353		if (sp->req_state_flags & RQSF_GOT_STATUS) {
4354			SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
4355		}
4356		if (sp->req_state_flags & RQSF_GOT_SENSE) {
4357			SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
4358		}
4359		if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
4360			SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
4361		}
4362		SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
4363		if (sp->req_status_flags & RQSTF_DISCONNECT) {
4364			SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
4365		}
4366		if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
4367			SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
4368		}
4369		if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
4370			SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
4371		}
4372		if (sp->req_status_flags & RQSTF_BUS_RESET) {
4373			SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
4374		}
4375		if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
4376			SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
4377		}
4378		if (sp->req_status_flags & RQSTF_ABORTED) {
4379			SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
4380		}
4381		if (sp->req_status_flags & RQSTF_TIMEOUT) {
4382			SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
4383		}
4384		if (sp->req_status_flags & RQSTF_NEGOTIATION) {
4385			SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
4386		}
4387		isp_prt(isp, ISP_LOGERR, "%s", buf);
4388		isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s",
4389		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), buf);
4390		break;
4391	}
4392	case RQCS_RESET_OCCURRED:
4393		isp_prt(isp, ISP_LOGWARN,
4394		    "bus reset destroyed command for %d.%d.%d",
4395		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4396		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
4397		if (XS_NOERR(xs)) {
4398			XS_SETERR(xs, HBA_BUSRESET);
4399		}
4400		return;
4401
4402	case RQCS_ABORTED:
4403		isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d",
4404		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4405		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
4406		if (XS_NOERR(xs)) {
4407			XS_SETERR(xs, HBA_ABORTED);
4408		}
4409		return;
4410
4411	case RQCS_TIMEOUT:
4412		isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
4413		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4414		/*
4415	 	 * Check to see if we logged out the device.
4416		 */
4417		if (IS_FC(isp)) {
4418			if ((sp->req_completion_status & RQSTF_LOGOUT) &&
4419			    FCPARAM(isp)->portdb[XS_TGT(xs)].valid &&
4420			    FCPARAM(isp)->portdb[XS_TGT(xs)].fabric_dev) {
4421				FCPARAM(isp)->portdb[XS_TGT(xs)].relogin = 1;
4422			}
4423		}
4424		if (XS_NOERR(xs)) {
4425			XS_SETERR(xs, HBA_CMDTIMEOUT);
4426		}
4427		return;
4428
4429	case RQCS_DATA_OVERRUN:
4430		XS_RESID(xs) = sp->req_resid;
4431		isp_prt(isp, ISP_LOGERR, "data overrun for command on %d.%d.%d",
4432		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4433		if (XS_NOERR(xs)) {
4434			XS_SETERR(xs, HBA_DATAOVR);
4435		}
4436		return;
4437
4438	case RQCS_COMMAND_OVERRUN:
4439		isp_prt(isp, ISP_LOGERR,
4440		    "command overrun for command on %d.%d.%d",
4441		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4442		break;
4443
4444	case RQCS_STATUS_OVERRUN:
4445		isp_prt(isp, ISP_LOGERR,
4446		    "status overrun for command on %d.%d.%d",
4447		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4448		break;
4449
4450	case RQCS_BAD_MESSAGE:
4451		isp_prt(isp, ISP_LOGERR,
4452		    "msg not COMMAND COMPLETE after status %d.%d.%d",
4453		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4454		break;
4455
4456	case RQCS_NO_MESSAGE_OUT:
4457		isp_prt(isp, ISP_LOGERR,
4458		    "No MESSAGE OUT phase after selection on %d.%d.%d",
4459		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4460		break;
4461
4462	case RQCS_EXT_ID_FAILED:
4463		isp_prt(isp, ISP_LOGERR, "EXTENDED IDENTIFY failed %d.%d.%d",
4464		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4465		break;
4466
4467	case RQCS_IDE_MSG_FAILED:
4468		isp_prt(isp, ISP_LOGERR,
4469		    "INITIATOR DETECTED ERROR rejected by %d.%d.%d",
4470		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4471		break;
4472
4473	case RQCS_ABORT_MSG_FAILED:
4474		isp_prt(isp, ISP_LOGERR, "ABORT OPERATION rejected by %d.%d.%d",
4475		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4476		break;
4477
4478	case RQCS_REJECT_MSG_FAILED:
4479		isp_prt(isp, ISP_LOGERR, "MESSAGE REJECT rejected by %d.%d.%d",
4480		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4481		break;
4482
4483	case RQCS_NOP_MSG_FAILED:
4484		isp_prt(isp, ISP_LOGERR, "NOP rejected by %d.%d.%d",
4485		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4486		break;
4487
4488	case RQCS_PARITY_ERROR_MSG_FAILED:
4489		isp_prt(isp, ISP_LOGERR,
4490		    "MESSAGE PARITY ERROR rejected by %d.%d.%d",
4491		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4492		break;
4493
4494	case RQCS_DEVICE_RESET_MSG_FAILED:
4495		isp_prt(isp, ISP_LOGWARN,
4496		    "BUS DEVICE RESET rejected by %d.%d.%d",
4497		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4498		break;
4499
4500	case RQCS_ID_MSG_FAILED:
4501		isp_prt(isp, ISP_LOGERR, "IDENTIFY rejected by %d.%d.%d",
4502		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4503		break;
4504
4505	case RQCS_UNEXP_BUS_FREE:
4506		isp_prt(isp, ISP_LOGERR, "%d.%d.%d had an unexpected bus free",
4507		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4508		break;
4509
4510	case RQCS_DATA_UNDERRUN:
4511	{
4512		if (IS_FC(isp)) {
4513			int ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
4514			if (!ru_marked || sp->req_resid > XS_XFRLEN(xs)) {
4515				isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs),
4516				    XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid,
4517				    (ru_marked)? "marked" : "not marked");
4518				if (XS_NOERR(xs)) {
4519					XS_SETERR(xs, HBA_BOTCH);
4520				}
4521				return;
4522			}
4523		}
4524		XS_RESID(xs) = sp->req_resid;
4525		if (XS_NOERR(xs)) {
4526			XS_SETERR(xs, HBA_NOERROR);
4527		}
4528		return;
4529	}
4530
4531	case RQCS_XACT_ERR1:
4532		isp_prt(isp, ISP_LOGERR, xact1, XS_CHANNEL(xs),
4533		    XS_TGT(xs), XS_LUN(xs));
4534		break;
4535
4536	case RQCS_XACT_ERR2:
4537		isp_prt(isp, ISP_LOGERR, xact2,
4538		    XS_LUN(xs), XS_TGT(xs), XS_CHANNEL(xs));
4539		break;
4540
4541	case RQCS_XACT_ERR3:
4542		isp_prt(isp, ISP_LOGERR, xact3,
4543		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4544		break;
4545
4546	case RQCS_BAD_ENTRY:
4547		isp_prt(isp, ISP_LOGERR, "Invalid IOCB entry type detected");
4548		break;
4549
4550	case RQCS_QUEUE_FULL:
4551		isp_prt(isp, ISP_LOGDEBUG0,
4552		    "internal queues full for %d.%d.%d status 0x%x",
4553		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), *XS_STSP(xs));
4554
4555		/*
4556		 * If QFULL or some other status byte is set, then this
4557		 * isn't an error, per se.
4558		 *
4559		 * Unfortunately, some QLogic f/w writers have, in
4560		 * some cases, ommitted to *set* status to QFULL.
4561		 *
4562
4563		if (*XS_STSP(xs) != SCSI_GOOD && XS_NOERR(xs)) {
4564			XS_SETERR(xs, HBA_NOERROR);
4565			return;
4566		}
4567
4568		 *
4569		 *
4570		 */
4571
4572		*XS_STSP(xs) = SCSI_QFULL;
4573		XS_SETERR(xs, HBA_NOERROR);
4574		return;
4575
4576	case RQCS_PHASE_SKIPPED:
4577		isp_prt(isp, ISP_LOGERR, pskip, XS_CHANNEL(xs),
4578		    XS_TGT(xs), XS_LUN(xs));
4579		break;
4580
4581	case RQCS_ARQS_FAILED:
4582		isp_prt(isp, ISP_LOGERR,
4583		    "Auto Request Sense failed for %d.%d.%d",
4584		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4585		if (XS_NOERR(xs)) {
4586			XS_SETERR(xs, HBA_ARQFAIL);
4587		}
4588		return;
4589
4590	case RQCS_WIDE_FAILED:
4591		isp_prt(isp, ISP_LOGERR,
4592		    "Wide Negotiation failed for %d.%d.%d",
4593		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
4594		if (IS_SCSI(isp)) {
4595			sdparam *sdp = isp->isp_param;
4596			sdp += XS_CHANNEL(xs);
4597			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_WIDE;
4598			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
4599			isp->isp_update |= (1 << XS_CHANNEL(xs));
4600		}
4601		if (XS_NOERR(xs)) {
4602			XS_SETERR(xs, HBA_NOERROR);
4603		}
4604		return;
4605
4606	case RQCS_SYNCXFER_FAILED:
4607		isp_prt(isp, ISP_LOGERR,
4608		    "SDTR Message failed for target %d.%d.%d",
4609		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
4610		if (IS_SCSI(isp)) {
4611			sdparam *sdp = isp->isp_param;
4612			sdp += XS_CHANNEL(xs);
4613			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_SYNC;
4614			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
4615			isp->isp_update |= (1 << XS_CHANNEL(xs));
4616		}
4617		break;
4618
4619	case RQCS_LVD_BUSERR:
4620		isp_prt(isp, ISP_LOGERR,
4621		    "Bad LVD condition while talking to %d.%d.%d",
4622		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
4623		break;
4624
4625	case RQCS_PORT_UNAVAILABLE:
4626		/*
4627		 * No such port on the loop. Moral equivalent of SELTIMEO
4628		 */
4629	case RQCS_PORT_LOGGED_OUT:
4630		/*
4631		 * It was there (maybe)- treat as a selection timeout.
4632		 */
4633		if ((sp->req_completion_status & 0xff) == RQCS_PORT_UNAVAILABLE)
4634			isp_prt(isp, ISP_LOGINFO,
4635			    "port unavailable for target %d", XS_TGT(xs));
4636		else
4637			isp_prt(isp, ISP_LOGINFO,
4638			    "port logout for target %d", XS_TGT(xs));
4639		/*
4640		 * If we're on a local loop, force a LIP (which is overkill)
4641		 * to force a re-login of this unit. If we're on fabric,
4642		 * then we'll have to relogin as a matter of course.
4643		 */
4644		if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
4645		    FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
4646			mbreg_t mbs;
4647			mbs.param[0] = MBOX_INIT_LIP;
4648			isp_mboxcmd_qnw(isp, &mbs, 1);
4649		}
4650
4651		/*
4652		 * Probably overkill.
4653		 */
4654		isp->isp_sendmarker = 1;
4655		FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
4656		isp_mark_getpdb_all(isp);
4657		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
4658		if (XS_NOERR(xs)) {
4659			XS_SETERR(xs, HBA_SELTIMEOUT);
4660		}
4661		return;
4662
4663	case RQCS_PORT_CHANGED:
4664		isp_prt(isp, ISP_LOGWARN,
4665		    "port changed for target %d", XS_TGT(xs));
4666		if (XS_NOERR(xs)) {
4667			XS_SETERR(xs, HBA_SELTIMEOUT);
4668		}
4669		return;
4670
4671	case RQCS_PORT_BUSY:
4672		isp_prt(isp, ISP_LOGWARN,
4673		    "port busy for target %d", XS_TGT(xs));
4674		if (XS_NOERR(xs)) {
4675			XS_SETERR(xs, HBA_TGTBSY);
4676		}
4677		return;
4678
4679	default:
4680		isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
4681		    sp->req_completion_status);
4682		break;
4683	}
4684	if (XS_NOERR(xs)) {
4685		XS_SETERR(xs, HBA_BOTCH);
4686	}
4687}
4688
4689static void
4690isp_fastpost_complete(struct ispsoftc *isp, u_int16_t fph)
4691{
4692	XS_T *xs;
4693
4694	if (fph == 0) {
4695		return;
4696	}
4697	xs = isp_find_xs(isp, fph);
4698	if (xs == NULL) {
4699		isp_prt(isp, ISP_LOGWARN,
4700		    "Command for fast post handle 0x%x not found", fph);
4701		return;
4702	}
4703	isp_destroy_handle(isp, fph);
4704
4705	/*
4706	 * Since we don't have a result queue entry item,
4707	 * we must believe that SCSI status is zero and
4708	 * that all data transferred.
4709	 */
4710	XS_SET_STATE_STAT(isp, xs, NULL);
4711	XS_RESID(xs) = 0;
4712	*XS_STSP(xs) = SCSI_GOOD;
4713	if (XS_XFRLEN(xs)) {
4714		ISP_DMAFREE(isp, xs, fph);
4715	}
4716	if (isp->isp_nactive)
4717		isp->isp_nactive--;
4718	isp->isp_fphccmplt++;
4719	isp_done(xs);
4720}
4721
4722static int
4723isp_mbox_continue(struct ispsoftc *isp)
4724{
4725	mbreg_t mbs;
4726	u_int16_t *ptr;
4727
4728	switch (isp->isp_lastmbxcmd) {
4729	case MBOX_WRITE_RAM_WORD:
4730	case MBOX_READ_RAM_WORD:
4731	case MBOX_READ_RAM_WORD_EXTENDED:
4732		break;
4733	default:
4734		return (1);
4735	}
4736	if (isp->isp_mboxtmp[0] != MBOX_COMMAND_COMPLETE) {
4737		isp->isp_mbxwrk0 = 0;
4738		return (-1);
4739	}
4740
4741
4742	/*
4743	 * Clear the previous interrupt.
4744	 */
4745	ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
4746	ISP_WRITE(isp, BIU_SEMA, 0);
4747
4748	/*
4749	 * Continue with next word.
4750	 */
4751	ptr = isp->isp_mbxworkp;
4752	switch (isp->isp_lastmbxcmd) {
4753	case MBOX_WRITE_RAM_WORD:
4754		mbs.param[2] = *ptr++;
4755		mbs.param[1] = isp->isp_mbxwrk1++;
4756		break;
4757	case MBOX_READ_RAM_WORD:
4758	case MBOX_READ_RAM_WORD_EXTENDED:
4759		*ptr++ = isp->isp_mboxtmp[2];
4760		mbs.param[1] = isp->isp_mbxwrk1++;
4761		break;
4762	}
4763	isp->isp_mbxworkp = ptr;
4764	mbs.param[0] = isp->isp_lastmbxcmd;
4765	isp->isp_mbxwrk0 -= 1;
4766	isp_mboxcmd_qnw(isp, &mbs, 0);
4767	return (0);
4768}
4769
4770
4771#define	HIBYT(x)			((x) >> 0x8)
4772#define	LOBYT(x)			((x)  & 0xff)
4773#define	ISPOPMAP(a, b)			(((a) << 8) | (b))
4774static u_int16_t mbpscsi[] = {
4775	ISPOPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
4776	ISPOPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
4777	ISPOPMAP(0x03, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
4778	ISPOPMAP(0x1f, 0x01),	/* 0x03: MBOX_DUMP_RAM */
4779	ISPOPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
4780	ISPOPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
4781	ISPOPMAP(0x3f, 0x3f),	/* 0x06: MBOX_MAILBOX_REG_TEST */
4782	ISPOPMAP(0x03, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
4783	ISPOPMAP(0x01, 0x0f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
4784	ISPOPMAP(0x00, 0x00),	/* 0x09: */
4785	ISPOPMAP(0x00, 0x00),	/* 0x0a: */
4786	ISPOPMAP(0x00, 0x00),	/* 0x0b: */
4787	ISPOPMAP(0x00, 0x00),	/* 0x0c: */
4788	ISPOPMAP(0x00, 0x00),	/* 0x0d: */
4789	ISPOPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
4790	ISPOPMAP(0x00, 0x00),	/* 0x0f: */
4791	ISPOPMAP(0x1f, 0x1f),	/* 0x10: MBOX_INIT_REQ_QUEUE */
4792	ISPOPMAP(0x3f, 0x3f),	/* 0x11: MBOX_INIT_RES_QUEUE */
4793	ISPOPMAP(0x0f, 0x0f),	/* 0x12: MBOX_EXECUTE_IOCB */
4794	ISPOPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
4795	ISPOPMAP(0x01, 0x3f),	/* 0x14: MBOX_STOP_FIRMWARE */
4796	ISPOPMAP(0x0f, 0x0f),	/* 0x15: MBOX_ABORT */
4797	ISPOPMAP(0x03, 0x03),	/* 0x16: MBOX_ABORT_DEVICE */
4798	ISPOPMAP(0x07, 0x07),	/* 0x17: MBOX_ABORT_TARGET */
4799	ISPOPMAP(0x07, 0x07),	/* 0x18: MBOX_BUS_RESET */
4800	ISPOPMAP(0x03, 0x07),	/* 0x19: MBOX_STOP_QUEUE */
4801	ISPOPMAP(0x03, 0x07),	/* 0x1a: MBOX_START_QUEUE */
4802	ISPOPMAP(0x03, 0x07),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
4803	ISPOPMAP(0x03, 0x07),	/* 0x1c: MBOX_ABORT_QUEUE */
4804	ISPOPMAP(0x03, 0x4f),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
4805	ISPOPMAP(0x00, 0x00),	/* 0x1e: */
4806	ISPOPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
4807	ISPOPMAP(0x01, 0x07),	/* 0x20: MBOX_GET_INIT_SCSI_ID */
4808	ISPOPMAP(0x01, 0x07),	/* 0x21: MBOX_GET_SELECT_TIMEOUT */
4809	ISPOPMAP(0x01, 0xc7),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
4810	ISPOPMAP(0x01, 0x07),	/* 0x23: MBOX_GET_TAG_AGE_LIMIT */
4811	ISPOPMAP(0x01, 0x03),	/* 0x24: MBOX_GET_CLOCK_RATE */
4812	ISPOPMAP(0x01, 0x07),	/* 0x25: MBOX_GET_ACT_NEG_STATE */
4813	ISPOPMAP(0x01, 0x07),	/* 0x26: MBOX_GET_ASYNC_DATA_SETUP_TIME */
4814	ISPOPMAP(0x01, 0x07),	/* 0x27: MBOX_GET_PCI_PARAMS */
4815	ISPOPMAP(0x03, 0x4f),	/* 0x28: MBOX_GET_TARGET_PARAMS */
4816	ISPOPMAP(0x03, 0x0f),	/* 0x29: MBOX_GET_DEV_QUEUE_PARAMS */
4817	ISPOPMAP(0x01, 0x07),	/* 0x2a: MBOX_GET_RESET_DELAY_PARAMS */
4818	ISPOPMAP(0x00, 0x00),	/* 0x2b: */
4819	ISPOPMAP(0x00, 0x00),	/* 0x2c: */
4820	ISPOPMAP(0x00, 0x00),	/* 0x2d: */
4821	ISPOPMAP(0x00, 0x00),	/* 0x2e: */
4822	ISPOPMAP(0x00, 0x00),	/* 0x2f: */
4823	ISPOPMAP(0x03, 0x03),	/* 0x30: MBOX_SET_INIT_SCSI_ID */
4824	ISPOPMAP(0x07, 0x07),	/* 0x31: MBOX_SET_SELECT_TIMEOUT */
4825	ISPOPMAP(0xc7, 0xc7),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
4826	ISPOPMAP(0x07, 0x07),	/* 0x33: MBOX_SET_TAG_AGE_LIMIT */
4827	ISPOPMAP(0x03, 0x03),	/* 0x34: MBOX_SET_CLOCK_RATE */
4828	ISPOPMAP(0x07, 0x07),	/* 0x35: MBOX_SET_ACT_NEG_STATE */
4829	ISPOPMAP(0x07, 0x07),	/* 0x36: MBOX_SET_ASYNC_DATA_SETUP_TIME */
4830	ISPOPMAP(0x07, 0x07),	/* 0x37: MBOX_SET_PCI_CONTROL_PARAMS */
4831	ISPOPMAP(0x4f, 0x4f),	/* 0x38: MBOX_SET_TARGET_PARAMS */
4832	ISPOPMAP(0x0f, 0x0f),	/* 0x39: MBOX_SET_DEV_QUEUE_PARAMS */
4833	ISPOPMAP(0x07, 0x07),	/* 0x3a: MBOX_SET_RESET_DELAY_PARAMS */
4834	ISPOPMAP(0x00, 0x00),	/* 0x3b: */
4835	ISPOPMAP(0x00, 0x00),	/* 0x3c: */
4836	ISPOPMAP(0x00, 0x00),	/* 0x3d: */
4837	ISPOPMAP(0x00, 0x00),	/* 0x3e: */
4838	ISPOPMAP(0x00, 0x00),	/* 0x3f: */
4839	ISPOPMAP(0x01, 0x03),	/* 0x40: MBOX_RETURN_BIOS_BLOCK_ADDR */
4840	ISPOPMAP(0x3f, 0x01),	/* 0x41: MBOX_WRITE_FOUR_RAM_WORDS */
4841	ISPOPMAP(0x03, 0x07),	/* 0x42: MBOX_EXEC_BIOS_IOCB */
4842	ISPOPMAP(0x00, 0x00),	/* 0x43: */
4843	ISPOPMAP(0x00, 0x00),	/* 0x44: */
4844	ISPOPMAP(0x03, 0x03),	/* 0x45: SET SYSTEM PARAMETER */
4845	ISPOPMAP(0x01, 0x03),	/* 0x46: GET SYSTEM PARAMETER */
4846	ISPOPMAP(0x00, 0x00),	/* 0x47: */
4847	ISPOPMAP(0x01, 0xcf),	/* 0x48: GET SCAM CONFIGURATION */
4848	ISPOPMAP(0xcf, 0xcf),	/* 0x49: SET SCAM CONFIGURATION */
4849	ISPOPMAP(0x03, 0x03),	/* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
4850	ISPOPMAP(0x01, 0x03),	/* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
4851	ISPOPMAP(0x00, 0x00),	/* 0x4c: */
4852	ISPOPMAP(0x00, 0x00),	/* 0x4d: */
4853	ISPOPMAP(0x00, 0x00),	/* 0x4e: */
4854	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
4855	ISPOPMAP(0xdf, 0xdf),	/* 0x50: LOAD RAM A64 */
4856	ISPOPMAP(0xdf, 0xdf),	/* 0x51: DUMP RAM A64 */
4857	ISPOPMAP(0xdf, 0xff),	/* 0x52: INITIALIZE REQUEST QUEUE A64 */
4858	ISPOPMAP(0xef, 0xff),	/* 0x53: INITIALIZE RESPONSE QUEUE A64 */
4859	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUTE IOCB A64 */
4860	ISPOPMAP(0x07, 0x01),	/* 0x55: ENABLE TARGET MODE */
4861	ISPOPMAP(0x03, 0x0f),	/* 0x56: GET TARGET STATUS */
4862	ISPOPMAP(0x00, 0x00),	/* 0x57: */
4863	ISPOPMAP(0x00, 0x00),	/* 0x58: */
4864	ISPOPMAP(0x00, 0x00),	/* 0x59: */
4865	ISPOPMAP(0x03, 0x03),	/* 0x5a: SET DATA OVERRUN RECOVERY MODE */
4866	ISPOPMAP(0x01, 0x03),	/* 0x5b: GET DATA OVERRUN RECOVERY MODE */
4867	ISPOPMAP(0x0f, 0x0f),	/* 0x5c: SET HOST DATA */
4868	ISPOPMAP(0x01, 0x01)	/* 0x5d: GET NOST DATA */
4869};
4870
4871#ifndef	ISP_STRIPPED
4872static char *scsi_mbcmd_names[] = {
4873	"NO-OP",
4874	"LOAD RAM",
4875	"EXEC FIRMWARE",
4876	"DUMP RAM",
4877	"WRITE RAM WORD",
4878	"READ RAM WORD",
4879	"MAILBOX REG TEST",
4880	"VERIFY CHECKSUM",
4881	"ABOUT FIRMWARE",
4882	NULL,
4883	NULL,
4884	NULL,
4885	NULL,
4886	NULL,
4887	"CHECK FIRMWARE",
4888	NULL,
4889	"INIT REQUEST QUEUE",
4890	"INIT RESULT QUEUE",
4891	"EXECUTE IOCB",
4892	"WAKE UP",
4893	"STOP FIRMWARE",
4894	"ABORT",
4895	"ABORT DEVICE",
4896	"ABORT TARGET",
4897	"BUS RESET",
4898	"STOP QUEUE",
4899	"START QUEUE",
4900	"SINGLE STEP QUEUE",
4901	"ABORT QUEUE",
4902	"GET DEV QUEUE STATUS",
4903	NULL,
4904	"GET FIRMWARE STATUS",
4905	"GET INIT SCSI ID",
4906	"GET SELECT TIMEOUT",
4907	"GET RETRY COUNT",
4908	"GET TAG AGE LIMIT",
4909	"GET CLOCK RATE",
4910	"GET ACT NEG STATE",
4911	"GET ASYNC DATA SETUP TIME",
4912	"GET PCI PARAMS",
4913	"GET TARGET PARAMS",
4914	"GET DEV QUEUE PARAMS",
4915	"GET RESET DELAY PARAMS",
4916	NULL,
4917	NULL,
4918	NULL,
4919	NULL,
4920	NULL,
4921	"SET INIT SCSI ID",
4922	"SET SELECT TIMEOUT",
4923	"SET RETRY COUNT",
4924	"SET TAG AGE LIMIT",
4925	"SET CLOCK RATE",
4926	"SET ACT NEG STATE",
4927	"SET ASYNC DATA SETUP TIME",
4928	"SET PCI CONTROL PARAMS",
4929	"SET TARGET PARAMS",
4930	"SET DEV QUEUE PARAMS",
4931	"SET RESET DELAY PARAMS",
4932	NULL,
4933	NULL,
4934	NULL,
4935	NULL,
4936	NULL,
4937	"RETURN BIOS BLOCK ADDR",
4938	"WRITE FOUR RAM WORDS",
4939	"EXEC BIOS IOCB",
4940	NULL,
4941	NULL,
4942	"SET SYSTEM PARAMETER",
4943	"GET SYSTEM PARAMETER",
4944	NULL,
4945	"GET SCAM CONFIGURATION",
4946	"SET SCAM CONFIGURATION",
4947	"SET FIRMWARE FEATURES",
4948	"GET FIRMWARE FEATURES",
4949	NULL,
4950	NULL,
4951	NULL,
4952	NULL,
4953	"LOAD RAM A64",
4954	"DUMP RAM A64",
4955	"INITIALIZE REQUEST QUEUE A64",
4956	"INITIALIZE RESPONSE QUEUE A64",
4957	"EXECUTE IOCB A64",
4958	"ENABLE TARGET MODE",
4959	"GET TARGET MODE STATE",
4960	NULL,
4961	NULL,
4962	NULL,
4963	"SET DATA OVERRUN RECOVERY MODE",
4964	"GET DATA OVERRUN RECOVERY MODE",
4965	"SET HOST DATA",
4966	"GET NOST DATA",
4967};
4968#endif
4969
4970static u_int16_t mbpfc[] = {
4971	ISPOPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
4972	ISPOPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
4973	ISPOPMAP(0x03, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
4974	ISPOPMAP(0xdf, 0x01),	/* 0x03: MBOX_DUMP_RAM */
4975	ISPOPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
4976	ISPOPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
4977	ISPOPMAP(0xff, 0xff),	/* 0x06: MBOX_MAILBOX_REG_TEST */
4978	ISPOPMAP(0x03, 0x05),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
4979	ISPOPMAP(0x01, 0x4f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
4980	ISPOPMAP(0xdf, 0x01),	/* 0x09: LOAD RAM */
4981	ISPOPMAP(0xdf, 0x01),	/* 0x0a: DUMP RAM */
4982	ISPOPMAP(0x00, 0x00),	/* 0x0b: */
4983	ISPOPMAP(0x00, 0x00),	/* 0x0c: */
4984	ISPOPMAP(0x00, 0x00),	/* 0x0d: */
4985	ISPOPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
4986	ISPOPMAP(0x03, 0x07),	/* 0x0f: MBOX_READ_RAM_WORD_EXTENDED(1) */
4987	ISPOPMAP(0x1f, 0x11),	/* 0x10: MBOX_INIT_REQ_QUEUE */
4988	ISPOPMAP(0x2f, 0x21),	/* 0x11: MBOX_INIT_RES_QUEUE */
4989	ISPOPMAP(0x0f, 0x01),	/* 0x12: MBOX_EXECUTE_IOCB */
4990	ISPOPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
4991	ISPOPMAP(0x01, 0xff),	/* 0x14: MBOX_STOP_FIRMWARE */
4992	ISPOPMAP(0x4f, 0x01),	/* 0x15: MBOX_ABORT */
4993	ISPOPMAP(0x07, 0x01),	/* 0x16: MBOX_ABORT_DEVICE */
4994	ISPOPMAP(0x07, 0x01),	/* 0x17: MBOX_ABORT_TARGET */
4995	ISPOPMAP(0x03, 0x03),	/* 0x18: MBOX_BUS_RESET */
4996	ISPOPMAP(0x07, 0x05),	/* 0x19: MBOX_STOP_QUEUE */
4997	ISPOPMAP(0x07, 0x05),	/* 0x1a: MBOX_START_QUEUE */
4998	ISPOPMAP(0x07, 0x05),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
4999	ISPOPMAP(0x07, 0x05),	/* 0x1c: MBOX_ABORT_QUEUE */
5000	ISPOPMAP(0x07, 0x03),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
5001	ISPOPMAP(0x00, 0x00),	/* 0x1e: */
5002	ISPOPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
5003	ISPOPMAP(0x01, 0x4f),	/* 0x20: MBOX_GET_LOOP_ID */
5004	ISPOPMAP(0x00, 0x00),	/* 0x21: */
5005	ISPOPMAP(0x01, 0x07),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
5006	ISPOPMAP(0x00, 0x00),	/* 0x23: */
5007	ISPOPMAP(0x00, 0x00),	/* 0x24: */
5008	ISPOPMAP(0x00, 0x00),	/* 0x25: */
5009	ISPOPMAP(0x00, 0x00),	/* 0x26: */
5010	ISPOPMAP(0x00, 0x00),	/* 0x27: */
5011	ISPOPMAP(0x01, 0x03),	/* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
5012	ISPOPMAP(0x03, 0x07),	/* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
5013	ISPOPMAP(0x00, 0x00),	/* 0x2a: */
5014	ISPOPMAP(0x00, 0x00),	/* 0x2b: */
5015	ISPOPMAP(0x00, 0x00),	/* 0x2c: */
5016	ISPOPMAP(0x00, 0x00),	/* 0x2d: */
5017	ISPOPMAP(0x00, 0x00),	/* 0x2e: */
5018	ISPOPMAP(0x00, 0x00),	/* 0x2f: */
5019	ISPOPMAP(0x00, 0x00),	/* 0x30: */
5020	ISPOPMAP(0x00, 0x00),	/* 0x31: */
5021	ISPOPMAP(0x07, 0x07),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
5022	ISPOPMAP(0x00, 0x00),	/* 0x33: */
5023	ISPOPMAP(0x00, 0x00),	/* 0x34: */
5024	ISPOPMAP(0x00, 0x00),	/* 0x35: */
5025	ISPOPMAP(0x00, 0x00),	/* 0x36: */
5026	ISPOPMAP(0x00, 0x00),	/* 0x37: */
5027	ISPOPMAP(0x0f, 0x01),	/* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
5028	ISPOPMAP(0x0f, 0x07),	/* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
5029	ISPOPMAP(0x00, 0x00),	/* 0x3a: */
5030	ISPOPMAP(0x00, 0x00),	/* 0x3b: */
5031	ISPOPMAP(0x00, 0x00),	/* 0x3c: */
5032	ISPOPMAP(0x00, 0x00),	/* 0x3d: */
5033	ISPOPMAP(0x00, 0x00),	/* 0x3e: */
5034	ISPOPMAP(0x00, 0x00),	/* 0x3f: */
5035	ISPOPMAP(0x03, 0x01),	/* 0x40: MBOX_LOOP_PORT_BYPASS */
5036	ISPOPMAP(0x03, 0x01),	/* 0x41: MBOX_LOOP_PORT_ENABLE */
5037	ISPOPMAP(0x03, 0x07),	/* 0x42: MBOX_GET_RESOURCE_COUNTS */
5038	ISPOPMAP(0x01, 0x01),	/* 0x43: MBOX_REQUEST_NON_PARTICIPATING_MODE */
5039	ISPOPMAP(0x00, 0x00),	/* 0x44: */
5040	ISPOPMAP(0x00, 0x00),	/* 0x45: */
5041	ISPOPMAP(0x00, 0x00),	/* 0x46: */
5042	ISPOPMAP(0xcf, 0x03),	/* 0x47: GET PORT_DATABASE ENHANCED */
5043	ISPOPMAP(0x00, 0x00),	/* 0x48: */
5044	ISPOPMAP(0x00, 0x00),	/* 0x49: */
5045	ISPOPMAP(0x00, 0x00),	/* 0x4a: */
5046	ISPOPMAP(0x00, 0x00),	/* 0x4b: */
5047	ISPOPMAP(0x00, 0x00),	/* 0x4c: */
5048	ISPOPMAP(0x00, 0x00),	/* 0x4d: */
5049	ISPOPMAP(0x00, 0x00),	/* 0x4e: */
5050	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
5051	ISPOPMAP(0x00, 0x00),	/* 0x50: */
5052	ISPOPMAP(0x00, 0x00),	/* 0x51: */
5053	ISPOPMAP(0x00, 0x00),	/* 0x52: */
5054	ISPOPMAP(0x00, 0x00),	/* 0x53: */
5055	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUTE IOCB A64 */
5056	ISPOPMAP(0x00, 0x00),	/* 0x55: */
5057	ISPOPMAP(0x00, 0x00),	/* 0x56: */
5058	ISPOPMAP(0x00, 0x00),	/* 0x57: */
5059	ISPOPMAP(0x00, 0x00),	/* 0x58: */
5060	ISPOPMAP(0x00, 0x00),	/* 0x59: */
5061	ISPOPMAP(0x00, 0x00),	/* 0x5a: */
5062	ISPOPMAP(0x03, 0x01),	/* 0x5b: MBOX_DRIVER_HEARTBEAT */
5063	ISPOPMAP(0xcf, 0x01),	/* 0x5c: MBOX_FW_HEARTBEAT */
5064	ISPOPMAP(0x07, 0x03),	/* 0x5d: MBOX_GET_SET_DATA_RATE */
5065	ISPOPMAP(0x00, 0x00),	/* 0x5e: */
5066	ISPOPMAP(0x00, 0x00),	/* 0x5f: */
5067	ISPOPMAP(0xfd, 0x31),	/* 0x60: MBOX_INIT_FIRMWARE */
5068	ISPOPMAP(0x00, 0x00),	/* 0x61: */
5069	ISPOPMAP(0x01, 0x01),	/* 0x62: MBOX_INIT_LIP */
5070	ISPOPMAP(0xcd, 0x03),	/* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
5071	ISPOPMAP(0xcf, 0x01),	/* 0x64: MBOX_GET_PORT_DB */
5072	ISPOPMAP(0x07, 0x01),	/* 0x65: MBOX_CLEAR_ACA */
5073	ISPOPMAP(0x07, 0x01),	/* 0x66: MBOX_TARGET_RESET */
5074	ISPOPMAP(0x07, 0x01),	/* 0x67: MBOX_CLEAR_TASK_SET */
5075	ISPOPMAP(0x07, 0x01),	/* 0x68: MBOX_ABORT_TASK_SET */
5076	ISPOPMAP(0x01, 0x07),	/* 0x69: MBOX_GET_FW_STATE */
5077	ISPOPMAP(0x03, 0xcf),	/* 0x6a: MBOX_GET_PORT_NAME */
5078	ISPOPMAP(0xcf, 0x01),	/* 0x6b: MBOX_GET_LINK_STATUS */
5079	ISPOPMAP(0x0f, 0x01),	/* 0x6c: MBOX_INIT_LIP_RESET */
5080	ISPOPMAP(0x00, 0x00),	/* 0x6d: */
5081	ISPOPMAP(0xcf, 0x03),	/* 0x6e: MBOX_SEND_SNS */
5082	ISPOPMAP(0x0f, 0x07),	/* 0x6f: MBOX_FABRIC_LOGIN */
5083	ISPOPMAP(0x03, 0x01),	/* 0x70: MBOX_SEND_CHANGE_REQUEST */
5084	ISPOPMAP(0x03, 0x03),	/* 0x71: MBOX_FABRIC_LOGOUT */
5085	ISPOPMAP(0x0f, 0x0f),	/* 0x72: MBOX_INIT_LIP_LOGIN */
5086	ISPOPMAP(0x00, 0x00),	/* 0x73: */
5087	ISPOPMAP(0x07, 0x01),	/* 0x74: LOGIN LOOP PORT */
5088	ISPOPMAP(0xcf, 0x03),	/* 0x75: GET PORT/NODE NAME LIST */
5089	ISPOPMAP(0x4f, 0x01),	/* 0x76: SET VENDOR ID */
5090	ISPOPMAP(0xcd, 0x01),	/* 0x77: INITIALIZE IP MAILBOX */
5091	ISPOPMAP(0x00, 0x00),	/* 0x78: */
5092	ISPOPMAP(0x00, 0x00),	/* 0x79: */
5093	ISPOPMAP(0x00, 0x00),	/* 0x7a: */
5094	ISPOPMAP(0x00, 0x00),	/* 0x7b: */
5095	ISPOPMAP(0x4f, 0x03),	/* 0x7c: Get ID List */
5096	ISPOPMAP(0xcf, 0x01),	/* 0x7d: SEND LFA */
5097	ISPOPMAP(0x07, 0x01)	/* 0x7e: Lun RESET */
5098};
5099/*
5100 * Footnotes
5101 *
5102 * (1): this sets bits 21..16 in mailbox register #8, which we nominally
5103 *	do not access at this time in the core driver. The caller is
5104 *	responsible for setting this register first (Gross!).
5105 */
5106
5107#ifndef	ISP_STRIPPED
5108static char *fc_mbcmd_names[] = {
5109	"NO-OP",
5110	"LOAD RAM",
5111	"EXEC FIRMWARE",
5112	"DUMP RAM",
5113	"WRITE RAM WORD",
5114	"READ RAM WORD",
5115	"MAILBOX REG TEST",
5116	"VERIFY CHECKSUM",
5117	"ABOUT FIRMWARE",
5118	"LOAD RAM",
5119	"DUMP RAM",
5120	NULL,
5121	NULL,
5122	"READ RAM WORD EXTENDED",
5123	"CHECK FIRMWARE",
5124	NULL,
5125	"INIT REQUEST QUEUE",
5126	"INIT RESULT QUEUE",
5127	"EXECUTE IOCB",
5128	"WAKE UP",
5129	"STOP FIRMWARE",
5130	"ABORT",
5131	"ABORT DEVICE",
5132	"ABORT TARGET",
5133	"BUS RESET",
5134	"STOP QUEUE",
5135	"START QUEUE",
5136	"SINGLE STEP QUEUE",
5137	"ABORT QUEUE",
5138	"GET DEV QUEUE STATUS",
5139	NULL,
5140	"GET FIRMWARE STATUS",
5141	"GET LOOP ID",
5142	NULL,
5143	"GET RETRY COUNT",
5144	NULL,
5145	NULL,
5146	NULL,
5147	NULL,
5148	NULL,
5149	"GET FIRMWARE OPTIONS",
5150	"GET PORT QUEUE PARAMS",
5151	NULL,
5152	NULL,
5153	NULL,
5154	NULL,
5155	NULL,
5156	NULL,
5157	NULL,
5158	NULL,
5159	"SET RETRY COUNT",
5160	NULL,
5161	NULL,
5162	NULL,
5163	NULL,
5164	NULL,
5165	"SET FIRMWARE OPTIONS",
5166	"SET PORT QUEUE PARAMS",
5167	NULL,
5168	NULL,
5169	NULL,
5170	NULL,
5171	NULL,
5172	NULL,
5173	"LOOP PORT BYPASS",
5174	"LOOP PORT ENABLE",
5175	"GET RESOURCE COUNTS",
5176	"REQUEST NON PARTICIPATING MODE",
5177	NULL,
5178	NULL,
5179	NULL,
5180	"GET PORT DATABASE,, ENHANCED",
5181	NULL,
5182	NULL,
5183	NULL,
5184	NULL,
5185	NULL,
5186	NULL,
5187	NULL,
5188	NULL,
5189	NULL,
5190	NULL,
5191	NULL,
5192	NULL,
5193	"EXECUTE IOCB A64",
5194	NULL,
5195	NULL,
5196	NULL,
5197	NULL,
5198	NULL,
5199	NULL,
5200	NULL,
5201	NULL,
5202	"GET/SET DATA RATE",
5203	NULL,
5204	NULL,
5205	"INIT FIRMWARE",
5206	NULL,
5207	"INIT LIP",
5208	"GET FC-AL POSITION MAP",
5209	"GET PORT DATABASE",
5210	"CLEAR ACA",
5211	"TARGET RESET",
5212	"CLEAR TASK SET",
5213	"ABORT TASK SET",
5214	"GET FW STATE",
5215	"GET PORT NAME",
5216	"GET LINK STATUS",
5217	"INIT LIP RESET",
5218	NULL,
5219	"SEND SNS",
5220	"FABRIC LOGIN",
5221	"SEND CHANGE REQUEST",
5222	"FABRIC LOGOUT",
5223	"INIT LIP LOGIN",
5224	NULL,
5225	"LOGIN LOOP PORT",
5226	"GET PORT/NODE NAME LIST",
5227	"SET VENDOR ID",
5228	"INITIALIZE IP MAILBOX",
5229	NULL,
5230	NULL,
5231	NULL,
5232	NULL,
5233	"Get ID List",
5234	"SEND LFA",
5235	"Lun RESET"
5236};
5237#endif
5238
5239static void
5240isp_mboxcmd_qnw(struct ispsoftc *isp, mbreg_t *mbp, int nodelay)
5241{
5242	unsigned int lim, ibits, obits, box, opcode;
5243	u_int16_t *mcp;
5244
5245	if (IS_FC(isp)) {
5246		mcp = mbpfc;
5247		lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
5248	} else {
5249		mcp = mbpscsi;
5250		lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
5251	}
5252	opcode = mbp->param[0];
5253	ibits = HIBYT(mcp[opcode]) & NMBOX_BMASK(isp);
5254	obits = LOBYT(mcp[opcode]) & NMBOX_BMASK(isp);
5255	for (box = 0; box < MAX_MAILBOX; box++) {
5256		if (ibits & (1 << box)) {
5257			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
5258		}
5259		if (nodelay == 0) {
5260			isp->isp_mboxtmp[box] = mbp->param[box] = 0;
5261		}
5262	}
5263	if (nodelay == 0) {
5264		isp->isp_lastmbxcmd = opcode;
5265		isp->isp_obits = obits;
5266		isp->isp_mboxbsy = 1;
5267	}
5268	ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
5269	/*
5270	 * Oddly enough, if we're not delaying for an answer,
5271	 * delay a bit to give the f/w a chance to pick up the
5272	 * command.
5273	 */
5274	if (nodelay) {
5275		USEC_DELAY(1000);
5276	}
5277}
5278
5279static void
5280isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp, int logmask)
5281{
5282	char *cname, *xname, tname[16], mname[16];
5283	unsigned int lim, ibits, obits, box, opcode;
5284	u_int16_t *mcp;
5285
5286	if (IS_FC(isp)) {
5287		mcp = mbpfc;
5288		lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
5289	} else {
5290		mcp = mbpscsi;
5291		lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
5292	}
5293
5294	if ((opcode = mbp->param[0]) >= lim) {
5295		mbp->param[0] = MBOX_INVALID_COMMAND;
5296		isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
5297		return;
5298	}
5299
5300	ibits = HIBYT(mcp[opcode]) & NMBOX_BMASK(isp);
5301	obits = LOBYT(mcp[opcode]) & NMBOX_BMASK(isp);
5302
5303	if (ibits == 0 && obits == 0) {
5304		mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
5305		isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
5306		return;
5307	}
5308
5309	/*
5310	 * Get exclusive usage of mailbox registers.
5311	 */
5312	MBOX_ACQUIRE(isp);
5313
5314	for (box = 0; box < MAX_MAILBOX; box++) {
5315		if (ibits & (1 << box)) {
5316			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
5317		}
5318		isp->isp_mboxtmp[box] = mbp->param[box] = 0;
5319	}
5320
5321	isp->isp_lastmbxcmd = opcode;
5322
5323	/*
5324	 * We assume that we can't overwrite a previous command.
5325	 */
5326	isp->isp_obits = obits;
5327	isp->isp_mboxbsy = 1;
5328
5329	/*
5330	 * Set Host Interrupt condition so that RISC will pick up mailbox regs.
5331	 */
5332	ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
5333
5334	/*
5335	 * While we haven't finished the command, spin our wheels here.
5336	 */
5337	MBOX_WAIT_COMPLETE(isp);
5338
5339	if (isp->isp_mboxbsy) {
5340		/*
5341		 * Command timed out.
5342		 */
5343		isp->isp_mboxbsy = 0;
5344		MBOX_RELEASE(isp);
5345		return;
5346	}
5347
5348	/*
5349	 * Copy back output registers.
5350	 */
5351	for (box = 0; box < MAX_MAILBOX; box++) {
5352		if (obits & (1 << box)) {
5353			mbp->param[box] = isp->isp_mboxtmp[box];
5354		}
5355	}
5356
5357	MBOX_RELEASE(isp);
5358
5359	if (logmask == 0 || opcode == MBOX_EXEC_FIRMWARE) {
5360		return;
5361	}
5362#ifdef	ISP_STRIPPED
5363	cname = NULL;
5364#else
5365	cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode];
5366#endif
5367	if (cname == NULL) {
5368		cname = tname;
5369		SNPRINTF(tname, sizeof tname, "opcode %x", opcode);
5370	}
5371
5372	/*
5373	 * Just to be chatty here...
5374	 */
5375	xname = NULL;
5376	switch (mbp->param[0]) {
5377	case MBOX_COMMAND_COMPLETE:
5378		break;
5379	case MBOX_INVALID_COMMAND:
5380		if (logmask & MBLOGMASK(MBOX_COMMAND_COMPLETE))
5381			xname = "INVALID COMMAND";
5382		break;
5383	case MBOX_HOST_INTERFACE_ERROR:
5384		if (logmask & MBLOGMASK(MBOX_HOST_INTERFACE_ERROR))
5385			xname = "HOST INTERFACE ERROR";
5386		break;
5387	case MBOX_TEST_FAILED:
5388		if (logmask & MBLOGMASK(MBOX_TEST_FAILED))
5389			xname = "TEST FAILED";
5390		break;
5391	case MBOX_COMMAND_ERROR:
5392		if (logmask & MBLOGMASK(MBOX_COMMAND_ERROR))
5393			xname = "COMMAND ERROR";
5394		break;
5395	case MBOX_COMMAND_PARAM_ERROR:
5396		if (logmask & MBLOGMASK(MBOX_COMMAND_PARAM_ERROR))
5397			xname = "COMMAND PARAMETER ERROR";
5398		break;
5399	case MBOX_LOOP_ID_USED:
5400		if (logmask & MBLOGMASK(MBOX_LOOP_ID_USED))
5401			xname = "LOOP ID ALREADY IN USE";
5402		break;
5403	case MBOX_PORT_ID_USED:
5404		if (logmask & MBLOGMASK(MBOX_PORT_ID_USED))
5405			xname = "PORT ID ALREADY IN USE";
5406		break;
5407	case MBOX_ALL_IDS_USED:
5408		if (logmask & MBLOGMASK(MBOX_ALL_IDS_USED))
5409			xname = "ALL LOOP IDS IN USE";
5410		break;
5411	case 0:		/* special case */
5412		xname = "TIMEOUT";
5413		break;
5414	default:
5415		SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
5416		xname = mname;
5417		break;
5418	}
5419	if (xname)
5420		isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s)",
5421		    cname, xname);
5422}
5423
5424static void
5425isp_fw_state(struct ispsoftc *isp)
5426{
5427	if (IS_FC(isp)) {
5428		mbreg_t mbs;
5429		fcparam *fcp = isp->isp_param;
5430
5431		mbs.param[0] = MBOX_GET_FW_STATE;
5432		isp_mboxcmd(isp, &mbs, MBLOGALL);
5433		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
5434			fcp->isp_fwstate = mbs.param[1];
5435		}
5436	}
5437}
5438
5439static void
5440isp_update(struct ispsoftc *isp)
5441{
5442	int bus, upmask;
5443
5444	for (bus = 0, upmask = isp->isp_update; upmask != 0; bus++) {
5445		if (upmask & (1 << bus)) {
5446			isp_update_bus(isp, bus);
5447		}
5448		upmask &= ~(1 << bus);
5449	}
5450}
5451
5452static void
5453isp_update_bus(struct ispsoftc *isp, int bus)
5454{
5455	int tgt;
5456	mbreg_t mbs;
5457	sdparam *sdp;
5458
5459	isp->isp_update &= ~(1 << bus);
5460	if (IS_FC(isp)) {
5461		/*
5462		 * There are no 'per-bus' settings for Fibre Channel.
5463		 */
5464		return;
5465	}
5466	sdp = isp->isp_param;
5467	sdp += bus;
5468
5469	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
5470		u_int16_t flags, period, offset;
5471		int get;
5472
5473		if (sdp->isp_devparam[tgt].dev_enable == 0) {
5474			sdp->isp_devparam[tgt].dev_update = 0;
5475			sdp->isp_devparam[tgt].dev_refresh = 0;
5476			isp_prt(isp, ISP_LOGDEBUG0,
5477	 		    "skipping target %d bus %d update", tgt, bus);
5478			continue;
5479		}
5480		/*
5481		 * If the goal is to update the status of the device,
5482		 * take what's in goal_flags and try and set the device
5483		 * toward that. Otherwise, if we're just refreshing the
5484		 * current device state, get the current parameters.
5485		 */
5486
5487		/*
5488		 * Refresh overrides set
5489		 */
5490		if (sdp->isp_devparam[tgt].dev_refresh) {
5491			mbs.param[0] = MBOX_GET_TARGET_PARAMS;
5492			sdp->isp_devparam[tgt].dev_refresh = 0;
5493			get = 1;
5494		} else if (sdp->isp_devparam[tgt].dev_update) {
5495			mbs.param[0] = MBOX_SET_TARGET_PARAMS;
5496			/*
5497			 * Make sure goal_flags has "Renegotiate on Error"
5498			 * on and "Freeze Queue on Error" off.
5499			 */
5500			sdp->isp_devparam[tgt].goal_flags |= DPARM_RENEG;
5501			sdp->isp_devparam[tgt].goal_flags &= ~DPARM_QFRZ;
5502
5503			mbs.param[2] = sdp->isp_devparam[tgt].goal_flags;
5504
5505			/*
5506			 * Insist that PARITY must be enabled
5507			 * if SYNC or WIDE is enabled.
5508			 */
5509			if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) {
5510				mbs.param[2] |= DPARM_PARITY;
5511			}
5512
5513			if ((mbs.param[2] & DPARM_SYNC) == 0) {
5514				mbs.param[3] = 0;
5515			} else {
5516				mbs.param[3] =
5517				    (sdp->isp_devparam[tgt].goal_offset << 8) |
5518				    (sdp->isp_devparam[tgt].goal_period);
5519			}
5520			/*
5521			 * A command completion later that has
5522			 * RQSTF_NEGOTIATION set can cause
5523			 * the dev_refresh/announce cycle also.
5524			 *
5525			 * Note: It is really important to update our current
5526			 * flags with at least the state of TAG capabilities-
5527			 * otherwise we might try and send a tagged command
5528			 * when we have it all turned off. So change it here
5529			 * to say that current already matches goal.
5530			 */
5531			sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING;
5532			sdp->isp_devparam[tgt].actv_flags |=
5533			    (sdp->isp_devparam[tgt].goal_flags & DPARM_TQING);
5534			isp_prt(isp, ISP_LOGDEBUG0,
5535			    "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
5536			    bus, tgt, mbs.param[2], mbs.param[3] >> 8,
5537			    mbs.param[3] & 0xff);
5538			sdp->isp_devparam[tgt].dev_update = 0;
5539			sdp->isp_devparam[tgt].dev_refresh = 1;
5540			get = 0;
5541		} else {
5542			continue;
5543		}
5544		mbs.param[1] = (bus << 15) | (tgt << 8);
5545		isp_mboxcmd(isp, &mbs, MBLOGALL);
5546		if (get == 0) {
5547			isp->isp_sendmarker |= (1 << bus);
5548			continue;
5549		}
5550		flags = mbs.param[2];
5551		period = mbs.param[3] & 0xff;
5552		offset = mbs.param[3] >> 8;
5553		sdp->isp_devparam[tgt].actv_flags = flags;
5554		sdp->isp_devparam[tgt].actv_period = period;
5555		sdp->isp_devparam[tgt].actv_offset = offset;
5556		get = (bus << 16) | tgt;
5557		(void) isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, &get);
5558	}
5559
5560	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
5561		if (sdp->isp_devparam[tgt].dev_update ||
5562		    sdp->isp_devparam[tgt].dev_refresh) {
5563			isp->isp_update |= (1 << bus);
5564			break;
5565		}
5566	}
5567}
5568
5569#ifndef	DEFAULT_FRAMESIZE
5570#define	DEFAULT_FRAMESIZE(isp)		ICB_DFLT_FRMLEN
5571#endif
5572#ifndef	DEFAULT_EXEC_THROTTLE
5573#define	DEFAULT_EXEC_THROTTLE(isp)	ISP_EXEC_THROTTLE
5574#endif
5575
5576static void
5577isp_setdfltparm(struct ispsoftc *isp, int channel)
5578{
5579	int tgt;
5580	mbreg_t mbs;
5581	sdparam *sdp;
5582
5583	if (IS_FC(isp)) {
5584		fcparam *fcp = (fcparam *) isp->isp_param;
5585		int nvfail;
5586
5587		fcp += channel;
5588		if (fcp->isp_gotdparms) {
5589			return;
5590		}
5591		fcp->isp_gotdparms = 1;
5592		fcp->isp_maxfrmlen = DEFAULT_FRAMESIZE(isp);
5593		fcp->isp_maxalloc = ICB_DFLT_ALLOC;
5594		fcp->isp_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
5595		fcp->isp_retry_delay = ICB_DFLT_RDELAY;
5596		fcp->isp_retry_count = ICB_DFLT_RCOUNT;
5597		/* Platform specific.... */
5598		fcp->isp_loopid = DEFAULT_LOOPID(isp);
5599		fcp->isp_nodewwn = DEFAULT_NODEWWN(isp);
5600		fcp->isp_portwwn = DEFAULT_PORTWWN(isp);
5601		fcp->isp_fwoptions = 0;
5602		fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
5603		fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
5604		fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
5605#ifndef	ISP_NO_FASTPOST_FC
5606		fcp->isp_fwoptions |= ICBOPT_FAST_POST;
5607#endif
5608		if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
5609			fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
5610
5611		/*
5612		 * Make sure this is turned off now until we get
5613		 * extended options from NVRAM
5614		 */
5615		fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
5616
5617		/*
5618		 * Now try and read NVRAM unless told to not do so.
5619		 * This will set fcparam's isp_nodewwn && isp_portwwn.
5620		 */
5621		if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
5622		    	nvfail = isp_read_nvram(isp);
5623			if (nvfail)
5624				isp->isp_confopts |= ISP_CFG_NONVRAM;
5625		} else {
5626			nvfail = 1;
5627		}
5628		/*
5629		 * Set node && port to override platform set defaults
5630		 * unless the nvram read failed (or none was done),
5631		 * or the platform code wants to use what had been
5632		 * set in the defaults.
5633		 */
5634		if (nvfail) {
5635			isp->isp_confopts |= ISP_CFG_OWNWWPN|ISP_CFG_OWNWWNN;
5636		}
5637		if (isp->isp_confopts & ISP_CFG_OWNWWNN) {
5638			isp_prt(isp, ISP_LOGCONFIG, "Using Node WWN 0x%08x%08x",
5639			    (u_int32_t) (DEFAULT_NODEWWN(isp) >> 32),
5640			    (u_int32_t) (DEFAULT_NODEWWN(isp) & 0xffffffff));
5641			ISP_NODEWWN(isp) = DEFAULT_NODEWWN(isp);
5642		} else {
5643			/*
5644			 * We always start out with values derived
5645			 * from NVRAM or our platform default.
5646			 */
5647			ISP_NODEWWN(isp) = fcp->isp_nodewwn;
5648		}
5649		if (isp->isp_confopts & ISP_CFG_OWNWWPN) {
5650			isp_prt(isp, ISP_LOGCONFIG, "Using Port WWN 0x%08x%08x",
5651			    (u_int32_t) (DEFAULT_PORTWWN(isp) >> 32),
5652			    (u_int32_t) (DEFAULT_PORTWWN(isp) & 0xffffffff));
5653			ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp);
5654		} else {
5655			/*
5656			 * We always start out with values derived
5657			 * from NVRAM or our platform default.
5658			 */
5659			ISP_PORTWWN(isp) = fcp->isp_portwwn;
5660		}
5661		return;
5662	}
5663
5664	sdp = (sdparam *) isp->isp_param;
5665	sdp += channel;
5666
5667	/*
5668	 * Been there, done that, got the T-shirt...
5669	 */
5670	if (sdp->isp_gotdparms) {
5671		return;
5672	}
5673	sdp->isp_gotdparms = 1;
5674
5675	/*
5676	 * Establish some default parameters.
5677	 */
5678	sdp->isp_cmd_dma_burst_enable = 0;
5679	sdp->isp_data_dma_burst_enabl = 1;
5680	sdp->isp_fifo_threshold = 0;
5681	sdp->isp_initiator_id = DEFAULT_IID(isp);
5682	if (isp->isp_type >= ISP_HA_SCSI_1040) {
5683		sdp->isp_async_data_setup = 9;
5684	} else {
5685		sdp->isp_async_data_setup = 6;
5686	}
5687	sdp->isp_selection_timeout = 250;
5688	sdp->isp_max_queue_depth = MAXISPREQUEST(isp);
5689	sdp->isp_tag_aging = 8;
5690	sdp->isp_bus_reset_delay = 5;
5691	/*
5692	 * Don't retry selection, busy or queue full automatically- reflect
5693	 * these back to us.
5694	 */
5695	sdp->isp_retry_count = 0;
5696	sdp->isp_retry_delay = 0;
5697
5698	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
5699		sdp->isp_devparam[tgt].exc_throttle = ISP_EXEC_THROTTLE;
5700		sdp->isp_devparam[tgt].dev_enable = 1;
5701	}
5702
5703	/*
5704	 * If we've not been told to avoid reading NVRAM, try and read it.
5705	 * If we're successful reading it, we can then return because NVRAM
5706	 * will tell us what the desired settings are. Otherwise, we establish
5707	 * some reasonable 'fake' nvram and goal defaults.
5708	 */
5709
5710	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
5711		if (isp_read_nvram(isp) == 0) {
5712			return;
5713		}
5714	}
5715
5716	/*
5717	 * Now try and see whether we have specific values for them.
5718	 */
5719	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
5720		mbs.param[0] = MBOX_GET_ACT_NEG_STATE;
5721		isp_mboxcmd(isp, &mbs, MBLOGNONE);
5722		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
5723			sdp->isp_req_ack_active_neg = 1;
5724			sdp->isp_data_line_active_neg = 1;
5725		} else {
5726			sdp->isp_req_ack_active_neg =
5727			    (mbs.param[1+channel] >> 4) & 0x1;
5728			sdp->isp_data_line_active_neg =
5729			    (mbs.param[1+channel] >> 5) & 0x1;
5730		}
5731	}
5732
5733	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc3,
5734	    0, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
5735	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
5736	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
5737	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc3,
5738	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
5739	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
5740	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
5741
5742	/*
5743	 * The trick here is to establish a default for the default (honk!)
5744	 * state (goal_flags). Then try and get the current status from
5745	 * the card to fill in the current state. We don't, in fact, set
5746	 * the default to the SAFE default state- that's not the goal state.
5747	 */
5748	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
5749		u_int8_t off, per;
5750		sdp->isp_devparam[tgt].actv_offset = 0;
5751		sdp->isp_devparam[tgt].actv_period = 0;
5752		sdp->isp_devparam[tgt].actv_flags = 0;
5753
5754		sdp->isp_devparam[tgt].goal_flags =
5755		    sdp->isp_devparam[tgt].nvrm_flags = DPARM_DEFAULT;
5756
5757		/*
5758		 * We default to Wide/Fast for versions less than a 1040
5759		 * (unless it's SBus).
5760		 */
5761		if (IS_ULTRA3(isp)) {
5762			off = ISP_80M_SYNCPARMS >> 8;
5763			per = ISP_80M_SYNCPARMS & 0xff;
5764		} else if (IS_ULTRA2(isp)) {
5765			off = ISP_40M_SYNCPARMS >> 8;
5766			per = ISP_40M_SYNCPARMS & 0xff;
5767		} else if (IS_1240(isp)) {
5768			off = ISP_20M_SYNCPARMS >> 8;
5769			per = ISP_20M_SYNCPARMS & 0xff;
5770		} else if ((isp->isp_bustype == ISP_BT_SBUS &&
5771		    isp->isp_type < ISP_HA_SCSI_1020A) ||
5772		    (isp->isp_bustype == ISP_BT_PCI &&
5773		    isp->isp_type < ISP_HA_SCSI_1040) ||
5774		    (isp->isp_clock && isp->isp_clock < 60) ||
5775		    (sdp->isp_ultramode == 0)) {
5776			off = ISP_10M_SYNCPARMS >> 8;
5777			per = ISP_10M_SYNCPARMS & 0xff;
5778		} else {
5779			off = ISP_20M_SYNCPARMS_1040 >> 8;
5780			per = ISP_20M_SYNCPARMS_1040 & 0xff;
5781		}
5782		sdp->isp_devparam[tgt].goal_offset =
5783		    sdp->isp_devparam[tgt].nvrm_offset = off;
5784		sdp->isp_devparam[tgt].goal_period =
5785		    sdp->isp_devparam[tgt].nvrm_period = per;
5786
5787		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc3,
5788		    channel, tgt, sdp->isp_devparam[tgt].nvrm_flags,
5789		    sdp->isp_devparam[tgt].nvrm_offset,
5790		    sdp->isp_devparam[tgt].nvrm_period);
5791	}
5792}
5793
5794/*
5795 * Re-initialize the ISP and complete all orphaned commands
5796 * with a 'botched' notice. The reset/init routines should
5797 * not disturb an already active list of commands.
5798 *
5799 * Locks held prior to coming here.
5800 */
5801
5802void
5803isp_reinit(struct ispsoftc *isp)
5804{
5805	XS_T *xs;
5806	u_int16_t handle;
5807
5808	isp_reset(isp);
5809	if (isp->isp_state != ISP_RESETSTATE) {
5810		isp_prt(isp, ISP_LOGERR, "isp_reinit cannot reset card");
5811	} else if (isp->isp_role != ISP_ROLE_NONE) {
5812		isp_init(isp);
5813		if (isp->isp_state == ISP_INITSTATE) {
5814			isp->isp_state = ISP_RUNSTATE;
5815		}
5816		if (isp->isp_state != ISP_RUNSTATE) {
5817			isp_prt(isp, ISP_LOGERR,
5818			    "isp_reinit cannot restart card");
5819		}
5820	}
5821	isp->isp_nactive = 0;
5822
5823	for (handle = 1; (int) handle <= isp->isp_maxcmds; handle++) {
5824		xs = isp_find_xs(isp, handle);
5825		if (xs == NULL) {
5826			continue;
5827		}
5828		isp_destroy_handle(isp, handle);
5829		if (XS_XFRLEN(xs)) {
5830			ISP_DMAFREE(isp, xs, handle);
5831			XS_RESID(xs) = XS_XFRLEN(xs);
5832		} else {
5833			XS_RESID(xs) = 0;
5834		}
5835		XS_SETERR(xs, HBA_BUSRESET);
5836		isp_done(xs);
5837	}
5838}
5839
5840/*
5841 * NVRAM Routines
5842 */
5843static int
5844isp_read_nvram(struct ispsoftc *isp)
5845{
5846	int i, amt;
5847	u_int8_t csum, minversion;
5848	union {
5849		u_int8_t _x[ISP2100_NVRAM_SIZE];
5850		u_int16_t _s[ISP2100_NVRAM_SIZE>>1];
5851	} _n;
5852#define	nvram_data	_n._x
5853#define	nvram_words	_n._s
5854
5855	if (IS_FC(isp)) {
5856		amt = ISP2100_NVRAM_SIZE;
5857		minversion = 1;
5858	} else if (IS_ULTRA2(isp)) {
5859		amt = ISP1080_NVRAM_SIZE;
5860		minversion = 0;
5861	} else {
5862		amt = ISP_NVRAM_SIZE;
5863		minversion = 2;
5864	}
5865
5866	/*
5867	 * Just read the first two words first to see if we have a valid
5868	 * NVRAM to continue reading the rest with.
5869	 */
5870	for (i = 0; i < 2; i++) {
5871		isp_rdnvram_word(isp, i, &nvram_words[i]);
5872	}
5873	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
5874	    nvram_data[2] != 'P') {
5875		if (isp->isp_bustype != ISP_BT_SBUS) {
5876			isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
5877			isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x",
5878			    nvram_data[0], nvram_data[1], nvram_data[2]);
5879		}
5880		return (-1);
5881	}
5882	for (i = 2; i < amt>>1; i++) {
5883		isp_rdnvram_word(isp, i, &nvram_words[i]);
5884	}
5885	for (csum = 0, i = 0; i < amt; i++) {
5886		csum += nvram_data[i];
5887	}
5888	if (csum != 0) {
5889		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
5890		return (-1);
5891	}
5892	if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
5893		isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood",
5894		    ISP_NVRAM_VERSION(nvram_data));
5895		return (-1);
5896	}
5897
5898	if (IS_ULTRA3(isp)) {
5899		isp_parse_nvram_12160(isp, 0, nvram_data);
5900		if (IS_12160(isp))
5901			isp_parse_nvram_12160(isp, 1, nvram_data);
5902	} else if (IS_1080(isp)) {
5903		isp_parse_nvram_1080(isp, 0, nvram_data);
5904	} else if (IS_1280(isp) || IS_1240(isp)) {
5905		isp_parse_nvram_1080(isp, 0, nvram_data);
5906		isp_parse_nvram_1080(isp, 1, nvram_data);
5907	} else if (IS_SCSI(isp)) {
5908		isp_parse_nvram_1020(isp, nvram_data);
5909	} else {
5910		isp_parse_nvram_2100(isp, nvram_data);
5911	}
5912	return (0);
5913#undef	nvram_data
5914#undef	nvram_words
5915}
5916
5917static void
5918isp_rdnvram_word(struct ispsoftc *isp, int wo, u_int16_t *rp)
5919{
5920	int i, cbits;
5921	u_int16_t bit, rqst;
5922
5923	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
5924	USEC_DELAY(2);
5925	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
5926	USEC_DELAY(2);
5927
5928	if (IS_FC(isp)) {
5929		wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
5930		if (IS_2312(isp) && isp->isp_port) {
5931			wo += 128;
5932		}
5933		rqst = (ISP_NVRAM_READ << 8) | wo;
5934		cbits = 10;
5935	} else if (IS_ULTRA2(isp)) {
5936		wo &= ((ISP1080_NVRAM_SIZE >> 1) - 1);
5937		rqst = (ISP_NVRAM_READ << 8) | wo;
5938		cbits = 10;
5939	} else {
5940		wo &= ((ISP_NVRAM_SIZE >> 1) - 1);
5941		rqst = (ISP_NVRAM_READ << 6) | wo;
5942		cbits = 8;
5943	}
5944
5945	/*
5946	 * Clock the word select request out...
5947	 */
5948	for (i = cbits; i >= 0; i--) {
5949		if ((rqst >> i) & 1) {
5950			bit = BIU_NVRAM_SELECT | BIU_NVRAM_DATAOUT;
5951		} else {
5952			bit = BIU_NVRAM_SELECT;
5953		}
5954		ISP_WRITE(isp, BIU_NVRAM, bit);
5955		USEC_DELAY(2);
5956		ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
5957		USEC_DELAY(2);
5958		ISP_WRITE(isp, BIU_NVRAM, bit);
5959		USEC_DELAY(2);
5960	}
5961	/*
5962	 * Now read the result back in (bits come back in MSB format).
5963	 */
5964	*rp = 0;
5965	for (i = 0; i < 16; i++) {
5966		u_int16_t rv;
5967		*rp <<= 1;
5968		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
5969		USEC_DELAY(2);
5970		rv = ISP_READ(isp, BIU_NVRAM);
5971		if (rv & BIU_NVRAM_DATAIN) {
5972			*rp |= 1;
5973		}
5974		USEC_DELAY(2);
5975		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
5976		USEC_DELAY(2);
5977	}
5978	ISP_WRITE(isp, BIU_NVRAM, 0);
5979	USEC_DELAY(2);
5980	ISP_SWIZZLE_NVRAM_WORD(isp, rp);
5981}
5982
5983static void
5984isp_parse_nvram_1020(struct ispsoftc *isp, u_int8_t *nvram_data)
5985{
5986	sdparam *sdp = (sdparam *) isp->isp_param;
5987	int tgt;
5988
5989	sdp->isp_fifo_threshold =
5990		ISP_NVRAM_FIFO_THRESHOLD(nvram_data) |
5991		(ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2);
5992
5993	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
5994		sdp->isp_initiator_id =
5995			ISP_NVRAM_INITIATOR_ID(nvram_data);
5996
5997	sdp->isp_bus_reset_delay =
5998		ISP_NVRAM_BUS_RESET_DELAY(nvram_data);
5999
6000	sdp->isp_retry_count =
6001		ISP_NVRAM_BUS_RETRY_COUNT(nvram_data);
6002
6003	sdp->isp_retry_delay =
6004		ISP_NVRAM_BUS_RETRY_DELAY(nvram_data);
6005
6006	sdp->isp_async_data_setup =
6007		ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data);
6008
6009	if (isp->isp_type >= ISP_HA_SCSI_1040) {
6010		if (sdp->isp_async_data_setup < 9) {
6011			sdp->isp_async_data_setup = 9;
6012		}
6013	} else {
6014		if (sdp->isp_async_data_setup != 6) {
6015			sdp->isp_async_data_setup = 6;
6016		}
6017	}
6018
6019	sdp->isp_req_ack_active_neg =
6020		ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
6021
6022	sdp->isp_data_line_active_neg =
6023		ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data);
6024
6025	sdp->isp_data_dma_burst_enabl =
6026		ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data);
6027
6028	sdp->isp_cmd_dma_burst_enable =
6029		ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data);
6030
6031	sdp->isp_tag_aging =
6032		ISP_NVRAM_TAG_AGE_LIMIT(nvram_data);
6033
6034	sdp->isp_selection_timeout =
6035		ISP_NVRAM_SELECTION_TIMEOUT(nvram_data);
6036
6037	sdp->isp_max_queue_depth =
6038		ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
6039
6040	sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
6041
6042	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
6043	    0, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
6044	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
6045	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
6046	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
6047	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
6048	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
6049	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
6050
6051	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
6052		sdp->isp_devparam[tgt].dev_enable =
6053			ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt);
6054		sdp->isp_devparam[tgt].exc_throttle =
6055			ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt);
6056		sdp->isp_devparam[tgt].nvrm_offset =
6057			ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt);
6058		sdp->isp_devparam[tgt].nvrm_period =
6059			ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt);
6060		/*
6061		 * We probably shouldn't lie about this, but it
6062		 * it makes it much safer if we limit NVRAM values
6063		 * to sanity.
6064		 */
6065		if (isp->isp_type < ISP_HA_SCSI_1040) {
6066			/*
6067			 * If we're not ultra, we can't possibly
6068			 * be a shorter period than this.
6069			 */
6070			if (sdp->isp_devparam[tgt].nvrm_period < 0x19) {
6071				sdp->isp_devparam[tgt].nvrm_period = 0x19;
6072			}
6073			if (sdp->isp_devparam[tgt].nvrm_offset > 0xc) {
6074				sdp->isp_devparam[tgt].nvrm_offset = 0x0c;
6075			}
6076		} else {
6077			if (sdp->isp_devparam[tgt].nvrm_offset > 0x8) {
6078				sdp->isp_devparam[tgt].nvrm_offset = 0x8;
6079			}
6080		}
6081		sdp->isp_devparam[tgt].nvrm_flags = 0;
6082		if (ISP_NVRAM_TGT_RENEG(nvram_data, tgt))
6083			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
6084		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
6085		if (ISP_NVRAM_TGT_TQING(nvram_data, tgt))
6086			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
6087		if (ISP_NVRAM_TGT_SYNC(nvram_data, tgt))
6088			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
6089		if (ISP_NVRAM_TGT_WIDE(nvram_data, tgt))
6090			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
6091		if (ISP_NVRAM_TGT_PARITY(nvram_data, tgt))
6092			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
6093		if (ISP_NVRAM_TGT_DISC(nvram_data, tgt))
6094			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
6095		sdp->isp_devparam[tgt].actv_flags = 0; /* we don't know */
6096		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
6097		    0, tgt, sdp->isp_devparam[tgt].nvrm_flags,
6098		    sdp->isp_devparam[tgt].nvrm_offset,
6099		    sdp->isp_devparam[tgt].nvrm_period);
6100		sdp->isp_devparam[tgt].goal_offset =
6101		    sdp->isp_devparam[tgt].nvrm_offset;
6102		sdp->isp_devparam[tgt].goal_period =
6103		    sdp->isp_devparam[tgt].nvrm_period;
6104		sdp->isp_devparam[tgt].goal_flags =
6105		    sdp->isp_devparam[tgt].nvrm_flags;
6106	}
6107}
6108
6109static void
6110isp_parse_nvram_1080(struct ispsoftc *isp, int bus, u_int8_t *nvram_data)
6111{
6112	sdparam *sdp = (sdparam *) isp->isp_param;
6113	int tgt;
6114
6115	sdp += bus;
6116
6117	sdp->isp_fifo_threshold =
6118	    ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
6119
6120	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
6121		sdp->isp_initiator_id =
6122		    ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus);
6123
6124	sdp->isp_bus_reset_delay =
6125	    ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
6126
6127	sdp->isp_retry_count =
6128	    ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
6129
6130	sdp->isp_retry_delay =
6131	    ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
6132
6133	sdp->isp_async_data_setup =
6134	    ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
6135
6136	sdp->isp_req_ack_active_neg =
6137	    ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
6138
6139	sdp->isp_data_line_active_neg =
6140	    ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
6141
6142	sdp->isp_data_dma_burst_enabl =
6143	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
6144
6145	sdp->isp_cmd_dma_burst_enable =
6146	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
6147
6148	sdp->isp_selection_timeout =
6149	    ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
6150
6151	sdp->isp_max_queue_depth =
6152	     ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
6153
6154	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
6155	    bus, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
6156	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
6157	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
6158	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
6159	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
6160	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
6161	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
6162
6163
6164	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
6165		sdp->isp_devparam[tgt].dev_enable =
6166		    ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
6167		sdp->isp_devparam[tgt].exc_throttle =
6168			ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
6169		sdp->isp_devparam[tgt].nvrm_offset =
6170			ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
6171		sdp->isp_devparam[tgt].nvrm_period =
6172			ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
6173		sdp->isp_devparam[tgt].nvrm_flags = 0;
6174		if (ISP1080_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
6175			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
6176		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
6177		if (ISP1080_NVRAM_TGT_TQING(nvram_data, tgt, bus))
6178			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
6179		if (ISP1080_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
6180			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
6181		if (ISP1080_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
6182			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
6183		if (ISP1080_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
6184			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
6185		if (ISP1080_NVRAM_TGT_DISC(nvram_data, tgt, bus))
6186			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
6187		sdp->isp_devparam[tgt].actv_flags = 0;
6188		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
6189		    bus, tgt, sdp->isp_devparam[tgt].nvrm_flags,
6190		    sdp->isp_devparam[tgt].nvrm_offset,
6191		    sdp->isp_devparam[tgt].nvrm_period);
6192		sdp->isp_devparam[tgt].goal_offset =
6193		    sdp->isp_devparam[tgt].nvrm_offset;
6194		sdp->isp_devparam[tgt].goal_period =
6195		    sdp->isp_devparam[tgt].nvrm_period;
6196		sdp->isp_devparam[tgt].goal_flags =
6197		    sdp->isp_devparam[tgt].nvrm_flags;
6198	}
6199}
6200
6201static void
6202isp_parse_nvram_12160(struct ispsoftc *isp, int bus, u_int8_t *nvram_data)
6203{
6204	sdparam *sdp = (sdparam *) isp->isp_param;
6205	int tgt;
6206
6207	sdp += bus;
6208
6209	sdp->isp_fifo_threshold =
6210	    ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data);
6211
6212	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
6213		sdp->isp_initiator_id =
6214		    ISP12160_NVRAM_INITIATOR_ID(nvram_data, bus);
6215
6216	sdp->isp_bus_reset_delay =
6217	    ISP12160_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
6218
6219	sdp->isp_retry_count =
6220	    ISP12160_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
6221
6222	sdp->isp_retry_delay =
6223	    ISP12160_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
6224
6225	sdp->isp_async_data_setup =
6226	    ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
6227
6228	sdp->isp_req_ack_active_neg =
6229	    ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
6230
6231	sdp->isp_data_line_active_neg =
6232	    ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
6233
6234	sdp->isp_data_dma_burst_enabl =
6235	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
6236
6237	sdp->isp_cmd_dma_burst_enable =
6238	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
6239
6240	sdp->isp_selection_timeout =
6241	    ISP12160_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
6242
6243	sdp->isp_max_queue_depth =
6244	     ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
6245
6246	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
6247	    bus, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
6248	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
6249	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
6250	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
6251	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
6252	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
6253	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
6254
6255	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
6256		sdp->isp_devparam[tgt].dev_enable =
6257		    ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
6258		sdp->isp_devparam[tgt].exc_throttle =
6259			ISP12160_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
6260		sdp->isp_devparam[tgt].nvrm_offset =
6261			ISP12160_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
6262		sdp->isp_devparam[tgt].nvrm_period =
6263			ISP12160_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
6264		sdp->isp_devparam[tgt].nvrm_flags = 0;
6265		if (ISP12160_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
6266			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
6267		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
6268		if (ISP12160_NVRAM_TGT_TQING(nvram_data, tgt, bus))
6269			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
6270		if (ISP12160_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
6271			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
6272		if (ISP12160_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
6273			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
6274		if (ISP12160_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
6275			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
6276		if (ISP12160_NVRAM_TGT_DISC(nvram_data, tgt, bus))
6277			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
6278		sdp->isp_devparam[tgt].actv_flags = 0;
6279		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
6280		    bus, tgt, sdp->isp_devparam[tgt].nvrm_flags,
6281		    sdp->isp_devparam[tgt].nvrm_offset,
6282		    sdp->isp_devparam[tgt].nvrm_period);
6283		sdp->isp_devparam[tgt].goal_offset =
6284		    sdp->isp_devparam[tgt].nvrm_offset;
6285		sdp->isp_devparam[tgt].goal_period =
6286		    sdp->isp_devparam[tgt].nvrm_period;
6287		sdp->isp_devparam[tgt].goal_flags =
6288		    sdp->isp_devparam[tgt].nvrm_flags;
6289	}
6290}
6291
6292static void
6293isp_parse_nvram_2100(struct ispsoftc *isp, u_int8_t *nvram_data)
6294{
6295	fcparam *fcp = (fcparam *) isp->isp_param;
6296	u_int64_t wwn;
6297
6298	/*
6299	 * There is NVRAM storage for both Port and Node entities-
6300	 * but the Node entity appears to be unused on all the cards
6301	 * I can find. However, we should account for this being set
6302	 * at some point in the future.
6303	 *
6304	 * Qlogic WWNs have an NAA of 2, but usually nothing shows up in
6305	 * bits 48..60. In the case of the 2202, it appears that they do
6306	 * use bit 48 to distinguish between the two instances on the card.
6307	 * The 2204, which I've never seen, *probably* extends this method.
6308	 */
6309	wwn = ISP2100_NVRAM_PORT_NAME(nvram_data);
6310	if (wwn) {
6311		isp_prt(isp, ISP_LOGCONFIG, "NVRAM Port WWN 0x%08x%08x",
6312		    (u_int32_t) (wwn >> 32), (u_int32_t) (wwn & 0xffffffff));
6313		if ((wwn >> 60) == 0) {
6314			wwn |= (((u_int64_t) 2)<< 60);
6315		}
6316	}
6317	fcp->isp_portwwn = wwn;
6318	if (IS_2200(isp) || IS_23XX(isp)) {
6319		wwn = ISP2200_NVRAM_NODE_NAME(nvram_data);
6320		if (wwn) {
6321			isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
6322			    (u_int32_t) (wwn >> 32),
6323			    (u_int32_t) (wwn & 0xffffffff));
6324			if ((wwn >> 60) == 0) {
6325				wwn |= (((u_int64_t) 2)<< 60);
6326			}
6327		}
6328	} else {
6329		wwn &= ~((u_int64_t) 0xfff << 48);
6330	}
6331	fcp->isp_nodewwn = wwn;
6332
6333	/*
6334	 * Make sure we have both Node and Port as non-zero values.
6335	 */
6336	if (fcp->isp_nodewwn != 0 && fcp->isp_portwwn == 0) {
6337		fcp->isp_portwwn = fcp->isp_nodewwn;
6338	} else if (fcp->isp_nodewwn == 0 && fcp->isp_portwwn != 0) {
6339		fcp->isp_nodewwn = fcp->isp_portwwn;
6340	}
6341
6342	/*
6343	 * Make the Node and Port values sane if they're NAA == 2.
6344	 * This means to clear bits 48..56 for the Node WWN and
6345	 * make sure that there's some non-zero value in 48..56
6346	 * for the Port WWN.
6347	 */
6348	if (fcp->isp_nodewwn && fcp->isp_portwwn) {
6349		if ((fcp->isp_nodewwn & (((u_int64_t) 0xfff) << 48)) != 0 &&
6350		    (fcp->isp_nodewwn >> 60) == 2) {
6351			fcp->isp_nodewwn &= ~((u_int64_t) 0xfff << 48);
6352		}
6353		if ((fcp->isp_portwwn & (((u_int64_t) 0xfff) << 48)) == 0 &&
6354		    (fcp->isp_portwwn >> 60) == 2) {
6355			fcp->isp_portwwn |= ((u_int64_t) 1 << 56);
6356		}
6357	}
6358
6359	isp_prt(isp, ISP_LOGDEBUG0,
6360	    "NVRAM: maxfrmlen %d execthrottle %d fwoptions 0x%x loopid %x",
6361	    ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data),
6362	    ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
6363	    ISP2100_NVRAM_OPTIONS(nvram_data),
6364	    ISP2100_NVRAM_HARDLOOPID(nvram_data));
6365
6366	fcp->isp_maxalloc =
6367		ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
6368	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0)
6369		fcp->isp_maxfrmlen =
6370			ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
6371	fcp->isp_retry_delay =
6372		ISP2100_NVRAM_RETRY_DELAY(nvram_data);
6373	fcp->isp_retry_count =
6374		ISP2100_NVRAM_RETRY_COUNT(nvram_data);
6375	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
6376		fcp->isp_loopid =
6377			ISP2100_NVRAM_HARDLOOPID(nvram_data);
6378	if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0)
6379		fcp->isp_execthrottle =
6380			ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
6381	fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
6382}
6383
6384#ifdef	ISP_FW_CRASH_DUMP
6385static void isp2200_fw_dump(struct ispsoftc *);
6386static void isp2300_fw_dump(struct ispsoftc *);
6387
6388static void
6389isp2200_fw_dump(struct ispsoftc *isp)
6390{
6391	int i, j;
6392	mbreg_t mbs;
6393	u_int16_t *ptr;
6394
6395	ptr = FCPARAM(isp)->isp_dump_data;
6396	if (ptr == NULL) {
6397		isp_prt(isp, ISP_LOGERR,
6398		   "No place to dump RISC registers and SRAM");
6399		return;
6400	}
6401	if (*ptr++) {
6402		isp_prt(isp, ISP_LOGERR,
6403		   "dump area for RISC registers and SRAM already used");
6404		return;
6405	}
6406	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
6407	for (i = 0; i < 100; i++) {
6408		USEC_DELAY(100);
6409		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
6410			break;
6411		}
6412	}
6413	if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
6414		/*
6415		 * PBIU Registers
6416		 */
6417		for (i = 0; i < 8; i++) {
6418			*ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
6419		}
6420
6421		/*
6422		 * Mailbox Registers
6423		 */
6424		for (i = 0; i < 8; i++) {
6425			*ptr++ = ISP_READ(isp, MBOX_BLOCK + (i << 1));
6426		}
6427
6428		/*
6429		 * DMA Registers
6430		 */
6431		for (i = 0; i < 48; i++) {
6432			*ptr++ = ISP_READ(isp, DMA_BLOCK + 0x20 + (i << 1));
6433		}
6434
6435		/*
6436		 * RISC H/W Registers
6437		 */
6438		ISP_WRITE(isp, BIU2100_CSR, 0);
6439		for (i = 0; i < 16; i++) {
6440			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0xA0 + (i << 1));
6441		}
6442
6443		/*
6444		 * RISC GP Registers
6445		 */
6446		for (j = 0; j < 8; j++) {
6447			ISP_WRITE(isp, BIU_BLOCK + 0xA4, 0x2000 + (j << 8));
6448			for (i = 0; i < 16; i++) {
6449				*ptr++ =
6450				    ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6451			}
6452		}
6453
6454		/*
6455		 * Frame Buffer Hardware Registers
6456		 */
6457		ISP_WRITE(isp, BIU2100_CSR, 0x10);
6458		for (i = 0; i < 16; i++) {
6459			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6460		}
6461
6462		/*
6463		 * Fibre Protocol Module 0 Hardware Registers
6464		 */
6465		ISP_WRITE(isp, BIU2100_CSR, 0x20);
6466		for (i = 0; i < 64; i++) {
6467			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6468		}
6469
6470		/*
6471		 * Fibre Protocol Module 1 Hardware Registers
6472		 */
6473		ISP_WRITE(isp, BIU2100_CSR, 0x30);
6474		for (i = 0; i < 64; i++) {
6475			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6476		}
6477	} else {
6478		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause");
6479		return;
6480	}
6481	isp_prt(isp, ISP_LOGALL,
6482	   "isp_fw_dump: RISC registers dumped successfully");
6483	ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
6484	for (i = 0; i < 100; i++) {
6485		USEC_DELAY(100);
6486		if (ISP_READ(isp, OUTMAILBOX0) == 0) {
6487			break;
6488		}
6489	}
6490	if (ISP_READ(isp, OUTMAILBOX0) != 0) {
6491		isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
6492		return;
6493	}
6494	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
6495	for (i = 0; i < 100; i++) {
6496		USEC_DELAY(100);
6497		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
6498			break;
6499		}
6500	}
6501	if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
6502		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause After Reset");
6503		return;
6504	}
6505	ISP_WRITE(isp, RISC_EMB, 0xf2);
6506	ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
6507	for (i = 0; i < 100; i++) {
6508		USEC_DELAY(100);
6509		if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
6510			break;
6511		}
6512	}
6513	ENABLE_INTS(isp);
6514	mbs.param[0] = MBOX_READ_RAM_WORD;
6515	mbs.param[1] = 0x1000;
6516	isp->isp_mbxworkp = (void *) ptr;
6517	isp->isp_mbxwrk0 = 0xefff;	/* continuation count */
6518	isp->isp_mbxwrk1 = 0x1001;	/* next SRAM address */
6519	isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
6520	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
6521		isp_prt(isp, ISP_LOGWARN,
6522		    "RAM DUMP FAILED @ WORD %x", isp->isp_mbxwrk1);
6523		return;
6524	}
6525	ptr = isp->isp_mbxworkp;	/* finish fetch of final word */
6526	*ptr++ = isp->isp_mboxtmp[2];
6527	isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped succesfully");
6528	FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */
6529	(void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
6530}
6531
6532static void
6533isp2300_fw_dump(struct ispsoftc *isp)
6534{
6535	int i, j;
6536	mbreg_t mbs;
6537	u_int16_t *ptr;
6538
6539	ptr = FCPARAM(isp)->isp_dump_data;
6540	if (ptr == NULL) {
6541		isp_prt(isp, ISP_LOGERR,
6542		   "No place to dump RISC registers and SRAM");
6543		return;
6544	}
6545	if (*ptr++) {
6546		isp_prt(isp, ISP_LOGERR,
6547		   "dump area for RISC registers and SRAM already used");
6548		return;
6549	}
6550	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
6551	for (i = 0; i < 100; i++) {
6552		USEC_DELAY(100);
6553		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
6554			break;
6555		}
6556	}
6557	if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
6558		/*
6559		 * PBIU registers
6560		 */
6561		for (i = 0; i < 8; i++) {
6562			*ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
6563		}
6564
6565		/*
6566		 * ReqQ-RspQ-Risc2Host Status registers
6567		 */
6568		for (i = 0; i < 8; i++) {
6569			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x10 + (i << 1));
6570		}
6571
6572		/*
6573		 * Mailbox Registers
6574		 */
6575		for (i = 0; i < 32; i++) {
6576			*ptr++ =
6577			    ISP_READ(isp, PCI_MBOX_REGS2300_OFF + (i << 1));
6578		}
6579
6580		/*
6581		 * Auto Request Response DMA registers
6582		 */
6583		ISP_WRITE(isp, BIU2100_CSR, 0x40);
6584		for (i = 0; i < 32; i++) {
6585			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6586		}
6587
6588		/*
6589		 * DMA registers
6590		 */
6591		ISP_WRITE(isp, BIU2100_CSR, 0x50);
6592		for (i = 0; i < 48; i++) {
6593			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6594		}
6595
6596		/*
6597		 * RISC hardware registers
6598		 */
6599		ISP_WRITE(isp, BIU2100_CSR, 0);
6600		for (i = 0; i < 16; i++) {
6601			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0xA0 + (i << 1));
6602		}
6603
6604		/*
6605		 * RISC GP? registers
6606		 */
6607		for (j = 0; j < 8; j++) {
6608			ISP_WRITE(isp, BIU_BLOCK + 0xA4, 0x2000 + (j << 9));
6609			for (i = 0; i < 16; i++) {
6610				*ptr++ =
6611				    ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6612			}
6613		}
6614
6615		/*
6616		 * frame buffer hardware registers
6617		 */
6618		ISP_WRITE(isp, BIU2100_CSR, 0x10);
6619		for (i = 0; i < 64; i++) {
6620			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6621		}
6622
6623		/*
6624		 * FPM B0 hardware registers
6625		 */
6626		ISP_WRITE(isp, BIU2100_CSR, 0x20);
6627		for (i = 0; i < 64; i++) {
6628			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6629		}
6630
6631		/*
6632		 * FPM B1 hardware registers
6633		 */
6634		ISP_WRITE(isp, BIU2100_CSR, 0x30);
6635		for (i = 0; i < 64; i++) {
6636			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6637		}
6638	} else {
6639		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause");
6640		return;
6641	}
6642	isp_prt(isp, ISP_LOGALL,
6643	   "isp_fw_dump: RISC registers dumped successfully");
6644	ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
6645	for (i = 0; i < 100; i++) {
6646		USEC_DELAY(100);
6647		if (ISP_READ(isp, OUTMAILBOX0) == 0) {
6648			break;
6649		}
6650	}
6651	if (ISP_READ(isp, OUTMAILBOX0) != 0) {
6652		isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
6653		return;
6654	}
6655	ENABLE_INTS(isp);
6656	mbs.param[0] = MBOX_READ_RAM_WORD;
6657	mbs.param[1] = 0x800;
6658	isp->isp_mbxworkp = (void *) ptr;
6659	isp->isp_mbxwrk0 = 0xf7ff;	/* continuation count */
6660	isp->isp_mbxwrk1 = 0x801;	/* next SRAM address */
6661	isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
6662	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
6663		isp_prt(isp, ISP_LOGWARN,
6664		    "RAM DUMP FAILED @ WORD %x", isp->isp_mbxwrk1);
6665		return;
6666	}
6667	ptr = isp->isp_mbxworkp;	/* finish fetch of final word */
6668	*ptr++ = isp->isp_mboxtmp[2];
6669
6670	/*
6671	 * We don't have access to mailbox registers 8.. onward
6672	 * in our 'common' device model- so we have to set it
6673	 * here and hope it stays the same!
6674	 */
6675	ISP_WRITE(isp, PCI_MBOX_REGS2300_OFF + (8 << 1), 0x1);
6676
6677	mbs.param[0] = MBOX_READ_RAM_WORD_EXTENDED;
6678	mbs.param[1] = 0;
6679	isp->isp_mbxworkp = (void *) ptr;
6680	isp->isp_mbxwrk0 = 0xffff;	/* continuation count */
6681	isp->isp_mbxwrk1 = 0x1;		/* next SRAM address */
6682	isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
6683	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
6684		isp_prt(isp, ISP_LOGWARN,
6685		    "RAM DUMP FAILED @ WORD %x", 0x10000 + isp->isp_mbxwrk1);
6686		return;
6687	}
6688	ptr = isp->isp_mbxworkp;	/* finish final word */
6689	*ptr++ = mbs.param[2];
6690	isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped succesfully");
6691	FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */
6692	(void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
6693}
6694
6695void
6696isp_fw_dump(struct ispsoftc *isp)
6697{
6698	if (IS_2200(isp))
6699		isp2200_fw_dump(isp);
6700	else if (IS_23XX(isp))
6701		isp2300_fw_dump(isp);
6702}
6703#endif
6704