1 /*-
2  *  Copyright (c) 1997-2009 by Matthew Jacob
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions
7  *  are met:
8  *
9  *  1. Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  *  2. Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  *
15  *  THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  *  ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
19  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  *  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  *  SUCH DAMAGE.
26  *
27  */
28 
29 /*
30  * Machine and OS Independent (well, as best as possible)
31  * code for the Qlogic ISP SCSI and FC-SCSI adapters.
32  */
33 
34 /*
35  * Inspiration and ideas about this driver are from Erik Moe's Linux driver
36  * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some
37  * ideas dredged from the Solaris driver.
38  */
39 
40 /*
41  * Include header file appropriate for platform we're building on.
42  */
43 #ifdef	__NetBSD__
44 #include <sys/cdefs.h>
45 __KERNEL_RCSID(0, "$NetBSD$");
46 #include <dev/ic/isp_netbsd.h>
47 #endif
48 #ifdef	__FreeBSD__
49 #include <sys/cdefs.h>
50 __FBSDID("$FreeBSD: stable/10/sys/dev/isp/isp.c 321945 2017-08-02 20:24:28Z ken $");
51 #include <dev/isp/isp_freebsd.h>
52 #endif
53 #ifdef	__OpenBSD__
54 #include <dev/ic/isp_openbsd.h>
55 #endif
56 #ifdef	__linux__
57 #include "isp_linux.h"
58 #endif
59 #ifdef	__svr4__
60 #include "isp_solaris.h"
61 #endif
62 
63 /*
64  * General defines
65  */
66 #define	MBOX_DELAY_COUNT	1000000 / 100
67 
68 /*
69  * Local static data
70  */
71 static const char notresp[] = "Unknown IOCB in RESPONSE Queue (type 0x%x) @ idx %d (next %d)";
72 static const char bun[] = "bad underrun (count %d, resid %d, status %s)";
73 static const char lipd[] = "Chan %d LIP destroyed %d active commands";
74 static const char sacq[] = "unable to acquire scratch area";
75 
76 static const uint8_t alpa_map[] = {
77 	0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda,
78 	0xd9, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce,
79 	0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc7, 0xc6, 0xc5,
80 	0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5, 0xb4, 0xb3,
81 	0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9,
82 	0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b,
83 	0x98, 0x97, 0x90, 0x8f, 0x88, 0x84, 0x82, 0x81,
84 	0x80, 0x7c, 0x7a, 0x79, 0x76, 0x75, 0x74, 0x73,
85 	0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69,
86 	0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56,
87 	0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c,
88 	0x4b, 0x4a, 0x49, 0x47, 0x46, 0x45, 0x43, 0x3c,
89 	0x3a, 0x39, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31,
90 	0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x27, 0x26,
91 	0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17,
92 	0x10, 0x0f, 0x08, 0x04, 0x02, 0x01, 0x00
93 };
94 
95 /*
96  * Local function prototypes.
97  */
98 static void isp_parse_async(ispsoftc_t *, uint16_t);
99 static void isp_parse_async_fc(ispsoftc_t *, uint16_t);
100 static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *, uint32_t *);
101 static void isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *, uint32_t *);
102 static void isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *, uint32_t *);
103 static void isp_fastpost_complete(ispsoftc_t *, uint32_t);
104 static void isp_scsi_init(ispsoftc_t *);
105 static void isp_scsi_channel_init(ispsoftc_t *, int);
106 static void isp_fibre_init(ispsoftc_t *);
107 static void isp_fibre_init_2400(ispsoftc_t *);
108 static void isp_clear_portdb(ispsoftc_t *, int);
109 static void isp_mark_portdb(ispsoftc_t *, int);
110 static int isp_plogx(ispsoftc_t *, int, uint16_t, uint32_t, int);
111 static int isp_port_login(ispsoftc_t *, uint16_t, uint32_t);
112 static int isp_port_logout(ispsoftc_t *, uint16_t, uint32_t);
113 static int isp_getpdb(ispsoftc_t *, int, uint16_t, isp_pdb_t *);
114 static int isp_gethandles(ispsoftc_t *, int, uint16_t *, int *, int);
115 static void isp_dump_chip_portdb(ispsoftc_t *, int);
116 static uint64_t isp_get_wwn(ispsoftc_t *, int, int, int);
117 static int isp_fclink_test(ispsoftc_t *, int, int);
118 static int isp_pdb_sync(ispsoftc_t *, int);
119 static int isp_scan_loop(ispsoftc_t *, int);
120 static int isp_gid_ft_sns(ispsoftc_t *, int);
121 static int isp_gid_ft_ct_passthru(ispsoftc_t *, int);
122 static int isp_scan_fabric(ispsoftc_t *, int);
123 static int isp_login_device(ispsoftc_t *, int, uint32_t, isp_pdb_t *, uint16_t *);
124 static int isp_send_change_request(ispsoftc_t *, int);
125 static int isp_register_fc4_type(ispsoftc_t *, int);
126 static int isp_register_fc4_type_24xx(ispsoftc_t *, int);
127 static int isp_register_fc4_features_24xx(ispsoftc_t *, int);
128 static int isp_register_port_name_24xx(ispsoftc_t *, int);
129 static int isp_register_node_name_24xx(ispsoftc_t *, int);
130 static uint16_t isp_next_handle(ispsoftc_t *, uint16_t *);
131 static int isp_fw_state(ispsoftc_t *, int);
132 static void isp_mboxcmd(ispsoftc_t *, mbreg_t *);
133 
134 static void isp_spi_update(ispsoftc_t *, int);
135 static void isp_setdfltsdparm(ispsoftc_t *);
136 static void isp_setdfltfcparm(ispsoftc_t *, int);
137 static int isp_read_nvram(ispsoftc_t *, int);
138 static int isp_read_nvram_2400(ispsoftc_t *, uint8_t *);
139 static void isp_rdnvram_word(ispsoftc_t *, int, uint16_t *);
140 static void isp_rd_2400_nvram(ispsoftc_t *, uint32_t, uint32_t *);
141 static void isp_parse_nvram_1020(ispsoftc_t *, uint8_t *);
142 static void isp_parse_nvram_1080(ispsoftc_t *, int, uint8_t *);
143 static void isp_parse_nvram_12160(ispsoftc_t *, int, uint8_t *);
144 static void isp_parse_nvram_2100(ispsoftc_t *, uint8_t *);
145 static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *);
146 
147 static void
isp_change_fw_state(ispsoftc_t * isp,int chan,int state)148 isp_change_fw_state(ispsoftc_t *isp, int chan, int state)
149 {
150 	fcparam *fcp = FCPARAM(isp, chan);
151 
152 	if (fcp->isp_fwstate == state)
153 		return;
154 	isp_prt(isp, ISP_LOGCONFIG|ISP_LOG_SANCFG,
155 	    "Chan %d Firmware state <%s->%s>", chan,
156 	    isp_fc_fw_statename(fcp->isp_fwstate), isp_fc_fw_statename(state));
157 	fcp->isp_fwstate = state;
158 }
159 
160 /*
161  * Reset Hardware.
162  *
163  * Hit the chip over the head, download new f/w if available and set it running.
164  *
165  * Locking done elsewhere.
166  */
167 
168 void
isp_reset(ispsoftc_t * isp,int do_load_defaults)169 isp_reset(ispsoftc_t *isp, int do_load_defaults)
170 {
171 	mbreg_t mbs;
172 	char *buf;
173 	uint64_t fwt;
174 	uint32_t code_org, val;
175 	int loops, i, dodnld = 1;
176 	const char *btype = "????";
177 	static const char dcrc[] = "Downloaded RISC Code Checksum Failure";
178 
179 	/*
180 	 * Basic types (SCSI, FibreChannel and PCI or SBus)
181 	 * have been set in the MD code. We figure out more
182 	 * here. Possibly more refined types based upon PCI
183 	 * identification. Chip revision has been gathered.
184 	 *
185 	 * After we've fired this chip up, zero out the conf1 register
186 	 * for SCSI adapters and do other settings for the 2100.
187 	 */
188 
189 	isp->isp_state = ISP_NILSTATE;
190 	ISP_DISABLE_INTS(isp);
191 
192 	/*
193 	 * Put the board into PAUSE mode (so we can read the SXP registers
194 	 * or write FPM/FBM registers).
195 	 */
196 	if (IS_24XX(isp)) {
197 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_HOST_INT);
198 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
199 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
200 	} else {
201 		ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
202 	}
203 
204 	if (IS_FC(isp)) {
205 		switch (isp->isp_type) {
206 		case ISP_HA_FC_2100:
207 			btype = "2100";
208 			break;
209 		case ISP_HA_FC_2200:
210 			btype = "2200";
211 			break;
212 		case ISP_HA_FC_2300:
213 			btype = "2300";
214 			break;
215 		case ISP_HA_FC_2312:
216 			btype = "2312";
217 			break;
218 		case ISP_HA_FC_2322:
219 			btype = "2322";
220 			break;
221 		case ISP_HA_FC_2400:
222 			btype = "2422";
223 			break;
224 		case ISP_HA_FC_2500:
225 			btype = "2532";
226 			break;
227 		case ISP_HA_FC_2600:
228 			btype = "2031";
229 			break;
230 		default:
231 			break;
232 		}
233 
234 		if (!IS_24XX(isp)) {
235 			/*
236 			 * While we're paused, reset the FPM module and FBM
237 			 * fifos.
238 			 */
239 			ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
240 			ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
241 			ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
242 			ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
243 			ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
244 		}
245 	} else if (IS_1240(isp)) {
246 		sdparam *sdp;
247 
248 		btype = "1240";
249 		isp->isp_clock = 60;
250 		sdp = SDPARAM(isp, 0);
251 		sdp->isp_ultramode = 1;
252 		sdp = SDPARAM(isp, 1);
253 		sdp->isp_ultramode = 1;
254 		/*
255 		 * XXX: Should probably do some bus sensing.
256 		 */
257 	} else if (IS_ULTRA3(isp)) {
258 		sdparam *sdp = isp->isp_param;
259 
260 		isp->isp_clock = 100;
261 
262 		if (IS_10160(isp))
263 			btype = "10160";
264 		else if (IS_12160(isp))
265 			btype = "12160";
266 		else
267 			btype = "<UNKLVD>";
268 		sdp->isp_lvdmode = 1;
269 
270 		if (IS_DUALBUS(isp)) {
271 			sdp++;
272 			sdp->isp_lvdmode = 1;
273 		}
274 	} else if (IS_ULTRA2(isp)) {
275 		static const char m[] = "bus %d is in %s Mode";
276 		uint16_t l;
277 		sdparam *sdp = SDPARAM(isp, 0);
278 
279 		isp->isp_clock = 100;
280 
281 		if (IS_1280(isp))
282 			btype = "1280";
283 		else if (IS_1080(isp))
284 			btype = "1080";
285 		else
286 			btype = "<UNKLVD>";
287 
288 		l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK;
289 		switch (l) {
290 		case ISP1080_LVD_MODE:
291 			sdp->isp_lvdmode = 1;
292 			isp_prt(isp, ISP_LOGCONFIG, m, 0, "LVD");
293 			break;
294 		case ISP1080_HVD_MODE:
295 			sdp->isp_diffmode = 1;
296 			isp_prt(isp, ISP_LOGCONFIG, m, 0, "Differential");
297 			break;
298 		case ISP1080_SE_MODE:
299 			sdp->isp_ultramode = 1;
300 			isp_prt(isp, ISP_LOGCONFIG, m, 0, "Single-Ended");
301 			break;
302 		default:
303 			isp_prt(isp, ISP_LOGERR,
304 			    "unknown mode on bus %d (0x%x)", 0, l);
305 			break;
306 		}
307 
308 		if (IS_DUALBUS(isp)) {
309 			sdp = SDPARAM(isp, 1);
310 			l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT);
311 			l &= ISP1080_MODE_MASK;
312 			switch (l) {
313 			case ISP1080_LVD_MODE:
314 				sdp->isp_lvdmode = 1;
315 				isp_prt(isp, ISP_LOGCONFIG, m, 1, "LVD");
316 				break;
317 			case ISP1080_HVD_MODE:
318 				sdp->isp_diffmode = 1;
319 				isp_prt(isp, ISP_LOGCONFIG,
320 				    m, 1, "Differential");
321 				break;
322 			case ISP1080_SE_MODE:
323 				sdp->isp_ultramode = 1;
324 				isp_prt(isp, ISP_LOGCONFIG,
325 				    m, 1, "Single-Ended");
326 				break;
327 			default:
328 				isp_prt(isp, ISP_LOGERR,
329 				    "unknown mode on bus %d (0x%x)", 1, l);
330 				break;
331 			}
332 		}
333 	} else {
334 		sdparam *sdp = SDPARAM(isp, 0);
335 		i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK;
336 		switch (i) {
337 		default:
338 			isp_prt(isp, ISP_LOGALL, "Unknown Chip Type 0x%x", i);
339 			/* FALLTHROUGH */
340 		case 1:
341 			btype = "1020";
342 			isp->isp_type = ISP_HA_SCSI_1020;
343 			isp->isp_clock = 40;
344 			break;
345 		case 2:
346 			/*
347 			 * Some 1020A chips are Ultra Capable, but don't
348 			 * run the clock rate up for that unless told to
349 			 * do so by the Ultra Capable bits being set.
350 			 */
351 			btype = "1020A";
352 			isp->isp_type = ISP_HA_SCSI_1020A;
353 			isp->isp_clock = 40;
354 			break;
355 		case 3:
356 			btype = "1040";
357 			isp->isp_type = ISP_HA_SCSI_1040;
358 			isp->isp_clock = 60;
359 			break;
360 		case 4:
361 			btype = "1040A";
362 			isp->isp_type = ISP_HA_SCSI_1040A;
363 			isp->isp_clock = 60;
364 			break;
365 		case 5:
366 			btype = "1040B";
367 			isp->isp_type = ISP_HA_SCSI_1040B;
368 			isp->isp_clock = 60;
369 			break;
370 		case 6:
371 			btype = "1040C";
372 			isp->isp_type = ISP_HA_SCSI_1040C;
373 			isp->isp_clock = 60;
374                         break;
375 		}
376 		/*
377 		 * Now, while we're at it, gather info about ultra
378 		 * and/or differential mode.
379 		 */
380 		if (ISP_READ(isp, SXP_PINS_DIFF) & SXP_PINS_DIFF_MODE) {
381 			isp_prt(isp, ISP_LOGCONFIG, "Differential Mode");
382 			sdp->isp_diffmode = 1;
383 		} else {
384 			sdp->isp_diffmode = 0;
385 		}
386 		i = ISP_READ(isp, RISC_PSR);
387 		if (isp->isp_bustype == ISP_BT_SBUS) {
388 			i &= RISC_PSR_SBUS_ULTRA;
389 		} else {
390 			i &= RISC_PSR_PCI_ULTRA;
391 		}
392 		if (i != 0) {
393 			isp_prt(isp, ISP_LOGCONFIG, "Ultra Mode Capable");
394 			sdp->isp_ultramode = 1;
395 			/*
396 			 * If we're in Ultra Mode, we have to be 60MHz clock-
397 			 * even for the SBus version.
398 			 */
399 			isp->isp_clock = 60;
400 		} else {
401 			sdp->isp_ultramode = 0;
402 			/*
403 			 * Clock is known. Gronk.
404 			 */
405 		}
406 
407 		/*
408 		 * Machine dependent clock (if set) overrides
409 		 * our generic determinations.
410 		 */
411 		if (isp->isp_mdvec->dv_clock) {
412 			if (isp->isp_mdvec->dv_clock < isp->isp_clock) {
413 				isp->isp_clock = isp->isp_mdvec->dv_clock;
414 			}
415 		}
416 	}
417 
418 	/*
419 	 * Hit the chip over the head with hammer,
420 	 * and give it a chance to recover.
421 	 */
422 
423 	if (IS_SCSI(isp)) {
424 		ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET);
425 		/*
426 		 * A slight delay...
427 		 */
428 		ISP_DELAY(100);
429 
430 		/*
431 		 * Clear data && control DMA engines.
432 		 */
433 		ISP_WRITE(isp, CDMA_CONTROL, DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
434 		ISP_WRITE(isp, DDMA_CONTROL, DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
435 
436 
437 	} else if (IS_24XX(isp)) {
438 		/*
439 		 * Stop DMA and wait for it to stop.
440 		 */
441 		ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4));
442 		for (val = loops = 0; loops < 30000; loops++) {
443 			ISP_DELAY(10);
444 			val = ISP_READ(isp, BIU2400_CSR);
445 			if ((val & BIU2400_DMA_ACTIVE) == 0) {
446 				break;
447 			}
448 		}
449 		if (val & BIU2400_DMA_ACTIVE) {
450 			isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset");
451 			return;
452 		}
453 		/*
454 		 * Hold it in SOFT_RESET and STOP state for 100us.
455 		 */
456 		ISP_WRITE(isp, BIU2400_CSR, BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4));
457 		ISP_DELAY(100);
458 		for (loops = 0; loops < 10000; loops++) {
459 			ISP_DELAY(5);
460 			val = ISP_READ(isp, OUTMAILBOX0);
461 		}
462 		for (val = loops = 0; loops < 500000; loops ++) {
463 			val = ISP_READ(isp, BIU2400_CSR);
464 			if ((val & BIU2400_SOFT_RESET) == 0) {
465 				break;
466 			}
467 		}
468 		if (val & BIU2400_SOFT_RESET) {
469 			isp_prt(isp, ISP_LOGERR, "Failed to come out of reset");
470 			return;
471 		}
472 	} else {
473 		ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
474 		/*
475 		 * A slight delay...
476 		 */
477 		ISP_DELAY(100);
478 
479 		/*
480 		 * Clear data && control DMA engines.
481 		 */
482 		ISP_WRITE(isp, CDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
483 		ISP_WRITE(isp, TDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
484 		ISP_WRITE(isp, RDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
485 	}
486 
487 	/*
488 	 * Wait for ISP to be ready to go...
489 	 */
490 	loops = MBOX_DELAY_COUNT;
491 	for (;;) {
492 		if (IS_SCSI(isp)) {
493 			if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET)) {
494 				break;
495 			}
496 		} else if (IS_24XX(isp)) {
497 			if (ISP_READ(isp, OUTMAILBOX0) == 0) {
498 				break;
499 			}
500 		} else {
501 			if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET))
502 				break;
503 		}
504 		ISP_DELAY(100);
505 		if (--loops < 0) {
506 			ISP_DUMPREGS(isp, "chip reset timed out");
507 			return;
508 		}
509 	}
510 
511 	/*
512 	 * After we've fired this chip up, zero out the conf1 register
513 	 * for SCSI adapters and other settings for the 2100.
514 	 */
515 
516 	if (IS_SCSI(isp)) {
517 		ISP_WRITE(isp, BIU_CONF1, 0);
518 	} else if (!IS_24XX(isp)) {
519 		ISP_WRITE(isp, BIU2100_CSR, 0);
520 	}
521 
522 	/*
523 	 * Reset RISC Processor
524 	 */
525 	if (IS_24XX(isp)) {
526 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
527 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RELEASE);
528 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET);
529 	} else {
530 		ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
531 		ISP_DELAY(100);
532 		ISP_WRITE(isp, BIU_SEMA, 0);
533 	}
534 
535 	/*
536 	 * Post-RISC Reset stuff.
537 	 */
538 	if (IS_24XX(isp)) {
539 		for (val = loops = 0; loops < 5000000; loops++) {
540 			ISP_DELAY(5);
541 			val = ISP_READ(isp, OUTMAILBOX0);
542 			if (val == 0) {
543 				break;
544 			}
545 		}
546 		if (val != 0) {
547 			isp_prt(isp, ISP_LOGERR, "reset didn't clear");
548 			return;
549 		}
550 	} else if (IS_SCSI(isp)) {
551 		uint16_t tmp = isp->isp_mdvec->dv_conf1;
552 		/*
553 		 * Busted FIFO. Turn off all but burst enables.
554 		 */
555 		if (isp->isp_type == ISP_HA_SCSI_1040A) {
556 			tmp &= BIU_BURST_ENABLE;
557 		}
558 		ISP_SETBITS(isp, BIU_CONF1, tmp);
559 		if (tmp & BIU_BURST_ENABLE) {
560 			ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
561 			ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
562 		}
563 		if (SDPARAM(isp, 0)->isp_ptisp) {
564 			if (SDPARAM(isp, 0)->isp_ultramode) {
565 				while (ISP_READ(isp, RISC_MTR) != 0x1313) {
566 					ISP_WRITE(isp, RISC_MTR, 0x1313);
567 					ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
568 				}
569 			} else {
570 				ISP_WRITE(isp, RISC_MTR, 0x1212);
571 			}
572 			/*
573 			 * PTI specific register
574 			 */
575 			ISP_WRITE(isp, RISC_EMB, DUAL_BANK);
576 		} else {
577 			ISP_WRITE(isp, RISC_MTR, 0x1212);
578 		}
579 		ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
580 	} else {
581 		ISP_WRITE(isp, RISC_MTR2100, 0x1212);
582 		if (IS_2200(isp) || IS_23XX(isp)) {
583 			ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE);
584 		}
585 		ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
586 	}
587 
588 	/*
589 	 * Set up default request/response queue in-pointer/out-pointer
590 	 * register indices.
591 	 */
592 	if (IS_24XX(isp)) {
593 		isp->isp_rqstinrp = BIU2400_REQINP;
594 		isp->isp_rqstoutrp = BIU2400_REQOUTP;
595 		isp->isp_respinrp = BIU2400_RSPINP;
596 		isp->isp_respoutrp = BIU2400_RSPOUTP;
597 	} else if (IS_23XX(isp)) {
598 		isp->isp_rqstinrp = BIU_REQINP;
599 		isp->isp_rqstoutrp = BIU_REQOUTP;
600 		isp->isp_respinrp = BIU_RSPINP;
601 		isp->isp_respoutrp = BIU_RSPOUTP;
602 	} else {
603 		isp->isp_rqstinrp = INMAILBOX4;
604 		isp->isp_rqstoutrp = OUTMAILBOX4;
605 		isp->isp_respinrp = OUTMAILBOX5;
606 		isp->isp_respoutrp = INMAILBOX5;
607 	}
608 	ISP_WRITE(isp, isp->isp_rqstinrp, 0);
609 	ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
610 	ISP_WRITE(isp, isp->isp_respinrp, 0);
611 	ISP_WRITE(isp, isp->isp_respoutrp, 0);
612 	if (IS_24XX(isp)) {
613 		if (!IS_26XX(isp)) {
614 			ISP_WRITE(isp, BIU2400_PRI_REQINP, 0);
615 			ISP_WRITE(isp, BIU2400_PRI_REQOUTP, 0);
616 		}
617 		ISP_WRITE(isp, BIU2400_ATIO_RSPINP, 0);
618 		ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, 0);
619 	}
620 
621 	if (!IS_24XX(isp) && isp->isp_bustype == ISP_BT_PCI) {
622 		/* Make sure the BIOS is disabled */
623 		ISP_WRITE(isp, HCCR, PCI_HCCR_CMD_BIOS);
624 	}
625 
626 	/*
627 	 * Wait for everything to finish firing up.
628 	 *
629 	 * Avoid doing this on early 2312s because you can generate a PCI
630 	 * parity error (chip breakage).
631 	 */
632 	if (IS_2312(isp) && isp->isp_revision < 2) {
633 		ISP_DELAY(100);
634 	} else {
635 		loops = MBOX_DELAY_COUNT;
636 		while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
637 			ISP_DELAY(100);
638 			if (--loops < 0) {
639 				isp_prt(isp, ISP_LOGERR, "MBOX_BUSY never cleared on reset");
640 				return;
641 			}
642 		}
643 	}
644 
645 	/*
646 	 * Up until this point we've done everything by just reading or
647 	 * setting registers. From this point on we rely on at least *some*
648 	 * kind of firmware running in the card.
649 	 */
650 
651 	/*
652 	 * Do some sanity checking by running a NOP command.
653 	 * If it succeeds, the ROM firmware is now running.
654 	 */
655 	MBSINIT(&mbs, MBOX_NO_OP, MBLOGALL, 0);
656 	isp_mboxcmd(isp, &mbs);
657 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
658 		isp_prt(isp, ISP_LOGERR, "NOP command failed (%x)", mbs.param[0]);
659 		return;
660 	}
661 
662 	/*
663 	 * Do some operational tests
664 	 */
665 	if (IS_SCSI(isp) || IS_24XX(isp)) {
666 		static const uint16_t patterns[MAX_MAILBOX] = {
667 			0x0000, 0xdead, 0xbeef, 0xffff,
668 			0xa5a5, 0x5a5a, 0x7f7f, 0x7ff7,
669 			0x3421, 0xabcd, 0xdcba, 0xfeef,
670 			0xbead, 0xdebe, 0x2222, 0x3333,
671 			0x5555, 0x6666, 0x7777, 0xaaaa,
672 			0xffff, 0xdddd, 0x9999, 0x1fbc,
673 			0x6666, 0x6677, 0x1122, 0x33ff,
674 			0x0000, 0x0001, 0x1000, 0x1010,
675 		};
676 		int nmbox = ISP_NMBOX(isp);
677 		if (IS_SCSI(isp))
678 			nmbox = 6;
679 		MBSINIT(&mbs, MBOX_MAILBOX_REG_TEST, MBLOGALL, 0);
680 		for (i = 1; i < nmbox; i++) {
681 			mbs.param[i] = patterns[i];
682 		}
683 		isp_mboxcmd(isp, &mbs);
684 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
685 			return;
686 		}
687 		for (i = 1; i < nmbox; i++) {
688 			if (mbs.param[i] != patterns[i]) {
689 				isp_prt(isp, ISP_LOGERR, "Register Test Failed at Register %d: should have 0x%04x but got 0x%04x", i, patterns[i], mbs.param[i]);
690 				return;
691 			}
692 		}
693 	}
694 
695 	/*
696 	 * Download new Firmware, unless requested not to do so.
697 	 * This is made slightly trickier in some cases where the
698 	 * firmware of the ROM revision is newer than the revision
699 	 * compiled into the driver. So, where we used to compare
700 	 * versions of our f/w and the ROM f/w, now we just see
701 	 * whether we have f/w at all and whether a config flag
702 	 * has disabled our download.
703 	 */
704 	if ((isp->isp_mdvec->dv_ispfw == NULL) || (isp->isp_confopts & ISP_CFG_NORELOAD)) {
705 		dodnld = 0;
706 	} else {
707 
708 		/*
709 		 * Set up DMA for the request and response queues.
710 		 * We do this now so we can use the request queue
711 		 * for dma to load firmware from.
712 		 */
713 		if (ISP_MBOXDMASETUP(isp) != 0) {
714 			isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
715 			return;
716 		}
717 	}
718 
719 	if (IS_24XX(isp)) {
720 		code_org = ISP_CODE_ORG_2400;
721 	} else if (IS_23XX(isp)) {
722 		code_org = ISP_CODE_ORG_2300;
723 	} else {
724 		code_org = ISP_CODE_ORG;
725 	}
726 
727 	isp->isp_loaded_fw = 0;
728 	if (dodnld && IS_24XX(isp)) {
729 		const uint32_t *ptr = isp->isp_mdvec->dv_ispfw;
730 		uint32_t la, wi, wl;
731 
732 		/*
733 		 * Keep loading until we run out of f/w.
734 		 */
735 		code_org = ptr[2];	/* 1st load address is our start addr */
736 
737 		for (;;) {
738 
739 			isp_prt(isp, ISP_LOGDEBUG0, "load 0x%x words of code at load address 0x%x", ptr[3], ptr[2]);
740 
741 			wi = 0;
742 			la = ptr[2];
743 			wl = ptr[3];
744 			while (wi < ptr[3]) {
745 				uint32_t *cp;
746 				uint32_t nw;
747 
748 				nw = min(wl, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) / 4);
749 				cp = isp->isp_rquest;
750 				for (i = 0; i < nw; i++)
751 					ISP_IOXPUT_32(isp, ptr[wi + i], &cp[i]);
752 				MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)), -1);
753 				MBSINIT(&mbs, MBOX_LOAD_RISC_RAM, MBLOGALL, 0);
754 				mbs.param[1] = la;
755 				mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
756 				mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
757 				mbs.param[4] = nw >> 16;
758 				mbs.param[5] = nw;
759 				mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
760 				mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
761 				mbs.param[8] = la >> 16;
762 				isp_prt(isp, ISP_LOGDEBUG0, "LOAD RISC RAM %u words at load address 0x%x", nw, la);
763 				isp_mboxcmd(isp, &mbs);
764 				if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
765 					isp_prt(isp, ISP_LOGERR, "F/W download failed");
766 					return;
767 				}
768 				la += nw;
769 				wi += nw;
770 				wl -= nw;
771 			}
772 
773 			if (ptr[1] == 0) {
774 				break;
775 			}
776 			ptr += ptr[3];
777 		}
778 		isp->isp_loaded_fw = 1;
779 	} else if (dodnld && IS_23XX(isp)) {
780 		const uint16_t *ptr = isp->isp_mdvec->dv_ispfw;
781 		uint16_t wi, wl, segno;
782 		uint32_t la;
783 
784 		la = code_org;
785 		segno = 0;
786 
787 		for (;;) {
788 			uint32_t nxtaddr;
789 
790 			isp_prt(isp, ISP_LOGDEBUG0, "load 0x%x words of code at load address 0x%x", ptr[3], la);
791 
792 			wi = 0;
793 			wl = ptr[3];
794 
795 			while (wi < ptr[3]) {
796 				uint16_t *cp;
797 				uint16_t nw;
798 
799 				nw = min(wl, min((1 << 15), ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) / 2));
800 				cp = isp->isp_rquest;
801 				for (i = 0; i < nw; i++)
802 					ISP_IOXPUT_16(isp, ptr[wi + i], &cp[i]);
803 				MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)), -1);
804 				MBSINIT(&mbs, 0, MBLOGALL, 0);
805 				if (la < 0x10000) {
806 					mbs.param[0] = MBOX_LOAD_RISC_RAM_2100;
807 					mbs.param[1] = la;
808 					mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
809 					mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
810 					mbs.param[4] = nw;
811 					mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
812 					mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
813 					isp_prt(isp, ISP_LOGDEBUG1, "LOAD RISC RAM 2100 %u words at load address 0x%x\n", nw, la);
814 				} else {
815 					mbs.param[0] = MBOX_LOAD_RISC_RAM;
816 					mbs.param[1] = la;
817 					mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
818 					mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
819 					mbs.param[4] = nw;
820 					mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
821 					mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
822 					mbs.param[8] = la >> 16;
823 					isp_prt(isp, ISP_LOGDEBUG1, "LOAD RISC RAM %u words at load address 0x%x\n", nw, la);
824 				}
825 				isp_mboxcmd(isp, &mbs);
826 				if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
827 					isp_prt(isp, ISP_LOGERR, "F/W download failed");
828 					return;
829 				}
830 				la += nw;
831 				wi += nw;
832 				wl -= nw;
833 			}
834 
835 			if (!IS_2322(isp)) {
836 				break;
837 			}
838 
839 			if (++segno == 3) {
840 				break;
841 			}
842 
843 			/*
844 			 * If we're a 2322, the firmware actually comes in
845 			 * three chunks. We loaded the first at the code_org
846 			 * address. The other two chunks, which follow right
847 			 * after each other in memory here, get loaded at
848 			 * addresses specfied at offset 0x9..0xB.
849 			 */
850 
851 			nxtaddr = ptr[3];
852 			ptr = &ptr[nxtaddr];
853 			la = ptr[5] | ((ptr[4] & 0x3f) << 16);
854 		}
855 		isp->isp_loaded_fw = 1;
856 	} else if (dodnld) {
857 		const uint16_t *ptr = isp->isp_mdvec->dv_ispfw;
858 		u_int i, wl;
859 
860 		wl = ptr[3];
861 		isp_prt(isp, ISP_LOGDEBUG1,
862 		    "WRITE RAM %u words at load address 0x%x", wl, code_org);
863 		for (i = 0; i < wl; i++) {
864 			MBSINIT(&mbs, MBOX_WRITE_RAM_WORD, MBLOGNONE, 0);
865 			mbs.param[1] = code_org + i;
866 			mbs.param[2] = ptr[i];
867 			isp_mboxcmd(isp, &mbs);
868 			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
869 				isp_prt(isp, ISP_LOGERR,
870 				    "F/W download failed at word %d", i);
871 				return;
872 			}
873 		}
874 	} else if (IS_26XX(isp)) {
875 		MBSINIT(&mbs, MBOX_LOAD_FLASH_FIRMWARE, MBLOGALL, 5000000);
876 		mbs.ibitm = 0x01;
877 		mbs.obitm = 0x07;
878 		isp_mboxcmd(isp, &mbs);
879 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
880 			isp_prt(isp, ISP_LOGERR, "Flash F/W load failed");
881 			return;
882 		}
883 	} else {
884 		isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
885 	}
886 
887 	/*
888 	 * If we loaded firmware, verify its checksum
889 	 */
890 	if (isp->isp_loaded_fw) {
891 		MBSINIT(&mbs, MBOX_VERIFY_CHECKSUM, MBLOGNONE, 0);
892 		if (IS_24XX(isp)) {
893 			mbs.param[1] = code_org >> 16;
894 			mbs.param[2] = code_org;
895 		} else {
896 			mbs.param[1] = code_org;
897 		}
898 		isp_mboxcmd(isp, &mbs);
899 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
900 			isp_prt(isp, ISP_LOGERR, dcrc);
901 			return;
902 		}
903 	}
904 
905 	/*
906 	 * Now start it rolling.
907 	 *
908 	 * If we didn't actually download f/w,
909 	 * we still need to (re)start it.
910 	 */
911 	MBSINIT(&mbs, MBOX_EXEC_FIRMWARE, MBLOGALL, 5000000);
912 	if (IS_24XX(isp)) {
913 		mbs.param[1] = code_org >> 16;
914 		mbs.param[2] = code_org;
915 		if (isp->isp_loaded_fw) {
916 			mbs.param[3] = 0;
917 		} else {
918 			mbs.param[3] = 1;
919 		}
920 	} else if (IS_2322(isp)) {
921 		mbs.param[1] = code_org;
922 		if (isp->isp_loaded_fw) {
923 			mbs.param[2] = 0;
924 		} else {
925 			mbs.param[2] = 1;
926 		}
927 	} else {
928 		mbs.param[1] = code_org;
929 	}
930 	isp_mboxcmd(isp, &mbs);
931 	if (IS_2322(isp) || IS_24XX(isp)) {
932 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
933 			return;
934 		}
935 	}
936 
937 	if (IS_SCSI(isp)) {
938 		/*
939 		 * Set CLOCK RATE, but only if asked to.
940 		 */
941 		if (isp->isp_clock) {
942 			MBSINIT(&mbs, MBOX_SET_CLOCK_RATE, MBLOGALL, 0);
943 			mbs.param[1] = isp->isp_clock;
944 			isp_mboxcmd(isp, &mbs);
945 			/* we will try not to care if this fails */
946 		}
947 	}
948 
949 	/*
950 	 * Ask the chip for the current firmware version.
951 	 * This should prove that the new firmware is working.
952 	 */
953 	MBSINIT(&mbs, MBOX_ABOUT_FIRMWARE, MBLOGALL, 0);
954 	isp_mboxcmd(isp, &mbs);
955 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
956 		return;
957 	}
958 
959 	/*
960 	 * The SBus firmware that we are using apparently does not return
961 	 * major, minor, micro revisions in the mailbox registers, which
962 	 * is really, really, annoying.
963 	 */
964 	if (ISP_SBUS_SUPPORTED && isp->isp_bustype == ISP_BT_SBUS) {
965 		if (dodnld) {
966 #ifdef	ISP_TARGET_MODE
967 			isp->isp_fwrev[0] = 7;
968 			isp->isp_fwrev[1] = 55;
969 #else
970 			isp->isp_fwrev[0] = 1;
971 			isp->isp_fwrev[1] = 37;
972 #endif
973 			isp->isp_fwrev[2] = 0;
974 		}
975 	} else {
976 		isp->isp_fwrev[0] = mbs.param[1];
977 		isp->isp_fwrev[1] = mbs.param[2];
978 		isp->isp_fwrev[2] = mbs.param[3];
979 	}
980 
981 	if (IS_FC(isp)) {
982 		/*
983 		 * We do not believe firmware attributes for 2100 code less
984 		 * than 1.17.0, unless it's the firmware we specifically
985 		 * are loading.
986 		 *
987 		 * Note that all 22XX and later f/w is greater than 1.X.0.
988 		 */
989 		if ((ISP_FW_OLDER_THAN(isp, 1, 17, 1))) {
990 #ifdef	USE_SMALLER_2100_FIRMWARE
991 			isp->isp_fwattr = ISP_FW_ATTR_SCCLUN;
992 #else
993 			isp->isp_fwattr = 0;
994 #endif
995 		} else {
996 			isp->isp_fwattr = mbs.param[6];
997 		}
998 		if (IS_24XX(isp)) {
999 			isp->isp_fwattr |= ((uint64_t) mbs.param[15]) << 16;
1000 			if (isp->isp_fwattr & ISP2400_FW_ATTR_EXTNDED) {
1001 				isp->isp_fwattr |=
1002 				    (((uint64_t) mbs.param[16]) << 32) |
1003 				    (((uint64_t) mbs.param[17]) << 48);
1004 			}
1005 		}
1006 	} else {
1007 		isp->isp_fwattr = 0;
1008 	}
1009 
1010 	isp_prt(isp, ISP_LOGCONFIG, "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
1011 	    btype, isp->isp_revision, dodnld? "loaded" : "resident", isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
1012 
1013 	fwt = isp->isp_fwattr;
1014 	if (IS_24XX(isp)) {
1015 		buf = FCPARAM(isp, 0)->isp_scanscratch;
1016 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN, "Attributes:");
1017 		if (fwt & ISP2400_FW_ATTR_CLASS2) {
1018 			fwt ^=ISP2400_FW_ATTR_CLASS2;
1019 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s Class2", buf);
1020 		}
1021 		if (fwt & ISP2400_FW_ATTR_IP) {
1022 			fwt ^=ISP2400_FW_ATTR_IP;
1023 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s IP", buf);
1024 		}
1025 		if (fwt & ISP2400_FW_ATTR_MULTIID) {
1026 			fwt ^=ISP2400_FW_ATTR_MULTIID;
1027 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s MultiID", buf);
1028 		}
1029 		if (fwt & ISP2400_FW_ATTR_SB2) {
1030 			fwt ^=ISP2400_FW_ATTR_SB2;
1031 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s SB2", buf);
1032 		}
1033 		if (fwt & ISP2400_FW_ATTR_T10CRC) {
1034 			fwt ^=ISP2400_FW_ATTR_T10CRC;
1035 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s T10CRC", buf);
1036 		}
1037 		if (fwt & ISP2400_FW_ATTR_VI) {
1038 			fwt ^=ISP2400_FW_ATTR_VI;
1039 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s VI", buf);
1040 		}
1041 		if (fwt & ISP2400_FW_ATTR_MQ) {
1042 			fwt ^=ISP2400_FW_ATTR_MQ;
1043 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s MQ", buf);
1044 		}
1045 		if (fwt & ISP2400_FW_ATTR_MSIX) {
1046 			fwt ^=ISP2400_FW_ATTR_MSIX;
1047 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s MSIX", buf);
1048 		}
1049 		if (fwt & ISP2400_FW_ATTR_FCOE) {
1050 			fwt ^=ISP2400_FW_ATTR_FCOE;
1051 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s FCOE", buf);
1052 		}
1053 		if (fwt & ISP2400_FW_ATTR_VP0) {
1054 			fwt ^= ISP2400_FW_ATTR_VP0;
1055 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s VP0_Decoupling", buf);
1056 		}
1057 		if (fwt & ISP2400_FW_ATTR_EXPFW) {
1058 			fwt ^= ISP2400_FW_ATTR_EXPFW;
1059 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s (Experimental)", buf);
1060 		}
1061 		if (fwt & ISP2400_FW_ATTR_HOTFW) {
1062 			fwt ^= ISP2400_FW_ATTR_HOTFW;
1063 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s HotFW", buf);
1064 		}
1065 		fwt &= ~ISP2400_FW_ATTR_EXTNDED;
1066 		if (fwt & ISP2400_FW_ATTR_EXTVP) {
1067 			fwt ^= ISP2400_FW_ATTR_EXTVP;
1068 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s ExtVP", buf);
1069 		}
1070 		if (fwt & ISP2400_FW_ATTR_VN2VN) {
1071 			fwt ^= ISP2400_FW_ATTR_VN2VN;
1072 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s VN2VN", buf);
1073 		}
1074 		if (fwt & ISP2400_FW_ATTR_EXMOFF) {
1075 			fwt ^= ISP2400_FW_ATTR_EXMOFF;
1076 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s EXMOFF", buf);
1077 		}
1078 		if (fwt & ISP2400_FW_ATTR_NPMOFF) {
1079 			fwt ^= ISP2400_FW_ATTR_NPMOFF;
1080 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s NPMOFF", buf);
1081 		}
1082 		if (fwt & ISP2400_FW_ATTR_DIFCHOP) {
1083 			fwt ^= ISP2400_FW_ATTR_DIFCHOP;
1084 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s DIFCHOP", buf);
1085 		}
1086 		if (fwt & ISP2400_FW_ATTR_SRIOV) {
1087 			fwt ^= ISP2400_FW_ATTR_SRIOV;
1088 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s SRIOV", buf);
1089 		}
1090 		if (fwt & ISP2400_FW_ATTR_ASICTMP) {
1091 			fwt ^= ISP2400_FW_ATTR_ASICTMP;
1092 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s ASICTMP", buf);
1093 		}
1094 		if (fwt & ISP2400_FW_ATTR_ATIOMQ) {
1095 			fwt ^= ISP2400_FW_ATTR_ATIOMQ;
1096 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s ATIOMQ", buf);
1097 		}
1098 		if (fwt) {
1099 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s (unknown 0x%08x%08x)", buf,
1100 			    (uint32_t) (fwt >> 32), (uint32_t) fwt);
1101 		}
1102 		isp_prt(isp, ISP_LOGCONFIG, "%s", buf);
1103 	} else if (IS_FC(isp)) {
1104 		buf = FCPARAM(isp, 0)->isp_scanscratch;
1105 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN, "Attributes:");
1106 		if (fwt & ISP_FW_ATTR_TMODE) {
1107 			fwt ^=ISP_FW_ATTR_TMODE;
1108 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s TargetMode", buf);
1109 		}
1110 		if (fwt & ISP_FW_ATTR_SCCLUN) {
1111 			fwt ^=ISP_FW_ATTR_SCCLUN;
1112 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s SCC-Lun", buf);
1113 		}
1114 		if (fwt & ISP_FW_ATTR_FABRIC) {
1115 			fwt ^=ISP_FW_ATTR_FABRIC;
1116 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s Fabric", buf);
1117 		}
1118 		if (fwt & ISP_FW_ATTR_CLASS2) {
1119 			fwt ^=ISP_FW_ATTR_CLASS2;
1120 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s Class2", buf);
1121 		}
1122 		if (fwt & ISP_FW_ATTR_FCTAPE) {
1123 			fwt ^=ISP_FW_ATTR_FCTAPE;
1124 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s FC-Tape", buf);
1125 		}
1126 		if (fwt & ISP_FW_ATTR_IP) {
1127 			fwt ^=ISP_FW_ATTR_IP;
1128 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s IP", buf);
1129 		}
1130 		if (fwt & ISP_FW_ATTR_VI) {
1131 			fwt ^=ISP_FW_ATTR_VI;
1132 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s VI", buf);
1133 		}
1134 		if (fwt & ISP_FW_ATTR_VI_SOLARIS) {
1135 			fwt ^=ISP_FW_ATTR_VI_SOLARIS;
1136 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s VI_SOLARIS", buf);
1137 		}
1138 		if (fwt & ISP_FW_ATTR_2KLOGINS) {
1139 			fwt ^=ISP_FW_ATTR_2KLOGINS;
1140 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s 2K-Login", buf);
1141 		}
1142 		if (fwt != 0) {
1143 			ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s (unknown 0x%08x%08x)", buf,
1144 			    (uint32_t) (fwt >> 32), (uint32_t) fwt);
1145 		}
1146 		isp_prt(isp, ISP_LOGCONFIG, "%s", buf);
1147 	}
1148 
1149 	if (IS_24XX(isp)) {
1150 		MBSINIT(&mbs, MBOX_GET_RESOURCE_COUNT, MBLOGALL, 0);
1151 		isp_mboxcmd(isp, &mbs);
1152 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1153 			return;
1154 		}
1155 		isp->isp_maxcmds = mbs.param[3];
1156 	} else {
1157 		MBSINIT(&mbs, MBOX_GET_FIRMWARE_STATUS, MBLOGALL, 0);
1158 		isp_mboxcmd(isp, &mbs);
1159 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1160 			return;
1161 		}
1162 		isp->isp_maxcmds = mbs.param[2];
1163 	}
1164 	isp_prt(isp, ISP_LOGCONFIG, "%d max I/O command limit set", isp->isp_maxcmds);
1165 
1166 	/*
1167 	 * If we don't have Multi-ID f/w loaded, we need to restrict channels to one.
1168 	 * Only make this check for non-SCSI cards (I'm not sure firmware attributes
1169 	 * work for them).
1170 	 */
1171 	if (IS_FC(isp) && isp->isp_nchan > 1) {
1172 		if (!ISP_CAP_MULTI_ID(isp)) {
1173 			isp_prt(isp, ISP_LOGWARN, "non-MULTIID f/w loaded, "
1174 			    "only can enable 1 of %d channels", isp->isp_nchan);
1175 			isp->isp_nchan = 1;
1176 		} else if (!ISP_CAP_VP0(isp)) {
1177 			isp_prt(isp, ISP_LOGWARN, "We can not use MULTIID "
1178 			    "feature properly without VP0_Decoupling");
1179 			isp->isp_nchan = 1;
1180 		}
1181 	}
1182 
1183 	/*
1184 	 * Final DMA setup after we got isp_maxcmds.
1185 	 */
1186 	if (ISP_MBOXDMASETUP(isp) != 0) {
1187 		isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
1188 		return;
1189 	}
1190 
1191 	/*
1192 	 * Setup interrupts.
1193 	 */
1194 	if (ISP_IRQSETUP(isp) != 0) {
1195 		isp_prt(isp, ISP_LOGERR, "Cannot setup IRQ");
1196 		return;
1197 	}
1198 	ISP_ENABLE_INTS(isp);
1199 
1200 	if (IS_FC(isp)) {
1201 		for (i = 0; i < isp->isp_nchan; i++)
1202 			isp_change_fw_state(isp, i, FW_CONFIG_WAIT);
1203 	}
1204 
1205 	isp->isp_state = ISP_RESETSTATE;
1206 
1207 	/*
1208 	 * Okay- now that we have new firmware running, we now (re)set our
1209 	 * notion of how many luns we support. This is somewhat tricky because
1210 	 * if we haven't loaded firmware, we sometimes do not have an easy way
1211 	 * of knowing how many luns we support.
1212 	 *
1213 	 * Expanded lun firmware gives you 32 luns for SCSI cards and
1214 	 * unlimited luns for Fibre Channel cards.
1215 	 *
1216 	 * It turns out that even for QLogic 2100s with ROM 1.10 and above
1217 	 * we do get a firmware attributes word returned in mailbox register 6.
1218 	 *
1219 	 * Because the lun is in a different position in the Request Queue
1220 	 * Entry structure for Fibre Channel with expanded lun firmware, we
1221 	 * can only support one lun (lun zero) when we don't know what kind
1222 	 * of firmware we're running.
1223 	 */
1224 	if (IS_SCSI(isp)) {
1225 		if (dodnld) {
1226 			if (IS_ULTRA2(isp) || IS_ULTRA3(isp)) {
1227 				isp->isp_maxluns = 32;
1228 			} else {
1229 				isp->isp_maxluns = 8;
1230 			}
1231 		} else {
1232 			isp->isp_maxluns = 8;
1233 		}
1234 	} else {
1235 		if (ISP_CAP_SCCFW(isp)) {
1236 			isp->isp_maxluns = 0;	/* No limit -- 2/8 bytes */
1237 		} else {
1238 			isp->isp_maxluns = 16;
1239 		}
1240 	}
1241 
1242 	/*
1243 	 * We get some default values established. As a side
1244 	 * effect, NVRAM is read here (unless overriden by
1245 	 * a configuration flag).
1246 	 */
1247 	if (do_load_defaults) {
1248 		if (IS_SCSI(isp)) {
1249 			isp_setdfltsdparm(isp);
1250 		} else {
1251 			for (i = 0; i < isp->isp_nchan; i++) {
1252 				isp_setdfltfcparm(isp, i);
1253 			}
1254 		}
1255 	}
1256 }
1257 
1258 /*
1259  * Clean firmware shutdown.
1260  */
1261 static int
isp_stop(ispsoftc_t * isp)1262 isp_stop(ispsoftc_t *isp)
1263 {
1264 	mbreg_t mbs;
1265 
1266 	isp->isp_state = ISP_NILSTATE;
1267 	MBSINIT(&mbs, MBOX_STOP_FIRMWARE, MBLOGALL, 500000);
1268 	mbs.param[1] = 0;
1269 	mbs.param[2] = 0;
1270 	mbs.param[3] = 0;
1271 	mbs.param[4] = 0;
1272 	mbs.param[5] = 0;
1273 	mbs.param[6] = 0;
1274 	mbs.param[7] = 0;
1275 	mbs.param[8] = 0;
1276 	isp_mboxcmd(isp, &mbs);
1277 	return (mbs.param[0] == MBOX_COMMAND_COMPLETE ? 0 : mbs.param[0]);
1278 }
1279 
1280 /*
1281  * Hardware shutdown.
1282  */
1283 void
isp_shutdown(ispsoftc_t * isp)1284 isp_shutdown(ispsoftc_t *isp)
1285 {
1286 
1287 	if (isp->isp_state >= ISP_RESETSTATE)
1288 		isp_stop(isp);
1289 	ISP_DISABLE_INTS(isp);
1290 	if (IS_FC(isp)) {
1291 		if (IS_24XX(isp)) {
1292 			ISP_WRITE(isp, BIU2400_ICR, 0);
1293 			ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
1294 		} else {
1295 			ISP_WRITE(isp, BIU_ICR, 0);
1296 			ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
1297 			ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
1298 			ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
1299 			ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
1300 			ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
1301 			ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
1302 		}
1303 	} else {
1304 		ISP_WRITE(isp, BIU_ICR, 0);
1305 		ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
1306 	}
1307 }
1308 
1309 /*
1310  * Initialize Parameters of Hardware to a known state.
1311  *
1312  * Locks are held before coming here.
1313  */
1314 void
isp_init(ispsoftc_t * isp)1315 isp_init(ispsoftc_t *isp)
1316 {
1317 	if (IS_FC(isp)) {
1318 		if (IS_24XX(isp)) {
1319 			isp_fibre_init_2400(isp);
1320 		} else {
1321 			isp_fibre_init(isp);
1322 		}
1323 	} else {
1324 		isp_scsi_init(isp);
1325 	}
1326 }
1327 
1328 static void
isp_scsi_init(ispsoftc_t * isp)1329 isp_scsi_init(ispsoftc_t *isp)
1330 {
1331 	sdparam *sdp_chan0, *sdp_chan1;
1332 	mbreg_t mbs;
1333 
1334 	isp->isp_state = ISP_INITSTATE;
1335 
1336 	sdp_chan0 = SDPARAM(isp, 0);
1337 	sdp_chan1 = sdp_chan0;
1338 	if (IS_DUALBUS(isp)) {
1339 		sdp_chan1 = SDPARAM(isp, 1);
1340 	}
1341 
1342 	/* First do overall per-card settings. */
1343 
1344 	/*
1345 	 * If we have fast memory timing enabled, turn it on.
1346 	 */
1347 	if (sdp_chan0->isp_fast_mttr) {
1348 		ISP_WRITE(isp, RISC_MTR, 0x1313);
1349 	}
1350 
1351 	/*
1352 	 * Set Retry Delay and Count.
1353 	 * You set both channels at the same time.
1354 	 */
1355 	MBSINIT(&mbs, MBOX_SET_RETRY_COUNT, MBLOGALL, 0);
1356 	mbs.param[1] = sdp_chan0->isp_retry_count;
1357 	mbs.param[2] = sdp_chan0->isp_retry_delay;
1358 	mbs.param[6] = sdp_chan1->isp_retry_count;
1359 	mbs.param[7] = sdp_chan1->isp_retry_delay;
1360 	isp_mboxcmd(isp, &mbs);
1361 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1362 		return;
1363 	}
1364 
1365 	/*
1366 	 * Set ASYNC DATA SETUP time. This is very important.
1367 	 */
1368 	MBSINIT(&mbs, MBOX_SET_ASYNC_DATA_SETUP_TIME, MBLOGALL, 0);
1369 	mbs.param[1] = sdp_chan0->isp_async_data_setup;
1370 	mbs.param[2] = sdp_chan1->isp_async_data_setup;
1371 	isp_mboxcmd(isp, &mbs);
1372 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1373 		return;
1374 	}
1375 
1376 	/*
1377 	 * Set ACTIVE Negation State.
1378 	 */
1379 	MBSINIT(&mbs, MBOX_SET_ACT_NEG_STATE, MBLOGNONE, 0);
1380 	mbs.param[1] =
1381 	    (sdp_chan0->isp_req_ack_active_neg << 4) |
1382 	    (sdp_chan0->isp_data_line_active_neg << 5);
1383 	mbs.param[2] =
1384 	    (sdp_chan1->isp_req_ack_active_neg << 4) |
1385 	    (sdp_chan1->isp_data_line_active_neg << 5);
1386 	isp_mboxcmd(isp, &mbs);
1387 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1388 		isp_prt(isp, ISP_LOGERR,
1389 		    "failed to set active negation state (%d,%d), (%d,%d)",
1390 		    sdp_chan0->isp_req_ack_active_neg,
1391 		    sdp_chan0->isp_data_line_active_neg,
1392 		    sdp_chan1->isp_req_ack_active_neg,
1393 		    sdp_chan1->isp_data_line_active_neg);
1394 		/*
1395 		 * But don't return.
1396 		 */
1397 	}
1398 
1399 	/*
1400 	 * Set the Tag Aging limit
1401 	 */
1402 	MBSINIT(&mbs, MBOX_SET_TAG_AGE_LIMIT, MBLOGALL, 0);
1403 	mbs.param[1] = sdp_chan0->isp_tag_aging;
1404 	mbs.param[2] = sdp_chan1->isp_tag_aging;
1405 	isp_mboxcmd(isp, &mbs);
1406 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1407 		isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)",
1408 		    sdp_chan0->isp_tag_aging, sdp_chan1->isp_tag_aging);
1409 		return;
1410 	}
1411 
1412 	/*
1413 	 * Set selection timeout.
1414 	 */
1415 	MBSINIT(&mbs, MBOX_SET_SELECT_TIMEOUT, MBLOGALL, 0);
1416 	mbs.param[1] = sdp_chan0->isp_selection_timeout;
1417 	mbs.param[2] = sdp_chan1->isp_selection_timeout;
1418 	isp_mboxcmd(isp, &mbs);
1419 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1420 		return;
1421 	}
1422 
1423 	/* now do per-channel settings */
1424 	isp_scsi_channel_init(isp, 0);
1425 	if (IS_DUALBUS(isp))
1426 		isp_scsi_channel_init(isp, 1);
1427 
1428 	/*
1429 	 * Now enable request/response queues
1430 	 */
1431 
1432 	if (IS_ULTRA2(isp) || IS_1240(isp)) {
1433 		MBSINIT(&mbs, MBOX_INIT_RES_QUEUE_A64, MBLOGALL, 0);
1434 		mbs.param[1] = RESULT_QUEUE_LEN(isp);
1435 		mbs.param[2] = DMA_WD1(isp->isp_result_dma);
1436 		mbs.param[3] = DMA_WD0(isp->isp_result_dma);
1437 		mbs.param[4] = 0;
1438 		mbs.param[6] = DMA_WD3(isp->isp_result_dma);
1439 		mbs.param[7] = DMA_WD2(isp->isp_result_dma);
1440 		isp_mboxcmd(isp, &mbs);
1441 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1442 			return;
1443 		}
1444 		isp->isp_residx = isp->isp_resodx = mbs.param[5];
1445 
1446 		MBSINIT(&mbs, MBOX_INIT_REQ_QUEUE_A64, MBLOGALL, 0);
1447 		mbs.param[1] = RQUEST_QUEUE_LEN(isp);
1448 		mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
1449 		mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
1450 		mbs.param[5] = 0;
1451 		mbs.param[6] = DMA_WD3(isp->isp_result_dma);
1452 		mbs.param[7] = DMA_WD2(isp->isp_result_dma);
1453 		isp_mboxcmd(isp, &mbs);
1454 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1455 			return;
1456 		}
1457 		isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
1458 	} else {
1459 		MBSINIT(&mbs, MBOX_INIT_RES_QUEUE, MBLOGALL, 0);
1460 		mbs.param[1] = RESULT_QUEUE_LEN(isp);
1461 		mbs.param[2] = DMA_WD1(isp->isp_result_dma);
1462 		mbs.param[3] = DMA_WD0(isp->isp_result_dma);
1463 		mbs.param[4] = 0;
1464 		isp_mboxcmd(isp, &mbs);
1465 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1466 			return;
1467 		}
1468 		isp->isp_residx = isp->isp_resodx = mbs.param[5];
1469 
1470 		MBSINIT(&mbs, MBOX_INIT_REQ_QUEUE, MBLOGALL, 0);
1471 		mbs.param[1] = RQUEST_QUEUE_LEN(isp);
1472 		mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
1473 		mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
1474 		mbs.param[5] = 0;
1475 		isp_mboxcmd(isp, &mbs);
1476 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1477 			return;
1478 		}
1479 		isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
1480 	}
1481 
1482 	/*
1483 	 * Turn on LVD transitions for ULTRA2 or better and other features
1484 	 *
1485 	 * Now that we have 32 bit handles, don't do any fast posting
1486 	 * any more. For Ultra2/Ultra3 cards, we can turn on 32 bit RIO
1487 	 * operation or use fast posting. To be conservative, we'll only
1488 	 * do this for Ultra3 cards now because the other cards are so
1489 	 * rare for this author to find and test with.
1490 	 */
1491 
1492 	MBSINIT(&mbs, MBOX_SET_FW_FEATURES, MBLOGALL, 0);
1493 	if (IS_ULTRA2(isp))
1494 		mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
1495 #ifdef	ISP_NO_RIO
1496 	if (IS_ULTRA3(isp))
1497 		mbs.param[1] |= FW_FEATURE_FAST_POST;
1498 #else
1499 	if (IS_ULTRA3(isp))
1500 		mbs.param[1] |= FW_FEATURE_RIO_32BIT;
1501 #endif
1502 	if (mbs.param[1] != 0) {
1503 		uint16_t sfeat = mbs.param[1];
1504 		isp_mboxcmd(isp, &mbs);
1505 		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1506 			isp_prt(isp, ISP_LOGINFO,
1507 			    "Enabled FW features (0x%x)", sfeat);
1508 		}
1509 	}
1510 
1511 	isp->isp_state = ISP_RUNSTATE;
1512 }
1513 
1514 static void
isp_scsi_channel_init(ispsoftc_t * isp,int chan)1515 isp_scsi_channel_init(ispsoftc_t *isp, int chan)
1516 {
1517 	sdparam *sdp;
1518 	mbreg_t mbs;
1519 	int tgt;
1520 
1521 	sdp = SDPARAM(isp, chan);
1522 
1523 	/*
1524 	 * Set (possibly new) Initiator ID.
1525 	 */
1526 	MBSINIT(&mbs, MBOX_SET_INIT_SCSI_ID, MBLOGALL, 0);
1527 	mbs.param[1] = (chan << 7) | sdp->isp_initiator_id;
1528 	isp_mboxcmd(isp, &mbs);
1529 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1530 		return;
1531 	}
1532 	isp_prt(isp, ISP_LOGINFO, "Chan %d Initiator ID is %d",
1533 	    chan, sdp->isp_initiator_id);
1534 
1535 
1536 	/*
1537 	 * Set current per-target parameters to an initial safe minimum.
1538 	 */
1539 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
1540 		int lun;
1541 		uint16_t sdf;
1542 
1543 		if (sdp->isp_devparam[tgt].dev_enable == 0) {
1544 			continue;
1545 		}
1546 #ifndef	ISP_TARGET_MODE
1547 		sdf = sdp->isp_devparam[tgt].goal_flags;
1548 		sdf &= DPARM_SAFE_DFLT;
1549 		/*
1550 		 * It is not quite clear when this changed over so that
1551 		 * we could force narrow and async for 1000/1020 cards,
1552 		 * but assume that this is only the case for loaded
1553 		 * firmware.
1554 		 */
1555 		if (isp->isp_loaded_fw) {
1556 			sdf |= DPARM_NARROW | DPARM_ASYNC;
1557 		}
1558 #else
1559 		/*
1560 		 * The !$*!)$!$)* f/w uses the same index into some
1561 		 * internal table to decide how to respond to negotiations,
1562 		 * so if we've said "let's be safe" for ID X, and ID X
1563 		 * selects *us*, the negotiations will back to 'safe'
1564 		 * (as in narrow/async). What the f/w *should* do is
1565 		 * use the initiator id settings to decide how to respond.
1566 		 */
1567 		sdp->isp_devparam[tgt].goal_flags = sdf = DPARM_DEFAULT;
1568 #endif
1569 		MBSINIT(&mbs, MBOX_SET_TARGET_PARAMS, MBLOGNONE, 0);
1570 		mbs.param[1] = (chan << 15) | (tgt << 8);
1571 		mbs.param[2] = sdf;
1572 		if ((sdf & DPARM_SYNC) == 0) {
1573 			mbs.param[3] = 0;
1574 		} else {
1575 			mbs.param[3] =
1576 			    (sdp->isp_devparam[tgt].goal_offset << 8) |
1577 			    (sdp->isp_devparam[tgt].goal_period);
1578 		}
1579 		isp_prt(isp, ISP_LOGDEBUG0, "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x",
1580 		    chan, tgt, mbs.param[2], mbs.param[3] >> 8, mbs.param[3] & 0xff);
1581 		isp_mboxcmd(isp, &mbs);
1582 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1583 			sdf = DPARM_SAFE_DFLT;
1584 			MBSINIT(&mbs, MBOX_SET_TARGET_PARAMS, MBLOGALL, 0);
1585 			mbs.param[1] = (tgt << 8) | (chan << 15);
1586 			mbs.param[2] = sdf;
1587 			mbs.param[3] = 0;
1588 			isp_mboxcmd(isp, &mbs);
1589 			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1590 				continue;
1591 			}
1592 		}
1593 
1594 		/*
1595 		 * We don't update any information directly from the f/w
1596 		 * because we need to run at least one command to cause a
1597 		 * new state to be latched up. So, we just assume that we
1598 		 * converge to the values we just had set.
1599 		 *
1600 		 * Ensure that we don't believe tagged queuing is enabled yet.
1601 		 * It turns out that sometimes the ISP just ignores our
1602 		 * attempts to set parameters for devices that it hasn't
1603 		 * seen yet.
1604 		 */
1605 		sdp->isp_devparam[tgt].actv_flags = sdf & ~DPARM_TQING;
1606 		for (lun = 0; lun < (int) isp->isp_maxluns; lun++) {
1607 			MBSINIT(&mbs, MBOX_SET_DEV_QUEUE_PARAMS, MBLOGALL, 0);
1608 			mbs.param[1] = (chan << 15) | (tgt << 8) | lun;
1609 			mbs.param[2] = sdp->isp_max_queue_depth;
1610 			mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle;
1611 			isp_mboxcmd(isp, &mbs);
1612 			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1613 				break;
1614 			}
1615 		}
1616 	}
1617 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
1618 		if (sdp->isp_devparam[tgt].dev_refresh) {
1619 			sdp->sendmarker = 1;
1620 			sdp->update = 1;
1621 			break;
1622 		}
1623 	}
1624 }
1625 
1626 /*
1627  * Fibre Channel specific initialization.
1628  */
1629 static void
isp_fibre_init(ispsoftc_t * isp)1630 isp_fibre_init(ispsoftc_t *isp)
1631 {
1632 	fcparam *fcp;
1633 	isp_icb_t local, *icbp = &local;
1634 	mbreg_t mbs;
1635 	int ownloopid;
1636 
1637 	/*
1638 	 * We only support one channel on non-24XX cards
1639 	 */
1640 	fcp = FCPARAM(isp, 0);
1641 	if (fcp->role == ISP_ROLE_NONE)
1642 		return;
1643 
1644 	isp->isp_state = ISP_INITSTATE;
1645 	ISP_MEMZERO(icbp, sizeof (*icbp));
1646 	icbp->icb_version = ICB_VERSION1;
1647 	icbp->icb_fwoptions = fcp->isp_fwoptions;
1648 
1649 	/*
1650 	 * Firmware Options are either retrieved from NVRAM or
1651 	 * are patched elsewhere. We check them for sanity here
1652 	 * and make changes based on board revision, but otherwise
1653 	 * let others decide policy.
1654 	 */
1655 
1656 	/*
1657 	 * If this is a 2100 < revision 5, we have to turn off FAIRNESS.
1658 	 */
1659 	if (IS_2100(isp) && isp->isp_revision < 5) {
1660 		icbp->icb_fwoptions &= ~ICBOPT_FAIRNESS;
1661 	}
1662 
1663 	/*
1664 	 * We have to use FULL LOGIN even though it resets the loop too much
1665 	 * because otherwise port database entries don't get updated after
1666 	 * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0.
1667 	 */
1668 	if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
1669 		icbp->icb_fwoptions |= ICBOPT_FULL_LOGIN;
1670 	}
1671 
1672 	/*
1673 	 * Insist on Port Database Update Async notifications
1674 	 */
1675 	icbp->icb_fwoptions |= ICBOPT_PDBCHANGE_AE;
1676 
1677 	/*
1678 	 * Make sure that target role reflects into fwoptions.
1679 	 */
1680 	if (fcp->role & ISP_ROLE_TARGET) {
1681 		icbp->icb_fwoptions |= ICBOPT_TGT_ENABLE;
1682 	} else {
1683 		icbp->icb_fwoptions &= ~ICBOPT_TGT_ENABLE;
1684 	}
1685 
1686 	/*
1687 	 * For some reason my 2200 does not generate ATIOs in target mode
1688 	 * if initiator is disabled.  Extra logins are better then target
1689 	 * not working at all.
1690 	 */
1691 	if ((fcp->role & ISP_ROLE_INITIATOR) || IS_2100(isp) || IS_2200(isp)) {
1692 		icbp->icb_fwoptions &= ~ICBOPT_INI_DISABLE;
1693 	} else {
1694 		icbp->icb_fwoptions |= ICBOPT_INI_DISABLE;
1695 	}
1696 
1697 	icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
1698 	if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
1699 		isp_prt(isp, ISP_LOGERR, "bad frame length (%d) from NVRAM- using %d", DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
1700 		icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
1701 	}
1702 	icbp->icb_maxalloc = fcp->isp_maxalloc;
1703 	if (icbp->icb_maxalloc < 1) {
1704 		isp_prt(isp, ISP_LOGERR, "bad maximum allocation (%d)- using 16", fcp->isp_maxalloc);
1705 		icbp->icb_maxalloc = 16;
1706 	}
1707 	icbp->icb_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
1708 	if (icbp->icb_execthrottle < 1) {
1709 		isp_prt(isp, ISP_LOGERR, "bad execution throttle of %d- using %d", DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE);
1710 		icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
1711 	}
1712 	icbp->icb_retry_delay = fcp->isp_retry_delay;
1713 	icbp->icb_retry_count = fcp->isp_retry_count;
1714 	icbp->icb_hardaddr = fcp->isp_loopid;
1715 	ownloopid = (isp->isp_confopts & ISP_CFG_OWNLOOPID) != 0;
1716 	if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) {
1717 		icbp->icb_hardaddr = 0;
1718 		ownloopid = 0;
1719 	}
1720 
1721 	/*
1722 	 * Our life seems so much better with 2200s and later with
1723 	 * the latest f/w if we set Hard Address.
1724 	 */
1725 	if (ownloopid || ISP_FW_NEWER_THAN(isp, 2, 2, 5)) {
1726 		icbp->icb_fwoptions |= ICBOPT_HARD_ADDRESS;
1727 	}
1728 
1729 	/*
1730 	 * Right now we just set extended options to prefer point-to-point
1731 	 * over loop based upon some soft config options.
1732 	 *
1733 	 * NB: for the 2300, ICBOPT_EXTENDED is required.
1734 	 */
1735 	if (IS_2100(isp)) {
1736 		/*
1737 		 * We can't have Fast Posting any more- we now
1738 		 * have 32 bit handles.
1739 		 */
1740 		icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
1741 	} else if (IS_2200(isp) || IS_23XX(isp)) {
1742 		icbp->icb_fwoptions |= ICBOPT_EXTENDED;
1743 
1744 		icbp->icb_xfwoptions = fcp->isp_xfwoptions;
1745 
1746 		if (ISP_CAP_FCTAPE(isp)) {
1747 			if (isp->isp_confopts & ISP_CFG_NOFCTAPE)
1748 				icbp->icb_xfwoptions &= ~ICBXOPT_FCTAPE;
1749 
1750 			if (isp->isp_confopts & ISP_CFG_FCTAPE)
1751 				icbp->icb_xfwoptions |= ICBXOPT_FCTAPE;
1752 
1753 			if (icbp->icb_xfwoptions & ICBXOPT_FCTAPE) {
1754 				icbp->icb_fwoptions &= ~ICBOPT_FULL_LOGIN;	/* per documents */
1755 				icbp->icb_xfwoptions |= ICBXOPT_FCTAPE_CCQ|ICBXOPT_FCTAPE_CONFIRM;
1756 				FCPARAM(isp, 0)->fctape_enabled = 1;
1757 			} else {
1758 				FCPARAM(isp, 0)->fctape_enabled = 0;
1759 			}
1760 		} else {
1761 			icbp->icb_xfwoptions &= ~ICBXOPT_FCTAPE;
1762 			FCPARAM(isp, 0)->fctape_enabled = 0;
1763 		}
1764 
1765 		/*
1766 		 * Prefer or force Point-To-Point instead Loop?
1767 		 */
1768 		switch (isp->isp_confopts & ISP_CFG_PORT_PREF) {
1769 		case ISP_CFG_LPORT_ONLY:
1770 			icbp->icb_xfwoptions &= ~ICBXOPT_TOPO_MASK;
1771 			icbp->icb_xfwoptions |= ICBXOPT_LOOP_ONLY;
1772 			break;
1773 		case ISP_CFG_NPORT_ONLY:
1774 			icbp->icb_xfwoptions &= ~ICBXOPT_TOPO_MASK;
1775 			icbp->icb_xfwoptions |= ICBXOPT_PTP_ONLY;
1776 			break;
1777 		case ISP_CFG_LPORT:
1778 			icbp->icb_xfwoptions &= ~ICBXOPT_TOPO_MASK;
1779 			icbp->icb_xfwoptions |= ICBXOPT_LOOP_2_PTP;
1780 			break;
1781 		case ISP_CFG_NPORT:
1782 			icbp->icb_xfwoptions &= ~ICBXOPT_TOPO_MASK;
1783 			icbp->icb_xfwoptions |= ICBXOPT_PTP_2_LOOP;
1784 			break;
1785 		default:
1786 			/* Let NVRAM settings define it if they are sane */
1787 			switch (icbp->icb_xfwoptions & ICBXOPT_TOPO_MASK) {
1788 			case ICBXOPT_PTP_2_LOOP:
1789 			case ICBXOPT_PTP_ONLY:
1790 			case ICBXOPT_LOOP_ONLY:
1791 			case ICBXOPT_LOOP_2_PTP:
1792 				break;
1793 			default:
1794 				icbp->icb_xfwoptions &= ~ICBXOPT_TOPO_MASK;
1795 				icbp->icb_xfwoptions |= ICBXOPT_LOOP_2_PTP;
1796 			}
1797 			break;
1798 		}
1799 		if (IS_2200(isp)) {
1800 			/*
1801 			 * We can't have Fast Posting any more- we now
1802 			 * have 32 bit handles.
1803 			 *
1804 			 * RIO seemed to have to much breakage.
1805 			 *
1806 			 * Just opt for safety.
1807 			 */
1808 			icbp->icb_xfwoptions &= ~ICBXOPT_RIO_16BIT;
1809 			icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
1810 		} else {
1811 			/*
1812 			 * QLogic recommends that FAST Posting be turned
1813 			 * off for 23XX cards and instead allow the HBA
1814 			 * to write response queue entries and interrupt
1815 			 * after a delay (ZIO).
1816 			 */
1817 			icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
1818 			if ((fcp->isp_xfwoptions & ICBXOPT_TIMER_MASK) == ICBXOPT_ZIO) {
1819 				icbp->icb_xfwoptions |= ICBXOPT_ZIO;
1820 				icbp->icb_idelaytimer = 10;
1821 			}
1822 			icbp->icb_zfwoptions = fcp->isp_zfwoptions;
1823 			if (isp->isp_confopts & ISP_CFG_1GB) {
1824 				icbp->icb_zfwoptions &= ~ICBZOPT_RATE_MASK;
1825 				icbp->icb_zfwoptions |= ICBZOPT_RATE_1GB;
1826 			} else if (isp->isp_confopts & ISP_CFG_2GB) {
1827 				icbp->icb_zfwoptions &= ~ICBZOPT_RATE_MASK;
1828 				icbp->icb_zfwoptions |= ICBZOPT_RATE_2GB;
1829 			} else {
1830 				switch (icbp->icb_zfwoptions & ICBZOPT_RATE_MASK) {
1831 				case ICBZOPT_RATE_1GB:
1832 				case ICBZOPT_RATE_2GB:
1833 				case ICBZOPT_RATE_AUTO:
1834 					break;
1835 				default:
1836 					icbp->icb_zfwoptions &= ~ICBZOPT_RATE_MASK;
1837 					icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO;
1838 					break;
1839 				}
1840 			}
1841 		}
1842 	}
1843 
1844 
1845 	/*
1846 	 * For 22XX > 2.1.26 && 23XX, set some options.
1847 	 */
1848 	if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) {
1849 		MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0);
1850 		mbs.param[1] = IFCOPT1_DISF7SWTCH|IFCOPT1_LIPASYNC|IFCOPT1_LIPF8;
1851 		mbs.param[2] = 0;
1852 		mbs.param[3] = 0;
1853 		if (ISP_FW_NEWER_THAN(isp, 3, 16, 0)) {
1854 			mbs.param[1] |= IFCOPT1_EQFQASYNC|IFCOPT1_CTIO_RETRY;
1855 			if (fcp->role & ISP_ROLE_TARGET) {
1856 				if (ISP_FW_NEWER_THAN(isp, 3, 25, 0)) {
1857 					mbs.param[1] |= IFCOPT1_ENAPURE;
1858 				}
1859 				mbs.param[3] = IFCOPT3_NOPRLI;
1860 			}
1861 		}
1862 		isp_mboxcmd(isp, &mbs);
1863 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1864 			return;
1865 		}
1866 	}
1867 	icbp->icb_logintime = ICB_LOGIN_TOV;
1868 
1869 #ifdef	ISP_TARGET_MODE
1870 	if (icbp->icb_fwoptions & ICBOPT_TGT_ENABLE) {
1871 		icbp->icb_lunenables = 0xffff;
1872 		icbp->icb_ccnt = 0xff;
1873 		icbp->icb_icnt = 0xff;
1874 		icbp->icb_lunetimeout = ICB_LUN_ENABLE_TOV;
1875 	}
1876 #endif
1877 	if (fcp->isp_wwnn && fcp->isp_wwpn) {
1878 		icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS;
1879 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
1880 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1881 		isp_prt(isp, ISP_LOGDEBUG1,
1882 		    "Setting ICB Node 0x%08x%08x Port 0x%08x%08x",
1883 		    ((uint32_t) (fcp->isp_wwnn >> 32)),
1884 		    ((uint32_t) (fcp->isp_wwnn)),
1885 		    ((uint32_t) (fcp->isp_wwpn >> 32)),
1886 		    ((uint32_t) (fcp->isp_wwpn)));
1887 	} else if (fcp->isp_wwpn) {
1888 		icbp->icb_fwoptions &= ~ICBOPT_BOTH_WWNS;
1889 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1890 		isp_prt(isp, ISP_LOGDEBUG1,
1891 		    "Setting ICB Port 0x%08x%08x",
1892 		    ((uint32_t) (fcp->isp_wwpn >> 32)),
1893 		    ((uint32_t) (fcp->isp_wwpn)));
1894 	} else {
1895 		isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
1896 		return;
1897 	}
1898 	icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
1899 	if (icbp->icb_rqstqlen < 1) {
1900 		isp_prt(isp, ISP_LOGERR, "bad request queue length");
1901 	}
1902 	icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
1903 	if (icbp->icb_rsltqlen < 1) {
1904 		isp_prt(isp, ISP_LOGERR, "bad result queue length");
1905 	}
1906 	icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
1907 	icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
1908 	icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
1909 	icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
1910 	icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
1911 	icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
1912 	icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
1913 	icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
1914 
1915 	if (FC_SCRATCH_ACQUIRE(isp, 0)) {
1916 		isp_prt(isp, ISP_LOGERR, sacq);
1917 		return;
1918 	}
1919 	isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x",
1920 	    icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions);
1921 
1922 	isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch);
1923 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
1924 		isp_print_bytes(isp, "isp_fibre_init",
1925 		    sizeof(*icbp), fcp->isp_scratch);
1926 	}
1927 
1928 	/*
1929 	 * Init the firmware
1930 	 */
1931 	MBSINIT(&mbs, MBOX_INIT_FIRMWARE, MBLOGALL, 30000000);
1932 	mbs.param[1] = 0;
1933 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1934 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1935 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
1936 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
1937 	isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %p (%08x%08x)",
1938 	    fcp->isp_scratch, (uint32_t) ((uint64_t)fcp->isp_scdma >> 32),
1939 	    (uint32_t) fcp->isp_scdma);
1940 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp), 0);
1941 	isp_mboxcmd(isp, &mbs);
1942 	FC_SCRATCH_RELEASE(isp, 0);
1943 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE)
1944 		return;
1945 	isp->isp_reqidx = 0;
1946 	isp->isp_reqodx = 0;
1947 	isp->isp_residx = 0;
1948 	isp->isp_resodx = 0;
1949 
1950 	/*
1951 	 * Whatever happens, we're now committed to being here.
1952 	 */
1953 	isp->isp_state = ISP_RUNSTATE;
1954 }
1955 
1956 static void
isp_fibre_init_2400(ispsoftc_t * isp)1957 isp_fibre_init_2400(ispsoftc_t *isp)
1958 {
1959 	fcparam *fcp;
1960 	isp_icb_2400_t local, *icbp = &local;
1961 	mbreg_t mbs;
1962 	int chan;
1963 	int ownloopid = 0;
1964 
1965 	/*
1966 	 * Check to see whether all channels have *some* kind of role
1967 	 */
1968 	for (chan = 0; chan < isp->isp_nchan; chan++) {
1969 		fcp = FCPARAM(isp, chan);
1970 		if (fcp->role != ISP_ROLE_NONE) {
1971 			break;
1972 		}
1973 	}
1974 	if (chan == isp->isp_nchan) {
1975 		isp_prt(isp, ISP_LOG_WARN1, "all %d channels with role 'none'", chan);
1976 		return;
1977 	}
1978 
1979 	isp->isp_state = ISP_INITSTATE;
1980 
1981 	/*
1982 	 * Start with channel 0.
1983 	 */
1984 	fcp = FCPARAM(isp, 0);
1985 
1986 	/*
1987 	 * Turn on LIP F8 async event (1)
1988 	 */
1989 	MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0);
1990 	mbs.param[1] = 1;
1991 	isp_mboxcmd(isp, &mbs);
1992 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1993 		return;
1994 	}
1995 
1996 	ISP_MEMZERO(icbp, sizeof (*icbp));
1997 	icbp->icb_fwoptions1 = fcp->isp_fwoptions;
1998 	icbp->icb_fwoptions2 = fcp->isp_xfwoptions;
1999 	icbp->icb_fwoptions3 = fcp->isp_zfwoptions;
2000 	if (isp->isp_nchan > 1 && ISP_CAP_VP0(isp)) {
2001 		icbp->icb_fwoptions1 &= ~ICB2400_OPT1_INI_DISABLE;
2002 		icbp->icb_fwoptions1 |= ICB2400_OPT1_TGT_ENABLE;
2003 	} else {
2004 		if (fcp->role & ISP_ROLE_TARGET)
2005 			icbp->icb_fwoptions1 |= ICB2400_OPT1_TGT_ENABLE;
2006 		else
2007 			icbp->icb_fwoptions1 &= ~ICB2400_OPT1_TGT_ENABLE;
2008 		if (fcp->role & ISP_ROLE_INITIATOR)
2009 			icbp->icb_fwoptions1 &= ~ICB2400_OPT1_INI_DISABLE;
2010 		else
2011 			icbp->icb_fwoptions1 |= ICB2400_OPT1_INI_DISABLE;
2012 	}
2013 
2014 	icbp->icb_version = ICB_VERSION1;
2015 	icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
2016 	if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
2017 		isp_prt(isp, ISP_LOGERR, "bad frame length (%d) from NVRAM- using %d", DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
2018 		icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
2019 	}
2020 
2021 	icbp->icb_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
2022 	if (icbp->icb_execthrottle < 1) {
2023 		isp_prt(isp, ISP_LOGERR, "bad execution throttle of %d- using %d", DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE);
2024 		icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
2025 	}
2026 
2027 	/*
2028 	 * Set target exchange count. Take half if we are supporting both roles.
2029 	 */
2030 	if (icbp->icb_fwoptions1 & ICB2400_OPT1_TGT_ENABLE) {
2031 		icbp->icb_xchgcnt = isp->isp_maxcmds;
2032 		if ((icbp->icb_fwoptions1 & ICB2400_OPT1_INI_DISABLE) == 0)
2033 			icbp->icb_xchgcnt >>= 1;
2034 	}
2035 
2036 
2037 	ownloopid = (isp->isp_confopts & ISP_CFG_OWNLOOPID) != 0;
2038 	icbp->icb_hardaddr = fcp->isp_loopid;
2039 	if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) {
2040 		icbp->icb_hardaddr = 0;
2041 		ownloopid = 0;
2042 	}
2043 
2044 	if (ownloopid)
2045 		icbp->icb_fwoptions1 |= ICB2400_OPT1_HARD_ADDRESS;
2046 
2047 	if (isp->isp_confopts & ISP_CFG_NOFCTAPE) {
2048 		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_FCTAPE;
2049 	}
2050 	if (isp->isp_confopts & ISP_CFG_FCTAPE) {
2051 		icbp->icb_fwoptions2 |= ICB2400_OPT2_FCTAPE;
2052 	}
2053 
2054 	for (chan = 0; chan < isp->isp_nchan; chan++) {
2055 		if (icbp->icb_fwoptions2 & ICB2400_OPT2_FCTAPE)
2056 			FCPARAM(isp, chan)->fctape_enabled = 1;
2057 		else
2058 			FCPARAM(isp, chan)->fctape_enabled = 0;
2059 	}
2060 
2061 	switch (isp->isp_confopts & ISP_CFG_PORT_PREF) {
2062 	case ISP_CFG_LPORT_ONLY:
2063 		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
2064 		icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_ONLY;
2065 		break;
2066 	case ISP_CFG_NPORT_ONLY:
2067 		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
2068 		icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_ONLY;
2069 		break;
2070 	case ISP_CFG_NPORT:
2071 		/* ISP_CFG_PTP_2_LOOP not available in 24XX/25XX */
2072 	case ISP_CFG_LPORT:
2073 		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
2074 		icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP;
2075 		break;
2076 	default:
2077 		/* Let NVRAM settings define it if they are sane */
2078 		switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TOPO_MASK) {
2079 		case ICB2400_OPT2_LOOP_ONLY:
2080 		case ICB2400_OPT2_PTP_ONLY:
2081 		case ICB2400_OPT2_LOOP_2_PTP:
2082 			break;
2083 		default:
2084 			icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
2085 			icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP;
2086 		}
2087 		break;
2088 	}
2089 
2090 	switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK) {
2091 	case ICB2400_OPT2_ZIO:
2092 	case ICB2400_OPT2_ZIO1:
2093 		icbp->icb_idelaytimer = 0;
2094 		break;
2095 	case 0:
2096 		break;
2097 	default:
2098 		isp_prt(isp, ISP_LOGWARN, "bad value %x in fwopt2 timer field", icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK);
2099 		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TIMER_MASK;
2100 		break;
2101 	}
2102 
2103 	if (IS_26XX(isp)) {
2104 		/* Use handshake to reduce global lock congestion. */
2105 		icbp->icb_fwoptions2 |= ICB2400_OPT2_ENA_IHR;
2106 		icbp->icb_fwoptions2 |= ICB2400_OPT2_ENA_IHA;
2107 	}
2108 
2109 	if ((icbp->icb_fwoptions3 & ICB2400_OPT3_RSPSZ_MASK) == 0) {
2110 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RSPSZ_24;
2111 	}
2112 	if (isp->isp_confopts & ISP_CFG_1GB) {
2113 		icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
2114 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_1GB;
2115 	} else if (isp->isp_confopts & ISP_CFG_2GB) {
2116 		icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
2117 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_2GB;
2118 	} else if (isp->isp_confopts & ISP_CFG_4GB) {
2119 		icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
2120 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_4GB;
2121 	} else if (isp->isp_confopts & ISP_CFG_8GB) {
2122 		icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
2123 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_8GB;
2124 	} else if (isp->isp_confopts & ISP_CFG_16GB) {
2125 		icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
2126 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_16GB;
2127 	} else {
2128 		switch (icbp->icb_fwoptions3 & ICB2400_OPT3_RATE_MASK) {
2129 		case ICB2400_OPT3_RATE_4GB:
2130 		case ICB2400_OPT3_RATE_8GB:
2131 		case ICB2400_OPT3_RATE_16GB:
2132 		case ICB2400_OPT3_RATE_AUTO:
2133 			break;
2134 		case ICB2400_OPT3_RATE_2GB:
2135 			if (isp->isp_type <= ISP_HA_FC_2500)
2136 				break;
2137 			/*FALLTHROUGH*/
2138 		case ICB2400_OPT3_RATE_1GB:
2139 			if (isp->isp_type <= ISP_HA_FC_2400)
2140 				break;
2141 			/*FALLTHROUGH*/
2142 		default:
2143 			icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
2144 			icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_AUTO;
2145 			break;
2146 		}
2147 	}
2148 	if (ownloopid == 0) {
2149 		icbp->icb_fwoptions3 |= ICB2400_OPT3_SOFTID;
2150 	}
2151 	icbp->icb_logintime = ICB_LOGIN_TOV;
2152 
2153 	if (fcp->isp_wwnn && fcp->isp_wwpn) {
2154 		icbp->icb_fwoptions1 |= ICB2400_OPT1_BOTH_WWNS;
2155 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
2156 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
2157 		isp_prt(isp, ISP_LOGDEBUG1, "Setting ICB Node 0x%08x%08x Port 0x%08x%08x", ((uint32_t) (fcp->isp_wwnn >> 32)), ((uint32_t) (fcp->isp_wwnn)),
2158 		    ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
2159 	} else if (fcp->isp_wwpn) {
2160 		icbp->icb_fwoptions1 &= ~ICB2400_OPT1_BOTH_WWNS;
2161 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
2162 		isp_prt(isp, ISP_LOGDEBUG1, "Setting ICB Node to be same as Port 0x%08x%08x", ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
2163 	} else {
2164 		isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
2165 		return;
2166 	}
2167 	icbp->icb_retry_count = fcp->isp_retry_count;
2168 
2169 	icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
2170 	if (icbp->icb_rqstqlen < 8) {
2171 		isp_prt(isp, ISP_LOGERR, "bad request queue length %d", icbp->icb_rqstqlen);
2172 		return;
2173 	}
2174 	icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
2175 	if (icbp->icb_rsltqlen < 8) {
2176 		isp_prt(isp, ISP_LOGERR, "bad result queue length %d",
2177 		    icbp->icb_rsltqlen);
2178 		return;
2179 	}
2180 	icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
2181 	icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
2182 	icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
2183 	icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
2184 
2185 	icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
2186 	icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
2187 	icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
2188 	icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
2189 
2190 #ifdef	ISP_TARGET_MODE
2191 	/* unconditionally set up the ATIO queue if we support target mode */
2192 	icbp->icb_atioqlen = RESULT_QUEUE_LEN(isp);
2193 	if (icbp->icb_atioqlen < 8) {
2194 		isp_prt(isp, ISP_LOGERR, "bad ATIO queue length %d", icbp->icb_atioqlen);
2195 		return;
2196 	}
2197 	icbp->icb_atioqaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_atioq_dma);
2198 	icbp->icb_atioqaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_atioq_dma);
2199 	icbp->icb_atioqaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_atioq_dma);
2200 	icbp->icb_atioqaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_atioq_dma);
2201 	isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: atioq %04x%04x%04x%04x", DMA_WD3(isp->isp_atioq_dma), DMA_WD2(isp->isp_atioq_dma),
2202 	    DMA_WD1(isp->isp_atioq_dma), DMA_WD0(isp->isp_atioq_dma));
2203 #endif
2204 
2205 	if (ISP_CAP_MSIX(isp) && isp->isp_nirq >= 2) {
2206 		icbp->icb_msixresp = 1;
2207 		if (IS_26XX(isp) && isp->isp_nirq >= 3)
2208 			icbp->icb_msixatio = 2;
2209 	}
2210 
2211 	isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x", icbp->icb_fwoptions1, icbp->icb_fwoptions2, icbp->icb_fwoptions3);
2212 
2213 	isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: rqst %04x%04x%04x%04x rsp %04x%04x%04x%04x", DMA_WD3(isp->isp_rquest_dma), DMA_WD2(isp->isp_rquest_dma),
2214 	    DMA_WD1(isp->isp_rquest_dma), DMA_WD0(isp->isp_rquest_dma), DMA_WD3(isp->isp_result_dma), DMA_WD2(isp->isp_result_dma),
2215 	    DMA_WD1(isp->isp_result_dma), DMA_WD0(isp->isp_result_dma));
2216 
2217 	if (FC_SCRATCH_ACQUIRE(isp, 0)) {
2218 		isp_prt(isp, ISP_LOGERR, sacq);
2219 		return;
2220 	}
2221 	ISP_MEMZERO(fcp->isp_scratch, ISP_FC_SCRLEN);
2222 	isp_put_icb_2400(isp, icbp, fcp->isp_scratch);
2223 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
2224 		isp_print_bytes(isp, "isp_fibre_init_2400",
2225 		    sizeof (*icbp), fcp->isp_scratch);
2226 	}
2227 
2228 	/*
2229 	 * Now fill in information about any additional channels
2230 	 */
2231 	if (isp->isp_nchan > 1) {
2232 		isp_icb_2400_vpinfo_t vpinfo, *vdst;
2233 		vp_port_info_t pi, *pdst;
2234 		size_t amt = 0;
2235 		uint8_t *off;
2236 
2237 		vpinfo.vp_global_options = ICB2400_VPGOPT_GEN_RIDA;
2238 		if (ISP_CAP_VP0(isp)) {
2239 			vpinfo.vp_global_options |= ICB2400_VPGOPT_VP0_DECOUPLE;
2240 			vpinfo.vp_count = isp->isp_nchan;
2241 			chan = 0;
2242 		} else {
2243 			vpinfo.vp_count = isp->isp_nchan - 1;
2244 			chan = 1;
2245 		}
2246 		off = fcp->isp_scratch;
2247 		off += ICB2400_VPINFO_OFF;
2248 		vdst = (isp_icb_2400_vpinfo_t *) off;
2249 		isp_put_icb_2400_vpinfo(isp, &vpinfo, vdst);
2250 		amt = ICB2400_VPINFO_OFF + sizeof (isp_icb_2400_vpinfo_t);
2251 		for (; chan < isp->isp_nchan; chan++) {
2252 			fcparam *fcp2;
2253 
2254 			ISP_MEMZERO(&pi, sizeof (pi));
2255 			fcp2 = FCPARAM(isp, chan);
2256 			if (fcp2->role != ISP_ROLE_NONE) {
2257 				pi.vp_port_options = ICB2400_VPOPT_ENABLED |
2258 				    ICB2400_VPOPT_ENA_SNSLOGIN;
2259 				if (fcp2->role & ISP_ROLE_INITIATOR)
2260 					pi.vp_port_options |= ICB2400_VPOPT_INI_ENABLE;
2261 				if ((fcp2->role & ISP_ROLE_TARGET) == 0)
2262 					pi.vp_port_options |= ICB2400_VPOPT_TGT_DISABLE;
2263 				if (fcp2->isp_loopid < LOCAL_LOOP_LIM) {
2264 					pi.vp_port_loopid = fcp2->isp_loopid;
2265 					if (isp->isp_confopts & ISP_CFG_OWNLOOPID)
2266 						pi.vp_port_options |= ICB2400_VPOPT_HARD_ADDRESS;
2267 				}
2268 
2269 			}
2270 			MAKE_NODE_NAME_FROM_WWN(pi.vp_port_portname, fcp2->isp_wwpn);
2271 			MAKE_NODE_NAME_FROM_WWN(pi.vp_port_nodename, fcp2->isp_wwnn);
2272 			off = fcp->isp_scratch;
2273 			if (ISP_CAP_VP0(isp))
2274 				off += ICB2400_VPINFO_PORT_OFF(chan);
2275 			else
2276 				off += ICB2400_VPINFO_PORT_OFF(chan - 1);
2277 			pdst = (vp_port_info_t *) off;
2278 			isp_put_vp_port_info(isp, &pi, pdst);
2279 			amt += ICB2400_VPOPT_WRITE_SIZE;
2280 		}
2281 		if (isp->isp_dblev & ISP_LOGDEBUG1) {
2282 			isp_print_bytes(isp, "isp_fibre_init_2400",
2283 			    amt - ICB2400_VPINFO_OFF,
2284 			    (char *)fcp->isp_scratch + ICB2400_VPINFO_OFF);
2285 		}
2286 	}
2287 
2288 	/*
2289 	 * Init the firmware
2290 	 */
2291 	MBSINIT(&mbs, 0, MBLOGALL, 30000000);
2292 	if (isp->isp_nchan > 1) {
2293 		mbs.param[0] = MBOX_INIT_FIRMWARE_MULTI_ID;
2294 	} else {
2295 		mbs.param[0] = MBOX_INIT_FIRMWARE;
2296 	}
2297 	mbs.param[1] = 0;
2298 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2299 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2300 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2301 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2302 	isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %04x%04x%04x%04x", DMA_WD3(fcp->isp_scdma), DMA_WD2(fcp->isp_scdma), DMA_WD1(fcp->isp_scdma), DMA_WD0(fcp->isp_scdma));
2303 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp), 0);
2304 	isp_mboxcmd(isp, &mbs);
2305 	FC_SCRATCH_RELEASE(isp, 0);
2306 
2307 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2308 		return;
2309 	}
2310 	isp->isp_reqidx = 0;
2311 	isp->isp_reqodx = 0;
2312 	isp->isp_residx = 0;
2313 	isp->isp_resodx = 0;
2314 	isp->isp_atioodx = 0;
2315 
2316 	/*
2317 	 * Whatever happens, we're now committed to being here.
2318 	 */
2319 	isp->isp_state = ISP_RUNSTATE;
2320 }
2321 
2322 static int
isp_fc_enable_vp(ispsoftc_t * isp,int chan)2323 isp_fc_enable_vp(ispsoftc_t *isp, int chan)
2324 {
2325 	fcparam *fcp = FCPARAM(isp, chan);
2326 	vp_modify_t vp;
2327 	void *reqp;
2328 	uint8_t resp[QENTRY_LEN];
2329 
2330 	/* Build a VP MODIFY command in memory */
2331 	ISP_MEMZERO(&vp, sizeof(vp));
2332 	vp.vp_mod_hdr.rqs_entry_type = RQSTYPE_VP_MODIFY;
2333 	vp.vp_mod_hdr.rqs_entry_count = 1;
2334 	vp.vp_mod_cnt = 1;
2335 	vp.vp_mod_idx0 = chan;
2336 	vp.vp_mod_cmd = VP_MODIFY_ENA;
2337 	vp.vp_mod_ports[0].options = ICB2400_VPOPT_ENABLED |
2338 	    ICB2400_VPOPT_ENA_SNSLOGIN;
2339 	if (fcp->role & ISP_ROLE_INITIATOR)
2340 		vp.vp_mod_ports[0].options |= ICB2400_VPOPT_INI_ENABLE;
2341 	if ((fcp->role & ISP_ROLE_TARGET) == 0)
2342 		vp.vp_mod_ports[0].options |= ICB2400_VPOPT_TGT_DISABLE;
2343 	if (fcp->isp_loopid < LOCAL_LOOP_LIM) {
2344 		vp.vp_mod_ports[0].loopid = fcp->isp_loopid;
2345 		if (isp->isp_confopts & ISP_CFG_OWNLOOPID)
2346 			vp.vp_mod_ports[0].options |= ICB2400_VPOPT_HARD_ADDRESS;
2347 	}
2348 	MAKE_NODE_NAME_FROM_WWN(vp.vp_mod_ports[0].wwpn, fcp->isp_wwpn);
2349 	MAKE_NODE_NAME_FROM_WWN(vp.vp_mod_ports[0].wwnn, fcp->isp_wwnn);
2350 
2351 	/* Prepare space for response in memory */
2352 	memset(resp, 0xff, sizeof(resp));
2353 	vp.vp_mod_hdl = isp_allocate_handle(isp, resp, ISP_HANDLE_CTRL);
2354 	if (vp.vp_mod_hdl == 0) {
2355 		isp_prt(isp, ISP_LOGERR,
2356 		    "%s: VP_MODIFY of Chan %d out of handles", __func__, chan);
2357 		return (EIO);
2358 	}
2359 
2360 	/* Send request and wait for response. */
2361 	reqp = isp_getrqentry(isp);
2362 	if (reqp == NULL) {
2363 		isp_prt(isp, ISP_LOGERR,
2364 		    "%s: VP_MODIFY of Chan %d out of rqent", __func__, chan);
2365 		isp_destroy_handle(isp, vp.vp_mod_hdl);
2366 		return (EIO);
2367 	}
2368 	isp_put_vp_modify(isp, &vp, (vp_modify_t *)reqp);
2369 	if (isp->isp_dblev & ISP_LOGDEBUG1)
2370 		isp_print_bytes(isp, "IOCB VP_MODIFY", QENTRY_LEN, reqp);
2371 	ISP_SYNC_REQUEST(isp);
2372 	if (msleep(resp, &isp->isp_lock, 0, "VP_MODIFY", 5*hz) == EWOULDBLOCK) {
2373 		isp_prt(isp, ISP_LOGERR,
2374 		    "%s: VP_MODIFY of Chan %d timed out", __func__, chan);
2375 		isp_destroy_handle(isp, vp.vp_mod_hdl);
2376 		return (EIO);
2377 	}
2378 	if (isp->isp_dblev & ISP_LOGDEBUG1)
2379 		isp_print_bytes(isp, "IOCB VP_MODIFY response", QENTRY_LEN, resp);
2380 	isp_get_vp_modify(isp, (vp_modify_t *)resp, &vp);
2381 
2382 	if (vp.vp_mod_hdr.rqs_flags != 0 || vp.vp_mod_status != VP_STS_OK) {
2383 		isp_prt(isp, ISP_LOGERR,
2384 		    "%s: VP_MODIFY of Chan %d failed with flags %x status %d",
2385 		    __func__, chan, vp.vp_mod_hdr.rqs_flags, vp.vp_mod_status);
2386 		return (EIO);
2387 	}
2388 	return (0);
2389 }
2390 
2391 static int
isp_fc_disable_vp(ispsoftc_t * isp,int chan)2392 isp_fc_disable_vp(ispsoftc_t *isp, int chan)
2393 {
2394 	vp_ctrl_info_t vp;
2395 	void *reqp;
2396 	uint8_t resp[QENTRY_LEN];
2397 
2398 	/* Build a VP CTRL command in memory */
2399 	ISP_MEMZERO(&vp, sizeof(vp));
2400 	vp.vp_ctrl_hdr.rqs_entry_type = RQSTYPE_VP_CTRL;
2401 	vp.vp_ctrl_hdr.rqs_entry_count = 1;
2402 	if (ISP_CAP_VP0(isp)) {
2403 		vp.vp_ctrl_status = 1;
2404 	} else {
2405 		vp.vp_ctrl_status = 0;
2406 		chan--;	/* VP0 can not be controlled in this case. */
2407 	}
2408 	vp.vp_ctrl_command = VP_CTRL_CMD_DISABLE_VP_LOGO_ALL;
2409 	vp.vp_ctrl_vp_count = 1;
2410 	vp.vp_ctrl_idmap[chan / 16] |= (1 << chan % 16);
2411 
2412 	/* Prepare space for response in memory */
2413 	memset(resp, 0xff, sizeof(resp));
2414 	vp.vp_ctrl_handle = isp_allocate_handle(isp, resp, ISP_HANDLE_CTRL);
2415 	if (vp.vp_ctrl_handle == 0) {
2416 		isp_prt(isp, ISP_LOGERR,
2417 		    "%s: VP_CTRL of Chan %d out of handles", __func__, chan);
2418 		return (EIO);
2419 	}
2420 
2421 	/* Send request and wait for response. */
2422 	reqp = isp_getrqentry(isp);
2423 	if (reqp == NULL) {
2424 		isp_prt(isp, ISP_LOGERR,
2425 		    "%s: VP_CTRL of Chan %d out of rqent", __func__, chan);
2426 		isp_destroy_handle(isp, vp.vp_ctrl_handle);
2427 		return (EIO);
2428 	}
2429 	isp_put_vp_ctrl_info(isp, &vp, (vp_ctrl_info_t *)reqp);
2430 	if (isp->isp_dblev & ISP_LOGDEBUG1)
2431 		isp_print_bytes(isp, "IOCB VP_CTRL", QENTRY_LEN, reqp);
2432 	ISP_SYNC_REQUEST(isp);
2433 	if (msleep(resp, &isp->isp_lock, 0, "VP_CTRL", 5*hz) == EWOULDBLOCK) {
2434 		isp_prt(isp, ISP_LOGERR,
2435 		    "%s: VP_CTRL of Chan %d timed out", __func__, chan);
2436 		isp_destroy_handle(isp, vp.vp_ctrl_handle);
2437 		return (EIO);
2438 	}
2439 	if (isp->isp_dblev & ISP_LOGDEBUG1)
2440 		isp_print_bytes(isp, "IOCB VP_CTRL response", QENTRY_LEN, resp);
2441 	isp_get_vp_ctrl_info(isp, (vp_ctrl_info_t *)resp, &vp);
2442 
2443 	if (vp.vp_ctrl_hdr.rqs_flags != 0 || vp.vp_ctrl_status != 0) {
2444 		isp_prt(isp, ISP_LOGERR,
2445 		    "%s: VP_CTRL of Chan %d failed with flags %x status %d %d",
2446 		    __func__, chan, vp.vp_ctrl_hdr.rqs_flags,
2447 		    vp.vp_ctrl_status, vp.vp_ctrl_index_fail);
2448 		return (EIO);
2449 	}
2450 	return (0);
2451 }
2452 
2453 static int
isp_fc_change_role(ispsoftc_t * isp,int chan,int new_role)2454 isp_fc_change_role(ispsoftc_t *isp, int chan, int new_role)
2455 {
2456 	fcparam *fcp = FCPARAM(isp, chan);
2457 	int i, was, res = 0;
2458 
2459 	if (chan >= isp->isp_nchan) {
2460 		isp_prt(isp, ISP_LOGWARN, "%s: bad channel %d", __func__, chan);
2461 		return (ENXIO);
2462 	}
2463 	if (fcp->role == new_role)
2464 		return (0);
2465 	for (was = 0, i = 0; i < isp->isp_nchan; i++) {
2466 		if (FCPARAM(isp, i)->role != ISP_ROLE_NONE)
2467 			was++;
2468 	}
2469 	if (was == 0 || (was == 1 && fcp->role != ISP_ROLE_NONE)) {
2470 		fcp->role = new_role;
2471 		return (isp_reinit(isp, 0));
2472 	}
2473 	if (fcp->role != ISP_ROLE_NONE) {
2474 		res = isp_fc_disable_vp(isp, chan);
2475 		isp_clear_portdb(isp, chan);
2476 	}
2477 	fcp->role = new_role;
2478 	if (fcp->role != ISP_ROLE_NONE)
2479 		res = isp_fc_enable_vp(isp, chan);
2480 	return (res);
2481 }
2482 
2483 static void
isp_clear_portdb(ispsoftc_t * isp,int chan)2484 isp_clear_portdb(ispsoftc_t *isp, int chan)
2485 {
2486 	fcparam *fcp = FCPARAM(isp, chan);
2487 	fcportdb_t *lp;
2488 	int i;
2489 
2490 	for (i = 0; i < MAX_FC_TARG; i++) {
2491 		lp = &fcp->portdb[i];
2492 		switch (lp->state) {
2493 		case FC_PORTDB_STATE_DEAD:
2494 		case FC_PORTDB_STATE_CHANGED:
2495 		case FC_PORTDB_STATE_VALID:
2496 			lp->state = FC_PORTDB_STATE_NIL;
2497 			isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
2498 			break;
2499 		case FC_PORTDB_STATE_NIL:
2500 		case FC_PORTDB_STATE_NEW:
2501 			lp->state = FC_PORTDB_STATE_NIL;
2502 			break;
2503 		case FC_PORTDB_STATE_ZOMBIE:
2504 			break;
2505 		default:
2506 			panic("Don't know how to clear state %d\n", lp->state);
2507 		}
2508 	}
2509 }
2510 
2511 static void
isp_mark_portdb(ispsoftc_t * isp,int chan)2512 isp_mark_portdb(ispsoftc_t *isp, int chan)
2513 {
2514 	fcparam *fcp = FCPARAM(isp, chan);
2515 	fcportdb_t *lp;
2516 	int i;
2517 
2518 	for (i = 0; i < MAX_FC_TARG; i++) {
2519 		lp = &fcp->portdb[i];
2520 		if (lp->state == FC_PORTDB_STATE_NIL)
2521 			continue;
2522 		if (lp->portid >= DOMAIN_CONTROLLER_BASE &&
2523 		    lp->portid <= DOMAIN_CONTROLLER_END)
2524 			continue;
2525 		fcp->portdb[i].probational = 1;
2526 	}
2527 }
2528 
2529 /*
2530  * Perform an IOCB PLOGI or LOGO via EXECUTE IOCB A64 for 24XX cards
2531  * or via FABRIC LOGIN/FABRIC LOGOUT for other cards.
2532  */
2533 static int
isp_plogx(ispsoftc_t * isp,int chan,uint16_t handle,uint32_t portid,int flags)2534 isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags)
2535 {
2536 	isp_plogx_t pl;
2537 	void *reqp;
2538 	uint8_t resp[QENTRY_LEN];
2539 	uint32_t sst, parm1;
2540 	int rval, lev;
2541 	const char *msg;
2542 	char buf[64];
2543 
2544 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d PLOGX %s PortID 0x%06x nphdl 0x%x",
2545 	    chan, (flags & PLOGX_FLG_CMD_MASK) == PLOGX_FLG_CMD_PLOGI ?
2546 	    "Login":"Logout", portid, handle);
2547 	if (!IS_24XX(isp)) {
2548 		int action = flags & PLOGX_FLG_CMD_MASK;
2549 		if (action == PLOGX_FLG_CMD_PLOGI) {
2550 			return (isp_port_login(isp, handle, portid));
2551 		} else if (action == PLOGX_FLG_CMD_LOGO) {
2552 			return (isp_port_logout(isp, handle, portid));
2553 		} else {
2554 			return (MBOX_INVALID_COMMAND);
2555 		}
2556 	}
2557 
2558 	ISP_MEMZERO(&pl, sizeof(pl));
2559 	pl.plogx_header.rqs_entry_count = 1;
2560 	pl.plogx_header.rqs_entry_type = RQSTYPE_LOGIN;
2561 	pl.plogx_nphdl = handle;
2562 	pl.plogx_vphdl = chan;
2563 	pl.plogx_portlo = portid;
2564 	pl.plogx_rspsz_porthi = (portid >> 16) & 0xff;
2565 	pl.plogx_flags = flags;
2566 
2567 	/* Prepare space for response in memory */
2568 	memset(resp, 0xff, sizeof(resp));
2569 	pl.plogx_handle = isp_allocate_handle(isp, resp, ISP_HANDLE_CTRL);
2570 	if (pl.plogx_handle == 0) {
2571 		isp_prt(isp, ISP_LOGERR,
2572 		    "%s: PLOGX of Chan %d out of handles", __func__, chan);
2573 		return (-1);
2574 	}
2575 
2576 	/* Send request and wait for response. */
2577 	reqp = isp_getrqentry(isp);
2578 	if (reqp == NULL) {
2579 		isp_prt(isp, ISP_LOGERR,
2580 		    "%s: PLOGX of Chan %d out of rqent", __func__, chan);
2581 		isp_destroy_handle(isp, pl.plogx_handle);
2582 		return (-1);
2583 	}
2584 	isp_put_plogx(isp, &pl, (isp_plogx_t *)reqp);
2585 	if (isp->isp_dblev & ISP_LOGDEBUG1)
2586 		isp_print_bytes(isp, "IOCB LOGX", QENTRY_LEN, reqp);
2587 	FCPARAM(isp, chan)->isp_login_hdl = handle;
2588 	ISP_SYNC_REQUEST(isp);
2589 	if (msleep(resp, &isp->isp_lock, 0, "PLOGX", 3 * ICB_LOGIN_TOV * hz)
2590 	    == EWOULDBLOCK) {
2591 		isp_prt(isp, ISP_LOGERR,
2592 		    "%s: PLOGX of Chan %d timed out", __func__, chan);
2593 		isp_destroy_handle(isp, pl.plogx_handle);
2594 		return (-1);
2595 	}
2596 	FCPARAM(isp, chan)->isp_login_hdl = NIL_HANDLE;
2597 	if (isp->isp_dblev & ISP_LOGDEBUG1)
2598 		isp_print_bytes(isp, "IOCB LOGX response", QENTRY_LEN, resp);
2599 	isp_get_plogx(isp, (isp_plogx_t *)resp, &pl);
2600 
2601 	if (pl.plogx_status == PLOGX_STATUS_OK) {
2602 		return (0);
2603 	} else if (pl.plogx_status != PLOGX_STATUS_IOCBERR) {
2604 		isp_prt(isp, ISP_LOGWARN,
2605 		    "status 0x%x on port login IOCB channel %d",
2606 		    pl.plogx_status, chan);
2607 		return (-1);
2608 	}
2609 
2610 	sst = pl.plogx_ioparm[0].lo16 | (pl.plogx_ioparm[0].hi16 << 16);
2611 	parm1 = pl.plogx_ioparm[1].lo16 | (pl.plogx_ioparm[1].hi16 << 16);
2612 
2613 	rval = -1;
2614 	lev = ISP_LOGERR;
2615 	msg = NULL;
2616 
2617 	switch (sst) {
2618 	case PLOGX_IOCBERR_NOLINK:
2619 		msg = "no link";
2620 		break;
2621 	case PLOGX_IOCBERR_NOIOCB:
2622 		msg = "no IOCB buffer";
2623 		break;
2624 	case PLOGX_IOCBERR_NOXGHG:
2625 		msg = "no Exchange Control Block";
2626 		break;
2627 	case PLOGX_IOCBERR_FAILED:
2628 		ISP_SNPRINTF(buf, sizeof (buf), "reason 0x%x (last LOGIN state 0x%x)", parm1 & 0xff, (parm1 >> 8) & 0xff);
2629 		msg = buf;
2630 		break;
2631 	case PLOGX_IOCBERR_NOFABRIC:
2632 		msg = "no fabric";
2633 		break;
2634 	case PLOGX_IOCBERR_NOTREADY:
2635 		msg = "firmware not ready";
2636 		break;
2637 	case PLOGX_IOCBERR_NOLOGIN:
2638 		ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)", parm1);
2639 		msg = buf;
2640 		rval = MBOX_NOT_LOGGED_IN;
2641 		break;
2642 	case PLOGX_IOCBERR_REJECT:
2643 		ISP_SNPRINTF(buf, sizeof (buf), "LS_RJT = 0x%x", parm1);
2644 		msg = buf;
2645 		break;
2646 	case PLOGX_IOCBERR_NOPCB:
2647 		msg = "no PCB allocated";
2648 		break;
2649 	case PLOGX_IOCBERR_EINVAL:
2650 		ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x", parm1);
2651 		msg = buf;
2652 		break;
2653 	case PLOGX_IOCBERR_PORTUSED:
2654 		lev = ISP_LOG_SANCFG|ISP_LOG_WARN1;
2655 		ISP_SNPRINTF(buf, sizeof (buf), "already logged in with N-Port handle 0x%x", parm1);
2656 		msg = buf;
2657 		rval = MBOX_PORT_ID_USED | (parm1 << 16);
2658 		break;
2659 	case PLOGX_IOCBERR_HNDLUSED:
2660 		lev = ISP_LOG_SANCFG|ISP_LOG_WARN1;
2661 		ISP_SNPRINTF(buf, sizeof (buf), "handle already used for PortID 0x%06x", parm1);
2662 		msg = buf;
2663 		rval = MBOX_LOOP_ID_USED;
2664 		break;
2665 	case PLOGX_IOCBERR_NOHANDLE:
2666 		msg = "no handle allocated";
2667 		break;
2668 	case PLOGX_IOCBERR_NOFLOGI:
2669 		msg = "no FLOGI_ACC";
2670 		break;
2671 	default:
2672 		ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x", pl.plogx_status, flags);
2673 		msg = buf;
2674 		break;
2675 	}
2676 	if (msg) {
2677 		isp_prt(isp, lev, "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s",
2678 		    chan, portid, handle, msg);
2679 	}
2680 	return (rval);
2681 }
2682 
2683 static int
isp_port_login(ispsoftc_t * isp,uint16_t handle,uint32_t portid)2684 isp_port_login(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
2685 {
2686 	mbreg_t mbs;
2687 
2688 	MBSINIT(&mbs, MBOX_FABRIC_LOGIN, MBLOGNONE, 500000);
2689 	if (ISP_CAP_2KLOGIN(isp)) {
2690 		mbs.param[1] = handle;
2691 		mbs.ibits = (1 << 10);
2692 	} else {
2693 		mbs.param[1] = handle << 8;
2694 	}
2695 	mbs.param[2] = portid >> 16;
2696 	mbs.param[3] = portid;
2697 	mbs.logval = MBLOGNONE;
2698 	mbs.timeout = 500000;
2699 	isp_mboxcmd(isp, &mbs);
2700 
2701 	switch (mbs.param[0]) {
2702 	case MBOX_PORT_ID_USED:
2703 		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1, "isp_port_login: portid 0x%06x already logged in as 0x%x", portid, mbs.param[1]);
2704 		return (MBOX_PORT_ID_USED | (mbs.param[1] << 16));
2705 
2706 	case MBOX_LOOP_ID_USED:
2707 		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1, "isp_port_login: handle 0x%x in use for port id 0x%02xXXXX", handle, mbs.param[1] & 0xff);
2708 		return (MBOX_LOOP_ID_USED);
2709 
2710 	case MBOX_COMMAND_COMPLETE:
2711 		return (0);
2712 
2713 	case MBOX_COMMAND_ERROR:
2714 		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1, "isp_port_login: error 0x%x in PLOGI to port 0x%06x", mbs.param[1], portid);
2715 		return (MBOX_COMMAND_ERROR);
2716 
2717 	case MBOX_ALL_IDS_USED:
2718 		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1, "isp_port_login: all IDs used for fabric login");
2719 		return (MBOX_ALL_IDS_USED);
2720 
2721 	default:
2722 		isp_prt(isp, ISP_LOG_SANCFG, "isp_port_login: error 0x%x on port login of 0x%06x@0x%0x", mbs.param[0], portid, handle);
2723 		return (mbs.param[0]);
2724 	}
2725 }
2726 
2727 /*
2728  * Pre-24XX fabric port logout
2729  *
2730  * Note that portid is not used
2731  */
2732 static int
isp_port_logout(ispsoftc_t * isp,uint16_t handle,uint32_t portid)2733 isp_port_logout(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
2734 {
2735 	mbreg_t mbs;
2736 
2737 	MBSINIT(&mbs, MBOX_FABRIC_LOGOUT, MBLOGNONE, 500000);
2738 	if (ISP_CAP_2KLOGIN(isp)) {
2739 		mbs.param[1] = handle;
2740 		mbs.ibits = (1 << 10);
2741 	} else {
2742 		mbs.param[1] = handle << 8;
2743 	}
2744 	isp_mboxcmd(isp, &mbs);
2745 	return (mbs.param[0] == MBOX_COMMAND_COMPLETE? 0 : mbs.param[0]);
2746 }
2747 
2748 static int
isp_getpdb(ispsoftc_t * isp,int chan,uint16_t id,isp_pdb_t * pdb)2749 isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb)
2750 {
2751 	mbreg_t mbs;
2752 	union {
2753 		isp_pdb_21xx_t fred;
2754 		isp_pdb_24xx_t bill;
2755 	} un;
2756 
2757 	MBSINIT(&mbs, MBOX_GET_PORT_DB,
2758 	    MBLOGALL & ~MBLOGMASK(MBOX_COMMAND_PARAM_ERROR), 250000);
2759 	if (IS_24XX(isp)) {
2760 		mbs.ibits = (1 << 9)|(1 << 10);
2761 		mbs.param[1] = id;
2762 		mbs.param[9] = chan;
2763 	} else if (ISP_CAP_2KLOGIN(isp)) {
2764 		mbs.param[1] = id;
2765 	} else {
2766 		mbs.param[1] = id << 8;
2767 	}
2768 	mbs.param[2] = DMA_WD1(isp->isp_iocb_dma);
2769 	mbs.param[3] = DMA_WD0(isp->isp_iocb_dma);
2770 	mbs.param[6] = DMA_WD3(isp->isp_iocb_dma);
2771 	mbs.param[7] = DMA_WD2(isp->isp_iocb_dma);
2772 	MEMORYBARRIER(isp, SYNC_IFORDEV, 0, sizeof(un), chan);
2773 
2774 	isp_mboxcmd(isp, &mbs);
2775 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE)
2776 		return (mbs.param[0] | (mbs.param[1] << 16));
2777 
2778 	MEMORYBARRIER(isp, SYNC_IFORCPU, 0, sizeof(un), chan);
2779 	if (IS_24XX(isp)) {
2780 		isp_get_pdb_24xx(isp, isp->isp_iocb, &un.bill);
2781 		pdb->handle = un.bill.pdb_handle;
2782 		pdb->prli_word3 = un.bill.pdb_prli_svc3;
2783 		pdb->portid = BITS2WORD_24XX(un.bill.pdb_portid_bits);
2784 		ISP_MEMCPY(pdb->portname, un.bill.pdb_portname, 8);
2785 		ISP_MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8);
2786 		isp_prt(isp, ISP_LOGDEBUG0,
2787 		    "Chan %d handle 0x%x Port 0x%06x flags 0x%x curstate %x laststate %x",
2788 		    chan, id, pdb->portid, un.bill.pdb_flags,
2789 		    un.bill.pdb_curstate, un.bill.pdb_laststate);
2790 
2791 		if (un.bill.pdb_curstate < PDB2400_STATE_PLOGI_DONE || un.bill.pdb_curstate > PDB2400_STATE_LOGGED_IN) {
2792 			mbs.param[0] = MBOX_NOT_LOGGED_IN;
2793 			return (mbs.param[0]);
2794 		}
2795 	} else {
2796 		isp_get_pdb_21xx(isp, isp->isp_iocb, &un.fred);
2797 		pdb->handle = un.fred.pdb_loopid;
2798 		pdb->prli_word3 = un.fred.pdb_prli_svc3;
2799 		pdb->portid = BITS2WORD(un.fred.pdb_portid_bits);
2800 		ISP_MEMCPY(pdb->portname, un.fred.pdb_portname, 8);
2801 		ISP_MEMCPY(pdb->nodename, un.fred.pdb_nodename, 8);
2802 		isp_prt(isp, ISP_LOGDEBUG1,
2803 		    "Chan %d handle 0x%x Port 0x%06x", chan, id, pdb->portid);
2804 	}
2805 	return (0);
2806 }
2807 
2808 static int
isp_gethandles(ispsoftc_t * isp,int chan,uint16_t * handles,int * num,int loop)2809 isp_gethandles(ispsoftc_t *isp, int chan, uint16_t *handles, int *num, int loop)
2810 {
2811 	fcparam *fcp = FCPARAM(isp, chan);
2812 	mbreg_t mbs;
2813 	isp_pnhle_21xx_t el1, *elp1;
2814 	isp_pnhle_23xx_t el3, *elp3;
2815 	isp_pnhle_24xx_t el4, *elp4;
2816 	int i, j;
2817 	uint32_t p;
2818 	uint16_t h;
2819 
2820 	MBSINIT(&mbs, MBOX_GET_ID_LIST, MBLOGALL, 250000);
2821 	if (IS_24XX(isp)) {
2822 		mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2823 		mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2824 		mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2825 		mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2826 		mbs.param[8] = ISP_FC_SCRLEN;
2827 		mbs.param[9] = chan;
2828 	} else {
2829 		mbs.ibits = (1 << 1)|(1 << 2)|(1 << 3)|(1 << 6);
2830 		mbs.param[1] = DMA_WD1(fcp->isp_scdma);
2831 		mbs.param[2] = DMA_WD0(fcp->isp_scdma);
2832 		mbs.param[3] = DMA_WD3(fcp->isp_scdma);
2833 		mbs.param[6] = DMA_WD2(fcp->isp_scdma);
2834 	}
2835 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2836 		isp_prt(isp, ISP_LOGERR, sacq);
2837 		return (-1);
2838 	}
2839 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, ISP_FC_SCRLEN, chan);
2840 	isp_mboxcmd(isp, &mbs);
2841 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2842 		FC_SCRATCH_RELEASE(isp, chan);
2843 		return (mbs.param[0] | (mbs.param[1] << 16));
2844 	}
2845 	MEMORYBARRIER(isp, SYNC_SFORCPU, 0, ISP_FC_SCRLEN, chan);
2846 	elp1 = fcp->isp_scratch;
2847 	elp3 = fcp->isp_scratch;
2848 	elp4 = fcp->isp_scratch;
2849 	for (i = 0, j = 0; i < mbs.param[1] && j < *num; i++) {
2850 		if (IS_24XX(isp)) {
2851 			isp_get_pnhle_24xx(isp, &elp4[i], &el4);
2852 			p = el4.pnhle_port_id_lo |
2853 			    (el4.pnhle_port_id_hi << 16);
2854 			h = el4.pnhle_handle;
2855 		} else if (IS_23XX(isp)) {
2856 			isp_get_pnhle_23xx(isp, &elp3[i], &el3);
2857 			p = el3.pnhle_port_id_lo |
2858 			    (el3.pnhle_port_id_hi << 16);
2859 			h = el3.pnhle_handle;
2860 		} else { /* 21xx */
2861 			isp_get_pnhle_21xx(isp, &elp1[i], &el1);
2862 			p = el1.pnhle_port_id_lo |
2863 			    ((el1.pnhle_port_id_hi_handle & 0xff) << 16);
2864 			h = el1.pnhle_port_id_hi_handle >> 8;
2865 		}
2866 		if (loop && (p >> 8) != (fcp->isp_portid >> 8))
2867 			continue;
2868 		handles[j++] = h;
2869 	}
2870 	*num = j;
2871 	FC_SCRATCH_RELEASE(isp, chan);
2872 	return (0);
2873 }
2874 
2875 static void
isp_dump_chip_portdb(ispsoftc_t * isp,int chan)2876 isp_dump_chip_portdb(ispsoftc_t *isp, int chan)
2877 {
2878 	isp_pdb_t pdb;
2879 	uint16_t lim, nphdl;
2880 
2881 	isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGINFO, "Chan %d chip port dump", chan);
2882 	if (ISP_CAP_2KLOGIN(isp)) {
2883 		lim = NPH_MAX_2K;
2884 	} else {
2885 		lim = NPH_MAX;
2886 	}
2887 	for (nphdl = 0; nphdl != lim; nphdl++) {
2888 		if (isp_getpdb(isp, chan, nphdl, &pdb)) {
2889 			continue;
2890 		}
2891 		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGINFO, "Chan %d Handle 0x%04x "
2892 		    "PortID 0x%06x WWPN 0x%02x%02x%02x%02x%02x%02x%02x%02x",
2893 		    chan, nphdl, pdb.portid, pdb.portname[0], pdb.portname[1],
2894 		    pdb.portname[2], pdb.portname[3], pdb.portname[4],
2895 		    pdb.portname[5], pdb.portname[6], pdb.portname[7]);
2896 	}
2897 }
2898 
2899 static uint64_t
isp_get_wwn(ispsoftc_t * isp,int chan,int nphdl,int nodename)2900 isp_get_wwn(ispsoftc_t *isp, int chan, int nphdl, int nodename)
2901 {
2902 	uint64_t wwn = INI_NONE;
2903 	mbreg_t mbs;
2904 
2905 	MBSINIT(&mbs, MBOX_GET_PORT_NAME,
2906 	    MBLOGALL & ~MBLOGMASK(MBOX_COMMAND_PARAM_ERROR), 500000);
2907 	if (ISP_CAP_2KLOGIN(isp)) {
2908 		mbs.param[1] = nphdl;
2909 		if (nodename) {
2910 			mbs.param[10] = 1;
2911 		}
2912 		mbs.param[9] = chan;
2913 	} else {
2914 		mbs.ibitm = 3;
2915 		mbs.param[1] = nphdl << 8;
2916 		if (nodename) {
2917 			mbs.param[1] |= 1;
2918 		}
2919 	}
2920 	isp_mboxcmd(isp, &mbs);
2921 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2922 		return (wwn);
2923 	}
2924 	if (IS_24XX(isp)) {
2925 		wwn =
2926 		    (((uint64_t)(mbs.param[2] >> 8))	<< 56) |
2927 		    (((uint64_t)(mbs.param[2] & 0xff))	<< 48) |
2928 		    (((uint64_t)(mbs.param[3] >> 8))	<< 40) |
2929 		    (((uint64_t)(mbs.param[3] & 0xff))	<< 32) |
2930 		    (((uint64_t)(mbs.param[6] >> 8))	<< 24) |
2931 		    (((uint64_t)(mbs.param[6] & 0xff))	<< 16) |
2932 		    (((uint64_t)(mbs.param[7] >> 8))	<<  8) |
2933 		    (((uint64_t)(mbs.param[7] & 0xff)));
2934 	} else {
2935 		wwn =
2936 		    (((uint64_t)(mbs.param[2] & 0xff))  << 56) |
2937 		    (((uint64_t)(mbs.param[2] >> 8))	<< 48) |
2938 		    (((uint64_t)(mbs.param[3] & 0xff))	<< 40) |
2939 		    (((uint64_t)(mbs.param[3] >> 8))	<< 32) |
2940 		    (((uint64_t)(mbs.param[6] & 0xff))	<< 24) |
2941 		    (((uint64_t)(mbs.param[6] >> 8))	<< 16) |
2942 		    (((uint64_t)(mbs.param[7] & 0xff))	<<  8) |
2943 		    (((uint64_t)(mbs.param[7] >> 8)));
2944 	}
2945 	return (wwn);
2946 }
2947 
2948 /*
2949  * Make sure we have good FC link.
2950  */
2951 
2952 static int
isp_fclink_test(ispsoftc_t * isp,int chan,int usdelay)2953 isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay)
2954 {
2955 	mbreg_t mbs;
2956 	int i, r;
2957 	uint16_t nphdl;
2958 	fcparam *fcp;
2959 	isp_pdb_t pdb;
2960 	NANOTIME_T hra, hrb;
2961 
2962 	fcp = FCPARAM(isp, chan);
2963 
2964 	if (fcp->isp_loopstate < LOOP_HAVE_LINK)
2965 		return (-1);
2966 	if (fcp->isp_loopstate >= LOOP_LTEST_DONE)
2967 		return (0);
2968 
2969 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC link test", chan);
2970 
2971 	/*
2972 	 * Wait up to N microseconds for F/W to go to a ready state.
2973 	 */
2974 	GET_NANOTIME(&hra);
2975 	while (1) {
2976 		isp_change_fw_state(isp, chan, isp_fw_state(isp, chan));
2977 		if (fcp->isp_fwstate == FW_READY) {
2978 			break;
2979 		}
2980 		if (fcp->isp_loopstate < LOOP_HAVE_LINK)
2981 			goto abort;
2982 		GET_NANOTIME(&hrb);
2983 		if ((NANOTIME_SUB(&hrb, &hra) / 1000 + 1000 >= usdelay))
2984 			break;
2985 		ISP_SLEEP(isp, 1000);
2986 	}
2987 	if (fcp->isp_fwstate != FW_READY) {
2988 		isp_prt(isp, ISP_LOG_SANCFG,
2989 		    "Chan %d Firmware is not ready (%s)",
2990 		    chan, isp_fc_fw_statename(fcp->isp_fwstate));
2991 		return (-1);
2992 	}
2993 
2994 	/*
2995 	 * Get our Loop ID and Port ID.
2996 	 */
2997 	MBSINIT(&mbs, MBOX_GET_LOOP_ID, MBLOGALL, 0);
2998 	mbs.param[9] = chan;
2999 	isp_mboxcmd(isp, &mbs);
3000 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3001 		return (-1);
3002 	}
3003 
3004 	if (IS_2100(isp)) {
3005 		/*
3006 		 * Don't bother with fabric if we are using really old
3007 		 * 2100 firmware. It's just not worth it.
3008 		 */
3009 		if (ISP_FW_NEWER_THAN(isp, 1, 15, 37))
3010 			fcp->isp_topo = TOPO_FL_PORT;
3011 		else
3012 			fcp->isp_topo = TOPO_NL_PORT;
3013 	} else {
3014 		int topo = (int) mbs.param[6];
3015 		if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB) {
3016 			topo = TOPO_PTP_STUB;
3017 		}
3018 		fcp->isp_topo = topo;
3019 	}
3020 	fcp->isp_portid = mbs.param[2] | (mbs.param[3] << 16);
3021 
3022 	if (!TOPO_IS_FABRIC(fcp->isp_topo)) {
3023 		fcp->isp_loopid = mbs.param[1] & 0xff;
3024 	} else if (fcp->isp_topo != TOPO_F_PORT) {
3025 		uint8_t alpa = fcp->isp_portid;
3026 
3027 		for (i = 0; alpa_map[i]; i++) {
3028 			if (alpa_map[i] == alpa)
3029 				break;
3030 		}
3031 		if (alpa_map[i])
3032 			fcp->isp_loopid = i;
3033 	}
3034 
3035 #if 0
3036 	fcp->isp_loopstate = LOOP_HAVE_ADDR;
3037 #endif
3038 	fcp->isp_loopstate = LOOP_TESTING_LINK;
3039 
3040 	if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) {
3041 		nphdl = IS_24XX(isp) ? NPH_FL_ID : FL_ID;
3042 		r = isp_getpdb(isp, chan, nphdl, &pdb);
3043 		if (r != 0 || pdb.portid == 0) {
3044 			if (IS_2100(isp)) {
3045 				fcp->isp_topo = TOPO_NL_PORT;
3046 			} else {
3047 				isp_prt(isp, ISP_LOGWARN,
3048 				    "fabric topology, but cannot get info about fabric controller (0x%x)", r);
3049 				fcp->isp_topo = TOPO_PTP_STUB;
3050 			}
3051 			goto not_on_fabric;
3052 		}
3053 
3054 		if (IS_24XX(isp)) {
3055 			fcp->isp_fabric_params = mbs.param[7];
3056 			fcp->isp_sns_hdl = NPH_SNS_ID;
3057 			r = isp_register_fc4_type_24xx(isp, chan);
3058 			if (fcp->isp_loopstate < LOOP_TESTING_LINK)
3059 				goto abort;
3060 			if (r != 0)
3061 				goto not_on_fabric;
3062 			r = isp_register_fc4_features_24xx(isp, chan);
3063 			if (fcp->isp_loopstate < LOOP_TESTING_LINK)
3064 				goto abort;
3065 			if (r != 0)
3066 				goto not_on_fabric;
3067 			r = isp_register_port_name_24xx(isp, chan);
3068 			if (fcp->isp_loopstate < LOOP_TESTING_LINK)
3069 				goto abort;
3070 			if (r != 0)
3071 				goto not_on_fabric;
3072 			isp_register_node_name_24xx(isp, chan);
3073 			if (fcp->isp_loopstate < LOOP_TESTING_LINK)
3074 				goto abort;
3075 		} else {
3076 			fcp->isp_sns_hdl = SNS_ID;
3077 			r = isp_register_fc4_type(isp, chan);
3078 			if (r != 0)
3079 				goto not_on_fabric;
3080 			if (fcp->role == ISP_ROLE_TARGET)
3081 				isp_send_change_request(isp, chan);
3082 		}
3083 	}
3084 
3085 not_on_fabric:
3086 	/* Get link speed. */
3087 	fcp->isp_gbspeed = 1;
3088 	if (IS_23XX(isp) || IS_24XX(isp)) {
3089 		MBSINIT(&mbs, MBOX_GET_SET_DATA_RATE, MBLOGALL, 3000000);
3090 		mbs.param[1] = MBGSD_GET_RATE;
3091 		/* mbs.param[2] undefined if we're just getting rate */
3092 		isp_mboxcmd(isp, &mbs);
3093 		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
3094 			if (mbs.param[1] == MBGSD_10GB)
3095 				fcp->isp_gbspeed = 10;
3096 			else if (mbs.param[1] == MBGSD_16GB)
3097 				fcp->isp_gbspeed = 16;
3098 			else if (mbs.param[1] == MBGSD_8GB)
3099 				fcp->isp_gbspeed = 8;
3100 			else if (mbs.param[1] == MBGSD_4GB)
3101 				fcp->isp_gbspeed = 4;
3102 			else if (mbs.param[1] == MBGSD_2GB)
3103 				fcp->isp_gbspeed = 2;
3104 			else if (mbs.param[1] == MBGSD_1GB)
3105 				fcp->isp_gbspeed = 1;
3106 		}
3107 	}
3108 
3109 	if (fcp->isp_loopstate < LOOP_TESTING_LINK) {
3110 abort:
3111 		isp_prt(isp, ISP_LOG_SANCFG,
3112 		    "Chan %d FC link test aborted", chan);
3113 		return (1);
3114 	}
3115 	fcp->isp_loopstate = LOOP_LTEST_DONE;
3116 	isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGCONFIG,
3117 	    "Chan %d WWPN %016jx WWNN %016jx",
3118 	    chan, (uintmax_t)fcp->isp_wwpn, (uintmax_t)fcp->isp_wwnn);
3119 	isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGCONFIG,
3120 	    "Chan %d %dGb %s PortID 0x%06x LoopID 0x%02x",
3121 	    chan, fcp->isp_gbspeed, isp_fc_toponame(fcp), fcp->isp_portid,
3122 	    fcp->isp_loopid);
3123 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC link test done", chan);
3124 	return (0);
3125 }
3126 
3127 /*
3128  * Complete the synchronization of our Port Database.
3129  *
3130  * At this point, we've scanned the local loop (if any) and the fabric
3131  * and performed fabric logins on all new devices.
3132  *
3133  * Our task here is to go through our port database removing any entities
3134  * that are still marked probational (issuing PLOGO for ones which we had
3135  * PLOGI'd into) or are dead, and notifying upper layers about new/changed
3136  * devices.
3137  */
3138 static int
isp_pdb_sync(ispsoftc_t * isp,int chan)3139 isp_pdb_sync(ispsoftc_t *isp, int chan)
3140 {
3141 	fcparam *fcp = FCPARAM(isp, chan);
3142 	fcportdb_t *lp;
3143 	uint16_t dbidx;
3144 
3145 	if (fcp->isp_loopstate < LOOP_FSCAN_DONE)
3146 		return (-1);
3147 	if (fcp->isp_loopstate >= LOOP_READY)
3148 		return (0);
3149 
3150 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC PDB sync", chan);
3151 
3152 	fcp->isp_loopstate = LOOP_SYNCING_PDB;
3153 
3154 	for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
3155 		lp = &fcp->portdb[dbidx];
3156 
3157 		if (lp->state == FC_PORTDB_STATE_NIL)
3158 			continue;
3159 		if (lp->probational && lp->state != FC_PORTDB_STATE_ZOMBIE)
3160 			lp->state = FC_PORTDB_STATE_DEAD;
3161 		switch (lp->state) {
3162 		case FC_PORTDB_STATE_DEAD:
3163 			lp->state = FC_PORTDB_STATE_NIL;
3164 			isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
3165 			if ((lp->portid & 0xffff00) != 0) {
3166 				(void) isp_plogx(isp, chan, lp->handle,
3167 				    lp->portid,
3168 				    PLOGX_FLG_CMD_LOGO |
3169 				    PLOGX_FLG_IMPLICIT |
3170 				    PLOGX_FLG_FREE_NPHDL);
3171 			}
3172 			/*
3173 			 * Note that we might come out of this with our state
3174 			 * set to FC_PORTDB_STATE_ZOMBIE.
3175 			 */
3176 			break;
3177 		case FC_PORTDB_STATE_NEW:
3178 			lp->state = FC_PORTDB_STATE_VALID;
3179 			isp_async(isp, ISPASYNC_DEV_ARRIVED, chan, lp);
3180 			break;
3181 		case FC_PORTDB_STATE_CHANGED:
3182 			lp->state = FC_PORTDB_STATE_VALID;
3183 			isp_async(isp, ISPASYNC_DEV_CHANGED, chan, lp);
3184 			lp->portid = lp->new_portid;
3185 			lp->prli_word3 = lp->new_prli_word3;
3186 			break;
3187 		case FC_PORTDB_STATE_VALID:
3188 			isp_async(isp, ISPASYNC_DEV_STAYED, chan, lp);
3189 			break;
3190 		case FC_PORTDB_STATE_ZOMBIE:
3191 			break;
3192 		default:
3193 			isp_prt(isp, ISP_LOGWARN,
3194 			    "isp_pdb_sync: state %d for idx %d",
3195 			    lp->state, dbidx);
3196 			isp_dump_portdb(isp, chan);
3197 		}
3198 	}
3199 
3200 	if (fcp->isp_loopstate < LOOP_SYNCING_PDB) {
3201 		isp_prt(isp, ISP_LOG_SANCFG,
3202 		    "Chan %d FC PDB sync aborted", chan);
3203 		return (1);
3204 	}
3205 
3206 	fcp->isp_loopstate = LOOP_READY;
3207 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC PDB sync done", chan);
3208 	return (0);
3209 }
3210 
3211 static void
isp_pdb_add_update(ispsoftc_t * isp,int chan,isp_pdb_t * pdb)3212 isp_pdb_add_update(ispsoftc_t *isp, int chan, isp_pdb_t *pdb)
3213 {
3214 	fcportdb_t *lp;
3215 	uint64_t wwnn, wwpn;
3216 
3217 	MAKE_WWN_FROM_NODE_NAME(wwnn, pdb->nodename);
3218 	MAKE_WWN_FROM_NODE_NAME(wwpn, pdb->portname);
3219 
3220 	/* Search port database for the same WWPN. */
3221 	if (isp_find_pdb_by_wwpn(isp, chan, wwpn, &lp)) {
3222 		if (!lp->probational) {
3223 			isp_prt(isp, ISP_LOGERR,
3224 			    "Chan %d Port 0x%06x@0x%04x [%d] is not probational (0x%x)",
3225 			    chan, lp->portid, lp->handle,
3226 			    FC_PORTDB_TGT(isp, chan, lp), lp->state);
3227 			isp_dump_portdb(isp, chan);
3228 			return;
3229 		}
3230 		lp->probational = 0;
3231 		lp->node_wwn = wwnn;
3232 
3233 		/* Old device, nothing new. */
3234 		if (lp->portid == pdb->portid &&
3235 		    lp->handle == pdb->handle &&
3236 		    lp->prli_word3 == pdb->prli_word3) {
3237 			if (lp->state != FC_PORTDB_STATE_NEW)
3238 				lp->state = FC_PORTDB_STATE_VALID;
3239 			isp_prt(isp, ISP_LOG_SANCFG,
3240 			    "Chan %d Port 0x%06x@0x%04x is valid",
3241 			    chan, pdb->portid, pdb->handle);
3242 			return;
3243 		}
3244 
3245 		/* Something has changed. */
3246 		lp->state = FC_PORTDB_STATE_CHANGED;
3247 		lp->handle = pdb->handle;
3248 		lp->new_portid = pdb->portid;
3249 		lp->new_prli_word3 = pdb->prli_word3;
3250 		isp_prt(isp, ISP_LOG_SANCFG,
3251 		    "Chan %d Port 0x%06x@0x%04x is changed",
3252 		    chan, pdb->portid, pdb->handle);
3253 		return;
3254 	}
3255 
3256 	/* It seems like a new port. Find an empty slot for it. */
3257 	if (!isp_find_pdb_empty(isp, chan, &lp)) {
3258 		isp_prt(isp, ISP_LOGERR, "Chan %d out of portdb entries", chan);
3259 		return;
3260 	}
3261 
3262 	ISP_MEMZERO(lp, sizeof (fcportdb_t));
3263 	lp->probational = 0;
3264 	lp->state = FC_PORTDB_STATE_NEW;
3265 	lp->portid = lp->new_portid = pdb->portid;
3266 	lp->prli_word3 = lp->new_prli_word3 = pdb->prli_word3;
3267 	lp->handle = pdb->handle;
3268 	lp->port_wwn = wwpn;
3269 	lp->node_wwn = wwnn;
3270 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Port 0x%06x@0x%04x is new",
3271 	    chan, pdb->portid, pdb->handle);
3272 }
3273 
3274 /*
3275  * Fix port IDs for logged-in initiators on pre-2400 chips.
3276  * For those chips we are not receiving login events, adding initiators
3277  * based on ATIO requests, but there is no port ID in that structure.
3278  */
3279 static void
isp_fix_portids(ispsoftc_t * isp,int chan)3280 isp_fix_portids(ispsoftc_t *isp, int chan)
3281 {
3282 	fcparam *fcp = FCPARAM(isp, chan);
3283 	isp_pdb_t pdb;
3284 	uint64_t wwpn;
3285 	int i, r;
3286 
3287 	for (i = 0; i < MAX_FC_TARG; i++) {
3288 		fcportdb_t *lp = &fcp->portdb[i];
3289 
3290 		if (lp->state == FC_PORTDB_STATE_NIL ||
3291 		    lp->state == FC_PORTDB_STATE_ZOMBIE)
3292 			continue;
3293 		if (VALID_PORT(lp->portid))
3294 			continue;
3295 
3296 		r = isp_getpdb(isp, chan, lp->handle, &pdb);
3297 		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
3298 			return;
3299 		if (r != 0) {
3300 			isp_prt(isp, ISP_LOGDEBUG1,
3301 			    "Chan %d FC Scan Loop handle %d returned %x",
3302 			    chan, lp->handle, r);
3303 			continue;
3304 		}
3305 
3306 		MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
3307 		if (lp->port_wwn != wwpn)
3308 			continue;
3309 		lp->portid = lp->new_portid = pdb.portid;
3310 		isp_prt(isp, ISP_LOG_SANCFG,
3311 		    "Chan %d Port 0x%06x@0x%04x is fixed",
3312 		    chan, pdb.portid, pdb.handle);
3313 	}
3314 }
3315 
3316 /*
3317  * Scan local loop for devices.
3318  */
3319 static int
isp_scan_loop(ispsoftc_t * isp,int chan)3320 isp_scan_loop(ispsoftc_t *isp, int chan)
3321 {
3322 	fcparam *fcp = FCPARAM(isp, chan);
3323 	int idx, lim, r;
3324 	isp_pdb_t pdb;
3325 	uint16_t *handles;
3326 	uint16_t handle;
3327 
3328 	if (fcp->isp_loopstate < LOOP_LTEST_DONE)
3329 		return (-1);
3330 	if (fcp->isp_loopstate >= LOOP_LSCAN_DONE)
3331 		return (0);
3332 
3333 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC loop scan", chan);
3334 	fcp->isp_loopstate = LOOP_SCANNING_LOOP;
3335 	if (TOPO_IS_FABRIC(fcp->isp_topo)) {
3336 		if (!IS_24XX(isp)) {
3337 			isp_fix_portids(isp, chan);
3338 			if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
3339 				goto abort;
3340 		}
3341 		isp_prt(isp, ISP_LOG_SANCFG,
3342 		    "Chan %d FC loop scan done (no loop)", chan);
3343 		fcp->isp_loopstate = LOOP_LSCAN_DONE;
3344 		return (0);
3345 	}
3346 
3347 	handles = (uint16_t *)fcp->isp_scanscratch;
3348 	lim = ISP_FC_SCRLEN / 2;
3349 	r = isp_gethandles(isp, chan, handles, &lim, 1);
3350 	if (r != 0) {
3351 		isp_prt(isp, ISP_LOG_SANCFG,
3352 		    "Chan %d Getting list of handles failed with %x", chan, r);
3353 		isp_prt(isp, ISP_LOG_SANCFG,
3354 		    "Chan %d FC loop scan done (bad)", chan);
3355 		return (-1);
3356 	}
3357 
3358 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Got %d handles",
3359 	    chan, lim);
3360 
3361 	/*
3362 	 * Run through the list and get the port database info for each one.
3363 	 */
3364 	isp_mark_portdb(isp, chan);
3365 	for (idx = 0; idx < lim; idx++) {
3366 		handle = handles[idx];
3367 
3368 		/*
3369 		 * Don't scan "special" ids.
3370 		 */
3371 		if (ISP_CAP_2KLOGIN(isp)) {
3372 			if (handle >= NPH_RESERVED)
3373 				continue;
3374 		} else {
3375 			if (handle >= FL_ID && handle <= SNS_ID)
3376 				continue;
3377 		}
3378 
3379 		/*
3380 		 * In older cards with older f/w GET_PORT_DATABASE has been
3381 		 * known to hang. This trick gets around that problem.
3382 		 */
3383 		if (IS_2100(isp) || IS_2200(isp)) {
3384 			uint64_t node_wwn = isp_get_wwn(isp, chan, handle, 1);
3385 			if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
3386 abort:
3387 				isp_prt(isp, ISP_LOG_SANCFG,
3388 				    "Chan %d FC loop scan aborted", chan);
3389 				return (1);
3390 			}
3391 			if (node_wwn == INI_NONE) {
3392 				continue;
3393 			}
3394 		}
3395 
3396 		/*
3397 		 * Get the port database entity for this index.
3398 		 */
3399 		r = isp_getpdb(isp, chan, handle, &pdb);
3400 		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
3401 			goto abort;
3402 		if (r != 0) {
3403 			isp_prt(isp, ISP_LOGDEBUG1,
3404 			    "Chan %d FC Scan Loop handle %d returned %x",
3405 			    chan, handle, r);
3406 			continue;
3407 		}
3408 
3409 		isp_pdb_add_update(isp, chan, &pdb);
3410 	}
3411 	if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
3412 		goto abort;
3413 	fcp->isp_loopstate = LOOP_LSCAN_DONE;
3414 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC loop scan done", chan);
3415 	return (0);
3416 }
3417 
3418 /*
3419  * Scan the fabric for devices and add them to our port database.
3420  *
3421  * Use the GID_FT command to get all Port IDs for FC4 SCSI devices it knows.
3422  *
3423  * For 2100-23XX cards, we use the SNS mailbox command to pass simple name
3424  * server commands to the switch management server via the QLogic f/w.
3425  *
3426  * For the 24XX and above card, we use CT Pass-through IOCB.
3427  */
3428 #define	GIDLEN	ISP_FC_SCRLEN
3429 #define	NGENT	((GIDLEN - 16) >> 2)
3430 
3431 static int
isp_gid_ft_sns(ispsoftc_t * isp,int chan)3432 isp_gid_ft_sns(ispsoftc_t *isp, int chan)
3433 {
3434 	union {
3435 		sns_gid_ft_req_t _x;
3436 		uint8_t _y[SNS_GID_FT_REQ_SIZE];
3437 	} un;
3438 	fcparam *fcp = FCPARAM(isp, chan);
3439 	sns_gid_ft_req_t *rq = &un._x;
3440 	uint8_t *scp = fcp->isp_scratch;
3441 	mbreg_t mbs;
3442 
3443 	isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GID_FT via SNS", chan);
3444 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
3445 		isp_prt(isp, ISP_LOGERR, sacq);
3446 		return (-1);
3447 	}
3448 
3449 	ISP_MEMZERO(rq, SNS_GID_FT_REQ_SIZE);
3450 	rq->snscb_rblen = GIDLEN >> 1;
3451 	rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma);
3452 	rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma);
3453 	rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma);
3454 	rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma);
3455 	rq->snscb_sblen = 6;
3456 	rq->snscb_cmd = SNS_GID_FT;
3457 	rq->snscb_mword_div_2 = NGENT;
3458 	rq->snscb_fc4_type = FC4_SCSI;
3459 
3460 	isp_put_gid_ft_request(isp, rq, (sns_gid_ft_req_t *)scp);
3461 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE, chan);
3462 
3463 	MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 10000000);
3464 	mbs.param[0] = MBOX_SEND_SNS;
3465 	mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1;
3466 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
3467 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
3468 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
3469 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
3470 	isp_mboxcmd(isp, &mbs);
3471 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3472 		if (mbs.param[0] == MBOX_INVALID_COMMAND) {
3473 			return (1);
3474 		} else {
3475 			return (-1);
3476 		}
3477 	}
3478 	MEMORYBARRIER(isp, SYNC_SFORCPU, 0, GIDLEN, chan);
3479 	if (isp->isp_dblev & ISP_LOGDEBUG1)
3480 		isp_print_bytes(isp, "CT response", GIDLEN, scp);
3481 	isp_get_gid_ft_response(isp, (sns_gid_ft_rsp_t *)scp,
3482 	    (sns_gid_ft_rsp_t *)fcp->isp_scanscratch, NGENT);
3483 	FC_SCRATCH_RELEASE(isp, chan);
3484 	return (0);
3485 }
3486 
3487 static int
isp_ct_passthru(ispsoftc_t * isp,int chan,uint32_t cmd_bcnt,uint32_t rsp_bcnt)3488 isp_ct_passthru(ispsoftc_t *isp, int chan, uint32_t cmd_bcnt, uint32_t rsp_bcnt)
3489 {
3490 	fcparam *fcp = FCPARAM(isp, chan);
3491 	isp_ct_pt_t pt;
3492 	void *reqp;
3493 	uint8_t resp[QENTRY_LEN];
3494 
3495 	/*
3496 	 * Build a Passthrough IOCB in memory.
3497 	 */
3498 	ISP_MEMZERO(&pt, sizeof(pt));
3499 	pt.ctp_header.rqs_entry_count = 1;
3500 	pt.ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
3501 	pt.ctp_nphdl = fcp->isp_sns_hdl;
3502 	pt.ctp_cmd_cnt = 1;
3503 	pt.ctp_vpidx = ISP_GET_VPIDX(isp, chan);
3504 	pt.ctp_time = 10;
3505 	pt.ctp_rsp_cnt = 1;
3506 	pt.ctp_rsp_bcnt = rsp_bcnt;
3507 	pt.ctp_cmd_bcnt = cmd_bcnt;
3508 	pt.ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma);
3509 	pt.ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma);
3510 	pt.ctp_dataseg[0].ds_count = cmd_bcnt;
3511 	pt.ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma);
3512 	pt.ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma);
3513 	pt.ctp_dataseg[1].ds_count = rsp_bcnt;
3514 
3515 	/* Prepare space for response in memory */
3516 	memset(resp, 0xff, sizeof(resp));
3517 	pt.ctp_handle = isp_allocate_handle(isp, resp, ISP_HANDLE_CTRL);
3518 	if (pt.ctp_handle == 0) {
3519 		isp_prt(isp, ISP_LOGERR,
3520 		    "%s: CTP of Chan %d out of handles", __func__, chan);
3521 		return (-1);
3522 	}
3523 
3524 	/* Send request and wait for response. */
3525 	reqp = isp_getrqentry(isp);
3526 	if (reqp == NULL) {
3527 		isp_prt(isp, ISP_LOGERR,
3528 		    "%s: CTP of Chan %d out of rqent", __func__, chan);
3529 		isp_destroy_handle(isp, pt.ctp_handle);
3530 		return (-1);
3531 	}
3532 	isp_put_ct_pt(isp, &pt, (isp_ct_pt_t *)reqp);
3533 	if (isp->isp_dblev & ISP_LOGDEBUG1)
3534 		isp_print_bytes(isp, "CT IOCB request", QENTRY_LEN, reqp);
3535 	ISP_SYNC_REQUEST(isp);
3536 	if (msleep(resp, &isp->isp_lock, 0, "CTP", pt.ctp_time*hz) == EWOULDBLOCK) {
3537 		isp_prt(isp, ISP_LOGERR,
3538 		    "%s: CTP of Chan %d timed out", __func__, chan);
3539 		isp_destroy_handle(isp, pt.ctp_handle);
3540 		return (-1);
3541 	}
3542 	if (isp->isp_dblev & ISP_LOGDEBUG1)
3543 		isp_print_bytes(isp, "CT IOCB response", QENTRY_LEN, resp);
3544 
3545 	isp_get_ct_pt(isp, (isp_ct_pt_t *)resp, &pt);
3546 	if (pt.ctp_status && pt.ctp_status != RQCS_DATA_UNDERRUN) {
3547 		isp_prt(isp, ISP_LOGWARN,
3548 		    "Chan %d GID_FT CT Passthrough returned 0x%x",
3549 		    chan, pt.ctp_status);
3550 		return (-1);
3551 	}
3552 
3553 	return (0);
3554 }
3555 
3556 static int
isp_gid_ft_ct_passthru(ispsoftc_t * isp,int chan)3557 isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan)
3558 {
3559 	fcparam *fcp = FCPARAM(isp, chan);
3560 	ct_hdr_t ct;
3561 	uint32_t *rp;
3562 	uint8_t *scp = fcp->isp_scratch;
3563 
3564 	isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GID_FT via CT", chan);
3565 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
3566 		isp_prt(isp, ISP_LOGERR, sacq);
3567 		return (-1);
3568 	}
3569 
3570 	/*
3571 	 * Build the CT header and command in memory.
3572 	 */
3573 	ISP_MEMZERO(&ct, sizeof (ct));
3574 	ct.ct_revision = CT_REVISION;
3575 	ct.ct_fcs_type = CT_FC_TYPE_FC;
3576 	ct.ct_fcs_subtype = CT_FC_SUBTYPE_NS;
3577 	ct.ct_cmd_resp = SNS_GID_FT;
3578 	ct.ct_bcnt_resid = (GIDLEN - 16) >> 2;
3579 	isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp);
3580 	rp = (uint32_t *) &scp[sizeof(ct)];
3581 	ISP_IOZPUT_32(isp, FC4_SCSI, rp);
3582 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
3583 		isp_print_bytes(isp, "CT request",
3584 		    sizeof(ct) + sizeof(uint32_t), scp);
3585 	}
3586 
3587 	if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t), GIDLEN)) {
3588 		FC_SCRATCH_RELEASE(isp, chan);
3589 		return (-1);
3590 	}
3591 
3592 	if (isp->isp_dblev & ISP_LOGDEBUG1)
3593 		isp_print_bytes(isp, "CT response", GIDLEN, scp);
3594 	isp_get_gid_ft_response(isp, (sns_gid_ft_rsp_t *)scp,
3595 	    (sns_gid_ft_rsp_t *)fcp->isp_scanscratch, NGENT);
3596 	FC_SCRATCH_RELEASE(isp, chan);
3597 	return (0);
3598 }
3599 
3600 static int
isp_scan_fabric(ispsoftc_t * isp,int chan)3601 isp_scan_fabric(ispsoftc_t *isp, int chan)
3602 {
3603 	fcparam *fcp = FCPARAM(isp, chan);
3604 	fcportdb_t *lp;
3605 	uint32_t portid;
3606 	uint16_t nphdl;
3607 	isp_pdb_t pdb;
3608 	int portidx, portlim, r;
3609 	sns_gid_ft_rsp_t *rs;
3610 
3611 	if (fcp->isp_loopstate < LOOP_LSCAN_DONE)
3612 		return (-1);
3613 	if (fcp->isp_loopstate >= LOOP_FSCAN_DONE)
3614 		return (0);
3615 
3616 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC fabric scan", chan);
3617 	fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
3618 	if (!TOPO_IS_FABRIC(fcp->isp_topo)) {
3619 		fcp->isp_loopstate = LOOP_FSCAN_DONE;
3620 		isp_prt(isp, ISP_LOG_SANCFG,
3621 		    "Chan %d FC fabric scan done (no fabric)", chan);
3622 		return (0);
3623 	}
3624 
3625 	if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
3626 abort:
3627 		FC_SCRATCH_RELEASE(isp, chan);
3628 		isp_prt(isp, ISP_LOG_SANCFG,
3629 		    "Chan %d FC fabric scan aborted", chan);
3630 		return (1);
3631 	}
3632 
3633 	/*
3634 	 * Make sure we still are logged into the fabric controller.
3635 	 */
3636 	nphdl = IS_24XX(isp) ? NPH_FL_ID : FL_ID;
3637 	r = isp_getpdb(isp, chan, nphdl, &pdb);
3638 	if ((r & 0xffff) == MBOX_NOT_LOGGED_IN) {
3639 		isp_dump_chip_portdb(isp, chan);
3640 	}
3641 	if (r) {
3642 		fcp->isp_loopstate = LOOP_LTEST_DONE;
3643 fail:
3644 		isp_prt(isp, ISP_LOG_SANCFG,
3645 		    "Chan %d FC fabric scan done (bad)", chan);
3646 		return (-1);
3647 	}
3648 
3649 	/* Get list of port IDs from SNS. */
3650 	if (IS_24XX(isp))
3651 		r = isp_gid_ft_ct_passthru(isp, chan);
3652 	else
3653 		r = isp_gid_ft_sns(isp, chan);
3654 	if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
3655 		goto abort;
3656 	if (r > 0) {
3657 		fcp->isp_loopstate = LOOP_FSCAN_DONE;
3658 		return (-1);
3659 	} else if (r < 0) {
3660 		fcp->isp_loopstate = LOOP_LTEST_DONE;	/* try again */
3661 		return (-1);
3662 	}
3663 
3664 	rs = (sns_gid_ft_rsp_t *) fcp->isp_scanscratch;
3665 	if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
3666 		goto abort;
3667 	if (rs->snscb_cthdr.ct_cmd_resp != LS_ACC) {
3668 		int level;
3669 		if (rs->snscb_cthdr.ct_reason == 9 && rs->snscb_cthdr.ct_explanation == 7) {
3670 			level = ISP_LOG_SANCFG;
3671 		} else {
3672 			level = ISP_LOGWARN;
3673 		}
3674 		isp_prt(isp, level, "Chan %d Fabric Nameserver rejected GID_FT"
3675 		    " (Reason=0x%x Expl=0x%x)", chan,
3676 		    rs->snscb_cthdr.ct_reason,
3677 		    rs->snscb_cthdr.ct_explanation);
3678 		fcp->isp_loopstate = LOOP_FSCAN_DONE;
3679 		return (-1);
3680 	}
3681 
3682 	/* Check our buffer was big enough to get the full list. */
3683 	for (portidx = 0; portidx < NGENT-1; portidx++) {
3684 		if (rs->snscb_ports[portidx].control & 0x80)
3685 			break;
3686 	}
3687 	if ((rs->snscb_ports[portidx].control & 0x80) == 0) {
3688 		isp_prt(isp, ISP_LOGWARN,
3689 		    "fabric too big for scratch area: increase ISP_FC_SCRLEN");
3690 	}
3691 	portlim = portidx + 1;
3692 	isp_prt(isp, ISP_LOG_SANCFG,
3693 	    "Chan %d Got %d ports back from name server", chan, portlim);
3694 
3695 	/* Go through the list and remove duplicate port ids. */
3696 	for (portidx = 0; portidx < portlim; portidx++) {
3697 		int npidx;
3698 
3699 		portid =
3700 		    ((rs->snscb_ports[portidx].portid[0]) << 16) |
3701 		    ((rs->snscb_ports[portidx].portid[1]) << 8) |
3702 		    ((rs->snscb_ports[portidx].portid[2]));
3703 
3704 		for (npidx = portidx + 1; npidx < portlim; npidx++) {
3705 			uint32_t new_portid =
3706 			    ((rs->snscb_ports[npidx].portid[0]) << 16) |
3707 			    ((rs->snscb_ports[npidx].portid[1]) << 8) |
3708 			    ((rs->snscb_ports[npidx].portid[2]));
3709 			if (new_portid == portid) {
3710 				break;
3711 			}
3712 		}
3713 
3714 		if (npidx < portlim) {
3715 			rs->snscb_ports[npidx].portid[0] = 0;
3716 			rs->snscb_ports[npidx].portid[1] = 0;
3717 			rs->snscb_ports[npidx].portid[2] = 0;
3718 			isp_prt(isp, ISP_LOG_SANCFG, "Chan %d removing duplicate PortID 0x%06x entry from list", chan, portid);
3719 		}
3720 	}
3721 
3722 	/*
3723 	 * We now have a list of Port IDs for all FC4 SCSI devices
3724 	 * that the Fabric Name server knows about.
3725 	 *
3726 	 * For each entry on this list go through our port database looking
3727 	 * for probational entries- if we find one, then an old entry is
3728 	 * maybe still this one. We get some information to find out.
3729 	 *
3730 	 * Otherwise, it's a new fabric device, and we log into it
3731 	 * (unconditionally). After searching the entire database
3732 	 * again to make sure that we never ever ever ever have more
3733 	 * than one entry that has the same PortID or the same
3734 	 * WWNN/WWPN duple, we enter the device into our database.
3735 	 */
3736 	isp_mark_portdb(isp, chan);
3737 	for (portidx = 0; portidx < portlim; portidx++) {
3738 		portid = ((rs->snscb_ports[portidx].portid[0]) << 16) |
3739 			 ((rs->snscb_ports[portidx].portid[1]) << 8) |
3740 			 ((rs->snscb_ports[portidx].portid[2]));
3741 		isp_prt(isp, ISP_LOG_SANCFG,
3742 		    "Chan %d Checking fabric port 0x%06x", chan, portid);
3743 		if (portid == 0) {
3744 			isp_prt(isp, ISP_LOG_SANCFG,
3745 			    "Chan %d Port at idx %d is zero",
3746 			    chan, portidx);
3747 			continue;
3748 		}
3749 		if (portid == fcp->isp_portid) {
3750 			isp_prt(isp, ISP_LOG_SANCFG,
3751 			    "Chan %d Port 0x%06x is our", chan, portid);
3752 			continue;
3753 		}
3754 
3755 		/* Now search the entire port database for the same portid. */
3756 		if (isp_find_pdb_by_portid(isp, chan, portid, &lp)) {
3757 			if (!lp->probational) {
3758 				isp_prt(isp, ISP_LOGERR,
3759 				    "Chan %d Port 0x%06x@0x%04x [%d] is not probational (0x%x)",
3760 				    chan, lp->portid, lp->handle,
3761 				    FC_PORTDB_TGT(isp, chan, lp), lp->state);
3762 				isp_dump_portdb(isp, chan);
3763 				goto fail;
3764 			}
3765 
3766 			if (lp->state == FC_PORTDB_STATE_ZOMBIE)
3767 				goto relogin;
3768 
3769 			/*
3770 			 * See if we're still logged into it.
3771 			 *
3772 			 * If we aren't, mark it as a dead device and
3773 			 * leave the new portid in the database entry
3774 			 * for somebody further along to decide what to
3775 			 * do (policy choice).
3776 			 *
3777 			 * If we are, check to see if it's the same
3778 			 * device still (it should be). If for some
3779 			 * reason it isn't, mark it as a changed device
3780 			 * and leave the new portid and role in the
3781 			 * database entry for somebody further along to
3782 			 * decide what to do (policy choice).
3783 			 */
3784 			r = isp_getpdb(isp, chan, lp->handle, &pdb);
3785 			if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
3786 				goto abort;
3787 			if (r != 0) {
3788 				lp->state = FC_PORTDB_STATE_DEAD;
3789 				isp_prt(isp, ISP_LOG_SANCFG,
3790 				    "Chan %d Port 0x%06x handle 0x%x is dead (%d)",
3791 				    chan, portid, lp->handle, r);
3792 				goto relogin;
3793 			}
3794 
3795 			isp_pdb_add_update(isp, chan, &pdb);
3796 			continue;
3797 		}
3798 
3799 relogin:
3800 		if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
3801 			isp_prt(isp, ISP_LOG_SANCFG,
3802 			    "Chan %d Port 0x%06x is not logged in", chan, portid);
3803 			continue;
3804 		}
3805 
3806 		if (isp_login_device(isp, chan, portid, &pdb,
3807 		    &FCPARAM(isp, 0)->isp_lasthdl)) {
3808 			if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
3809 				goto abort;
3810 			continue;
3811 		}
3812 
3813 		isp_pdb_add_update(isp, chan, &pdb);
3814 	}
3815 
3816 	if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
3817 		goto abort;
3818 	fcp->isp_loopstate = LOOP_FSCAN_DONE;
3819 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC fabric scan done", chan);
3820 	return (0);
3821 }
3822 
3823 /*
3824  * Find an unused handle and try and use to login to a port.
3825  */
3826 static int
isp_login_device(ispsoftc_t * isp,int chan,uint32_t portid,isp_pdb_t * p,uint16_t * ohp)3827 isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p, uint16_t *ohp)
3828 {
3829 	int lim, i, r;
3830 	uint16_t handle;
3831 
3832 	if (ISP_CAP_2KLOGIN(isp)) {
3833 		lim = NPH_MAX_2K;
3834 	} else {
3835 		lim = NPH_MAX;
3836 	}
3837 
3838 	handle = isp_next_handle(isp, ohp);
3839 	for (i = 0; i < lim; i++) {
3840 		if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
3841 			return (-1);
3842 
3843 		/* Check if this handle is free. */
3844 		r = isp_getpdb(isp, chan, handle, p);
3845 		if (r == 0) {
3846 			if (p->portid != portid) {
3847 				/* This handle is busy, try next one. */
3848 				handle = isp_next_handle(isp, ohp);
3849 				continue;
3850 			}
3851 			break;
3852 		}
3853 		if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
3854 			return (-1);
3855 
3856 		/*
3857 		 * Now try and log into the device
3858 		 */
3859 		r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI);
3860 		if (r == 0) {
3861 			break;
3862 		} else if ((r & 0xffff) == MBOX_PORT_ID_USED) {
3863 			/*
3864 			 * If we get here, then the firmwware still thinks we're logged into this device, but with a different
3865 			 * handle. We need to break that association. We used to try and just substitute the handle, but then
3866 			 * failed to get any data via isp_getpdb (below).
3867 			 */
3868 			if (isp_plogx(isp, chan, r >> 16, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL)) {
3869 				isp_prt(isp, ISP_LOGERR, "baw... logout of %x failed", r >> 16);
3870 			}
3871 			if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
3872 				return (-1);
3873 			r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI);
3874 			if (r != 0)
3875 				i = lim;
3876 			break;
3877 		} else if ((r & 0xffff) == MBOX_LOOP_ID_USED) {
3878 			/* Try the next handle. */
3879 			handle = isp_next_handle(isp, ohp);
3880 		} else {
3881 			/* Give up. */
3882 			i = lim;
3883 			break;
3884 		}
3885 	}
3886 
3887 	if (i == lim) {
3888 		isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed", chan, portid);
3889 		return (-1);
3890 	}
3891 
3892 	/*
3893 	 * If we successfully logged into it, get the PDB for it
3894 	 * so we can crosscheck that it is still what we think it
3895 	 * is and that we also have the role it plays
3896 	 */
3897 	r = isp_getpdb(isp, chan, handle, p);
3898 	if (r != 0) {
3899 		isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x disappeared", chan, portid, handle);
3900 		return (-1);
3901 	}
3902 
3903 	if (p->handle != handle || p->portid != portid) {
3904 		isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
3905 		    chan, portid, handle, p->portid, p->handle);
3906 		return (-1);
3907 	}
3908 	return (0);
3909 }
3910 
3911 static int
isp_send_change_request(ispsoftc_t * isp,int chan)3912 isp_send_change_request(ispsoftc_t *isp, int chan)
3913 {
3914 	mbreg_t mbs;
3915 
3916 	MBSINIT(&mbs, MBOX_SEND_CHANGE_REQUEST, MBLOGALL, 500000);
3917 	mbs.param[1] = 0x03;
3918 	mbs.param[9] = chan;
3919 	isp_mboxcmd(isp, &mbs);
3920 	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
3921 		return (0);
3922 	} else {
3923 		isp_prt(isp, ISP_LOGWARN, "Chan %d Send Change Request: 0x%x",
3924 		    chan, mbs.param[0]);
3925 		return (-1);
3926 	}
3927 }
3928 
3929 static int
isp_register_fc4_type(ispsoftc_t * isp,int chan)3930 isp_register_fc4_type(ispsoftc_t *isp, int chan)
3931 {
3932 	fcparam *fcp = FCPARAM(isp, chan);
3933 	uint8_t local[SNS_RFT_ID_REQ_SIZE];
3934 	sns_screq_t *reqp = (sns_screq_t *) local;
3935 	mbreg_t mbs;
3936 
3937 	ISP_MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE);
3938 	reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1;
3939 	reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100);
3940 	reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100);
3941 	reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100);
3942 	reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100);
3943 	reqp->snscb_sblen = 22;
3944 	reqp->snscb_data[0] = SNS_RFT_ID;
3945 	reqp->snscb_data[4] = fcp->isp_portid & 0xffff;
3946 	reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff;
3947 	reqp->snscb_data[6] = (1 << FC4_SCSI);
3948 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
3949 		isp_prt(isp, ISP_LOGERR, sacq);
3950 		return (-1);
3951 	}
3952 	isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
3953 	MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 1000000);
3954 	mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1;
3955 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
3956 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
3957 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
3958 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
3959 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_RFT_ID_REQ_SIZE, chan);
3960 	isp_mboxcmd(isp, &mbs);
3961 	FC_SCRATCH_RELEASE(isp, chan);
3962 	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
3963 		return (0);
3964 	} else {
3965 		isp_prt(isp, ISP_LOGWARN, "Chan %d Register FC4 Type: 0x%x",
3966 		    chan, mbs.param[0]);
3967 		return (-1);
3968 	}
3969 }
3970 
3971 static int
isp_register_fc4_type_24xx(ispsoftc_t * isp,int chan)3972 isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan)
3973 {
3974 	fcparam *fcp = FCPARAM(isp, chan);
3975 	ct_hdr_t *ct;
3976 	rft_id_t rp;
3977 	uint8_t *scp = fcp->isp_scratch;
3978 
3979 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
3980 		isp_prt(isp, ISP_LOGERR, sacq);
3981 		return (-1);
3982 	}
3983 
3984 	/*
3985 	 * Build the CT header and command in memory.
3986 	 */
3987 	ISP_MEMZERO(&rp, sizeof(rp));
3988 	ct = &rp.rftid_hdr;
3989 	ct->ct_revision = CT_REVISION;
3990 	ct->ct_fcs_type = CT_FC_TYPE_FC;
3991 	ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
3992 	ct->ct_cmd_resp = SNS_RFT_ID;
3993 	ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2;
3994 	rp.rftid_portid[0] = fcp->isp_portid >> 16;
3995 	rp.rftid_portid[1] = fcp->isp_portid >> 8;
3996 	rp.rftid_portid[2] = fcp->isp_portid;
3997 	rp.rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f);
3998 	isp_put_rft_id(isp, &rp, (rft_id_t *)scp);
3999 	if (isp->isp_dblev & ISP_LOGDEBUG1)
4000 		isp_print_bytes(isp, "CT request", sizeof(rft_id_t), scp);
4001 
4002 	if (isp_ct_passthru(isp, chan, sizeof(rft_id_t), sizeof(ct_hdr_t))) {
4003 		FC_SCRATCH_RELEASE(isp, chan);
4004 		return (-1);
4005 	}
4006 
4007 	isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
4008 	FC_SCRATCH_RELEASE(isp, chan);
4009 	if (ct->ct_cmd_resp == LS_RJT) {
4010 		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1, "Chan %d Register FC4 Type rejected", chan);
4011 		return (-1);
4012 	} else if (ct->ct_cmd_resp == LS_ACC) {
4013 		isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Register FC4 Type accepted", chan);
4014 	} else {
4015 		isp_prt(isp, ISP_LOGWARN, "Chan %d Register FC4 Type: 0x%x", chan, ct->ct_cmd_resp);
4016 		return (-1);
4017 	}
4018 	return (0);
4019 }
4020 
4021 static int
isp_register_fc4_features_24xx(ispsoftc_t * isp,int chan)4022 isp_register_fc4_features_24xx(ispsoftc_t *isp, int chan)
4023 {
4024 	fcparam *fcp = FCPARAM(isp, chan);
4025 	ct_hdr_t *ct;
4026 	rff_id_t rp;
4027 	uint8_t *scp = fcp->isp_scratch;
4028 
4029 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4030 		isp_prt(isp, ISP_LOGERR, sacq);
4031 		return (-1);
4032 	}
4033 
4034 	/*
4035 	 * Build the CT header and command in memory.
4036 	 */
4037 	ISP_MEMZERO(&rp, sizeof(rp));
4038 	ct = &rp.rffid_hdr;
4039 	ct->ct_revision = CT_REVISION;
4040 	ct->ct_fcs_type = CT_FC_TYPE_FC;
4041 	ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
4042 	ct->ct_cmd_resp = SNS_RFF_ID;
4043 	ct->ct_bcnt_resid = (sizeof (rff_id_t) - sizeof (ct_hdr_t)) >> 2;
4044 	rp.rffid_portid[0] = fcp->isp_portid >> 16;
4045 	rp.rffid_portid[1] = fcp->isp_portid >> 8;
4046 	rp.rffid_portid[2] = fcp->isp_portid;
4047 	rp.rffid_fc4features = 0;
4048 	if (fcp->role & ISP_ROLE_TARGET)
4049 		rp.rffid_fc4features |= 1;
4050 	if (fcp->role & ISP_ROLE_INITIATOR)
4051 		rp.rffid_fc4features |= 2;
4052 	rp.rffid_fc4type = FC4_SCSI;
4053 	isp_put_rff_id(isp, &rp, (rff_id_t *)scp);
4054 	if (isp->isp_dblev & ISP_LOGDEBUG1)
4055 		isp_print_bytes(isp, "CT request", sizeof(rft_id_t), scp);
4056 
4057 	if (isp_ct_passthru(isp, chan, sizeof(rft_id_t), sizeof(ct_hdr_t))) {
4058 		FC_SCRATCH_RELEASE(isp, chan);
4059 		return (-1);
4060 	}
4061 
4062 	isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
4063 	FC_SCRATCH_RELEASE(isp, chan);
4064 	if (ct->ct_cmd_resp == LS_RJT) {
4065 		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
4066 		    "Chan %d Register FC4 Features rejected", chan);
4067 		return (-1);
4068 	} else if (ct->ct_cmd_resp == LS_ACC) {
4069 		isp_prt(isp, ISP_LOG_SANCFG,
4070 		    "Chan %d Register FC4 Features accepted", chan);
4071 	} else {
4072 		isp_prt(isp, ISP_LOGWARN,
4073 		    "Chan %d Register FC4 Features: 0x%x", chan, ct->ct_cmd_resp);
4074 		return (-1);
4075 	}
4076 	return (0);
4077 }
4078 
4079 static int
isp_register_port_name_24xx(ispsoftc_t * isp,int chan)4080 isp_register_port_name_24xx(ispsoftc_t *isp, int chan)
4081 {
4082 	fcparam *fcp = FCPARAM(isp, chan);
4083 	ct_hdr_t *ct;
4084 	rspn_id_t rp;
4085 	uint8_t *scp = fcp->isp_scratch;
4086 	int len;
4087 
4088 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4089 		isp_prt(isp, ISP_LOGERR, sacq);
4090 		return (-1);
4091 	}
4092 
4093 	/*
4094 	 * Build the CT header and command in memory.
4095 	 */
4096 	ISP_MEMZERO(&rp, sizeof(rp));
4097 	ct = &rp.rspnid_hdr;
4098 	ct->ct_revision = CT_REVISION;
4099 	ct->ct_fcs_type = CT_FC_TYPE_FC;
4100 	ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
4101 	ct->ct_cmd_resp = SNS_RSPN_ID;
4102 	rp.rspnid_portid[0] = fcp->isp_portid >> 16;
4103 	rp.rspnid_portid[1] = fcp->isp_portid >> 8;
4104 	rp.rspnid_portid[2] = fcp->isp_portid;
4105 	rp.rspnid_length = 0;
4106 	len = offsetof(rspn_id_t, rspnid_name);
4107 	mtx_lock(&prison0.pr_mtx);
4108 	rp.rspnid_length += sprintf(&scp[len + rp.rspnid_length],
4109 	    "%s", prison0.pr_hostname[0] ? prison0.pr_hostname : "FreeBSD");
4110 	mtx_unlock(&prison0.pr_mtx);
4111 	rp.rspnid_length += sprintf(&scp[len + rp.rspnid_length],
4112 	    ":%s", device_get_nameunit(isp->isp_dev));
4113 	if (chan != 0) {
4114 		rp.rspnid_length += sprintf(&scp[len + rp.rspnid_length],
4115 		    "/%d", chan);
4116 	}
4117 	len += rp.rspnid_length;
4118 	ct->ct_bcnt_resid = (len - sizeof(ct_hdr_t)) >> 2;
4119 	isp_put_rspn_id(isp, &rp, (rspn_id_t *)scp);
4120 	if (isp->isp_dblev & ISP_LOGDEBUG1)
4121 		isp_print_bytes(isp, "CT request", len, scp);
4122 
4123 	if (isp_ct_passthru(isp, chan, len, sizeof(ct_hdr_t))) {
4124 		FC_SCRATCH_RELEASE(isp, chan);
4125 		return (-1);
4126 	}
4127 
4128 	isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
4129 	FC_SCRATCH_RELEASE(isp, chan);
4130 	if (ct->ct_cmd_resp == LS_RJT) {
4131 		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
4132 		    "Chan %d Register Symbolic Port Name rejected", chan);
4133 		return (-1);
4134 	} else if (ct->ct_cmd_resp == LS_ACC) {
4135 		isp_prt(isp, ISP_LOG_SANCFG,
4136 		    "Chan %d Register Symbolic Port Name accepted", chan);
4137 	} else {
4138 		isp_prt(isp, ISP_LOGWARN,
4139 		    "Chan %d Register Symbolic Port Name: 0x%x", chan, ct->ct_cmd_resp);
4140 		return (-1);
4141 	}
4142 	return (0);
4143 }
4144 
4145 static int
isp_register_node_name_24xx(ispsoftc_t * isp,int chan)4146 isp_register_node_name_24xx(ispsoftc_t *isp, int chan)
4147 {
4148 	fcparam *fcp = FCPARAM(isp, chan);
4149 	ct_hdr_t *ct;
4150 	rsnn_nn_t rp;
4151 	uint8_t *scp = fcp->isp_scratch;
4152 	int len;
4153 
4154 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4155 		isp_prt(isp, ISP_LOGERR, sacq);
4156 		return (-1);
4157 	}
4158 
4159 	/*
4160 	 * Build the CT header and command in memory.
4161 	 */
4162 	ISP_MEMZERO(&rp, sizeof(rp));
4163 	ct = &rp.rsnnnn_hdr;
4164 	ct->ct_revision = CT_REVISION;
4165 	ct->ct_fcs_type = CT_FC_TYPE_FC;
4166 	ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
4167 	ct->ct_cmd_resp = SNS_RSNN_NN;
4168 	MAKE_NODE_NAME_FROM_WWN(rp.rsnnnn_nodename, fcp->isp_wwnn);
4169 	rp.rsnnnn_length = 0;
4170 	len = offsetof(rsnn_nn_t, rsnnnn_name);
4171 	mtx_lock(&prison0.pr_mtx);
4172 	rp.rsnnnn_length += sprintf(&scp[len + rp.rsnnnn_length],
4173 	    "%s", prison0.pr_hostname[0] ? prison0.pr_hostname : "FreeBSD");
4174 	mtx_unlock(&prison0.pr_mtx);
4175 	len += rp.rsnnnn_length;
4176 	ct->ct_bcnt_resid = (len - sizeof(ct_hdr_t)) >> 2;
4177 	isp_put_rsnn_nn(isp, &rp, (rsnn_nn_t *)scp);
4178 	if (isp->isp_dblev & ISP_LOGDEBUG1)
4179 		isp_print_bytes(isp, "CT request", len, scp);
4180 
4181 	if (isp_ct_passthru(isp, chan, len, sizeof(ct_hdr_t))) {
4182 		FC_SCRATCH_RELEASE(isp, chan);
4183 		return (-1);
4184 	}
4185 
4186 	isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
4187 	FC_SCRATCH_RELEASE(isp, chan);
4188 	if (ct->ct_cmd_resp == LS_RJT) {
4189 		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
4190 		    "Chan %d Register Symbolic Node Name rejected", chan);
4191 		return (-1);
4192 	} else if (ct->ct_cmd_resp == LS_ACC) {
4193 		isp_prt(isp, ISP_LOG_SANCFG,
4194 		    "Chan %d Register Symbolic Node Name accepted", chan);
4195 	} else {
4196 		isp_prt(isp, ISP_LOGWARN,
4197 		    "Chan %d Register Symbolic Node Name: 0x%x", chan, ct->ct_cmd_resp);
4198 		return (-1);
4199 	}
4200 	return (0);
4201 }
4202 
4203 static uint16_t
isp_next_handle(ispsoftc_t * isp,uint16_t * ohp)4204 isp_next_handle(ispsoftc_t *isp, uint16_t *ohp)
4205 {
4206 	fcparam *fcp;
4207 	int i, chan, wrap;
4208 	uint16_t handle, minh, maxh;
4209 
4210 	handle = *ohp;
4211 	if (ISP_CAP_2KLOGIN(isp)) {
4212 		minh = 0;
4213 		maxh = NPH_RESERVED - 1;
4214 	} else {
4215 		minh = SNS_ID + 1;
4216 		maxh = NPH_MAX - 1;
4217 	}
4218 	wrap = 0;
4219 
4220 next:
4221 	if (handle == NIL_HANDLE) {
4222 		handle = minh;
4223 	} else {
4224 		handle++;
4225 		if (handle > maxh) {
4226 			if (++wrap >= 2) {
4227 				isp_prt(isp, ISP_LOGERR, "Out of port handles!");
4228 				return (NIL_HANDLE);
4229 			}
4230 			handle = minh;
4231 		}
4232 	}
4233 	for (chan = 0; chan < isp->isp_nchan; chan++) {
4234 		fcp = FCPARAM(isp, chan);
4235 		if (fcp->role == ISP_ROLE_NONE)
4236 			continue;
4237 		for (i = 0; i < MAX_FC_TARG; i++) {
4238 			if (fcp->portdb[i].state != FC_PORTDB_STATE_NIL &&
4239 			    fcp->portdb[i].handle == handle)
4240 				goto next;
4241 		}
4242 	}
4243 	*ohp = handle;
4244 	return (handle);
4245 }
4246 
4247 /*
4248  * Start a command. Locking is assumed done in the caller.
4249  */
4250 
4251 int
isp_start(XS_T * xs)4252 isp_start(XS_T *xs)
4253 {
4254 	ispsoftc_t *isp;
4255 	uint32_t cdblen;
4256 	uint8_t local[QENTRY_LEN];
4257 	ispreq_t *reqp;
4258 	void *cdbp, *qep;
4259 	uint16_t *tptr;
4260 	fcportdb_t *lp;
4261 	int target, dmaresult;
4262 
4263 	XS_INITERR(xs);
4264 	isp = XS_ISP(xs);
4265 
4266 	/*
4267 	 * Check command CDB length, etc.. We really are limited to 16 bytes
4268 	 * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
4269 	 * but probably only if we're running fairly new firmware (we'll
4270 	 * let the old f/w choke on an extended command queue entry).
4271 	 */
4272 
4273 	if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) {
4274 		isp_prt(isp, ISP_LOGERR, "unsupported cdb length (%d, CDB[0]=0x%x)", XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
4275 		XS_SETERR(xs, HBA_REQINVAL);
4276 		return (CMD_COMPLETE);
4277 	}
4278 
4279 	/*
4280 	 * Translate the target to device handle as appropriate, checking
4281 	 * for correct device state as well.
4282 	 */
4283 	target = XS_TGT(xs);
4284 	if (IS_FC(isp)) {
4285 		fcparam *fcp = FCPARAM(isp, XS_CHANNEL(xs));
4286 
4287 		if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
4288 			isp_prt(isp, ISP_LOG_WARN1,
4289 			    "%d.%d.%jx I am not an initiator",
4290 			    XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
4291 			XS_SETERR(xs, HBA_SELTIMEOUT);
4292 			return (CMD_COMPLETE);
4293 		}
4294 
4295 		if (isp->isp_state != ISP_RUNSTATE) {
4296 			isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
4297 			XS_SETERR(xs, HBA_BOTCH);
4298 			return (CMD_COMPLETE);
4299 		}
4300 
4301 		isp_prt(isp, ISP_LOGDEBUG2, "XS_TGT(xs)=%d", target);
4302 		lp = &fcp->portdb[target];
4303 		if (target < 0 || target >= MAX_FC_TARG ||
4304 		    lp->is_target == 0) {
4305 			XS_SETERR(xs, HBA_SELTIMEOUT);
4306 			return (CMD_COMPLETE);
4307 		}
4308 		if (fcp->isp_loopstate != LOOP_READY) {
4309 			isp_prt(isp, ISP_LOGDEBUG1,
4310 			    "%d.%d.%jx loop is not ready",
4311 			    XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
4312 			return (CMD_RQLATER);
4313 		}
4314 		if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
4315 			isp_prt(isp, ISP_LOGDEBUG1,
4316 			    "%d.%d.%jx target zombie",
4317 			    XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
4318 			return (CMD_RQLATER);
4319 		}
4320 		if (lp->state != FC_PORTDB_STATE_VALID) {
4321 			isp_prt(isp, ISP_LOGDEBUG1,
4322 			    "%d.%d.%jx bad db port state 0x%x",
4323 			    XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs), lp->state);
4324 			XS_SETERR(xs, HBA_SELTIMEOUT);
4325 			return (CMD_COMPLETE);
4326 		}
4327 	} else {
4328 		sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
4329 		if (isp->isp_state != ISP_RUNSTATE) {
4330 			isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
4331 			XS_SETERR(xs, HBA_BOTCH);
4332 			return (CMD_COMPLETE);
4333 		}
4334 
4335 		if (sdp->update) {
4336 			isp_spi_update(isp, XS_CHANNEL(xs));
4337 		}
4338 		lp = NULL;
4339 	}
4340 
4341  start_again:
4342 
4343 	qep = isp_getrqentry(isp);
4344 	if (qep == NULL) {
4345 		isp_prt(isp, ISP_LOG_WARN1, "Request Queue Overflow");
4346 		XS_SETERR(xs, HBA_BOTCH);
4347 		return (CMD_EAGAIN);
4348 	}
4349 	XS_SETERR(xs, HBA_NOERROR);
4350 
4351 	/*
4352 	 * Now see if we need to synchronize the ISP with respect to anything.
4353 	 * We do dual duty here (cough) for synchronizing for busses other
4354 	 * than which we got here to send a command to.
4355 	 */
4356 	reqp = (ispreq_t *) local;
4357 	ISP_MEMZERO(local, QENTRY_LEN);
4358 	if (ISP_TST_SENDMARKER(isp, XS_CHANNEL(xs))) {
4359 		if (IS_24XX(isp)) {
4360 			isp_marker_24xx_t *m = (isp_marker_24xx_t *) reqp;
4361 			m->mrk_header.rqs_entry_count = 1;
4362 			m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
4363 			m->mrk_modifier = SYNC_ALL;
4364 			m->mrk_vphdl = XS_CHANNEL(xs);
4365 			isp_put_marker_24xx(isp, m, qep);
4366 		} else {
4367 			isp_marker_t *m = (isp_marker_t *) reqp;
4368 			m->mrk_header.rqs_entry_count = 1;
4369 			m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
4370 			m->mrk_target = (XS_CHANNEL(xs) << 7);	/* bus # */
4371 			m->mrk_modifier = SYNC_ALL;
4372 			isp_put_marker(isp, m, qep);
4373 		}
4374 		ISP_SYNC_REQUEST(isp);
4375 		ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 0);
4376 		goto start_again;
4377 	}
4378 
4379 	reqp->req_header.rqs_entry_count = 1;
4380 
4381 	/*
4382 	 * Select and install Header Code.
4383 	 * Note that it might be overridden before going out
4384 	 * if we're on a 64 bit platform. The lower level
4385 	 * code (isp_send_cmd) will select the appropriate
4386 	 * 64 bit variant if it needs to.
4387 	 */
4388 	if (IS_24XX(isp)) {
4389 		reqp->req_header.rqs_entry_type = RQSTYPE_T7RQS;
4390 	} else if (IS_FC(isp)) {
4391 		reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
4392 	} else {
4393 		if (XS_CDBLEN(xs) > 12) {
4394 			reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY;
4395 		} else {
4396 			reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
4397 		}
4398 	}
4399 
4400 	/*
4401 	 * Set task attributes
4402 	 */
4403 	if (IS_24XX(isp)) {
4404 		int ttype;
4405 		if (XS_TAG_P(xs)) {
4406 			ttype = XS_TAG_TYPE(xs);
4407 		} else {
4408 			ttype = REQFLAG_STAG;
4409 		}
4410 		if (ttype == REQFLAG_OTAG) {
4411 			ttype = FCP_CMND_TASK_ATTR_ORDERED;
4412 		} else if (ttype == REQFLAG_HTAG) {
4413 			ttype = FCP_CMND_TASK_ATTR_HEAD;
4414 		} else {
4415 			ttype = FCP_CMND_TASK_ATTR_SIMPLE;
4416 		}
4417 		((ispreqt7_t *)reqp)->req_task_attribute = ttype;
4418 	} else if (IS_FC(isp)) {
4419 		/*
4420 		 * See comment in isp_intr_respq
4421 		 */
4422 		/* XS_SET_RESID(xs, 0); */
4423 
4424 		/*
4425 		 * Fibre Channel always requires some kind of tag.
4426 		 * The Qlogic drivers seem be happy not to use a tag,
4427 		 * but this breaks for some devices (IBM drives).
4428 		 */
4429 		if (XS_TAG_P(xs)) {
4430 			((ispreqt2_t *)reqp)->req_flags = XS_TAG_TYPE(xs);
4431 		} else {
4432 			((ispreqt2_t *)reqp)->req_flags = REQFLAG_STAG;
4433 		}
4434 	} else {
4435 		sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
4436 		if ((sdp->isp_devparam[target].actv_flags & DPARM_TQING) && XS_TAG_P(xs)) {
4437 			reqp->req_flags = XS_TAG_TYPE(xs);
4438 		}
4439 	}
4440 
4441 	/*
4442 	 * NB: we do not support long CDBs (yet)
4443 	 */
4444 	cdblen = XS_CDBLEN(xs);
4445 
4446 	if (IS_SCSI(isp)) {
4447 		if (cdblen > sizeof (reqp->req_cdb)) {
4448 			isp_prt(isp, ISP_LOGERR, "Command Length %u too long for this chip", cdblen);
4449 			XS_SETERR(xs, HBA_REQINVAL);
4450 			return (CMD_COMPLETE);
4451 		}
4452 		reqp->req_target = target | (XS_CHANNEL(xs) << 7);
4453 		reqp->req_lun_trn = XS_LUN(xs);
4454 		reqp->req_cdblen = cdblen;
4455 		tptr = &reqp->req_time;
4456 		cdbp = reqp->req_cdb;
4457 	} else if (IS_24XX(isp)) {
4458 		ispreqt7_t *t7 = (ispreqt7_t *)local;
4459 
4460 		if (cdblen > sizeof (t7->req_cdb)) {
4461 			isp_prt(isp, ISP_LOGERR, "Command Length %u too long for this chip", cdblen);
4462 			XS_SETERR(xs, HBA_REQINVAL);
4463 			return (CMD_COMPLETE);
4464 		}
4465 
4466 		t7->req_nphdl = lp->handle;
4467 		t7->req_tidlo = lp->portid;
4468 		t7->req_tidhi = lp->portid >> 16;
4469 		t7->req_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(xs));
4470 		be64enc(t7->req_lun, CAM_EXTLUN_BYTE_SWIZZLE(XS_LUN(xs)));
4471 		if (FCPARAM(isp, XS_CHANNEL(xs))->fctape_enabled && (lp->prli_word3 & PRLI_WD3_RETRY)) {
4472 			if (FCP_NEXT_CRN(isp, &t7->req_crn, xs)) {
4473 				isp_prt(isp, ISP_LOG_WARN1,
4474 				    "%d.%d.%jx cannot generate next CRN",
4475 				    XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
4476 				XS_SETERR(xs, HBA_BOTCH);
4477 				return (CMD_EAGAIN);
4478 			}
4479 		}
4480 		tptr = &t7->req_time;
4481 		cdbp = t7->req_cdb;
4482 	} else {
4483 		ispreqt2_t *t2 = (ispreqt2_t *)local;
4484 
4485 		if (cdblen > sizeof t2->req_cdb) {
4486 			isp_prt(isp, ISP_LOGERR, "Command Length %u too long for this chip", cdblen);
4487 			XS_SETERR(xs, HBA_REQINVAL);
4488 			return (CMD_COMPLETE);
4489 		}
4490 		if (FCPARAM(isp, XS_CHANNEL(xs))->fctape_enabled && (lp->prli_word3 & PRLI_WD3_RETRY)) {
4491 			if (FCP_NEXT_CRN(isp, &t2->req_crn, xs)) {
4492 				isp_prt(isp, ISP_LOG_WARN1,
4493 				    "%d.%d.%jx cannot generate next CRN",
4494 				    XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
4495 				XS_SETERR(xs, HBA_BOTCH);
4496 				return (CMD_EAGAIN);
4497 			}
4498 		}
4499 		if (ISP_CAP_2KLOGIN(isp)) {
4500 			ispreqt2e_t *t2e = (ispreqt2e_t *)local;
4501 			t2e->req_target = lp->handle;
4502 			t2e->req_scclun = XS_LUN(xs);
4503 			tptr = &t2e->req_time;
4504 			cdbp = t2e->req_cdb;
4505 		} else if (ISP_CAP_SCCFW(isp)) {
4506 			t2->req_target = lp->handle;
4507 			t2->req_scclun = XS_LUN(xs);
4508 			tptr = &t2->req_time;
4509 			cdbp = t2->req_cdb;
4510 		} else {
4511 			t2->req_target = lp->handle;
4512 			t2->req_lun_trn = XS_LUN(xs);
4513 			tptr = &t2->req_time;
4514 			cdbp = t2->req_cdb;
4515 		}
4516 	}
4517 	*tptr = XS_TIME(xs);
4518 	ISP_MEMCPY(cdbp, XS_CDBP(xs), cdblen);
4519 
4520 	/* Whew. Thankfully the same for type 7 requests */
4521 	reqp->req_handle = isp_allocate_handle(isp, xs, ISP_HANDLE_INITIATOR);
4522 	if (reqp->req_handle == 0) {
4523 		isp_prt(isp, ISP_LOG_WARN1, "out of xflist pointers");
4524 		XS_SETERR(xs, HBA_BOTCH);
4525 		return (CMD_EAGAIN);
4526 	}
4527 
4528 	/*
4529 	 * Set up DMA and/or do any platform dependent swizzling of the request entry
4530 	 * so that the Qlogic F/W understands what is being asked of it.
4531 	 *
4532 	 * The callee is responsible for adding all requests at this point.
4533 	 */
4534 	dmaresult = ISP_DMASETUP(isp, xs, reqp);
4535 	if (dmaresult != CMD_QUEUED) {
4536 		isp_destroy_handle(isp, reqp->req_handle);
4537 		/*
4538 		 * dmasetup sets actual error in packet, and
4539 		 * return what we were given to return.
4540 		 */
4541 		return (dmaresult);
4542 	}
4543 	isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "START cmd cdb[0]=0x%x datalen %ld", XS_CDBP(xs)[0], (long) XS_XFRLEN(xs));
4544 	return (CMD_QUEUED);
4545 }
4546 
4547 /*
4548  * isp control
4549  * Locks (ints blocked) assumed held.
4550  */
4551 
4552 int
isp_control(ispsoftc_t * isp,ispctl_t ctl,...)4553 isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
4554 {
4555 	XS_T *xs;
4556 	mbreg_t *mbr, mbs;
4557 	int chan, tgt;
4558 	uint32_t handle;
4559 	va_list ap;
4560 
4561 	switch (ctl) {
4562 	case ISPCTL_RESET_BUS:
4563 		/*
4564 		 * Issue a bus reset.
4565 		 */
4566 		if (IS_24XX(isp)) {
4567 			isp_prt(isp, ISP_LOGERR, "BUS RESET NOT IMPLEMENTED");
4568 			break;
4569 		} else if (IS_FC(isp)) {
4570 			mbs.param[1] = 10;
4571 			chan = 0;
4572 		} else {
4573 			va_start(ap, ctl);
4574 			chan = va_arg(ap, int);
4575 			va_end(ap);
4576 			mbs.param[1] = SDPARAM(isp, chan)->isp_bus_reset_delay;
4577 			if (mbs.param[1] < 2) {
4578 				mbs.param[1] = 2;
4579 			}
4580 			mbs.param[2] = chan;
4581 		}
4582 		MBSINIT(&mbs, MBOX_BUS_RESET, MBLOGALL, 0);
4583 		ISP_SET_SENDMARKER(isp, chan, 1);
4584 		isp_mboxcmd(isp, &mbs);
4585 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4586 			break;
4587 		}
4588 		isp_prt(isp, ISP_LOGINFO, "driver initiated bus reset of bus %d", chan);
4589 		return (0);
4590 
4591 	case ISPCTL_RESET_DEV:
4592 		va_start(ap, ctl);
4593 		chan = va_arg(ap, int);
4594 		tgt = va_arg(ap, int);
4595 		va_end(ap);
4596 		if (IS_24XX(isp)) {
4597 			uint8_t local[QENTRY_LEN];
4598 			isp24xx_tmf_t *tmf;
4599 			isp24xx_statusreq_t *sp;
4600 			fcparam *fcp = FCPARAM(isp, chan);
4601 			fcportdb_t *lp;
4602 
4603 			if (tgt < 0 || tgt >= MAX_FC_TARG) {
4604 				isp_prt(isp, ISP_LOGWARN, "Chan %d trying to reset bad target %d", chan, tgt);
4605 				break;
4606 			}
4607 			lp = &fcp->portdb[tgt];
4608 			if (lp->is_target == 0 ||
4609 			    lp->state != FC_PORTDB_STATE_VALID) {
4610 				isp_prt(isp, ISP_LOGWARN, "Chan %d abort of no longer valid target %d", chan, tgt);
4611 				break;
4612 			}
4613 
4614 			tmf = (isp24xx_tmf_t *) local;
4615 			ISP_MEMZERO(tmf, QENTRY_LEN);
4616 			tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
4617 			tmf->tmf_header.rqs_entry_count = 1;
4618 			tmf->tmf_nphdl = lp->handle;
4619 			tmf->tmf_delay = 2;
4620 			tmf->tmf_timeout = 4;
4621 			tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET;
4622 			tmf->tmf_tidlo = lp->portid;
4623 			tmf->tmf_tidhi = lp->portid >> 16;
4624 			tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan);
4625 			isp_put_24xx_tmf(isp, tmf, isp->isp_iocb);
4626 			if (isp->isp_dblev & ISP_LOGDEBUG1)
4627 				isp_print_bytes(isp, "TMF IOCB request", QENTRY_LEN, isp->isp_iocb);
4628 			MEMORYBARRIER(isp, SYNC_IFORDEV, 0, QENTRY_LEN, chan);
4629 			fcp->sendmarker = 1;
4630 
4631 			isp_prt(isp, ISP_LOGALL, "Chan %d Reset N-Port Handle 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
4632 			MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL,
4633 			    MBCMD_DEFAULT_TIMEOUT + tmf->tmf_timeout * 1000000);
4634 			mbs.param[1] = QENTRY_LEN;
4635 			mbs.param[2] = DMA_WD1(isp->isp_iocb_dma);
4636 			mbs.param[3] = DMA_WD0(isp->isp_iocb_dma);
4637 			mbs.param[6] = DMA_WD3(isp->isp_iocb_dma);
4638 			mbs.param[7] = DMA_WD2(isp->isp_iocb_dma);
4639 			isp_mboxcmd(isp, &mbs);
4640 			if (mbs.param[0] != MBOX_COMMAND_COMPLETE)
4641 				break;
4642 
4643 			MEMORYBARRIER(isp, SYNC_IFORCPU, QENTRY_LEN, QENTRY_LEN, chan);
4644 			if (isp->isp_dblev & ISP_LOGDEBUG1)
4645 				isp_print_bytes(isp, "TMF IOCB response", QENTRY_LEN, &((isp24xx_statusreq_t *)isp->isp_iocb)[1]);
4646 			sp = (isp24xx_statusreq_t *) local;
4647 			isp_get_24xx_response(isp, &((isp24xx_statusreq_t *)isp->isp_iocb)[1], sp);
4648 			if (sp->req_completion_status == 0) {
4649 				return (0);
4650 			}
4651 			isp_prt(isp, ISP_LOGWARN, "Chan %d reset of target %d returned 0x%x", chan, tgt, sp->req_completion_status);
4652 			break;
4653 		} else if (IS_FC(isp)) {
4654 			if (ISP_CAP_2KLOGIN(isp)) {
4655 				mbs.param[1] = tgt;
4656 				mbs.ibits = (1 << 10);
4657 			} else {
4658 				mbs.param[1] = (tgt << 8);
4659 			}
4660 		} else {
4661 			mbs.param[1] = (chan << 15) | (tgt << 8);
4662 		}
4663 		MBSINIT(&mbs, MBOX_ABORT_TARGET, MBLOGALL, 0);
4664 		mbs.param[2] = 3;	/* 'delay', in seconds */
4665 		isp_mboxcmd(isp, &mbs);
4666 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4667 			break;
4668 		}
4669 		isp_prt(isp, ISP_LOGINFO, "Target %d on Bus %d Reset Succeeded", tgt, chan);
4670 		ISP_SET_SENDMARKER(isp, chan, 1);
4671 		return (0);
4672 
4673 	case ISPCTL_ABORT_CMD:
4674 		va_start(ap, ctl);
4675 		xs = va_arg(ap, XS_T *);
4676 		va_end(ap);
4677 
4678 		tgt = XS_TGT(xs);
4679 		chan = XS_CHANNEL(xs);
4680 
4681 		handle = isp_find_handle(isp, xs);
4682 		if (handle == 0) {
4683 			isp_prt(isp, ISP_LOGWARN, "cannot find handle for command to abort");
4684 			break;
4685 		}
4686 		if (IS_24XX(isp)) {
4687 			isp24xx_abrt_t local, *ab = &local;
4688 			fcparam *fcp;
4689 			fcportdb_t *lp;
4690 
4691 			fcp = FCPARAM(isp, chan);
4692 			if (tgt < 0 || tgt >= MAX_FC_TARG) {
4693 				isp_prt(isp, ISP_LOGWARN, "Chan %d trying to abort bad target %d", chan, tgt);
4694 				break;
4695 			}
4696 			lp = &fcp->portdb[tgt];
4697 			if (lp->is_target == 0 ||
4698 			    lp->state != FC_PORTDB_STATE_VALID) {
4699 				isp_prt(isp, ISP_LOGWARN, "Chan %d abort of no longer valid target %d", chan, tgt);
4700 				break;
4701 			}
4702 			isp_prt(isp, ISP_LOGALL, "Chan %d Abort Cmd for N-Port 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
4703 			ISP_MEMZERO(ab, QENTRY_LEN);
4704 			ab->abrt_header.rqs_entry_type = RQSTYPE_ABORT_IO;
4705 			ab->abrt_header.rqs_entry_count = 1;
4706 			ab->abrt_handle = lp->handle;
4707 			ab->abrt_cmd_handle = handle;
4708 			ab->abrt_tidlo = lp->portid;
4709 			ab->abrt_tidhi = lp->portid >> 16;
4710 			ab->abrt_vpidx = ISP_GET_VPIDX(isp, chan);
4711 			isp_put_24xx_abrt(isp, ab, isp->isp_iocb);
4712 			if (isp->isp_dblev & ISP_LOGDEBUG1)
4713 				isp_print_bytes(isp, "AB IOCB quest", QENTRY_LEN, isp->isp_iocb);
4714 			MEMORYBARRIER(isp, SYNC_IFORDEV, 0, 2 * QENTRY_LEN, chan);
4715 
4716 			ISP_MEMZERO(&mbs, sizeof (mbs));
4717 			MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
4718 			mbs.param[1] = QENTRY_LEN;
4719 			mbs.param[2] = DMA_WD1(isp->isp_iocb_dma);
4720 			mbs.param[3] = DMA_WD0(isp->isp_iocb_dma);
4721 			mbs.param[6] = DMA_WD3(isp->isp_iocb_dma);
4722 			mbs.param[7] = DMA_WD2(isp->isp_iocb_dma);
4723 
4724 			isp_mboxcmd(isp, &mbs);
4725 			if (mbs.param[0] != MBOX_COMMAND_COMPLETE)
4726 				break;
4727 
4728 			MEMORYBARRIER(isp, SYNC_IFORCPU, QENTRY_LEN, QENTRY_LEN, chan);
4729 			if (isp->isp_dblev & ISP_LOGDEBUG1)
4730 				isp_print_bytes(isp, "AB IOCB response", QENTRY_LEN, &((isp24xx_abrt_t *)isp->isp_iocb)[1]);
4731 			isp_get_24xx_abrt(isp, &((isp24xx_abrt_t *)isp->isp_iocb)[1], ab);
4732 			if (ab->abrt_nphdl == ISP24XX_ABRT_OKAY) {
4733 				return (0);
4734 			}
4735 			isp_prt(isp, ISP_LOGWARN, "Chan %d handle %d abort returned 0x%x", chan, tgt, ab->abrt_nphdl);
4736 			break;
4737 		} else if (IS_FC(isp)) {
4738 			if (ISP_CAP_SCCFW(isp)) {
4739 				if (ISP_CAP_2KLOGIN(isp)) {
4740 					mbs.param[1] = tgt;
4741 				} else {
4742 					mbs.param[1] = tgt << 8;
4743 				}
4744 				mbs.param[6] = XS_LUN(xs);
4745 			} else {
4746 				mbs.param[1] = tgt << 8 | XS_LUN(xs);
4747 			}
4748 		} else {
4749 			mbs.param[1] = (chan << 15) | (tgt << 8) | XS_LUN(xs);
4750 		}
4751 		MBSINIT(&mbs, MBOX_ABORT,
4752 		    MBLOGALL & ~MBLOGMASK(MBOX_COMMAND_ERROR), 0);
4753 		mbs.param[2] = handle;
4754 		isp_mboxcmd(isp, &mbs);
4755 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4756 			break;
4757 		}
4758 		return (0);
4759 
4760 	case ISPCTL_UPDATE_PARAMS:
4761 
4762 		va_start(ap, ctl);
4763 		chan = va_arg(ap, int);
4764 		va_end(ap);
4765 		isp_spi_update(isp, chan);
4766 		return (0);
4767 
4768 	case ISPCTL_FCLINK_TEST:
4769 
4770 		if (IS_FC(isp)) {
4771 			int usdelay;
4772 			va_start(ap, ctl);
4773 			chan = va_arg(ap, int);
4774 			usdelay = va_arg(ap, int);
4775 			va_end(ap);
4776 			if (usdelay == 0) {
4777 				usdelay =  250000;
4778 			}
4779 			return (isp_fclink_test(isp, chan, usdelay));
4780 		}
4781 		break;
4782 
4783 	case ISPCTL_SCAN_FABRIC:
4784 
4785 		if (IS_FC(isp)) {
4786 			va_start(ap, ctl);
4787 			chan = va_arg(ap, int);
4788 			va_end(ap);
4789 			return (isp_scan_fabric(isp, chan));
4790 		}
4791 		break;
4792 
4793 	case ISPCTL_SCAN_LOOP:
4794 
4795 		if (IS_FC(isp)) {
4796 			va_start(ap, ctl);
4797 			chan = va_arg(ap, int);
4798 			va_end(ap);
4799 			return (isp_scan_loop(isp, chan));
4800 		}
4801 		break;
4802 
4803 	case ISPCTL_PDB_SYNC:
4804 
4805 		if (IS_FC(isp)) {
4806 			va_start(ap, ctl);
4807 			chan = va_arg(ap, int);
4808 			va_end(ap);
4809 			return (isp_pdb_sync(isp, chan));
4810 		}
4811 		break;
4812 
4813 	case ISPCTL_SEND_LIP:
4814 
4815 		if (IS_FC(isp) && !IS_24XX(isp)) {
4816 			MBSINIT(&mbs, MBOX_INIT_LIP, MBLOGALL, 0);
4817 			if (ISP_CAP_2KLOGIN(isp)) {
4818 				mbs.ibits = (1 << 10);
4819 			}
4820 			isp_mboxcmd(isp, &mbs);
4821 			if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
4822 				return (0);
4823 			}
4824 		}
4825 		break;
4826 
4827 	case ISPCTL_GET_PDB:
4828 		if (IS_FC(isp)) {
4829 			isp_pdb_t *pdb;
4830 			va_start(ap, ctl);
4831 			chan = va_arg(ap, int);
4832 			tgt = va_arg(ap, int);
4833 			pdb = va_arg(ap, isp_pdb_t *);
4834 			va_end(ap);
4835 			return (isp_getpdb(isp, chan, tgt, pdb));
4836 		}
4837 		break;
4838 
4839 	case ISPCTL_GET_NAMES:
4840 	{
4841 		uint64_t *wwnn, *wwnp;
4842 		va_start(ap, ctl);
4843 		chan = va_arg(ap, int);
4844 		tgt = va_arg(ap, int);
4845 		wwnn = va_arg(ap, uint64_t *);
4846 		wwnp = va_arg(ap, uint64_t *);
4847 		va_end(ap);
4848 		if (wwnn == NULL && wwnp == NULL) {
4849 			break;
4850 		}
4851 		if (wwnn) {
4852 			*wwnn = isp_get_wwn(isp, chan, tgt, 1);
4853 			if (*wwnn == INI_NONE) {
4854 				break;
4855 			}
4856 		}
4857 		if (wwnp) {
4858 			*wwnp = isp_get_wwn(isp, chan, tgt, 0);
4859 			if (*wwnp == INI_NONE) {
4860 				break;
4861 			}
4862 		}
4863 		return (0);
4864 	}
4865 	case ISPCTL_RUN_MBOXCMD:
4866 	{
4867 		va_start(ap, ctl);
4868 		mbr = va_arg(ap, mbreg_t *);
4869 		va_end(ap);
4870 		isp_mboxcmd(isp, mbr);
4871 		return (0);
4872 	}
4873 	case ISPCTL_PLOGX:
4874 	{
4875 		isp_plcmd_t *p;
4876 		int r;
4877 
4878 		va_start(ap, ctl);
4879 		p = va_arg(ap, isp_plcmd_t *);
4880 		va_end(ap);
4881 
4882 		if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI || (p->handle != NIL_HANDLE)) {
4883 			return (isp_plogx(isp, p->channel, p->handle, p->portid, p->flags));
4884 		}
4885 		do {
4886 			isp_next_handle(isp, &p->handle);
4887 			r = isp_plogx(isp, p->channel, p->handle, p->portid, p->flags);
4888 			if ((r & 0xffff) == MBOX_PORT_ID_USED) {
4889 				p->handle = r >> 16;
4890 				r = 0;
4891 				break;
4892 			}
4893 		} while ((r & 0xffff) == MBOX_LOOP_ID_USED);
4894 		return (r);
4895 	}
4896 	case ISPCTL_CHANGE_ROLE:
4897 		if (IS_FC(isp)) {
4898 			int role, r;
4899 
4900 			va_start(ap, ctl);
4901 			chan = va_arg(ap, int);
4902 			role = va_arg(ap, int);
4903 			va_end(ap);
4904 			r = isp_fc_change_role(isp, chan, role);
4905 			return (r);
4906 		}
4907 		break;
4908 	default:
4909 		isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
4910 		break;
4911 
4912 	}
4913 	return (-1);
4914 }
4915 
4916 /*
4917  * Interrupt Service Routine(s).
4918  *
4919  * External (OS) framework has done the appropriate locking,
4920  * and the locking will be held throughout this function.
4921  */
4922 
4923 #ifdef	ISP_TARGET_MODE
4924 void
isp_intr_atioq(ispsoftc_t * isp)4925 isp_intr_atioq(ispsoftc_t *isp)
4926 {
4927 	uint8_t qe[QENTRY_LEN];
4928 	isphdr_t *hp;
4929 	void *addr;
4930 	uint32_t iptr, optr, oop;
4931 
4932 	iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP);
4933 	optr = isp->isp_atioodx;
4934 	while (optr != iptr) {
4935 		oop = optr;
4936 		MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN, -1);
4937 		addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop);
4938 		isp_get_hdr(isp, addr, (isphdr_t *)qe);
4939 		hp = (isphdr_t *)qe;
4940 		switch (hp->rqs_entry_type) {
4941 		case RQSTYPE_NOTIFY:
4942 		case RQSTYPE_ATIO:
4943 			(void) isp_target_notify(isp, addr, &oop);
4944 			break;
4945 		default:
4946 			isp_print_qentry(isp, "?ATIOQ entry?", oop, addr);
4947 			break;
4948 		}
4949 		optr = ISP_NXT_QENTRY(oop, RESULT_QUEUE_LEN(isp));
4950 	}
4951 	if (isp->isp_atioodx != optr) {
4952 		ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr);
4953 		isp->isp_atioodx = optr;
4954 	}
4955 }
4956 #endif
4957 
4958 void
isp_intr_async(ispsoftc_t * isp,uint16_t event)4959 isp_intr_async(ispsoftc_t *isp, uint16_t event)
4960 {
4961 
4962 	if (IS_FC(isp))
4963 		isp_parse_async_fc(isp, event);
4964 	else
4965 		isp_parse_async(isp, event);
4966 }
4967 
4968 void
isp_intr_mbox(ispsoftc_t * isp,uint16_t mbox0)4969 isp_intr_mbox(ispsoftc_t *isp, uint16_t mbox0)
4970 {
4971 	int i, obits;
4972 
4973 	if (!isp->isp_mboxbsy) {
4974 		isp_prt(isp, ISP_LOGWARN, "mailbox 0x%x with no waiters", mbox0);
4975 		return;
4976 	}
4977 	obits = isp->isp_obits;
4978 	isp->isp_mboxtmp[0] = mbox0;
4979 	for (i = 1; i < ISP_NMBOX(isp); i++) {
4980 		if ((obits & (1 << i)) == 0)
4981 			continue;
4982 		isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i));
4983 	}
4984 	MBOX_NOTIFY_COMPLETE(isp);
4985 }
4986 
4987 void
isp_intr_respq(ispsoftc_t * isp)4988 isp_intr_respq(ispsoftc_t *isp)
4989 {
4990 	XS_T *xs, *cont_xs;
4991 	uint8_t qe[QENTRY_LEN];
4992 	ispstatusreq_t *sp = (ispstatusreq_t *)qe;
4993 	isp24xx_statusreq_t *sp2 = (isp24xx_statusreq_t *)qe;
4994 	isphdr_t *hp;
4995 	uint8_t *resp, *snsp;
4996 	int buddaboom, completion_status, cont = 0, etype, i;
4997 	int req_status_flags, req_state_flags, scsi_status;
4998 	uint32_t iptr, junk, cptr, optr, rlen, slen, sptr, totslen, resid;
4999 
5000 	/*
5001 	 * We can't be getting this now.
5002 	 */
5003 	if (isp->isp_state != ISP_RUNSTATE) {
5004 		isp_prt(isp, ISP_LOGINFO, "respq interrupt when not ready");
5005 		return;
5006 	}
5007 
5008 	iptr = ISP_READ(isp, isp->isp_respinrp);
5009 	/* Debounce the 2300 if revision less than 2. */
5010 	if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) {
5011 		do {
5012 			junk = iptr;
5013 			iptr = ISP_READ(isp, isp->isp_respinrp);
5014 		} while (junk != iptr);
5015 	}
5016 	isp->isp_residx = iptr;
5017 
5018 	optr = isp->isp_resodx;
5019 	while (optr != iptr) {
5020 		sptr = cptr = optr;
5021 		hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, cptr);
5022 		optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
5023 
5024 		/*
5025 		 * Synchronize our view of this response queue entry.
5026 		 */
5027 		MEMORYBARRIER(isp, SYNC_RESULT, cptr, QENTRY_LEN, -1);
5028 		if (isp->isp_dblev & ISP_LOGDEBUG1)
5029 			isp_print_qentry(isp, "Response Queue Entry", cptr, hp);
5030 		isp_get_hdr(isp, hp, &sp->req_header);
5031 		etype = sp->req_header.rqs_entry_type;
5032 
5033 		/* We expected Status Continuation, but got different IOCB. */
5034 		if (cont > 0 && etype != RQSTYPE_STATUS_CONT) {
5035 			cont = 0;
5036 			isp_done(cont_xs);
5037 		}
5038 
5039 		if (IS_24XX(isp) && etype == RQSTYPE_RESPONSE) {
5040 			isp_get_24xx_response(isp, (isp24xx_statusreq_t *)hp, sp2);
5041 			scsi_status = sp2->req_scsi_status;
5042 			completion_status = sp2->req_completion_status;
5043 			req_status_flags = 0;
5044 			if ((scsi_status & 0xff) != 0)
5045 				req_state_flags = RQSF_GOT_STATUS;
5046 			else
5047 				req_state_flags = 0;
5048 			resid = sp2->req_resid;
5049 		} else if (etype == RQSTYPE_RESPONSE) {
5050 			isp_get_response(isp, (ispstatusreq_t *) hp, sp);
5051 			scsi_status = sp->req_scsi_status;
5052 			completion_status = sp->req_completion_status;
5053 			req_status_flags = sp->req_status_flags;
5054 			req_state_flags = sp->req_state_flags;
5055 			resid = sp->req_resid;
5056 		} else if (etype == RQSTYPE_RIO1) {
5057 			isp_rio1_t *rio = (isp_rio1_t *) qe;
5058 			isp_get_rio1(isp, (isp_rio1_t *) hp, rio);
5059 			for (i = 0; i < rio->req_header.rqs_seqno; i++) {
5060 				isp_fastpost_complete(isp, rio->req_handles[i]);
5061 			}
5062 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5063 			continue;
5064 		} else if (etype == RQSTYPE_RIO2) {
5065 			isp_prt(isp, ISP_LOGERR, "dropping RIO2 response");
5066 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5067 			continue;
5068 		} else if (etype == RQSTYPE_STATUS_CONT) {
5069 			ispstatus_cont_t *scp = (ispstatus_cont_t *)qe;
5070 			isp_get_cont_response(isp, (ispstatus_cont_t *)hp, scp);
5071 			if (cont > 0) {
5072 				i = min(cont, sizeof(scp->req_sense_data));
5073 				XS_SENSE_APPEND(cont_xs, scp->req_sense_data, i);
5074 				cont -= i;
5075 				if (cont == 0) {
5076 					isp_done(cont_xs);
5077 				} else {
5078 					isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN,
5079 					    "Expecting Status Continuations for %u bytes",
5080 					    cont);
5081 				}
5082 			} else {
5083 				isp_prt(isp, ISP_LOG_WARN1, "Ignored Continuation Response");
5084 			}
5085 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5086 			continue;
5087 		} else if (isp_handle_other_response(isp, etype, hp, &cptr)) {
5088 			/* More then one IOCB could be consumed. */
5089 			while (sptr != cptr) {
5090 				ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5091 				sptr = ISP_NXT_QENTRY(sptr, RESULT_QUEUE_LEN(isp));
5092 				hp = (isphdr_t *)ISP_QUEUE_ENTRY(isp->isp_result, sptr);
5093 			}
5094 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5095 			optr = ISP_NXT_QENTRY(cptr, RESULT_QUEUE_LEN(isp));
5096 			continue;
5097 		} else {
5098 			/* We don't know what was this -- log and skip. */
5099 			isp_prt(isp, ISP_LOGERR, notresp, etype, cptr, optr);
5100 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5101 			continue;
5102 		}
5103 
5104 		buddaboom = 0;
5105 		if (sp->req_header.rqs_flags & RQSFLAG_MASK) {
5106 			if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
5107 				isp_print_qentry(isp, "unexpected continuation segment",
5108 				    cptr, hp);
5109 				continue;
5110 			}
5111 			if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
5112 				isp_prt(isp, ISP_LOG_WARN1, "internal queues full");
5113 				/*
5114 				 * We'll synthesize a QUEUE FULL message below.
5115 				 */
5116 			}
5117 			if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
5118 				isp_print_qentry(isp, "bad header flag",
5119 				    cptr, hp);
5120 				buddaboom++;
5121 			}
5122 			if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
5123 				isp_print_qentry(isp, "bad request packet",
5124 				    cptr, hp);
5125 				buddaboom++;
5126 			}
5127 			if (sp->req_header.rqs_flags & RQSFLAG_BADCOUNT) {
5128 				isp_print_qentry(isp, "invalid entry count",
5129 				    cptr, hp);
5130 				buddaboom++;
5131 			}
5132 			if (sp->req_header.rqs_flags & RQSFLAG_BADORDER) {
5133 				isp_print_qentry(isp, "invalid IOCB ordering",
5134 				    cptr, hp);
5135 				continue;
5136 			}
5137 		}
5138 
5139 		xs = isp_find_xs(isp, sp->req_handle);
5140 		if (xs == NULL) {
5141 			uint8_t ts = completion_status & 0xff;
5142 			/*
5143 			 * Only whine if this isn't the expected fallout of
5144 			 * aborting the command or resetting the target.
5145 			 */
5146 			if (etype != RQSTYPE_RESPONSE) {
5147 				isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (type 0x%x)", sp->req_handle, etype);
5148 			} else if (ts != RQCS_ABORTED && ts != RQCS_RESET_OCCURRED) {
5149 				isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (status 0x%x)", sp->req_handle, ts);
5150 			}
5151 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5152 			continue;
5153 		}
5154 		if (req_status_flags & RQSTF_BUS_RESET) {
5155 			isp_prt(isp, ISP_LOG_WARN1, "%d.%d.%jx bus was reset",
5156 			    XS_CHANNEL(xs), XS_TGT(xs), (uintmax_t)XS_LUN(xs));
5157 			XS_SETERR(xs, HBA_BUSRESET);
5158 			ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1);
5159 		}
5160 		if (buddaboom) {
5161 			isp_prt(isp, ISP_LOG_WARN1, "%d.%d.%jx buddaboom",
5162 			    XS_CHANNEL(xs), XS_TGT(xs), (uintmax_t)XS_LUN(xs));
5163 			XS_SETERR(xs, HBA_BOTCH);
5164 		}
5165 
5166 		resp = snsp = NULL;
5167 		rlen = slen = totslen = 0;
5168 		if (IS_24XX(isp) && (scsi_status & (RQCS_RV|RQCS_SV)) != 0) {
5169 			resp = sp2->req_rsp_sense;
5170 			rlen = sp2->req_response_len;
5171 		} else if (IS_FC(isp) && (scsi_status & RQCS_RV) != 0) {
5172 			resp = sp->req_response;
5173 			rlen = sp->req_response_len;
5174 		}
5175 		if (IS_FC(isp) && (scsi_status & RQCS_SV) != 0) {
5176 			/*
5177 			 * Fibre Channel F/W doesn't say we got status
5178 			 * if there's Sense Data instead. I guess they
5179 			 * think it goes w/o saying.
5180 			 */
5181 			req_state_flags |= RQSF_GOT_STATUS|RQSF_GOT_SENSE;
5182 			if (IS_24XX(isp)) {
5183 				snsp = sp2->req_rsp_sense;
5184 				snsp += rlen;
5185 				totslen = sp2->req_sense_len;
5186 				slen = sizeof(sp2->req_rsp_sense) - rlen;
5187 			} else {
5188 				snsp = sp->req_sense_data;
5189 				totslen = sp->req_sense_len;
5190 				slen = sizeof(sp->req_sense_data);
5191 			}
5192 		} else if (IS_SCSI(isp) && (req_state_flags & RQSF_GOT_SENSE)) {
5193 			snsp = sp->req_sense_data;
5194 			totslen = sp->req_sense_len;
5195 			slen = sizeof (sp->req_sense_data);
5196 		}
5197 		if (slen > totslen)
5198 			slen = totslen;
5199 		if (req_state_flags & RQSF_GOT_STATUS)
5200 			*XS_STSP(xs) = scsi_status & 0xff;
5201 
5202 		if (rlen >= 4 && resp[FCP_RSPNS_CODE_OFFSET] != 0) {
5203 			const char *ptr;
5204 			char lb[64];
5205 			const char *rnames[10] = {
5206 			    "Task Management function complete",
5207 			    "FCP_DATA length different than FCP_BURST_LEN",
5208 			    "FCP_CMND fields invalid",
5209 			    "FCP_DATA parameter mismatch with FCP_DATA_RO",
5210 			    "Task Management function rejected",
5211 			    "Task Management function failed",
5212 			    NULL,
5213 			    NULL,
5214 			    "Task Management function succeeded",
5215 			    "Task Management function incorrect logical unit number",
5216 			};
5217 			uint8_t code = resp[FCP_RSPNS_CODE_OFFSET];
5218 			if (code >= 10 || rnames[code] == NULL) {
5219 				ISP_SNPRINTF(lb, sizeof(lb),
5220 				    "Unknown FCP Response Code 0x%x", code);
5221 				ptr = lb;
5222 			} else {
5223 				ptr = rnames[code];
5224 			}
5225 			isp_xs_prt(isp, xs, ISP_LOGWARN,
5226 			    "FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x",
5227 			    rlen, ptr, XS_CDBP(xs)[0] & 0xff);
5228 			if (code != 0 && code != 8)
5229 				XS_SETERR(xs, HBA_BOTCH);
5230 		}
5231 		if (IS_24XX(isp))
5232 			isp_parse_status_24xx(isp, sp2, xs, &resid);
5233 		else
5234 			isp_parse_status(isp, sp, xs, &resid);
5235 		if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) &&
5236 		    (*XS_STSP(xs) == SCSI_BUSY))
5237 			XS_SETERR(xs, HBA_TGTBSY);
5238 		if (IS_SCSI(isp)) {
5239 			XS_SET_RESID(xs, resid);
5240 			/*
5241 			 * A new synchronous rate was negotiated for
5242 			 * this target. Mark state such that we'll go
5243 			 * look up that which has changed later.
5244 			 */
5245 			if (req_status_flags & RQSTF_NEGOTIATION) {
5246 				int t = XS_TGT(xs);
5247 				sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
5248 				sdp->isp_devparam[t].dev_refresh = 1;
5249 				sdp->update = 1;
5250 			}
5251 		} else {
5252 			if (req_status_flags & RQSF_XFER_COMPLETE) {
5253 				XS_SET_RESID(xs, 0);
5254 			} else if (scsi_status & RQCS_RESID) {
5255 				XS_SET_RESID(xs, resid);
5256 			} else {
5257 				XS_SET_RESID(xs, 0);
5258 			}
5259 		}
5260 		if (slen > 0) {
5261 			XS_SAVE_SENSE(xs, snsp, slen);
5262 			if (totslen > slen) {
5263 				cont = totslen - slen;
5264 				cont_xs = xs;
5265 				isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN,
5266 				    "Expecting Status Continuations for %u bytes",
5267 				    cont);
5268 			}
5269 		}
5270 		isp_prt(isp, ISP_LOGDEBUG2, "asked for %lu got raw resid %lu settled for %lu",
5271 		    (u_long)XS_XFRLEN(xs), (u_long)resid, (u_long)XS_GET_RESID(xs));
5272 
5273 		if (XS_XFRLEN(xs))
5274 			ISP_DMAFREE(isp, xs, sp->req_handle);
5275 		isp_destroy_handle(isp, sp->req_handle);
5276 
5277 		ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5278 
5279 		/* Complete command if we expect no Status Continuations. */
5280 		if (cont == 0)
5281 			isp_done(xs);
5282 	}
5283 
5284 	/* We haven't received all Status Continuations, but that is it. */
5285 	if (cont > 0)
5286 		isp_done(cont_xs);
5287 
5288 	/* If we processed any IOCBs, let ISP know about it. */
5289 	if (optr != isp->isp_resodx) {
5290 		ISP_WRITE(isp, isp->isp_respoutrp, optr);
5291 		isp->isp_resodx = optr;
5292 	}
5293 }
5294 
5295 /*
5296  * Parse an ASYNC mailbox complete
5297  */
5298 static void
isp_parse_async(ispsoftc_t * isp,uint16_t mbox)5299 isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
5300 {
5301 	uint32_t h1 = 0, h2 = 0;
5302 	uint16_t chan = 0;
5303 
5304 	/*
5305 	 * Pick up the channel, but not if this is a ASYNC_RIO32_2,
5306 	 * where Mailboxes 6/7 have the second handle.
5307 	 */
5308 	if (mbox != ASYNC_RIO32_2) {
5309 		if (IS_DUALBUS(isp)) {
5310 			chan = ISP_READ(isp, OUTMAILBOX6);
5311 		}
5312 	}
5313 	isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
5314 
5315 	switch (mbox) {
5316 	case ASYNC_BUS_RESET:
5317 		ISP_SET_SENDMARKER(isp, chan, 1);
5318 #ifdef	ISP_TARGET_MODE
5319 		isp_target_async(isp, chan, mbox);
5320 #endif
5321 		isp_async(isp, ISPASYNC_BUS_RESET, chan);
5322 		break;
5323 	case ASYNC_SYSTEM_ERROR:
5324 		isp->isp_state = ISP_CRASHED;
5325 		/*
5326 		 * Were we waiting for a mailbox command to complete?
5327 		 * If so, it's dead, so wake up the waiter.
5328 		 */
5329 		if (isp->isp_mboxbsy) {
5330 			isp->isp_obits = 1;
5331 			isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
5332 			MBOX_NOTIFY_COMPLETE(isp);
5333 		}
5334 		/*
5335 		 * It's up to the handler for isp_async to reinit stuff and
5336 		 * restart the firmware
5337 		 */
5338 		isp_async(isp, ISPASYNC_FW_CRASH);
5339 		break;
5340 
5341 	case ASYNC_RQS_XFER_ERR:
5342 		isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
5343 		break;
5344 
5345 	case ASYNC_RSP_XFER_ERR:
5346 		isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
5347 		break;
5348 
5349 	case ASYNC_QWAKEUP:
5350 		/*
5351 		 * We've just been notified that the Queue has woken up.
5352 		 * We don't need to be chatty about this- just unlatch things
5353 		 * and move on.
5354 		 */
5355 		mbox = ISP_READ(isp, isp->isp_rqstoutrp);
5356 		break;
5357 
5358 	case ASYNC_TIMEOUT_RESET:
5359 		isp_prt(isp, ISP_LOGWARN, "timeout initiated SCSI bus reset of chan %d", chan);
5360 		ISP_SET_SENDMARKER(isp, chan, 1);
5361 #ifdef	ISP_TARGET_MODE
5362 		isp_target_async(isp, chan, mbox);
5363 #endif
5364 		break;
5365 
5366 	case ASYNC_DEVICE_RESET:
5367 		isp_prt(isp, ISP_LOGINFO, "device reset on chan %d", chan);
5368 		ISP_SET_SENDMARKER(isp, chan, 1);
5369 #ifdef	ISP_TARGET_MODE
5370 		isp_target_async(isp, chan, mbox);
5371 #endif
5372 		break;
5373 
5374 	case ASYNC_EXTMSG_UNDERRUN:
5375 		isp_prt(isp, ISP_LOGWARN, "extended message underrun");
5376 		break;
5377 
5378 	case ASYNC_SCAM_INT:
5379 		isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
5380 		break;
5381 
5382 	case ASYNC_HUNG_SCSI:
5383 		isp_prt(isp, ISP_LOGERR, "stalled SCSI Bus after DATA Overrun");
5384 		/* XXX: Need to issue SCSI reset at this point */
5385 		break;
5386 
5387 	case ASYNC_KILLED_BUS:
5388 		isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
5389 		break;
5390 
5391 	case ASYNC_BUS_TRANSIT:
5392 		mbox = ISP_READ(isp, OUTMAILBOX2);
5393 		switch (mbox & SXP_PINS_MODE_MASK) {
5394 		case SXP_PINS_LVD_MODE:
5395 			isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
5396 			SDPARAM(isp, chan)->isp_diffmode = 0;
5397 			SDPARAM(isp, chan)->isp_ultramode = 0;
5398 			SDPARAM(isp, chan)->isp_lvdmode = 1;
5399 			break;
5400 		case SXP_PINS_HVD_MODE:
5401 			isp_prt(isp, ISP_LOGINFO,
5402 			    "Transition to Differential mode");
5403 			SDPARAM(isp, chan)->isp_diffmode = 1;
5404 			SDPARAM(isp, chan)->isp_ultramode = 0;
5405 			SDPARAM(isp, chan)->isp_lvdmode = 0;
5406 			break;
5407 		case SXP_PINS_SE_MODE:
5408 			isp_prt(isp, ISP_LOGINFO,
5409 			    "Transition to Single Ended mode");
5410 			SDPARAM(isp, chan)->isp_diffmode = 0;
5411 			SDPARAM(isp, chan)->isp_ultramode = 1;
5412 			SDPARAM(isp, chan)->isp_lvdmode = 0;
5413 			break;
5414 		default:
5415 			isp_prt(isp, ISP_LOGWARN,
5416 			    "Transition to Unknown Mode 0x%x", mbox);
5417 			break;
5418 		}
5419 		/*
5420 		 * XXX: Set up to renegotiate again!
5421 		 */
5422 		/* Can only be for a 1080... */
5423 		ISP_SET_SENDMARKER(isp, chan, 1);
5424 		break;
5425 
5426 	case ASYNC_CMD_CMPLT:
5427 	case ASYNC_RIO32_1:
5428 		if (!IS_ULTRA3(isp)) {
5429 			isp_prt(isp, ISP_LOGERR, "unexpected fast posting completion");
5430 			break;
5431 		}
5432 		/* FALLTHROUGH */
5433 		h1 = (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1);
5434 		break;
5435 
5436 	case ASYNC_RIO32_2:
5437 		h1 = (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1);
5438 		h2 = (ISP_READ(isp, OUTMAILBOX7) << 16) | ISP_READ(isp, OUTMAILBOX6);
5439 		break;
5440 
5441 	case ASYNC_RIO16_5:
5442 	case ASYNC_RIO16_4:
5443 	case ASYNC_RIO16_3:
5444 	case ASYNC_RIO16_2:
5445 	case ASYNC_RIO16_1:
5446 		isp_prt(isp, ISP_LOGERR, "unexpected 16 bit RIO handle");
5447 		break;
5448 	default:
5449 		isp_prt(isp, ISP_LOGWARN, "%s: unhandled async code 0x%x", __func__, mbox);
5450 		break;
5451 	}
5452 
5453 	if (h1 || h2) {
5454 		isp_prt(isp, ISP_LOGDEBUG3, "fast post/rio completion of 0x%08x", h1);
5455 		isp_fastpost_complete(isp, h1);
5456 		if (h2) {
5457 			isp_prt(isp, ISP_LOGDEBUG3, "fast post/rio completion of 0x%08x", h2);
5458 			isp_fastpost_complete(isp, h2);
5459 		}
5460 	}
5461 }
5462 
5463 static void
isp_parse_async_fc(ispsoftc_t * isp,uint16_t mbox)5464 isp_parse_async_fc(ispsoftc_t *isp, uint16_t mbox)
5465 {
5466 	fcparam *fcp;
5467 	uint16_t chan;
5468 
5469 	if (IS_DUALBUS(isp)) {
5470 		chan = ISP_READ(isp, OUTMAILBOX6);
5471 	} else {
5472 		chan = 0;
5473 	}
5474 	isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
5475 
5476 	switch (mbox) {
5477 	case ASYNC_SYSTEM_ERROR:
5478 		isp->isp_state = ISP_CRASHED;
5479 		FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL;
5480 		isp_change_fw_state(isp, chan, FW_CONFIG_WAIT);
5481 		/*
5482 		 * Were we waiting for a mailbox command to complete?
5483 		 * If so, it's dead, so wake up the waiter.
5484 		 */
5485 		if (isp->isp_mboxbsy) {
5486 			isp->isp_obits = 1;
5487 			isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
5488 			MBOX_NOTIFY_COMPLETE(isp);
5489 		}
5490 		/*
5491 		 * It's up to the handler for isp_async to reinit stuff and
5492 		 * restart the firmware
5493 		 */
5494 		isp_async(isp, ISPASYNC_FW_CRASH);
5495 		break;
5496 
5497 	case ASYNC_RQS_XFER_ERR:
5498 		isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
5499 		break;
5500 
5501 	case ASYNC_RSP_XFER_ERR:
5502 		isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
5503 		break;
5504 
5505 	case ASYNC_QWAKEUP:
5506 #ifdef	ISP_TARGET_MODE
5507 		if (IS_24XX(isp)) {
5508 			isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error");
5509 			break;
5510 		}
5511 #endif
5512 		isp_prt(isp, ISP_LOGERR, "%s: unexpected ASYNC_QWAKEUP code", __func__);
5513 		break;
5514 
5515 	case ASYNC_CMD_CMPLT:
5516 		isp_fastpost_complete(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1));
5517 		break;
5518 
5519 	case ASYNC_RIOZIO_STALL:
5520 		isp_intr_respq(isp);
5521 		break;
5522 
5523 	case ASYNC_CTIO_DONE:
5524 #ifdef	ISP_TARGET_MODE
5525 		isp_target_async(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) |
5526 		    ISP_READ(isp, OUTMAILBOX1), mbox);
5527 #else
5528 		isp_prt(isp, ISP_LOGWARN, "unexpected ASYNC CTIO done");
5529 #endif
5530 		break;
5531 	case ASYNC_LIP_ERROR:
5532 	case ASYNC_LIP_NOS_OLS_RECV:
5533 	case ASYNC_LIP_OCCURRED:
5534 	case ASYNC_PTPMODE:
5535 		/*
5536 		 * These are broadcast events that have to be sent across
5537 		 * all active channels.
5538 		 */
5539 		for (chan = 0; chan < isp->isp_nchan; chan++) {
5540 			fcp = FCPARAM(isp, chan);
5541 			int topo = fcp->isp_topo;
5542 
5543 			if (fcp->role == ISP_ROLE_NONE)
5544 				continue;
5545 			if (fcp->isp_loopstate > LOOP_HAVE_LINK)
5546 				fcp->isp_loopstate = LOOP_HAVE_LINK;
5547 			ISP_SET_SENDMARKER(isp, chan, 1);
5548 			isp_async(isp, ISPASYNC_LIP, chan);
5549 #ifdef	ISP_TARGET_MODE
5550 			isp_target_async(isp, chan, mbox);
5551 #endif
5552 			/*
5553 			 * We've had problems with data corruption occuring on
5554 			 * commands that complete (with no apparent error) after
5555 			 * we receive a LIP. This has been observed mostly on
5556 			 * Local Loop topologies. To be safe, let's just mark
5557 			 * all active initiator commands as dead.
5558 			 */
5559 			if (topo == TOPO_NL_PORT || topo == TOPO_FL_PORT) {
5560 				int i, j;
5561 				for (i = j = 0; i < isp->isp_maxcmds; i++) {
5562 					XS_T *xs;
5563 					isp_hdl_t *hdp;
5564 
5565 					hdp = &isp->isp_xflist[i];
5566 					if (ISP_H2HT(hdp->handle) != ISP_HANDLE_INITIATOR) {
5567 						continue;
5568 					}
5569 					xs = hdp->cmd;
5570 					if (XS_CHANNEL(xs) != chan) {
5571 						continue;
5572 					}
5573 					j++;
5574 					isp_prt(isp, ISP_LOG_WARN1,
5575 					    "%d.%d.%jx bus reset set at %s:%u",
5576 					    XS_CHANNEL(xs), XS_TGT(xs),
5577 					    (uintmax_t)XS_LUN(xs),
5578 					    __func__, __LINE__);
5579 					XS_SETERR(xs, HBA_BUSRESET);
5580 				}
5581 				if (j) {
5582 					isp_prt(isp, ISP_LOGERR, lipd, chan, j);
5583 				}
5584 			}
5585 		}
5586 		break;
5587 
5588 	case ASYNC_LOOP_UP:
5589 		/*
5590 		 * This is a broadcast event that has to be sent across
5591 		 * all active channels.
5592 		 */
5593 		for (chan = 0; chan < isp->isp_nchan; chan++) {
5594 			fcp = FCPARAM(isp, chan);
5595 			if (fcp->role == ISP_ROLE_NONE)
5596 				continue;
5597 			fcp->isp_linkstate = 1;
5598 			if (fcp->isp_loopstate < LOOP_HAVE_LINK)
5599 				fcp->isp_loopstate = LOOP_HAVE_LINK;
5600 			ISP_SET_SENDMARKER(isp, chan, 1);
5601 			isp_async(isp, ISPASYNC_LOOP_UP, chan);
5602 #ifdef	ISP_TARGET_MODE
5603 			isp_target_async(isp, chan, mbox);
5604 #endif
5605 		}
5606 		break;
5607 
5608 	case ASYNC_LOOP_DOWN:
5609 		/*
5610 		 * This is a broadcast event that has to be sent across
5611 		 * all active channels.
5612 		 */
5613 		for (chan = 0; chan < isp->isp_nchan; chan++) {
5614 			fcp = FCPARAM(isp, chan);
5615 			if (fcp->role == ISP_ROLE_NONE)
5616 				continue;
5617 			ISP_SET_SENDMARKER(isp, chan, 1);
5618 			fcp->isp_linkstate = 0;
5619 			fcp->isp_loopstate = LOOP_NIL;
5620 			isp_async(isp, ISPASYNC_LOOP_DOWN, chan);
5621 #ifdef	ISP_TARGET_MODE
5622 			isp_target_async(isp, chan, mbox);
5623 #endif
5624 		}
5625 		break;
5626 
5627 	case ASYNC_LOOP_RESET:
5628 		/*
5629 		 * This is a broadcast event that has to be sent across
5630 		 * all active channels.
5631 		 */
5632 		for (chan = 0; chan < isp->isp_nchan; chan++) {
5633 			fcp = FCPARAM(isp, chan);
5634 			if (fcp->role == ISP_ROLE_NONE)
5635 				continue;
5636 			ISP_SET_SENDMARKER(isp, chan, 1);
5637 			if (fcp->isp_loopstate > LOOP_HAVE_LINK)
5638 				fcp->isp_loopstate = LOOP_HAVE_LINK;
5639 			isp_async(isp, ISPASYNC_LOOP_RESET, chan);
5640 #ifdef	ISP_TARGET_MODE
5641 			isp_target_async(isp, chan, mbox);
5642 #endif
5643 		}
5644 		break;
5645 
5646 	case ASYNC_PDB_CHANGED:
5647 	{
5648 		int echan, nphdl, nlstate, reason;
5649 
5650 		if (IS_23XX(isp) || IS_24XX(isp)) {
5651 			nphdl = ISP_READ(isp, OUTMAILBOX1);
5652 			nlstate = ISP_READ(isp, OUTMAILBOX2);
5653 		} else {
5654 			nphdl = nlstate = 0xffff;
5655 		}
5656 		if (IS_24XX(isp))
5657 			reason = ISP_READ(isp, OUTMAILBOX3) >> 8;
5658 		else
5659 			reason = 0xff;
5660 		if (ISP_CAP_MULTI_ID(isp)) {
5661 			chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;
5662 			if (chan == 0xff || nphdl == NIL_HANDLE) {
5663 				chan = 0;
5664 				echan = isp->isp_nchan - 1;
5665 			} else if (chan >= isp->isp_nchan) {
5666 				break;
5667 			} else {
5668 				echan = chan;
5669 			}
5670 		} else {
5671 			chan = echan = 0;
5672 		}
5673 		for (; chan <= echan; chan++) {
5674 			fcp = FCPARAM(isp, chan);
5675 			if (fcp->role == ISP_ROLE_NONE)
5676 				continue;
5677 			if (fcp->isp_loopstate > LOOP_LTEST_DONE) {
5678 				if (nphdl != NIL_HANDLE &&
5679 				    nphdl == fcp->isp_login_hdl &&
5680 				    reason == PDB24XX_AE_OPN_2)
5681 					continue;
5682 				fcp->isp_loopstate = LOOP_LTEST_DONE;
5683 			} else if (fcp->isp_loopstate < LOOP_HAVE_LINK)
5684 				fcp->isp_loopstate = LOOP_HAVE_LINK;
5685 			isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
5686 			    ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason);
5687 		}
5688 		break;
5689 	}
5690 	case ASYNC_CHANGE_NOTIFY:
5691 	{
5692 		int portid;
5693 
5694 		portid = ((ISP_READ(isp, OUTMAILBOX1) & 0xff) << 16) |
5695 		    ISP_READ(isp, OUTMAILBOX2);
5696 		if (ISP_CAP_MULTI_ID(isp)) {
5697 			chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;
5698 			if (chan >= isp->isp_nchan)
5699 				break;
5700 		} else {
5701 			chan = 0;
5702 		}
5703 		fcp = FCPARAM(isp, chan);
5704 		if (fcp->role == ISP_ROLE_NONE)
5705 			break;
5706 		if (fcp->isp_loopstate > LOOP_LTEST_DONE)
5707 			fcp->isp_loopstate = LOOP_LTEST_DONE;
5708 		else if (fcp->isp_loopstate < LOOP_HAVE_LINK)
5709 			fcp->isp_loopstate = LOOP_HAVE_LINK;
5710 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
5711 		    ISPASYNC_CHANGE_SNS, portid);
5712 		break;
5713 	}
5714 	case ASYNC_ERR_LOGGING_DISABLED:
5715 		isp_prt(isp, ISP_LOGWARN, "Error logging disabled (reason 0x%x)",
5716 		    ISP_READ(isp, OUTMAILBOX1));
5717 		break;
5718 	case ASYNC_CONNMODE:
5719 		/*
5720 		 * This only applies to 2100 amd 2200 cards
5721 		 */
5722 		if (!IS_2200(isp) && !IS_2100(isp)) {
5723 			isp_prt(isp, ISP_LOGWARN, "bad card for ASYNC_CONNMODE event");
5724 			break;
5725 		}
5726 		chan = 0;
5727 		mbox = ISP_READ(isp, OUTMAILBOX1);
5728 		switch (mbox) {
5729 		case ISP_CONN_LOOP:
5730 			isp_prt(isp, ISP_LOGINFO,
5731 			    "Point-to-Point -> Loop mode");
5732 			break;
5733 		case ISP_CONN_PTP:
5734 			isp_prt(isp, ISP_LOGINFO,
5735 			    "Loop -> Point-to-Point mode");
5736 			break;
5737 		case ISP_CONN_BADLIP:
5738 			isp_prt(isp, ISP_LOGWARN,
5739 			    "Point-to-Point -> Loop mode (BAD LIP)");
5740 			break;
5741 		case ISP_CONN_FATAL:
5742 			isp->isp_state = ISP_CRASHED;
5743 			isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
5744 			isp_async(isp, ISPASYNC_FW_CRASH);
5745 			return;
5746 		case ISP_CONN_LOOPBACK:
5747 			isp_prt(isp, ISP_LOGWARN,
5748 			    "Looped Back in Point-to-Point mode");
5749 			break;
5750 		default:
5751 			isp_prt(isp, ISP_LOGWARN,
5752 			    "Unknown connection mode (0x%x)", mbox);
5753 			break;
5754 		}
5755 		ISP_SET_SENDMARKER(isp, chan, 1);
5756 		FCPARAM(isp, chan)->isp_loopstate = LOOP_HAVE_LINK;
5757 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_OTHER);
5758 		break;
5759 	case ASYNC_P2P_INIT_ERR:
5760 		isp_prt(isp, ISP_LOGWARN, "P2P init error (reason 0x%x)",
5761 		    ISP_READ(isp, OUTMAILBOX1));
5762 		break;
5763 	case ASYNC_RCV_ERR:
5764 		if (IS_24XX(isp)) {
5765 			isp_prt(isp, ISP_LOGWARN, "Receive Error");
5766 		} else {
5767 			isp_prt(isp, ISP_LOGWARN, "unexpected ASYNC_RCV_ERR");
5768 		}
5769 		break;
5770 	case ASYNC_RJT_SENT:	/* same as ASYNC_QFULL_SENT */
5771 		if (IS_24XX(isp)) {
5772 			isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent");
5773 			break;
5774 		} else {
5775 			isp_prt(isp, ISP_LOGTDEBUG0, "QFULL sent");
5776 			break;
5777 		}
5778 	case ASYNC_FW_RESTART_COMPLETE:
5779 		isp_prt(isp, ISP_LOGDEBUG0, "FW restart complete");
5780 		break;
5781 	case ASYNC_TEMPERATURE_ALERT:
5782 		isp_prt(isp, ISP_LOGERR, "Temperature alert (subcode 0x%x)",
5783 		    ISP_READ(isp, OUTMAILBOX1));
5784 		break;
5785 	case ASYNC_AUTOLOAD_FW_COMPLETE:
5786 		isp_prt(isp, ISP_LOGDEBUG0, "Autoload FW init complete");
5787 		break;
5788 	case ASYNC_AUTOLOAD_FW_FAILURE:
5789 		isp_prt(isp, ISP_LOGERR, "Autoload FW init failure");
5790 		break;
5791 	default:
5792 		isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
5793 		break;
5794 	}
5795 }
5796 
5797 /*
5798  * Handle other response entries. A pointer to the request queue output
5799  * index is here in case we want to eat several entries at once, although
5800  * this is not used currently.
5801  */
5802 
5803 static int
isp_handle_other_response(ispsoftc_t * isp,int type,isphdr_t * hp,uint32_t * optrp)5804 isp_handle_other_response(ispsoftc_t *isp, int type, isphdr_t *hp, uint32_t *optrp)
5805 {
5806 	isp_ridacq_t rid;
5807 	int chan, c;
5808 	uint32_t hdl, portid;
5809 	void *ptr;
5810 
5811 	switch (type) {
5812 	case RQSTYPE_MARKER:
5813 		isp_prt(isp, ISP_LOG_WARN1, "Marker Response");
5814 		return (1);
5815 	case RQSTYPE_RPT_ID_ACQ:
5816 		isp_get_ridacq(isp, (isp_ridacq_t *)hp, &rid);
5817 		portid = (uint32_t)rid.ridacq_vp_port_hi << 16 |
5818 		    rid.ridacq_vp_port_lo;
5819 		if (rid.ridacq_format == 0) {
5820 			for (chan = 0; chan < isp->isp_nchan; chan++) {
5821 				fcparam *fcp = FCPARAM(isp, chan);
5822 				if (fcp->role == ISP_ROLE_NONE)
5823 					continue;
5824 				c = (chan == 0) ? 127 : (chan - 1);
5825 				if (rid.ridacq_map[c / 16] & (1 << (c % 16)) ||
5826 				    chan == 0) {
5827 					fcp->isp_loopstate = LOOP_HAVE_LINK;
5828 					isp_async(isp, ISPASYNC_CHANGE_NOTIFY,
5829 					    chan, ISPASYNC_CHANGE_OTHER);
5830 				} else {
5831 					fcp->isp_loopstate = LOOP_NIL;
5832 					isp_async(isp, ISPASYNC_LOOP_DOWN,
5833 					    chan);
5834 				}
5835 			}
5836 		} else {
5837 			fcparam *fcp = FCPARAM(isp, rid.ridacq_vp_index);
5838 			if (rid.ridacq_vp_status == RIDACQ_STS_COMPLETE ||
5839 			    rid.ridacq_vp_status == RIDACQ_STS_CHANGED) {
5840 				fcp->isp_topo = (rid.ridacq_map[0] >> 9) & 0x7;
5841 				fcp->isp_portid = portid;
5842 				fcp->isp_loopstate = LOOP_HAVE_ADDR;
5843 				isp_async(isp, ISPASYNC_CHANGE_NOTIFY,
5844 				    rid.ridacq_vp_index, ISPASYNC_CHANGE_OTHER);
5845 			} else {
5846 				fcp->isp_loopstate = LOOP_NIL;
5847 				isp_async(isp, ISPASYNC_LOOP_DOWN,
5848 				    rid.ridacq_vp_index);
5849 			}
5850 		}
5851 		return (1);
5852 	case RQSTYPE_CT_PASSTHRU:
5853 	case RQSTYPE_VP_MODIFY:
5854 	case RQSTYPE_VP_CTRL:
5855 	case RQSTYPE_LOGIN:
5856 		ISP_IOXGET_32(isp, (uint32_t *)(hp + 1), hdl);
5857 		ptr = isp_find_xs(isp, hdl);
5858 		if (ptr != NULL) {
5859 			isp_destroy_handle(isp, hdl);
5860 			memcpy(ptr, hp, QENTRY_LEN);
5861 			wakeup(ptr);
5862 		}
5863 		return (1);
5864 	case RQSTYPE_ATIO:
5865 	case RQSTYPE_CTIO:
5866 	case RQSTYPE_NOTIFY:
5867 	case RQSTYPE_NOTIFY_ACK:
5868 	case RQSTYPE_CTIO1:
5869 	case RQSTYPE_ATIO2:
5870 	case RQSTYPE_CTIO2:
5871 	case RQSTYPE_CTIO3:
5872 	case RQSTYPE_CTIO7:
5873 	case RQSTYPE_ABTS_RCVD:
5874 	case RQSTYPE_ABTS_RSP:
5875 #ifdef	ISP_TARGET_MODE
5876 		return (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp));
5877 #endif
5878 		/* FALLTHROUGH */
5879 	case RQSTYPE_REQUEST:
5880 	default:
5881 		return (0);
5882 	}
5883 }
5884 
5885 static void
isp_parse_status(ispsoftc_t * isp,ispstatusreq_t * sp,XS_T * xs,uint32_t * rp)5886 isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, uint32_t *rp)
5887 {
5888 	switch (sp->req_completion_status & 0xff) {
5889 	case RQCS_COMPLETE:
5890 		if (XS_NOERR(xs)) {
5891 			XS_SETERR(xs, HBA_NOERROR);
5892 		}
5893 		return;
5894 
5895 	case RQCS_INCOMPLETE:
5896 		if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
5897 			isp_xs_prt(isp, xs, ISP_LOG_WARN1, "Selection Timeout @ %s:%d", __func__, __LINE__);
5898 			if (XS_NOERR(xs)) {
5899 				XS_SETERR(xs, HBA_SELTIMEOUT);
5900 				*rp = XS_XFRLEN(xs);
5901 			}
5902 			return;
5903 		}
5904 		isp_xs_prt(isp, xs, ISP_LOGERR, "Command Incomplete, state 0x%x", sp->req_state_flags);
5905 		break;
5906 
5907 	case RQCS_DMA_ERROR:
5908 		isp_xs_prt(isp, xs, ISP_LOGERR, "DMA Error");
5909 		*rp = XS_XFRLEN(xs);
5910 		break;
5911 
5912 	case RQCS_TRANSPORT_ERROR:
5913 	{
5914 		char buf[172];
5915 		ISP_SNPRINTF(buf, sizeof (buf), "states=>");
5916 		if (sp->req_state_flags & RQSF_GOT_BUS) {
5917 			ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
5918 		}
5919 		if (sp->req_state_flags & RQSF_GOT_TARGET) {
5920 			ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
5921 		}
5922 		if (sp->req_state_flags & RQSF_SENT_CDB) {
5923 			ISP_SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
5924 		}
5925 		if (sp->req_state_flags & RQSF_XFRD_DATA) {
5926 			ISP_SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
5927 		}
5928 		if (sp->req_state_flags & RQSF_GOT_STATUS) {
5929 			ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
5930 		}
5931 		if (sp->req_state_flags & RQSF_GOT_SENSE) {
5932 			ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
5933 		}
5934 		if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
5935 			ISP_SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
5936 		}
5937 		ISP_SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
5938 		if (sp->req_status_flags & RQSTF_DISCONNECT) {
5939 			ISP_SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
5940 		}
5941 		if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
5942 			ISP_SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
5943 		}
5944 		if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
5945 			ISP_SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
5946 		}
5947 		if (sp->req_status_flags & RQSTF_BUS_RESET) {
5948 			ISP_SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
5949 		}
5950 		if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
5951 			ISP_SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
5952 		}
5953 		if (sp->req_status_flags & RQSTF_ABORTED) {
5954 			ISP_SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
5955 		}
5956 		if (sp->req_status_flags & RQSTF_TIMEOUT) {
5957 			ISP_SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
5958 		}
5959 		if (sp->req_status_flags & RQSTF_NEGOTIATION) {
5960 			ISP_SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
5961 		}
5962 		isp_xs_prt(isp, xs,  ISP_LOGERR, "Transport Error: %s", buf);
5963 		*rp = XS_XFRLEN(xs);
5964 		break;
5965 	}
5966 	case RQCS_RESET_OCCURRED:
5967 	{
5968 		int chan;
5969 		isp_xs_prt(isp, xs, ISP_LOGWARN, "Bus Reset destroyed command");
5970 		for (chan = 0; chan < isp->isp_nchan; chan++) {
5971 			FCPARAM(isp, chan)->sendmarker = 1;
5972 		}
5973 		if (XS_NOERR(xs)) {
5974 			XS_SETERR(xs, HBA_BUSRESET);
5975 		}
5976 		*rp = XS_XFRLEN(xs);
5977 		return;
5978 	}
5979 	case RQCS_ABORTED:
5980 		isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted");
5981 		ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1);
5982 		if (XS_NOERR(xs)) {
5983 			XS_SETERR(xs, HBA_ABORTED);
5984 		}
5985 		return;
5986 
5987 	case RQCS_TIMEOUT:
5988 		isp_xs_prt(isp, xs, ISP_LOGWARN, "Command timed out");
5989 		/*
5990 	 	 * XXX: Check to see if we logged out of the device.
5991 		 */
5992 		if (XS_NOERR(xs)) {
5993 			XS_SETERR(xs, HBA_CMDTIMEOUT);
5994 		}
5995 		return;
5996 
5997 	case RQCS_DATA_OVERRUN:
5998 		XS_SET_RESID(xs, sp->req_resid);
5999 		isp_xs_prt(isp, xs, ISP_LOGERR, "data overrun (%ld)", (long) XS_GET_RESID(xs));
6000 		if (XS_NOERR(xs)) {
6001 			XS_SETERR(xs, HBA_DATAOVR);
6002 		}
6003 		return;
6004 
6005 	case RQCS_COMMAND_OVERRUN:
6006 		isp_xs_prt(isp, xs, ISP_LOGERR, "command overrun");
6007 		break;
6008 
6009 	case RQCS_STATUS_OVERRUN:
6010 		isp_xs_prt(isp, xs, ISP_LOGERR, "status overrun");
6011 		break;
6012 
6013 	case RQCS_BAD_MESSAGE:
6014 		isp_xs_prt(isp, xs, ISP_LOGERR, "msg not COMMAND COMPLETE after status");
6015 		break;
6016 
6017 	case RQCS_NO_MESSAGE_OUT:
6018 		isp_xs_prt(isp, xs, ISP_LOGERR, "No MESSAGE OUT phase after selection");
6019 		break;
6020 
6021 	case RQCS_EXT_ID_FAILED:
6022 		isp_xs_prt(isp, xs, ISP_LOGERR, "EXTENDED IDENTIFY failed");
6023 		break;
6024 
6025 	case RQCS_IDE_MSG_FAILED:
6026 		isp_xs_prt(isp, xs, ISP_LOGERR, "INITIATOR DETECTED ERROR rejected");
6027 		break;
6028 
6029 	case RQCS_ABORT_MSG_FAILED:
6030 		isp_xs_prt(isp, xs, ISP_LOGERR, "ABORT OPERATION rejected");
6031 		break;
6032 
6033 	case RQCS_REJECT_MSG_FAILED:
6034 		isp_xs_prt(isp, xs, ISP_LOGERR, "MESSAGE REJECT rejected");
6035 		break;
6036 
6037 	case RQCS_NOP_MSG_FAILED:
6038 		isp_xs_prt(isp, xs, ISP_LOGERR, "NOP rejected");
6039 		break;
6040 
6041 	case RQCS_PARITY_ERROR_MSG_FAILED:
6042 		isp_xs_prt(isp, xs, ISP_LOGERR, "MESSAGE PARITY ERROR rejected");
6043 		break;
6044 
6045 	case RQCS_DEVICE_RESET_MSG_FAILED:
6046 		isp_xs_prt(isp, xs, ISP_LOGWARN, "BUS DEVICE RESET rejected");
6047 		break;
6048 
6049 	case RQCS_ID_MSG_FAILED:
6050 		isp_xs_prt(isp, xs, ISP_LOGERR, "IDENTIFY rejected");
6051 		break;
6052 
6053 	case RQCS_UNEXP_BUS_FREE:
6054 		isp_xs_prt(isp, xs, ISP_LOGERR, "Unexpected Bus Free");
6055 		break;
6056 
6057 	case RQCS_DATA_UNDERRUN:
6058 	{
6059 		if (IS_FC(isp)) {
6060 			int ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
6061 			if (!ru_marked || sp->req_resid > XS_XFRLEN(xs)) {
6062 				isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked");
6063 				if (XS_NOERR(xs)) {
6064 					XS_SETERR(xs, HBA_BOTCH);
6065 				}
6066 				return;
6067 			}
6068 		}
6069 		XS_SET_RESID(xs, sp->req_resid);
6070 		if (XS_NOERR(xs)) {
6071 			XS_SETERR(xs, HBA_NOERROR);
6072 		}
6073 		return;
6074 	}
6075 
6076 	case RQCS_XACT_ERR1:
6077 		isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued transaction with disconnect not set");
6078 		break;
6079 
6080 	case RQCS_XACT_ERR2:
6081 		isp_xs_prt(isp, xs, ISP_LOGERR,
6082 		    "HBA attempted queued transaction to target routine %jx",
6083 		    (uintmax_t)XS_LUN(xs));
6084 		break;
6085 
6086 	case RQCS_XACT_ERR3:
6087 		isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued cmd when queueing disabled");
6088 		break;
6089 
6090 	case RQCS_BAD_ENTRY:
6091 		isp_prt(isp, ISP_LOGERR, "Invalid IOCB entry type detected");
6092 		break;
6093 
6094 	case RQCS_QUEUE_FULL:
6095 		isp_xs_prt(isp, xs, ISP_LOG_WARN1, "internal queues full status 0x%x", *XS_STSP(xs));
6096 
6097 		/*
6098 		 * If QFULL or some other status byte is set, then this
6099 		 * isn't an error, per se.
6100 		 *
6101 		 * Unfortunately, some QLogic f/w writers have, in
6102 		 * some cases, ommitted to *set* status to QFULL.
6103 		 */
6104 #if	0
6105 		if (*XS_STSP(xs) != SCSI_GOOD && XS_NOERR(xs)) {
6106 			XS_SETERR(xs, HBA_NOERROR);
6107 			return;
6108 		}
6109 
6110 #endif
6111 		*XS_STSP(xs) = SCSI_QFULL;
6112 		XS_SETERR(xs, HBA_NOERROR);
6113 		return;
6114 
6115 	case RQCS_PHASE_SKIPPED:
6116 		isp_xs_prt(isp, xs, ISP_LOGERR, "SCSI phase skipped");
6117 		break;
6118 
6119 	case RQCS_ARQS_FAILED:
6120 		isp_xs_prt(isp, xs, ISP_LOGERR, "Auto Request Sense Failed");
6121 		if (XS_NOERR(xs)) {
6122 			XS_SETERR(xs, HBA_ARQFAIL);
6123 		}
6124 		return;
6125 
6126 	case RQCS_WIDE_FAILED:
6127 		isp_xs_prt(isp, xs, ISP_LOGERR, "Wide Negotiation Failed");
6128 		if (IS_SCSI(isp)) {
6129 			sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
6130 			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_WIDE;
6131 			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
6132 			sdp->update = 1;
6133 		}
6134 		if (XS_NOERR(xs)) {
6135 			XS_SETERR(xs, HBA_NOERROR);
6136 		}
6137 		return;
6138 
6139 	case RQCS_SYNCXFER_FAILED:
6140 		isp_xs_prt(isp, xs, ISP_LOGERR, "SDTR Message Failed");
6141 		if (IS_SCSI(isp)) {
6142 			sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
6143 			sdp += XS_CHANNEL(xs);
6144 			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_SYNC;
6145 			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
6146 			sdp->update = 1;
6147 		}
6148 		break;
6149 
6150 	case RQCS_LVD_BUSERR:
6151 		isp_xs_prt(isp, xs, ISP_LOGERR, "Bad LVD condition");
6152 		break;
6153 
6154 	case RQCS_PORT_UNAVAILABLE:
6155 		/*
6156 		 * No such port on the loop. Moral equivalent of SELTIMEO
6157 		 */
6158 	case RQCS_PORT_LOGGED_OUT:
6159 	{
6160 		const char *reason;
6161 		uint8_t sts = sp->req_completion_status & 0xff;
6162 		fcparam *fcp = FCPARAM(isp, 0);
6163 		fcportdb_t *lp;
6164 
6165 		/*
6166 		 * It was there (maybe)- treat as a selection timeout.
6167 		 */
6168 		if (sts == RQCS_PORT_UNAVAILABLE) {
6169 			reason = "unavailable";
6170 		} else {
6171 			reason = "logout";
6172 		}
6173 
6174 		isp_prt(isp, ISP_LOGINFO, "port %s for target %d", reason, XS_TGT(xs));
6175 
6176 		/* XXX: Should we trigger rescan or FW announce change? */
6177 
6178 		if (XS_NOERR(xs)) {
6179 			lp = &fcp->portdb[XS_TGT(xs)];
6180 			if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
6181 				*XS_STSP(xs) = SCSI_BUSY;
6182 				XS_SETERR(xs, HBA_TGTBSY);
6183 			} else
6184 				XS_SETERR(xs, HBA_SELTIMEOUT);
6185 		}
6186 		return;
6187 	}
6188 	case RQCS_PORT_CHANGED:
6189 		isp_prt(isp, ISP_LOGWARN, "port changed for target %d", XS_TGT(xs));
6190 		if (XS_NOERR(xs)) {
6191 			*XS_STSP(xs) = SCSI_BUSY;
6192 			XS_SETERR(xs, HBA_TGTBSY);
6193 		}
6194 		return;
6195 
6196 	case RQCS_PORT_BUSY:
6197 		isp_prt(isp, ISP_LOGWARN, "port busy for target %d", XS_TGT(xs));
6198 		if (XS_NOERR(xs)) {
6199 			*XS_STSP(xs) = SCSI_BUSY;
6200 			XS_SETERR(xs, HBA_TGTBSY);
6201 		}
6202 		return;
6203 
6204 	default:
6205 		isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x", sp->req_completion_status);
6206 		break;
6207 	}
6208 	if (XS_NOERR(xs)) {
6209 		XS_SETERR(xs, HBA_BOTCH);
6210 	}
6211 }
6212 
6213 static void
isp_parse_status_24xx(ispsoftc_t * isp,isp24xx_statusreq_t * sp,XS_T * xs,uint32_t * rp)6214 isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, XS_T *xs, uint32_t *rp)
6215 {
6216 	int ru_marked, sv_marked;
6217 	int chan = XS_CHANNEL(xs);
6218 
6219 	switch (sp->req_completion_status) {
6220 	case RQCS_COMPLETE:
6221 		if (XS_NOERR(xs)) {
6222 			XS_SETERR(xs, HBA_NOERROR);
6223 		}
6224 		return;
6225 
6226 	case RQCS_DMA_ERROR:
6227 		isp_xs_prt(isp, xs, ISP_LOGERR, "DMA error");
6228 		break;
6229 
6230 	case RQCS_TRANSPORT_ERROR:
6231 		isp_xs_prt(isp, xs,  ISP_LOGERR, "Transport Error");
6232 		break;
6233 
6234 	case RQCS_RESET_OCCURRED:
6235 		isp_xs_prt(isp, xs, ISP_LOGWARN, "reset destroyed command");
6236 		FCPARAM(isp, chan)->sendmarker = 1;
6237 		if (XS_NOERR(xs)) {
6238 			XS_SETERR(xs, HBA_BUSRESET);
6239 		}
6240 		return;
6241 
6242 	case RQCS_ABORTED:
6243 		isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted");
6244 		FCPARAM(isp, chan)->sendmarker = 1;
6245 		if (XS_NOERR(xs)) {
6246 			XS_SETERR(xs, HBA_ABORTED);
6247 		}
6248 		return;
6249 
6250 	case RQCS_TIMEOUT:
6251 		isp_xs_prt(isp, xs, ISP_LOGWARN, "Command Timed Out");
6252 		if (XS_NOERR(xs)) {
6253 			XS_SETERR(xs, HBA_CMDTIMEOUT);
6254 		}
6255 		return;
6256 
6257 	case RQCS_DATA_OVERRUN:
6258 		XS_SET_RESID(xs, sp->req_resid);
6259 		isp_xs_prt(isp, xs, ISP_LOGERR, "Data Overrun");
6260 		if (XS_NOERR(xs)) {
6261 			XS_SETERR(xs, HBA_DATAOVR);
6262 		}
6263 		return;
6264 
6265 	case RQCS_24XX_DRE:	/* data reassembly error */
6266 		isp_prt(isp, ISP_LOGERR, "Chan %d data reassembly error for target %d", chan, XS_TGT(xs));
6267 		if (XS_NOERR(xs)) {
6268 			XS_SETERR(xs, HBA_ABORTED);
6269 		}
6270 		*rp = XS_XFRLEN(xs);
6271 		return;
6272 
6273 	case RQCS_24XX_TABORT:	/* aborted by target */
6274 		isp_prt(isp, ISP_LOGERR, "Chan %d target %d sent ABTS", chan, XS_TGT(xs));
6275 		if (XS_NOERR(xs)) {
6276 			XS_SETERR(xs, HBA_ABORTED);
6277 		}
6278 		return;
6279 
6280 	case RQCS_DATA_UNDERRUN:
6281 		ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
6282 		/*
6283 		 * We can get an underrun w/o things being marked
6284 		 * if we got a non-zero status.
6285 		 */
6286 		sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0;
6287 		if ((ru_marked == 0 && sv_marked == 0) ||
6288 		    (sp->req_resid > XS_XFRLEN(xs))) {
6289 			isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked");
6290 			if (XS_NOERR(xs)) {
6291 				XS_SETERR(xs, HBA_BOTCH);
6292 			}
6293 			return;
6294 		}
6295 		XS_SET_RESID(xs, sp->req_resid);
6296 		isp_xs_prt(isp, xs, ISP_LOG_WARN1, "Data Underrun (%d) for command 0x%x", sp->req_resid, XS_CDBP(xs)[0] & 0xff);
6297 		if (XS_NOERR(xs)) {
6298 			XS_SETERR(xs, HBA_NOERROR);
6299 		}
6300 		return;
6301 
6302 	case RQCS_PORT_UNAVAILABLE:
6303 		/*
6304 		 * No such port on the loop. Moral equivalent of SELTIMEO
6305 		 */
6306 	case RQCS_PORT_LOGGED_OUT:
6307 	{
6308 		const char *reason;
6309 		uint8_t sts = sp->req_completion_status & 0xff;
6310 		fcparam *fcp = FCPARAM(isp, XS_CHANNEL(xs));
6311 		fcportdb_t *lp;
6312 
6313 		/*
6314 		 * It was there (maybe)- treat as a selection timeout.
6315 		 */
6316 		if (sts == RQCS_PORT_UNAVAILABLE) {
6317 			reason = "unavailable";
6318 		} else {
6319 			reason = "logout";
6320 		}
6321 
6322 		isp_prt(isp, ISP_LOGINFO, "Chan %d port %s for target %d",
6323 		    chan, reason, XS_TGT(xs));
6324 
6325 		/* XXX: Should we trigger rescan or FW announce change? */
6326 
6327 		if (XS_NOERR(xs)) {
6328 			lp = &fcp->portdb[XS_TGT(xs)];
6329 			if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
6330 				*XS_STSP(xs) = SCSI_BUSY;
6331 				XS_SETERR(xs, HBA_TGTBSY);
6332 			} else
6333 				XS_SETERR(xs, HBA_SELTIMEOUT);
6334 		}
6335 		return;
6336 	}
6337 	case RQCS_PORT_CHANGED:
6338 		isp_prt(isp, ISP_LOGWARN, "port changed for target %d chan %d", XS_TGT(xs), chan);
6339 		if (XS_NOERR(xs)) {
6340 			*XS_STSP(xs) = SCSI_BUSY;
6341 			XS_SETERR(xs, HBA_TGTBSY);
6342 		}
6343 		return;
6344 
6345 	case RQCS_24XX_ENOMEM:	/* f/w resource unavailable */
6346 		isp_prt(isp, ISP_LOGWARN, "f/w resource unavailable for target %d chan %d", XS_TGT(xs), chan);
6347 		if (XS_NOERR(xs)) {
6348 			*XS_STSP(xs) = SCSI_BUSY;
6349 			XS_SETERR(xs, HBA_TGTBSY);
6350 		}
6351 		return;
6352 
6353 	case RQCS_24XX_TMO:	/* task management overrun */
6354 		isp_prt(isp, ISP_LOGWARN, "command for target %d overlapped task management for chan %d", XS_TGT(xs), chan);
6355 		if (XS_NOERR(xs)) {
6356 			*XS_STSP(xs) = SCSI_BUSY;
6357 			XS_SETERR(xs, HBA_TGTBSY);
6358 		}
6359 		return;
6360 
6361 	default:
6362 		isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x on chan %d", sp->req_completion_status, chan);
6363 		break;
6364 	}
6365 	if (XS_NOERR(xs)) {
6366 		XS_SETERR(xs, HBA_BOTCH);
6367 	}
6368 }
6369 
6370 static void
isp_fastpost_complete(ispsoftc_t * isp,uint32_t fph)6371 isp_fastpost_complete(ispsoftc_t *isp, uint32_t fph)
6372 {
6373 	XS_T *xs;
6374 
6375 	if (fph == 0) {
6376 		return;
6377 	}
6378 	xs = isp_find_xs(isp, fph);
6379 	if (xs == NULL) {
6380 		isp_prt(isp, ISP_LOGWARN,
6381 		    "Command for fast post handle 0x%x not found", fph);
6382 		return;
6383 	}
6384 	isp_destroy_handle(isp, fph);
6385 
6386 	/*
6387 	 * Since we don't have a result queue entry item,
6388 	 * we must believe that SCSI status is zero and
6389 	 * that all data transferred.
6390 	 */
6391 	XS_SET_RESID(xs, 0);
6392 	*XS_STSP(xs) = SCSI_GOOD;
6393 	if (XS_XFRLEN(xs)) {
6394 		ISP_DMAFREE(isp, xs, fph);
6395 	}
6396 	isp_done(xs);
6397 }
6398 
6399 #define	ISP_SCSI_IBITS(op)		(mbpscsi[((op)<<1)])
6400 #define	ISP_SCSI_OBITS(op)		(mbpscsi[((op)<<1) + 1])
6401 #define	ISP_SCSI_OPMAP(in, out)		in, out
6402 static const uint8_t mbpscsi[] = {
6403 	ISP_SCSI_OPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
6404 	ISP_SCSI_OPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
6405 	ISP_SCSI_OPMAP(0x03, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
6406 	ISP_SCSI_OPMAP(0x1f, 0x01),	/* 0x03: MBOX_DUMP_RAM */
6407 	ISP_SCSI_OPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
6408 	ISP_SCSI_OPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
6409 	ISP_SCSI_OPMAP(0x3f, 0x3f),	/* 0x06: MBOX_MAILBOX_REG_TEST */
6410 	ISP_SCSI_OPMAP(0x07, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
6411 	ISP_SCSI_OPMAP(0x01, 0x0f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
6412 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x09: */
6413 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x0a: */
6414 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x0b: */
6415 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x0c: */
6416 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x0d: */
6417 	ISP_SCSI_OPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
6418 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x0f: */
6419 	ISP_SCSI_OPMAP(0x1f, 0x1f),	/* 0x10: MBOX_INIT_REQ_QUEUE */
6420 	ISP_SCSI_OPMAP(0x3f, 0x3f),	/* 0x11: MBOX_INIT_RES_QUEUE */
6421 	ISP_SCSI_OPMAP(0x0f, 0x0f),	/* 0x12: MBOX_EXECUTE_IOCB */
6422 	ISP_SCSI_OPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
6423 	ISP_SCSI_OPMAP(0x01, 0x3f),	/* 0x14: MBOX_STOP_FIRMWARE */
6424 	ISP_SCSI_OPMAP(0x0f, 0x0f),	/* 0x15: MBOX_ABORT */
6425 	ISP_SCSI_OPMAP(0x03, 0x03),	/* 0x16: MBOX_ABORT_DEVICE */
6426 	ISP_SCSI_OPMAP(0x07, 0x07),	/* 0x17: MBOX_ABORT_TARGET */
6427 	ISP_SCSI_OPMAP(0x07, 0x07),	/* 0x18: MBOX_BUS_RESET */
6428 	ISP_SCSI_OPMAP(0x03, 0x07),	/* 0x19: MBOX_STOP_QUEUE */
6429 	ISP_SCSI_OPMAP(0x03, 0x07),	/* 0x1a: MBOX_START_QUEUE */
6430 	ISP_SCSI_OPMAP(0x03, 0x07),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
6431 	ISP_SCSI_OPMAP(0x03, 0x07),	/* 0x1c: MBOX_ABORT_QUEUE */
6432 	ISP_SCSI_OPMAP(0x03, 0x4f),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
6433 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x1e: */
6434 	ISP_SCSI_OPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
6435 	ISP_SCSI_OPMAP(0x01, 0x07),	/* 0x20: MBOX_GET_INIT_SCSI_ID */
6436 	ISP_SCSI_OPMAP(0x01, 0x07),	/* 0x21: MBOX_GET_SELECT_TIMEOUT */
6437 	ISP_SCSI_OPMAP(0x01, 0xc7),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
6438 	ISP_SCSI_OPMAP(0x01, 0x07),	/* 0x23: MBOX_GET_TAG_AGE_LIMIT */
6439 	ISP_SCSI_OPMAP(0x01, 0x03),	/* 0x24: MBOX_GET_CLOCK_RATE */
6440 	ISP_SCSI_OPMAP(0x01, 0x07),	/* 0x25: MBOX_GET_ACT_NEG_STATE */
6441 	ISP_SCSI_OPMAP(0x01, 0x07),	/* 0x26: MBOX_GET_ASYNC_DATA_SETUP_TIME */
6442 	ISP_SCSI_OPMAP(0x01, 0x07),	/* 0x27: MBOX_GET_PCI_PARAMS */
6443 	ISP_SCSI_OPMAP(0x03, 0x4f),	/* 0x28: MBOX_GET_TARGET_PARAMS */
6444 	ISP_SCSI_OPMAP(0x03, 0x0f),	/* 0x29: MBOX_GET_DEV_QUEUE_PARAMS */
6445 	ISP_SCSI_OPMAP(0x01, 0x07),	/* 0x2a: MBOX_GET_RESET_DELAY_PARAMS */
6446 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x2b: */
6447 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x2c: */
6448 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x2d: */
6449 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x2e: */
6450 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x2f: */
6451 	ISP_SCSI_OPMAP(0x03, 0x03),	/* 0x30: MBOX_SET_INIT_SCSI_ID */
6452 	ISP_SCSI_OPMAP(0x07, 0x07),	/* 0x31: MBOX_SET_SELECT_TIMEOUT */
6453 	ISP_SCSI_OPMAP(0xc7, 0xc7),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
6454 	ISP_SCSI_OPMAP(0x07, 0x07),	/* 0x33: MBOX_SET_TAG_AGE_LIMIT */
6455 	ISP_SCSI_OPMAP(0x03, 0x03),	/* 0x34: MBOX_SET_CLOCK_RATE */
6456 	ISP_SCSI_OPMAP(0x07, 0x07),	/* 0x35: MBOX_SET_ACT_NEG_STATE */
6457 	ISP_SCSI_OPMAP(0x07, 0x07),	/* 0x36: MBOX_SET_ASYNC_DATA_SETUP_TIME */
6458 	ISP_SCSI_OPMAP(0x07, 0x07),	/* 0x37: MBOX_SET_PCI_CONTROL_PARAMS */
6459 	ISP_SCSI_OPMAP(0x4f, 0x4f),	/* 0x38: MBOX_SET_TARGET_PARAMS */
6460 	ISP_SCSI_OPMAP(0x0f, 0x0f),	/* 0x39: MBOX_SET_DEV_QUEUE_PARAMS */
6461 	ISP_SCSI_OPMAP(0x07, 0x07),	/* 0x3a: MBOX_SET_RESET_DELAY_PARAMS */
6462 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x3b: */
6463 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x3c: */
6464 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x3d: */
6465 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x3e: */
6466 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x3f: */
6467 	ISP_SCSI_OPMAP(0x01, 0x03),	/* 0x40: MBOX_RETURN_BIOS_BLOCK_ADDR */
6468 	ISP_SCSI_OPMAP(0x3f, 0x01),	/* 0x41: MBOX_WRITE_FOUR_RAM_WORDS */
6469 	ISP_SCSI_OPMAP(0x03, 0x07),	/* 0x42: MBOX_EXEC_BIOS_IOCB */
6470 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x43: */
6471 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x44: */
6472 	ISP_SCSI_OPMAP(0x03, 0x03),	/* 0x45: SET SYSTEM PARAMETER */
6473 	ISP_SCSI_OPMAP(0x01, 0x03),	/* 0x46: GET SYSTEM PARAMETER */
6474 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x47: */
6475 	ISP_SCSI_OPMAP(0x01, 0xcf),	/* 0x48: GET SCAM CONFIGURATION */
6476 	ISP_SCSI_OPMAP(0xcf, 0xcf),	/* 0x49: SET SCAM CONFIGURATION */
6477 	ISP_SCSI_OPMAP(0x03, 0x03),	/* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
6478 	ISP_SCSI_OPMAP(0x01, 0x03),	/* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
6479 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x4c: */
6480 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x4d: */
6481 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x4e: */
6482 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x4f: */
6483 	ISP_SCSI_OPMAP(0xdf, 0xdf),	/* 0x50: LOAD RAM A64 */
6484 	ISP_SCSI_OPMAP(0xdf, 0xdf),	/* 0x51: DUMP RAM A64 */
6485 	ISP_SCSI_OPMAP(0xdf, 0xff),	/* 0x52: INITIALIZE REQUEST QUEUE A64 */
6486 	ISP_SCSI_OPMAP(0xef, 0xff),	/* 0x53: INITIALIZE RESPONSE QUEUE A64 */
6487 	ISP_SCSI_OPMAP(0xcf, 0x01),	/* 0x54: EXECUCUTE COMMAND IOCB A64 */
6488 	ISP_SCSI_OPMAP(0x07, 0x01),	/* 0x55: ENABLE TARGET MODE */
6489 	ISP_SCSI_OPMAP(0x03, 0x0f),	/* 0x56: GET TARGET STATUS */
6490 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x57: */
6491 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x58: */
6492 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x59: */
6493 	ISP_SCSI_OPMAP(0x03, 0x03),	/* 0x5a: SET DATA OVERRUN RECOVERY MODE */
6494 	ISP_SCSI_OPMAP(0x01, 0x03),	/* 0x5b: GET DATA OVERRUN RECOVERY MODE */
6495 	ISP_SCSI_OPMAP(0x0f, 0x0f),	/* 0x5c: SET HOST DATA */
6496 	ISP_SCSI_OPMAP(0x01, 0x01)	/* 0x5d: GET NOST DATA */
6497 };
6498 #define	MAX_SCSI_OPCODE	0x5d
6499 
6500 static const char *scsi_mbcmd_names[] = {
6501 	"NO-OP",
6502 	"LOAD RAM",
6503 	"EXEC FIRMWARE",
6504 	"DUMP RAM",
6505 	"WRITE RAM WORD",
6506 	"READ RAM WORD",
6507 	"MAILBOX REG TEST",
6508 	"VERIFY CHECKSUM",
6509 	"ABOUT FIRMWARE",
6510 	NULL,
6511 	NULL,
6512 	NULL,
6513 	NULL,
6514 	NULL,
6515 	"CHECK FIRMWARE",
6516 	NULL,
6517 	"INIT REQUEST QUEUE",
6518 	"INIT RESULT QUEUE",
6519 	"EXECUTE IOCB",
6520 	"WAKE UP",
6521 	"STOP FIRMWARE",
6522 	"ABORT",
6523 	"ABORT DEVICE",
6524 	"ABORT TARGET",
6525 	"BUS RESET",
6526 	"STOP QUEUE",
6527 	"START QUEUE",
6528 	"SINGLE STEP QUEUE",
6529 	"ABORT QUEUE",
6530 	"GET DEV QUEUE STATUS",
6531 	NULL,
6532 	"GET FIRMWARE STATUS",
6533 	"GET INIT SCSI ID",
6534 	"GET SELECT TIMEOUT",
6535 	"GET RETRY COUNT",
6536 	"GET TAG AGE LIMIT",
6537 	"GET CLOCK RATE",
6538 	"GET ACT NEG STATE",
6539 	"GET ASYNC DATA SETUP TIME",
6540 	"GET PCI PARAMS",
6541 	"GET TARGET PARAMS",
6542 	"GET DEV QUEUE PARAMS",
6543 	"GET RESET DELAY PARAMS",
6544 	NULL,
6545 	NULL,
6546 	NULL,
6547 	NULL,
6548 	NULL,
6549 	"SET INIT SCSI ID",
6550 	"SET SELECT TIMEOUT",
6551 	"SET RETRY COUNT",
6552 	"SET TAG AGE LIMIT",
6553 	"SET CLOCK RATE",
6554 	"SET ACT NEG STATE",
6555 	"SET ASYNC DATA SETUP TIME",
6556 	"SET PCI CONTROL PARAMS",
6557 	"SET TARGET PARAMS",
6558 	"SET DEV QUEUE PARAMS",
6559 	"SET RESET DELAY PARAMS",
6560 	NULL,
6561 	NULL,
6562 	NULL,
6563 	NULL,
6564 	NULL,
6565 	"RETURN BIOS BLOCK ADDR",
6566 	"WRITE FOUR RAM WORDS",
6567 	"EXEC BIOS IOCB",
6568 	NULL,
6569 	NULL,
6570 	"SET SYSTEM PARAMETER",
6571 	"GET SYSTEM PARAMETER",
6572 	NULL,
6573 	"GET SCAM CONFIGURATION",
6574 	"SET SCAM CONFIGURATION",
6575 	"SET FIRMWARE FEATURES",
6576 	"GET FIRMWARE FEATURES",
6577 	NULL,
6578 	NULL,
6579 	NULL,
6580 	NULL,
6581 	"LOAD RAM A64",
6582 	"DUMP RAM A64",
6583 	"INITIALIZE REQUEST QUEUE A64",
6584 	"INITIALIZE RESPONSE QUEUE A64",
6585 	"EXECUTE IOCB A64",
6586 	"ENABLE TARGET MODE",
6587 	"GET TARGET MODE STATE",
6588 	NULL,
6589 	NULL,
6590 	NULL,
6591 	"SET DATA OVERRUN RECOVERY MODE",
6592 	"GET DATA OVERRUN RECOVERY MODE",
6593 	"SET HOST DATA",
6594 	"GET NOST DATA",
6595 };
6596 
6597 #define	ISP_FC_IBITS(op)	((mbpfc[((op)<<3) + 0] << 24) | (mbpfc[((op)<<3) + 1] << 16) | (mbpfc[((op)<<3) + 2] << 8) | (mbpfc[((op)<<3) + 3]))
6598 #define	ISP_FC_OBITS(op)	((mbpfc[((op)<<3) + 4] << 24) | (mbpfc[((op)<<3) + 5] << 16) | (mbpfc[((op)<<3) + 6] << 8) | (mbpfc[((op)<<3) + 7]))
6599 
6600 #define	ISP_FC_OPMAP(in0, out0)							  0,   0,   0, in0,    0,    0,    0, out0
6601 #define	ISP_FC_OPMAP_HALF(in1, in0, out1, out0)					  0,   0, in1, in0,    0,    0, out1, out0
6602 #define	ISP_FC_OPMAP_FULL(in3, in2, in1, in0, out3, out2, out1, out0)		in3, in2, in1, in0, out3, out2, out1, out0
6603 static const uint32_t mbpfc[] = {
6604 	ISP_FC_OPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
6605 	ISP_FC_OPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
6606 	ISP_FC_OPMAP_HALF(0x07, 0xff, 0x00, 0x03),	/* 0x02: MBOX_EXEC_FIRMWARE */
6607 	ISP_FC_OPMAP(0xdf, 0x01),	/* 0x03: MBOX_DUMP_RAM */
6608 	ISP_FC_OPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
6609 	ISP_FC_OPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
6610 	ISP_FC_OPMAP_FULL(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff),	/* 0x06: MBOX_MAILBOX_REG_TEST */
6611 	ISP_FC_OPMAP(0x07, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
6612 	ISP_FC_OPMAP_FULL(0x0, 0x0, 0x0, 0x01, 0x0, 0x3, 0x80, 0x7f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
6613 	ISP_FC_OPMAP(0xdf, 0x01),	/* 0x09: MBOX_LOAD_RISC_RAM_2100 */
6614 	ISP_FC_OPMAP(0xdf, 0x01),	/* 0x0a: DUMP RAM */
6615 	ISP_FC_OPMAP_HALF(0x1, 0xff, 0x0, 0x01),	/* 0x0b: MBOX_LOAD_RISC_RAM */
6616 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x0c: */
6617 	ISP_FC_OPMAP_HALF(0x1, 0x0f, 0x0, 0x01),	/* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED */
6618 	ISP_FC_OPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
6619 	ISP_FC_OPMAP_HALF(0x1, 0x03, 0x0, 0x0d),	/* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */
6620 	ISP_FC_OPMAP(0x1f, 0x11),	/* 0x10: MBOX_INIT_REQ_QUEUE */
6621 	ISP_FC_OPMAP(0x2f, 0x21),	/* 0x11: MBOX_INIT_RES_QUEUE */
6622 	ISP_FC_OPMAP(0x0f, 0x01),	/* 0x12: MBOX_EXECUTE_IOCB */
6623 	ISP_FC_OPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
6624 	ISP_FC_OPMAP_HALF(0x1, 0xff, 0x0, 0x03),	/* 0x14: MBOX_STOP_FIRMWARE */
6625 	ISP_FC_OPMAP(0x4f, 0x01),	/* 0x15: MBOX_ABORT */
6626 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x16: MBOX_ABORT_DEVICE */
6627 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x17: MBOX_ABORT_TARGET */
6628 	ISP_FC_OPMAP(0x03, 0x03),	/* 0x18: MBOX_BUS_RESET */
6629 	ISP_FC_OPMAP(0x07, 0x05),	/* 0x19: MBOX_STOP_QUEUE */
6630 	ISP_FC_OPMAP(0x07, 0x05),	/* 0x1a: MBOX_START_QUEUE */
6631 	ISP_FC_OPMAP(0x07, 0x05),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
6632 	ISP_FC_OPMAP(0x07, 0x05),	/* 0x1c: MBOX_ABORT_QUEUE */
6633 	ISP_FC_OPMAP(0x07, 0x03),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
6634 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x1e: */
6635 	ISP_FC_OPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
6636 	ISP_FC_OPMAP_HALF(0x2, 0x01, 0x7e, 0xcf),	/* 0x20: MBOX_GET_LOOP_ID */
6637 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x21: */
6638 	ISP_FC_OPMAP(0x03, 0x4b),	/* 0x22: MBOX_GET_TIMEOUT_PARAMS */
6639 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x23: */
6640 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x24: */
6641 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x25: */
6642 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x26: */
6643 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x27: */
6644 	ISP_FC_OPMAP(0x01, 0x03),	/* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
6645 	ISP_FC_OPMAP(0x03, 0x07),	/* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
6646 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2a: */
6647 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2b: */
6648 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2c: */
6649 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2d: */
6650 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2e: */
6651 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2f: */
6652 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x30: */
6653 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x31: */
6654 	ISP_FC_OPMAP(0x4b, 0x4b),	/* 0x32: MBOX_SET_TIMEOUT_PARAMS */
6655 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x33: */
6656 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x34: */
6657 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x35: */
6658 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x36: */
6659 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x37: */
6660 	ISP_FC_OPMAP(0x0f, 0x01),	/* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
6661 	ISP_FC_OPMAP(0x0f, 0x07),	/* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
6662 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3a: */
6663 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3b: */
6664 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3c: */
6665 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3d: */
6666 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3e: */
6667 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3f: */
6668 	ISP_FC_OPMAP(0x03, 0x01),	/* 0x40: MBOX_LOOP_PORT_BYPASS */
6669 	ISP_FC_OPMAP(0x03, 0x01),	/* 0x41: MBOX_LOOP_PORT_ENABLE */
6670 	ISP_FC_OPMAP_HALF(0x0, 0x01, 0x1f, 0xcf),	/* 0x42: MBOX_GET_RESOURCE_COUNT */
6671 	ISP_FC_OPMAP(0x01, 0x01),	/* 0x43: MBOX_REQUEST_OFFLINE_MODE */
6672 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x44: */
6673 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x45: */
6674 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x46: */
6675 	ISP_FC_OPMAP(0xcf, 0x03),	/* 0x47: GET PORT_DATABASE ENHANCED */
6676 	ISP_FC_OPMAP(0xcf, 0x0f),	/* 0x48: MBOX_INIT_FIRMWARE_MULTI_ID */
6677 	ISP_FC_OPMAP(0xcd, 0x01),	/* 0x49: MBOX_GET_VP_DATABASE */
6678 	ISP_FC_OPMAP_HALF(0x2, 0xcd, 0x0, 0x01),	/* 0x4a: MBOX_GET_VP_DATABASE_ENTRY */
6679 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x4b: */
6680 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x4c: */
6681 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x4d: */
6682 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x4e: */
6683 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x4f: */
6684 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x50: */
6685 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x51: */
6686 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x52: */
6687 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x53: */
6688 	ISP_FC_OPMAP(0xcf, 0x01),	/* 0x54: EXECUTE IOCB A64 */
6689 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x55: */
6690 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x56: */
6691 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x57: */
6692 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x58: */
6693 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x59: */
6694 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x5a: */
6695 	ISP_FC_OPMAP(0x03, 0x01),	/* 0x5b: MBOX_DRIVER_HEARTBEAT */
6696 	ISP_FC_OPMAP(0xcf, 0x01),	/* 0x5c: MBOX_FW_HEARTBEAT */
6697 	ISP_FC_OPMAP(0x07, 0x1f),	/* 0x5d: MBOX_GET_SET_DATA_RATE */
6698 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x5e: */
6699 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x5f: */
6700 	ISP_FC_OPMAP(0xcf, 0x0f),	/* 0x60: MBOX_INIT_FIRMWARE */
6701 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x61: */
6702 	ISP_FC_OPMAP(0x01, 0x01),	/* 0x62: MBOX_INIT_LIP */
6703 	ISP_FC_OPMAP(0xcd, 0x03),	/* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
6704 	ISP_FC_OPMAP(0xcf, 0x01),	/* 0x64: MBOX_GET_PORT_DB */
6705 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x65: MBOX_CLEAR_ACA */
6706 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x66: MBOX_TARGET_RESET */
6707 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x67: MBOX_CLEAR_TASK_SET */
6708 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x68: MBOX_ABORT_TASK_SET */
6709 	ISP_FC_OPMAP(0x01, 0x07),	/* 0x69: MBOX_GET_FW_STATE */
6710 	ISP_FC_OPMAP_HALF(0x6, 0x03, 0x0, 0xcf),	/* 0x6a: MBOX_GET_PORT_NAME */
6711 	ISP_FC_OPMAP(0xcf, 0x01),	/* 0x6b: MBOX_GET_LINK_STATUS */
6712 	ISP_FC_OPMAP(0x0f, 0x01),	/* 0x6c: MBOX_INIT_LIP_RESET */
6713 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x6d: */
6714 	ISP_FC_OPMAP(0xcf, 0x03),	/* 0x6e: MBOX_SEND_SNS */
6715 	ISP_FC_OPMAP(0x0f, 0x07),	/* 0x6f: MBOX_FABRIC_LOGIN */
6716 	ISP_FC_OPMAP_HALF(0x02, 0x03, 0x00, 0x03),	/* 0x70: MBOX_SEND_CHANGE_REQUEST */
6717 	ISP_FC_OPMAP(0x03, 0x03),	/* 0x71: MBOX_FABRIC_LOGOUT */
6718 	ISP_FC_OPMAP(0x0f, 0x0f),	/* 0x72: MBOX_INIT_LIP_LOGIN */
6719 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x73: */
6720 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x74: LOGIN LOOP PORT */
6721 	ISP_FC_OPMAP_HALF(0x03, 0xcf, 0x00, 0x07),	/* 0x75: GET PORT/NODE NAME LIST */
6722 	ISP_FC_OPMAP(0x4f, 0x01),	/* 0x76: SET VENDOR ID */
6723 	ISP_FC_OPMAP(0xcd, 0x01),	/* 0x77: INITIALIZE IP MAILBOX */
6724 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x78: */
6725 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x79: */
6726 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x7a: */
6727 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x7b: */
6728 	ISP_FC_OPMAP_HALF(0x03, 0x4f, 0x00, 0x07),	/* 0x7c: Get ID List */
6729 	ISP_FC_OPMAP(0xcf, 0x01),	/* 0x7d: SEND LFA */
6730 	ISP_FC_OPMAP(0x0f, 0x01)	/* 0x7e: LUN RESET */
6731 };
6732 #define	MAX_FC_OPCODE	0x7e
6733 /*
6734  * Footnotes
6735  *
6736  * (1): this sets bits 21..16 in mailbox register #8, which we nominally
6737  *	do not access at this time in the core driver. The caller is
6738  *	responsible for setting this register first (Gross!). The assumption
6739  *	is that we won't overflow.
6740  */
6741 
6742 static const char *fc_mbcmd_names[] = {
6743 	"NO-OP",			/* 00h */
6744 	"LOAD RAM",
6745 	"EXEC FIRMWARE",
6746 	"DUMP RAM",
6747 	"WRITE RAM WORD",
6748 	"READ RAM WORD",
6749 	"MAILBOX REG TEST",
6750 	"VERIFY CHECKSUM",
6751 	"ABOUT FIRMWARE",
6752 	"LOAD RAM (2100)",
6753 	"DUMP RAM",
6754 	"LOAD RISC RAM",
6755 	"DUMP RISC RAM",
6756 	"WRITE RAM WORD EXTENDED",
6757 	"CHECK FIRMWARE",
6758 	"READ RAM WORD EXTENDED",
6759 	"INIT REQUEST QUEUE",		/* 10h */
6760 	"INIT RESULT QUEUE",
6761 	"EXECUTE IOCB",
6762 	"WAKE UP",
6763 	"STOP FIRMWARE",
6764 	"ABORT",
6765 	"ABORT DEVICE",
6766 	"ABORT TARGET",
6767 	"BUS RESET",
6768 	"STOP QUEUE",
6769 	"START QUEUE",
6770 	"SINGLE STEP QUEUE",
6771 	"ABORT QUEUE",
6772 	"GET DEV QUEUE STATUS",
6773 	NULL,
6774 	"GET FIRMWARE STATUS",
6775 	"GET LOOP ID",			/* 20h */
6776 	NULL,
6777 	"GET TIMEOUT PARAMS",
6778 	NULL,
6779 	NULL,
6780 	NULL,
6781 	NULL,
6782 	NULL,
6783 	"GET FIRMWARE OPTIONS",
6784 	"GET PORT QUEUE PARAMS",
6785 	"GENERATE SYSTEM ERROR",
6786 	NULL,
6787 	NULL,
6788 	NULL,
6789 	NULL,
6790 	NULL,
6791 	"WRITE SFP",			/* 30h */
6792 	"READ SFP",
6793 	"SET TIMEOUT PARAMS",
6794 	NULL,
6795 	NULL,
6796 	NULL,
6797 	NULL,
6798 	NULL,
6799 	"SET FIRMWARE OPTIONS",
6800 	"SET PORT QUEUE PARAMS",
6801 	NULL,
6802 	"SET FC LED CONF",
6803 	NULL,
6804 	"RESTART NIC FIRMWARE",
6805 	"ACCESS CONTROL",
6806 	NULL,
6807 	"LOOP PORT BYPASS",		/* 40h */
6808 	"LOOP PORT ENABLE",
6809 	"GET RESOURCE COUNT",
6810 	"REQUEST NON PARTICIPATING MODE",
6811 	"DIAGNOSTIC ECHO TEST",
6812 	"DIAGNOSTIC LOOPBACK",
6813 	NULL,
6814 	"GET PORT DATABASE ENHANCED",
6815 	"INIT FIRMWARE MULTI ID",
6816 	"GET VP DATABASE",
6817 	"GET VP DATABASE ENTRY",
6818 	NULL,
6819 	NULL,
6820 	NULL,
6821 	NULL,
6822 	NULL,
6823 	"GET FCF LIST",			/* 50h */
6824 	"GET DCBX PARAMETERS",
6825 	NULL,
6826 	"HOST MEMORY COPY",
6827 	"EXECUTE IOCB A64",
6828 	NULL,
6829 	NULL,
6830 	"SEND RNID",
6831 	NULL,
6832 	"SET PARAMETERS",
6833 	"GET PARAMETERS",
6834 	"DRIVER HEARTBEAT",
6835 	"FIRMWARE HEARTBEAT",
6836 	"GET/SET DATA RATE",
6837 	"SEND RNFT",
6838 	NULL,
6839 	"INIT FIRMWARE",		/* 60h */
6840 	"GET INIT CONTROL BLOCK",
6841 	"INIT LIP",
6842 	"GET FC-AL POSITION MAP",
6843 	"GET PORT DATABASE",
6844 	"CLEAR ACA",
6845 	"TARGET RESET",
6846 	"CLEAR TASK SET",
6847 	"ABORT TASK SET",
6848 	"GET FW STATE",
6849 	"GET PORT NAME",
6850 	"GET LINK STATUS",
6851 	"INIT LIP RESET",
6852 	"GET LINK STATS & PRIVATE DATA CNTS",
6853 	"SEND SNS",
6854 	"FABRIC LOGIN",
6855 	"SEND CHANGE REQUEST",		/* 70h */
6856 	"FABRIC LOGOUT",
6857 	"INIT LIP LOGIN",
6858 	NULL,
6859 	"LOGIN LOOP PORT",
6860 	"GET PORT/NODE NAME LIST",
6861 	"SET VENDOR ID",
6862 	"INITIALIZE IP MAILBOX",
6863 	NULL,
6864 	NULL,
6865 	"GET XGMAC STATS",
6866 	NULL,
6867 	"GET ID LIST",
6868 	"SEND LFA",
6869 	"LUN RESET"
6870 };
6871 
6872 static void
isp_mboxcmd(ispsoftc_t * isp,mbreg_t * mbp)6873 isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
6874 {
6875 	const char *cname, *xname, *sname;
6876 	char tname[16], mname[16];
6877 	unsigned int ibits, obits, box, opcode;
6878 
6879 	opcode = mbp->param[0];
6880 	if (IS_FC(isp)) {
6881 		if (opcode > MAX_FC_OPCODE) {
6882 			mbp->param[0] = MBOX_INVALID_COMMAND;
6883 			isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
6884 			return;
6885 		}
6886 		cname = fc_mbcmd_names[opcode];
6887 		ibits = ISP_FC_IBITS(opcode);
6888 		obits = ISP_FC_OBITS(opcode);
6889 	} else {
6890 		if (opcode > MAX_SCSI_OPCODE) {
6891 			mbp->param[0] = MBOX_INVALID_COMMAND;
6892 			isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
6893 			return;
6894 		}
6895 		cname = scsi_mbcmd_names[opcode];
6896 		ibits = ISP_SCSI_IBITS(opcode);
6897 		obits = ISP_SCSI_OBITS(opcode);
6898 	}
6899 	if (cname == NULL) {
6900 		cname = tname;
6901 		ISP_SNPRINTF(tname, sizeof tname, "opcode %x", opcode);
6902 	}
6903 	isp_prt(isp, ISP_LOGDEBUG3, "Mailbox Command '%s'", cname);
6904 
6905 	/*
6906 	 * Pick up any additional bits that the caller might have set.
6907 	 */
6908 	ibits |= mbp->ibits;
6909 	obits |= mbp->obits;
6910 
6911 	/*
6912 	 * Mask any bits that the caller wants us to mask
6913 	 */
6914 	ibits &= mbp->ibitm;
6915 	obits &= mbp->obitm;
6916 
6917 
6918 	if (ibits == 0 && obits == 0) {
6919 		mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
6920 		isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
6921 		return;
6922 	}
6923 
6924 	/*
6925 	 * Get exclusive usage of mailbox registers.
6926 	 */
6927 	if (MBOX_ACQUIRE(isp)) {
6928 		mbp->param[0] = MBOX_REGS_BUSY;
6929 		goto out;
6930 	}
6931 
6932 	for (box = 0; box < ISP_NMBOX(isp); box++) {
6933 		if (ibits & (1 << box)) {
6934 			isp_prt(isp, ISP_LOGDEBUG3, "IN mbox %d = 0x%04x", box,
6935 			    mbp->param[box]);
6936 			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
6937 		}
6938 		isp->isp_mboxtmp[box] = mbp->param[box] = 0;
6939 	}
6940 
6941 	isp->isp_lastmbxcmd = opcode;
6942 
6943 	/*
6944 	 * We assume that we can't overwrite a previous command.
6945 	 */
6946 	isp->isp_obits = obits;
6947 	isp->isp_mboxbsy = 1;
6948 
6949 	/*
6950 	 * Set Host Interrupt condition so that RISC will pick up mailbox regs.
6951 	 */
6952 	if (IS_24XX(isp)) {
6953 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
6954 	} else {
6955 		ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
6956 	}
6957 
6958 	/*
6959 	 * While we haven't finished the command, spin our wheels here.
6960 	 */
6961 	MBOX_WAIT_COMPLETE(isp, mbp);
6962 
6963 	/*
6964 	 * Did the command time out?
6965 	 */
6966 	if (mbp->param[0] == MBOX_TIMEOUT) {
6967 		isp->isp_mboxbsy = 0;
6968 		MBOX_RELEASE(isp);
6969 		goto out;
6970 	}
6971 
6972 	/*
6973 	 * Copy back output registers.
6974 	 */
6975 	for (box = 0; box < ISP_NMBOX(isp); box++) {
6976 		if (obits & (1 << box)) {
6977 			mbp->param[box] = isp->isp_mboxtmp[box];
6978 			isp_prt(isp, ISP_LOGDEBUG3, "OUT mbox %d = 0x%04x", box,
6979 			    mbp->param[box]);
6980 		}
6981 	}
6982 
6983 	isp->isp_mboxbsy = 0;
6984 	MBOX_RELEASE(isp);
6985 out:
6986 	if (mbp->logval == 0 || mbp->param[0] == MBOX_COMMAND_COMPLETE)
6987 		return;
6988 
6989 	if ((mbp->param[0] & 0xbfe0) == 0 &&
6990 	    (mbp->logval & MBLOGMASK(mbp->param[0])) == 0)
6991 		return;
6992 
6993 	xname = NULL;
6994 	sname = "";
6995 	switch (mbp->param[0]) {
6996 	case MBOX_INVALID_COMMAND:
6997 		xname = "INVALID COMMAND";
6998 		break;
6999 	case MBOX_HOST_INTERFACE_ERROR:
7000 		xname = "HOST INTERFACE ERROR";
7001 		break;
7002 	case MBOX_TEST_FAILED:
7003 		xname = "TEST FAILED";
7004 		break;
7005 	case MBOX_COMMAND_ERROR:
7006 		xname = "COMMAND ERROR";
7007 		ISP_SNPRINTF(mname, sizeof(mname), " subcode 0x%x",
7008 		    mbp->param[1]);
7009 		sname = mname;
7010 		break;
7011 	case MBOX_COMMAND_PARAM_ERROR:
7012 		xname = "COMMAND PARAMETER ERROR";
7013 		break;
7014 	case MBOX_PORT_ID_USED:
7015 		xname = "PORT ID ALREADY IN USE";
7016 		break;
7017 	case MBOX_LOOP_ID_USED:
7018 		xname = "LOOP ID ALREADY IN USE";
7019 		break;
7020 	case MBOX_ALL_IDS_USED:
7021 		xname = "ALL LOOP IDS IN USE";
7022 		break;
7023 	case MBOX_NOT_LOGGED_IN:
7024 		xname = "NOT LOGGED IN";
7025 		break;
7026 	case MBOX_LINK_DOWN_ERROR:
7027 		xname = "LINK DOWN ERROR";
7028 		break;
7029 	case MBOX_LOOPBACK_ERROR:
7030 		xname = "LOOPBACK ERROR";
7031 		break;
7032 	case MBOX_CHECKSUM_ERROR:
7033 		xname = "CHECKSUM ERROR";
7034 		break;
7035 	case MBOX_INVALID_PRODUCT_KEY:
7036 		xname = "INVALID PRODUCT KEY";
7037 		break;
7038 	case MBOX_REGS_BUSY:
7039 		xname = "REGISTERS BUSY";
7040 		break;
7041 	case MBOX_TIMEOUT:
7042 		xname = "TIMEOUT";
7043 		break;
7044 	default:
7045 		ISP_SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
7046 		xname = mname;
7047 		break;
7048 	}
7049 	if (xname) {
7050 		isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s%s)",
7051 		    cname, xname, sname);
7052 	}
7053 }
7054 
7055 static int
isp_fw_state(ispsoftc_t * isp,int chan)7056 isp_fw_state(ispsoftc_t *isp, int chan)
7057 {
7058 	if (IS_FC(isp)) {
7059 		mbreg_t mbs;
7060 
7061 		MBSINIT(&mbs, MBOX_GET_FW_STATE, MBLOGALL, 0);
7062 		isp_mboxcmd(isp, &mbs);
7063 		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
7064 			return (mbs.param[1]);
7065 		}
7066 	}
7067 	return (FW_ERROR);
7068 }
7069 
7070 static void
isp_spi_update(ispsoftc_t * isp,int chan)7071 isp_spi_update(ispsoftc_t *isp, int chan)
7072 {
7073 	int tgt;
7074 	mbreg_t mbs;
7075 	sdparam *sdp;
7076 
7077 	if (IS_FC(isp)) {
7078 		/*
7079 		 * There are no 'per-bus' settings for Fibre Channel.
7080 		 */
7081 		return;
7082 	}
7083 	sdp = SDPARAM(isp, chan);
7084 	sdp->update = 0;
7085 
7086 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7087 		uint16_t flags, period, offset;
7088 		int get;
7089 
7090 		if (sdp->isp_devparam[tgt].dev_enable == 0) {
7091 			sdp->isp_devparam[tgt].dev_update = 0;
7092 			sdp->isp_devparam[tgt].dev_refresh = 0;
7093 			isp_prt(isp, ISP_LOGDEBUG0, "skipping target %d bus %d update", tgt, chan);
7094 			continue;
7095 		}
7096 		/*
7097 		 * If the goal is to update the status of the device,
7098 		 * take what's in goal_flags and try and set the device
7099 		 * toward that. Otherwise, if we're just refreshing the
7100 		 * current device state, get the current parameters.
7101 		 */
7102 
7103 		MBSINIT(&mbs, 0, MBLOGALL, 0);
7104 
7105 		/*
7106 		 * Refresh overrides set
7107 		 */
7108 		if (sdp->isp_devparam[tgt].dev_refresh) {
7109 			mbs.param[0] = MBOX_GET_TARGET_PARAMS;
7110 			get = 1;
7111 		} else if (sdp->isp_devparam[tgt].dev_update) {
7112 			mbs.param[0] = MBOX_SET_TARGET_PARAMS;
7113 
7114 			/*
7115 			 * Make sure goal_flags has "Renegotiate on Error"
7116 			 * on and "Freeze Queue on Error" off.
7117 			 */
7118 			sdp->isp_devparam[tgt].goal_flags |= DPARM_RENEG;
7119 			sdp->isp_devparam[tgt].goal_flags &= ~DPARM_QFRZ;
7120 			mbs.param[2] = sdp->isp_devparam[tgt].goal_flags;
7121 
7122 			/*
7123 			 * Insist that PARITY must be enabled
7124 			 * if SYNC or WIDE is enabled.
7125 			 */
7126 			if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) {
7127 				mbs.param[2] |= DPARM_PARITY;
7128 			}
7129 
7130 			if (mbs.param[2] & DPARM_SYNC) {
7131 				mbs.param[3] =
7132 				    (sdp->isp_devparam[tgt].goal_offset << 8) |
7133 				    (sdp->isp_devparam[tgt].goal_period);
7134 			}
7135 			/*
7136 			 * A command completion later that has
7137 			 * RQSTF_NEGOTIATION set can cause
7138 			 * the dev_refresh/announce cycle also.
7139 			 *
7140 			 * Note: It is really important to update our current
7141 			 * flags with at least the state of TAG capabilities-
7142 			 * otherwise we might try and send a tagged command
7143 			 * when we have it all turned off. So change it here
7144 			 * to say that current already matches goal.
7145 			 */
7146 			sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING;
7147 			sdp->isp_devparam[tgt].actv_flags |=
7148 			    (sdp->isp_devparam[tgt].goal_flags & DPARM_TQING);
7149 			isp_prt(isp, ISP_LOGDEBUG0, "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
7150 			    chan, tgt, mbs.param[2], mbs.param[3] >> 8, mbs.param[3] & 0xff);
7151 			get = 0;
7152 		} else {
7153 			continue;
7154 		}
7155 		mbs.param[1] = (chan << 15) | (tgt << 8);
7156 		isp_mboxcmd(isp, &mbs);
7157 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
7158 			continue;
7159 		}
7160 		if (get == 0) {
7161 			sdp->sendmarker = 1;
7162 			sdp->isp_devparam[tgt].dev_update = 0;
7163 			sdp->isp_devparam[tgt].dev_refresh = 1;
7164 		} else {
7165 			sdp->isp_devparam[tgt].dev_refresh = 0;
7166 			flags = mbs.param[2];
7167 			period = mbs.param[3] & 0xff;
7168 			offset = mbs.param[3] >> 8;
7169 			sdp->isp_devparam[tgt].actv_flags = flags;
7170 			sdp->isp_devparam[tgt].actv_period = period;
7171 			sdp->isp_devparam[tgt].actv_offset = offset;
7172 			isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, chan, tgt);
7173 		}
7174 	}
7175 
7176 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7177 		if (sdp->isp_devparam[tgt].dev_update ||
7178 		    sdp->isp_devparam[tgt].dev_refresh) {
7179 			sdp->update = 1;
7180 			break;
7181 		}
7182 	}
7183 }
7184 
7185 static void
isp_setdfltsdparm(ispsoftc_t * isp)7186 isp_setdfltsdparm(ispsoftc_t *isp)
7187 {
7188 	int tgt;
7189 	sdparam *sdp, *sdp1;
7190 
7191 	sdp = SDPARAM(isp, 0);
7192 	if (IS_DUALBUS(isp))
7193 		sdp1 = sdp + 1;
7194 	else
7195 		sdp1 = NULL;
7196 
7197 	/*
7198 	 * Establish some default parameters.
7199 	 */
7200 	sdp->isp_cmd_dma_burst_enable = 0;
7201 	sdp->isp_data_dma_burst_enabl = 1;
7202 	sdp->isp_fifo_threshold = 0;
7203 	sdp->isp_initiator_id = DEFAULT_IID(isp, 0);
7204 	if (isp->isp_type >= ISP_HA_SCSI_1040) {
7205 		sdp->isp_async_data_setup = 9;
7206 	} else {
7207 		sdp->isp_async_data_setup = 6;
7208 	}
7209 	sdp->isp_selection_timeout = 250;
7210 	sdp->isp_max_queue_depth = MAXISPREQUEST(isp);
7211 	sdp->isp_tag_aging = 8;
7212 	sdp->isp_bus_reset_delay = 5;
7213 	/*
7214 	 * Don't retry selection, busy or queue full automatically- reflect
7215 	 * these back to us.
7216 	 */
7217 	sdp->isp_retry_count = 0;
7218 	sdp->isp_retry_delay = 0;
7219 
7220 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7221 		sdp->isp_devparam[tgt].exc_throttle = ISP_EXEC_THROTTLE;
7222 		sdp->isp_devparam[tgt].dev_enable = 1;
7223 	}
7224 
7225 	/*
7226 	 * The trick here is to establish a default for the default (honk!)
7227 	 * state (goal_flags). Then try and get the current status from
7228 	 * the card to fill in the current state. We don't, in fact, set
7229 	 * the default to the SAFE default state- that's not the goal state.
7230 	 */
7231 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7232 		uint8_t off, per;
7233 		sdp->isp_devparam[tgt].actv_offset = 0;
7234 		sdp->isp_devparam[tgt].actv_period = 0;
7235 		sdp->isp_devparam[tgt].actv_flags = 0;
7236 
7237 		sdp->isp_devparam[tgt].goal_flags =
7238 		    sdp->isp_devparam[tgt].nvrm_flags = DPARM_DEFAULT;
7239 
7240 		/*
7241 		 * We default to Wide/Fast for versions less than a 1040
7242 		 * (unless it's SBus).
7243 		 */
7244 		if (IS_ULTRA3(isp)) {
7245 			off = ISP_80M_SYNCPARMS >> 8;
7246 			per = ISP_80M_SYNCPARMS & 0xff;
7247 		} else if (IS_ULTRA2(isp)) {
7248 			off = ISP_40M_SYNCPARMS >> 8;
7249 			per = ISP_40M_SYNCPARMS & 0xff;
7250 		} else if (IS_1240(isp)) {
7251 			off = ISP_20M_SYNCPARMS >> 8;
7252 			per = ISP_20M_SYNCPARMS & 0xff;
7253 		} else if ((isp->isp_bustype == ISP_BT_SBUS &&
7254 		    isp->isp_type < ISP_HA_SCSI_1020A) ||
7255 		    (isp->isp_bustype == ISP_BT_PCI &&
7256 		    isp->isp_type < ISP_HA_SCSI_1040) ||
7257 		    (isp->isp_clock && isp->isp_clock < 60) ||
7258 		    (sdp->isp_ultramode == 0)) {
7259 			off = ISP_10M_SYNCPARMS >> 8;
7260 			per = ISP_10M_SYNCPARMS & 0xff;
7261 		} else {
7262 			off = ISP_20M_SYNCPARMS_1040 >> 8;
7263 			per = ISP_20M_SYNCPARMS_1040 & 0xff;
7264 		}
7265 		sdp->isp_devparam[tgt].goal_offset =
7266 		    sdp->isp_devparam[tgt].nvrm_offset = off;
7267 		sdp->isp_devparam[tgt].goal_period =
7268 		    sdp->isp_devparam[tgt].nvrm_period = per;
7269 
7270 	}
7271 
7272 	/*
7273 	 * If we're a dual bus card, just copy the data over
7274 	 */
7275 	if (sdp1) {
7276 		*sdp1 = *sdp;
7277 		sdp1->isp_initiator_id = DEFAULT_IID(isp, 1);
7278 	}
7279 
7280 	/*
7281 	 * If we've not been told to avoid reading NVRAM, try and read it.
7282 	 * If we're successful reading it, we can then return because NVRAM
7283 	 * will tell us what the desired settings are. Otherwise, we establish
7284 	 * some reasonable 'fake' nvram and goal defaults.
7285 	 */
7286 	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
7287 		mbreg_t mbs;
7288 
7289 		if (isp_read_nvram(isp, 0) == 0) {
7290 			if (IS_DUALBUS(isp)) {
7291 				if (isp_read_nvram(isp, 1) == 0) {
7292 					return;
7293 				}
7294 			}
7295 		}
7296 		MBSINIT(&mbs, MBOX_GET_ACT_NEG_STATE, MBLOGNONE, 0);
7297 		isp_mboxcmd(isp, &mbs);
7298 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
7299 			sdp->isp_req_ack_active_neg = 1;
7300 			sdp->isp_data_line_active_neg = 1;
7301 			if (sdp1) {
7302 				sdp1->isp_req_ack_active_neg = 1;
7303 				sdp1->isp_data_line_active_neg = 1;
7304 			}
7305 		} else {
7306 			sdp->isp_req_ack_active_neg =
7307 			    (mbs.param[1] >> 4) & 0x1;
7308 			sdp->isp_data_line_active_neg =
7309 			    (mbs.param[1] >> 5) & 0x1;
7310 			if (sdp1) {
7311 				sdp1->isp_req_ack_active_neg =
7312 				    (mbs.param[2] >> 4) & 0x1;
7313 				sdp1->isp_data_line_active_neg =
7314 				    (mbs.param[2] >> 5) & 0x1;
7315 			}
7316 		}
7317 	}
7318 
7319 }
7320 
7321 static void
isp_setdfltfcparm(ispsoftc_t * isp,int chan)7322 isp_setdfltfcparm(ispsoftc_t *isp, int chan)
7323 {
7324 	fcparam *fcp = FCPARAM(isp, chan);
7325 
7326 	/*
7327 	 * Establish some default parameters.
7328 	 */
7329 	fcp->role = DEFAULT_ROLE(isp, chan);
7330 	fcp->isp_maxalloc = ICB_DFLT_ALLOC;
7331 	fcp->isp_retry_delay = ICB_DFLT_RDELAY;
7332 	fcp->isp_retry_count = ICB_DFLT_RCOUNT;
7333 	fcp->isp_loopid = DEFAULT_LOOPID(isp, chan);
7334 	fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp, chan);
7335 	fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp, chan);
7336 	fcp->isp_fwoptions = 0;
7337 	fcp->isp_xfwoptions = 0;
7338 	fcp->isp_zfwoptions = 0;
7339 	fcp->isp_lasthdl = NIL_HANDLE;
7340 	fcp->isp_login_hdl = NIL_HANDLE;
7341 
7342 	if (IS_24XX(isp)) {
7343 		fcp->isp_fwoptions |= ICB2400_OPT1_FAIRNESS;
7344 		fcp->isp_fwoptions |= ICB2400_OPT1_HARD_ADDRESS;
7345 		if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
7346 			fcp->isp_fwoptions |= ICB2400_OPT1_FULL_DUPLEX;
7347 		fcp->isp_fwoptions |= ICB2400_OPT1_BOTH_WWNS;
7348 		fcp->isp_xfwoptions |= ICB2400_OPT2_LOOP_2_PTP;
7349 		fcp->isp_zfwoptions |= ICB2400_OPT3_RATE_AUTO;
7350 	} else {
7351 		fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
7352 		fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
7353 		fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
7354 		if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
7355 			fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
7356 		/*
7357 		 * Make sure this is turned off now until we get
7358 		 * extended options from NVRAM
7359 		 */
7360 		fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
7361 		fcp->isp_xfwoptions |= ICBXOPT_LOOP_2_PTP;
7362 		fcp->isp_zfwoptions |= ICBZOPT_RATE_AUTO;
7363 	}
7364 
7365 
7366 	/*
7367 	 * Now try and read NVRAM unless told to not do so.
7368 	 * This will set fcparam's isp_wwnn_nvram && isp_wwpn_nvram.
7369 	 */
7370 	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
7371 		int i, j = 0;
7372 		/*
7373 		 * Give a couple of tries at reading NVRAM.
7374 		 */
7375 		for (i = 0; i < 2; i++) {
7376 			j = isp_read_nvram(isp, chan);
7377 			if (j == 0) {
7378 				break;
7379 			}
7380 		}
7381 		if (j) {
7382 			isp->isp_confopts |= ISP_CFG_NONVRAM;
7383 		}
7384 	}
7385 
7386 	fcp->isp_wwnn = ACTIVE_NODEWWN(isp, chan);
7387 	fcp->isp_wwpn = ACTIVE_PORTWWN(isp, chan);
7388 	isp_prt(isp, ISP_LOGCONFIG, "Chan %d 0x%08x%08x/0x%08x%08x Role %s",
7389 	    chan, (uint32_t) (fcp->isp_wwnn >> 32), (uint32_t) (fcp->isp_wwnn),
7390 	    (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) (fcp->isp_wwpn),
7391 	    isp_class3_roles[fcp->role]);
7392 }
7393 
7394 /*
7395  * Re-initialize the ISP and complete all orphaned commands
7396  * with a 'botched' notice. The reset/init routines should
7397  * not disturb an already active list of commands.
7398  */
7399 
7400 int
isp_reinit(ispsoftc_t * isp,int do_load_defaults)7401 isp_reinit(ispsoftc_t *isp, int do_load_defaults)
7402 {
7403 	int i, res = 0;
7404 
7405 	if (isp->isp_state > ISP_RESETSTATE)
7406 		isp_stop(isp);
7407 	if (isp->isp_state != ISP_RESETSTATE)
7408 		isp_reset(isp, do_load_defaults);
7409 	if (isp->isp_state != ISP_RESETSTATE) {
7410 		res = EIO;
7411 		isp_prt(isp, ISP_LOGERR, "%s: cannot reset card", __func__);
7412 		goto cleanup;
7413 	}
7414 
7415 	isp_init(isp);
7416 	if (isp->isp_state > ISP_RESETSTATE &&
7417 	    isp->isp_state != ISP_RUNSTATE) {
7418 		res = EIO;
7419 		isp_prt(isp, ISP_LOGERR, "%s: cannot init card", __func__);
7420 		ISP_DISABLE_INTS(isp);
7421 		if (IS_FC(isp)) {
7422 			/*
7423 			 * If we're in ISP_ROLE_NONE, turn off the lasers.
7424 			 */
7425 			if (!IS_24XX(isp)) {
7426 				ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
7427 				ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
7428 				ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
7429 				ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
7430 				ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
7431 			}
7432 		}
7433 	}
7434 
7435 cleanup:
7436 	isp_clear_commands(isp);
7437 	if (IS_FC(isp)) {
7438 		for (i = 0; i < isp->isp_nchan; i++)
7439 			isp_clear_portdb(isp, i);
7440 	}
7441 	return (res);
7442 }
7443 
7444 /*
7445  * NVRAM Routines
7446  */
7447 static int
isp_read_nvram(ispsoftc_t * isp,int bus)7448 isp_read_nvram(ispsoftc_t *isp, int bus)
7449 {
7450 	int i, amt, retval;
7451 	uint8_t csum, minversion;
7452 	union {
7453 		uint8_t _x[ISP2400_NVRAM_SIZE];
7454 		uint16_t _s[ISP2400_NVRAM_SIZE>>1];
7455 	} _n;
7456 #define	nvram_data	_n._x
7457 #define	nvram_words	_n._s
7458 
7459 	if (IS_24XX(isp)) {
7460 		return (isp_read_nvram_2400(isp, nvram_data));
7461 	} else if (IS_FC(isp)) {
7462 		amt = ISP2100_NVRAM_SIZE;
7463 		minversion = 1;
7464 	} else if (IS_ULTRA2(isp)) {
7465 		amt = ISP1080_NVRAM_SIZE;
7466 		minversion = 0;
7467 	} else {
7468 		amt = ISP_NVRAM_SIZE;
7469 		minversion = 2;
7470 	}
7471 
7472 	for (i = 0; i < amt>>1; i++) {
7473 		isp_rdnvram_word(isp, i, &nvram_words[i]);
7474 	}
7475 
7476 	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
7477 	    nvram_data[2] != 'P') {
7478 		if (isp->isp_bustype != ISP_BT_SBUS) {
7479 			isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
7480 			isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x", nvram_data[0], nvram_data[1], nvram_data[2]);
7481 		}
7482 		retval = -1;
7483 		goto out;
7484 	}
7485 
7486 	for (csum = 0, i = 0; i < amt; i++) {
7487 		csum += nvram_data[i];
7488 	}
7489 	if (csum != 0) {
7490 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
7491 		retval = -1;
7492 		goto out;
7493 	}
7494 
7495 	if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
7496 		isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood",
7497 		    ISP_NVRAM_VERSION(nvram_data));
7498 		retval = -1;
7499 		goto out;
7500 	}
7501 
7502 	if (IS_ULTRA3(isp)) {
7503 		isp_parse_nvram_12160(isp, bus, nvram_data);
7504 	} else if (IS_1080(isp)) {
7505 		isp_parse_nvram_1080(isp, bus, nvram_data);
7506 	} else if (IS_1280(isp) || IS_1240(isp)) {
7507 		isp_parse_nvram_1080(isp, bus, nvram_data);
7508 	} else if (IS_SCSI(isp)) {
7509 		isp_parse_nvram_1020(isp, nvram_data);
7510 	} else {
7511 		isp_parse_nvram_2100(isp, nvram_data);
7512 	}
7513 	retval = 0;
7514 out:
7515 	return (retval);
7516 #undef	nvram_data
7517 #undef	nvram_words
7518 }
7519 
7520 static int
isp_read_nvram_2400(ispsoftc_t * isp,uint8_t * nvram_data)7521 isp_read_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
7522 {
7523 	int retval = 0;
7524 	uint32_t addr, csum, lwrds, *dptr;
7525 
7526 	if (isp->isp_port) {
7527 		addr = ISP2400_NVRAM_PORT1_ADDR;
7528 	} else {
7529 		addr = ISP2400_NVRAM_PORT0_ADDR;
7530 	}
7531 
7532 	dptr = (uint32_t *) nvram_data;
7533 	for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
7534 		isp_rd_2400_nvram(isp, addr++, dptr++);
7535 	}
7536 	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
7537 	    nvram_data[2] != 'P') {
7538 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)",
7539 		    nvram_data[0], nvram_data[1], nvram_data[2]);
7540 		retval = -1;
7541 		goto out;
7542 	}
7543 	dptr = (uint32_t *) nvram_data;
7544 	for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
7545 		uint32_t tmp;
7546 		ISP_IOXGET_32(isp, &dptr[lwrds], tmp);
7547 		csum += tmp;
7548 	}
7549 	if (csum != 0) {
7550 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
7551 		retval = -1;
7552 		goto out;
7553 	}
7554 	isp_parse_nvram_2400(isp, nvram_data);
7555 out:
7556 	return (retval);
7557 }
7558 
7559 static void
isp_rdnvram_word(ispsoftc_t * isp,int wo,uint16_t * rp)7560 isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp)
7561 {
7562 	int i, cbits;
7563 	uint16_t bit, rqst, junk;
7564 
7565 	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
7566 	ISP_DELAY(10);
7567 	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
7568 	ISP_DELAY(10);
7569 
7570 	if (IS_FC(isp)) {
7571 		wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
7572 		if (IS_2312(isp) && isp->isp_port) {
7573 			wo += 128;
7574 		}
7575 		rqst = (ISP_NVRAM_READ << 8) | wo;
7576 		cbits = 10;
7577 	} else if (IS_ULTRA2(isp)) {
7578 		wo &= ((ISP1080_NVRAM_SIZE >> 1) - 1);
7579 		rqst = (ISP_NVRAM_READ << 8) | wo;
7580 		cbits = 10;
7581 	} else {
7582 		wo &= ((ISP_NVRAM_SIZE >> 1) - 1);
7583 		rqst = (ISP_NVRAM_READ << 6) | wo;
7584 		cbits = 8;
7585 	}
7586 
7587 	/*
7588 	 * Clock the word select request out...
7589 	 */
7590 	for (i = cbits; i >= 0; i--) {
7591 		if ((rqst >> i) & 1) {
7592 			bit = BIU_NVRAM_SELECT | BIU_NVRAM_DATAOUT;
7593 		} else {
7594 			bit = BIU_NVRAM_SELECT;
7595 		}
7596 		ISP_WRITE(isp, BIU_NVRAM, bit);
7597 		ISP_DELAY(10);
7598 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7599 		ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
7600 		ISP_DELAY(10);
7601 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7602 		ISP_WRITE(isp, BIU_NVRAM, bit);
7603 		ISP_DELAY(10);
7604 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7605 	}
7606 	/*
7607 	 * Now read the result back in (bits come back in MSB format).
7608 	 */
7609 	*rp = 0;
7610 	for (i = 0; i < 16; i++) {
7611 		uint16_t rv;
7612 		*rp <<= 1;
7613 		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
7614 		ISP_DELAY(10);
7615 		rv = ISP_READ(isp, BIU_NVRAM);
7616 		if (rv & BIU_NVRAM_DATAIN) {
7617 			*rp |= 1;
7618 		}
7619 		ISP_DELAY(10);
7620 		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
7621 		ISP_DELAY(10);
7622 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7623 	}
7624 	ISP_WRITE(isp, BIU_NVRAM, 0);
7625 	ISP_DELAY(10);
7626 	junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7627 	ISP_SWIZZLE_NVRAM_WORD(isp, rp);
7628 }
7629 
7630 static void
isp_rd_2400_nvram(ispsoftc_t * isp,uint32_t addr,uint32_t * rp)7631 isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
7632 {
7633 	int loops = 0;
7634 	uint32_t base = 0x7ffe0000;
7635 	uint32_t tmp = 0;
7636 
7637 	if (IS_26XX(isp)) {
7638 		base = 0x7fe7c000;	/* XXX: Observation, may be wrong. */
7639 	} else if (IS_25XX(isp)) {
7640 		base = 0x7ff00000 | 0x48000;
7641 	}
7642 	ISP_WRITE(isp, BIU2400_FLASH_ADDR, base | addr);
7643 	for (loops = 0; loops < 5000; loops++) {
7644 		ISP_DELAY(10);
7645 		tmp = ISP_READ(isp, BIU2400_FLASH_ADDR);
7646 		if ((tmp & (1U << 31)) != 0) {
7647 			break;
7648 		}
7649 	}
7650 	if (tmp & (1U << 31)) {
7651 		*rp = ISP_READ(isp, BIU2400_FLASH_DATA);
7652 		ISP_SWIZZLE_NVRAM_LONG(isp, rp);
7653 	} else {
7654 		*rp = 0xffffffff;
7655 	}
7656 }
7657 
7658 static void
isp_parse_nvram_1020(ispsoftc_t * isp,uint8_t * nvram_data)7659 isp_parse_nvram_1020(ispsoftc_t *isp, uint8_t *nvram_data)
7660 {
7661 	sdparam *sdp = SDPARAM(isp, 0);
7662 	int tgt;
7663 
7664 	sdp->isp_fifo_threshold =
7665 		ISP_NVRAM_FIFO_THRESHOLD(nvram_data) |
7666 		(ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2);
7667 
7668 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
7669 		sdp->isp_initiator_id = ISP_NVRAM_INITIATOR_ID(nvram_data);
7670 
7671 	sdp->isp_bus_reset_delay =
7672 		ISP_NVRAM_BUS_RESET_DELAY(nvram_data);
7673 
7674 	sdp->isp_retry_count =
7675 		ISP_NVRAM_BUS_RETRY_COUNT(nvram_data);
7676 
7677 	sdp->isp_retry_delay =
7678 		ISP_NVRAM_BUS_RETRY_DELAY(nvram_data);
7679 
7680 	sdp->isp_async_data_setup =
7681 		ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data);
7682 
7683 	if (isp->isp_type >= ISP_HA_SCSI_1040) {
7684 		if (sdp->isp_async_data_setup < 9) {
7685 			sdp->isp_async_data_setup = 9;
7686 		}
7687 	} else {
7688 		if (sdp->isp_async_data_setup != 6) {
7689 			sdp->isp_async_data_setup = 6;
7690 		}
7691 	}
7692 
7693 	sdp->isp_req_ack_active_neg =
7694 		ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
7695 
7696 	sdp->isp_data_line_active_neg =
7697 		ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data);
7698 
7699 	sdp->isp_data_dma_burst_enabl =
7700 		ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data);
7701 
7702 	sdp->isp_cmd_dma_burst_enable =
7703 		ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data);
7704 
7705 	sdp->isp_tag_aging =
7706 		ISP_NVRAM_TAG_AGE_LIMIT(nvram_data);
7707 
7708 	sdp->isp_selection_timeout =
7709 		ISP_NVRAM_SELECTION_TIMEOUT(nvram_data);
7710 
7711 	sdp->isp_max_queue_depth =
7712 		ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
7713 
7714 	sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
7715 
7716 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7717 		sdp->isp_devparam[tgt].dev_enable =
7718 			ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt);
7719 		sdp->isp_devparam[tgt].exc_throttle =
7720 			ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt);
7721 		sdp->isp_devparam[tgt].nvrm_offset =
7722 			ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt);
7723 		sdp->isp_devparam[tgt].nvrm_period =
7724 			ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt);
7725 		/*
7726 		 * We probably shouldn't lie about this, but it
7727 		 * it makes it much safer if we limit NVRAM values
7728 		 * to sanity.
7729 		 */
7730 		if (isp->isp_type < ISP_HA_SCSI_1040) {
7731 			/*
7732 			 * If we're not ultra, we can't possibly
7733 			 * be a shorter period than this.
7734 			 */
7735 			if (sdp->isp_devparam[tgt].nvrm_period < 0x19) {
7736 				sdp->isp_devparam[tgt].nvrm_period = 0x19;
7737 			}
7738 			if (sdp->isp_devparam[tgt].nvrm_offset > 0xc) {
7739 				sdp->isp_devparam[tgt].nvrm_offset = 0x0c;
7740 			}
7741 		} else {
7742 			if (sdp->isp_devparam[tgt].nvrm_offset > 0x8) {
7743 				sdp->isp_devparam[tgt].nvrm_offset = 0x8;
7744 			}
7745 		}
7746 		sdp->isp_devparam[tgt].nvrm_flags = 0;
7747 		if (ISP_NVRAM_TGT_RENEG(nvram_data, tgt))
7748 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
7749 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
7750 		if (ISP_NVRAM_TGT_TQING(nvram_data, tgt))
7751 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
7752 		if (ISP_NVRAM_TGT_SYNC(nvram_data, tgt))
7753 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
7754 		if (ISP_NVRAM_TGT_WIDE(nvram_data, tgt))
7755 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
7756 		if (ISP_NVRAM_TGT_PARITY(nvram_data, tgt))
7757 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
7758 		if (ISP_NVRAM_TGT_DISC(nvram_data, tgt))
7759 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
7760 		sdp->isp_devparam[tgt].actv_flags = 0; /* we don't know */
7761 		sdp->isp_devparam[tgt].goal_offset =
7762 		    sdp->isp_devparam[tgt].nvrm_offset;
7763 		sdp->isp_devparam[tgt].goal_period =
7764 		    sdp->isp_devparam[tgt].nvrm_period;
7765 		sdp->isp_devparam[tgt].goal_flags =
7766 		    sdp->isp_devparam[tgt].nvrm_flags;
7767 	}
7768 }
7769 
7770 static void
isp_parse_nvram_1080(ispsoftc_t * isp,int bus,uint8_t * nvram_data)7771 isp_parse_nvram_1080(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
7772 {
7773 	sdparam *sdp = SDPARAM(isp, bus);
7774 	int tgt;
7775 
7776 	sdp->isp_fifo_threshold =
7777 	    ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
7778 
7779 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
7780 		sdp->isp_initiator_id = ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus);
7781 
7782 	sdp->isp_bus_reset_delay =
7783 	    ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
7784 
7785 	sdp->isp_retry_count =
7786 	    ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
7787 
7788 	sdp->isp_retry_delay =
7789 	    ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
7790 
7791 	sdp->isp_async_data_setup =
7792 	    ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
7793 
7794 	sdp->isp_req_ack_active_neg =
7795 	    ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
7796 
7797 	sdp->isp_data_line_active_neg =
7798 	    ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
7799 
7800 	sdp->isp_data_dma_burst_enabl =
7801 	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
7802 
7803 	sdp->isp_cmd_dma_burst_enable =
7804 	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
7805 
7806 	sdp->isp_selection_timeout =
7807 	    ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
7808 
7809 	sdp->isp_max_queue_depth =
7810 	     ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
7811 
7812 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7813 		sdp->isp_devparam[tgt].dev_enable =
7814 		    ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
7815 		sdp->isp_devparam[tgt].exc_throttle =
7816 			ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
7817 		sdp->isp_devparam[tgt].nvrm_offset =
7818 			ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
7819 		sdp->isp_devparam[tgt].nvrm_period =
7820 			ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
7821 		sdp->isp_devparam[tgt].nvrm_flags = 0;
7822 		if (ISP1080_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
7823 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
7824 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
7825 		if (ISP1080_NVRAM_TGT_TQING(nvram_data, tgt, bus))
7826 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
7827 		if (ISP1080_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
7828 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
7829 		if (ISP1080_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
7830 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
7831 		if (ISP1080_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
7832 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
7833 		if (ISP1080_NVRAM_TGT_DISC(nvram_data, tgt, bus))
7834 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
7835 		sdp->isp_devparam[tgt].actv_flags = 0;
7836 		sdp->isp_devparam[tgt].goal_offset =
7837 		    sdp->isp_devparam[tgt].nvrm_offset;
7838 		sdp->isp_devparam[tgt].goal_period =
7839 		    sdp->isp_devparam[tgt].nvrm_period;
7840 		sdp->isp_devparam[tgt].goal_flags =
7841 		    sdp->isp_devparam[tgt].nvrm_flags;
7842 	}
7843 }
7844 
7845 static void
isp_parse_nvram_12160(ispsoftc_t * isp,int bus,uint8_t * nvram_data)7846 isp_parse_nvram_12160(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
7847 {
7848 	sdparam *sdp = SDPARAM(isp, bus);
7849 	int tgt;
7850 
7851 	sdp->isp_fifo_threshold =
7852 	    ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data);
7853 
7854 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
7855 		sdp->isp_initiator_id = ISP12160_NVRAM_INITIATOR_ID(nvram_data, bus);
7856 
7857 	sdp->isp_bus_reset_delay =
7858 	    ISP12160_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
7859 
7860 	sdp->isp_retry_count =
7861 	    ISP12160_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
7862 
7863 	sdp->isp_retry_delay =
7864 	    ISP12160_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
7865 
7866 	sdp->isp_async_data_setup =
7867 	    ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
7868 
7869 	sdp->isp_req_ack_active_neg =
7870 	    ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
7871 
7872 	sdp->isp_data_line_active_neg =
7873 	    ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
7874 
7875 	sdp->isp_data_dma_burst_enabl =
7876 	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
7877 
7878 	sdp->isp_cmd_dma_burst_enable =
7879 	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
7880 
7881 	sdp->isp_selection_timeout =
7882 	    ISP12160_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
7883 
7884 	sdp->isp_max_queue_depth =
7885 	     ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
7886 
7887 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7888 		sdp->isp_devparam[tgt].dev_enable =
7889 		    ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
7890 		sdp->isp_devparam[tgt].exc_throttle =
7891 			ISP12160_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
7892 		sdp->isp_devparam[tgt].nvrm_offset =
7893 			ISP12160_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
7894 		sdp->isp_devparam[tgt].nvrm_period =
7895 			ISP12160_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
7896 		sdp->isp_devparam[tgt].nvrm_flags = 0;
7897 		if (ISP12160_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
7898 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
7899 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
7900 		if (ISP12160_NVRAM_TGT_TQING(nvram_data, tgt, bus))
7901 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
7902 		if (ISP12160_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
7903 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
7904 		if (ISP12160_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
7905 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
7906 		if (ISP12160_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
7907 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
7908 		if (ISP12160_NVRAM_TGT_DISC(nvram_data, tgt, bus))
7909 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
7910 		sdp->isp_devparam[tgt].actv_flags = 0;
7911 		sdp->isp_devparam[tgt].goal_offset =
7912 		    sdp->isp_devparam[tgt].nvrm_offset;
7913 		sdp->isp_devparam[tgt].goal_period =
7914 		    sdp->isp_devparam[tgt].nvrm_period;
7915 		sdp->isp_devparam[tgt].goal_flags =
7916 		    sdp->isp_devparam[tgt].nvrm_flags;
7917 	}
7918 }
7919 
7920 static void
isp_parse_nvram_2100(ispsoftc_t * isp,uint8_t * nvram_data)7921 isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
7922 {
7923 	fcparam *fcp = FCPARAM(isp, 0);
7924 	uint64_t wwn;
7925 
7926 	/*
7927 	 * There is NVRAM storage for both Port and Node entities-
7928 	 * but the Node entity appears to be unused on all the cards
7929 	 * I can find. However, we should account for this being set
7930 	 * at some point in the future.
7931 	 *
7932 	 * Qlogic WWNs have an NAA of 2, but usually nothing shows up in
7933 	 * bits 48..60. In the case of the 2202, it appears that they do
7934 	 * use bit 48 to distinguish between the two instances on the card.
7935 	 * The 2204, which I've never seen, *probably* extends this method.
7936 	 */
7937 	wwn = ISP2100_NVRAM_PORT_NAME(nvram_data);
7938 	if (wwn) {
7939 		isp_prt(isp, ISP_LOGCONFIG, "NVRAM Port WWN 0x%08x%08x",
7940 		    (uint32_t) (wwn >> 32), (uint32_t) (wwn));
7941 		if ((wwn >> 60) == 0) {
7942 			wwn |= (((uint64_t) 2)<< 60);
7943 		}
7944 	}
7945 	fcp->isp_wwpn_nvram = wwn;
7946 	if (IS_2200(isp) || IS_23XX(isp)) {
7947 		wwn = ISP2100_NVRAM_NODE_NAME(nvram_data);
7948 		if (wwn) {
7949 			isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
7950 			    (uint32_t) (wwn >> 32),
7951 			    (uint32_t) (wwn));
7952 			if ((wwn >> 60) == 0) {
7953 				wwn |= (((uint64_t) 2)<< 60);
7954 			}
7955 		} else {
7956 			wwn = fcp->isp_wwpn_nvram & ~((uint64_t) 0xfff << 48);
7957 		}
7958 	} else {
7959 		wwn &= ~((uint64_t) 0xfff << 48);
7960 	}
7961 	fcp->isp_wwnn_nvram = wwn;
7962 
7963 	fcp->isp_maxalloc = ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
7964 	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
7965 		DEFAULT_FRAMESIZE(isp) =
7966 		    ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
7967 	}
7968 	fcp->isp_retry_delay = ISP2100_NVRAM_RETRY_DELAY(nvram_data);
7969 	fcp->isp_retry_count = ISP2100_NVRAM_RETRY_COUNT(nvram_data);
7970 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
7971 		fcp->isp_loopid = ISP2100_NVRAM_HARDLOOPID(nvram_data);
7972 	}
7973 	if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
7974 		DEFAULT_EXEC_THROTTLE(isp) =
7975 			ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
7976 	}
7977 	fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
7978 	isp_prt(isp, ISP_LOGDEBUG0,
7979 	    "NVRAM 0x%08x%08x 0x%08x%08x maxalloc %d maxframelen %d",
7980 	    (uint32_t) (fcp->isp_wwnn_nvram >> 32),
7981 	    (uint32_t) fcp->isp_wwnn_nvram,
7982 	    (uint32_t) (fcp->isp_wwpn_nvram >> 32),
7983 	    (uint32_t) fcp->isp_wwpn_nvram,
7984 	    ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data),
7985 	    ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data));
7986 	isp_prt(isp, ISP_LOGDEBUG0,
7987 	    "execthrottle %d fwoptions 0x%x hardloop %d tov %d",
7988 	    ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
7989 	    ISP2100_NVRAM_OPTIONS(nvram_data),
7990 	    ISP2100_NVRAM_HARDLOOPID(nvram_data),
7991 	    ISP2100_NVRAM_TOV(nvram_data));
7992 	fcp->isp_xfwoptions = ISP2100_XFW_OPTIONS(nvram_data);
7993 	fcp->isp_zfwoptions = ISP2100_ZFW_OPTIONS(nvram_data);
7994 	isp_prt(isp, ISP_LOGDEBUG0, "xfwoptions 0x%x zfw options 0x%x",
7995 	    ISP2100_XFW_OPTIONS(nvram_data), ISP2100_ZFW_OPTIONS(nvram_data));
7996 }
7997 
7998 static void
isp_parse_nvram_2400(ispsoftc_t * isp,uint8_t * nvram_data)7999 isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
8000 {
8001 	fcparam *fcp = FCPARAM(isp, 0);
8002 	uint64_t wwn;
8003 
8004 	isp_prt(isp, ISP_LOGDEBUG0,
8005 	    "NVRAM 0x%08x%08x 0x%08x%08x exchg_cnt %d maxframelen %d",
8006 	    (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32),
8007 	    (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)),
8008 	    (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32),
8009 	    (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)),
8010 	    ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data),
8011 	    ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data));
8012 	isp_prt(isp, ISP_LOGDEBUG0,
8013 	    "NVRAM execthr %d loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
8014 	    ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data),
8015 	    ISP2400_NVRAM_HARDLOOPID(nvram_data),
8016 	    ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data),
8017 	    ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data),
8018 	    ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data));
8019 
8020 	wwn = ISP2400_NVRAM_PORT_NAME(nvram_data);
8021 	fcp->isp_wwpn_nvram = wwn;
8022 
8023 	wwn = ISP2400_NVRAM_NODE_NAME(nvram_data);
8024 	if (wwn) {
8025 		if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
8026 			wwn = 0;
8027 		}
8028 	}
8029 	if (wwn == 0 && (fcp->isp_wwpn_nvram >> 60) == 2) {
8030 		wwn = fcp->isp_wwpn_nvram;
8031 		wwn &= ~((uint64_t) 0xfff << 48);
8032 	}
8033 	fcp->isp_wwnn_nvram = wwn;
8034 
8035 	if (ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data)) {
8036 		fcp->isp_maxalloc = ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data);
8037 	}
8038 	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
8039 		DEFAULT_FRAMESIZE(isp) =
8040 		    ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data);
8041 	}
8042 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
8043 		fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data);
8044 	}
8045 	if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
8046 		DEFAULT_EXEC_THROTTLE(isp) =
8047 			ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data);
8048 	}
8049 	fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data);
8050 	fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data);
8051 	fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data);
8052 }
8053