1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /* Copyright 2008 QLogic Corporation */
23 
24 /*
25  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
26  * Use is subject to license terms.
27  */
28 
29 #pragma ident	"Copyright 2008 QLogic Corporation; ql_init.c"
30 
31 /*
32  * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
33  *
34  * ***********************************************************************
35  * *									**
36  * *				NOTICE					**
37  * *		COPYRIGHT (C) 1996-2008 QLOGIC CORPORATION		**
38  * *			ALL RIGHTS RESERVED				**
39  * *									**
40  * ***********************************************************************
41  *
42  */
43 
44 #include <ql_apps.h>
45 #include <ql_api.h>
46 #include <ql_debug.h>
47 #include <ql_init.h>
48 #include <ql_iocb.h>
49 #include <ql_isr.h>
50 #include <ql_mbx.h>
51 #include <ql_xioctl.h>
52 
53 /*
54  * Local data
55  */
56 
57 /*
58  * Local prototypes
59  */
60 static uint16_t ql_nvram_request(ql_adapter_state_t *, uint32_t);
61 static int ql_nvram_24xx_config(ql_adapter_state_t *);
62 static void ql_23_properties(ql_adapter_state_t *, nvram_t *);
63 static void ql_24xx_properties(ql_adapter_state_t *, nvram_24xx_t *);
64 static int ql_check_isp_firmware(ql_adapter_state_t *);
65 static int ql_chip_diag(ql_adapter_state_t *);
66 static int ql_load_flash_fw(ql_adapter_state_t *);
67 static int ql_configure_loop(ql_adapter_state_t *);
68 static int ql_configure_hba(ql_adapter_state_t *);
69 static int ql_configure_fabric(ql_adapter_state_t *);
70 static int ql_configure_device_d_id(ql_adapter_state_t *);
71 static void ql_set_max_read_req(ql_adapter_state_t *);
72 /*
73  * ql_initialize_adapter
74  *	Initialize board.
75  *
76  * Input:
77  *	ha = adapter state pointer.
78  *
79  * Returns:
80  *	ql local function return status code.
81  *
82  * Context:
83  *	Kernel context.
84  */
85 int
86 ql_initialize_adapter(ql_adapter_state_t *ha)
87 {
88 	int			rval;
89 	class_svc_param_t	*class3_param;
90 	caddr_t			msg;
91 	la_els_logi_t		*els = &ha->loginparams;
92 	int			retries = 5;
93 
94 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
95 
96 	do {
97 		/* Clear adapter flags. */
98 		TASK_DAEMON_LOCK(ha);
99 		ha->task_daemon_flags &= TASK_DAEMON_STOP_FLG |
100 		    TASK_DAEMON_SLEEPING_FLG | TASK_DAEMON_ALIVE_FLG |
101 		    TASK_DAEMON_IDLE_CHK_FLG;
102 		ha->task_daemon_flags |= LOOP_DOWN;
103 		TASK_DAEMON_UNLOCK(ha);
104 
105 		ha->loop_down_timer = LOOP_DOWN_TIMER_OFF;
106 		ADAPTER_STATE_LOCK(ha);
107 		ha->flags |= COMMAND_ABORT_TIMEOUT;
108 		ha->flags &= ~ONLINE;
109 		ADAPTER_STATE_UNLOCK(ha);
110 
111 		ha->state = FC_STATE_OFFLINE;
112 		msg = "Loop OFFLINE";
113 
114 		rval = ql_pci_sbus_config(ha);
115 		if (rval != QL_SUCCESS) {
116 			TASK_DAEMON_LOCK(ha);
117 			if (!(ha->task_daemon_flags & ABORT_ISP_ACTIVE)) {
118 				EL(ha, "ql_pci_sbus_cfg, isp_abort_needed\n");
119 				ha->task_daemon_flags |= ISP_ABORT_NEEDED;
120 			}
121 			TASK_DAEMON_UNLOCK(ha);
122 			continue;
123 		}
124 
125 		ql_setup_fcache(ha);
126 
127 		/* Reset ISP chip. */
128 		ql_reset_chip(ha);
129 
130 		/* Get NVRAM configuration if needed. */
131 		if (ha->init_ctrl_blk.cb.version == 0) {
132 			(void) ql_nvram_config(ha);
133 		}
134 
135 		/* Set login parameters. */
136 		if (CFG_IST(ha, CFG_CTRL_2425)) {
137 			els->common_service.rx_bufsize = CHAR_TO_SHORT(
138 			    ha->init_ctrl_blk.cb24.max_frame_length[0],
139 			    ha->init_ctrl_blk.cb24.max_frame_length[1]);
140 			bcopy((void *)&ha->init_ctrl_blk.cb24.port_name[0],
141 			    (void *)&els->nport_ww_name.raw_wwn[0], 8);
142 			bcopy((void *)&ha->init_ctrl_blk.cb24.node_name[0],
143 			    (void *)&els->node_ww_name.raw_wwn[0], 8);
144 		} else {
145 			els->common_service.rx_bufsize = CHAR_TO_SHORT(
146 			    ha->init_ctrl_blk.cb.max_frame_length[0],
147 			    ha->init_ctrl_blk.cb.max_frame_length[1]);
148 			bcopy((void *)&ha->init_ctrl_blk.cb.port_name[0],
149 			    (void *)&els->nport_ww_name.raw_wwn[0], 8);
150 			bcopy((void *)&ha->init_ctrl_blk.cb.node_name[0],
151 			    (void *)&els->node_ww_name.raw_wwn[0], 8);
152 		}
153 
154 		/* Determine which RISC code to use. */
155 		(void) ql_check_isp_firmware(ha);
156 
157 		rval = ql_chip_diag(ha);
158 		if (rval == QL_SUCCESS) {
159 			rval = ql_load_isp_firmware(ha);
160 		}
161 
162 		if (rval == QL_SUCCESS && (rval = ql_set_cache_line(ha)) ==
163 		    QL_SUCCESS && (rval = ql_init_rings(ha)) ==
164 		    QL_SUCCESS) {
165 
166 			(void) ql_fw_ready(ha, ha->fwwait);
167 
168 			if (!(ha->task_daemon_flags & QL_SUSPENDED) &&
169 			    ha->loop_down_timer == LOOP_DOWN_TIMER_OFF) {
170 				if (ha->topology & QL_LOOP_CONNECTION) {
171 					ha->state = ha->state | FC_STATE_LOOP;
172 					msg = "Loop ONLINE";
173 					ha->task_daemon_flags |= STATE_ONLINE;
174 				} else if (ha->topology & QL_P2P_CONNECTION) {
175 					ha->state = ha->state |
176 					    FC_STATE_ONLINE;
177 					msg = "Link ONLINE";
178 					ha->task_daemon_flags |= STATE_ONLINE;
179 				} else {
180 					msg = "Unknown Link state";
181 				}
182 			}
183 		} else {
184 			TASK_DAEMON_LOCK(ha);
185 			if (!(ha->task_daemon_flags & ABORT_ISP_ACTIVE)) {
186 				EL(ha, "failed, isp_abort_needed\n");
187 				ha->task_daemon_flags |= ISP_ABORT_NEEDED |
188 				    LOOP_DOWN;
189 			}
190 			TASK_DAEMON_UNLOCK(ha);
191 		}
192 
193 	} while (retries-- != 0 && ha->task_daemon_flags & ISP_ABORT_NEEDED);
194 
195 	cmn_err(CE_NOTE, "!Qlogic %s(%d): %s", QL_NAME, ha->instance, msg);
196 
197 	/* Enable ISP interrupts and login parameters. */
198 	CFG_IST(ha, CFG_CTRL_2425) ? WRT32_IO_REG(ha, ictrl, ISP_EN_RISC):
199 	    WRT16_IO_REG(ha, ictrl, ISP_EN_INT + ISP_EN_RISC);
200 
201 	ADAPTER_STATE_LOCK(ha);
202 	ha->flags |= (INTERRUPTS_ENABLED | ONLINE);
203 	ADAPTER_STATE_UNLOCK(ha);
204 
205 	ha->task_daemon_flags &= ~(FC_STATE_CHANGE | RESET_MARKER_NEEDED |
206 	    COMMAND_WAIT_NEEDED);
207 
208 	/*
209 	 * Setup login parameters.
210 	 */
211 	els->common_service.fcph_version = 0x2006;
212 	els->common_service.btob_credit = 3;
213 	els->common_service.cmn_features = 0x8800;
214 	els->common_service.conc_sequences = 0xff;
215 	els->common_service.relative_offset = 3;
216 	els->common_service.e_d_tov = 0x07d0;
217 
218 	class3_param = (class_svc_param_t *)&els->class_3;
219 	class3_param->class_valid_svc_opt = 0x8800;
220 	class3_param->rcv_data_size = els->common_service.rx_bufsize;
221 	class3_param->conc_sequences = 0xff;
222 
223 	if (rval != QL_SUCCESS) {
224 		EL(ha, "failed, rval = %xh\n", rval);
225 	} else {
226 		/*EMPTY*/
227 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
228 	}
229 	return (rval);
230 }
231 
232 /*
233  * ql_pci_sbus_config
234  *	Setup device PCI/SBUS configuration registers.
235  *
236  * Input:
237  *	ha = adapter state pointer.
238  *
239  * Returns:
240  *	ql local function return status code.
241  *
242  * Context:
243  *	Kernel context.
244  */
245 int
246 ql_pci_sbus_config(ql_adapter_state_t *ha)
247 {
248 	uint32_t	timer;
249 	uint16_t	cmd, w16;
250 
251 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
252 
253 	if (CFG_IST(ha, CFG_SBUS_CARD)) {
254 		w16 = (uint16_t)ddi_get16(ha->sbus_fpga_dev_handle,
255 		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_REVISION));
256 		EL(ha, "FPGA rev is %d.%d", (w16 & 0xf0) >> 4,
257 		    w16 & 0xf);
258 	} else {
259 		/*
260 		 * we want to respect framework's setting of PCI
261 		 * configuration space command register and also
262 		 * want to make sure that all bits of interest to us
263 		 * are properly set in command register.
264 		 */
265 		cmd = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_COMM);
266 		cmd = (uint16_t)(cmd | PCI_COMM_IO | PCI_COMM_MAE |
267 		    PCI_COMM_ME | PCI_COMM_MEMWR_INVAL |
268 		    PCI_COMM_PARITY_DETECT | PCI_COMM_SERR_ENABLE);
269 
270 		/*
271 		 * If this is a 2300 card and not 2312, reset the
272 		 * MEMWR_INVAL due to a bug in the 2300. Unfortunately, the
273 		 * 2310 also reports itself as a 2300 so we need to get the
274 		 * fb revision level -- a 6 indicates it really is a 2300 and
275 		 * not a 2310.
276 		 */
277 
278 		if (ha->device_id == 0x2300) {
279 			/* Pause RISC. */
280 			WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC);
281 			for (timer = 0; timer < 30000; timer++) {
282 				if ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) !=
283 				    0) {
284 					break;
285 				} else {
286 					drv_usecwait(MILLISEC);
287 				}
288 			}
289 
290 			/* Select FPM registers. */
291 			WRT16_IO_REG(ha, ctrl_status, 0x20);
292 
293 			/* Get the fb rev level */
294 			if (RD16_IO_REG(ha, fb_cmd) == 6) {
295 				cmd = (uint16_t)(cmd & ~PCI_COMM_MEMWR_INVAL);
296 			}
297 
298 			/* Deselect FPM registers. */
299 			WRT16_IO_REG(ha, ctrl_status, 0x0);
300 
301 			/* Release RISC module. */
302 			WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
303 			for (timer = 0; timer < 30000; timer++) {
304 				if ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) ==
305 				    0) {
306 					break;
307 				} else {
308 					drv_usecwait(MILLISEC);
309 				}
310 			}
311 		} else if (ha->device_id == 0x2312) {
312 			/*
313 			 * cPCI ISP2312 specific code to service function 1
314 			 * hot-swap registers.
315 			 */
316 			if ((RD16_IO_REG(ha, ctrl_status) & ISP_FUNC_NUM_MASK)
317 			    != 0) {
318 				ql_pci_config_put8(ha, 0x66, 0xc2);
319 			}
320 		}
321 
322 		/* max memory read byte cnt override */
323 		if (ha->pci_max_read_req != 0) {
324 			ql_set_max_read_req(ha);
325 		}
326 
327 		ql_pci_config_put16(ha, PCI_CONF_COMM, cmd);
328 
329 		/* Set cache line register. */
330 		ql_pci_config_put8(ha, PCI_CONF_CACHE_LINESZ, 0x10);
331 
332 		/* Set latency register. */
333 		ql_pci_config_put8(ha, PCI_CONF_LATENCY_TIMER, 0x40);
334 
335 		/* Reset expansion ROM address decode enable. */
336 		w16 = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_ROM);
337 		w16 = (uint16_t)(w16 & ~BIT_0);
338 		ql_pci_config_put16(ha, PCI_CONF_ROM, w16);
339 	}
340 
341 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
342 
343 	return (QL_SUCCESS);
344 }
345 
346 /*
347  * Set the PCI max read request value.
348  *
349  * Input:
350  *	ha:		adapter state pointer.
351  *
352  * Output:
353  *	none.
354  *
355  * Returns:
356  *
357  * Context:
358  *	Kernel context.
359  */
360 
361 static void
362 ql_set_max_read_req(ql_adapter_state_t *ha)
363 {
364 	uint16_t	read_req, w16;
365 	uint16_t	tmp = ha->pci_max_read_req;
366 
367 	if ((ha->device_id == 0x2422) ||
368 	    ((ha->device_id & 0xff00) == 0x2300)) {
369 		/* check for vaild override value */
370 		if (tmp == 512 || tmp == 1024 || tmp == 2048 ||
371 		    tmp == 4096) {
372 			/* shift away the don't cares */
373 			tmp = (uint16_t)(tmp >> 10);
374 			/* convert bit pos to request value */
375 			for (read_req = 0; tmp != 0; read_req++) {
376 				tmp = (uint16_t)(tmp >> 1);
377 			}
378 			w16 = (uint16_t)ql_pci_config_get16(ha, 0x4e);
379 			w16 = (uint16_t)(w16 & ~(BIT_3 & BIT_2));
380 			w16 = (uint16_t)(w16 | (read_req << 2));
381 			ql_pci_config_put16(ha, 0x4e, w16);
382 		} else {
383 			EL(ha, "invalid parameter value for "
384 			    "'pci-max-read-request': %d; using system "
385 			    "default\n", tmp);
386 		}
387 	} else if ((ha->device_id == 0x2432) || ((ha->device_id & 0xff00) ==
388 	    0x2500)) {
389 		/* check for vaild override value */
390 		if (tmp == 128 || tmp == 256 || tmp == 512 ||
391 		    tmp == 1024 || tmp == 2048 || tmp == 4096) {
392 			/* shift away the don't cares */
393 			tmp = (uint16_t)(tmp >> 8);
394 			/* convert bit pos to request value */
395 			for (read_req = 0; tmp != 0; read_req++) {
396 				tmp = (uint16_t)(tmp >> 1);
397 			}
398 			w16 = (uint16_t)ql_pci_config_get16(ha, 0x54);
399 			w16 = (uint16_t)(w16 & ~(BIT_14 | BIT_13 |
400 			    BIT_12));
401 			w16 = (uint16_t)(w16 | (read_req << 12));
402 			ql_pci_config_put16(ha, 0x54, w16);
403 		} else {
404 			EL(ha, "invalid parameter value for "
405 			    "'pci-max-read-request': %d; using system "
406 			    "default\n", tmp);
407 		}
408 	}
409 }
410 
411 /*
412  * NVRAM configuration.
413  *
414  * Input:
415  *	ha:		adapter state pointer.
416  *	ha->hba_buf = request and response rings
417  *
418  * Output:
419  *	ha->init_ctrl_blk = initialization control block
420  *	host adapters parameters in host adapter block
421  *
422  * Returns:
423  *	ql local function return status code.
424  *
425  * Context:
426  *	Kernel context.
427  */
428 int
429 ql_nvram_config(ql_adapter_state_t *ha)
430 {
431 	uint32_t	cnt;
432 	caddr_t		dptr1, dptr2;
433 	ql_init_cb_t	*icb = &ha->init_ctrl_blk.cb;
434 	ql_ip_init_cb_t	*ip_icb = &ha->ip_init_ctrl_blk.cb;
435 	nvram_t		*nv = (nvram_t *)ha->request_ring_bp;
436 	uint16_t	*wptr = (uint16_t *)ha->request_ring_bp;
437 	uint8_t		chksum = 0;
438 	int		rval;
439 	int		idpromlen;
440 	char		idprombuf[32];
441 	uint32_t	start_addr;
442 
443 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
444 
445 	if (CFG_IST(ha, CFG_CTRL_2425)) {
446 		return (ql_nvram_24xx_config(ha));
447 	}
448 
449 	start_addr = 0;
450 	if ((rval = ql_lock_nvram(ha, &start_addr, LNF_NVRAM_DATA)) ==
451 	    QL_SUCCESS) {
452 		/* Verify valid NVRAM checksum. */
453 		for (cnt = 0; cnt < sizeof (nvram_t)/2; cnt++) {
454 			*wptr = (uint16_t)ql_get_nvram_word(ha,
455 			    (uint32_t)(cnt + start_addr));
456 			chksum = (uint8_t)(chksum + (uint8_t)*wptr);
457 			chksum = (uint8_t)(chksum + (uint8_t)(*wptr >> 8));
458 			wptr++;
459 		}
460 		ql_release_nvram(ha);
461 	}
462 
463 	/* Bad NVRAM data, set defaults parameters. */
464 	if (rval != QL_SUCCESS || chksum || nv->id[0] != 'I' ||
465 	    nv->id[1] != 'S' || nv->id[2] != 'P' || nv->id[3] != ' ' ||
466 	    nv->nvram_version < 1) {
467 
468 		EL(ha, "failed, rval=%xh, checksum=%xh, "
469 		    "id=%02x%02x%02x%02xh, flsz=%xh, pciconfvid=%xh, "
470 		    "nvram_version=%x\n", rval, chksum, nv->id[0], nv->id[1],
471 		    nv->id[2], nv->id[3], ha->xioctl->fdesc.flash_size,
472 		    ha->subven_id, nv->nvram_version);
473 
474 		/* Don't print nvram message if it's an on-board 2200 */
475 		if (!((CFG_IST(ha, CFG_CTRL_2200)) &&
476 		    (ha->xioctl->fdesc.flash_size == 0))) {
477 			cmn_err(CE_WARN, "%s(%d): NVRAM configuration failed,"
478 			    " using driver defaults.", QL_NAME, ha->instance);
479 		}
480 
481 		/* Reset NVRAM data. */
482 		bzero((void *)nv, sizeof (nvram_t));
483 
484 		/*
485 		 * Set default initialization control block.
486 		 */
487 		nv->parameter_block_version = ICB_VERSION;
488 		nv->firmware_options[0] = BIT_4 | BIT_3 | BIT_2 | BIT_1;
489 		nv->firmware_options[1] = BIT_7 | BIT_5 | BIT_2;
490 
491 		nv->max_frame_length[1] = 4;
492 
493 		/*
494 		 * Allow 2048 byte frames for 2300
495 		 */
496 		if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
497 			nv->max_frame_length[1] = 8;
498 		}
499 		nv->max_iocb_allocation[1] = 1;
500 		nv->execution_throttle[0] = 16;
501 		nv->login_retry_count = 8;
502 
503 		idpromlen = 32;
504 
505 		/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
506 		if (ddi_getlongprop_buf(DDI_DEV_T_ANY, ha->dip,
507 		    DDI_PROP_CANSLEEP, "idprom", (caddr_t)idprombuf,
508 		    &idpromlen) != DDI_PROP_SUCCESS) {
509 
510 			QL_PRINT_3(CE_CONT, "(%d): Unable to read idprom "
511 			    "property\n", ha->instance);
512 			cmn_err(CE_WARN, "%s(%d) : Unable to read idprom "
513 			    "property", QL_NAME, ha->instance);
514 
515 			nv->port_name[2] = 33;
516 			nv->port_name[3] = 224;
517 			nv->port_name[4] = 139;
518 			nv->port_name[7] = (uint8_t)
519 			    (NAA_ID_IEEE_EXTENDED << 4 | ha->instance);
520 
521 		} else {
522 
523 			nv->port_name[2] = idprombuf[2];
524 			nv->port_name[3] = idprombuf[3];
525 			nv->port_name[4] = idprombuf[4];
526 			nv->port_name[5] = idprombuf[5];
527 			nv->port_name[6] = idprombuf[6];
528 			nv->port_name[7] = idprombuf[7];
529 			nv->port_name[0] = (uint8_t)
530 			    (NAA_ID_IEEE_EXTENDED << 4 | ha->instance);
531 
532 		}
533 
534 		/* Don't print nvram message if it's an on-board 2200 */
535 		if (!(CFG_IST(ha, CFG_CTRL_2200)) &&
536 		    (ha->xioctl->fdesc.flash_size == 0)) {
537 			cmn_err(CE_WARN, "%s(%d): Unreliable HBA NVRAM, using"
538 			    " default HBA parameters and temporary WWPN:"
539 			    " %02x%02x%02x%02x%02x%02x%02x%02x", QL_NAME,
540 			    ha->instance, nv->port_name[0], nv->port_name[1],
541 			    nv->port_name[2], nv->port_name[3],
542 			    nv->port_name[4], nv->port_name[5],
543 			    nv->port_name[6], nv->port_name[7]);
544 		}
545 
546 		nv->login_timeout = 4;
547 
548 		/* Set default connection options for the 23xx to 2 */
549 		if (!(CFG_IST(ha, CFG_CTRL_2200))) {
550 			nv->add_fw_opt[0] = (uint8_t)(nv->add_fw_opt[0] |
551 			    BIT_5);
552 		}
553 
554 		/*
555 		 * Set default host adapter parameters
556 		 */
557 		nv->host_p[0] = BIT_1;
558 		nv->host_p[1] = BIT_2;
559 		nv->reset_delay = 5;
560 		nv->port_down_retry_count = 8;
561 		nv->maximum_luns_per_target[0] = 8;
562 
563 		rval = QL_FUNCTION_FAILED;
564 	}
565 
566 	/* Check for adapter node name (big endian). */
567 	for (cnt = 0; cnt < 8; cnt++) {
568 		if (nv->node_name[cnt] != 0) {
569 			break;
570 		}
571 	}
572 
573 	/* Copy port name if no node name (big endian). */
574 	if (cnt == 8) {
575 		bcopy((void *)&nv->port_name[0], (void *)&nv->node_name[0], 8);
576 		nv->node_name[0] = (uint8_t)(nv->node_name[0] & ~BIT_0);
577 		nv->port_name[0] = (uint8_t)(nv->node_name[0] | BIT_0);
578 	}
579 
580 	/* Reset initialization control blocks. */
581 	bzero((void *)icb, sizeof (ql_init_cb_t));
582 
583 	/* Get driver properties. */
584 	ql_23_properties(ha, nv);
585 
586 	cmn_err(CE_CONT, "!Qlogic %s(%d) WWPN=%02x%02x%02x%02x"
587 	    "%02x%02x%02x%02x : WWNN=%02x%02x%02x%02x%02x%02x%02x%02x\n",
588 	    QL_NAME, ha->instance, nv->port_name[0], nv->port_name[1],
589 	    nv->port_name[2], nv->port_name[3], nv->port_name[4],
590 	    nv->port_name[5], nv->port_name[6], nv->port_name[7],
591 	    nv->node_name[0], nv->node_name[1], nv->node_name[2],
592 	    nv->node_name[3], nv->node_name[4], nv->node_name[5],
593 	    nv->node_name[6], nv->node_name[7]);
594 
595 	/*
596 	 * Copy over NVRAM RISC parameter block
597 	 * to initialization control block.
598 	 */
599 	dptr1 = (caddr_t)icb;
600 	dptr2 = (caddr_t)&nv->parameter_block_version;
601 	cnt = (uint32_t)((uintptr_t)&icb->request_q_outpointer[0] -
602 	    (uintptr_t)&icb->version);
603 	while (cnt-- != 0) {
604 		*dptr1++ = *dptr2++;
605 	}
606 
607 	/* Copy 2nd half. */
608 	dptr1 = (caddr_t)&icb->add_fw_opt[0];
609 	cnt = (uint32_t)((uintptr_t)&icb->reserved_3[0] -
610 	    (uintptr_t)&icb->add_fw_opt[0]);
611 
612 	while (cnt-- != 0) {
613 		*dptr1++ = *dptr2++;
614 	}
615 
616 	/*
617 	 * Setup driver firmware options.
618 	 */
619 	icb->firmware_options[0] = (uint8_t)
620 	    (icb->firmware_options[0] | BIT_6 | BIT_1);
621 
622 	/*
623 	 * There is no use enabling fast post for SBUS or 2300
624 	 */
625 	if (CFG_IST(ha, (CFG_SBUS_CARD | CFG_CTRL_2300 | CFG_CTRL_6322))) {
626 		icb->firmware_options[0] = (uint8_t)
627 		    (icb->firmware_options[0] & ~BIT_3);
628 		if (CFG_IST(ha, CFG_SBUS_CARD)) {
629 			icb->special_options[0] = (uint8_t)
630 			    (icb->special_options[0] | BIT_5);
631 		}
632 	} else {
633 		icb->firmware_options[0] = (uint8_t)
634 		    (icb->firmware_options[0] | BIT_3);
635 	}
636 	/* RIO and ZIO not supported. */
637 	icb->add_fw_opt[0] = (uint8_t)(icb->add_fw_opt[0] &
638 	    ~(BIT_3 | BIT_2 | BIT_1 | BIT_0));
639 
640 	icb->firmware_options[1] = (uint8_t)(icb->firmware_options[1] |
641 	    BIT_7 | BIT_6 | BIT_5 | BIT_2 | BIT_0);
642 	icb->firmware_options[0] = (uint8_t)
643 	    (icb->firmware_options[0] & ~(BIT_5 | BIT_4));
644 	icb->firmware_options[1] = (uint8_t)
645 	    (icb->firmware_options[1] & ~BIT_4);
646 
647 	icb->add_fw_opt[1] = (uint8_t)(icb->add_fw_opt[1] & ~(BIT_5 | BIT_4));
648 	icb->special_options[0] = (uint8_t)(icb->special_options[0] | BIT_1);
649 
650 	if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
651 		if ((icb->special_options[1] & 0x20) == 0) {
652 			EL(ha, "50 ohm is not set\n");
653 		}
654 	}
655 	icb->execution_throttle[0] = 0xff;
656 	icb->execution_throttle[1] = 0xff;
657 
658 	if (CFG_IST(ha, CFG_TARGET_MODE_ENABLE)) {
659 		icb->firmware_options[0] = (uint8_t)
660 		    (icb->firmware_options[0] | BIT_4 | BIT_7);
661 		icb->inquiry = 0x1F;
662 		EL(ha, "Target mode enabled");
663 	}
664 
665 	if (CFG_IST(ha, CFG_ENABLE_FCP_2_SUPPORT)) {
666 		icb->firmware_options[1] = (uint8_t)
667 		    (icb->firmware_options[1] | BIT_7 | BIT_6);
668 		icb->add_fw_opt[1] = (uint8_t)
669 		    (icb->add_fw_opt[1] | BIT_5 | BIT_4);
670 	}
671 
672 	/*
673 	 * Set host adapter parameters
674 	 */
675 	ADAPTER_STATE_LOCK(ha);
676 	ha->nvram_version = nv->nvram_version;
677 	ha->adapter_features = CHAR_TO_SHORT(nv->adapter_features[0],
678 	    nv->adapter_features[1]);
679 
680 	nv->host_p[0] & BIT_4 ? (ha->cfg_flags |= CFG_DISABLE_RISC_CODE_LOAD) :
681 	    (ha->cfg_flags &= ~CFG_DISABLE_RISC_CODE_LOAD);
682 	nv->host_p[0] & BIT_5 ? (ha->cfg_flags |= CFG_SET_CACHE_LINE_SIZE_1) :
683 	    (ha->cfg_flags &= ~CFG_SET_CACHE_LINE_SIZE_1);
684 
685 	/* Always enable 64bit addressing, except SBUS cards. */
686 	if (CFG_IST(ha, CFG_SBUS_CARD)) {
687 		ha->cfg_flags &= ~CFG_ENABLE_64BIT_ADDRESSING;
688 		ha->cmd_segs = CMD_TYPE_2_DATA_SEGMENTS;
689 		ha->cmd_cont_segs = CONT_TYPE_0_DATA_SEGMENTS;
690 	} else {
691 		ha->cfg_flags |= CFG_ENABLE_64BIT_ADDRESSING;
692 		ha->cmd_segs = CMD_TYPE_3_DATA_SEGMENTS;
693 		ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
694 	}
695 
696 	nv->host_p[1] & BIT_1 ? (ha->cfg_flags |= CFG_ENABLE_LIP_RESET) :
697 	    (ha->cfg_flags &= ~CFG_ENABLE_LIP_RESET);
698 	nv->host_p[1] & BIT_2 ? (ha->cfg_flags |= CFG_ENABLE_FULL_LIP_LOGIN) :
699 	    (ha->cfg_flags &= ~CFG_ENABLE_FULL_LIP_LOGIN);
700 	nv->host_p[1] & BIT_3 ? (ha->cfg_flags |= CFG_ENABLE_TARGET_RESET) :
701 	    (ha->cfg_flags &= ~CFG_ENABLE_TARGET_RESET);
702 
703 	nv->adapter_features[0] & BIT_3 ?
704 	    (ha->cfg_flags |= CFG_MULTI_CHIP_ADAPTER) :
705 	    (ha->cfg_flags &= ~CFG_MULTI_CHIP_ADAPTER);
706 
707 	ADAPTER_STATE_UNLOCK(ha);
708 
709 	ha->execution_throttle = CHAR_TO_SHORT(nv->execution_throttle[0],
710 	    nv->execution_throttle[1]);
711 	ha->loop_reset_delay = nv->reset_delay;
712 	ha->port_down_retry_count = nv->port_down_retry_count;
713 	ha->r_a_tov = (uint16_t)(icb->login_timeout < R_A_TOV_DEFAULT ?
714 	    R_A_TOV_DEFAULT : icb->login_timeout);
715 	ha->maximum_luns_per_target = CHAR_TO_SHORT(
716 	    nv->maximum_luns_per_target[0], nv->maximum_luns_per_target[1]);
717 	if (ha->maximum_luns_per_target == 0) {
718 		ha->maximum_luns_per_target++;
719 	}
720 
721 	/*
722 	 * Setup ring parameters in initialization control block
723 	 */
724 	cnt = REQUEST_ENTRY_CNT;
725 	icb->request_q_length[0] = LSB(cnt);
726 	icb->request_q_length[1] = MSB(cnt);
727 	cnt = RESPONSE_ENTRY_CNT;
728 	icb->response_q_length[0] = LSB(cnt);
729 	icb->response_q_length[1] = MSB(cnt);
730 
731 	icb->request_q_address[0] = LSB(LSW(LSD(ha->request_dvma)));
732 	icb->request_q_address[1] = MSB(LSW(LSD(ha->request_dvma)));
733 	icb->request_q_address[2] = LSB(MSW(LSD(ha->request_dvma)));
734 	icb->request_q_address[3] = MSB(MSW(LSD(ha->request_dvma)));
735 	icb->request_q_address[4] = LSB(LSW(MSD(ha->request_dvma)));
736 	icb->request_q_address[5] = MSB(LSW(MSD(ha->request_dvma)));
737 	icb->request_q_address[6] = LSB(MSW(MSD(ha->request_dvma)));
738 	icb->request_q_address[7] = MSB(MSW(MSD(ha->request_dvma)));
739 
740 	icb->response_q_address[0] = LSB(LSW(LSD(ha->response_dvma)));
741 	icb->response_q_address[1] = MSB(LSW(LSD(ha->response_dvma)));
742 	icb->response_q_address[2] = LSB(MSW(LSD(ha->response_dvma)));
743 	icb->response_q_address[3] = MSB(MSW(LSD(ha->response_dvma)));
744 	icb->response_q_address[4] = LSB(LSW(MSD(ha->response_dvma)));
745 	icb->response_q_address[5] = MSB(LSW(MSD(ha->response_dvma)));
746 	icb->response_q_address[6] = LSB(MSW(MSD(ha->response_dvma)));
747 	icb->response_q_address[7] = MSB(MSW(MSD(ha->response_dvma)));
748 
749 	/*
750 	 * Setup IP initialization control block
751 	 */
752 	ip_icb->version = IP_ICB_VERSION;
753 
754 	if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
755 		ip_icb->ip_firmware_options[0] = (uint8_t)
756 		    (ip_icb->ip_firmware_options[0] | BIT_2 | BIT_0);
757 	} else {
758 		ip_icb->ip_firmware_options[0] = (uint8_t)
759 		    (ip_icb->ip_firmware_options[0] | BIT_2);
760 	}
761 
762 	cnt = RCVBUF_CONTAINER_CNT;
763 	ip_icb->queue_size[0] = LSB(cnt);
764 	ip_icb->queue_size[1] = MSB(cnt);
765 
766 	ip_icb->queue_address[0] = LSB(LSW(LSD(ha->rcvbuf_dvma)));
767 	ip_icb->queue_address[1] = MSB(LSW(LSD(ha->rcvbuf_dvma)));
768 	ip_icb->queue_address[2] = LSB(MSW(LSD(ha->rcvbuf_dvma)));
769 	ip_icb->queue_address[3] = MSB(MSW(LSD(ha->rcvbuf_dvma)));
770 	ip_icb->queue_address[4] = LSB(LSW(MSD(ha->rcvbuf_dvma)));
771 	ip_icb->queue_address[5] = MSB(LSW(MSD(ha->rcvbuf_dvma)));
772 	ip_icb->queue_address[6] = LSB(MSW(MSD(ha->rcvbuf_dvma)));
773 	ip_icb->queue_address[7] = MSB(MSW(MSD(ha->rcvbuf_dvma)));
774 
775 	if (rval != QL_SUCCESS) {
776 		EL(ha, "failed, rval = %xh\n", rval);
777 	} else {
778 		/*EMPTY*/
779 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
780 	}
781 	return (rval);
782 }
783 
784 /*
785  * Get NVRAM data word
786  *	Calculates word position in NVRAM and calls request routine to
787  *	get the word from NVRAM.
788  *
789  * Input:
790  *	ha = adapter state pointer.
791  *	address = NVRAM word address.
792  *
793  * Returns:
794  *	data word.
795  *
796  * Context:
797  *	Kernel context.
798  */
799 uint16_t
800 ql_get_nvram_word(ql_adapter_state_t *ha, uint32_t address)
801 {
802 	uint32_t	nv_cmd;
803 	uint16_t	rval;
804 
805 	QL_PRINT_4(CE_CONT, "(%d): started\n", ha->instance);
806 
807 	nv_cmd = address << 16;
808 	nv_cmd = nv_cmd | NV_READ_OP;
809 
810 	rval = (uint16_t)ql_nvram_request(ha, nv_cmd);
811 
812 	QL_PRINT_4(CE_CONT, "(%d): NVRAM data = %xh\n", ha->instance, rval);
813 
814 	return (rval);
815 }
816 
817 /*
818  * NVRAM request
819  *	Sends read command to NVRAM and gets data from NVRAM.
820  *
821  * Input:
822  *	ha = adapter state pointer.
823  *	nv_cmd = Bit 26= start bit
824  *	Bit 25, 24 = opcode
825  *	Bit 23-16 = address
826  *	Bit 15-0 = write data
827  *
828  * Returns:
829  *	data word.
830  *
831  * Context:
832  *	Kernel context.
833  */
834 static uint16_t
835 ql_nvram_request(ql_adapter_state_t *ha, uint32_t nv_cmd)
836 {
837 	uint8_t		cnt;
838 	uint16_t	reg_data;
839 	uint16_t	data = 0;
840 
841 	/* Send command to NVRAM. */
842 
843 	nv_cmd <<= 5;
844 	for (cnt = 0; cnt < 11; cnt++) {
845 		if (nv_cmd & BIT_31) {
846 			ql_nv_write(ha, NV_DATA_OUT);
847 		} else {
848 			ql_nv_write(ha, 0);
849 		}
850 		nv_cmd <<= 1;
851 	}
852 
853 	/* Read data from NVRAM. */
854 
855 	for (cnt = 0; cnt < 16; cnt++) {
856 		WRT16_IO_REG(ha, nvram, NV_SELECT+NV_CLOCK);
857 		ql_nv_delay();
858 		data <<= 1;
859 		reg_data = RD16_IO_REG(ha, nvram);
860 		if (reg_data & NV_DATA_IN) {
861 			data = (uint16_t)(data | BIT_0);
862 		}
863 		WRT16_IO_REG(ha, nvram, NV_SELECT);
864 		ql_nv_delay();
865 	}
866 
867 	/* Deselect chip. */
868 
869 	WRT16_IO_REG(ha, nvram, NV_DESELECT);
870 	ql_nv_delay();
871 
872 	return (data);
873 }
874 
875 void
876 ql_nv_write(ql_adapter_state_t *ha, uint16_t data)
877 {
878 	WRT16_IO_REG(ha, nvram, (uint16_t)(data | NV_SELECT));
879 	ql_nv_delay();
880 	WRT16_IO_REG(ha, nvram, (uint16_t)(data | NV_SELECT | NV_CLOCK));
881 	ql_nv_delay();
882 	WRT16_IO_REG(ha, nvram, (uint16_t)(data | NV_SELECT));
883 	ql_nv_delay();
884 }
885 
886 void
887 ql_nv_delay(void) {
888 	drv_usecwait(NV_DELAY_COUNT);
889 }
890 
891 /*
892  * ql_nvram_24xx_config
893  *	ISP2400 nvram.
894  *
895  * Input:
896  *	ha:		adapter state pointer.
897  *	ha->hba_buf = request and response rings
898  *
899  * Output:
900  *	ha->init_ctrl_blk = initialization control block
901  *	host adapters parameters in host adapter block
902  *
903  * Returns:
904  *	ql local function return status code.
905  *
906  * Context:
907  *	Kernel context.
908  */
909 int
910 ql_nvram_24xx_config(ql_adapter_state_t *ha)
911 {
912 	uint32_t		index, addr, chksum, saved_chksum;
913 	uint32_t		*longptr;
914 	nvram_24xx_t		nvram;
915 	int			idpromlen;
916 	char			idprombuf[32];
917 	caddr_t			src, dst;
918 	uint16_t		w1;
919 	int			rval;
920 	nvram_24xx_t		*nv = (nvram_24xx_t *)&nvram;
921 	ql_init_24xx_cb_t	*icb =
922 	    (ql_init_24xx_cb_t *)&ha->init_ctrl_blk.cb24;
923 	ql_ip_init_24xx_cb_t	*ip_icb = &ha->ip_init_ctrl_blk.cb24;
924 
925 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
926 
927 	if ((rval = ql_lock_nvram(ha, &addr, LNF_NVRAM_DATA)) == QL_SUCCESS) {
928 
929 		/* Get NVRAM data and calculate checksum. */
930 		longptr = (uint32_t *)nv;
931 		chksum = saved_chksum = 0;
932 		for (index = 0; index < sizeof (nvram_24xx_t) / 4; index++) {
933 			rval = ql_24xx_read_flash(ha, addr++, longptr);
934 			if (rval != QL_SUCCESS) {
935 				EL(ha, "24xx_read_flash failed=%xh\n", rval);
936 				break;
937 			}
938 			saved_chksum = chksum;
939 			chksum += *longptr;
940 			LITTLE_ENDIAN_32(longptr);
941 			longptr++;
942 		}
943 
944 		ql_release_nvram(ha);
945 	}
946 
947 	/* Bad NVRAM data, set defaults parameters. */
948 	if (rval != QL_SUCCESS || chksum || nv->id[0] != 'I' ||
949 	    nv->id[1] != 'S' || nv->id[2] != 'P' || nv->id[3] != ' ' ||
950 	    (nv->nvram_version[0] | nv->nvram_version[1]) == 0) {
951 
952 		cmn_err(CE_WARN, "%s(%d): NVRAM configuration failed, using "
953 		    "driver defaults.", QL_NAME, ha->instance);
954 
955 		EL(ha, "failed, rval=%xh, checksum=%xh, id=%c%c%c%c, "
956 		    "nvram_version=%x\n", rval, chksum, nv->id[0], nv->id[1],
957 		    nv->id[2], nv->id[3], CHAR_TO_SHORT(nv->nvram_version[0],
958 		    nv->nvram_version[1]));
959 
960 		saved_chksum = ~saved_chksum + 1;
961 
962 		(void) ql_flash_errlog(ha, FLASH_ERRLOG_NVRAM_CHKSUM_ERR, 0,
963 		    MSW(saved_chksum), LSW(saved_chksum));
964 
965 		/* Reset NVRAM data. */
966 		bzero((void *)nv, sizeof (nvram_24xx_t));
967 
968 		/*
969 		 * Set default initialization control block.
970 		 */
971 		nv->nvram_version[0] = LSB(ICB_24XX_VERSION);
972 		nv->nvram_version[1] = MSB(ICB_24XX_VERSION);
973 
974 		nv->version[0] = 1;
975 		nv->max_frame_length[1] = 8;
976 		nv->execution_throttle[0] = 16;
977 		nv->max_luns_per_target[0] = 8;
978 
979 		idpromlen = 32;
980 
981 		/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
982 		if (ddi_getlongprop_buf(DDI_DEV_T_ANY, ha->dip,
983 		    DDI_PROP_CANSLEEP, "idprom", (caddr_t)idprombuf,
984 		    &idpromlen) != DDI_PROP_SUCCESS) {
985 
986 			cmn_err(CE_WARN, "%s(%d) : Unable to read idprom "
987 			    "property", QL_NAME, ha->instance);
988 
989 			nv->port_name[0] = 33;
990 			nv->port_name[3] = 224;
991 			nv->port_name[4] = 139;
992 			nv->port_name[7] = (uint8_t)
993 			    (NAA_ID_IEEE_EXTENDED << 4 | ha->instance);
994 
995 		} else {
996 			nv->port_name[2] = idprombuf[2];
997 			nv->port_name[3] = idprombuf[3];
998 			nv->port_name[4] = idprombuf[4];
999 			nv->port_name[5] = idprombuf[5];
1000 			nv->port_name[6] = idprombuf[6];
1001 			nv->port_name[7] = idprombuf[7];
1002 			nv->port_name[0] = (uint8_t)
1003 			    (NAA_ID_IEEE_EXTENDED << 4 | ha->instance);
1004 
1005 		}
1006 
1007 		cmn_err(CE_WARN, "%s(%d): Unreliable HBA NVRAM, using default "
1008 		    "HBA parameters and temporary "
1009 		    "WWPN: %02x%02x%02x%02x%02x%02x%02x%02x", QL_NAME,
1010 		    ha->instance, nv->port_name[0], nv->port_name[1],
1011 		    nv->port_name[2], nv->port_name[3], nv->port_name[4],
1012 		    nv->port_name[5], nv->port_name[6], nv->port_name[7]);
1013 
1014 
1015 		nv->login_retry_count[0] = 8;
1016 
1017 		nv->firmware_options_1[0] = BIT_2 | BIT_1;
1018 		nv->firmware_options_1[1] = BIT_5;
1019 		nv->firmware_options_2[0] = BIT_5;
1020 		nv->firmware_options_2[1] = BIT_4;
1021 		nv->firmware_options_3[1] = BIT_6;
1022 
1023 		/*
1024 		 * Set default host adapter parameters
1025 		 */
1026 		nv->host_p[0] = BIT_4 | BIT_1;
1027 		nv->host_p[1] = BIT_3 | BIT_2;
1028 		nv->reset_delay = 5;
1029 		nv->max_luns_per_target[0] = 128;
1030 		nv->port_down_retry_count[0] = 30;
1031 		nv->link_down_timeout[0] = 30;
1032 
1033 		rval = QL_FUNCTION_FAILED;
1034 	}
1035 
1036 	/* Check for adapter node name (big endian). */
1037 	for (index = 0; index < 8; index++) {
1038 		if (nv->node_name[index] != 0) {
1039 			break;
1040 		}
1041 	}
1042 
1043 	/* Copy port name if no node name (big endian). */
1044 	if (index == 8) {
1045 		bcopy((void *)&nv->port_name[0], (void *)&nv->node_name[0], 8);
1046 		nv->node_name[0] = (uint8_t)(nv->node_name[0] & ~BIT_0);
1047 		nv->port_name[0] = (uint8_t)(nv->node_name[0] | BIT_0);
1048 	}
1049 
1050 	/* Reset initialization control blocks. */
1051 	bzero((void *)icb, sizeof (ql_init_24xx_cb_t));
1052 
1053 	/* Get driver properties. */
1054 	ql_24xx_properties(ha, nv);
1055 
1056 	cmn_err(CE_CONT, "!Qlogic %s(%d) WWPN=%02x%02x%02x%02x"
1057 	    "%02x%02x%02x%02x : WWNN=%02x%02x%02x%02x%02x%02x%02x%02x\n",
1058 	    QL_NAME, ha->instance, nv->port_name[0], nv->port_name[1],
1059 	    nv->port_name[2], nv->port_name[3], nv->port_name[4],
1060 	    nv->port_name[5], nv->port_name[6], nv->port_name[7],
1061 	    nv->node_name[0], nv->node_name[1], nv->node_name[2],
1062 	    nv->node_name[3], nv->node_name[4], nv->node_name[5],
1063 	    nv->node_name[6], nv->node_name[7]);
1064 
1065 	/*
1066 	 * Copy over NVRAM Firmware Initialization Control Block.
1067 	 */
1068 	dst = (caddr_t)icb;
1069 	src = (caddr_t)&nv->version;
1070 	index = (uint32_t)((uintptr_t)&icb->response_q_inpointer[0] -
1071 	    (uintptr_t)icb);
1072 	while (index--) {
1073 		*dst++ = *src++;
1074 	}
1075 	icb->login_retry_count[0] = nv->login_retry_count[0];
1076 	icb->login_retry_count[1] = nv->login_retry_count[1];
1077 	icb->link_down_on_nos[0] = nv->link_down_on_nos[0];
1078 	icb->link_down_on_nos[1] = nv->link_down_on_nos[1];
1079 
1080 	dst = (caddr_t)&icb->interrupt_delay_timer;
1081 	src = (caddr_t)&nv->interrupt_delay_timer;
1082 	index = (uint32_t)((uintptr_t)&icb->reserved_3 -
1083 	    (uintptr_t)&icb->interrupt_delay_timer);
1084 	while (index--) {
1085 		*dst++ = *src++;
1086 	}
1087 
1088 	/*
1089 	 * Setup driver firmware options.
1090 	 */
1091 	icb->firmware_options_1[0] = (uint8_t)(icb->firmware_options_1[0] &
1092 	    ~(BIT_5 | BIT_4));
1093 	icb->firmware_options_1[1] = (uint8_t)(icb->firmware_options_1[1] |
1094 	    BIT_6 | BIT_5 | BIT_2);
1095 	if (CFG_IST(ha, CFG_TARGET_MODE_ENABLE)) {
1096 		icb->firmware_options_1[0] = (uint8_t)
1097 		    (icb->firmware_options_1[0] | BIT_4 | BIT_1);
1098 		EL(ha, "Target mode enabled\n");
1099 	} else {
1100 		icb->firmware_options_1[0] = (uint8_t)
1101 		    (icb->firmware_options_1[0] | BIT_1);
1102 	}
1103 
1104 	if (CFG_IST(ha, CFG_ENABLE_FCP_2_SUPPORT)) {
1105 		icb->firmware_options_2[1] = (uint8_t)
1106 		    (icb->firmware_options_2[1] | BIT_4);
1107 	} else {
1108 		icb->firmware_options_2[1] = (uint8_t)
1109 		    (icb->firmware_options_2[1] & ~BIT_4);
1110 	}
1111 
1112 	icb->firmware_options_3[0] = (uint8_t)(icb->firmware_options_3[0] |
1113 	    BIT_1);
1114 	icb->firmware_options_3[0] = (uint8_t)(icb->firmware_options_3[0] &
1115 	    ~BIT_7);
1116 
1117 	icb->execution_throttle[0] = 0xff;
1118 	icb->execution_throttle[1] = 0xff;
1119 
1120 	/*
1121 	 * Set host adapter parameters
1122 	 */
1123 	ADAPTER_STATE_LOCK(ha);
1124 	ha->nvram_version = CHAR_TO_SHORT(nv->nvram_version[0],
1125 	    nv->nvram_version[1]);
1126 	nv->host_p[1] & BIT_2 ? (ha->cfg_flags |= CFG_ENABLE_FULL_LIP_LOGIN) :
1127 	    (ha->cfg_flags &= ~CFG_ENABLE_FULL_LIP_LOGIN);
1128 	nv->host_p[1] & BIT_3 ? (ha->cfg_flags |= CFG_ENABLE_TARGET_RESET) :
1129 	    (ha->cfg_flags &= ~CFG_ENABLE_TARGET_RESET);
1130 	ha->cfg_flags &= ~(CFG_DISABLE_RISC_CODE_LOAD |
1131 	    CFG_SET_CACHE_LINE_SIZE_1 | CFG_MULTI_CHIP_ADAPTER);
1132 	ha->cfg_flags |= CFG_ENABLE_64BIT_ADDRESSING;
1133 	ADAPTER_STATE_UNLOCK(ha);
1134 
1135 	ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS;
1136 	ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
1137 
1138 	ha->execution_throttle = CHAR_TO_SHORT(nv->execution_throttle[0],
1139 	    nv->execution_throttle[1]);
1140 	ha->loop_reset_delay = nv->reset_delay;
1141 	ha->port_down_retry_count = CHAR_TO_SHORT(nv->port_down_retry_count[0],
1142 	    nv->port_down_retry_count[1]);
1143 	w1 = CHAR_TO_SHORT(icb->login_timeout[0], icb->login_timeout[1]);
1144 	ha->r_a_tov = (uint16_t)(w1 < R_A_TOV_DEFAULT ? R_A_TOV_DEFAULT : w1);
1145 	ha->maximum_luns_per_target = CHAR_TO_SHORT(
1146 	    nv->max_luns_per_target[0], nv->max_luns_per_target[1]);
1147 	if (ha->maximum_luns_per_target == 0) {
1148 		ha->maximum_luns_per_target++;
1149 	}
1150 
1151 	/* ISP2422 Serial Link Control */
1152 	ha->serdes_param[0] = CHAR_TO_SHORT(nv->swing_opt[0],
1153 	    nv->swing_opt[1]);
1154 	ha->serdes_param[1] = CHAR_TO_SHORT(nv->swing_1g[0], nv->swing_1g[1]);
1155 	ha->serdes_param[2] = CHAR_TO_SHORT(nv->swing_2g[0], nv->swing_2g[1]);
1156 	ha->serdes_param[3] = CHAR_TO_SHORT(nv->swing_4g[0], nv->swing_4g[1]);
1157 
1158 	/*
1159 	 * Setup ring parameters in initialization control block
1160 	 */
1161 	w1 = REQUEST_ENTRY_CNT;
1162 	icb->request_q_length[0] = LSB(w1);
1163 	icb->request_q_length[1] = MSB(w1);
1164 	w1 = RESPONSE_ENTRY_CNT;
1165 	icb->response_q_length[0] = LSB(w1);
1166 	icb->response_q_length[1] = MSB(w1);
1167 
1168 	icb->request_q_address[0] = LSB(LSW(LSD(ha->request_dvma)));
1169 	icb->request_q_address[1] = MSB(LSW(LSD(ha->request_dvma)));
1170 	icb->request_q_address[2] = LSB(MSW(LSD(ha->request_dvma)));
1171 	icb->request_q_address[3] = MSB(MSW(LSD(ha->request_dvma)));
1172 	icb->request_q_address[4] = LSB(LSW(MSD(ha->request_dvma)));
1173 	icb->request_q_address[5] = MSB(LSW(MSD(ha->request_dvma)));
1174 	icb->request_q_address[6] = LSB(MSW(MSD(ha->request_dvma)));
1175 	icb->request_q_address[7] = MSB(MSW(MSD(ha->request_dvma)));
1176 
1177 	icb->response_q_address[0] = LSB(LSW(LSD(ha->response_dvma)));
1178 	icb->response_q_address[1] = MSB(LSW(LSD(ha->response_dvma)));
1179 	icb->response_q_address[2] = LSB(MSW(LSD(ha->response_dvma)));
1180 	icb->response_q_address[3] = MSB(MSW(LSD(ha->response_dvma)));
1181 	icb->response_q_address[4] = LSB(LSW(MSD(ha->response_dvma)));
1182 	icb->response_q_address[5] = MSB(LSW(MSD(ha->response_dvma)));
1183 	icb->response_q_address[6] = LSB(MSW(MSD(ha->response_dvma)));
1184 	icb->response_q_address[7] = MSB(MSW(MSD(ha->response_dvma)));
1185 
1186 	/*
1187 	 * Setup IP initialization control block
1188 	 */
1189 	ip_icb->version = IP_ICB_24XX_VERSION;
1190 
1191 	ip_icb->ip_firmware_options[0] = (uint8_t)
1192 	    (ip_icb->ip_firmware_options[0] | BIT_2);
1193 
1194 	if (rval != QL_SUCCESS) {
1195 		EL(ha, "failed, rval = %xh\n", rval);
1196 	} else {
1197 		/*EMPTY*/
1198 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1199 	}
1200 	return (rval);
1201 }
1202 
1203 /*
1204  * ql_lock_nvram
1205  *	Locks NVRAM access and returns starting address of NVRAM.
1206  *
1207  * Input:
1208  *	ha:	adapter state pointer.
1209  *	addr:	pointer for start address.
1210  *	flags:	Are mutually exclusive:
1211  *		LNF_NVRAM_DATA --> get nvram
1212  *		LNF_VPD_DATA --> get vpd data (24/25xx only).
1213  *
1214  * Returns:
1215  *	ql local function return status code.
1216  *
1217  * Context:
1218  *	Kernel context.
1219  */
1220 int
1221 ql_lock_nvram(ql_adapter_state_t *ha, uint32_t *addr, uint32_t flags)
1222 {
1223 	int	i;
1224 
1225 	if ((flags & LNF_NVRAM_DATA) && (flags & LNF_VPD_DATA)) {
1226 		EL(ha, "invalid options for function");
1227 		return (QL_FUNCTION_FAILED);
1228 	}
1229 
1230 	if (ha->device_id == 0x2312 || ha->device_id == 0x2322) {
1231 		if ((flags & LNF_NVRAM_DATA) == 0) {
1232 			EL(ha, "invalid 2312/2322 option for HBA");
1233 			return (QL_FUNCTION_FAILED);
1234 		}
1235 
1236 		/* if function number is non-zero, then adjust offset */
1237 		*addr = RD16_IO_REG(ha, ctrl_status) & 0xc000 ? 128 : 0;
1238 
1239 		/* Try to get resource lock. Wait for 10 seconds max */
1240 		for (i = 0; i < 10000; i++) {
1241 			/* if nvram busy bit is reset, acquire sema */
1242 			if ((RD16_IO_REG(ha, nvram) & 0x8000) == 0) {
1243 				WRT16_IO_REG(ha, host_to_host_sema, 1);
1244 				drv_usecwait(MILLISEC);
1245 				if (RD16_IO_REG(ha, host_to_host_sema) & 1) {
1246 					break;
1247 				}
1248 			}
1249 			drv_usecwait(MILLISEC);
1250 		}
1251 		if ((RD16_IO_REG(ha, host_to_host_sema) & 1) == 0) {
1252 			cmn_err(CE_WARN, "%s(%d): unable to get NVRAM lock",
1253 			    QL_NAME, ha->instance);
1254 			return (QL_FUNCTION_FAILED);
1255 		}
1256 	} else if (CFG_IST(ha, CFG_CTRL_2422)) {
1257 		if (flags & LNF_VPD_DATA) {
1258 			*addr = RD32_IO_REG(ha, ctrl_status) &
1259 			    FUNCTION_NUMBER ? VPD_24XX_FUNC1_ADDR :
1260 			    VPD_24XX_FUNC0_ADDR;
1261 		} else if (flags & LNF_NVRAM_DATA) {
1262 			*addr = RD32_IO_REG(ha, ctrl_status) &
1263 			    FUNCTION_NUMBER ? NVRAM_24XX_FUNC1_ADDR :
1264 			    NVRAM_24XX_FUNC0_ADDR;
1265 		} else {
1266 			EL(ha, "invalid 24xx option for HBA");
1267 			return (QL_FUNCTION_FAILED);
1268 		}
1269 
1270 		GLOBAL_HW_LOCK();
1271 	} else if (CFG_IST(ha, CFG_CTRL_25XX)) {
1272 		if (flags & LNF_VPD_DATA) {
1273 			*addr = RD32_IO_REG(ha, ctrl_status) &
1274 			    FUNCTION_NUMBER ? VPD_25XX_FUNC1_ADDR :
1275 			    VPD_25XX_FUNC0_ADDR;
1276 		} else if (flags & LNF_NVRAM_DATA) {
1277 			*addr = RD32_IO_REG(ha, ctrl_status) &
1278 			    FUNCTION_NUMBER ? NVRAM_25XX_FUNC1_ADDR :
1279 			    NVRAM_25XX_FUNC0_ADDR;
1280 		} else {
1281 			EL(ha, "invalid 25xx option for HBA");
1282 			return (QL_FUNCTION_FAILED);
1283 		}
1284 
1285 		GLOBAL_HW_LOCK();
1286 	} else {
1287 		if ((flags & LNF_NVRAM_DATA) == 0) {
1288 			EL(ha, "invalid option for HBA");
1289 			return (QL_FUNCTION_FAILED);
1290 		}
1291 		*addr = 0;
1292 		GLOBAL_HW_LOCK();
1293 	}
1294 
1295 	return (QL_SUCCESS);
1296 }
1297 
1298 /*
1299  * ql_release_nvram
1300  *	Releases NVRAM access.
1301  *
1302  * Input:
1303  *	ha:	adapter state pointer.
1304  *
1305  * Context:
1306  *	Kernel context.
1307  */
1308 void
1309 ql_release_nvram(ql_adapter_state_t *ha)
1310 {
1311 	if (ha->device_id == 0x2312 || ha->device_id == 0x2322) {
1312 		/* Release resource lock */
1313 		WRT16_IO_REG(ha, host_to_host_sema, 0);
1314 	} else {
1315 		GLOBAL_HW_UNLOCK();
1316 	}
1317 }
1318 
1319 /*
1320  * ql_23_properties
1321  *	Copies driver properties to NVRAM or adapter structure.
1322  *
1323  *	Driver properties are by design global variables and hidden
1324  *	completely from administrators. Knowledgeable folks can
1325  *	override the default values using driver.conf
1326  *
1327  * Input:
1328  *	ha:	adapter state pointer.
1329  *	nv:	NVRAM structure pointer.
1330  *
1331  * Context:
1332  *	Kernel context.
1333  */
1334 static void
1335 ql_23_properties(ql_adapter_state_t *ha, nvram_t *nv)
1336 {
1337 	uint32_t	data, cnt;
1338 
1339 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1340 
1341 	/* Get frame payload size. */
1342 	if ((data = ql_get_prop(ha, "max-frame-length")) == 0xffffffff) {
1343 		data = 2048;
1344 	}
1345 	if (data == 512 || data == 1024 || data == 2048) {
1346 		nv->max_frame_length[0] = LSB(data);
1347 		nv->max_frame_length[1] = MSB(data);
1348 	} else {
1349 		EL(ha, "invalid parameter value for 'max-frame-length': "
1350 		    "%d; using nvram default of %d\n", data, CHAR_TO_SHORT(
1351 		    nv->max_frame_length[0], nv->max_frame_length[1]));
1352 	}
1353 
1354 	/* Get max IOCB allocation. */
1355 	nv->max_iocb_allocation[0] = 0;
1356 	nv->max_iocb_allocation[1] = 1;
1357 
1358 	/* Get execution throttle. */
1359 	if ((data = ql_get_prop(ha, "execution-throttle")) == 0xffffffff) {
1360 		data = 32;
1361 	}
1362 	if (data != 0 && data < 65536) {
1363 		nv->execution_throttle[0] = LSB(data);
1364 		nv->execution_throttle[1] = MSB(data);
1365 	} else {
1366 		EL(ha, "invalid parameter value for 'execution-throttle': "
1367 		    "%d; using nvram default of %d\n", data, CHAR_TO_SHORT(
1368 		    nv->execution_throttle[0], nv->execution_throttle[1]));
1369 	}
1370 
1371 	/* Get Login timeout. */
1372 	if ((data = ql_get_prop(ha, "login-timeout")) == 0xffffffff) {
1373 		data = 3;
1374 	}
1375 	if (data < 256) {
1376 		nv->login_timeout = (uint8_t)data;
1377 	} else {
1378 		EL(ha, "invalid parameter value for 'login-timeout': "
1379 		    "%d; using nvram value of %d\n", data, nv->login_timeout);
1380 	}
1381 
1382 	/* Get retry count. */
1383 	if ((data = ql_get_prop(ha, "login-retry-count")) == 0xffffffff) {
1384 		data = 4;
1385 	}
1386 	if (data < 256) {
1387 		nv->login_retry_count = (uint8_t)data;
1388 	} else {
1389 		EL(ha, "invalid parameter value for 'login-retry-count': "
1390 		    "%d; using nvram value of %d\n", data,
1391 		    nv->login_retry_count);
1392 	}
1393 
1394 	/* Get adapter hard loop ID enable. */
1395 	data =  ql_get_prop(ha, "enable-adapter-hard-loop-ID");
1396 	if (data == 0) {
1397 		nv->firmware_options[0] =
1398 		    (uint8_t)(nv->firmware_options[0] & ~BIT_0);
1399 	} else if (data == 1) {
1400 		nv->firmware_options[0] =
1401 		    (uint8_t)(nv->firmware_options[0] | BIT_0);
1402 	} else if (data != 0xffffffff) {
1403 		EL(ha, "invalid parameter value for "
1404 		    "'enable-adapter-hard-loop-ID': %d; using nvram value "
1405 		    "of %d\n", data, nv->firmware_options[0] & BIT_0 ? 1 : 0);
1406 	}
1407 
1408 	/* Get adapter hard loop ID. */
1409 	data =  ql_get_prop(ha, "adapter-hard-loop-ID");
1410 	if (data < 126) {
1411 		nv->hard_address[0] = (uint8_t)data;
1412 	} else if (data != 0xffffffff) {
1413 		EL(ha, "invalid parameter value for 'adapter-hard-loop-ID': "
1414 		    "%d; using nvram value of %d\n", data, nv->hard_address[0]);
1415 	}
1416 
1417 	/* Get LIP reset. */
1418 	if ((data = ql_get_prop(ha, "enable-LIP-reset-on-bus-reset")) ==
1419 	    0xffffffff) {
1420 		data = 0;
1421 	}
1422 	if (data == 0) {
1423 		nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_1);
1424 	} else if (data == 1) {
1425 		nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_1);
1426 	} else {
1427 		EL(ha, "invalid parameter value for "
1428 		    "'enable-LIP-reset-on-bus-reset': %d; using nvram value "
1429 		    "of %d\n", data, nv->host_p[1] & BIT_1 ? 1 : 0);
1430 	}
1431 
1432 	/* Get LIP full login. */
1433 	if ((data = ql_get_prop(ha, "enable-LIP-full-login-on-bus-reset")) ==
1434 	    0xffffffff) {
1435 		data = 1;
1436 	}
1437 	if (data == 0) {
1438 		nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_2);
1439 	} else if (data == 1) {
1440 		nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_2);
1441 	} else {
1442 		EL(ha, "invalid parameter value for "
1443 		    "'enable-LIP-full-login-on-bus-reset': %d; using nvram "
1444 		    "value of %d\n", data, nv->host_p[1] & BIT_2 ? 1 : 0);
1445 	}
1446 
1447 	/* Get target reset. */
1448 	if ((data = ql_get_prop(ha, "enable-target-reset-on-bus-reset")) ==
1449 	    0xffffffff) {
1450 		data = 0;
1451 	}
1452 	if (data == 0) {
1453 		nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_3);
1454 	} else if (data == 1) {
1455 		nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_3);
1456 	} else {
1457 		EL(ha, "invalid parameter value for "
1458 		    "'enable-target-reset-on-bus-reset': %d; using nvram "
1459 		    "value of %d", data, nv->host_p[1] & BIT_3 ? 1 : 0);
1460 	}
1461 
1462 	/* Get reset delay. */
1463 	if ((data = ql_get_prop(ha, "reset-delay")) == 0xffffffff) {
1464 		data = 5;
1465 	}
1466 	if (data != 0 && data < 256) {
1467 		nv->reset_delay = (uint8_t)data;
1468 	} else {
1469 		EL(ha, "invalid parameter value for 'reset-delay': %d; "
1470 		    "using nvram value of %d", data, nv->reset_delay);
1471 	}
1472 
1473 	/* Get port down retry count. */
1474 	if ((data = ql_get_prop(ha, "port-down-retry-count")) == 0xffffffff) {
1475 		data = 8;
1476 	}
1477 	if (data < 256) {
1478 		nv->port_down_retry_count = (uint8_t)data;
1479 	} else {
1480 		EL(ha, "invalid parameter value for 'port-down-retry-count':"
1481 		    " %d; using nvram value of %d\n", data,
1482 		    nv->port_down_retry_count);
1483 	}
1484 
1485 	/* Get connection mode setting. */
1486 	if ((data = ql_get_prop(ha, "connection-options")) == 0xffffffff) {
1487 		data = 2;
1488 	}
1489 	cnt = CFG_IST(ha, CFG_CTRL_2200) ? 3 : 2;
1490 	if (data <= cnt) {
1491 		nv->add_fw_opt[0] = (uint8_t)(nv->add_fw_opt[0] &
1492 		    ~(BIT_6 | BIT_5 | BIT_4));
1493 		nv->add_fw_opt[0] = (uint8_t)(nv->add_fw_opt[0] |
1494 		    (uint8_t)(data << 4));
1495 	} else {
1496 		EL(ha, "invalid parameter value for 'connection-options': "
1497 		    "%d; using nvram value of %d\n", data,
1498 		    (nv->add_fw_opt[0] >> 4) & 0x3);
1499 	}
1500 
1501 	/* Get data rate setting. */
1502 	if ((CFG_IST(ha, CFG_CTRL_2200)) == 0) {
1503 		if ((data = ql_get_prop(ha, "fc-data-rate")) == 0xffffffff) {
1504 			data = 2;
1505 		}
1506 		if (data < 3) {
1507 			nv->special_options[1] = (uint8_t)
1508 			    (nv->special_options[1] & 0x3f);
1509 			nv->special_options[1] = (uint8_t)
1510 			    (nv->special_options[1] | (uint8_t)(data << 6));
1511 		} else {
1512 			EL(ha, "invalid parameter value for 'fc-data-rate': "
1513 			    "%d; using nvram value of %d\n", data,
1514 			    (nv->special_options[1] >> 6) & 0x3);
1515 		}
1516 	}
1517 
1518 	/* Get adapter id string for Sun branded 23xx only */
1519 	if ((CFG_IST(ha, CFG_CTRL_2300)) && nv->adapInfo[0] != 0) {
1520 		(void) snprintf((int8_t *)ha->adapInfo, 16, "%s",
1521 		    nv->adapInfo);
1522 	}
1523 
1524 	/* Get IP FW container count. */
1525 	ha->ip_init_ctrl_blk.cb.cc[0] = LSB(ql_ip_buffer_count);
1526 	ha->ip_init_ctrl_blk.cb.cc[1] = MSB(ql_ip_buffer_count);
1527 
1528 	/* Get IP low water mark. */
1529 	ha->ip_init_ctrl_blk.cb.low_water_mark[0] = LSB(ql_ip_low_water);
1530 	ha->ip_init_ctrl_blk.cb.low_water_mark[1] = MSB(ql_ip_low_water);
1531 
1532 	/* Get IP fast register post count. */
1533 	ha->ip_init_ctrl_blk.cb.fast_post_reg_count[0] =
1534 	    ql_ip_fast_post_count;
1535 
1536 	ADAPTER_STATE_LOCK(ha);
1537 
1538 	ql_common_properties(ha);
1539 
1540 	ADAPTER_STATE_UNLOCK(ha);
1541 
1542 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1543 }
1544 
1545 /*
1546  * ql_common_properties
1547  *	Driver properties adapter structure.
1548  *
1549  *	Driver properties are by design global variables and hidden
1550  *	completely from administrators. Knowledgeable folks can
1551  *	override the default values using driver.conf
1552  *
1553  * Input:
1554  *	ha:	adapter state pointer.
1555  *
1556  * Context:
1557  *	Kernel context.
1558  */
1559 void
1560 ql_common_properties(ql_adapter_state_t *ha)
1561 {
1562 	uint32_t	data;
1563 
1564 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1565 
1566 	/* Get FCP 2 Error Recovery. */
1567 	if ((data = ql_get_prop(ha, "enable-FCP-2-error-recovery")) ==
1568 	    0xffffffff || data == 1) {
1569 		ha->cfg_flags |= CFG_ENABLE_FCP_2_SUPPORT;
1570 	} else if (data == 0) {
1571 		ha->cfg_flags &= ~CFG_ENABLE_FCP_2_SUPPORT;
1572 	} else {
1573 		EL(ha, "invalid parameter value for "
1574 		    "'enable-FCP-2-error-recovery': %d; using nvram value of "
1575 		    "1\n", data);
1576 		ha->cfg_flags |= CFG_ENABLE_FCP_2_SUPPORT;
1577 	}
1578 
1579 	/* Get target mode enable. */
1580 	ha->cfg_flags &= ~CFG_TARGET_MODE_ENABLE;
1581 
1582 	/* Get extended logging enable. */
1583 	if ((data = ql_get_prop(ha, "extended-logging")) == 0xffffffff ||
1584 	    data == 0) {
1585 		ha->cfg_flags &= ~CFG_ENABLE_EXTENDED_LOGGING;
1586 	} else if (data == 1) {
1587 		ha->cfg_flags |= CFG_ENABLE_EXTENDED_LOGGING;
1588 	} else {
1589 		EL(ha, "invalid parameter value for 'extended-logging': %d;"
1590 		    " using default value of 0\n", data);
1591 		ha->cfg_flags &= ~CFG_ENABLE_EXTENDED_LOGGING;
1592 	}
1593 
1594 #ifdef QL_DEBUG_LEVEL_2
1595 	ha->cfg_flags |= CFG_ENABLE_EXTENDED_LOGGING;
1596 #endif
1597 
1598 	/* Get port down retry delay. */
1599 	if ((data = ql_get_prop(ha, "port-down-retry-delay")) == 0xffffffff) {
1600 		ha->port_down_retry_delay = PORT_RETRY_TIME;
1601 	} else if (data < 256) {
1602 		ha->port_down_retry_delay = (uint8_t)data;
1603 	} else {
1604 		EL(ha, "invalid parameter value for 'port-down-retry-delay':"
1605 		    " %d; using default value of %d", data, PORT_RETRY_TIME);
1606 		ha->port_down_retry_delay = PORT_RETRY_TIME;
1607 	}
1608 
1609 	/* Get queue full retry count. */
1610 	if ((data = ql_get_prop(ha, "queue-full-retry-count")) == 0xffffffff) {
1611 		ha->qfull_retry_count = 16;
1612 	} else if (data < 256) {
1613 		ha->qfull_retry_count = (uint8_t)data;
1614 	} else {
1615 		EL(ha, "invalid parameter value for 'queue-full-retry-count':"
1616 		    " %d; using default value of 16", data);
1617 		ha->qfull_retry_count = 16;
1618 	}
1619 
1620 	/* Get queue full retry delay. */
1621 	if ((data = ql_get_prop(ha, "queue-full-retry-delay")) == 0xffffffff) {
1622 		ha->qfull_retry_delay = PORT_RETRY_TIME;
1623 	} else if (data < 256) {
1624 		ha->qfull_retry_delay = (uint8_t)data;
1625 	} else {
1626 		EL(ha, "invalid parameter value for 'queue-full-retry-delay':"
1627 		    " %d; using default value of %d", data, PORT_RETRY_TIME);
1628 		ha->qfull_retry_delay = PORT_RETRY_TIME;
1629 	}
1630 
1631 	/* Get loop down timeout. */
1632 	if ((data = ql_get_prop(ha, "link-down-timeout")) == 0xffffffff) {
1633 		data = 0;
1634 	} else if (data > 255) {
1635 		EL(ha, "invalid parameter value for 'link-down-timeout': %d;"
1636 		    " using nvram value of 0\n", data);
1637 		data = 0;
1638 	}
1639 	ha->loop_down_abort_time = (uint8_t)(LOOP_DOWN_TIMER_START - data);
1640 	if (ha->loop_down_abort_time == LOOP_DOWN_TIMER_START) {
1641 		ha->loop_down_abort_time--;
1642 	} else if (ha->loop_down_abort_time <= LOOP_DOWN_TIMER_END) {
1643 		ha->loop_down_abort_time = LOOP_DOWN_TIMER_END + 1;
1644 	}
1645 
1646 	/* Get link down error enable. */
1647 	if ((data = ql_get_prop(ha, "enable-link-down-error")) == 0xffffffff ||
1648 	    data == 1) {
1649 		ha->cfg_flags |= CFG_ENABLE_LINK_DOWN_REPORTING;
1650 	} else if (data == 0) {
1651 		ha->cfg_flags &= ~CFG_ENABLE_LINK_DOWN_REPORTING;
1652 	} else {
1653 		EL(ha, "invalid parameter value for 'link-down-error': %d;"
1654 		    " using default value of 1\n", data);
1655 	}
1656 
1657 	/*
1658 	 * Get firmware dump flags.
1659 	 *	TAKE_FW_DUMP_ON_MAILBOX_TIMEOUT		BIT_0
1660 	 *	TAKE_FW_DUMP_ON_ISP_SYSTEM_ERROR	BIT_1
1661 	 *	TAKE_FW_DUMP_ON_DRIVER_COMMAND_TIMEOUT	BIT_2
1662 	 *	TAKE_FW_DUMP_ON_LOOP_OFFLINE_TIMEOUT	BIT_3
1663 	 */
1664 	ha->cfg_flags &= ~(CFG_DUMP_MAILBOX_TIMEOUT |
1665 	    CFG_DUMP_ISP_SYSTEM_ERROR | CFG_DUMP_DRIVER_COMMAND_TIMEOUT |
1666 	    CFG_DUMP_LOOP_OFFLINE_TIMEOUT);
1667 	if ((data = ql_get_prop(ha, "firmware-dump-flags")) != 0xffffffff) {
1668 		if (data & BIT_0) {
1669 			ha->cfg_flags |= CFG_DUMP_MAILBOX_TIMEOUT;
1670 		}
1671 		if (data & BIT_1) {
1672 			ha->cfg_flags |= CFG_DUMP_ISP_SYSTEM_ERROR;
1673 		}
1674 		if (data & BIT_2) {
1675 			ha->cfg_flags |= CFG_DUMP_DRIVER_COMMAND_TIMEOUT;
1676 		}
1677 		if (data & BIT_3) {
1678 			ha->cfg_flags |= CFG_DUMP_LOOP_OFFLINE_TIMEOUT;
1679 		}
1680 	}
1681 
1682 	/* Get the PCI max read request size override. */
1683 	ha->pci_max_read_req = 0;
1684 	if ((data = ql_get_prop(ha, "pci-max-read-request")) != 0xffffffff &&
1685 	    data != 0) {
1686 		ha->pci_max_read_req = (uint16_t)(data);
1687 	}
1688 
1689 	/* Get the attach fw_ready override value. */
1690 	ha->fwwait = 10;
1691 	if ((data = ql_get_prop(ha, "init-loop-sync-wait")) != 0xffffffff) {
1692 		if (data > 0 && data <= 240) {
1693 			ha->fwwait = (uint8_t)data;
1694 		} else {
1695 			EL(ha, "invalid parameter value for "
1696 			    "'init-loop-sync-wait': %d; using default "
1697 			    "value of %d\n", data, ha->fwwait);
1698 		}
1699 	}
1700 
1701 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1702 }
1703 
1704 /*
1705  * ql_24xx_properties
1706  *	Copies driver properties to NVRAM or adapter structure.
1707  *
1708  *	Driver properties are by design global variables and hidden
1709  *	completely from administrators. Knowledgeable folks can
1710  *	override the default values using /etc/system.
1711  *
1712  * Input:
1713  *	ha:	adapter state pointer.
1714  *	nv:	NVRAM structure pointer.
1715  *
1716  * Context:
1717  *	Kernel context.
1718  */
1719 static void
1720 ql_24xx_properties(ql_adapter_state_t *ha, nvram_24xx_t *nv)
1721 {
1722 	uint32_t	data;
1723 
1724 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1725 
1726 	/* Get frame size */
1727 	if ((data = ql_get_prop(ha, "max-frame-length")) == 0xffffffff) {
1728 		data = 2048;
1729 	}
1730 	if (data == 512 || data == 1024 || data == 2048) {
1731 		nv->max_frame_length[0] = LSB(data);
1732 		nv->max_frame_length[1] = MSB(data);
1733 	} else {
1734 		EL(ha, "invalid parameter value for 'max-frame-length': %d;"
1735 		    " using nvram default of %d\n", data, CHAR_TO_SHORT(
1736 		    nv->max_frame_length[0], nv->max_frame_length[1]));
1737 	}
1738 
1739 	/* Get execution throttle. */
1740 	if ((data = ql_get_prop(ha, "execution-throttle")) == 0xffffffff) {
1741 		data = 32;
1742 	}
1743 	if (data != 0 && data < 65536) {
1744 		nv->execution_throttle[0] = LSB(data);
1745 		nv->execution_throttle[1] = MSB(data);
1746 	} else {
1747 		EL(ha, "invalid parameter value for 'execution-throttle':"
1748 		    " %d; using nvram default of %d\n", data, CHAR_TO_SHORT(
1749 		    nv->execution_throttle[0], nv->execution_throttle[1]));
1750 	}
1751 
1752 	/* Get Login timeout. */
1753 	if ((data = ql_get_prop(ha, "login-timeout")) == 0xffffffff) {
1754 		data = 3;
1755 	}
1756 	if (data < 65536) {
1757 		nv->login_timeout[0] = LSB(data);
1758 		nv->login_timeout[1] = MSB(data);
1759 	} else {
1760 		EL(ha, "invalid parameter value for 'login-timeout': %d; "
1761 		    "using nvram value of %d\n", data, CHAR_TO_SHORT(
1762 		    nv->login_timeout[0], nv->login_timeout[1]));
1763 	}
1764 
1765 	/* Get retry count. */
1766 	if ((data = ql_get_prop(ha, "login-retry-count")) == 0xffffffff) {
1767 		data = 4;
1768 	}
1769 	if (data < 65536) {
1770 		nv->login_retry_count[0] = LSB(data);
1771 		nv->login_retry_count[1] = MSB(data);
1772 	} else {
1773 		EL(ha, "invalid parameter value for 'login-retry-count': "
1774 		    "%d; using nvram value of %d\n", data, CHAR_TO_SHORT(
1775 		    nv->login_retry_count[0], nv->login_retry_count[1]));
1776 	}
1777 
1778 	/* Get adapter hard loop ID enable. */
1779 	data =  ql_get_prop(ha, "enable-adapter-hard-loop-ID");
1780 	if (data == 0) {
1781 		nv->firmware_options_1[0] =
1782 		    (uint8_t)(nv->firmware_options_1[0] & ~BIT_0);
1783 	} else if (data == 1) {
1784 		nv->firmware_options_1[0] =
1785 		    (uint8_t)(nv->firmware_options_1[0] | BIT_0);
1786 	} else if (data != 0xffffffff) {
1787 		EL(ha, "invalid parameter value for "
1788 		    "'enable-adapter-hard-loop-ID': %d; using nvram value "
1789 		    "of %d\n", data,
1790 		    nv->firmware_options_1[0] & BIT_0 ? 1 : 0);
1791 	}
1792 
1793 	/* Get adapter hard loop ID. */
1794 	data =  ql_get_prop(ha, "adapter-hard-loop-ID");
1795 	if (data < 126) {
1796 		nv->hard_address[0] = LSB(data);
1797 		nv->hard_address[1] = MSB(data);
1798 	} else if (data != 0xffffffff) {
1799 		EL(ha, "invalid parameter value for 'adapter-hard-loop-ID':"
1800 		    " %d; using nvram value of %d\n", data, CHAR_TO_SHORT(
1801 		    nv->hard_address[0], nv->hard_address[1]));
1802 	}
1803 
1804 	/* Get LIP reset. */
1805 	if ((data = ql_get_prop(ha, "enable-LIP-reset-on-bus-reset")) ==
1806 	    0xffffffff) {
1807 		data = 0;
1808 	}
1809 	if (data == 0) {
1810 		ha->cfg_flags &= ~CFG_ENABLE_LIP_RESET;
1811 	} else if (data == 1) {
1812 		ha->cfg_flags |= CFG_ENABLE_LIP_RESET;
1813 	} else {
1814 		EL(ha, "invalid parameter value for "
1815 		    "'enable-LIP-reset-on-bus-reset': %d; using value of 0\n",
1816 		    data);
1817 	}
1818 
1819 	/* Get LIP full login. */
1820 	if ((data = ql_get_prop(ha, "enable-LIP-full-login-on-bus-reset")) ==
1821 	    0xffffffff) {
1822 		data = 1;
1823 	}
1824 	if (data == 0) {
1825 		nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_2);
1826 	} else if (data == 1) {
1827 		nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_2);
1828 	} else {
1829 		EL(ha, "invalid parameter value for "
1830 		    "'enable-LIP-full-login-on-bus-reset': %d; using nvram "
1831 		    "value of %d\n", data, nv->host_p[1] & BIT_2 ? 1 : 0);
1832 	}
1833 
1834 	/* Get target reset. */
1835 	if ((data = ql_get_prop(ha, "enable-target-reset-on-bus-reset")) ==
1836 	    0xffffffff) {
1837 		data = 0;
1838 	}
1839 	if (data == 0) {
1840 		nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_3);
1841 	} else if (data == 1) {
1842 		nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_3);
1843 	} else {
1844 		EL(ha, "invalid parameter value for "
1845 		    "'enable-target-reset-on-bus-reset': %d; using nvram "
1846 		    "value of %d", data, nv->host_p[1] & BIT_3 ? 1 : 0);
1847 	}
1848 
1849 	/* Get reset delay. */
1850 	if ((data = ql_get_prop(ha, "reset-delay")) == 0xffffffff) {
1851 		data = 5;
1852 	}
1853 	if (data != 0 && data < 256) {
1854 		nv->reset_delay = (uint8_t)data;
1855 	} else {
1856 		EL(ha, "invalid parameter value for 'reset-delay': %d; "
1857 		    "using nvram value of %d", data, nv->reset_delay);
1858 	}
1859 
1860 	/* Get port down retry count. */
1861 	if ((data = ql_get_prop(ha, "port-down-retry-count")) == 0xffffffff) {
1862 		data = 8;
1863 	}
1864 	if (data < 256) {
1865 		nv->port_down_retry_count[0] = LSB(data);
1866 		nv->port_down_retry_count[1] = MSB(data);
1867 	} else {
1868 		EL(ha, "invalid parameter value for 'port-down-retry-count':"
1869 		    " %d; using nvram value of %d\n", data, CHAR_TO_SHORT(
1870 		    nv->port_down_retry_count[0],
1871 		    nv->port_down_retry_count[1]));
1872 	}
1873 
1874 	/* Get connection mode setting. */
1875 	if ((data = ql_get_prop(ha, "connection-options")) == 0xffffffff) {
1876 		data = 2;
1877 	}
1878 	if (data <= 2) {
1879 		nv->firmware_options_2[0] = (uint8_t)
1880 		    (nv->firmware_options_2[0] & ~(BIT_6 | BIT_5 | BIT_4));
1881 		nv->firmware_options_2[0] = (uint8_t)
1882 		    (nv->firmware_options_2[0] | (uint8_t)(data << 4));
1883 	} else {
1884 		EL(ha, "invalid parameter value for 'connection-options':"
1885 		    " %d; using nvram value of %d\n", data,
1886 		    (nv->firmware_options_2[0] >> 4) & 0x3);
1887 	}
1888 
1889 	/* Get data rate setting. */
1890 	if ((data = ql_get_prop(ha, "fc-data-rate")) == 0xffffffff) {
1891 		data = 2;
1892 	}
1893 	if ((CFG_IST(ha, CFG_CTRL_2422) && data < 4) ||
1894 	    (CFG_IST(ha, CFG_CTRL_25XX) && data < 5)) {
1895 		nv->firmware_options_3[1] = (uint8_t)
1896 		    (nv->firmware_options_3[1] & 0x1f);
1897 		nv->firmware_options_3[1] = (uint8_t)
1898 		    (nv->firmware_options_3[1] | (uint8_t)(data << 5));
1899 	} else {
1900 		EL(ha, "invalid parameter value for 'fc-data-rate': %d; "
1901 		    "using nvram value of %d\n", data,
1902 		    (nv->firmware_options_3[1] >> 5) & 0x7);
1903 	}
1904 
1905 	/* Get IP FW container count. */
1906 	ha->ip_init_ctrl_blk.cb24.cc[0] = LSB(ql_ip_buffer_count);
1907 	ha->ip_init_ctrl_blk.cb24.cc[1] = MSB(ql_ip_buffer_count);
1908 
1909 	/* Get IP low water mark. */
1910 	ha->ip_init_ctrl_blk.cb24.low_water_mark[0] = LSB(ql_ip_low_water);
1911 	ha->ip_init_ctrl_blk.cb24.low_water_mark[1] = MSB(ql_ip_low_water);
1912 
1913 	ADAPTER_STATE_LOCK(ha);
1914 
1915 	/* Get enable flash load. */
1916 	if ((data = ql_get_prop(ha, "enable-flash-load")) == 0xffffffff ||
1917 	    data == 0) {
1918 		ha->cfg_flags &= ~CFG_LOAD_FLASH_FW;
1919 	} else if (data == 1) {
1920 		ha->cfg_flags |= CFG_LOAD_FLASH_FW;
1921 	} else {
1922 		EL(ha, "invalid parameter value for 'enable-flash-load': "
1923 		    "%d; using default value of 0\n", data);
1924 	}
1925 
1926 	/* Enable firmware extended tracing */
1927 	if ((data = ql_get_prop(ha, "enable-fwexttrace")) != 0xffffffff) {
1928 		if (data != 0) {
1929 			ha->cfg_flags |= CFG_ENABLE_FWEXTTRACE;
1930 		}
1931 	}
1932 
1933 	/* Enable firmware fc tracing */
1934 	if ((data = ql_get_prop(ha, "enable-fwfcetrace")) != 0xffffffff) {
1935 		ha->cfg_flags |= CFG_ENABLE_FWFCETRACE;
1936 		ha->fwfcetraceopt = data;
1937 	}
1938 
1939 	ql_common_properties(ha);
1940 
1941 	ADAPTER_STATE_UNLOCK(ha);
1942 
1943 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1944 }
1945 
1946 /*
1947  * ql_get_prop
1948  *	Get property value from configuration file.
1949  *
1950  * Input:
1951  *	ha= adapter state pointer.
1952  *	string = property string pointer.
1953  *
1954  * Returns:
1955  *	0xFFFFFFFF = no property else property value.
1956  *
1957  * Context:
1958  *	Kernel context.
1959  */
1960 uint32_t
1961 ql_get_prop(ql_adapter_state_t *ha, char *string)
1962 {
1963 	char		buf[256];
1964 	uint32_t	data;
1965 
1966 	/* Get adapter instance parameter. */
1967 	(void) sprintf(buf, "hba%d-%s", ha->instance, string);
1968 	/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
1969 	data = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, ha->dip, 0, buf,
1970 	    (int)0xffffffff);
1971 
1972 	/* Adapter instance parameter found? */
1973 	if (data == 0xffffffff) {
1974 		/* No, get default parameter. */
1975 		/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
1976 		data = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, ha->dip, 0,
1977 		    string, (int)0xffffffff);
1978 	}
1979 
1980 	return (data);
1981 }
1982 
1983 /*
1984  * ql_check_isp_firmware
1985  *	Checks if using already loaded RISC code or drivers copy.
1986  *	If using already loaded code, save a copy of it.
1987  *
1988  * Input:
1989  *	ha = adapter state pointer.
1990  *
1991  * Returns:
1992  *	ql local function return status code.
1993  *
1994  * Context:
1995  *	Kernel context.
1996  */
1997 static int
1998 ql_check_isp_firmware(ql_adapter_state_t *ha)
1999 {
2000 	int		rval;
2001 	uint16_t	word_count;
2002 	uint32_t	byte_count;
2003 	uint32_t	fw_size, *lptr;
2004 	caddr_t		bufp;
2005 	uint16_t	risc_address = (uint16_t)ha->risc_fw[0].addr;
2006 
2007 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2008 
2009 	if (CFG_IST(ha, CFG_DISABLE_RISC_CODE_LOAD)) {
2010 		if (ha->risc_code != NULL) {
2011 			kmem_free(ha->risc_code, ha->risc_code_size);
2012 			ha->risc_code = NULL;
2013 			ha->risc_code_size = 0;
2014 		}
2015 
2016 		/* Get RISC code length. */
2017 		rval = ql_rd_risc_ram(ha, risc_address + 3, ha->request_dvma,
2018 		    1);
2019 		if (rval == QL_SUCCESS) {
2020 			lptr = (uint32_t *)ha->request_ring_bp;
2021 			fw_size = *lptr << 1;
2022 
2023 			if ((bufp = kmem_alloc(fw_size, KM_SLEEP)) != NULL) {
2024 				ha->risc_code_size = fw_size;
2025 				ha->risc_code = bufp;
2026 				ha->fw_transfer_size = 128;
2027 
2028 				/* Dump RISC code. */
2029 				do {
2030 					if (fw_size > ha->fw_transfer_size) {
2031 						byte_count =
2032 						    ha->fw_transfer_size;
2033 					} else {
2034 						byte_count = fw_size;
2035 					}
2036 
2037 					word_count =
2038 					    (uint16_t)(byte_count >> 1);
2039 
2040 					rval = ql_rd_risc_ram(ha, risc_address,
2041 					    ha->request_dvma, word_count);
2042 					if (rval != QL_SUCCESS) {
2043 						kmem_free(ha->risc_code,
2044 						    ha->risc_code_size);
2045 						ha->risc_code = NULL;
2046 						ha->risc_code_size = 0;
2047 						break;
2048 					}
2049 
2050 					(void) ddi_dma_sync(
2051 					    ha->hba_buf.dma_handle,
2052 					    REQUEST_Q_BUFFER_OFFSET,
2053 					    byte_count,
2054 					    DDI_DMA_SYNC_FORKERNEL);
2055 					ddi_rep_get16(ha->hba_buf.acc_handle,
2056 					    (uint16_t *)bufp,
2057 					    (uint16_t *)ha->request_ring_bp,
2058 					    word_count, DDI_DEV_AUTOINCR);
2059 
2060 					risc_address += word_count;
2061 					fw_size -= byte_count;
2062 					bufp	+= byte_count;
2063 				} while (fw_size != 0);
2064 			}
2065 		}
2066 	} else {
2067 		rval = QL_FUNCTION_FAILED;
2068 	}
2069 
2070 	if (rval != QL_SUCCESS) {
2071 		EL(ha, "Load RISC code\n");
2072 	} else {
2073 		/*EMPTY*/
2074 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2075 	}
2076 	return (rval);
2077 }
2078 
2079 /*
2080  * Chip diagnostics
2081  *	Test chip for proper operation.
2082  *
2083  * Input:
2084  *	ha = adapter state pointer.
2085  *
2086  * Returns:
2087  *	ql local function return status code.
2088  *
2089  * Context:
2090  *	Kernel context.
2091  */
2092 static int
2093 ql_chip_diag(ql_adapter_state_t *ha)
2094 {
2095 	ql_mbx_data_t	mr;
2096 	int32_t		rval = QL_FUNCTION_FAILED;
2097 	int32_t		retries = 4;
2098 	uint16_t	id;
2099 
2100 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2101 
2102 	do {
2103 		/* Reset ISP chip. */
2104 		TASK_DAEMON_LOCK(ha);
2105 		ha->task_daemon_flags &= ~ISP_ABORT_NEEDED;
2106 		TASK_DAEMON_UNLOCK(ha);
2107 		ql_reset_chip(ha);
2108 
2109 		/* For ISP2200A reduce firmware load size. */
2110 		if (CFG_IST(ha, CFG_CTRL_2200) &&
2111 		    RD16_IO_REG(ha, mailbox[7]) == 4) {
2112 			ha->fw_transfer_size = 128;
2113 		} else {
2114 			ha->fw_transfer_size = REQUEST_QUEUE_SIZE;
2115 		}
2116 
2117 		/* Check product ID of chip */
2118 		mr.mb[1] = RD16_IO_REG(ha, mailbox[1]);
2119 		mr.mb[2] = RD16_IO_REG(ha, mailbox[2]);
2120 		mr.mb[3] = RD16_IO_REG(ha, mailbox[3]);
2121 
2122 		if (ha->device_id == 0x5432 || ha->device_id == 0x8432) {
2123 			id = 0x2432;
2124 		} else if (ha->device_id == 0x5422 ||
2125 		    ha->device_id == 0x8432) {
2126 			id = 0x2422;
2127 		} else {
2128 			id = ha->device_id;
2129 		}
2130 
2131 		if (mr.mb[1] == PROD_ID_1 &&
2132 		    (mr.mb[2] == PROD_ID_2 || mr.mb[2] == PROD_ID_2a) &&
2133 		    (mr.mb[3] == PROD_ID_3 || mr.mb[3] == id)) {
2134 
2135 			ha->adapter_stats->revlvl.isp2200 = RD16_IO_REG(ha,
2136 			    mailbox[4]);
2137 			ha->adapter_stats->revlvl.risc = RD16_IO_REG(ha,
2138 			    mailbox[5]);
2139 			ha->adapter_stats->revlvl.frmbfr = RD16_IO_REG(ha,
2140 			    mailbox[6]);
2141 			ha->adapter_stats->revlvl.riscrom = RD16_IO_REG(ha,
2142 			    mailbox[7]);
2143 			bcopy(QL_VERSION, ha->adapter_stats->revlvl.qlddv,
2144 			    strlen(QL_VERSION));
2145 
2146 			/* Wrap Incoming Mailboxes Test. */
2147 			mr.mb[1] = 0xAAAA;
2148 			mr.mb[2] = 0x5555;
2149 			mr.mb[3] = 0xAA55;
2150 			mr.mb[4] = 0x55AA;
2151 			mr.mb[5] = 0xA5A5;
2152 			mr.mb[6] = 0x5A5A;
2153 			mr.mb[7] = 0x2525;
2154 			rval = ql_mbx_wrap_test(ha, &mr);
2155 			if (rval == QL_SUCCESS) {
2156 				if (mr.mb[1] != 0xAAAA ||
2157 				    mr.mb[2] != 0x5555 ||
2158 				    mr.mb[3] != 0xAA55 ||
2159 				    mr.mb[4] != 0x55AA ||
2160 				    mr.mb[5] != 0xA5A5 ||
2161 				    mr.mb[6] != 0x5A5A ||
2162 				    mr.mb[7] != 0x2525) {
2163 					rval = QL_FUNCTION_FAILED;
2164 					(void) ql_flash_errlog(ha,
2165 					    FLASH_ERRLOG_ISP_ERR, 0,
2166 					    RD16_IO_REG(ha, hccr),
2167 					    RD16_IO_REG(ha, istatus));
2168 				}
2169 			} else {
2170 				cmn_err(CE_WARN, "%s(%d) - reg test failed="
2171 				    "%xh!", QL_NAME, ha->instance, rval);
2172 			}
2173 		} else {
2174 			cmn_err(CE_WARN, "%s(%d) - prod id failed!, mb1=%xh, "
2175 			    "mb2=%xh, mb3=%xh", QL_NAME, ha->instance,
2176 			    mr.mb[1], mr.mb[2], mr.mb[3]);
2177 		}
2178 	} while ((retries-- != 0) && (rval != QL_SUCCESS));
2179 
2180 	if (rval != QL_SUCCESS) {
2181 		EL(ha, "failed, rval = %xh\n", rval);
2182 	} else {
2183 		/*EMPTY*/
2184 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2185 	}
2186 	return (rval);
2187 }
2188 
2189 /*
2190  * ql_load_isp_firmware
2191  *	Load and start RISC firmware.
2192  *	Uses request ring for DMA buffer.
2193  *
2194  * Input:
2195  *	ha = adapter state pointer.
2196  *
2197  * Returns:
2198  *	ql local function return status code.
2199  *
2200  * Context:
2201  *	Kernel context.
2202  */
2203 int
2204 ql_load_isp_firmware(ql_adapter_state_t *vha)
2205 {
2206 	caddr_t			risc_code_address;
2207 	uint32_t		risc_address, risc_code_size;
2208 	int			rval;
2209 	uint32_t		word_count, cnt;
2210 	size_t			byte_count;
2211 	ql_adapter_state_t	*ha = vha->pha;
2212 
2213 	if (CFG_IST(ha, CFG_LOAD_FLASH_FW)) {
2214 		return (ql_load_flash_fw(ha));
2215 	}
2216 
2217 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2218 
2219 	/* Load firmware segments */
2220 	for (cnt = 0; cnt < MAX_RISC_CODE_SEGMENTS &&
2221 	    ha->risc_fw[cnt].code != NULL; cnt++) {
2222 
2223 		risc_code_address = ha->risc_fw[cnt].code;
2224 		risc_address = ha->risc_fw[cnt].addr;
2225 		risc_code_size = ha->risc_fw[cnt].length;
2226 
2227 		while (risc_code_size) {
2228 			if (CFG_IST(ha, CFG_CTRL_2425)) {
2229 				word_count = ha->fw_transfer_size >> 2;
2230 				if (word_count > risc_code_size) {
2231 					word_count = risc_code_size;
2232 				}
2233 				byte_count = word_count << 2;
2234 
2235 				ddi_rep_put32(ha->hba_buf.acc_handle,
2236 				    (uint32_t *)risc_code_address,
2237 				    (uint32_t *)ha->request_ring_bp,
2238 				    word_count, DDI_DEV_AUTOINCR);
2239 			} else {
2240 				word_count = ha->fw_transfer_size >> 1;
2241 				if (word_count > risc_code_size) {
2242 					word_count = risc_code_size;
2243 				}
2244 				byte_count = word_count << 1;
2245 
2246 				ddi_rep_put16(ha->hba_buf.acc_handle,
2247 				    (uint16_t *)risc_code_address,
2248 				    (uint16_t *)ha->request_ring_bp,
2249 				    word_count, DDI_DEV_AUTOINCR);
2250 			}
2251 
2252 			(void) ddi_dma_sync(ha->hba_buf.dma_handle,
2253 			    REQUEST_Q_BUFFER_OFFSET, byte_count,
2254 			    DDI_DMA_SYNC_FORDEV);
2255 
2256 			rval = ql_wrt_risc_ram(ha, risc_address,
2257 			    ha->request_dvma, word_count);
2258 			if (rval != QL_SUCCESS) {
2259 				EL(ha, "failed, load=%xh\n", rval);
2260 				cnt = MAX_RISC_CODE_SEGMENTS;
2261 				break;
2262 			}
2263 
2264 			risc_address += word_count;
2265 			risc_code_size -= word_count;
2266 			risc_code_address += byte_count;
2267 		}
2268 	}
2269 
2270 	/* Start firmware. */
2271 	if (rval == QL_SUCCESS) {
2272 		rval = ql_start_firmware(ha);
2273 	}
2274 
2275 	if (rval != QL_SUCCESS) {
2276 		EL(ha, "failed, rval = %xh\n", rval);
2277 	} else {
2278 		/*EMPTY*/
2279 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2280 	}
2281 
2282 	return (rval);
2283 }
2284 
2285 /*
2286  * ql_load_flash_fw
2287  *	Gets ISP24xx firmware from flash and loads ISP.
2288  *
2289  * Input:
2290  *	ha:	adapter state pointer.
2291  *
2292  * Returns:
2293  *	qla local function return status code.
2294  */
2295 static int
2296 ql_load_flash_fw(ql_adapter_state_t *ha)
2297 {
2298 	int		rval;
2299 	uint8_t		seg_cnt;
2300 	uint32_t	risc_address, xfer_size, count,	*bp, faddr;
2301 	uint32_t	flash_addr = FLASH_24XX_FIRMWARE_ADDR;
2302 	uint32_t	risc_code_size = 0;
2303 
2304 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2305 
2306 	/* Adjust addr for 32 bit words */
2307 	flash_addr = flash_addr / 4;
2308 
2309 	for (seg_cnt = 0; seg_cnt < 2; seg_cnt++) {
2310 		xfer_size = ha->fw_transfer_size >> 2;
2311 		do {
2312 			GLOBAL_HW_LOCK();
2313 
2314 			/* Read data from flash. */
2315 			bp = (uint32_t *)ha->request_ring_bp;
2316 			faddr = FLASH_DATA_ADDR | flash_addr;
2317 			for (count = 0; count < xfer_size; count++) {
2318 				rval = ql_24xx_read_flash(ha, faddr++, bp);
2319 				if (rval != QL_SUCCESS) {
2320 					break;
2321 				}
2322 				ql_chg_endian((uint8_t *)bp++, 4);
2323 			}
2324 
2325 			GLOBAL_HW_UNLOCK();
2326 
2327 			if (rval != QL_SUCCESS) {
2328 				EL(ha, "24xx_read_flash failed=%xh\n", rval);
2329 				break;
2330 			}
2331 
2332 			if (risc_code_size == 0) {
2333 				bp = (uint32_t *)ha->request_ring_bp;
2334 				risc_address = bp[2];
2335 				risc_code_size = bp[3];
2336 				ha->risc_fw[seg_cnt].addr = risc_address;
2337 				ha->risc_fw[seg_cnt].length = risc_code_size;
2338 			}
2339 
2340 			if (risc_code_size < xfer_size) {
2341 				xfer_size = risc_code_size;
2342 			}
2343 
2344 			(void) ddi_dma_sync(ha->hba_buf.dma_handle,
2345 			    REQUEST_Q_BUFFER_OFFSET, xfer_size << 2,
2346 			    DDI_DMA_SYNC_FORDEV);
2347 
2348 			rval = ql_wrt_risc_ram(ha, risc_address,
2349 			    ha->request_dvma, xfer_size);
2350 			if (rval != QL_SUCCESS) {
2351 				EL(ha, "ql_wrt_risc_ram failed=%xh\n", rval);
2352 				break;
2353 			}
2354 
2355 			risc_address += xfer_size;
2356 			risc_code_size -= xfer_size;
2357 			flash_addr += xfer_size;
2358 		} while (risc_code_size);
2359 
2360 		if (rval != QL_SUCCESS) {
2361 			break;
2362 		}
2363 	}
2364 
2365 	/* Start firmware. */
2366 	if (rval == QL_SUCCESS) {
2367 		rval = ql_start_firmware(ha);
2368 	}
2369 
2370 	if (rval != QL_SUCCESS) {
2371 		EL(ha, "failed, rval = %xh\n", rval);
2372 	} else {
2373 		/*EMPTY*/
2374 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2375 	}
2376 	return (rval);
2377 }
2378 
2379 /*
2380  * ql_start_firmware
2381  *	Starts RISC code.
2382  *
2383  * Input:
2384  *	ha = adapter state pointer.
2385  *
2386  * Returns:
2387  *	ql local function return status code.
2388  *
2389  * Context:
2390  *	Kernel context.
2391  */
2392 int
2393 ql_start_firmware(ql_adapter_state_t *vha)
2394 {
2395 	int			rval;
2396 	ql_mbx_data_t		mr;
2397 	ql_adapter_state_t	*ha = vha->pha;
2398 
2399 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2400 
2401 	/* Verify checksum of loaded RISC code. */
2402 	rval = ql_verify_checksum(ha);
2403 	if (rval == QL_SUCCESS) {
2404 		/* Start firmware execution. */
2405 		(void) ql_execute_fw(ha);
2406 
2407 		/* Save firmware version. */
2408 		(void) ql_get_fw_version(ha, &mr);
2409 		ha->fw_major_version = mr.mb[1];
2410 		ha->fw_minor_version = mr.mb[2];
2411 		ha->fw_subminor_version = mr.mb[3];
2412 		ha->fw_ext_memory_size = ((SHORT_TO_LONG(mr.mb[4], mr.mb[5]) -
2413 		    0x100000) + 1) * 4;
2414 		ha->fw_attributes = mr.mb[6];
2415 
2416 		/* Set Serdes Transmit Parameters. */
2417 		if (ha->serdes_param[0] & BIT_0) {
2418 			mr.mb[1] = ha->serdes_param[0];
2419 			mr.mb[2] = ha->serdes_param[1];
2420 			mr.mb[3] = ha->serdes_param[2];
2421 			mr.mb[4] = ha->serdes_param[3];
2422 			(void) ql_serdes_param(ha, &mr);
2423 		}
2424 	}
2425 
2426 	if (rval != QL_SUCCESS) {
2427 		ha->task_daemon_flags &= ~FIRMWARE_LOADED;
2428 		EL(ha, "failed, rval = %xh\n", rval);
2429 	} else {
2430 		ha->task_daemon_flags |= FIRMWARE_LOADED;
2431 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2432 	}
2433 	return (rval);
2434 }
2435 
2436 /*
2437  * ql_set_cache_line
2438  *	Sets PCI cache line parameter.
2439  *
2440  * Input:
2441  *	ha = adapter state pointer.
2442  *
2443  * Returns:
2444  *	ql local function return status code.
2445  *
2446  * Context:
2447  *	Kernel context.
2448  */
2449 int
2450 ql_set_cache_line(ql_adapter_state_t *ha)
2451 {
2452 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2453 
2454 	/* Set the cache line. */
2455 	if (CFG_IST(ha->pha, CFG_SET_CACHE_LINE_SIZE_1)) {
2456 		/* Set cache line register. */
2457 		ql_pci_config_put8(ha->pha, PCI_CONF_CACHE_LINESZ, 1);
2458 	}
2459 
2460 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2461 
2462 	return (QL_SUCCESS);
2463 }
2464 
2465 /*
2466  * ql_init_rings
2467  *	Initializes firmware and ring pointers.
2468  *
2469  *	Beginning of response ring has initialization control block
2470  *	already built by nvram config routine.
2471  *
2472  * Input:
2473  *	ha = adapter state pointer.
2474  *	ha->hba_buf = request and response rings
2475  *	ha->init_ctrl_blk = initialization control block
2476  *
2477  * Returns:
2478  *	ql local function return status code.
2479  *
2480  * Context:
2481  *	Kernel context.
2482  */
2483 int
2484 ql_init_rings(ql_adapter_state_t *vha2)
2485 {
2486 	int			rval, rval2;
2487 	uint16_t		index;
2488 	ql_mbx_data_t		mr;
2489 	ql_adapter_state_t	*ha = vha2->pha;
2490 
2491 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2492 
2493 	/* Clear outstanding commands array. */
2494 	for (index = 0; index < MAX_OUTSTANDING_COMMANDS; index++) {
2495 		ha->outstanding_cmds[index] = NULL;
2496 	}
2497 	ha->osc_index = 1;
2498 
2499 	ha->pending_cmds.first = NULL;
2500 	ha->pending_cmds.last = NULL;
2501 
2502 	/* Initialize firmware. */
2503 	ha->request_ring_ptr = ha->request_ring_bp;
2504 	ha->req_ring_index = 0;
2505 	ha->req_q_cnt = REQUEST_ENTRY_CNT - 1;
2506 	ha->response_ring_ptr = ha->response_ring_bp;
2507 	ha->rsp_ring_index = 0;
2508 
2509 	if (ha->flags & VP_ENABLED) {
2510 		ql_adapter_state_t	*vha;
2511 		uint16_t		cnt;
2512 		uint32_t		max_vports;
2513 		ql_init_24xx_cb_t	*icb = &ha->init_ctrl_blk.cb24;
2514 
2515 		max_vports = (CFG_IST(ha, CFG_CTRL_2422) ?
2516 		    MAX_24_VIRTUAL_PORTS : MAX_25_VIRTUAL_PORTS);
2517 		bzero(icb->vp_count,
2518 		    ((uintptr_t)icb + sizeof (ql_init_24xx_cb_t)) -
2519 		    (uintptr_t)icb->vp_count);
2520 		icb->vp_count[0] = (uint8_t)max_vports;
2521 
2522 		/* Allow connection option 2. */
2523 		icb->global_vp_option[0] = BIT_1;
2524 
2525 		for (cnt = 0, vha = ha->vp_next; cnt < max_vports &&
2526 		    vha != NULL; vha = vha->vp_next, cnt++) {
2527 
2528 			index = (uint8_t)(vha->vp_index - 1);
2529 			bcopy(vha->loginparams.node_ww_name.raw_wwn,
2530 			    icb->vpc[index].node_name, 8);
2531 			bcopy(vha->loginparams.nport_ww_name.raw_wwn,
2532 			    icb->vpc[index].port_name, 8);
2533 
2534 			icb->vpc[index].options = VPO_TARGET_MODE_DISABLED |
2535 			    VPO_INITIATOR_MODE_ENABLED;
2536 			if (vha->flags & VP_ENABLED) {
2537 				icb->vpc[index].options = (uint8_t)
2538 				    (icb->vpc[index].options | VPO_ENABLED);
2539 			}
2540 		}
2541 	}
2542 
2543 	rval = ql_init_firmware(ha);
2544 
2545 	if (rval == QL_SUCCESS && (CFG_IST(ha, CFG_CTRL_2425)) == 0) {
2546 		/* Tell firmware to enable MBA_PORT_BYPASS_CHANGED event */
2547 		rval = ql_get_firmware_option(ha, &mr);
2548 		if (rval == QL_SUCCESS) {
2549 			mr.mb[1] = (uint16_t)(mr.mb[1] | BIT_9);
2550 			mr.mb[2] = 0;
2551 			mr.mb[3] = BIT_10;
2552 			rval = ql_set_firmware_option(ha, &mr);
2553 		}
2554 	}
2555 
2556 	if ((rval == QL_SUCCESS) && (CFG_IST(ha, CFG_ENABLE_FWFCETRACE))) {
2557 		if ((rval2 = ql_get_dma_mem(ha, &ha->fwfcetracebuf,
2558 		    FWFCESIZE, LITTLE_ENDIAN_DMA, MEM_RING_ALIGN))
2559 		    != QL_SUCCESS) {
2560 			EL(ha, "fcetrace buffer alloc failed: %xh\n", rval2);
2561 		} else {
2562 			if ((rval2 = ql_fw_etrace(ha, &ha->fwfcetracebuf,
2563 			    FTO_FCEENABLE)) != QL_SUCCESS) {
2564 				EL(ha, "fcetrace enable failed: %xh\n", rval2);
2565 				ql_free_phys(ha, &ha->fwfcetracebuf);
2566 			}
2567 		}
2568 	}
2569 
2570 	if ((rval == QL_SUCCESS) && (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE))) {
2571 		if ((rval2 = ql_get_dma_mem(ha, &ha->fwexttracebuf,
2572 		    FWEXTSIZE, LITTLE_ENDIAN_DMA, MEM_RING_ALIGN))
2573 		    != QL_SUCCESS) {
2574 			EL(ha, "exttrace buffer alloc failed: %xh\n", rval2);
2575 		} else {
2576 			if ((rval2 = ql_fw_etrace(ha, &ha->fwexttracebuf,
2577 			    FTO_EXTENABLE)) != QL_SUCCESS) {
2578 				EL(ha, "exttrace enable failed: %xh\n", rval2);
2579 				ql_free_phys(ha, &ha->fwexttracebuf);
2580 			}
2581 		}
2582 	}
2583 
2584 	if (rval == QL_SUCCESS && CFG_IST(ha, CFG_CTRL_MENLO)) {
2585 		ql_mbx_iocb_t	*pkt;
2586 		clock_t		timer;
2587 
2588 		/* Wait for firmware login of menlo. */
2589 		for (timer = 3000; timer; timer--) {
2590 			if (ha->flags & MENLO_LOGIN_OPERATIONAL) {
2591 				break;
2592 			}
2593 
2594 			if (!(ha->flags & INTERRUPTS_ENABLED) ||
2595 			    ddi_in_panic()) {
2596 				if (RD16_IO_REG(ha, istatus) & RISC_INT) {
2597 					(void) ql_isr((caddr_t)ha);
2598 					INTR_LOCK(ha);
2599 					ha->intr_claimed = B_TRUE;
2600 					INTR_UNLOCK(ha);
2601 				}
2602 			}
2603 
2604 			/* Delay for 1 tick (10 milliseconds). */
2605 			ql_delay(ha, 10000);
2606 		}
2607 
2608 		if (timer == 0) {
2609 			rval = QL_FUNCTION_TIMEOUT;
2610 		} else {
2611 			pkt = kmem_zalloc(sizeof (ql_mbx_iocb_t), KM_SLEEP);
2612 			if (pkt == NULL) {
2613 				EL(ha, "failed, kmem_zalloc\n");
2614 				rval = QL_MEMORY_ALLOC_FAILED;
2615 			} else {
2616 				pkt->mvfy.entry_type = VERIFY_MENLO_TYPE;
2617 				pkt->mvfy.entry_count = 1;
2618 				pkt->mvfy.options_status =
2619 				    LE_16(VMF_DO_NOT_UPDATE_FW);
2620 
2621 				rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt,
2622 				    sizeof (ql_mbx_iocb_t));
2623 				LITTLE_ENDIAN_16(&pkt->mvfy.options_status);
2624 				LITTLE_ENDIAN_16(&pkt->mvfy.failure_code);
2625 
2626 				if (rval != QL_SUCCESS ||
2627 				    (pkt->mvfy.entry_status & 0x3c) != 0 ||
2628 				    pkt->mvfy.options_status != CS_COMPLETE) {
2629 					EL(ha, "failed, status=%xh, es=%xh, "
2630 					    "cs=%xh, fc=%xh\n", rval,
2631 					    pkt->mvfy.entry_status & 0x3c,
2632 					    pkt->mvfy.options_status,
2633 					    pkt->mvfy.failure_code);
2634 					if (rval == QL_SUCCESS) {
2635 						rval = QL_FUNCTION_FAILED;
2636 					}
2637 				}
2638 
2639 				kmem_free(pkt, sizeof (ql_mbx_iocb_t));
2640 			}
2641 		}
2642 	}
2643 
2644 	if (rval != QL_SUCCESS) {
2645 		TASK_DAEMON_LOCK(ha);
2646 		ha->task_daemon_flags &= ~FIRMWARE_UP;
2647 		TASK_DAEMON_UNLOCK(ha);
2648 		EL(ha, "failed, rval = %xh\n", rval);
2649 	} else {
2650 		TASK_DAEMON_LOCK(ha);
2651 		ha->task_daemon_flags |= FIRMWARE_UP;
2652 		TASK_DAEMON_UNLOCK(ha);
2653 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2654 	}
2655 	return (rval);
2656 }
2657 
2658 /*
2659  * ql_fw_ready
2660  *	Waits for firmware ready. If firmware becomes ready
2661  *	device queues and RISC code are synchronized.
2662  *
2663  * Input:
2664  *	ha = adapter state pointer.
2665  *	secs = max wait time, in seconds (0-255).
2666  *
2667  * Returns:
2668  *	ql local function return status code.
2669  *
2670  * Context:
2671  *	Kernel context.
2672  */
2673 int
2674 ql_fw_ready(ql_adapter_state_t *ha, uint8_t secs)
2675 {
2676 	ql_mbx_data_t	mr;
2677 	clock_t		timer;
2678 	clock_t		dly = 250000;
2679 	clock_t		sec_delay = MICROSEC / dly;
2680 	clock_t		wait = secs * sec_delay;
2681 	int		rval = QL_FUNCTION_FAILED;
2682 	uint16_t	state = 0xffff;
2683 
2684 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2685 
2686 	timer = ha->r_a_tov < secs ? secs : ha->r_a_tov;
2687 	timer = (timer + 2) * sec_delay;
2688 
2689 	/* Wait for ISP to finish LIP */
2690 	while (timer != 0 && wait != 0 &&
2691 	    !(ha->task_daemon_flags & ISP_ABORT_NEEDED)) {
2692 
2693 		rval = ql_get_firmware_state(ha, &mr);
2694 		if (rval == QL_SUCCESS) {
2695 			if (ha->task_daemon_flags & (ISP_ABORT_NEEDED |
2696 			    LOOP_DOWN)) {
2697 				wait--;
2698 			} else if (mr.mb[1] != FSTATE_READY) {
2699 				if (mr.mb[1] != FSTATE_WAIT_LOGIN) {
2700 					wait--;
2701 				}
2702 				rval = QL_FUNCTION_FAILED;
2703 			} else {
2704 				/* Firmware is ready. Get 2 * R_A_TOV. */
2705 				rval = ql_get_timeout_parameters(ha,
2706 				    &ha->r_a_tov);
2707 				if (rval != QL_SUCCESS) {
2708 					EL(ha, "failed, get_timeout_param"
2709 					    "=%xh\n", rval);
2710 				}
2711 
2712 				/* Configure loop. */
2713 				rval = ql_configure_loop(ha);
2714 				(void) ql_marker(ha, 0, 0, MK_SYNC_ALL);
2715 
2716 				if (ha->task_daemon_flags &
2717 				    LOOP_RESYNC_NEEDED) {
2718 					wait--;
2719 					EL(ha, "loop trans; tdf=%xh\n",
2720 					    ha->task_daemon_flags);
2721 				} else {
2722 					break;
2723 				}
2724 			}
2725 		} else {
2726 			wait--;
2727 		}
2728 
2729 		if (state != mr.mb[1]) {
2730 			EL(ha, "mailbox_reg[1] = %xh\n", mr.mb[1]);
2731 			state = mr.mb[1];
2732 		}
2733 
2734 		/* Delay for a tick if waiting. */
2735 		if (timer-- != 0 && wait != 0) {
2736 			if (timer % 4 == 0) {
2737 				delay(drv_usectohz(dly));
2738 			} else {
2739 				drv_usecwait(dly);
2740 			}
2741 		} else {
2742 			rval = QL_FUNCTION_TIMEOUT;
2743 		}
2744 	}
2745 
2746 	if (rval != QL_SUCCESS) {
2747 		EL(ha, "failed, rval = %xh\n", rval);
2748 	} else {
2749 		/*EMPTY*/
2750 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2751 	}
2752 	return (rval);
2753 }
2754 
2755 /*
2756  * ql_configure_loop
2757  *	Setup configurations based on loop.
2758  *
2759  * Input:
2760  *	ha = adapter state pointer.
2761  *
2762  * Returns:
2763  *	ql local function return status code.
2764  *
2765  * Context:
2766  *	Kernel context.
2767  */
2768 static int
2769 ql_configure_loop(ql_adapter_state_t *ha)
2770 {
2771 	int			rval;
2772 	ql_adapter_state_t	*vha;
2773 
2774 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2775 
2776 	for (vha = ha; vha != NULL; vha = vha->vp_next) {
2777 		TASK_DAEMON_LOCK(ha);
2778 		if (!(vha->task_daemon_flags & LOOP_RESYNC_NEEDED) &&
2779 		    vha->vp_index != 0 && !(vha->flags & VP_ENABLED)) {
2780 			TASK_DAEMON_UNLOCK(ha);
2781 			continue;
2782 		}
2783 		vha->task_daemon_flags &= ~LOOP_RESYNC_NEEDED;
2784 		TASK_DAEMON_UNLOCK(ha);
2785 
2786 		rval = ql_configure_hba(vha);
2787 		if (rval == QL_SUCCESS && !(ha->task_daemon_flags &
2788 		    (LOOP_RESYNC_NEEDED | LOOP_DOWN))) {
2789 			rval = ql_configure_device_d_id(vha);
2790 			if (rval == QL_SUCCESS && !(ha->task_daemon_flags &
2791 			    (LOOP_RESYNC_NEEDED | LOOP_DOWN))) {
2792 				(void) ql_configure_fabric(vha);
2793 			}
2794 		}
2795 	}
2796 
2797 	if (rval != QL_SUCCESS) {
2798 		EL(ha, "failed, rval = %xh\n", rval);
2799 	} else {
2800 		/*EMPTY*/
2801 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2802 	}
2803 	return (rval);
2804 }
2805 
2806 /*
2807  * ql_configure_hba
2808  *	Setup adapter context.
2809  *
2810  * Input:
2811  *	ha = adapter state pointer.
2812  *
2813  * Returns:
2814  *	ql local function return status code.
2815  *
2816  * Context:
2817  *	Kernel context.
2818  */
2819 static int
2820 ql_configure_hba(ql_adapter_state_t *ha)
2821 {
2822 	uint8_t		*bp;
2823 	int		rval;
2824 	uint32_t	state;
2825 	ql_mbx_data_t	mr;
2826 
2827 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2828 
2829 	/* Get host addresses. */
2830 	rval = ql_get_adapter_id(ha, &mr);
2831 	if (rval == QL_SUCCESS) {
2832 		ha->topology = (uint8_t)(ha->topology &
2833 		    ~(QL_N_PORT | QL_NL_PORT | QL_F_PORT | QL_FL_PORT));
2834 
2835 		/* Save Host d_id, alpa, loop ID. */
2836 		ha->loop_id = mr.mb[1];
2837 		ha->d_id.b.al_pa = LSB(mr.mb[2]);
2838 		ha->d_id.b.area = MSB(mr.mb[2]);
2839 		ha->d_id.b.domain = LSB(mr.mb[3]);
2840 
2841 		ADAPTER_STATE_LOCK(ha);
2842 		ha->flags &= ~FDISC_ENABLED;
2843 
2844 		/* Get loop topology. */
2845 		switch (mr.mb[6]) {
2846 		case CNX_LOOP_NO_FABRIC:
2847 			ha->topology = (uint8_t)(ha->topology | QL_NL_PORT);
2848 			break;
2849 		case CNX_FLPORT_IN_LOOP:
2850 			ha->topology = (uint8_t)(ha->topology | QL_FL_PORT);
2851 			break;
2852 		case CNX_NPORT_2_NPORT_P2P:
2853 		case CNX_NPORT_2_NPORT_NO_TGT_RSP:
2854 			ha->flags |= POINT_TO_POINT;
2855 			ha->topology = (uint8_t)(ha->topology | QL_N_PORT);
2856 			break;
2857 		case CNX_FLPORT_P2P:
2858 			ha->flags |= POINT_TO_POINT;
2859 			ha->topology = (uint8_t)(ha->topology | QL_F_PORT);
2860 
2861 			/* Get supported option. */
2862 			if (CFG_IST(ha, CFG_CTRL_2425) &&
2863 			    mr.mb[7] & FLOGI_NPIV_SUPPORT) {
2864 				ha->flags |= FDISC_ENABLED;
2865 			}
2866 			break;
2867 		default:
2868 			QL_PRINT_2(CE_CONT, "(%d,%d): UNKNOWN topology=%xh, "
2869 			    "d_id=%xh\n", ha->instance, ha->vp_index, mr.mb[6],
2870 			    ha->d_id.b24);
2871 			rval = QL_FUNCTION_FAILED;
2872 			break;
2873 		}
2874 		ADAPTER_STATE_UNLOCK(ha);
2875 
2876 		if (CFG_IST(ha, (CFG_CTRL_2300|CFG_CTRL_6322|
2877 		    CFG_CTRL_2425))) {
2878 			mr.mb[1] = 0;
2879 			mr.mb[2] = 0;
2880 			rval = ql_data_rate(ha, &mr);
2881 			if (rval != QL_SUCCESS) {
2882 				EL(ha, "data_rate status=%xh\n", rval);
2883 				state = FC_STATE_FULL_SPEED;
2884 			} else {
2885 				if (mr.mb[1] == 0) {
2886 					state = FC_STATE_1GBIT_SPEED;
2887 				} else if (mr.mb[1] == 1) {
2888 					state = FC_STATE_2GBIT_SPEED;
2889 				} else if (mr.mb[1] == 3) {
2890 					state = FC_STATE_4GBIT_SPEED;
2891 				} else if (mr.mb[1] == 4) {
2892 					state = FC_STATE_8GBIT_SPEED;
2893 				} else {
2894 					state = 0;
2895 				}
2896 			}
2897 		} else {
2898 			state = FC_STATE_FULL_SPEED;
2899 		}
2900 		ha->state = FC_PORT_STATE_MASK(ha->state) | state;
2901 	}
2902 
2903 	if (rval != QL_SUCCESS) {
2904 		EL(ha, "failed, rval = %xh\n", rval);
2905 	} else {
2906 		bp = ha->loginparams.nport_ww_name.raw_wwn;
2907 		EL(ha, "topology=%xh, d_id=%xh, "
2908 		    "wwpn=%02x%02x%02x%02x%02x%02x%02x%02xh\n",
2909 		    ha->topology, ha->d_id.b24, bp[0], bp[1],
2910 		    bp[2], bp[3], bp[4], bp[5], bp[6], bp[7]);
2911 	}
2912 	return (rval);
2913 }
2914 
2915 /*
2916  * ql_configure_device_d_id
2917  *	Updates device loop ID.
2918  *	Also adds to device queue any new devices found on private loop.
2919  *
2920  * Input:
2921  *	ha = adapter state pointer.
2922  *
2923  * Returns:
2924  *	ql local function return status code.
2925  *
2926  * Context:
2927  *	Kernel context.
2928  */
2929 static int
2930 ql_configure_device_d_id(ql_adapter_state_t *ha)
2931 {
2932 	port_id_t		d_id;
2933 	ql_link_t		*link;
2934 	int			rval;
2935 	int			loop;
2936 	ql_tgt_t		*tq;
2937 	ql_dev_id_list_t	*list;
2938 	uint32_t		list_size;
2939 	uint16_t		index, loop_id;
2940 	ql_mbx_data_t		mr;
2941 	uint8_t			retries = MAX_DEVICE_LOST_RETRY;
2942 
2943 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2944 
2945 	list_size = sizeof (ql_dev_id_list_t) * DEVICE_LIST_ENTRIES;
2946 	list = kmem_zalloc(list_size, KM_SLEEP);
2947 	if (list == NULL) {
2948 		rval = QL_MEMORY_ALLOC_FAILED;
2949 		EL(ha, "failed, rval = %xh\n", rval);
2950 		return (rval);
2951 	}
2952 
2953 	do {
2954 		/*
2955 		 * Get data from RISC code d_id list to init each device queue.
2956 		 */
2957 		rval = ql_get_id_list(ha, (caddr_t)list, list_size, &mr);
2958 		if (rval != QL_SUCCESS) {
2959 			kmem_free(list, list_size);
2960 			EL(ha, "failed, rval = %xh\n", rval);
2961 			return (rval);
2962 		}
2963 
2964 		/* Acquire adapter state lock. */
2965 		ADAPTER_STATE_LOCK(ha);
2966 
2967 		/* Mark all queues as unusable. */
2968 		for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
2969 			for (link = ha->dev[index].first; link != NULL;
2970 			    link = link->next) {
2971 				tq = link->base_address;
2972 				DEVICE_QUEUE_LOCK(tq);
2973 				if (!(tq->flags & TQF_PLOGI_PROGRS)) {
2974 					tq->loop_id = (uint16_t)
2975 					    (tq->loop_id | PORT_LOST_ID);
2976 				}
2977 				DEVICE_QUEUE_UNLOCK(tq);
2978 			}
2979 		}
2980 
2981 		/* If device not in queues add new queue. */
2982 		for (index = 0; index < mr.mb[1]; index++) {
2983 			ql_dev_list(ha, list, index, &d_id, &loop_id);
2984 
2985 			if (VALID_DEVICE_ID(ha, loop_id)) {
2986 				tq = ql_dev_init(ha, d_id, loop_id);
2987 				if (tq != NULL) {
2988 					tq->loop_id = loop_id;
2989 
2990 					/* Test for fabric device. */
2991 					if (d_id.b.domain !=
2992 					    ha->d_id.b.domain ||
2993 					    d_id.b.area != ha->d_id.b.area) {
2994 						tq->flags |= TQF_FABRIC_DEVICE;
2995 					}
2996 
2997 					ADAPTER_STATE_UNLOCK(ha);
2998 					if (ql_get_port_database(ha, tq,
2999 					    PDF_NONE) == QL_SUCCESS) {
3000 						ADAPTER_STATE_LOCK(ha);
3001 						tq->loop_id = (uint16_t)
3002 						    (tq->loop_id &
3003 						    ~PORT_LOST_ID);
3004 					} else {
3005 						ADAPTER_STATE_LOCK(ha);
3006 					}
3007 				}
3008 			}
3009 		}
3010 
3011 		/* 24xx does not report switch devices in ID list. */
3012 		if ((CFG_IST(ha, CFG_CTRL_2425)) &&
3013 		    ha->topology & (QL_F_PORT | QL_FL_PORT)) {
3014 			d_id.b24 = 0xfffffe;
3015 			tq = ql_dev_init(ha, d_id, FL_PORT_24XX_HDL);
3016 			if (tq != NULL) {
3017 				ADAPTER_STATE_UNLOCK(ha);
3018 				(void) ql_get_port_database(ha, tq, PDF_NONE);
3019 				ADAPTER_STATE_LOCK(ha);
3020 			}
3021 			d_id.b24 = 0xfffffc;
3022 			tq = ql_dev_init(ha, d_id, SNS_24XX_HDL);
3023 			if (tq != NULL) {
3024 				ADAPTER_STATE_UNLOCK(ha);
3025 				if (ha->vp_index != 0) {
3026 					(void) ql_login_fport(ha, tq,
3027 					    SNS_24XX_HDL, LFF_NONE, NULL);
3028 				}
3029 				(void) ql_get_port_database(ha, tq, PDF_NONE);
3030 				ADAPTER_STATE_LOCK(ha);
3031 			}
3032 		}
3033 
3034 		/* If F_port exists, allocate queue for FL_Port. */
3035 		index = ql_alpa_to_index[0xfe];
3036 		d_id.b24 = 0;
3037 		if (ha->dev[index].first != NULL) {
3038 			tq = ql_dev_init(ha, d_id, (uint16_t)
3039 			    (CFG_IST(ha, CFG_CTRL_2425) ?
3040 			    FL_PORT_24XX_HDL : FL_PORT_LOOP_ID));
3041 			if (tq != NULL) {
3042 				ADAPTER_STATE_UNLOCK(ha);
3043 				(void) ql_get_port_database(ha, tq, PDF_NONE);
3044 				ADAPTER_STATE_LOCK(ha);
3045 			}
3046 		}
3047 
3048 		/* Allocate queue for broadcast. */
3049 		d_id.b24 = 0xffffff;
3050 		(void) ql_dev_init(ha, d_id, (uint16_t)
3051 		    (CFG_IST(ha, CFG_CTRL_2425) ? BROADCAST_24XX_HDL :
3052 		    IP_BROADCAST_LOOP_ID));
3053 
3054 		/* Check for any devices lost. */
3055 		loop = FALSE;
3056 		for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
3057 			for (link = ha->dev[index].first; link != NULL;
3058 			    link = link->next) {
3059 				tq = link->base_address;
3060 
3061 				if ((tq->loop_id & PORT_LOST_ID) &&
3062 				    !(tq->flags & (TQF_INITIATOR_DEVICE |
3063 				    TQF_FABRIC_DEVICE))) {
3064 					loop = TRUE;
3065 				}
3066 			}
3067 		}
3068 
3069 		/* Release adapter state lock. */
3070 		ADAPTER_STATE_UNLOCK(ha);
3071 
3072 		/* Give devices time to recover. */
3073 		if (loop == TRUE) {
3074 			drv_usecwait(1000000);
3075 		}
3076 	} while (retries-- && loop == TRUE &&
3077 	    !(ha->pha->task_daemon_flags & LOOP_RESYNC_NEEDED));
3078 
3079 	kmem_free(list, list_size);
3080 
3081 	if (rval != QL_SUCCESS) {
3082 		EL(ha, "failed=%xh\n", rval);
3083 	} else {
3084 		/*EMPTY*/
3085 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3086 	}
3087 
3088 	return (rval);
3089 }
3090 
3091 /*
3092  * ql_dev_list
3093  *	Gets device d_id and loop ID from firmware device list.
3094  *
3095  * Input:
3096  *	ha:	adapter state pointer.
3097  *	list	device list pointer.
3098  *	index:	list index of device data.
3099  *	d_id:	pointer for d_id data.
3100  *	id:	pointer for loop ID.
3101  *
3102  * Context:
3103  *	Kernel context.
3104  */
3105 void
3106 ql_dev_list(ql_adapter_state_t *ha, union ql_dev_id_list *list,
3107     uint32_t index, port_id_t *d_id, uint16_t *id)
3108 {
3109 	if (CFG_IST(ha, CFG_CTRL_2425)) {
3110 		struct ql_24_dev_id	*list24 = (struct ql_24_dev_id *)list;
3111 
3112 		d_id->b.al_pa = list24[index].al_pa;
3113 		d_id->b.area = list24[index].area;
3114 		d_id->b.domain = list24[index].domain;
3115 		*id = CHAR_TO_SHORT(list24[index].n_port_hdl_l,
3116 		    list24[index].n_port_hdl_h);
3117 
3118 	} else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
3119 		struct ql_ex_dev_id	*list23 = (struct ql_ex_dev_id *)list;
3120 
3121 		d_id->b.al_pa = list23[index].al_pa;
3122 		d_id->b.area = list23[index].area;
3123 		d_id->b.domain = list23[index].domain;
3124 		*id = CHAR_TO_SHORT(list23[index].loop_id_l,
3125 		    list23[index].loop_id_h);
3126 
3127 	} else {
3128 		struct ql_dev_id	*list22 = (struct ql_dev_id *)list;
3129 
3130 		d_id->b.al_pa = list22[index].al_pa;
3131 		d_id->b.area = list22[index].area;
3132 		d_id->b.domain = list22[index].domain;
3133 		*id = (uint16_t)list22[index].loop_id;
3134 	}
3135 }
3136 
3137 /*
3138  * ql_configure_fabric
3139  *	Setup fabric context.
3140  *
3141  * Input:
3142  *	ha = adapter state pointer.
3143  *
3144  * Returns:
3145  *	ql local function return status code.
3146  *
3147  * Context:
3148  *	Kernel context.
3149  */
3150 static int
3151 ql_configure_fabric(ql_adapter_state_t *ha)
3152 {
3153 	port_id_t	d_id;
3154 	ql_tgt_t	*tq;
3155 	int		rval = QL_FUNCTION_FAILED;
3156 
3157 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3158 
3159 	ha->topology = (uint8_t)(ha->topology & ~QL_SNS_CONNECTION);
3160 
3161 	/* Test switch fabric controller present. */
3162 	d_id.b24 = FS_FABRIC_F_PORT;
3163 	tq = ql_d_id_to_queue(ha, d_id);
3164 	if (tq != NULL) {
3165 		/* Get port/node names of F_Port. */
3166 		(void) ql_get_port_database(ha, tq, PDF_NONE);
3167 
3168 		d_id.b24 = FS_NAME_SERVER;
3169 		tq = ql_d_id_to_queue(ha, d_id);
3170 		if (tq != NULL) {
3171 			(void) ql_get_port_database(ha, tq, PDF_NONE);
3172 			ha->topology = (uint8_t)
3173 			    (ha->topology | QL_SNS_CONNECTION);
3174 			rval = QL_SUCCESS;
3175 		}
3176 	}
3177 
3178 	if (rval != QL_SUCCESS) {
3179 		EL(ha, "failed=%xh\n", rval);
3180 	} else {
3181 		/*EMPTY*/
3182 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3183 	}
3184 	return (rval);
3185 }
3186 
3187 /*
3188  * ql_reset_chip
3189  *	Reset ISP chip.
3190  *
3191  * Input:
3192  *	ha = adapter block pointer.
3193  *	All activity on chip must be already stopped.
3194  *	ADAPTER_STATE_LOCK must be released.
3195  *
3196  * Context:
3197  *	Interrupt or Kernel context, no mailbox commands allowed.
3198  */
3199 void
3200 ql_reset_chip(ql_adapter_state_t *vha)
3201 {
3202 	uint32_t		cnt;
3203 	uint16_t		cmd;
3204 	ql_adapter_state_t	*ha = vha->pha;
3205 
3206 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3207 
3208 	/*
3209 	 * accessing pci space while not powered can cause panic's
3210 	 * on some platforms (i.e. Sunblade 1000's)
3211 	 */
3212 	if (ha->power_level == PM_LEVEL_D3) {
3213 		QL_PRINT_2(CE_CONT, "(%d): Low Power exit\n", ha->instance);
3214 		return;
3215 	}
3216 
3217 	/* Reset all outbound mailbox registers */
3218 	for (cnt = 0; cnt < ha->reg_off->mbox_cnt; cnt++) {
3219 		WRT16_IO_REG(ha, mailbox[cnt], (uint16_t)0);
3220 	}
3221 
3222 	/* Disable ISP interrupts. */
3223 	WRT16_IO_REG(ha, ictrl, 0);
3224 	ADAPTER_STATE_LOCK(ha);
3225 	ha->flags &= ~INTERRUPTS_ENABLED;
3226 	ADAPTER_STATE_UNLOCK(ha);
3227 
3228 	if (CFG_IST(ha, CFG_CTRL_2425)) {
3229 		RD32_IO_REG(ha, ictrl);
3230 		ql_reset_24xx_chip(ha);
3231 		QL_PRINT_3(CE_CONT, "(%d): 24xx exit\n", ha->instance);
3232 		return;
3233 	}
3234 
3235 	/*
3236 	 * We are going to reset the chip in case of 2300. That might cause
3237 	 * a PBM ERR if a DMA transaction is in progress. One way of
3238 	 * avoiding it is to disable Bus Master operation before we start
3239 	 * the reset activity.
3240 	 */
3241 	cmd = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_COMM);
3242 	cmd = (uint16_t)(cmd & ~PCI_COMM_ME);
3243 	ql_pci_config_put16(ha, PCI_CONF_COMM, cmd);
3244 
3245 	/* Pause RISC. */
3246 	WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC);
3247 	for (cnt = 0; cnt < 30000; cnt++) {
3248 		if ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) != 0) {
3249 			break;
3250 		}
3251 		drv_usecwait(MILLISEC);
3252 	}
3253 
3254 	/*
3255 	 * A call to ql_isr() can still happen through
3256 	 * ql_mailbox_command(). So Mark that we are/(will-be)
3257 	 * running from rom code now.
3258 	 */
3259 	TASK_DAEMON_LOCK(ha);
3260 	ha->task_daemon_flags &= ~(FIRMWARE_UP | FIRMWARE_LOADED);
3261 	TASK_DAEMON_UNLOCK(ha);
3262 
3263 	/* Select FPM registers. */
3264 	WRT16_IO_REG(ha, ctrl_status, 0x20);
3265 
3266 	/* FPM Soft Reset. */
3267 	WRT16_IO_REG(ha, fpm_diag_config, 0x100);
3268 
3269 	/* Toggle FPM reset for 2300 */
3270 	if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
3271 		WRT16_IO_REG(ha, fpm_diag_config, 0);
3272 	}
3273 
3274 	/* Select frame buffer registers. */
3275 	WRT16_IO_REG(ha, ctrl_status, 0x10);
3276 
3277 	/* Reset frame buffer FIFOs. */
3278 	if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
3279 		WRT16_IO_REG(ha, fb_cmd, 0x00fc);
3280 		/* read back fb_cmd until zero or 3 seconds max */
3281 		for (cnt = 0; cnt < 300000; cnt++) {
3282 			if ((RD16_IO_REG(ha, fb_cmd) & 0xff) == 0) {
3283 				break;
3284 			}
3285 			drv_usecwait(10);
3286 		}
3287 	} else  {
3288 		WRT16_IO_REG(ha, fb_cmd, 0xa000);
3289 	}
3290 
3291 	/* Select RISC module registers. */
3292 	WRT16_IO_REG(ha, ctrl_status, 0);
3293 
3294 	/* Reset RISC module. */
3295 	WRT16_IO_REG(ha, hccr, HC_RESET_RISC);
3296 
3297 	/* Reset ISP semaphore. */
3298 	WRT16_IO_REG(ha, semaphore, 0);
3299 
3300 	/* Release RISC module. */
3301 	WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
3302 
3303 	/* Insure mailbox registers are free. */
3304 	WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT);
3305 	WRT16_IO_REG(ha, hccr, HC_CLR_HOST_INT);
3306 	ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
3307 	    ~(MBX_BUSY_FLG | MBX_WANT_FLG | MBX_ABORT | MBX_INTERRUPT));
3308 	ha->mcp = NULL;
3309 
3310 	/* Bus Master is disabled so chip reset is safe. */
3311 	if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
3312 		WRT16_IO_REG(ha, ctrl_status, ISP_RESET);
3313 		drv_usecwait(MILLISEC);
3314 
3315 		/* Wait for reset to finish. */
3316 		for (cnt = 0; cnt < 30000; cnt++) {
3317 			if ((RD16_IO_REG(ha, ctrl_status) & ISP_RESET) == 0) {
3318 				break;
3319 			}
3320 			drv_usecwait(MILLISEC);
3321 		}
3322 	}
3323 
3324 	/* Wait for RISC to recover from reset. */
3325 	for (cnt = 0; cnt < 30000; cnt++) {
3326 		if (RD16_IO_REG(ha, mailbox[0]) != MBS_BUSY) {
3327 			break;
3328 		}
3329 		drv_usecwait(MILLISEC);
3330 	}
3331 
3332 	/* restore bus master */
3333 	cmd = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_COMM);
3334 	cmd = (uint16_t)(cmd | PCI_COMM_ME);
3335 	ql_pci_config_put16(ha, PCI_CONF_COMM, cmd);
3336 
3337 	/* Disable RISC pause on FPM parity error. */
3338 	WRT16_IO_REG(ha, hccr, HC_DISABLE_PARITY_PAUSE);
3339 
3340 	/* Initialize probe registers */
3341 	if (CFG_IST(ha, CFG_SBUS_CARD)) {
3342 		/* Pause RISC. */
3343 		WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC);
3344 		for (cnt = 0; cnt < 30000; cnt++) {
3345 			if ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) != 0) {
3346 				break;
3347 			} else {
3348 				drv_usecwait(MILLISEC);
3349 			}
3350 		}
3351 
3352 		/* Select FPM registers. */
3353 		WRT16_IO_REG(ha, ctrl_status, 0x30);
3354 
3355 		/* Set probe register */
3356 		WRT16_IO_REG(ha, mailbox[23], 0x204c);
3357 
3358 		/* Select RISC module registers. */
3359 		WRT16_IO_REG(ha, ctrl_status, 0);
3360 
3361 		/* Release RISC module. */
3362 		WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
3363 	}
3364 
3365 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3366 }
3367 
3368 /*
3369  * ql_reset_24xx_chip
3370  *	Reset ISP24xx chip.
3371  *
3372  * Input:
3373  *	ha = adapter block pointer.
3374  *	All activity on chip must be already stopped.
3375  *
3376  * Context:
3377  *	Interrupt or Kernel context, no mailbox commands allowed.
3378  */
3379 void
3380 ql_reset_24xx_chip(ql_adapter_state_t *ha)
3381 {
3382 	uint32_t	timer, stat;
3383 
3384 	/* Shutdown DMA. */
3385 	WRT32_IO_REG(ha, ctrl_status, DMA_SHUTDOWN | MWB_4096_BYTES);
3386 
3387 	/* Wait for DMA to stop. */
3388 	for (timer = 0; timer < 30000; timer++) {
3389 		if ((RD32_IO_REG(ha, ctrl_status) & DMA_ACTIVE) == 0) {
3390 			break;
3391 		}
3392 		drv_usecwait(100);
3393 	}
3394 
3395 	/* Stop the firmware. */
3396 	WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
3397 	WRT16_IO_REG(ha, mailbox[0], MBC_STOP_FIRMWARE);
3398 	WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT);
3399 	for (timer = 0; timer < 30000; timer++) {
3400 		stat = RD32_IO_REG(ha, intr_info_lo);
3401 		if (stat & BIT_15) {
3402 			if ((stat & 0xff) < 0x12) {
3403 				WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
3404 				break;
3405 			}
3406 			WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
3407 		}
3408 		drv_usecwait(100);
3409 	}
3410 
3411 	/* Reset the chip. */
3412 	WRT32_IO_REG(ha, ctrl_status, ISP_RESET | DMA_SHUTDOWN |
3413 	    MWB_4096_BYTES);
3414 	drv_usecwait(100);
3415 
3416 	/* Wait for idle status from ROM firmware. */
3417 	for (timer = 0; timer < 30000; timer++) {
3418 		if (RD16_IO_REG(ha, mailbox[0]) == 0) {
3419 			break;
3420 		}
3421 		drv_usecwait(100);
3422 	}
3423 
3424 	/* Wait for reset to finish. */
3425 	for (timer = 0; timer < 30000; timer++) {
3426 		if ((RD32_IO_REG(ha, ctrl_status) & ISP_RESET) == 0) {
3427 			break;
3428 		}
3429 		drv_usecwait(100);
3430 	}
3431 
3432 	/* Insure mailbox registers are free. */
3433 	ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
3434 	    ~(MBX_BUSY_FLG | MBX_WANT_FLG | MBX_ABORT | MBX_INTERRUPT));
3435 	ha->mcp = NULL;
3436 
3437 	if (ha->fwfcetracebuf.bp != NULL) {
3438 		ql_free_phys(ha, &ha->fwfcetracebuf);
3439 	}
3440 
3441 	if (ha->fwexttracebuf.bp != NULL) {
3442 		ql_free_phys(ha, &ha->fwexttracebuf);
3443 	}
3444 
3445 	/*
3446 	 * Set flash write-protection.
3447 	 */
3448 	if ((ha->flags & ONLINE) == 0) {
3449 		ql_24xx_protect_flash(ha);
3450 	}
3451 }
3452 
3453 /*
3454  * ql_abort_isp
3455  *	Resets ISP and aborts all outstanding commands.
3456  *
3457  * Input:
3458  *	ha = adapter state pointer.
3459  *	DEVICE_QUEUE_LOCK must be released.
3460  *
3461  * Returns:
3462  *	ql local function return status code.
3463  *
3464  * Context:
3465  *	Kernel context.
3466  */
3467 int
3468 ql_abort_isp(ql_adapter_state_t *vha)
3469 {
3470 	ql_link_t		*link, *link2;
3471 	ddi_devstate_t		state;
3472 	uint16_t		index;
3473 	ql_tgt_t		*tq;
3474 	ql_lun_t		*lq;
3475 	ql_srb_t		*sp;
3476 	int			rval = QL_SUCCESS;
3477 	ql_adapter_state_t	*ha = vha->pha;
3478 
3479 	QL_PRINT_2(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
3480 
3481 	TASK_DAEMON_LOCK(ha);
3482 	ha->task_daemon_flags &= ~ISP_ABORT_NEEDED;
3483 	if (ha->task_daemon_flags & ABORT_ISP_ACTIVE ||
3484 	    (ha->flags & ONLINE) == 0 || ha->flags & ADAPTER_SUSPENDED) {
3485 		TASK_DAEMON_UNLOCK(ha);
3486 		return (rval);
3487 	}
3488 
3489 	ha->task_daemon_flags |= ABORT_ISP_ACTIVE;
3490 	ha->task_daemon_flags &= ~(RESET_MARKER_NEEDED | FIRMWARE_UP |
3491 	    FIRMWARE_LOADED);
3492 	for (vha = ha; vha != NULL; vha = vha->vp_next) {
3493 		vha->task_daemon_flags |= LOOP_DOWN;
3494 		vha->task_daemon_flags &= ~(COMMAND_WAIT_NEEDED |
3495 		    LOOP_RESYNC_NEEDED);
3496 	}
3497 
3498 	TASK_DAEMON_UNLOCK(ha);
3499 
3500 	if (ha->mailbox_flags & MBX_BUSY_FLG) {
3501 		/* Acquire mailbox register lock. */
3502 		MBX_REGISTER_LOCK(ha);
3503 
3504 		/* Wake up mailbox box routine. */
3505 		ha->mailbox_flags = (uint8_t)(ha->mailbox_flags | MBX_ABORT);
3506 		cv_broadcast(&ha->cv_mbx_intr);
3507 
3508 		/* Release mailbox register lock. */
3509 		MBX_REGISTER_UNLOCK(ha);
3510 
3511 		/* Wait for mailbox. */
3512 		for (index = 100; index &&
3513 		    ha->mailbox_flags & MBX_ABORT; index--) {
3514 			drv_usecwait(50000);
3515 		}
3516 	}
3517 
3518 	/* Wait for commands to end gracefully if not in panic. */
3519 	if (ha->flags & PARITY_ERROR) {
3520 		ADAPTER_STATE_LOCK(ha);
3521 		ha->flags &= ~PARITY_ERROR;
3522 		ADAPTER_STATE_UNLOCK(ha);
3523 	} else if (ddi_in_panic() == 0) {
3524 		ql_cmd_wait(ha);
3525 	}
3526 
3527 	/* Shutdown IP. */
3528 	if (ha->flags & IP_INITIALIZED) {
3529 		(void) ql_shutdown_ip(ha);
3530 	}
3531 
3532 	/* Reset the chip. */
3533 	ql_reset_chip(ha);
3534 
3535 	/* Place all commands in outstanding cmd list on device queue. */
3536 	for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
3537 		REQUEST_RING_LOCK(ha);
3538 		if ((link = ha->pending_cmds.first) != NULL) {
3539 			sp = link->base_address;
3540 			ql_remove_link(&ha->pending_cmds, &sp->cmd);
3541 
3542 			REQUEST_RING_UNLOCK(ha);
3543 			index = 0;
3544 		} else {
3545 			REQUEST_RING_UNLOCK(ha);
3546 			if ((sp = ha->outstanding_cmds[index]) == NULL) {
3547 				continue;
3548 			}
3549 		}
3550 
3551 		/* If command timeout. */
3552 		if (sp->flags & SRB_COMMAND_TIMEOUT) {
3553 			sp->pkt->pkt_reason = CS_TIMEOUT;
3554 			sp->flags &= ~SRB_RETRY;
3555 			sp->flags |= SRB_ISP_COMPLETED;
3556 
3557 			/* Call done routine to handle completion. */
3558 			ql_done(&sp->cmd);
3559 			continue;
3560 		}
3561 
3562 		ha->outstanding_cmds[index] = NULL;
3563 		sp->handle = 0;
3564 		sp->flags &= ~SRB_IN_TOKEN_ARRAY;
3565 
3566 		/* Acquire target queue lock. */
3567 		lq = sp->lun_queue;
3568 		tq = lq->target_queue;
3569 		DEVICE_QUEUE_LOCK(tq);
3570 
3571 		/* Reset watchdog time. */
3572 		sp->wdg_q_time = sp->init_wdg_q_time;
3573 
3574 		/* Place request back on top of device queue. */
3575 		sp->flags &= ~(SRB_ISP_STARTED | SRB_ISP_COMPLETED |
3576 		    SRB_RETRY);
3577 
3578 		ql_add_link_t(&lq->cmd, &sp->cmd);
3579 		sp->flags |= SRB_IN_DEVICE_QUEUE;
3580 
3581 		/* Release target queue lock. */
3582 		DEVICE_QUEUE_UNLOCK(tq);
3583 	}
3584 
3585 	/*
3586 	 * Clear per LUN active count, because there should not be
3587 	 * any IO outstanding at this time.
3588 	 */
3589 	for (vha = ha; vha != NULL; vha = vha->vp_next) {
3590 		for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
3591 			link = vha->dev[index].first;
3592 			while (link != NULL) {
3593 				tq = link->base_address;
3594 				link = link->next;
3595 				DEVICE_QUEUE_LOCK(tq);
3596 				tq->outcnt = 0;
3597 				tq->flags &= ~TQF_QUEUE_SUSPENDED;
3598 				for (link2 = tq->lun_queues.first;
3599 				    link2 != NULL; link2 = link2->next) {
3600 					lq = link2->base_address;
3601 					lq->lun_outcnt = 0;
3602 					lq->flags &= ~LQF_UNTAGGED_PENDING;
3603 				}
3604 				DEVICE_QUEUE_UNLOCK(tq);
3605 			}
3606 		}
3607 	}
3608 
3609 	if (ha->flags & TARGET_MODE_INITIALIZED) {
3610 		/* Enable Target Mode */
3611 		ha->init_ctrl_blk.cb.lun_enables[0] = (uint8_t)
3612 		    (ha->init_ctrl_blk.cb.lun_enables[0] | 0x01);
3613 		ha->init_ctrl_blk.cb.immediate_notify_resouce_count =
3614 		    ha->ub_notify_count;
3615 		ha->init_ctrl_blk.cb.command_resouce_count =
3616 		    ha->ub_command_count;
3617 	} else {
3618 		ha->init_ctrl_blk.cb.lun_enables[0] = 0;
3619 		ha->init_ctrl_blk.cb.lun_enables[1] = 0;
3620 		ha->init_ctrl_blk.cb.immediate_notify_resouce_count = 0;
3621 		ha->init_ctrl_blk.cb.command_resouce_count = 0;
3622 	}
3623 
3624 	rval = ql_chip_diag(ha);
3625 	if (rval == QL_SUCCESS) {
3626 		(void) ql_load_isp_firmware(ha);
3627 	}
3628 
3629 	if (rval == QL_SUCCESS && (rval = ql_set_cache_line(ha)) ==
3630 	    QL_SUCCESS && (rval = ql_init_rings(ha)) == QL_SUCCESS &&
3631 	    (rval = ql_fw_ready(ha, 10)) == QL_SUCCESS) {
3632 
3633 		/* If reset abort needed that may have been set. */
3634 		TASK_DAEMON_LOCK(ha);
3635 		ha->task_daemon_flags &= ~(ISP_ABORT_NEEDED |
3636 		    ABORT_ISP_ACTIVE);
3637 		TASK_DAEMON_UNLOCK(ha);
3638 
3639 		/* Enable ISP interrupts. */
3640 		CFG_IST(ha, CFG_CTRL_2425) ?
3641 		    WRT32_IO_REG(ha, ictrl, ISP_EN_RISC) :
3642 		    WRT16_IO_REG(ha, ictrl, ISP_EN_INT + ISP_EN_RISC);
3643 
3644 		ADAPTER_STATE_LOCK(ha);
3645 		ha->flags |= INTERRUPTS_ENABLED;
3646 		ADAPTER_STATE_UNLOCK(ha);
3647 
3648 		/* Set loop online, if it really is. */
3649 		ql_loop_online(ha);
3650 
3651 		state = ddi_get_devstate(ha->dip);
3652 		if (state != DDI_DEVSTATE_UP) {
3653 			/*EMPTY*/
3654 			ddi_dev_report_fault(ha->dip, DDI_SERVICE_RESTORED,
3655 			    DDI_DEVICE_FAULT, "Device reset succeeded");
3656 		}
3657 	} else {
3658 		/* Enable ISP interrupts. */
3659 		CFG_IST(ha, CFG_CTRL_2425) ?
3660 		    WRT32_IO_REG(ha, ictrl, ISP_EN_RISC) :
3661 		    WRT16_IO_REG(ha, ictrl, ISP_EN_INT + ISP_EN_RISC);
3662 
3663 		ADAPTER_STATE_LOCK(ha);
3664 		ha->flags |= INTERRUPTS_ENABLED;
3665 		ADAPTER_STATE_UNLOCK(ha);
3666 
3667 		TASK_DAEMON_LOCK(ha);
3668 		ha->task_daemon_flags &= ~(ISP_ABORT_NEEDED | ABORT_ISP_ACTIVE);
3669 		ha->task_daemon_flags |= LOOP_DOWN;
3670 		TASK_DAEMON_UNLOCK(ha);
3671 
3672 		ql_port_state(ha, FC_STATE_OFFLINE, FC_STATE_CHANGE);
3673 	}
3674 
3675 	if (rval != QL_SUCCESS) {
3676 		EL(ha, "failed, rval = %xh\n", rval);
3677 	} else {
3678 		/*EMPTY*/
3679 		QL_PRINT_2(CE_CONT, "(%d): done\n", ha->instance);
3680 	}
3681 	return (rval);
3682 }
3683 
3684 /*
3685  * ql_vport_control
3686  *	Issue Virtual Port Control command.
3687  *
3688  * Input:
3689  *	ha = virtual adapter state pointer.
3690  *	cmd = control command.
3691  *
3692  * Returns:
3693  *	ql local function return status code.
3694  *
3695  * Context:
3696  *	Kernel context.
3697  */
3698 int
3699 ql_vport_control(ql_adapter_state_t *ha, uint8_t cmd)
3700 {
3701 	ql_mbx_iocb_t	*pkt;
3702 	uint8_t		bit;
3703 	int		rval;
3704 	uint32_t	pkt_size;
3705 
3706 	QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
3707 
3708 	if (ha->vp_index != 0) {
3709 		pkt_size = sizeof (ql_mbx_iocb_t);
3710 		pkt = kmem_zalloc(pkt_size, KM_SLEEP);
3711 		if (pkt == NULL) {
3712 			EL(ha, "failed, kmem_zalloc\n");
3713 			return (QL_MEMORY_ALLOC_FAILED);
3714 		}
3715 
3716 		pkt->vpc.entry_type = VP_CONTROL_TYPE;
3717 		pkt->vpc.entry_count = 1;
3718 		pkt->vpc.command = cmd;
3719 		pkt->vpc.vp_count = 1;
3720 		bit = (uint8_t)(ha->vp_index - 1);
3721 		pkt->vpc.vp_index[bit / 8] = (uint8_t)
3722 		    (pkt->vpc.vp_index[bit / 8] | BIT_0 << bit % 8);
3723 
3724 		rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
3725 		if (rval == QL_SUCCESS && pkt->vpc.status != 0) {
3726 			rval = QL_COMMAND_ERROR;
3727 		}
3728 
3729 		kmem_free(pkt, pkt_size);
3730 	} else {
3731 		rval = QL_SUCCESS;
3732 	}
3733 
3734 	if (rval != QL_SUCCESS) {
3735 		EL(ha, "failed, rval = %xh\n", rval);
3736 	} else {
3737 		/*EMPTY*/
3738 		QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance,
3739 		    ha->vp_index);
3740 	}
3741 	return (rval);
3742 }
3743 
3744 /*
3745  * ql_vport_modify
3746  *	Issue of Modify Virtual Port command.
3747  *
3748  * Input:
3749  *	ha = virtual adapter state pointer.
3750  *	cmd = command.
3751  *	opt = option.
3752  *
3753  * Context:
3754  *	Interrupt or Kernel context, no mailbox commands allowed.
3755  */
3756 int
3757 ql_vport_modify(ql_adapter_state_t *ha, uint8_t cmd, uint8_t opt)
3758 {
3759 	ql_mbx_iocb_t	*pkt;
3760 	int		rval;
3761 	uint32_t	pkt_size;
3762 
3763 	QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
3764 
3765 	pkt_size = sizeof (ql_mbx_iocb_t);
3766 	pkt = kmem_zalloc(pkt_size, KM_SLEEP);
3767 	if (pkt == NULL) {
3768 		EL(ha, "failed, kmem_zalloc\n");
3769 		return (QL_MEMORY_ALLOC_FAILED);
3770 	}
3771 
3772 	pkt->vpm.entry_type = VP_MODIFY_TYPE;
3773 	pkt->vpm.entry_count = 1;
3774 	pkt->vpm.command = cmd;
3775 	pkt->vpm.vp_count = 1;
3776 	pkt->vpm.first_vp_index = ha->vp_index;
3777 	pkt->vpm.first_options = opt;
3778 	bcopy(ha->loginparams.nport_ww_name.raw_wwn, pkt->vpm.first_port_name,
3779 	    8);
3780 	bcopy(ha->loginparams.node_ww_name.raw_wwn, pkt->vpm.first_node_name,
3781 	    8);
3782 
3783 	rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
3784 	if (rval == QL_SUCCESS && pkt->vpm.status != 0) {
3785 		EL(ha, "failed, ql_issue_mbx_iocb=%xh, status=%xh\n", rval,
3786 		    pkt->vpm.status);
3787 		rval = QL_COMMAND_ERROR;
3788 	}
3789 
3790 	kmem_free(pkt, pkt_size);
3791 
3792 	if (rval != QL_SUCCESS) {
3793 		EL(ha, "failed, rval = %xh\n", rval);
3794 	} else {
3795 		/*EMPTY*/
3796 		QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance,
3797 		    ha->vp_index);
3798 	}
3799 	return (rval);
3800 }
3801 
3802 /*
3803  * ql_vport_enable
3804  *	Enable virtual port.
3805  *
3806  * Input:
3807  *	ha = virtual adapter state pointer.
3808  *
3809  * Context:
3810  *	Kernel context.
3811  */
3812 int
3813 ql_vport_enable(ql_adapter_state_t *ha)
3814 {
3815 	int	timer;
3816 
3817 	QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
3818 
3819 	ha->state = FC_PORT_SPEED_MASK(ha->state) | FC_STATE_OFFLINE;
3820 	TASK_DAEMON_LOCK(ha);
3821 	ha->task_daemon_flags |= LOOP_DOWN;
3822 	ha->task_daemon_flags &= ~(FC_STATE_CHANGE | STATE_ONLINE);
3823 	TASK_DAEMON_UNLOCK(ha);
3824 
3825 	ADAPTER_STATE_LOCK(ha);
3826 	ha->flags |= VP_ENABLED;
3827 	ADAPTER_STATE_UNLOCK(ha);
3828 
3829 	if (ql_vport_modify(ha, VPM_MODIFY_ENABLE, VPO_TARGET_MODE_DISABLED |
3830 	    VPO_INITIATOR_MODE_ENABLED | VPO_ENABLED) != QL_SUCCESS) {
3831 		QL_PRINT_2(CE_CONT, "(%d): failed to enable virtual port=%d\n",
3832 		    ha->instance, ha->vp_index);
3833 		return (QL_FUNCTION_FAILED);
3834 	}
3835 	if (!(ha->pha->task_daemon_flags & LOOP_DOWN)) {
3836 		/* Wait for loop to come up. */
3837 		for (timer = 0; timer < 3000 &&
3838 		    !(ha->task_daemon_flags & STATE_ONLINE);
3839 		    timer++) {
3840 			delay(1);
3841 		}
3842 	}
3843 
3844 	QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
3845 
3846 	return (QL_SUCCESS);
3847 }
3848 
3849 /*
3850  * ql_vport_create
3851  *	Create virtual port context.
3852  *
3853  * Input:
3854  *	ha:	parent adapter state pointer.
3855  *	index:	virtual port index number.
3856  *
3857  * Context:
3858  *	Kernel context.
3859  */
3860 ql_adapter_state_t *
3861 ql_vport_create(ql_adapter_state_t *ha, uint8_t index)
3862 {
3863 	ql_adapter_state_t	*vha;
3864 
3865 	QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
3866 
3867 	/* Inherit the parents data. */
3868 	vha = kmem_alloc(sizeof (ql_adapter_state_t), KM_SLEEP);
3869 
3870 	ADAPTER_STATE_LOCK(ha);
3871 	bcopy(ha, vha, sizeof (ql_adapter_state_t));
3872 	vha->pi_attrs = NULL;
3873 	vha->ub_outcnt = 0;
3874 	vha->ub_allocated = 0;
3875 	vha->flags = 0;
3876 	vha->task_daemon_flags = 0;
3877 	ha->vp_next = vha;
3878 	vha->pha = ha;
3879 	vha->vp_index = index;
3880 	ADAPTER_STATE_UNLOCK(ha);
3881 
3882 	vha->hba.next = NULL;
3883 	vha->hba.prev = NULL;
3884 	vha->hba.base_address = vha;
3885 	vha->state = FC_PORT_SPEED_MASK(ha->state) | FC_STATE_OFFLINE;
3886 	vha->dev = kmem_zalloc(sizeof (*vha->dev) * DEVICE_HEAD_LIST_SIZE,
3887 	    KM_SLEEP);
3888 	vha->ub_array = kmem_zalloc(sizeof (*vha->ub_array) * QL_UB_LIMIT,
3889 	    KM_SLEEP);
3890 
3891 	QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
3892 
3893 	return (vha);
3894 }
3895 
3896 /*
3897  * ql_vport_destroy
3898  *	Destroys virtual port context.
3899  *
3900  * Input:
3901  *	ha = virtual adapter state pointer.
3902  *
3903  * Context:
3904  *	Kernel context.
3905  */
3906 void
3907 ql_vport_destroy(ql_adapter_state_t *ha)
3908 {
3909 	ql_adapter_state_t	*vha;
3910 
3911 	QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
3912 
3913 	/* Remove port from list. */
3914 	ADAPTER_STATE_LOCK(ha);
3915 	for (vha = ha->pha; vha != NULL; vha = vha->vp_next) {
3916 		if (vha->vp_next == ha) {
3917 			vha->vp_next = ha->vp_next;
3918 			break;
3919 		}
3920 	}
3921 	ADAPTER_STATE_UNLOCK(ha);
3922 
3923 	if (ha->ub_array != NULL) {
3924 		kmem_free(ha->ub_array, sizeof (*ha->ub_array) * QL_UB_LIMIT);
3925 	}
3926 	if (ha->dev != NULL) {
3927 		kmem_free(ha->dev, sizeof (*vha->dev) * DEVICE_HEAD_LIST_SIZE);
3928 	}
3929 	kmem_free(ha, sizeof (ql_adapter_state_t));
3930 
3931 	QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
3932 }
3933