xref: /illumos-gate/usr/src/uts/common/io/fibre-channel/fca/qlc/ql_init.c (revision d288ba7491829a622697c947c3f1a30aec18c133)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /* Copyright 2009 QLogic Corporation */
23 
24 /*
25  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
26  * Use is subject to license terms.
27  */
28 
29 #pragma ident	"Copyright 2009 QLogic Corporation; ql_init.c"
30 
31 /*
32  * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
33  *
34  * ***********************************************************************
35  * *									**
36  * *				NOTICE					**
37  * *		COPYRIGHT (C) 1996-2009 QLOGIC CORPORATION		**
38  * *			ALL RIGHTS RESERVED				**
39  * *									**
40  * ***********************************************************************
41  *
42  */
43 
44 #include <ql_apps.h>
45 #include <ql_api.h>
46 #include <ql_debug.h>
47 #include <ql_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 |= ABORT_CMDS_LOOP_DOWN_TMO;
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) || (ha->device_id == 0x8432)) {
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 (rval = 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, rval=%x", QL_NAME, ha->instance, rval);
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",
1415 		    data, nv->hard_address[0]);
1416 	}
1417 
1418 	/* Get LIP reset. */
1419 	if ((data = ql_get_prop(ha, "enable-LIP-reset-on-bus-reset")) ==
1420 	    0xffffffff) {
1421 		data = 0;
1422 	}
1423 	if (data == 0) {
1424 		nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_1);
1425 	} else if (data == 1) {
1426 		nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_1);
1427 	} else {
1428 		EL(ha, "invalid parameter value for "
1429 		    "'enable-LIP-reset-on-bus-reset': %d; using nvram value "
1430 		    "of %d\n", data, nv->host_p[1] & BIT_1 ? 1 : 0);
1431 	}
1432 
1433 	/* Get LIP full login. */
1434 	if ((data = ql_get_prop(ha, "enable-LIP-full-login-on-bus-reset")) ==
1435 	    0xffffffff) {
1436 		data = 1;
1437 	}
1438 	if (data == 0) {
1439 		nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_2);
1440 	} else if (data == 1) {
1441 		nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_2);
1442 	} else {
1443 		EL(ha, "invalid parameter value for "
1444 		    "'enable-LIP-full-login-on-bus-reset': %d; using nvram "
1445 		    "value of %d\n", data, nv->host_p[1] & BIT_2 ? 1 : 0);
1446 	}
1447 
1448 	/* Get target reset. */
1449 	if ((data = ql_get_prop(ha, "enable-target-reset-on-bus-reset")) ==
1450 	    0xffffffff) {
1451 		data = 0;
1452 	}
1453 	if (data == 0) {
1454 		nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_3);
1455 	} else if (data == 1) {
1456 		nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_3);
1457 	} else {
1458 		EL(ha, "invalid parameter value for "
1459 		    "'enable-target-reset-on-bus-reset': %d; using nvram "
1460 		    "value of %d", data, nv->host_p[1] & BIT_3 ? 1 : 0);
1461 	}
1462 
1463 	/* Get reset delay. */
1464 	if ((data = ql_get_prop(ha, "reset-delay")) == 0xffffffff) {
1465 		data = 5;
1466 	}
1467 	if (data != 0 && data < 256) {
1468 		nv->reset_delay = (uint8_t)data;
1469 	} else {
1470 		EL(ha, "invalid parameter value for 'reset-delay': %d; "
1471 		    "using nvram value of %d", data, nv->reset_delay);
1472 	}
1473 
1474 	/* Get port down retry count. */
1475 	if ((data = ql_get_prop(ha, "port-down-retry-count")) == 0xffffffff) {
1476 		data = 8;
1477 	}
1478 	if (data < 256) {
1479 		nv->port_down_retry_count = (uint8_t)data;
1480 	} else {
1481 		EL(ha, "invalid parameter value for 'port-down-retry-count':"
1482 		    " %d; using nvram value of %d\n", data,
1483 		    nv->port_down_retry_count);
1484 	}
1485 
1486 	/* Get connection mode setting. */
1487 	if ((data = ql_get_prop(ha, "connection-options")) == 0xffffffff) {
1488 		data = 2;
1489 	}
1490 	cnt = CFG_IST(ha, CFG_CTRL_2200) ? 3 : 2;
1491 	if (data <= cnt) {
1492 		nv->add_fw_opt[0] = (uint8_t)(nv->add_fw_opt[0] &
1493 		    ~(BIT_6 | BIT_5 | BIT_4));
1494 		nv->add_fw_opt[0] = (uint8_t)(nv->add_fw_opt[0] |
1495 		    (uint8_t)(data << 4));
1496 	} else {
1497 		EL(ha, "invalid parameter value for 'connection-options': "
1498 		    "%d; using nvram value of %d\n", data,
1499 		    (nv->add_fw_opt[0] >> 4) & 0x3);
1500 	}
1501 
1502 	/* Get data rate setting. */
1503 	if ((CFG_IST(ha, CFG_CTRL_2200)) == 0) {
1504 		if ((data = ql_get_prop(ha, "fc-data-rate")) == 0xffffffff) {
1505 			data = 2;
1506 		}
1507 		if (data < 3) {
1508 			nv->special_options[1] = (uint8_t)
1509 			    (nv->special_options[1] & 0x3f);
1510 			nv->special_options[1] = (uint8_t)
1511 			    (nv->special_options[1] | (uint8_t)(data << 6));
1512 		} else {
1513 			EL(ha, "invalid parameter value for 'fc-data-rate': "
1514 			    "%d; using nvram value of %d\n", data,
1515 			    (nv->special_options[1] >> 6) & 0x3);
1516 		}
1517 	}
1518 
1519 	/* Get adapter id string for Sun branded 23xx only */
1520 	if ((CFG_IST(ha, CFG_CTRL_2300)) && nv->adapInfo[0] != 0) {
1521 		(void) snprintf((int8_t *)ha->adapInfo, 16, "%s",
1522 		    nv->adapInfo);
1523 	}
1524 
1525 	/* Get IP FW container count. */
1526 	ha->ip_init_ctrl_blk.cb.cc[0] = LSB(ql_ip_buffer_count);
1527 	ha->ip_init_ctrl_blk.cb.cc[1] = MSB(ql_ip_buffer_count);
1528 
1529 	/* Get IP low water mark. */
1530 	ha->ip_init_ctrl_blk.cb.low_water_mark[0] = LSB(ql_ip_low_water);
1531 	ha->ip_init_ctrl_blk.cb.low_water_mark[1] = MSB(ql_ip_low_water);
1532 
1533 	/* Get IP fast register post count. */
1534 	ha->ip_init_ctrl_blk.cb.fast_post_reg_count[0] =
1535 	    ql_ip_fast_post_count;
1536 
1537 	ADAPTER_STATE_LOCK(ha);
1538 
1539 	ql_common_properties(ha);
1540 
1541 	ADAPTER_STATE_UNLOCK(ha);
1542 
1543 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1544 }
1545 
1546 /*
1547  * ql_common_properties
1548  *	Driver properties adapter structure.
1549  *
1550  *	Driver properties are by design global variables and hidden
1551  *	completely from administrators. Knowledgeable folks can
1552  *	override the default values using driver.conf
1553  *
1554  * Input:
1555  *	ha:	adapter state pointer.
1556  *
1557  * Context:
1558  *	Kernel context.
1559  */
1560 void
1561 ql_common_properties(ql_adapter_state_t *ha)
1562 {
1563 	uint32_t	data;
1564 
1565 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1566 
1567 	/* Get extended logging trace buffer size. */
1568 	if ((data = ql_get_prop(ha, "set-ext-log-buffer-size")) !=
1569 	    0xffffffff && data != 0) {
1570 		char		*new_trace;
1571 		uint32_t	new_size;
1572 
1573 		if (ha->el_trace_desc->trace_buffer != NULL) {
1574 			new_size = 1024 * data;
1575 			new_trace = (char *)kmem_zalloc(new_size, KM_SLEEP);
1576 
1577 			if (new_trace == NULL) {
1578 				cmn_err(CE_WARN, "%s(%d): can't get new"
1579 				    " trace buffer",
1580 				    QL_NAME, ha->instance);
1581 			} else {
1582 				/* free the previous */
1583 				kmem_free(ha->el_trace_desc->trace_buffer,
1584 				    ha->el_trace_desc->trace_buffer_size);
1585 				/* Use the new one */
1586 				ha->el_trace_desc->trace_buffer = new_trace;
1587 				ha->el_trace_desc->trace_buffer_size = new_size;
1588 			}
1589 		}
1590 
1591 	}
1592 
1593 	/* Get extended logging enable. */
1594 	if ((data = ql_get_prop(ha, "extended-logging")) == 0xffffffff ||
1595 	    data == 0) {
1596 		ha->cfg_flags &= ~CFG_ENABLE_EXTENDED_LOGGING;
1597 	} else if (data == 1) {
1598 		ha->cfg_flags |= CFG_ENABLE_EXTENDED_LOGGING;
1599 	} else {
1600 		EL(ha, "invalid parameter value for 'extended-logging': %d;"
1601 		    " using default value of 0\n", data);
1602 		ha->cfg_flags &= ~CFG_ENABLE_EXTENDED_LOGGING;
1603 	}
1604 
1605 	/* Get extended logging trace disable. */
1606 	if ((data = ql_get_prop(ha, "disable-extended-logging-trace")) ==
1607 	    0xffffffff || data == 0) {
1608 		ha->cfg_flags &= ~CFG_DISABLE_EXTENDED_LOGGING_TRACE;
1609 	} else if (data == 1) {
1610 		ha->cfg_flags |= CFG_DISABLE_EXTENDED_LOGGING_TRACE;
1611 	} else {
1612 		EL(ha, "invalid parameter value for "
1613 		    "'disable-extended-logging-trace': %d;"
1614 		    " using default value of 0\n", data);
1615 		ha->cfg_flags &= ~CFG_DISABLE_EXTENDED_LOGGING_TRACE;
1616 	}
1617 
1618 	/* Get FCP 2 Error Recovery. */
1619 	if ((data = ql_get_prop(ha, "enable-FCP-2-error-recovery")) ==
1620 	    0xffffffff || data == 1) {
1621 		ha->cfg_flags |= CFG_ENABLE_FCP_2_SUPPORT;
1622 	} else if (data == 0) {
1623 		ha->cfg_flags &= ~CFG_ENABLE_FCP_2_SUPPORT;
1624 	} else {
1625 		EL(ha, "invalid parameter value for "
1626 		    "'enable-FCP-2-error-recovery': %d; using nvram value of "
1627 		    "1\n", data);
1628 		ha->cfg_flags |= CFG_ENABLE_FCP_2_SUPPORT;
1629 	}
1630 
1631 	/* Get target mode enable. */
1632 	ha->cfg_flags &= ~CFG_TARGET_MODE_ENABLE;
1633 
1634 
1635 #ifdef QL_DEBUG_LEVEL_2
1636 	ha->cfg_flags |= CFG_ENABLE_EXTENDED_LOGGING;
1637 #endif
1638 
1639 	/* Get port down retry delay. */
1640 	if ((data = ql_get_prop(ha, "port-down-retry-delay")) == 0xffffffff) {
1641 		ha->port_down_retry_delay = PORT_RETRY_TIME;
1642 	} else if (data < 256) {
1643 		ha->port_down_retry_delay = (uint8_t)data;
1644 	} else {
1645 		EL(ha, "invalid parameter value for 'port-down-retry-delay':"
1646 		    " %d; using default value of %d", data, PORT_RETRY_TIME);
1647 		ha->port_down_retry_delay = PORT_RETRY_TIME;
1648 	}
1649 
1650 	/* Get queue full retry count. */
1651 	if ((data = ql_get_prop(ha, "queue-full-retry-count")) == 0xffffffff) {
1652 		ha->qfull_retry_count = 16;
1653 	} else if (data < 256) {
1654 		ha->qfull_retry_count = (uint8_t)data;
1655 	} else {
1656 		EL(ha, "invalid parameter value for 'queue-full-retry-count':"
1657 		    " %d; using default value of 16", data);
1658 		ha->qfull_retry_count = 16;
1659 	}
1660 
1661 	/* Get queue full retry delay. */
1662 	if ((data = ql_get_prop(ha, "queue-full-retry-delay")) == 0xffffffff) {
1663 		ha->qfull_retry_delay = PORT_RETRY_TIME;
1664 	} else if (data < 256) {
1665 		ha->qfull_retry_delay = (uint8_t)data;
1666 	} else {
1667 		EL(ha, "invalid parameter value for 'queue-full-retry-delay':"
1668 		    " %d; using default value of %d", data, PORT_RETRY_TIME);
1669 		ha->qfull_retry_delay = PORT_RETRY_TIME;
1670 	}
1671 
1672 	/* Get loop down timeout. */
1673 	if ((data = ql_get_prop(ha, "link-down-timeout")) == 0xffffffff) {
1674 		data = 0;
1675 	} else if (data > 255) {
1676 		EL(ha, "invalid parameter value for 'link-down-timeout': %d;"
1677 		    " using nvram value of 0\n", data);
1678 		data = 0;
1679 	}
1680 	ha->loop_down_abort_time = (uint8_t)(LOOP_DOWN_TIMER_START - data);
1681 	if (ha->loop_down_abort_time == LOOP_DOWN_TIMER_START) {
1682 		ha->loop_down_abort_time--;
1683 	} else if (ha->loop_down_abort_time <= LOOP_DOWN_TIMER_END) {
1684 		ha->loop_down_abort_time = LOOP_DOWN_TIMER_END + 1;
1685 	}
1686 
1687 	/* Get link down error enable. */
1688 	if ((data = ql_get_prop(ha, "enable-link-down-error")) == 0xffffffff ||
1689 	    data == 1) {
1690 		ha->cfg_flags |= CFG_ENABLE_LINK_DOWN_REPORTING;
1691 	} else if (data == 0) {
1692 		ha->cfg_flags &= ~CFG_ENABLE_LINK_DOWN_REPORTING;
1693 	} else {
1694 		EL(ha, "invalid parameter value for 'link-down-error': %d;"
1695 		    " using default value of 1\n", data);
1696 	}
1697 
1698 	/*
1699 	 * Get firmware dump flags.
1700 	 *	TAKE_FW_DUMP_ON_MAILBOX_TIMEOUT		BIT_0
1701 	 *	TAKE_FW_DUMP_ON_ISP_SYSTEM_ERROR	BIT_1
1702 	 *	TAKE_FW_DUMP_ON_DRIVER_COMMAND_TIMEOUT	BIT_2
1703 	 *	TAKE_FW_DUMP_ON_LOOP_OFFLINE_TIMEOUT	BIT_3
1704 	 */
1705 	ha->cfg_flags &= ~(CFG_DUMP_MAILBOX_TIMEOUT |
1706 	    CFG_DUMP_ISP_SYSTEM_ERROR | CFG_DUMP_DRIVER_COMMAND_TIMEOUT |
1707 	    CFG_DUMP_LOOP_OFFLINE_TIMEOUT);
1708 	if ((data = ql_get_prop(ha, "firmware-dump-flags")) != 0xffffffff) {
1709 		if (data & BIT_0) {
1710 			ha->cfg_flags |= CFG_DUMP_MAILBOX_TIMEOUT;
1711 		}
1712 		if (data & BIT_1) {
1713 			ha->cfg_flags |= CFG_DUMP_ISP_SYSTEM_ERROR;
1714 		}
1715 		if (data & BIT_2) {
1716 			ha->cfg_flags |= CFG_DUMP_DRIVER_COMMAND_TIMEOUT;
1717 		}
1718 		if (data & BIT_3) {
1719 			ha->cfg_flags |= CFG_DUMP_LOOP_OFFLINE_TIMEOUT;
1720 		}
1721 	}
1722 
1723 	/* Get the PCI max read request size override. */
1724 	ha->pci_max_read_req = 0;
1725 	if ((data = ql_get_prop(ha, "pci-max-read-request")) != 0xffffffff &&
1726 	    data != 0) {
1727 		ha->pci_max_read_req = (uint16_t)(data);
1728 	}
1729 
1730 	/* Get the attach fw_ready override value. */
1731 	ha->fwwait = 10;
1732 	if ((data = ql_get_prop(ha, "init-loop-sync-wait")) != 0xffffffff) {
1733 		if (data > 0 && data <= 240) {
1734 			ha->fwwait = (uint8_t)data;
1735 		} else {
1736 			EL(ha, "invalid parameter value for "
1737 			    "'init-loop-sync-wait': %d; using default "
1738 			    "value of %d\n", data, ha->fwwait);
1739 		}
1740 	}
1741 
1742 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1743 }
1744 
1745 /*
1746  * ql_24xx_properties
1747  *	Copies driver properties to NVRAM or adapter structure.
1748  *
1749  *	Driver properties are by design global variables and hidden
1750  *	completely from administrators. Knowledgeable folks can
1751  *	override the default values using /etc/system.
1752  *
1753  * Input:
1754  *	ha:	adapter state pointer.
1755  *	nv:	NVRAM structure pointer.
1756  *
1757  * Context:
1758  *	Kernel context.
1759  */
1760 static void
1761 ql_24xx_properties(ql_adapter_state_t *ha, nvram_24xx_t *nv)
1762 {
1763 	uint32_t	data;
1764 
1765 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1766 
1767 	/* Get frame size */
1768 	if ((data = ql_get_prop(ha, "max-frame-length")) == 0xffffffff) {
1769 		data = 2048;
1770 	}
1771 	if (data == 512 || data == 1024 || data == 2048) {
1772 		nv->max_frame_length[0] = LSB(data);
1773 		nv->max_frame_length[1] = MSB(data);
1774 	} else {
1775 		EL(ha, "invalid parameter value for 'max-frame-length': %d;"
1776 		    " using nvram default of %d\n", data, CHAR_TO_SHORT(
1777 		    nv->max_frame_length[0], nv->max_frame_length[1]));
1778 	}
1779 
1780 	/* Get execution throttle. */
1781 	if ((data = ql_get_prop(ha, "execution-throttle")) == 0xffffffff) {
1782 		data = 32;
1783 	}
1784 	if (data != 0 && data < 65536) {
1785 		nv->execution_throttle[0] = LSB(data);
1786 		nv->execution_throttle[1] = MSB(data);
1787 	} else {
1788 		EL(ha, "invalid parameter value for 'execution-throttle':"
1789 		    " %d; using nvram default of %d\n", data, CHAR_TO_SHORT(
1790 		    nv->execution_throttle[0], nv->execution_throttle[1]));
1791 	}
1792 
1793 	/* Get Login timeout. */
1794 	if ((data = ql_get_prop(ha, "login-timeout")) == 0xffffffff) {
1795 		data = 3;
1796 	}
1797 	if (data < 65536) {
1798 		nv->login_timeout[0] = LSB(data);
1799 		nv->login_timeout[1] = MSB(data);
1800 	} else {
1801 		EL(ha, "invalid parameter value for 'login-timeout': %d; "
1802 		    "using nvram value of %d\n", data, CHAR_TO_SHORT(
1803 		    nv->login_timeout[0], nv->login_timeout[1]));
1804 	}
1805 
1806 	/* Get retry count. */
1807 	if ((data = ql_get_prop(ha, "login-retry-count")) == 0xffffffff) {
1808 		data = 4;
1809 	}
1810 	if (data < 65536) {
1811 		nv->login_retry_count[0] = LSB(data);
1812 		nv->login_retry_count[1] = MSB(data);
1813 	} else {
1814 		EL(ha, "invalid parameter value for 'login-retry-count': "
1815 		    "%d; using nvram value of %d\n", data, CHAR_TO_SHORT(
1816 		    nv->login_retry_count[0], nv->login_retry_count[1]));
1817 	}
1818 
1819 	/* Get adapter hard loop ID enable. */
1820 	data =  ql_get_prop(ha, "enable-adapter-hard-loop-ID");
1821 	if (data == 0) {
1822 		nv->firmware_options_1[0] =
1823 		    (uint8_t)(nv->firmware_options_1[0] & ~BIT_0);
1824 	} else if (data == 1) {
1825 		nv->firmware_options_1[0] =
1826 		    (uint8_t)(nv->firmware_options_1[0] | BIT_0);
1827 	} else if (data != 0xffffffff) {
1828 		EL(ha, "invalid parameter value for "
1829 		    "'enable-adapter-hard-loop-ID': %d; using nvram value "
1830 		    "of %d\n", data,
1831 		    nv->firmware_options_1[0] & BIT_0 ? 1 : 0);
1832 	}
1833 
1834 	/* Get adapter hard loop ID. */
1835 	data =  ql_get_prop(ha, "adapter-hard-loop-ID");
1836 	if (data < 126) {
1837 		nv->hard_address[0] = LSB(data);
1838 		nv->hard_address[1] = MSB(data);
1839 	} else if (data != 0xffffffff) {
1840 		EL(ha, "invalid parameter value for 'adapter-hard-loop-ID':"
1841 		    " %d; using nvram value of %d\n", data, CHAR_TO_SHORT(
1842 		    nv->hard_address[0], nv->hard_address[1]));
1843 	}
1844 
1845 	/* Get LIP reset. */
1846 	if ((data = ql_get_prop(ha, "enable-LIP-reset-on-bus-reset")) ==
1847 	    0xffffffff) {
1848 		data = 0;
1849 	}
1850 	if (data == 0) {
1851 		ha->cfg_flags &= ~CFG_ENABLE_LIP_RESET;
1852 	} else if (data == 1) {
1853 		ha->cfg_flags |= CFG_ENABLE_LIP_RESET;
1854 	} else {
1855 		EL(ha, "invalid parameter value for "
1856 		    "'enable-LIP-reset-on-bus-reset': %d; using value of 0\n",
1857 		    data);
1858 	}
1859 
1860 	/* Get LIP full login. */
1861 	if ((data = ql_get_prop(ha, "enable-LIP-full-login-on-bus-reset")) ==
1862 	    0xffffffff) {
1863 		data = 1;
1864 	}
1865 	if (data == 0) {
1866 		nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_2);
1867 	} else if (data == 1) {
1868 		nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_2);
1869 	} else {
1870 		EL(ha, "invalid parameter value for "
1871 		    "'enable-LIP-full-login-on-bus-reset': %d; using nvram "
1872 		    "value of %d\n", data, nv->host_p[1] & BIT_2 ? 1 : 0);
1873 	}
1874 
1875 	/* Get target reset. */
1876 	if ((data = ql_get_prop(ha, "enable-target-reset-on-bus-reset")) ==
1877 	    0xffffffff) {
1878 		data = 0;
1879 	}
1880 	if (data == 0) {
1881 		nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_3);
1882 	} else if (data == 1) {
1883 		nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_3);
1884 	} else {
1885 		EL(ha, "invalid parameter value for "
1886 		    "'enable-target-reset-on-bus-reset': %d; using nvram "
1887 		    "value of %d", data, nv->host_p[1] & BIT_3 ? 1 : 0);
1888 	}
1889 
1890 	/* Get reset delay. */
1891 	if ((data = ql_get_prop(ha, "reset-delay")) == 0xffffffff) {
1892 		data = 5;
1893 	}
1894 	if (data != 0 && data < 256) {
1895 		nv->reset_delay = (uint8_t)data;
1896 	} else {
1897 		EL(ha, "invalid parameter value for 'reset-delay': %d; "
1898 		    "using nvram value of %d", data, nv->reset_delay);
1899 	}
1900 
1901 	/* Get port down retry count. */
1902 	if ((data = ql_get_prop(ha, "port-down-retry-count")) == 0xffffffff) {
1903 		data = 8;
1904 	}
1905 	if (data < 256) {
1906 		nv->port_down_retry_count[0] = LSB(data);
1907 		nv->port_down_retry_count[1] = MSB(data);
1908 	} else {
1909 		EL(ha, "invalid parameter value for 'port-down-retry-count':"
1910 		    " %d; using nvram value of %d\n", data, CHAR_TO_SHORT(
1911 		    nv->port_down_retry_count[0],
1912 		    nv->port_down_retry_count[1]));
1913 	}
1914 
1915 	/* Get connection mode setting. */
1916 	if ((data = ql_get_prop(ha, "connection-options")) == 0xffffffff) {
1917 		data = 2;
1918 	}
1919 	if (data <= 2) {
1920 		nv->firmware_options_2[0] = (uint8_t)
1921 		    (nv->firmware_options_2[0] & ~(BIT_6 | BIT_5 | BIT_4));
1922 		nv->firmware_options_2[0] = (uint8_t)
1923 		    (nv->firmware_options_2[0] | (uint8_t)(data << 4));
1924 	} else {
1925 		EL(ha, "invalid parameter value for 'connection-options':"
1926 		    " %d; using nvram value of %d\n", data,
1927 		    (nv->firmware_options_2[0] >> 4) & 0x3);
1928 	}
1929 
1930 	/* Get data rate setting. */
1931 	if ((data = ql_get_prop(ha, "fc-data-rate")) == 0xffffffff) {
1932 		data = 2;
1933 	}
1934 	if ((CFG_IST(ha, CFG_CTRL_2422) && data < 4) ||
1935 	    (CFG_IST(ha, CFG_CTRL_25XX) && data < 5)) {
1936 		nv->firmware_options_3[1] = (uint8_t)
1937 		    (nv->firmware_options_3[1] & 0x1f);
1938 		nv->firmware_options_3[1] = (uint8_t)
1939 		    (nv->firmware_options_3[1] | (uint8_t)(data << 5));
1940 	} else {
1941 		EL(ha, "invalid parameter value for 'fc-data-rate': %d; "
1942 		    "using nvram value of %d\n", data,
1943 		    (nv->firmware_options_3[1] >> 5) & 0x7);
1944 	}
1945 
1946 	/* Get IP FW container count. */
1947 	ha->ip_init_ctrl_blk.cb24.cc[0] = LSB(ql_ip_buffer_count);
1948 	ha->ip_init_ctrl_blk.cb24.cc[1] = MSB(ql_ip_buffer_count);
1949 
1950 	/* Get IP low water mark. */
1951 	ha->ip_init_ctrl_blk.cb24.low_water_mark[0] = LSB(ql_ip_low_water);
1952 	ha->ip_init_ctrl_blk.cb24.low_water_mark[1] = MSB(ql_ip_low_water);
1953 
1954 	ADAPTER_STATE_LOCK(ha);
1955 
1956 	/* Get enable flash load. */
1957 	if ((data = ql_get_prop(ha, "enable-flash-load")) == 0xffffffff ||
1958 	    data == 0) {
1959 		ha->cfg_flags &= ~CFG_LOAD_FLASH_FW;
1960 	} else if (data == 1) {
1961 		ha->cfg_flags |= CFG_LOAD_FLASH_FW;
1962 	} else {
1963 		EL(ha, "invalid parameter value for 'enable-flash-load': "
1964 		    "%d; using default value of 0\n", data);
1965 	}
1966 
1967 	/* Enable firmware extended tracing */
1968 	if ((data = ql_get_prop(ha, "enable-fwexttrace")) != 0xffffffff) {
1969 		if (data != 0) {
1970 			ha->cfg_flags |= CFG_ENABLE_FWEXTTRACE;
1971 		}
1972 	}
1973 
1974 	/* Enable firmware fc tracing */
1975 	if ((data = ql_get_prop(ha, "enable-fwfcetrace")) != 0xffffffff) {
1976 		ha->cfg_flags |= CFG_ENABLE_FWFCETRACE;
1977 		ha->fwfcetraceopt = data;
1978 	}
1979 
1980 	ql_common_properties(ha);
1981 
1982 	ADAPTER_STATE_UNLOCK(ha);
1983 
1984 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1985 }
1986 
1987 /*
1988  * ql_get_prop
1989  *	Get property value from configuration file.
1990  *
1991  * Input:
1992  *	ha= adapter state pointer.
1993  *	string = property string pointer.
1994  *
1995  * Returns:
1996  *	0xFFFFFFFF = no property else property value.
1997  *
1998  * Context:
1999  *	Kernel context.
2000  */
2001 uint32_t
2002 ql_get_prop(ql_adapter_state_t *ha, char *string)
2003 {
2004 	char		buf[256];
2005 	uint32_t	data = 0xffffffff;
2006 
2007 	/*
2008 	 * Look for a adapter instance NPIV (virtual port) specific parameter
2009 	 */
2010 	if (CFG_IST(ha, CFG_CTRL_2425)) {
2011 		(void) sprintf(buf, "hba%d-vp%d-%s", ha->instance,
2012 		    ha->vp_index, string);
2013 		/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
2014 		data = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, ha->dip, 0,
2015 		    buf, (int)0xffffffff);
2016 	}
2017 
2018 	/*
2019 	 * Get adapter instance parameter if a vp specific one isn't found.
2020 	 */
2021 	if (data == 0xffffffff) {
2022 		(void) sprintf(buf, "hba%d-%s", ha->instance, string);
2023 		/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
2024 		data = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, ha->dip,
2025 		    0, buf, (int)0xffffffff);
2026 	}
2027 
2028 	/* Adapter instance parameter found? */
2029 	if (data == 0xffffffff) {
2030 		/* No, get default parameter. */
2031 		/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
2032 		data = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, ha->dip, 0,
2033 		    string, (int)0xffffffff);
2034 	}
2035 
2036 	return (data);
2037 }
2038 
2039 /*
2040  * ql_check_isp_firmware
2041  *	Checks if using already loaded RISC code or drivers copy.
2042  *	If using already loaded code, save a copy of it.
2043  *
2044  * Input:
2045  *	ha = adapter state pointer.
2046  *
2047  * Returns:
2048  *	ql local function return status code.
2049  *
2050  * Context:
2051  *	Kernel context.
2052  */
2053 static int
2054 ql_check_isp_firmware(ql_adapter_state_t *ha)
2055 {
2056 	int		rval;
2057 	uint16_t	word_count;
2058 	uint32_t	byte_count;
2059 	uint32_t	fw_size, *lptr;
2060 	caddr_t		bufp;
2061 	uint16_t	risc_address = (uint16_t)ha->risc_fw[0].addr;
2062 
2063 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2064 
2065 	if (CFG_IST(ha, CFG_DISABLE_RISC_CODE_LOAD)) {
2066 		if (ha->risc_code != NULL) {
2067 			kmem_free(ha->risc_code, ha->risc_code_size);
2068 			ha->risc_code = NULL;
2069 			ha->risc_code_size = 0;
2070 		}
2071 
2072 		/* Get RISC code length. */
2073 		rval = ql_rd_risc_ram(ha, risc_address + 3, ha->request_dvma,
2074 		    1);
2075 		if (rval == QL_SUCCESS) {
2076 			lptr = (uint32_t *)ha->request_ring_bp;
2077 			fw_size = *lptr << 1;
2078 
2079 			if ((bufp = kmem_alloc(fw_size, KM_SLEEP)) != NULL) {
2080 				ha->risc_code_size = fw_size;
2081 				ha->risc_code = bufp;
2082 				ha->fw_transfer_size = 128;
2083 
2084 				/* Dump RISC code. */
2085 				do {
2086 					if (fw_size > ha->fw_transfer_size) {
2087 						byte_count =
2088 						    ha->fw_transfer_size;
2089 					} else {
2090 						byte_count = fw_size;
2091 					}
2092 
2093 					word_count =
2094 					    (uint16_t)(byte_count >> 1);
2095 
2096 					rval = ql_rd_risc_ram(ha, risc_address,
2097 					    ha->request_dvma, word_count);
2098 					if (rval != QL_SUCCESS) {
2099 						kmem_free(ha->risc_code,
2100 						    ha->risc_code_size);
2101 						ha->risc_code = NULL;
2102 						ha->risc_code_size = 0;
2103 						break;
2104 					}
2105 
2106 					(void) ddi_dma_sync(
2107 					    ha->hba_buf.dma_handle,
2108 					    REQUEST_Q_BUFFER_OFFSET,
2109 					    byte_count,
2110 					    DDI_DMA_SYNC_FORKERNEL);
2111 					ddi_rep_get16(ha->hba_buf.acc_handle,
2112 					    (uint16_t *)bufp,
2113 					    (uint16_t *)ha->request_ring_bp,
2114 					    word_count, DDI_DEV_AUTOINCR);
2115 
2116 					risc_address += word_count;
2117 					fw_size -= byte_count;
2118 					bufp	+= byte_count;
2119 				} while (fw_size != 0);
2120 			}
2121 		}
2122 	} else {
2123 		rval = QL_FUNCTION_FAILED;
2124 	}
2125 
2126 	if (rval != QL_SUCCESS) {
2127 		EL(ha, "Load RISC code\n");
2128 	} else {
2129 		/*EMPTY*/
2130 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2131 	}
2132 	return (rval);
2133 }
2134 
2135 /*
2136  * Chip diagnostics
2137  *	Test chip for proper operation.
2138  *
2139  * Input:
2140  *	ha = adapter state pointer.
2141  *
2142  * Returns:
2143  *	ql local function return status code.
2144  *
2145  * Context:
2146  *	Kernel context.
2147  */
2148 static int
2149 ql_chip_diag(ql_adapter_state_t *ha)
2150 {
2151 	ql_mbx_data_t	mr;
2152 	int32_t		rval = QL_FUNCTION_FAILED;
2153 	int32_t		retries = 4;
2154 	uint16_t	id;
2155 
2156 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2157 
2158 	do {
2159 		/* Reset ISP chip. */
2160 		TASK_DAEMON_LOCK(ha);
2161 		ha->task_daemon_flags &= ~ISP_ABORT_NEEDED;
2162 		TASK_DAEMON_UNLOCK(ha);
2163 		ql_reset_chip(ha);
2164 
2165 		/* For ISP2200A reduce firmware load size. */
2166 		if (CFG_IST(ha, CFG_CTRL_2200) &&
2167 		    RD16_IO_REG(ha, mailbox[7]) == 4) {
2168 			ha->fw_transfer_size = 128;
2169 		} else {
2170 			ha->fw_transfer_size = REQUEST_QUEUE_SIZE;
2171 		}
2172 
2173 		/* Check product ID of chip */
2174 		mr.mb[1] = RD16_IO_REG(ha, mailbox[1]);
2175 		mr.mb[2] = RD16_IO_REG(ha, mailbox[2]);
2176 		mr.mb[3] = RD16_IO_REG(ha, mailbox[3]);
2177 
2178 		if (ha->device_id == 0x5432 || ha->device_id == 0x8432) {
2179 			id = 0x2432;
2180 		} else if (ha->device_id == 0x5422 ||
2181 		    ha->device_id == 0x8432) {
2182 			id = 0x2422;
2183 		} else {
2184 			id = ha->device_id;
2185 		}
2186 
2187 		if (mr.mb[1] == PROD_ID_1 &&
2188 		    (mr.mb[2] == PROD_ID_2 || mr.mb[2] == PROD_ID_2a) &&
2189 		    (mr.mb[3] == PROD_ID_3 || mr.mb[3] == id)) {
2190 
2191 			ha->adapter_stats->revlvl.isp2200 = RD16_IO_REG(ha,
2192 			    mailbox[4]);
2193 			ha->adapter_stats->revlvl.risc = RD16_IO_REG(ha,
2194 			    mailbox[5]);
2195 			ha->adapter_stats->revlvl.frmbfr = RD16_IO_REG(ha,
2196 			    mailbox[6]);
2197 			ha->adapter_stats->revlvl.riscrom = RD16_IO_REG(ha,
2198 			    mailbox[7]);
2199 			bcopy(QL_VERSION, ha->adapter_stats->revlvl.qlddv,
2200 			    strlen(QL_VERSION));
2201 
2202 			/* Wrap Incoming Mailboxes Test. */
2203 			mr.mb[1] = 0xAAAA;
2204 			mr.mb[2] = 0x5555;
2205 			mr.mb[3] = 0xAA55;
2206 			mr.mb[4] = 0x55AA;
2207 			mr.mb[5] = 0xA5A5;
2208 			mr.mb[6] = 0x5A5A;
2209 			mr.mb[7] = 0x2525;
2210 			rval = ql_mbx_wrap_test(ha, &mr);
2211 			if (rval == QL_SUCCESS) {
2212 				if (mr.mb[1] != 0xAAAA ||
2213 				    mr.mb[2] != 0x5555 ||
2214 				    mr.mb[3] != 0xAA55 ||
2215 				    mr.mb[4] != 0x55AA ||
2216 				    mr.mb[5] != 0xA5A5 ||
2217 				    mr.mb[6] != 0x5A5A ||
2218 				    mr.mb[7] != 0x2525) {
2219 					rval = QL_FUNCTION_FAILED;
2220 					(void) ql_flash_errlog(ha,
2221 					    FLASH_ERRLOG_ISP_ERR, 0,
2222 					    RD16_IO_REG(ha, hccr),
2223 					    RD16_IO_REG(ha, istatus));
2224 				}
2225 			} else {
2226 				cmn_err(CE_WARN, "%s(%d) - reg test failed="
2227 				    "%xh!", QL_NAME, ha->instance, rval);
2228 			}
2229 		} else {
2230 			cmn_err(CE_WARN, "%s(%d) - prod id failed!, mb1=%xh, "
2231 			    "mb2=%xh, mb3=%xh", QL_NAME, ha->instance,
2232 			    mr.mb[1], mr.mb[2], mr.mb[3]);
2233 		}
2234 	} while ((retries-- != 0) && (rval != QL_SUCCESS));
2235 
2236 	if (rval != QL_SUCCESS) {
2237 		EL(ha, "failed, rval = %xh\n", rval);
2238 	} else {
2239 		/*EMPTY*/
2240 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2241 	}
2242 	return (rval);
2243 }
2244 
2245 /*
2246  * ql_load_isp_firmware
2247  *	Load and start RISC firmware.
2248  *	Uses request ring for DMA buffer.
2249  *
2250  * Input:
2251  *	ha = adapter state pointer.
2252  *
2253  * Returns:
2254  *	ql local function return status code.
2255  *
2256  * Context:
2257  *	Kernel context.
2258  */
2259 int
2260 ql_load_isp_firmware(ql_adapter_state_t *vha)
2261 {
2262 	caddr_t			risc_code_address;
2263 	uint32_t		risc_address, risc_code_size;
2264 	int			rval;
2265 	uint32_t		word_count, cnt;
2266 	size_t			byte_count;
2267 	ql_adapter_state_t	*ha = vha->pha;
2268 
2269 	if (CFG_IST(ha, CFG_LOAD_FLASH_FW)) {
2270 		return (ql_load_flash_fw(ha));
2271 	}
2272 
2273 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2274 
2275 	/* Load firmware segments */
2276 	for (cnt = 0; cnt < MAX_RISC_CODE_SEGMENTS &&
2277 	    ha->risc_fw[cnt].code != NULL; cnt++) {
2278 
2279 		risc_code_address = ha->risc_fw[cnt].code;
2280 		risc_address = ha->risc_fw[cnt].addr;
2281 		risc_code_size = ha->risc_fw[cnt].length;
2282 
2283 		while (risc_code_size) {
2284 			if (CFG_IST(ha, CFG_CTRL_2425)) {
2285 				word_count = ha->fw_transfer_size >> 2;
2286 				if (word_count > risc_code_size) {
2287 					word_count = risc_code_size;
2288 				}
2289 				byte_count = word_count << 2;
2290 
2291 				ddi_rep_put32(ha->hba_buf.acc_handle,
2292 				    (uint32_t *)risc_code_address,
2293 				    (uint32_t *)ha->request_ring_bp,
2294 				    word_count, DDI_DEV_AUTOINCR);
2295 			} else {
2296 				word_count = ha->fw_transfer_size >> 1;
2297 				if (word_count > risc_code_size) {
2298 					word_count = risc_code_size;
2299 				}
2300 				byte_count = word_count << 1;
2301 
2302 				ddi_rep_put16(ha->hba_buf.acc_handle,
2303 				    (uint16_t *)risc_code_address,
2304 				    (uint16_t *)ha->request_ring_bp,
2305 				    word_count, DDI_DEV_AUTOINCR);
2306 			}
2307 
2308 			(void) ddi_dma_sync(ha->hba_buf.dma_handle,
2309 			    REQUEST_Q_BUFFER_OFFSET, byte_count,
2310 			    DDI_DMA_SYNC_FORDEV);
2311 
2312 			rval = ql_wrt_risc_ram(ha, risc_address,
2313 			    ha->request_dvma, word_count);
2314 			if (rval != QL_SUCCESS) {
2315 				EL(ha, "failed, load=%xh\n", rval);
2316 				cnt = MAX_RISC_CODE_SEGMENTS;
2317 				break;
2318 			}
2319 
2320 			risc_address += word_count;
2321 			risc_code_size -= word_count;
2322 			risc_code_address += byte_count;
2323 		}
2324 	}
2325 
2326 	/* Start firmware. */
2327 	if (rval == QL_SUCCESS) {
2328 		rval = ql_start_firmware(ha);
2329 	}
2330 
2331 	if (rval != QL_SUCCESS) {
2332 		EL(ha, "failed, rval = %xh\n", rval);
2333 	} else {
2334 		/*EMPTY*/
2335 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2336 	}
2337 
2338 	return (rval);
2339 }
2340 
2341 /*
2342  * ql_load_flash_fw
2343  *	Gets ISP24xx firmware from flash and loads ISP.
2344  *
2345  * Input:
2346  *	ha:	adapter state pointer.
2347  *
2348  * Returns:
2349  *	qla local function return status code.
2350  */
2351 static int
2352 ql_load_flash_fw(ql_adapter_state_t *ha)
2353 {
2354 	int		rval;
2355 	uint8_t		seg_cnt;
2356 	uint32_t	risc_address, xfer_size, count,	*bp, faddr;
2357 	uint32_t	flash_addr = FLASH_24XX_FIRMWARE_ADDR;
2358 	uint32_t	risc_code_size = 0;
2359 
2360 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2361 
2362 	/* Adjust addr for 32 bit words */
2363 	flash_addr = flash_addr / 4;
2364 
2365 	for (seg_cnt = 0; seg_cnt < 2; seg_cnt++) {
2366 		xfer_size = ha->fw_transfer_size >> 2;
2367 		do {
2368 			GLOBAL_HW_LOCK();
2369 
2370 			/* Read data from flash. */
2371 			bp = (uint32_t *)ha->request_ring_bp;
2372 			faddr = FLASH_DATA_ADDR | flash_addr;
2373 			for (count = 0; count < xfer_size; count++) {
2374 				rval = ql_24xx_read_flash(ha, faddr++, bp);
2375 				if (rval != QL_SUCCESS) {
2376 					break;
2377 				}
2378 				ql_chg_endian((uint8_t *)bp++, 4);
2379 			}
2380 
2381 			GLOBAL_HW_UNLOCK();
2382 
2383 			if (rval != QL_SUCCESS) {
2384 				EL(ha, "24xx_read_flash failed=%xh\n", rval);
2385 				break;
2386 			}
2387 
2388 			if (risc_code_size == 0) {
2389 				bp = (uint32_t *)ha->request_ring_bp;
2390 				risc_address = bp[2];
2391 				risc_code_size = bp[3];
2392 				ha->risc_fw[seg_cnt].addr = risc_address;
2393 				ha->risc_fw[seg_cnt].length = risc_code_size;
2394 			}
2395 
2396 			if (risc_code_size < xfer_size) {
2397 				xfer_size = risc_code_size;
2398 			}
2399 
2400 			(void) ddi_dma_sync(ha->hba_buf.dma_handle,
2401 			    REQUEST_Q_BUFFER_OFFSET, xfer_size << 2,
2402 			    DDI_DMA_SYNC_FORDEV);
2403 
2404 			rval = ql_wrt_risc_ram(ha, risc_address,
2405 			    ha->request_dvma, xfer_size);
2406 			if (rval != QL_SUCCESS) {
2407 				EL(ha, "ql_wrt_risc_ram failed=%xh\n", rval);
2408 				break;
2409 			}
2410 
2411 			risc_address += xfer_size;
2412 			risc_code_size -= xfer_size;
2413 			flash_addr += xfer_size;
2414 		} while (risc_code_size);
2415 
2416 		if (rval != QL_SUCCESS) {
2417 			break;
2418 		}
2419 	}
2420 
2421 	/* Start firmware. */
2422 	if (rval == QL_SUCCESS) {
2423 		rval = ql_start_firmware(ha);
2424 	}
2425 
2426 	if (rval != QL_SUCCESS) {
2427 		EL(ha, "failed, rval = %xh\n", rval);
2428 	} else {
2429 		/*EMPTY*/
2430 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2431 	}
2432 	return (rval);
2433 }
2434 
2435 /*
2436  * ql_start_firmware
2437  *	Starts RISC code.
2438  *
2439  * Input:
2440  *	ha = adapter state pointer.
2441  *
2442  * Returns:
2443  *	ql local function return status code.
2444  *
2445  * Context:
2446  *	Kernel context.
2447  */
2448 int
2449 ql_start_firmware(ql_adapter_state_t *vha)
2450 {
2451 	int			rval;
2452 	ql_mbx_data_t		mr;
2453 	ql_adapter_state_t	*ha = vha->pha;
2454 
2455 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2456 
2457 	/* Verify checksum of loaded RISC code. */
2458 	rval = ql_verify_checksum(ha);
2459 	if (rval == QL_SUCCESS) {
2460 		/* Start firmware execution. */
2461 		(void) ql_execute_fw(ha);
2462 
2463 		/* Save firmware version. */
2464 		(void) ql_get_fw_version(ha, &mr);
2465 		ha->fw_major_version = mr.mb[1];
2466 		ha->fw_minor_version = mr.mb[2];
2467 		ha->fw_subminor_version = mr.mb[3];
2468 		ha->fw_ext_memory_size = ((SHORT_TO_LONG(mr.mb[4], mr.mb[5]) -
2469 		    0x100000) + 1) * 4;
2470 		ha->fw_attributes = mr.mb[6];
2471 
2472 		/* Set Serdes Transmit Parameters. */
2473 		if (!ha->cfg_flags & CFG_CTRL_2200 &&
2474 		    ha->serdes_param[0] & BIT_0) {
2475 			mr.mb[1] = ha->serdes_param[0];
2476 			mr.mb[2] = ha->serdes_param[1];
2477 			mr.mb[3] = ha->serdes_param[2];
2478 			mr.mb[4] = ha->serdes_param[3];
2479 			(void) ql_serdes_param(ha, &mr);
2480 		}
2481 	}
2482 
2483 	if (rval != QL_SUCCESS) {
2484 		ha->task_daemon_flags &= ~FIRMWARE_LOADED;
2485 		EL(ha, "failed, rval = %xh\n", rval);
2486 	} else {
2487 		ha->task_daemon_flags |= FIRMWARE_LOADED;
2488 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2489 	}
2490 	return (rval);
2491 }
2492 
2493 /*
2494  * ql_set_cache_line
2495  *	Sets PCI cache line parameter.
2496  *
2497  * Input:
2498  *	ha = adapter state pointer.
2499  *
2500  * Returns:
2501  *	ql local function return status code.
2502  *
2503  * Context:
2504  *	Kernel context.
2505  */
2506 int
2507 ql_set_cache_line(ql_adapter_state_t *ha)
2508 {
2509 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2510 
2511 	/* Set the cache line. */
2512 	if (CFG_IST(ha->pha, CFG_SET_CACHE_LINE_SIZE_1)) {
2513 		/* Set cache line register. */
2514 		ql_pci_config_put8(ha->pha, PCI_CONF_CACHE_LINESZ, 1);
2515 	}
2516 
2517 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2518 
2519 	return (QL_SUCCESS);
2520 }
2521 
2522 /*
2523  * ql_init_rings
2524  *	Initializes firmware and ring pointers.
2525  *
2526  *	Beginning of response ring has initialization control block
2527  *	already built by nvram config routine.
2528  *
2529  * Input:
2530  *	ha = adapter state pointer.
2531  *	ha->hba_buf = request and response rings
2532  *	ha->init_ctrl_blk = initialization control block
2533  *
2534  * Returns:
2535  *	ql local function return status code.
2536  *
2537  * Context:
2538  *	Kernel context.
2539  */
2540 int
2541 ql_init_rings(ql_adapter_state_t *vha2)
2542 {
2543 	int			rval, rval2;
2544 	uint16_t		index;
2545 	ql_mbx_data_t		mr;
2546 	ql_adapter_state_t	*ha = vha2->pha;
2547 
2548 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2549 
2550 	/* Clear outstanding commands array. */
2551 	for (index = 0; index < MAX_OUTSTANDING_COMMANDS; index++) {
2552 		ha->outstanding_cmds[index] = NULL;
2553 	}
2554 	ha->osc_index = 1;
2555 
2556 	ha->pending_cmds.first = NULL;
2557 	ha->pending_cmds.last = NULL;
2558 
2559 	/* Initialize firmware. */
2560 	ha->request_ring_ptr = ha->request_ring_bp;
2561 	ha->req_ring_index = 0;
2562 	ha->req_q_cnt = REQUEST_ENTRY_CNT - 1;
2563 	ha->response_ring_ptr = ha->response_ring_bp;
2564 	ha->rsp_ring_index = 0;
2565 
2566 	if (ha->flags & VP_ENABLED) {
2567 		ql_adapter_state_t	*vha;
2568 		uint16_t		cnt;
2569 		uint32_t		max_vports;
2570 		ql_init_24xx_cb_t	*icb = &ha->init_ctrl_blk.cb24;
2571 
2572 		max_vports = (CFG_IST(ha, CFG_CTRL_2422) ?
2573 		    MAX_24_VIRTUAL_PORTS : MAX_25_VIRTUAL_PORTS);
2574 		bzero(icb->vp_count,
2575 		    ((uintptr_t)icb + sizeof (ql_init_24xx_cb_t)) -
2576 		    (uintptr_t)icb->vp_count);
2577 		icb->vp_count[0] = (uint8_t)max_vports;
2578 
2579 		/* Allow connection option 2. */
2580 		icb->global_vp_option[0] = BIT_1;
2581 
2582 		for (cnt = 0, vha = ha->vp_next; cnt < max_vports &&
2583 		    vha != NULL; vha = vha->vp_next, cnt++) {
2584 
2585 			index = (uint8_t)(vha->vp_index - 1);
2586 			bcopy(vha->loginparams.node_ww_name.raw_wwn,
2587 			    icb->vpc[index].node_name, 8);
2588 			bcopy(vha->loginparams.nport_ww_name.raw_wwn,
2589 			    icb->vpc[index].port_name, 8);
2590 
2591 			icb->vpc[index].options = VPO_TARGET_MODE_DISABLED |
2592 			    VPO_INITIATOR_MODE_ENABLED;
2593 			if (vha->flags & VP_ENABLED) {
2594 				icb->vpc[index].options = (uint8_t)
2595 				    (icb->vpc[index].options | VPO_ENABLED);
2596 			}
2597 		}
2598 	}
2599 
2600 	rval = ql_init_firmware(ha);
2601 
2602 	if (rval == QL_SUCCESS && (CFG_IST(ha, CFG_CTRL_2425)) == 0) {
2603 		/* Tell firmware to enable MBA_PORT_BYPASS_CHANGED event */
2604 		rval = ql_get_firmware_option(ha, &mr);
2605 		if (rval == QL_SUCCESS) {
2606 			mr.mb[1] = (uint16_t)(mr.mb[1] | BIT_9);
2607 			mr.mb[2] = 0;
2608 			mr.mb[3] = BIT_10;
2609 			rval = ql_set_firmware_option(ha, &mr);
2610 		}
2611 	}
2612 
2613 	if ((rval == QL_SUCCESS) && (CFG_IST(ha, CFG_ENABLE_FWFCETRACE))) {
2614 		/* Firmware Fibre Channel Event Trace Buffer */
2615 		if ((rval2 = ql_get_dma_mem(ha, &ha->fwfcetracebuf, FWFCESIZE,
2616 		    LITTLE_ENDIAN_DMA, QL_DMA_RING_ALIGN)) != QL_SUCCESS) {
2617 			EL(ha, "fcetrace buffer alloc failed: %xh\n", rval2);
2618 		} else {
2619 			if ((rval2 = ql_fw_etrace(ha, &ha->fwfcetracebuf,
2620 			    FTO_FCE_TRACE_ENABLE)) != QL_SUCCESS) {
2621 				EL(ha, "fcetrace enable failed: %xh\n", rval2);
2622 				ql_free_phys(ha, &ha->fwfcetracebuf);
2623 			}
2624 		}
2625 	}
2626 
2627 	if ((rval == QL_SUCCESS) && (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE))) {
2628 		/* Firmware Extended Trace Buffer */
2629 		if ((rval2 = ql_get_dma_mem(ha, &ha->fwexttracebuf, FWEXTSIZE,
2630 		    LITTLE_ENDIAN_DMA, QL_DMA_RING_ALIGN)) != QL_SUCCESS) {
2631 			EL(ha, "exttrace buffer alloc failed: %xh\n", rval2);
2632 		} else {
2633 			if ((rval2 = ql_fw_etrace(ha, &ha->fwexttracebuf,
2634 			    FTO_EXT_TRACE_ENABLE)) != QL_SUCCESS) {
2635 				EL(ha, "exttrace enable failed: %xh\n", rval2);
2636 				ql_free_phys(ha, &ha->fwexttracebuf);
2637 			}
2638 		}
2639 	}
2640 
2641 	if (rval == QL_SUCCESS && CFG_IST(ha, CFG_CTRL_MENLO)) {
2642 		ql_mbx_iocb_t	*pkt;
2643 		clock_t		timer;
2644 
2645 		/* Wait for firmware login of menlo. */
2646 		for (timer = 3000; timer; timer--) {
2647 			if (ha->flags & MENLO_LOGIN_OPERATIONAL) {
2648 				break;
2649 			}
2650 
2651 			if (!(ha->flags & INTERRUPTS_ENABLED) ||
2652 			    ddi_in_panic()) {
2653 				if (RD16_IO_REG(ha, istatus) & RISC_INT) {
2654 					(void) ql_isr((caddr_t)ha);
2655 					INTR_LOCK(ha);
2656 					ha->intr_claimed = B_TRUE;
2657 					INTR_UNLOCK(ha);
2658 				}
2659 			}
2660 
2661 			/* Delay for 1 tick (10 milliseconds). */
2662 			ql_delay(ha, 10000);
2663 		}
2664 
2665 		if (timer == 0) {
2666 			rval = QL_FUNCTION_TIMEOUT;
2667 		} else {
2668 			pkt = kmem_zalloc(sizeof (ql_mbx_iocb_t), KM_SLEEP);
2669 			if (pkt == NULL) {
2670 				EL(ha, "failed, kmem_zalloc\n");
2671 				rval = QL_MEMORY_ALLOC_FAILED;
2672 			} else {
2673 				pkt->mvfy.entry_type = VERIFY_MENLO_TYPE;
2674 				pkt->mvfy.entry_count = 1;
2675 				pkt->mvfy.options_status =
2676 				    LE_16(VMF_DO_NOT_UPDATE_FW);
2677 
2678 				rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt,
2679 				    sizeof (ql_mbx_iocb_t));
2680 				LITTLE_ENDIAN_16(&pkt->mvfy.options_status);
2681 				LITTLE_ENDIAN_16(&pkt->mvfy.failure_code);
2682 
2683 				if (rval != QL_SUCCESS ||
2684 				    (pkt->mvfy.entry_status & 0x3c) != 0 ||
2685 				    pkt->mvfy.options_status != CS_COMPLETE) {
2686 					EL(ha, "failed, status=%xh, es=%xh, "
2687 					    "cs=%xh, fc=%xh\n", rval,
2688 					    pkt->mvfy.entry_status & 0x3c,
2689 					    pkt->mvfy.options_status,
2690 					    pkt->mvfy.failure_code);
2691 					if (rval == QL_SUCCESS) {
2692 						rval = QL_FUNCTION_FAILED;
2693 					}
2694 				}
2695 
2696 				kmem_free(pkt, sizeof (ql_mbx_iocb_t));
2697 			}
2698 		}
2699 	}
2700 
2701 	if (rval != QL_SUCCESS) {
2702 		TASK_DAEMON_LOCK(ha);
2703 		ha->task_daemon_flags &= ~FIRMWARE_UP;
2704 		TASK_DAEMON_UNLOCK(ha);
2705 		EL(ha, "failed, rval = %xh\n", rval);
2706 	} else {
2707 		TASK_DAEMON_LOCK(ha);
2708 		ha->task_daemon_flags |= FIRMWARE_UP;
2709 		TASK_DAEMON_UNLOCK(ha);
2710 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2711 	}
2712 	return (rval);
2713 }
2714 
2715 /*
2716  * ql_fw_ready
2717  *	Waits for firmware ready. If firmware becomes ready
2718  *	device queues and RISC code are synchronized.
2719  *
2720  * Input:
2721  *	ha = adapter state pointer.
2722  *	secs = max wait time, in seconds (0-255).
2723  *
2724  * Returns:
2725  *	ql local function return status code.
2726  *
2727  * Context:
2728  *	Kernel context.
2729  */
2730 int
2731 ql_fw_ready(ql_adapter_state_t *ha, uint8_t secs)
2732 {
2733 	ql_mbx_data_t	mr;
2734 	clock_t		timer;
2735 	clock_t		dly = 250000;
2736 	clock_t		sec_delay = MICROSEC / dly;
2737 	clock_t		wait = secs * sec_delay;
2738 	int		rval = QL_FUNCTION_FAILED;
2739 	uint16_t	state = 0xffff;
2740 
2741 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2742 
2743 	timer = ha->r_a_tov < secs ? secs : ha->r_a_tov;
2744 	timer = (timer + 2) * sec_delay;
2745 
2746 	/* Wait for ISP to finish LIP */
2747 	while (timer != 0 && wait != 0 &&
2748 	    !(ha->task_daemon_flags & ISP_ABORT_NEEDED)) {
2749 
2750 		rval = ql_get_firmware_state(ha, &mr);
2751 		if (rval == QL_SUCCESS) {
2752 			if (ha->task_daemon_flags & (ISP_ABORT_NEEDED |
2753 			    LOOP_DOWN)) {
2754 				wait--;
2755 			} else if (mr.mb[1] != FSTATE_READY) {
2756 				if (mr.mb[1] != FSTATE_WAIT_LOGIN) {
2757 					wait--;
2758 				}
2759 				rval = QL_FUNCTION_FAILED;
2760 			} else {
2761 				/* Firmware is ready. Get 2 * R_A_TOV. */
2762 				rval = ql_get_timeout_parameters(ha,
2763 				    &ha->r_a_tov);
2764 				if (rval != QL_SUCCESS) {
2765 					EL(ha, "failed, get_timeout_param"
2766 					    "=%xh\n", rval);
2767 				}
2768 
2769 				/* Configure loop. */
2770 				rval = ql_configure_loop(ha);
2771 				(void) ql_marker(ha, 0, 0, MK_SYNC_ALL);
2772 
2773 				if (ha->task_daemon_flags &
2774 				    LOOP_RESYNC_NEEDED) {
2775 					wait--;
2776 					EL(ha, "loop trans; tdf=%xh\n",
2777 					    ha->task_daemon_flags);
2778 				} else {
2779 					break;
2780 				}
2781 			}
2782 		} else {
2783 			wait--;
2784 		}
2785 
2786 		if (state != mr.mb[1]) {
2787 			EL(ha, "mailbox_reg[1] = %xh\n", mr.mb[1]);
2788 			state = mr.mb[1];
2789 		}
2790 
2791 		/* Delay for a tick if waiting. */
2792 		if (timer-- != 0 && wait != 0) {
2793 			if (timer % 4 == 0) {
2794 				delay(drv_usectohz(dly));
2795 			} else {
2796 				drv_usecwait(dly);
2797 			}
2798 		} else {
2799 			rval = QL_FUNCTION_TIMEOUT;
2800 		}
2801 	}
2802 
2803 	if (rval != QL_SUCCESS) {
2804 		EL(ha, "failed, rval = %xh\n", rval);
2805 	} else {
2806 		/*EMPTY*/
2807 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2808 	}
2809 	return (rval);
2810 }
2811 
2812 /*
2813  * ql_configure_loop
2814  *	Setup configurations based on loop.
2815  *
2816  * Input:
2817  *	ha = adapter state pointer.
2818  *
2819  * Returns:
2820  *	ql local function return status code.
2821  *
2822  * Context:
2823  *	Kernel context.
2824  */
2825 static int
2826 ql_configure_loop(ql_adapter_state_t *ha)
2827 {
2828 	int			rval;
2829 	ql_adapter_state_t	*vha;
2830 
2831 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2832 
2833 	for (vha = ha; vha != NULL; vha = vha->vp_next) {
2834 		TASK_DAEMON_LOCK(ha);
2835 		if (!(vha->task_daemon_flags & LOOP_RESYNC_NEEDED) &&
2836 		    vha->vp_index != 0 && !(vha->flags & VP_ENABLED)) {
2837 			TASK_DAEMON_UNLOCK(ha);
2838 			continue;
2839 		}
2840 		vha->task_daemon_flags &= ~LOOP_RESYNC_NEEDED;
2841 		TASK_DAEMON_UNLOCK(ha);
2842 
2843 		rval = ql_configure_hba(vha);
2844 		if (rval == QL_SUCCESS && !(ha->task_daemon_flags &
2845 		    (LOOP_RESYNC_NEEDED | LOOP_DOWN))) {
2846 			rval = ql_configure_device_d_id(vha);
2847 			if (rval == QL_SUCCESS && !(ha->task_daemon_flags &
2848 			    (LOOP_RESYNC_NEEDED | LOOP_DOWN))) {
2849 				(void) ql_configure_fabric(vha);
2850 			}
2851 		}
2852 	}
2853 
2854 	if (rval != QL_SUCCESS) {
2855 		EL(ha, "failed, rval = %xh\n", rval);
2856 	} else {
2857 		/*EMPTY*/
2858 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2859 	}
2860 	return (rval);
2861 }
2862 
2863 /*
2864  * ql_configure_hba
2865  *	Setup adapter context.
2866  *
2867  * Input:
2868  *	ha = adapter state pointer.
2869  *
2870  * Returns:
2871  *	ql local function return status code.
2872  *
2873  * Context:
2874  *	Kernel context.
2875  */
2876 static int
2877 ql_configure_hba(ql_adapter_state_t *ha)
2878 {
2879 	uint8_t		*bp;
2880 	int		rval;
2881 	uint32_t	state;
2882 	ql_mbx_data_t	mr;
2883 
2884 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2885 
2886 	/* Get host addresses. */
2887 	rval = ql_get_adapter_id(ha, &mr);
2888 	if (rval == QL_SUCCESS) {
2889 		ha->topology = (uint8_t)(ha->topology &
2890 		    ~(QL_N_PORT | QL_NL_PORT | QL_F_PORT | QL_FL_PORT));
2891 
2892 		/* Save Host d_id, alpa, loop ID. */
2893 		ha->loop_id = mr.mb[1];
2894 		ha->d_id.b.al_pa = LSB(mr.mb[2]);
2895 		ha->d_id.b.area = MSB(mr.mb[2]);
2896 		ha->d_id.b.domain = LSB(mr.mb[3]);
2897 
2898 		ADAPTER_STATE_LOCK(ha);
2899 		ha->flags &= ~FDISC_ENABLED;
2900 
2901 		/* Get loop topology. */
2902 		switch (mr.mb[6]) {
2903 		case CNX_LOOP_NO_FABRIC:
2904 			ha->topology = (uint8_t)(ha->topology | QL_NL_PORT);
2905 			break;
2906 		case CNX_FLPORT_IN_LOOP:
2907 			ha->topology = (uint8_t)(ha->topology | QL_FL_PORT);
2908 			break;
2909 		case CNX_NPORT_2_NPORT_P2P:
2910 		case CNX_NPORT_2_NPORT_NO_TGT_RSP:
2911 			ha->flags |= POINT_TO_POINT;
2912 			ha->topology = (uint8_t)(ha->topology | QL_N_PORT);
2913 			break;
2914 		case CNX_FLPORT_P2P:
2915 			ha->flags |= POINT_TO_POINT;
2916 			ha->topology = (uint8_t)(ha->topology | QL_F_PORT);
2917 
2918 			/* Get supported option. */
2919 			if (CFG_IST(ha, CFG_CTRL_2425) &&
2920 			    mr.mb[7] & FLOGI_NPIV_SUPPORT) {
2921 				ha->flags |= FDISC_ENABLED;
2922 			}
2923 			break;
2924 		default:
2925 			QL_PRINT_2(CE_CONT, "(%d,%d): UNKNOWN topology=%xh, "
2926 			    "d_id=%xh\n", ha->instance, ha->vp_index, mr.mb[6],
2927 			    ha->d_id.b24);
2928 			rval = QL_FUNCTION_FAILED;
2929 			break;
2930 		}
2931 		ADAPTER_STATE_UNLOCK(ha);
2932 
2933 		if (CFG_IST(ha, (CFG_CTRL_2300|CFG_CTRL_6322|
2934 		    CFG_CTRL_2425))) {
2935 			mr.mb[1] = 0;
2936 			mr.mb[2] = 0;
2937 			rval = ql_data_rate(ha, &mr);
2938 			if (rval != QL_SUCCESS) {
2939 				EL(ha, "data_rate status=%xh\n", rval);
2940 				state = FC_STATE_FULL_SPEED;
2941 			} else {
2942 				if (mr.mb[1] == 0) {
2943 					state = FC_STATE_1GBIT_SPEED;
2944 				} else if (mr.mb[1] == 1) {
2945 					state = FC_STATE_2GBIT_SPEED;
2946 				} else if (mr.mb[1] == 3) {
2947 					state = FC_STATE_4GBIT_SPEED;
2948 				} else if (mr.mb[1] == 4) {
2949 					state = FC_STATE_8GBIT_SPEED;
2950 				} else {
2951 					state = 0;
2952 				}
2953 			}
2954 		} else {
2955 			state = FC_STATE_FULL_SPEED;
2956 		}
2957 		ha->state = FC_PORT_STATE_MASK(ha->state) | state;
2958 	} else if (rval == MBS_COMMAND_ERROR) {
2959 		EL(ha, "mbox cmd error, rval = %xh, mr.mb[1]=%hx\n",
2960 		    rval, mr.mb[1]);
2961 	}
2962 
2963 	if (rval != QL_SUCCESS) {
2964 		EL(ha, "failed, rval = %xh\n", rval);
2965 	} else {
2966 		bp = ha->loginparams.nport_ww_name.raw_wwn;
2967 		EL(ha, "topology=%xh, d_id=%xh, "
2968 		    "wwpn=%02x%02x%02x%02x%02x%02x%02x%02xh\n",
2969 		    ha->topology, ha->d_id.b24, bp[0], bp[1],
2970 		    bp[2], bp[3], bp[4], bp[5], bp[6], bp[7]);
2971 	}
2972 	return (rval);
2973 }
2974 
2975 /*
2976  * ql_configure_device_d_id
2977  *	Updates device loop ID.
2978  *	Also adds to device queue any new devices found on private loop.
2979  *
2980  * Input:
2981  *	ha = adapter state pointer.
2982  *
2983  * Returns:
2984  *	ql local function return status code.
2985  *
2986  * Context:
2987  *	Kernel context.
2988  */
2989 static int
2990 ql_configure_device_d_id(ql_adapter_state_t *ha)
2991 {
2992 	port_id_t		d_id;
2993 	ql_link_t		*link;
2994 	int			rval;
2995 	int			loop;
2996 	ql_tgt_t		*tq;
2997 	ql_dev_id_list_t	*list;
2998 	uint32_t		list_size;
2999 	uint16_t		index, loop_id;
3000 	ql_mbx_data_t		mr;
3001 	uint8_t			retries = MAX_DEVICE_LOST_RETRY;
3002 
3003 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3004 
3005 	list_size = sizeof (ql_dev_id_list_t) * DEVICE_LIST_ENTRIES;
3006 	list = kmem_zalloc(list_size, KM_SLEEP);
3007 	if (list == NULL) {
3008 		rval = QL_MEMORY_ALLOC_FAILED;
3009 		EL(ha, "failed, rval = %xh\n", rval);
3010 		return (rval);
3011 	}
3012 
3013 	do {
3014 		/*
3015 		 * Get data from RISC code d_id list to init each device queue.
3016 		 */
3017 		rval = ql_get_id_list(ha, (caddr_t)list, list_size, &mr);
3018 		if (rval != QL_SUCCESS) {
3019 			kmem_free(list, list_size);
3020 			EL(ha, "failed, rval = %xh\n", rval);
3021 			return (rval);
3022 		}
3023 
3024 		/* Acquire adapter state lock. */
3025 		ADAPTER_STATE_LOCK(ha);
3026 
3027 		/* Mark all queues as unusable. */
3028 		for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
3029 			for (link = ha->dev[index].first; link != NULL;
3030 			    link = link->next) {
3031 				tq = link->base_address;
3032 				DEVICE_QUEUE_LOCK(tq);
3033 				if (!(tq->flags & TQF_PLOGI_PROGRS)) {
3034 					tq->loop_id = (uint16_t)
3035 					    (tq->loop_id | PORT_LOST_ID);
3036 				}
3037 				DEVICE_QUEUE_UNLOCK(tq);
3038 			}
3039 		}
3040 
3041 		/* If device not in queues add new queue. */
3042 		for (index = 0; index < mr.mb[1]; index++) {
3043 			ql_dev_list(ha, list, index, &d_id, &loop_id);
3044 
3045 			if (VALID_DEVICE_ID(ha, loop_id)) {
3046 				tq = ql_dev_init(ha, d_id, loop_id);
3047 				if (tq != NULL) {
3048 					tq->loop_id = loop_id;
3049 
3050 					/* Test for fabric device. */
3051 					if (d_id.b.domain !=
3052 					    ha->d_id.b.domain ||
3053 					    d_id.b.area != ha->d_id.b.area) {
3054 						tq->flags |= TQF_FABRIC_DEVICE;
3055 					}
3056 
3057 					ADAPTER_STATE_UNLOCK(ha);
3058 					if (ql_get_port_database(ha, tq,
3059 					    PDF_NONE) == QL_SUCCESS) {
3060 						ADAPTER_STATE_LOCK(ha);
3061 						tq->loop_id = (uint16_t)
3062 						    (tq->loop_id &
3063 						    ~PORT_LOST_ID);
3064 					} else {
3065 						ADAPTER_STATE_LOCK(ha);
3066 					}
3067 				}
3068 			}
3069 		}
3070 
3071 		/* 24xx does not report switch devices in ID list. */
3072 		if ((CFG_IST(ha, CFG_CTRL_2425)) &&
3073 		    ha->topology & (QL_F_PORT | QL_FL_PORT)) {
3074 			d_id.b24 = 0xfffffe;
3075 			tq = ql_dev_init(ha, d_id, FL_PORT_24XX_HDL);
3076 			if (tq != NULL) {
3077 				tq->flags |= TQF_FABRIC_DEVICE;
3078 				ADAPTER_STATE_UNLOCK(ha);
3079 				(void) ql_get_port_database(ha, tq, PDF_NONE);
3080 				ADAPTER_STATE_LOCK(ha);
3081 			}
3082 			d_id.b24 = 0xfffffc;
3083 			tq = ql_dev_init(ha, d_id, SNS_24XX_HDL);
3084 			if (tq != NULL) {
3085 				tq->flags |= TQF_FABRIC_DEVICE;
3086 				ADAPTER_STATE_UNLOCK(ha);
3087 				if (ha->vp_index != 0) {
3088 					(void) ql_login_fport(ha, tq,
3089 					    SNS_24XX_HDL, LFF_NONE, NULL);
3090 				}
3091 				(void) ql_get_port_database(ha, tq, PDF_NONE);
3092 				ADAPTER_STATE_LOCK(ha);
3093 			}
3094 		}
3095 
3096 		/* If F_port exists, allocate queue for FL_Port. */
3097 		index = ql_alpa_to_index[0xfe];
3098 		d_id.b24 = 0;
3099 		if (ha->dev[index].first != NULL) {
3100 			tq = ql_dev_init(ha, d_id, (uint16_t)
3101 			    (CFG_IST(ha, CFG_CTRL_2425) ?
3102 			    FL_PORT_24XX_HDL : FL_PORT_LOOP_ID));
3103 			if (tq != NULL) {
3104 				tq->flags |= TQF_FABRIC_DEVICE;
3105 				ADAPTER_STATE_UNLOCK(ha);
3106 				(void) ql_get_port_database(ha, tq, PDF_NONE);
3107 				ADAPTER_STATE_LOCK(ha);
3108 			}
3109 		}
3110 
3111 		/* Allocate queue for broadcast. */
3112 		d_id.b24 = 0xffffff;
3113 		(void) ql_dev_init(ha, d_id, (uint16_t)
3114 		    (CFG_IST(ha, CFG_CTRL_2425) ? BROADCAST_24XX_HDL :
3115 		    IP_BROADCAST_LOOP_ID));
3116 
3117 		/* Check for any devices lost. */
3118 		loop = FALSE;
3119 		for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
3120 			for (link = ha->dev[index].first; link != NULL;
3121 			    link = link->next) {
3122 				tq = link->base_address;
3123 
3124 				if ((tq->loop_id & PORT_LOST_ID) &&
3125 				    !(tq->flags & (TQF_INITIATOR_DEVICE |
3126 				    TQF_FABRIC_DEVICE))) {
3127 					loop = TRUE;
3128 				}
3129 			}
3130 		}
3131 
3132 		/* Release adapter state lock. */
3133 		ADAPTER_STATE_UNLOCK(ha);
3134 
3135 		/* Give devices time to recover. */
3136 		if (loop == TRUE) {
3137 			drv_usecwait(1000000);
3138 		}
3139 	} while (retries-- && loop == TRUE &&
3140 	    !(ha->pha->task_daemon_flags & LOOP_RESYNC_NEEDED));
3141 
3142 	kmem_free(list, list_size);
3143 
3144 	if (rval != QL_SUCCESS) {
3145 		EL(ha, "failed=%xh\n", rval);
3146 	} else {
3147 		/*EMPTY*/
3148 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3149 	}
3150 
3151 	return (rval);
3152 }
3153 
3154 /*
3155  * ql_dev_list
3156  *	Gets device d_id and loop ID from firmware device list.
3157  *
3158  * Input:
3159  *	ha:	adapter state pointer.
3160  *	list	device list pointer.
3161  *	index:	list index of device data.
3162  *	d_id:	pointer for d_id data.
3163  *	id:	pointer for loop ID.
3164  *
3165  * Context:
3166  *	Kernel context.
3167  */
3168 void
3169 ql_dev_list(ql_adapter_state_t *ha, union ql_dev_id_list *list,
3170     uint32_t index, port_id_t *d_id, uint16_t *id)
3171 {
3172 	if (CFG_IST(ha, CFG_CTRL_2425)) {
3173 		struct ql_24_dev_id	*list24 = (struct ql_24_dev_id *)list;
3174 
3175 		d_id->b.al_pa = list24[index].al_pa;
3176 		d_id->b.area = list24[index].area;
3177 		d_id->b.domain = list24[index].domain;
3178 		*id = CHAR_TO_SHORT(list24[index].n_port_hdl_l,
3179 		    list24[index].n_port_hdl_h);
3180 
3181 	} else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
3182 		struct ql_ex_dev_id	*list23 = (struct ql_ex_dev_id *)list;
3183 
3184 		d_id->b.al_pa = list23[index].al_pa;
3185 		d_id->b.area = list23[index].area;
3186 		d_id->b.domain = list23[index].domain;
3187 		*id = CHAR_TO_SHORT(list23[index].loop_id_l,
3188 		    list23[index].loop_id_h);
3189 
3190 	} else {
3191 		struct ql_dev_id	*list22 = (struct ql_dev_id *)list;
3192 
3193 		d_id->b.al_pa = list22[index].al_pa;
3194 		d_id->b.area = list22[index].area;
3195 		d_id->b.domain = list22[index].domain;
3196 		*id = (uint16_t)list22[index].loop_id;
3197 	}
3198 }
3199 
3200 /*
3201  * ql_configure_fabric
3202  *	Setup fabric context.
3203  *
3204  * Input:
3205  *	ha = adapter state pointer.
3206  *
3207  * Returns:
3208  *	ql local function return status code.
3209  *
3210  * Context:
3211  *	Kernel context.
3212  */
3213 static int
3214 ql_configure_fabric(ql_adapter_state_t *ha)
3215 {
3216 	port_id_t	d_id;
3217 	ql_tgt_t	*tq;
3218 	int		rval = QL_FUNCTION_FAILED;
3219 
3220 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3221 
3222 	ha->topology = (uint8_t)(ha->topology & ~QL_SNS_CONNECTION);
3223 
3224 	/* Test switch fabric controller present. */
3225 	d_id.b24 = FS_FABRIC_F_PORT;
3226 	tq = ql_d_id_to_queue(ha, d_id);
3227 	if (tq != NULL) {
3228 		/* Get port/node names of F_Port. */
3229 		(void) ql_get_port_database(ha, tq, PDF_NONE);
3230 
3231 		d_id.b24 = FS_NAME_SERVER;
3232 		tq = ql_d_id_to_queue(ha, d_id);
3233 		if (tq != NULL) {
3234 			(void) ql_get_port_database(ha, tq, PDF_NONE);
3235 			ha->topology = (uint8_t)
3236 			    (ha->topology | QL_SNS_CONNECTION);
3237 			rval = QL_SUCCESS;
3238 		}
3239 	}
3240 
3241 	if (rval != QL_SUCCESS) {
3242 		EL(ha, "failed=%xh\n", rval);
3243 	} else {
3244 		/*EMPTY*/
3245 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3246 	}
3247 	return (rval);
3248 }
3249 
3250 /*
3251  * ql_reset_chip
3252  *	Reset ISP chip.
3253  *
3254  * Input:
3255  *	ha = adapter block pointer.
3256  *	All activity on chip must be already stopped.
3257  *	ADAPTER_STATE_LOCK must be released.
3258  *
3259  * Context:
3260  *	Interrupt or Kernel context, no mailbox commands allowed.
3261  */
3262 void
3263 ql_reset_chip(ql_adapter_state_t *vha)
3264 {
3265 	uint32_t		cnt;
3266 	uint16_t		cmd;
3267 	ql_adapter_state_t	*ha = vha->pha;
3268 
3269 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3270 
3271 	/*
3272 	 * accessing pci space while not powered can cause panic's
3273 	 * on some platforms (i.e. Sunblade 1000's)
3274 	 */
3275 	if (ha->power_level == PM_LEVEL_D3) {
3276 		QL_PRINT_2(CE_CONT, "(%d): Low Power exit\n", ha->instance);
3277 		return;
3278 	}
3279 
3280 	/* Reset all outbound mailbox registers */
3281 	for (cnt = 0; cnt < ha->reg_off->mbox_cnt; cnt++) {
3282 		WRT16_IO_REG(ha, mailbox[cnt], (uint16_t)0);
3283 	}
3284 
3285 	/* Disable ISP interrupts. */
3286 	WRT16_IO_REG(ha, ictrl, 0);
3287 	ADAPTER_STATE_LOCK(ha);
3288 	ha->flags &= ~INTERRUPTS_ENABLED;
3289 	ADAPTER_STATE_UNLOCK(ha);
3290 
3291 	if (CFG_IST(ha, CFG_CTRL_2425)) {
3292 		RD32_IO_REG(ha, ictrl);
3293 		ql_reset_24xx_chip(ha);
3294 		QL_PRINT_3(CE_CONT, "(%d): 24xx exit\n", ha->instance);
3295 		return;
3296 	}
3297 
3298 	/*
3299 	 * We are going to reset the chip in case of 2300. That might cause
3300 	 * a PBM ERR if a DMA transaction is in progress. One way of
3301 	 * avoiding it is to disable Bus Master operation before we start
3302 	 * the reset activity.
3303 	 */
3304 	cmd = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_COMM);
3305 	cmd = (uint16_t)(cmd & ~PCI_COMM_ME);
3306 	ql_pci_config_put16(ha, PCI_CONF_COMM, cmd);
3307 
3308 	/* Pause RISC. */
3309 	WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC);
3310 	for (cnt = 0; cnt < 30000; cnt++) {
3311 		if ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) != 0) {
3312 			break;
3313 		}
3314 		drv_usecwait(MILLISEC);
3315 	}
3316 
3317 	/*
3318 	 * A call to ql_isr() can still happen through
3319 	 * ql_mailbox_command(). So Mark that we are/(will-be)
3320 	 * running from rom code now.
3321 	 */
3322 	TASK_DAEMON_LOCK(ha);
3323 	ha->task_daemon_flags &= ~(FIRMWARE_UP | FIRMWARE_LOADED);
3324 	TASK_DAEMON_UNLOCK(ha);
3325 
3326 	/* Select FPM registers. */
3327 	WRT16_IO_REG(ha, ctrl_status, 0x20);
3328 
3329 	/* FPM Soft Reset. */
3330 	WRT16_IO_REG(ha, fpm_diag_config, 0x100);
3331 
3332 	/* Toggle FPM reset for 2300 */
3333 	if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
3334 		WRT16_IO_REG(ha, fpm_diag_config, 0);
3335 	}
3336 
3337 	/* Select frame buffer registers. */
3338 	WRT16_IO_REG(ha, ctrl_status, 0x10);
3339 
3340 	/* Reset frame buffer FIFOs. */
3341 	if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
3342 		WRT16_IO_REG(ha, fb_cmd, 0x00fc);
3343 		/* read back fb_cmd until zero or 3 seconds max */
3344 		for (cnt = 0; cnt < 300000; cnt++) {
3345 			if ((RD16_IO_REG(ha, fb_cmd) & 0xff) == 0) {
3346 				break;
3347 			}
3348 			drv_usecwait(10);
3349 		}
3350 	} else  {
3351 		WRT16_IO_REG(ha, fb_cmd, 0xa000);
3352 	}
3353 
3354 	/* Select RISC module registers. */
3355 	WRT16_IO_REG(ha, ctrl_status, 0);
3356 
3357 	/* Reset RISC module. */
3358 	WRT16_IO_REG(ha, hccr, HC_RESET_RISC);
3359 
3360 	/* Reset ISP semaphore. */
3361 	WRT16_IO_REG(ha, semaphore, 0);
3362 
3363 	/* Release RISC module. */
3364 	WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
3365 
3366 	/* Insure mailbox registers are free. */
3367 	WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT);
3368 	WRT16_IO_REG(ha, hccr, HC_CLR_HOST_INT);
3369 	ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
3370 	    ~(MBX_BUSY_FLG | MBX_WANT_FLG | MBX_ABORT | MBX_INTERRUPT));
3371 	ha->mcp = NULL;
3372 
3373 	/* Bus Master is disabled so chip reset is safe. */
3374 	if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
3375 		WRT16_IO_REG(ha, ctrl_status, ISP_RESET);
3376 		drv_usecwait(MILLISEC);
3377 
3378 		/* Wait for reset to finish. */
3379 		for (cnt = 0; cnt < 30000; cnt++) {
3380 			if ((RD16_IO_REG(ha, ctrl_status) & ISP_RESET) == 0) {
3381 				break;
3382 			}
3383 			drv_usecwait(MILLISEC);
3384 		}
3385 	}
3386 
3387 	/* Wait for RISC to recover from reset. */
3388 	for (cnt = 0; cnt < 30000; cnt++) {
3389 		if (RD16_IO_REG(ha, mailbox[0]) != MBS_BUSY) {
3390 			break;
3391 		}
3392 		drv_usecwait(MILLISEC);
3393 	}
3394 
3395 	/* restore bus master */
3396 	cmd = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_COMM);
3397 	cmd = (uint16_t)(cmd | PCI_COMM_ME);
3398 	ql_pci_config_put16(ha, PCI_CONF_COMM, cmd);
3399 
3400 	/* Disable RISC pause on FPM parity error. */
3401 	WRT16_IO_REG(ha, hccr, HC_DISABLE_PARITY_PAUSE);
3402 
3403 	/* Initialize probe registers */
3404 	if (CFG_IST(ha, CFG_SBUS_CARD)) {
3405 		/* Pause RISC. */
3406 		WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC);
3407 		for (cnt = 0; cnt < 30000; cnt++) {
3408 			if ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) != 0) {
3409 				break;
3410 			} else {
3411 				drv_usecwait(MILLISEC);
3412 			}
3413 		}
3414 
3415 		/* Select FPM registers. */
3416 		WRT16_IO_REG(ha, ctrl_status, 0x30);
3417 
3418 		/* Set probe register */
3419 		WRT16_IO_REG(ha, mailbox[23], 0x204c);
3420 
3421 		/* Select RISC module registers. */
3422 		WRT16_IO_REG(ha, ctrl_status, 0);
3423 
3424 		/* Release RISC module. */
3425 		WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
3426 	}
3427 
3428 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3429 }
3430 
3431 /*
3432  * ql_reset_24xx_chip
3433  *	Reset ISP24xx chip.
3434  *
3435  * Input:
3436  *	ha = adapter block pointer.
3437  *	All activity on chip must be already stopped.
3438  *
3439  * Context:
3440  *	Interrupt or Kernel context, no mailbox commands allowed.
3441  */
3442 void
3443 ql_reset_24xx_chip(ql_adapter_state_t *ha)
3444 {
3445 	uint32_t	timer, stat;
3446 
3447 	/* Shutdown DMA. */
3448 	WRT32_IO_REG(ha, ctrl_status, DMA_SHUTDOWN | MWB_4096_BYTES);
3449 
3450 	/* Wait for DMA to stop. */
3451 	for (timer = 0; timer < 30000; timer++) {
3452 		if ((RD32_IO_REG(ha, ctrl_status) & DMA_ACTIVE) == 0) {
3453 			break;
3454 		}
3455 		drv_usecwait(100);
3456 	}
3457 
3458 	/* Stop the firmware. */
3459 	WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
3460 	WRT16_IO_REG(ha, mailbox[0], MBC_STOP_FIRMWARE);
3461 	WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT);
3462 	for (timer = 0; timer < 30000; timer++) {
3463 		stat = RD32_IO_REG(ha, intr_info_lo);
3464 		if (stat & BIT_15) {
3465 			if ((stat & 0xff) < 0x12) {
3466 				WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
3467 				break;
3468 			}
3469 			WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
3470 		}
3471 		drv_usecwait(100);
3472 	}
3473 
3474 	/* Reset the chip. */
3475 	WRT32_IO_REG(ha, ctrl_status, ISP_RESET | DMA_SHUTDOWN |
3476 	    MWB_4096_BYTES);
3477 	drv_usecwait(100);
3478 
3479 	/* Wait for idle status from ROM firmware. */
3480 	for (timer = 0; timer < 30000; timer++) {
3481 		if (RD16_IO_REG(ha, mailbox[0]) == 0) {
3482 			break;
3483 		}
3484 		drv_usecwait(100);
3485 	}
3486 
3487 	/* Wait for reset to finish. */
3488 	for (timer = 0; timer < 30000; timer++) {
3489 		if ((RD32_IO_REG(ha, ctrl_status) & ISP_RESET) == 0) {
3490 			break;
3491 		}
3492 		drv_usecwait(100);
3493 	}
3494 
3495 	/* Insure mailbox registers are free. */
3496 	ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
3497 	    ~(MBX_BUSY_FLG | MBX_WANT_FLG | MBX_ABORT | MBX_INTERRUPT));
3498 	ha->mcp = NULL;
3499 
3500 	/*
3501 	 * Set flash write-protection.
3502 	 */
3503 	if ((ha->flags & ONLINE) == 0) {
3504 		ql_24xx_protect_flash(ha);
3505 	}
3506 }
3507 
3508 /*
3509  * ql_abort_isp
3510  *	Resets ISP and aborts all outstanding commands.
3511  *
3512  * Input:
3513  *	ha = adapter state pointer.
3514  *	DEVICE_QUEUE_LOCK must be released.
3515  *
3516  * Returns:
3517  *	ql local function return status code.
3518  *
3519  * Context:
3520  *	Kernel context.
3521  */
3522 int
3523 ql_abort_isp(ql_adapter_state_t *vha)
3524 {
3525 	ql_link_t		*link, *link2;
3526 	ddi_devstate_t		state;
3527 	uint16_t		index;
3528 	ql_tgt_t		*tq;
3529 	ql_lun_t		*lq;
3530 	ql_srb_t		*sp;
3531 	int			rval = QL_SUCCESS;
3532 	ql_adapter_state_t	*ha = vha->pha;
3533 
3534 	QL_PRINT_2(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
3535 
3536 	TASK_DAEMON_LOCK(ha);
3537 	ha->task_daemon_flags &= ~ISP_ABORT_NEEDED;
3538 	if (ha->task_daemon_flags & ABORT_ISP_ACTIVE ||
3539 	    (ha->flags & ONLINE) == 0 || ha->flags & ADAPTER_SUSPENDED) {
3540 		TASK_DAEMON_UNLOCK(ha);
3541 		return (rval);
3542 	}
3543 
3544 	ha->task_daemon_flags |= ABORT_ISP_ACTIVE;
3545 	ha->task_daemon_flags &= ~(RESET_MARKER_NEEDED | FIRMWARE_UP |
3546 	    FIRMWARE_LOADED);
3547 	for (vha = ha; vha != NULL; vha = vha->vp_next) {
3548 		vha->task_daemon_flags |= LOOP_DOWN;
3549 		vha->task_daemon_flags &= ~(COMMAND_WAIT_NEEDED |
3550 		    LOOP_RESYNC_NEEDED);
3551 	}
3552 
3553 	TASK_DAEMON_UNLOCK(ha);
3554 
3555 	if (ha->mailbox_flags & MBX_BUSY_FLG) {
3556 		/* Acquire mailbox register lock. */
3557 		MBX_REGISTER_LOCK(ha);
3558 
3559 		/* Wake up mailbox box routine. */
3560 		ha->mailbox_flags = (uint8_t)(ha->mailbox_flags | MBX_ABORT);
3561 		cv_broadcast(&ha->cv_mbx_intr);
3562 
3563 		/* Release mailbox register lock. */
3564 		MBX_REGISTER_UNLOCK(ha);
3565 
3566 		/* Wait for mailbox. */
3567 		for (index = 100; index &&
3568 		    ha->mailbox_flags & MBX_ABORT; index--) {
3569 			drv_usecwait(50000);
3570 		}
3571 	}
3572 
3573 	/* Wait for commands to end gracefully if not in panic. */
3574 	if (ha->flags & PARITY_ERROR) {
3575 		ADAPTER_STATE_LOCK(ha);
3576 		ha->flags &= ~PARITY_ERROR;
3577 		ADAPTER_STATE_UNLOCK(ha);
3578 	} else if (ddi_in_panic() == 0) {
3579 		ql_cmd_wait(ha);
3580 	}
3581 
3582 	/* Shutdown IP. */
3583 	if (ha->flags & IP_INITIALIZED) {
3584 		(void) ql_shutdown_ip(ha);
3585 	}
3586 
3587 	/* Reset the chip. */
3588 	ql_reset_chip(ha);
3589 
3590 	/* Place all commands in outstanding cmd list on device queue. */
3591 	for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
3592 		REQUEST_RING_LOCK(ha);
3593 		if ((link = ha->pending_cmds.first) != NULL) {
3594 			sp = link->base_address;
3595 			ql_remove_link(&ha->pending_cmds, &sp->cmd);
3596 
3597 			REQUEST_RING_UNLOCK(ha);
3598 			index = 0;
3599 		} else {
3600 			REQUEST_RING_UNLOCK(ha);
3601 			if ((sp = ha->outstanding_cmds[index]) == NULL) {
3602 				continue;
3603 			}
3604 		}
3605 
3606 		/* If command timeout. */
3607 		if (sp->flags & SRB_COMMAND_TIMEOUT) {
3608 			sp->pkt->pkt_reason = CS_TIMEOUT;
3609 			sp->flags &= ~SRB_RETRY;
3610 			sp->flags |= SRB_ISP_COMPLETED;
3611 
3612 			/* Call done routine to handle completion. */
3613 			ql_done(&sp->cmd);
3614 			continue;
3615 		}
3616 
3617 		ha->outstanding_cmds[index] = NULL;
3618 		sp->handle = 0;
3619 		sp->flags &= ~SRB_IN_TOKEN_ARRAY;
3620 
3621 		/* Acquire target queue lock. */
3622 		lq = sp->lun_queue;
3623 		tq = lq->target_queue;
3624 		DEVICE_QUEUE_LOCK(tq);
3625 
3626 		/* Reset watchdog time. */
3627 		sp->wdg_q_time = sp->init_wdg_q_time;
3628 
3629 		/* Place request back on top of device queue. */
3630 		sp->flags &= ~(SRB_ISP_STARTED | SRB_ISP_COMPLETED |
3631 		    SRB_RETRY);
3632 
3633 		ql_add_link_t(&lq->cmd, &sp->cmd);
3634 		sp->flags |= SRB_IN_DEVICE_QUEUE;
3635 
3636 		/* Release target queue lock. */
3637 		DEVICE_QUEUE_UNLOCK(tq);
3638 	}
3639 
3640 	/*
3641 	 * Clear per LUN active count, because there should not be
3642 	 * any IO outstanding at this time.
3643 	 */
3644 	for (vha = ha; vha != NULL; vha = vha->vp_next) {
3645 		for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
3646 			link = vha->dev[index].first;
3647 			while (link != NULL) {
3648 				tq = link->base_address;
3649 				link = link->next;
3650 				DEVICE_QUEUE_LOCK(tq);
3651 				tq->outcnt = 0;
3652 				tq->flags &= ~TQF_QUEUE_SUSPENDED;
3653 				for (link2 = tq->lun_queues.first;
3654 				    link2 != NULL; link2 = link2->next) {
3655 					lq = link2->base_address;
3656 					lq->lun_outcnt = 0;
3657 					lq->flags &= ~LQF_UNTAGGED_PENDING;
3658 				}
3659 				DEVICE_QUEUE_UNLOCK(tq);
3660 			}
3661 		}
3662 	}
3663 
3664 	if (ha->flags & TARGET_MODE_INITIALIZED) {
3665 		/* Enable Target Mode */
3666 		ha->init_ctrl_blk.cb.lun_enables[0] = (uint8_t)
3667 		    (ha->init_ctrl_blk.cb.lun_enables[0] | 0x01);
3668 		ha->init_ctrl_blk.cb.immediate_notify_resouce_count =
3669 		    ha->ub_notify_count;
3670 		ha->init_ctrl_blk.cb.command_resouce_count =
3671 		    ha->ub_command_count;
3672 	} else {
3673 		ha->init_ctrl_blk.cb.lun_enables[0] = 0;
3674 		ha->init_ctrl_blk.cb.lun_enables[1] = 0;
3675 		ha->init_ctrl_blk.cb.immediate_notify_resouce_count = 0;
3676 		ha->init_ctrl_blk.cb.command_resouce_count = 0;
3677 	}
3678 
3679 	rval = ql_chip_diag(ha);
3680 	if (rval == QL_SUCCESS) {
3681 		(void) ql_load_isp_firmware(ha);
3682 	}
3683 
3684 	if (rval == QL_SUCCESS && (rval = ql_set_cache_line(ha)) ==
3685 	    QL_SUCCESS && (rval = ql_init_rings(ha)) == QL_SUCCESS &&
3686 	    (rval = ql_fw_ready(ha, 10)) == QL_SUCCESS) {
3687 
3688 		/* If reset abort needed that may have been set. */
3689 		TASK_DAEMON_LOCK(ha);
3690 		ha->task_daemon_flags &= ~(ISP_ABORT_NEEDED |
3691 		    ABORT_ISP_ACTIVE);
3692 		TASK_DAEMON_UNLOCK(ha);
3693 
3694 		/* Enable ISP interrupts. */
3695 		CFG_IST(ha, CFG_CTRL_2425) ?
3696 		    WRT32_IO_REG(ha, ictrl, ISP_EN_RISC) :
3697 		    WRT16_IO_REG(ha, ictrl, ISP_EN_INT + ISP_EN_RISC);
3698 
3699 		ADAPTER_STATE_LOCK(ha);
3700 		ha->flags |= INTERRUPTS_ENABLED;
3701 		ADAPTER_STATE_UNLOCK(ha);
3702 
3703 		/* Set loop online, if it really is. */
3704 		ql_loop_online(ha);
3705 
3706 		state = ddi_get_devstate(ha->dip);
3707 		if (state != DDI_DEVSTATE_UP) {
3708 			/*EMPTY*/
3709 			ddi_dev_report_fault(ha->dip, DDI_SERVICE_RESTORED,
3710 			    DDI_DEVICE_FAULT, "Device reset succeeded");
3711 		}
3712 	} else {
3713 		/* Enable ISP interrupts. */
3714 		CFG_IST(ha, CFG_CTRL_2425) ?
3715 		    WRT32_IO_REG(ha, ictrl, ISP_EN_RISC) :
3716 		    WRT16_IO_REG(ha, ictrl, ISP_EN_INT + ISP_EN_RISC);
3717 
3718 		ADAPTER_STATE_LOCK(ha);
3719 		ha->flags |= INTERRUPTS_ENABLED;
3720 		ADAPTER_STATE_UNLOCK(ha);
3721 
3722 		TASK_DAEMON_LOCK(ha);
3723 		ha->task_daemon_flags &= ~(ISP_ABORT_NEEDED | ABORT_ISP_ACTIVE);
3724 		ha->task_daemon_flags |= LOOP_DOWN;
3725 		TASK_DAEMON_UNLOCK(ha);
3726 
3727 		ql_port_state(ha, FC_STATE_OFFLINE, FC_STATE_CHANGE);
3728 	}
3729 
3730 	if (rval != QL_SUCCESS) {
3731 		EL(ha, "failed, rval = %xh\n", rval);
3732 	} else {
3733 		/*EMPTY*/
3734 		QL_PRINT_2(CE_CONT, "(%d): done\n", ha->instance);
3735 	}
3736 	return (rval);
3737 }
3738 
3739 /*
3740  * ql_vport_control
3741  *	Issue Virtual Port Control command.
3742  *
3743  * Input:
3744  *	ha = virtual adapter state pointer.
3745  *	cmd = control command.
3746  *
3747  * Returns:
3748  *	ql local function return status code.
3749  *
3750  * Context:
3751  *	Kernel context.
3752  */
3753 int
3754 ql_vport_control(ql_adapter_state_t *ha, uint8_t cmd)
3755 {
3756 	ql_mbx_iocb_t	*pkt;
3757 	uint8_t		bit;
3758 	int		rval;
3759 	uint32_t	pkt_size;
3760 
3761 	QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
3762 
3763 	if (ha->vp_index != 0) {
3764 		pkt_size = sizeof (ql_mbx_iocb_t);
3765 		pkt = kmem_zalloc(pkt_size, KM_SLEEP);
3766 		if (pkt == NULL) {
3767 			EL(ha, "failed, kmem_zalloc\n");
3768 			return (QL_MEMORY_ALLOC_FAILED);
3769 		}
3770 
3771 		pkt->vpc.entry_type = VP_CONTROL_TYPE;
3772 		pkt->vpc.entry_count = 1;
3773 		pkt->vpc.command = cmd;
3774 		pkt->vpc.vp_count = 1;
3775 		bit = (uint8_t)(ha->vp_index - 1);
3776 		pkt->vpc.vp_index[bit / 8] = (uint8_t)
3777 		    (pkt->vpc.vp_index[bit / 8] | BIT_0 << bit % 8);
3778 
3779 		rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
3780 		if (rval == QL_SUCCESS && pkt->vpc.status != 0) {
3781 			rval = QL_COMMAND_ERROR;
3782 		}
3783 
3784 		kmem_free(pkt, pkt_size);
3785 	} else {
3786 		rval = QL_SUCCESS;
3787 	}
3788 
3789 	if (rval != QL_SUCCESS) {
3790 		EL(ha, "failed, rval = %xh\n", rval);
3791 	} else {
3792 		/*EMPTY*/
3793 		QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance,
3794 		    ha->vp_index);
3795 	}
3796 	return (rval);
3797 }
3798 
3799 /*
3800  * ql_vport_modify
3801  *	Issue of Modify Virtual Port command.
3802  *
3803  * Input:
3804  *	ha = virtual adapter state pointer.
3805  *	cmd = command.
3806  *	opt = option.
3807  *
3808  * Context:
3809  *	Interrupt or Kernel context, no mailbox commands allowed.
3810  */
3811 int
3812 ql_vport_modify(ql_adapter_state_t *ha, uint8_t cmd, uint8_t opt)
3813 {
3814 	ql_mbx_iocb_t	*pkt;
3815 	int		rval;
3816 	uint32_t	pkt_size;
3817 
3818 	QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
3819 
3820 	pkt_size = sizeof (ql_mbx_iocb_t);
3821 	pkt = kmem_zalloc(pkt_size, KM_SLEEP);
3822 	if (pkt == NULL) {
3823 		EL(ha, "failed, kmem_zalloc\n");
3824 		return (QL_MEMORY_ALLOC_FAILED);
3825 	}
3826 
3827 	pkt->vpm.entry_type = VP_MODIFY_TYPE;
3828 	pkt->vpm.entry_count = 1;
3829 	pkt->vpm.command = cmd;
3830 	pkt->vpm.vp_count = 1;
3831 	pkt->vpm.first_vp_index = ha->vp_index;
3832 	pkt->vpm.first_options = opt;
3833 	bcopy(ha->loginparams.nport_ww_name.raw_wwn, pkt->vpm.first_port_name,
3834 	    8);
3835 	bcopy(ha->loginparams.node_ww_name.raw_wwn, pkt->vpm.first_node_name,
3836 	    8);
3837 
3838 	rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
3839 	if (rval == QL_SUCCESS && pkt->vpm.status != 0) {
3840 		EL(ha, "failed, ql_issue_mbx_iocb=%xh, status=%xh\n", rval,
3841 		    pkt->vpm.status);
3842 		rval = QL_COMMAND_ERROR;
3843 	}
3844 
3845 	kmem_free(pkt, pkt_size);
3846 
3847 	if (rval != QL_SUCCESS) {
3848 		EL(ha, "failed, rval = %xh\n", rval);
3849 	} else {
3850 		/*EMPTY*/
3851 		QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance,
3852 		    ha->vp_index);
3853 	}
3854 	return (rval);
3855 }
3856 
3857 /*
3858  * ql_vport_enable
3859  *	Enable virtual port.
3860  *
3861  * Input:
3862  *	ha = virtual adapter state pointer.
3863  *
3864  * Context:
3865  *	Kernel context.
3866  */
3867 int
3868 ql_vport_enable(ql_adapter_state_t *ha)
3869 {
3870 	int	timer;
3871 
3872 	QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
3873 
3874 	ha->state = FC_PORT_SPEED_MASK(ha->state) | FC_STATE_OFFLINE;
3875 	TASK_DAEMON_LOCK(ha);
3876 	ha->task_daemon_flags |= LOOP_DOWN;
3877 	ha->task_daemon_flags &= ~(FC_STATE_CHANGE | STATE_ONLINE);
3878 	TASK_DAEMON_UNLOCK(ha);
3879 
3880 	ADAPTER_STATE_LOCK(ha);
3881 	ha->flags |= VP_ENABLED;
3882 	ADAPTER_STATE_UNLOCK(ha);
3883 
3884 	if (ql_vport_modify(ha, VPM_MODIFY_ENABLE, VPO_TARGET_MODE_DISABLED |
3885 	    VPO_INITIATOR_MODE_ENABLED | VPO_ENABLED) != QL_SUCCESS) {
3886 		QL_PRINT_2(CE_CONT, "(%d): failed to enable virtual port=%d\n",
3887 		    ha->instance, ha->vp_index);
3888 		return (QL_FUNCTION_FAILED);
3889 	}
3890 	if (!(ha->pha->task_daemon_flags & LOOP_DOWN)) {
3891 		/* Wait for loop to come up. */
3892 		for (timer = 0; timer < 3000 &&
3893 		    !(ha->task_daemon_flags & STATE_ONLINE);
3894 		    timer++) {
3895 			delay(1);
3896 		}
3897 	}
3898 
3899 	QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
3900 
3901 	return (QL_SUCCESS);
3902 }
3903 
3904 /*
3905  * ql_vport_create
3906  *	Create virtual port context.
3907  *
3908  * Input:
3909  *	ha:	parent adapter state pointer.
3910  *	index:	virtual port index number.
3911  *
3912  * Context:
3913  *	Kernel context.
3914  */
3915 ql_adapter_state_t *
3916 ql_vport_create(ql_adapter_state_t *ha, uint8_t index)
3917 {
3918 	ql_adapter_state_t	*vha;
3919 
3920 	QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
3921 
3922 	/* Inherit the parents data. */
3923 	vha = kmem_alloc(sizeof (ql_adapter_state_t), KM_SLEEP);
3924 
3925 	ADAPTER_STATE_LOCK(ha);
3926 	bcopy(ha, vha, sizeof (ql_adapter_state_t));
3927 	vha->pi_attrs = NULL;
3928 	vha->ub_outcnt = 0;
3929 	vha->ub_allocated = 0;
3930 	vha->flags = 0;
3931 	vha->task_daemon_flags = 0;
3932 	ha->vp_next = vha;
3933 	vha->pha = ha;
3934 	vha->vp_index = index;
3935 	ADAPTER_STATE_UNLOCK(ha);
3936 
3937 	vha->hba.next = NULL;
3938 	vha->hba.prev = NULL;
3939 	vha->hba.base_address = vha;
3940 	vha->state = FC_PORT_SPEED_MASK(ha->state) | FC_STATE_OFFLINE;
3941 	vha->dev = kmem_zalloc(sizeof (*vha->dev) * DEVICE_HEAD_LIST_SIZE,
3942 	    KM_SLEEP);
3943 	vha->ub_array = kmem_zalloc(sizeof (*vha->ub_array) * QL_UB_LIMIT,
3944 	    KM_SLEEP);
3945 
3946 	QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
3947 
3948 	return (vha);
3949 }
3950 
3951 /*
3952  * ql_vport_destroy
3953  *	Destroys virtual port context.
3954  *
3955  * Input:
3956  *	ha = virtual adapter state pointer.
3957  *
3958  * Context:
3959  *	Kernel context.
3960  */
3961 void
3962 ql_vport_destroy(ql_adapter_state_t *ha)
3963 {
3964 	ql_adapter_state_t	*vha;
3965 
3966 	QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
3967 
3968 	/* Remove port from list. */
3969 	ADAPTER_STATE_LOCK(ha);
3970 	for (vha = ha->pha; vha != NULL; vha = vha->vp_next) {
3971 		if (vha->vp_next == ha) {
3972 			vha->vp_next = ha->vp_next;
3973 			break;
3974 		}
3975 	}
3976 	ADAPTER_STATE_UNLOCK(ha);
3977 
3978 	if (ha->ub_array != NULL) {
3979 		kmem_free(ha->ub_array, sizeof (*ha->ub_array) * QL_UB_LIMIT);
3980 	}
3981 	if (ha->dev != NULL) {
3982 		kmem_free(ha->dev, sizeof (*vha->dev) * DEVICE_HEAD_LIST_SIZE);
3983 	}
3984 	kmem_free(ha, sizeof (ql_adapter_state_t));
3985 
3986 	QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
3987 }
3988