xref: /netbsd-src/sys/dev/ic/mpt.c (revision 23c8222edbfb0f0932d88a8351d3a0cf817dfb9e)
1 /*	$NetBSD: mpt.c,v 1.4 2003/11/02 11:07:45 wiz Exp $	*/
2 
3 /*
4  * Copyright (c) 2000, 2001 by Greg Ansley
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice immediately at the beginning of the file, without modification,
11  *    this list of conditions, and the following disclaimer.
12  * 2. The name of the author may not be used to endorse or promote products
13  *    derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
19  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 /*
28  * Additional Copyright (c) 2002 by Matthew Jacob under same license.
29  */
30 
31 /*
32  * mpt.c:
33  *
34  * Generic routines for LSI Fusion adapters.
35  *
36  * Adapted from the FreeBSD "mpt" driver by Jason R. Thorpe for
37  * Wasabi Systems, Inc.
38  */
39 
40 #include <sys/cdefs.h>
41 __KERNEL_RCSID(0, "$NetBSD: mpt.c,v 1.4 2003/11/02 11:07:45 wiz Exp $");
42 
43 #include <dev/ic/mpt.h>
44 
45 #define MPT_MAX_TRYS 3
46 #define MPT_MAX_WAIT 300000
47 
48 static int maxwait_ack = 0;
49 static int maxwait_int = 0;
50 static int maxwait_state = 0;
51 
52 static __inline u_int32_t
53 mpt_rd_db(mpt_softc_t *mpt)
54 {
55 	return mpt_read(mpt, MPT_OFFSET_DOORBELL);
56 }
57 
58 static __inline u_int32_t
59 mpt_rd_intr(mpt_softc_t *mpt)
60 {
61 	return mpt_read(mpt, MPT_OFFSET_INTR_STATUS);
62 }
63 
64 /* Busy wait for a door bell to be read by IOC */
65 static int
66 mpt_wait_db_ack(mpt_softc_t *mpt)
67 {
68 	int i;
69 	for (i=0; i < MPT_MAX_WAIT; i++) {
70 		if (!MPT_DB_IS_BUSY(mpt_rd_intr(mpt))) {
71 			maxwait_ack = i > maxwait_ack ? i : maxwait_ack;
72 			return MPT_OK;
73 		}
74 
75 		DELAY(100);
76 	}
77 	return MPT_FAIL;
78 }
79 
80 /* Busy wait for a door bell interrupt */
81 static int
82 mpt_wait_db_int(mpt_softc_t *mpt)
83 {
84 	int i;
85 	for (i=0; i < MPT_MAX_WAIT; i++) {
86 		if (MPT_DB_INTR(mpt_rd_intr(mpt))) {
87 			maxwait_int = i > maxwait_int ? i : maxwait_int;
88 			return MPT_OK;
89 		}
90 		DELAY(100);
91 	}
92 	return MPT_FAIL;
93 }
94 
95 /* Wait for IOC to transition to a give state */
96 void
97 mpt_check_doorbell(mpt_softc_t *mpt)
98 {
99 	u_int32_t db = mpt_rd_db(mpt);
100 	if (MPT_STATE(db) != MPT_DB_STATE_RUNNING) {
101 		mpt_prt(mpt, "Device not running");
102 		mpt_print_db(db);
103 	}
104 }
105 
106 /* Wait for IOC to transition to a give state */
107 static int
108 mpt_wait_state(mpt_softc_t *mpt, enum DB_STATE_BITS state)
109 {
110 	int i;
111 
112 	for (i = 0; i < MPT_MAX_WAIT; i++) {
113 		u_int32_t db = mpt_rd_db(mpt);
114 		if (MPT_STATE(db) == state) {
115 			maxwait_state = i > maxwait_state ? i : maxwait_state;
116 			return (MPT_OK);
117 		}
118 		DELAY(100);
119 	}
120 	return (MPT_FAIL);
121 }
122 
123 
124 /* Issue the reset COMMAND to the IOC */
125 int
126 mpt_soft_reset(mpt_softc_t *mpt)
127 {
128 	if (mpt->verbose) {
129 		mpt_prt(mpt, "soft reset");
130 	}
131 
132 	/* Have to use hard reset if we are not in Running state */
133 	if (MPT_STATE(mpt_rd_db(mpt)) != MPT_DB_STATE_RUNNING) {
134 		mpt_prt(mpt, "soft reset failed: device not running");
135 		return MPT_FAIL;
136 	}
137 
138 	/* If door bell is in use we don't have a chance of getting
139 	 * a word in since the IOC probably crashed in message
140 	 * processing. So don't waste our time.
141 	 */
142 	if (MPT_DB_IS_IN_USE(mpt_rd_db(mpt))) {
143 		mpt_prt(mpt, "soft reset failed: doorbell wedged");
144 		return MPT_FAIL;
145 	}
146 
147 	/* Send the reset request to the IOC */
148 	mpt_write(mpt, MPT_OFFSET_DOORBELL,
149 	    MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET << MPI_DOORBELL_FUNCTION_SHIFT);
150 	if (mpt_wait_db_ack(mpt) != MPT_OK) {
151 		mpt_prt(mpt, "soft reset failed: ack timeout");
152 		return MPT_FAIL;
153 	}
154 
155 	/* Wait for the IOC to reload and come out of reset state */
156 	if (mpt_wait_state(mpt, MPT_DB_STATE_READY) != MPT_OK) {
157 		mpt_prt(mpt, "soft reset failed: device did not start running");
158 		return MPT_FAIL;
159 	}
160 
161 	return MPT_OK;
162 }
163 
164 /* This is a magic diagnostic reset that resets all the ARM
165  * processors in the chip.
166  */
167 void
168 mpt_hard_reset(mpt_softc_t *mpt)
169 {
170 	/* This extra read comes for the Linux source
171 	 * released by LSI. It's function is undocumented!
172 	 */
173 	if (mpt->verbose) {
174 		mpt_prt(mpt, "hard reset");
175 	}
176 	mpt_read(mpt, MPT_OFFSET_FUBAR);
177 
178 	/* Enable diagnostic registers */
179 	mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_1);
180 	mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_2);
181 	mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_3);
182 	mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_4);
183 	mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_5);
184 
185 	/* Diag. port is now active so we can now hit the reset bit */
186 	mpt_write(mpt, MPT_OFFSET_DIAGNOSTIC, MPT_DIAG_RESET_IOC);
187 
188 	DELAY(10000);
189 
190 	/* Disable Diagnostic Register */
191 	mpt_write(mpt, MPT_OFFSET_SEQUENCE, 0xFF);
192 
193 	/* Restore the config register values */
194 	/*   Hard resets are known to screw up the BAR for diagnostic
195 	     memory accesses (Mem1). */
196 	mpt_set_config_regs(mpt);
197 	if (mpt->mpt2 != NULL) {
198 		mpt_set_config_regs(mpt->mpt2);
199 	}
200 
201 	/* Note that if there is no valid firmware to run, the doorbell will
202 	   remain in the reset state (0x00000000) */
203 }
204 
205 /*
206  * Reset the IOC when needed. Try software command first then if needed
207  * poke at the magic diagnostic reset. Note that a hard reset resets
208  * *both* IOCs on dual function chips (FC929 && LSI1030) as well as
209  * fouls up the PCI configuration registers.
210  */
211 int
212 mpt_reset(mpt_softc_t *mpt)
213 {
214 	int ret;
215 
216 	/* Try a soft reset */
217 	if ((ret = mpt_soft_reset(mpt)) != MPT_OK) {
218 		/* Failed; do a hard reset */
219 		mpt_hard_reset(mpt);
220 
221 		/* Wait for the IOC to reload and come out of reset state */
222 		ret = mpt_wait_state(mpt, MPT_DB_STATE_READY);
223 		if (ret != MPT_OK) {
224 			mpt_prt(mpt, "failed to reset device");
225 		}
226 	}
227 
228 	return ret;
229 }
230 
231 /* Return a command buffer to the free queue */
232 void
233 mpt_free_request(mpt_softc_t *mpt, request_t *req)
234 {
235 	if (req == NULL || req != &mpt->request_pool[req->index]) {
236 		panic("mpt_free_request bad req ptr\n");
237 		return;
238 	}
239 	req->sequence = 0;
240 	req->xfer = NULL;
241 	req->debug = REQ_FREE;
242 	SLIST_INSERT_HEAD(&mpt->request_free_list, req, link);
243 }
244 
245 /* Get a command buffer from the free queue */
246 request_t *
247 mpt_get_request(mpt_softc_t *mpt)
248 {
249 	request_t *req;
250 	req = SLIST_FIRST(&mpt->request_free_list);
251 	if (req != NULL) {
252 		if (req != &mpt->request_pool[req->index]) {
253 			panic("mpt_get_request: corrupted request free list\n");
254 		}
255 		if (req->xfer != NULL) {
256 			panic("mpt_get_request: corrupted request free list (xfer)\n");
257 		}
258 		SLIST_REMOVE_HEAD(&mpt->request_free_list, link);
259 		req->debug = REQ_IN_PROGRESS;
260 	}
261 	return req;
262 }
263 
264 /* Pass the command to the IOC */
265 void
266 mpt_send_cmd(mpt_softc_t *mpt, request_t *req)
267 {
268 	req->sequence = mpt->sequence++;
269 	if (mpt->verbose > 1) {
270 		u_int32_t *pReq;
271 		pReq = req->req_vbuf;
272 		mpt_prt(mpt, "Send Request %d (0x%x):",
273 		    req->index, req->req_pbuf);
274 		mpt_prt(mpt, "%08x %08x %08x %08x",
275 		    pReq[0], pReq[1], pReq[2], pReq[3]);
276 		mpt_prt(mpt, "%08x %08x %08x %08x",
277 		    pReq[4], pReq[5], pReq[6], pReq[7]);
278 		mpt_prt(mpt, "%08x %08x %08x %08x",
279 		    pReq[8], pReq[9], pReq[10], pReq[11]);
280 		mpt_prt(mpt, "%08x %08x %08x %08x",
281 		    pReq[12], pReq[13], pReq[14], pReq[15]);
282 	}
283 	MPT_SYNC_REQ(mpt, req, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
284 	req->debug = REQ_ON_CHIP;
285 	mpt_write(mpt, MPT_OFFSET_REQUEST_Q, (u_int32_t) req->req_pbuf);
286 }
287 
288 /*
289  * Give the reply buffer back to the IOC after we have
290  * finished processing it.
291  */
292 void
293 mpt_free_reply(mpt_softc_t *mpt, u_int32_t ptr)
294 {
295      mpt_write(mpt, MPT_OFFSET_REPLY_Q, ptr);
296 }
297 
298 /* Get a reply from the IOC */
299 u_int32_t
300 mpt_pop_reply_queue(mpt_softc_t *mpt)
301 {
302      return mpt_read(mpt, MPT_OFFSET_REPLY_Q);
303 }
304 
305 /*
306  * Send a command to the IOC via the handshake register.
307  *
308  * Only done at initialization time and for certain unusual
309  * commands such as device/bus reset as specified by LSI.
310  */
311 int
312 mpt_send_handshake_cmd(mpt_softc_t *mpt, size_t len, void *cmd)
313 {
314 	int i;
315 	u_int32_t data, *data32;
316 
317 	/* Check condition of the IOC */
318 	data = mpt_rd_db(mpt);
319 	if (((MPT_STATE(data) != MPT_DB_STATE_READY)	&&
320 	     (MPT_STATE(data) != MPT_DB_STATE_RUNNING)	&&
321 	     (MPT_STATE(data) != MPT_DB_STATE_FAULT))	||
322 	    (  MPT_DB_IS_IN_USE(data) )) {
323 		mpt_prt(mpt, "handshake aborted due to invalid doorbell state");
324 		mpt_print_db(data);
325 		return(EBUSY);
326 	}
327 
328 	/* We move things in 32 bit chunks */
329 	len = (len + 3) >> 2;
330 	data32 = cmd;
331 
332 	/* Clear any left over pending doorbell interrupts */
333 	if (MPT_DB_INTR(mpt_rd_intr(mpt)))
334 		mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
335 
336 	/*
337 	 * Tell the handshake reg. we are going to send a command
338          * and how long it is going to be.
339 	 */
340 	data = (MPI_FUNCTION_HANDSHAKE << MPI_DOORBELL_FUNCTION_SHIFT) |
341 	    (len << MPI_DOORBELL_ADD_DWORDS_SHIFT);
342 	mpt_write(mpt, MPT_OFFSET_DOORBELL, data);
343 
344 	/* Wait for the chip to notice */
345 	if (mpt_wait_db_int(mpt) != MPT_OK) {
346 		mpt_prt(mpt, "mpt_send_handshake_cmd timeout1");
347 		return ETIMEDOUT;
348 	}
349 
350 	/* Clear the interrupt */
351 	mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
352 
353 	if (mpt_wait_db_ack(mpt) != MPT_OK) {
354 		mpt_prt(mpt, "mpt_send_handshake_cmd timeout2");
355 		return ETIMEDOUT;
356 	}
357 
358 	/* Send the command */
359 	for (i = 0; i < len; i++) {
360 		mpt_write(mpt, MPT_OFFSET_DOORBELL, *data32++);
361 		if (mpt_wait_db_ack(mpt) != MPT_OK) {
362 			mpt_prt(mpt,
363 			    "mpt_send_handshake_cmd timeout! index = %d", i);
364 			return ETIMEDOUT;
365 		}
366 	}
367 	return MPT_OK;
368 }
369 
370 /* Get the response from the handshake register */
371 int
372 mpt_recv_handshake_reply(mpt_softc_t *mpt, size_t reply_len, void *reply)
373 {
374 	int left, reply_left;
375 	u_int16_t *data16;
376 	MSG_DEFAULT_REPLY *hdr;
377 
378 	/* We move things out in 16 bit chunks */
379 	reply_len >>= 1;
380 	data16 = (u_int16_t *)reply;
381 
382 	hdr = (MSG_DEFAULT_REPLY *)reply;
383 
384 	/* Get first word */
385 	if (mpt_wait_db_int(mpt) != MPT_OK) {
386 		mpt_prt(mpt, "mpt_recv_handshake_cmd timeout1");
387 		return ETIMEDOUT;
388 	}
389 	*data16++ = mpt_read(mpt, MPT_OFFSET_DOORBELL) & MPT_DB_DATA_MASK;
390 	mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
391 
392 	/* Get Second Word */
393 	if (mpt_wait_db_int(mpt) != MPT_OK) {
394 		mpt_prt(mpt, "mpt_recv_handshake_cmd timeout2");
395 		return ETIMEDOUT;
396 	}
397 	*data16++ = mpt_read(mpt, MPT_OFFSET_DOORBELL) & MPT_DB_DATA_MASK;
398 	mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
399 
400 	/* With the second word, we can now look at the length */
401 	if (mpt->verbose > 1 && ((reply_len >> 1) != hdr->MsgLength)) {
402 		mpt_prt(mpt, "reply length does not match message length: "
403 			"got 0x%02x, expected 0x%02x",
404 			hdr->MsgLength << 2, reply_len << 1);
405 	}
406 
407 	/* Get rest of the reply; but don't overflow the provided buffer */
408 	left = (hdr->MsgLength << 1) - 2;
409 	reply_left =  reply_len - 2;
410 	while (left--) {
411 		u_int16_t datum;
412 
413 		if (mpt_wait_db_int(mpt) != MPT_OK) {
414 			mpt_prt(mpt, "mpt_recv_handshake_cmd timeout3");
415 			return ETIMEDOUT;
416 		}
417 		datum = mpt_read(mpt, MPT_OFFSET_DOORBELL);
418 
419 		if (reply_left-- > 0)
420 			*data16++ = datum & MPT_DB_DATA_MASK;
421 
422 		mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
423 	}
424 
425 	/* One more wait & clear at the end */
426 	if (mpt_wait_db_int(mpt) != MPT_OK) {
427 		mpt_prt(mpt, "mpt_recv_handshake_cmd timeout4");
428 		return ETIMEDOUT;
429 	}
430 	mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
431 
432 	if ((hdr->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
433 		if (mpt->verbose > 1)
434 			mpt_print_reply(hdr);
435 		return (MPT_FAIL | hdr->IOCStatus);
436 	}
437 
438 	return (0);
439 }
440 
441 static int
442 mpt_get_iocfacts(mpt_softc_t *mpt, MSG_IOC_FACTS_REPLY *freplp)
443 {
444 	MSG_IOC_FACTS f_req;
445 	int error;
446 
447 	bzero(&f_req, sizeof f_req);
448 	f_req.Function = MPI_FUNCTION_IOC_FACTS;
449 	f_req.MsgContext =  0x12071942;
450 	error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req);
451 	if (error)
452 		return(error);
453 	error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp);
454 	return (error);
455 }
456 
457 static int
458 mpt_get_portfacts(mpt_softc_t *mpt, MSG_PORT_FACTS_REPLY *freplp)
459 {
460 	MSG_PORT_FACTS f_req;
461 	int error;
462 
463 	/* XXX: Only getting PORT FACTS for Port 0 */
464 	bzero(&f_req, sizeof f_req);
465 	f_req.Function = MPI_FUNCTION_PORT_FACTS;
466 	f_req.MsgContext =  0x12071943;
467 	error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req);
468 	if (error)
469 		return(error);
470 	error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp);
471 	return (error);
472 }
473 
474 /*
475  * Send the initialization request. This is where we specify how many
476  * SCSI busses and how many devices per bus we wish to emulate.
477  * This is also the command that specifies the max size of the reply
478  * frames from the IOC that we will be allocating.
479  */
480 static int
481 mpt_send_ioc_init(mpt_softc_t *mpt, u_int32_t who)
482 {
483 	int error = 0;
484 	MSG_IOC_INIT init;
485 	MSG_IOC_INIT_REPLY reply;
486 
487 	bzero(&init, sizeof init);
488 	init.WhoInit = who;
489 	init.Function = MPI_FUNCTION_IOC_INIT;
490 	if (mpt->is_fc) {
491 		init.MaxDevices = 255;
492 	} else {
493 		init.MaxDevices = 16;
494 	}
495 	init.MaxBuses = 1;
496 	init.ReplyFrameSize = MPT_REPLY_SIZE;
497 	init.MsgContext = 0x12071941;
498 
499 	if ((error = mpt_send_handshake_cmd(mpt, sizeof init, &init)) != 0) {
500 		return(error);
501 	}
502 
503 	error = mpt_recv_handshake_reply(mpt, sizeof reply, &reply);
504 	return (error);
505 }
506 
507 
508 /*
509  * Utiltity routine to read configuration headers and pages
510  */
511 
512 static int
513 mpt_read_cfg_header(mpt_softc_t *, int, int, int, fCONFIG_PAGE_HEADER *);
514 
515 static int
516 mpt_read_cfg_header(mpt_softc_t *mpt, int PageType, int PageNumber,
517     int PageAddress, fCONFIG_PAGE_HEADER *rslt)
518 {
519 	int count;
520 	request_t *req;
521 	MSG_CONFIG *cfgp;
522 	MSG_CONFIG_REPLY *reply;
523 
524 	req = mpt_get_request(mpt);
525 
526 	cfgp = req->req_vbuf;
527 	bzero(cfgp, sizeof *cfgp);
528 
529 	cfgp->Action = MPI_CONFIG_ACTION_PAGE_HEADER;
530 	cfgp->Function = MPI_FUNCTION_CONFIG;
531 	cfgp->Header.PageNumber = (U8) PageNumber;
532 	cfgp->Header.PageType = (U8) PageType;
533 	cfgp->PageAddress = PageAddress;
534 	MPI_pSGE_SET_FLAGS(((SGE_SIMPLE32 *) &cfgp->PageBufferSGE),
535 	    (MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
536 	    MPI_SGE_FLAGS_SIMPLE_ELEMENT | MPI_SGE_FLAGS_END_OF_LIST));
537 	cfgp->MsgContext = req->index | 0x80000000;
538 
539 	mpt_check_doorbell(mpt);
540 	mpt_send_cmd(mpt, req);
541 	count = 0;
542 	do {
543 		DELAY(500);
544 		mpt_intr(mpt);
545 		if (++count == 1000) {
546 			mpt_prt(mpt, "read_cfg_header timed out");
547 			return (-1);
548 		}
549 	} while (req->debug == REQ_ON_CHIP);
550 
551 	reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
552         if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
553 		mpt_prt(mpt, "mpt_read_cfg_header: Config Info Status %x",
554 		    reply->IOCStatus);
555 		mpt_free_reply(mpt, (req->sequence << 1));
556 		return (-1);
557 	}
558 	bcopy(&reply->Header, rslt, sizeof (fCONFIG_PAGE_HEADER));
559 	mpt_free_reply(mpt, (req->sequence << 1));
560 	mpt_free_request(mpt, req);
561 	return (0);
562 }
563 
564 #define	CFG_DATA_OFF	128
565 
566 int
567 mpt_read_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr)
568 {
569 	int count;
570 	request_t *req;
571 	SGE_SIMPLE32 *se;
572 	MSG_CONFIG *cfgp;
573 	size_t amt;
574 	MSG_CONFIG_REPLY *reply;
575 
576 	req = mpt_get_request(mpt);
577 
578 	cfgp = req->req_vbuf;
579 	bzero(cfgp, MPT_REQUEST_AREA);
580 	cfgp->Action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
581 	cfgp->Function = MPI_FUNCTION_CONFIG;
582 	cfgp->Header = *hdr;
583  	amt = (cfgp->Header.PageLength * sizeof (u_int32_t));
584 	cfgp->Header.PageType &= MPI_CONFIG_PAGETYPE_MASK;
585 	cfgp->PageAddress = PageAddress;
586 	se = (SGE_SIMPLE32 *) &cfgp->PageBufferSGE;
587 	se->Address = req->req_pbuf + CFG_DATA_OFF;
588 	MPI_pSGE_SET_LENGTH(se, amt);
589 	MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
590 	    MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
591 	    MPI_SGE_FLAGS_END_OF_LIST));
592 
593 	cfgp->MsgContext = req->index | 0x80000000;
594 
595 	mpt_check_doorbell(mpt);
596 	mpt_send_cmd(mpt, req);
597 	count = 0;
598 	do {
599 		DELAY(500);
600 		mpt_intr(mpt);
601 		if (++count == 1000) {
602 			mpt_prt(mpt, "read_cfg_page timed out");
603 			return (-1);
604 		}
605 	} while (req->debug == REQ_ON_CHIP);
606 
607 	reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
608         if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
609 		mpt_prt(mpt, "mpt_read_cfg_page: Config Info Status %x",
610 		    reply->IOCStatus);
611 		mpt_free_reply(mpt, (req->sequence << 1));
612 		return (-1);
613 	}
614 	mpt_free_reply(mpt, (req->sequence << 1));
615 #if 0 /* XXXJRT */
616 	bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap,
617 	    BUS_DMASYNC_POSTREAD);
618 #endif
619 	if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
620 	    cfgp->Header.PageNumber == 0) {
621 		amt = sizeof (fCONFIG_PAGE_SCSI_PORT_0);
622 	} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
623 	    cfgp->Header.PageNumber == 1) {
624 		amt = sizeof (fCONFIG_PAGE_SCSI_PORT_1);
625 	} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
626 	    cfgp->Header.PageNumber == 2) {
627 		amt = sizeof (fCONFIG_PAGE_SCSI_PORT_2);
628 	} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE  &&
629 	    cfgp->Header.PageNumber == 0) {
630 		amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_0);
631 	} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE  &&
632 	    cfgp->Header.PageNumber == 1) {
633 		amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_1);
634 	}
635 	bcopy(((caddr_t)req->req_vbuf)+CFG_DATA_OFF, hdr, amt);
636 	mpt_free_request(mpt, req);
637 	return (0);
638 }
639 
640 int
641 mpt_write_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr)
642 {
643 	int count, hdr_attr;
644 	request_t *req;
645 	SGE_SIMPLE32 *se;
646 	MSG_CONFIG *cfgp;
647 	size_t amt;
648 	MSG_CONFIG_REPLY *reply;
649 
650 	req = mpt_get_request(mpt);
651 
652 	cfgp = req->req_vbuf;
653 	bzero(cfgp, sizeof *cfgp);
654 
655 	hdr_attr = hdr->PageType & MPI_CONFIG_PAGEATTR_MASK;
656 	if (hdr_attr != MPI_CONFIG_PAGEATTR_CHANGEABLE &&
657 	    hdr_attr != MPI_CONFIG_PAGEATTR_PERSISTENT) {
658 		mpt_prt(mpt, "page type 0x%x not changeable",
659 		    hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
660 		return (-1);
661 	}
662 	hdr->PageType &= MPI_CONFIG_PAGETYPE_MASK;
663 
664 	cfgp->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
665 	cfgp->Function = MPI_FUNCTION_CONFIG;
666 	cfgp->Header = *hdr;
667  	amt = (cfgp->Header.PageLength * sizeof (u_int32_t));
668 	cfgp->PageAddress = PageAddress;
669 
670 	se = (SGE_SIMPLE32 *) &cfgp->PageBufferSGE;
671 	se->Address = req->req_pbuf + CFG_DATA_OFF;
672 	MPI_pSGE_SET_LENGTH(se, amt);
673 	MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
674 	    MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
675 	    MPI_SGE_FLAGS_END_OF_LIST | MPI_SGE_FLAGS_HOST_TO_IOC));
676 
677 	cfgp->MsgContext = req->index | 0x80000000;
678 
679 	if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
680 	    cfgp->Header.PageNumber == 0) {
681 		amt = sizeof (fCONFIG_PAGE_SCSI_PORT_0);
682 	} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
683 	    cfgp->Header.PageNumber == 1) {
684 		amt = sizeof (fCONFIG_PAGE_SCSI_PORT_1);
685 	} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
686 	    cfgp->Header.PageNumber == 2) {
687 		amt = sizeof (fCONFIG_PAGE_SCSI_PORT_2);
688 	} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE  &&
689 	    cfgp->Header.PageNumber == 0) {
690 		amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_0);
691 	} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE  &&
692 	    cfgp->Header.PageNumber == 1) {
693 		amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_1);
694 	}
695 	bcopy(hdr, ((caddr_t)req->req_vbuf)+CFG_DATA_OFF, amt);
696 	/* Restore stripped out attributes */
697 	hdr->PageType |= hdr_attr;
698 
699 	mpt_check_doorbell(mpt);
700 	mpt_send_cmd(mpt, req);
701 	count = 0;
702 	do {
703 		DELAY(500);
704 		mpt_intr(mpt);
705 		if (++count == 1000) {
706 			hdr->PageType |= hdr_attr;
707 			mpt_prt(mpt, "mpt_write_cfg_page timed out");
708 			return (-1);
709 		}
710 	} while (req->debug == REQ_ON_CHIP);
711 
712 	reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
713         if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
714 		mpt_prt(mpt, "mpt_write_cfg_page: Config Info Status %x",
715 		    reply->IOCStatus);
716 		mpt_free_reply(mpt, (req->sequence << 1));
717 		return (-1);
718 	}
719 	mpt_free_reply(mpt, (req->sequence << 1));
720 
721 	mpt_free_request(mpt, req);
722 	return (0);
723 }
724 
725 /*
726  * Read SCSI configuration information
727  */
728 static int
729 mpt_read_config_info_spi(mpt_softc_t *mpt)
730 {
731 	int rv, i;
732 
733 	rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 0,
734 	    0, &mpt->mpt_port_page0.Header);
735 	if (rv) {
736 		return (-1);
737 	}
738 	if (mpt->verbose > 1) {
739 		mpt_prt(mpt, "SPI Port Page 0 Header: %x %x %x %x",
740 		    mpt->mpt_port_page0.Header.PageVersion,
741 		    mpt->mpt_port_page0.Header.PageLength,
742 		    mpt->mpt_port_page0.Header.PageNumber,
743 		    mpt->mpt_port_page0.Header.PageType);
744 	}
745 
746 	rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 1,
747 	    0, &mpt->mpt_port_page1.Header);
748 	if (rv) {
749 		return (-1);
750 	}
751 	if (mpt->verbose > 1) {
752 		mpt_prt(mpt, "SPI Port Page 1 Header: %x %x %x %x",
753 		    mpt->mpt_port_page1.Header.PageVersion,
754 		    mpt->mpt_port_page1.Header.PageLength,
755 		    mpt->mpt_port_page1.Header.PageNumber,
756 		    mpt->mpt_port_page1.Header.PageType);
757 	}
758 
759 	rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 2,
760 	    0, &mpt->mpt_port_page2.Header);
761 	if (rv) {
762 		return (-1);
763 	}
764 
765 	if (mpt->verbose > 1) {
766 		mpt_prt(mpt, "SPI Port Page 2 Header: %x %x %x %x",
767 		    mpt->mpt_port_page1.Header.PageVersion,
768 		    mpt->mpt_port_page1.Header.PageLength,
769 		    mpt->mpt_port_page1.Header.PageNumber,
770 		    mpt->mpt_port_page1.Header.PageType);
771 	}
772 
773 	for (i = 0; i < 16; i++) {
774 		rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
775 		    0, i, &mpt->mpt_dev_page0[i].Header);
776 		if (rv) {
777 			return (-1);
778 		}
779 		if (mpt->verbose > 1) {
780 			mpt_prt(mpt,
781 			    "SPI Target %d Device Page 0 Header: %x %x %x %x",
782 			    i, mpt->mpt_dev_page0[i].Header.PageVersion,
783 			    mpt->mpt_dev_page0[i].Header.PageLength,
784 			    mpt->mpt_dev_page0[i].Header.PageNumber,
785 			    mpt->mpt_dev_page0[i].Header.PageType);
786 		}
787 
788 		rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
789 		    1, i, &mpt->mpt_dev_page1[i].Header);
790 		if (rv) {
791 			return (-1);
792 		}
793 		if (mpt->verbose > 1) {
794 			mpt_prt(mpt,
795 			    "SPI Target %d Device Page 1 Header: %x %x %x %x",
796 			    i, mpt->mpt_dev_page1[i].Header.PageVersion,
797 			    mpt->mpt_dev_page1[i].Header.PageLength,
798 			    mpt->mpt_dev_page1[i].Header.PageNumber,
799 			    mpt->mpt_dev_page1[i].Header.PageType);
800 		}
801 	}
802 
803 	/*
804 	 * At this point, we don't *have* to fail. As long as we have
805 	 * valid config header information, we can (barely) lurch
806 	 * along.
807 	 */
808 
809 	rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page0.Header);
810 	if (rv) {
811 		mpt_prt(mpt, "failed to read SPI Port Page 0");
812 	} else if (mpt->verbose > 1) {
813 		mpt_prt(mpt,
814 		    "SPI Port Page 0: Capabilities %x PhysicalInterface %x",
815 		    mpt->mpt_port_page0.Capabilities,
816 		    mpt->mpt_port_page0.PhysicalInterface);
817 	}
818 
819 	rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page1.Header);
820 	if (rv) {
821 		mpt_prt(mpt, "failed to read SPI Port Page 1");
822 	} else if (mpt->verbose > 1) {
823 		mpt_prt(mpt,
824 		    "SPI Port Page 1: Configuration %x OnBusTimerValue %x",
825 		    mpt->mpt_port_page1.Configuration,
826 		    mpt->mpt_port_page1.OnBusTimerValue);
827 	}
828 
829 	rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page2.Header);
830 	if (rv) {
831 		mpt_prt(mpt, "failed to read SPI Port Page 2");
832 	} else if (mpt->verbose > 1) {
833 		mpt_prt(mpt,
834 		    "SPI Port Page 2: Flags %x Settings %x",
835 		    mpt->mpt_port_page2.PortFlags,
836 		    mpt->mpt_port_page2.PortSettings);
837 		for (i = 0; i < 16; i++) {
838 			mpt_prt(mpt,
839 		  	    "SPI Port Page 2 Tgt %d: timo %x SF %x Flags %x",
840 			    i, mpt->mpt_port_page2.DeviceSettings[i].Timeout,
841 			    mpt->mpt_port_page2.DeviceSettings[i].SyncFactor,
842 			    mpt->mpt_port_page2.DeviceSettings[i].DeviceFlags);
843 		}
844 	}
845 
846 	for (i = 0; i < 16; i++) {
847 		rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page0[i].Header);
848 		if (rv) {
849 			mpt_prt(mpt, "cannot read SPI Tgt %d Device Page 0", i);
850 			continue;
851 		}
852 		if (mpt->verbose > 1) {
853 			mpt_prt(mpt,
854 			    "SPI Tgt %d Page 0: NParms %x Information %x",
855 			    i, mpt->mpt_dev_page0[i].NegotiatedParameters,
856 			    mpt->mpt_dev_page0[i].Information);
857 		}
858 		rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page1[i].Header);
859 		if (rv) {
860 			mpt_prt(mpt, "cannot read SPI Tgt %d Device Page 1", i);
861 			continue;
862 		}
863 		if (mpt->verbose > 1) {
864 			mpt_prt(mpt,
865 			    "SPI Tgt %d Page 1: RParms %x Configuration %x",
866 			    i, mpt->mpt_dev_page1[i].RequestedParameters,
867 			    mpt->mpt_dev_page1[i].Configuration);
868 		}
869 	}
870 	return (0);
871 }
872 
873 /*
874  * Validate SPI configuration information.
875  *
876  * In particular, validate SPI Port Page 1.
877  */
878 static int
879 mpt_set_initial_config_spi(mpt_softc_t *mpt)
880 {
881 	int i, pp1val = ((1 << mpt->mpt_ini_id) << 16) | mpt->mpt_ini_id;
882 
883 	mpt->mpt_disc_enable = 0xff;
884 	mpt->mpt_tag_enable = 0;
885 
886 	if (mpt->mpt_port_page1.Configuration != pp1val) {
887 		fCONFIG_PAGE_SCSI_PORT_1 tmp;
888 		mpt_prt(mpt,
889 		    "SPI Port Page 1 Config value bad (%x)- should be %x",
890 		    mpt->mpt_port_page1.Configuration, pp1val);
891 		tmp = mpt->mpt_port_page1;
892 		tmp.Configuration = pp1val;
893 		if (mpt_write_cfg_page(mpt, 0, &tmp.Header)) {
894 			return (-1);
895 		}
896 		if (mpt_read_cfg_page(mpt, 0, &tmp.Header)) {
897 			return (-1);
898 		}
899 		if (tmp.Configuration != pp1val) {
900 			mpt_prt(mpt,
901 			    "failed to reset SPI Port Page 1 Config value");
902 			return (-1);
903 		}
904 		mpt->mpt_port_page1 = tmp;
905 	}
906 
907 	for (i = 0; i < 16; i++) {
908 		fCONFIG_PAGE_SCSI_DEVICE_1 tmp;
909 		tmp = mpt->mpt_dev_page1[i];
910 		tmp.RequestedParameters = 0;
911 		tmp.Configuration = 0;
912 		if (mpt->verbose > 1) {
913 			mpt_prt(mpt,
914 			    "Set Tgt %d SPI DevicePage 1 values to %x 0 %x",
915 			    i, tmp.RequestedParameters, tmp.Configuration);
916 		}
917 		if (mpt_write_cfg_page(mpt, i, &tmp.Header)) {
918 			return (-1);
919 		}
920 		if (mpt_read_cfg_page(mpt, i, &tmp.Header)) {
921 			return (-1);
922 		}
923 		mpt->mpt_dev_page1[i] = tmp;
924 		if (mpt->verbose > 1) {
925 			mpt_prt(mpt,
926 		 	    "SPI Tgt %d Page 1: RParm %x Configuration %x", i,
927 			    mpt->mpt_dev_page1[i].RequestedParameters,
928 			    mpt->mpt_dev_page1[i].Configuration);
929 		}
930 	}
931 	return (0);
932 }
933 
934 /*
935  * Enable IOC port
936  */
937 static int
938 mpt_send_port_enable(mpt_softc_t *mpt, int port)
939 {
940 	int count;
941 	request_t *req;
942 	MSG_PORT_ENABLE *enable_req;
943 
944 	req = mpt_get_request(mpt);
945 
946 	enable_req = req->req_vbuf;
947 	bzero(enable_req, sizeof *enable_req);
948 
949 	enable_req->Function   = MPI_FUNCTION_PORT_ENABLE;
950 	enable_req->MsgContext = req->index | 0x80000000;
951 	enable_req->PortNumber = port;
952 
953 	mpt_check_doorbell(mpt);
954 	if (mpt->verbose > 1) {
955 		mpt_prt(mpt, "enabling port %d", port);
956 	}
957 	mpt_send_cmd(mpt, req);
958 
959 	count = 0;
960 	do {
961 		DELAY(500);
962 		mpt_intr(mpt);
963 		if (++count == 100000) {
964 			mpt_prt(mpt, "port enable timed out");
965 			return (-1);
966 		}
967 	} while (req->debug == REQ_ON_CHIP);
968 	mpt_free_request(mpt, req);
969 	return (0);
970 }
971 
972 /*
973  * Enable/Disable asynchronous event reporting.
974  *
975  * NB: this is the first command we send via shared memory
976  * instead of the handshake register.
977  */
978 static int
979 mpt_send_event_request(mpt_softc_t *mpt, int onoff)
980 {
981 	request_t *req;
982 	MSG_EVENT_NOTIFY *enable_req;
983 
984 	req = mpt_get_request(mpt);
985 
986 	enable_req = req->req_vbuf;
987 	bzero(enable_req, sizeof *enable_req);
988 
989 	enable_req->Function   = MPI_FUNCTION_EVENT_NOTIFICATION;
990 	enable_req->MsgContext = req->index | 0x80000000;
991 	enable_req->Switch     = onoff;
992 
993 	mpt_check_doorbell(mpt);
994 	if (mpt->verbose > 1) {
995 		mpt_prt(mpt, "%sabling async events", onoff? "en" : "dis");
996 	}
997 	mpt_send_cmd(mpt, req);
998 
999 	return (0);
1000 }
1001 
1002 /*
1003  * Un-mask the interrupts on the chip.
1004  */
1005 void
1006 mpt_enable_ints(mpt_softc_t *mpt)
1007 {
1008 	/* Unmask every thing except door bell int */
1009 	mpt_write(mpt, MPT_OFFSET_INTR_MASK, MPT_INTR_DB_MASK);
1010 }
1011 
1012 /*
1013  * Mask the interrupts on the chip.
1014  */
1015 void
1016 mpt_disable_ints(mpt_softc_t *mpt)
1017 {
1018 	/* Mask all interrupts */
1019 	mpt_write(mpt, MPT_OFFSET_INTR_MASK,
1020 	    MPT_INTR_REPLY_MASK | MPT_INTR_DB_MASK);
1021 }
1022 
1023 /* (Re)Initialize the chip for use */
1024 int
1025 mpt_init(mpt_softc_t *mpt, u_int32_t who)
1026 {
1027         int try;
1028         MSG_IOC_FACTS_REPLY facts;
1029         MSG_PORT_FACTS_REPLY pfp;
1030 	u_int32_t pptr;
1031         int val;
1032 
1033 	/* Put all request buffers (back) on the free list */
1034         SLIST_INIT(&mpt->request_free_list);
1035 	for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++) {
1036 		mpt_free_request(mpt, &mpt->request_pool[val]);
1037 	}
1038 
1039 	if (mpt->verbose > 1) {
1040 		mpt_prt(mpt, "doorbell req = %s",
1041 		    mpt_ioc_diag(mpt_read(mpt, MPT_OFFSET_DOORBELL)));
1042 	}
1043 
1044 	/*
1045 	 * Start by making sure we're not at FAULT or RESET state
1046 	 */
1047 	switch (mpt_rd_db(mpt) & MPT_DB_STATE_MASK) {
1048 	case MPT_DB_STATE_RESET:
1049 	case MPT_DB_STATE_FAULT:
1050 		if (mpt_reset(mpt) != MPT_OK) {
1051 			return (EIO);
1052 		}
1053 	default:
1054 		break;
1055 	}
1056 
1057 	for (try = 0; try < MPT_MAX_TRYS; try++) {
1058 		/*
1059 		 * No need to reset if the IOC is already in the READY state.
1060 		 *
1061 		 * Force reset if initialization failed previously.
1062 		 * Note that a hard_reset of the second channel of a '929
1063 		 * will stop operation of the first channel.  Hopefully, if the
1064 		 * first channel is ok, the second will not require a hard
1065 		 * reset.
1066 		 */
1067 		if ((mpt_rd_db(mpt) & MPT_DB_STATE_MASK) !=
1068 		    MPT_DB_STATE_READY) {
1069 			if (mpt_reset(mpt) != MPT_OK) {
1070 				DELAY(10000);
1071 				continue;
1072 			}
1073 		}
1074 
1075 		if (mpt_get_iocfacts(mpt, &facts) != MPT_OK) {
1076 			mpt_prt(mpt, "mpt_get_iocfacts failed");
1077 			continue;
1078 		}
1079 
1080 		if (mpt->verbose > 1) {
1081 			mpt_prt(mpt,
1082 			    "IOCFACTS: GlobalCredits=%d BlockSize=%u "
1083 			    "Request Frame Size %u\n", facts.GlobalCredits,
1084 			    facts.BlockSize, facts.RequestFrameSize);
1085 		}
1086 		mpt->mpt_global_credits = facts.GlobalCredits;
1087 		mpt->request_frame_size = facts.RequestFrameSize;
1088 
1089 		if (mpt_get_portfacts(mpt, &pfp) != MPT_OK) {
1090 			mpt_prt(mpt, "mpt_get_portfacts failed");
1091 			continue;
1092 		}
1093 
1094 		if (mpt->verbose > 1) {
1095 			mpt_prt(mpt,
1096 			    "PORTFACTS: Type %x PFlags %x IID %d MaxDev %d\n",
1097 			    pfp.PortType, pfp.ProtocolFlags, pfp.PortSCSIID,
1098 			    pfp.MaxDevices);
1099 		}
1100 
1101 		if (pfp.PortType != MPI_PORTFACTS_PORTTYPE_SCSI &&
1102 		    pfp.PortType != MPI_PORTFACTS_PORTTYPE_FC) {
1103 			mpt_prt(mpt, "Unsupported Port Type (%x)",
1104 			    pfp.PortType);
1105 			return (ENXIO);
1106 		}
1107 		if (!(pfp.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
1108 			mpt_prt(mpt, "initiator role unsupported");
1109 			return (ENXIO);
1110 		}
1111 		if (pfp.PortType == MPI_PORTFACTS_PORTTYPE_FC) {
1112 			mpt->is_fc = 1;
1113 		} else {
1114 			mpt->is_fc = 0;
1115 		}
1116 		mpt->mpt_ini_id = pfp.PortSCSIID;
1117 
1118 		if (mpt_send_ioc_init(mpt, who) != MPT_OK) {
1119 			mpt_prt(mpt, "mpt_send_ioc_init failed");
1120 			continue;
1121 		}
1122 
1123 		if (mpt->verbose > 1) {
1124 			mpt_prt(mpt, "mpt_send_ioc_init ok");
1125 		}
1126 
1127 		if (mpt_wait_state(mpt, MPT_DB_STATE_RUNNING) != MPT_OK) {
1128 			mpt_prt(mpt, "IOC failed to go to run state");
1129 			continue;
1130 		}
1131 		if (mpt->verbose > 1) {
1132 			mpt_prt(mpt, "IOC now at RUNSTATE");
1133 		}
1134 
1135 		/*
1136 		 * Give it reply buffers
1137 		 *
1138 		 * Do *not* except global credits.
1139 		 */
1140 		for (val = 0, pptr = mpt->reply_phys;
1141 		    (pptr + MPT_REPLY_SIZE) < (mpt->reply_phys + PAGE_SIZE);
1142 		     pptr += MPT_REPLY_SIZE) {
1143 			mpt_free_reply(mpt, pptr);
1144 			if (++val == mpt->mpt_global_credits - 1)
1145 				break;
1146 		}
1147 
1148 		/*
1149 		 * Enable asynchronous event reporting
1150 		 */
1151 		mpt_send_event_request(mpt, 1);
1152 
1153 
1154 		/*
1155 		 * Read set up initial configuration information
1156 		 * (SPI only for now)
1157 		 */
1158 
1159 		if (mpt->is_fc == 0) {
1160 			if (mpt_read_config_info_spi(mpt)) {
1161 				return (EIO);
1162 			}
1163 			if (mpt_set_initial_config_spi(mpt)) {
1164 				return (EIO);
1165 			}
1166 		}
1167 
1168 		/*
1169 		 * Now enable the port
1170 		 */
1171 		if (mpt_send_port_enable(mpt, 0) != MPT_OK) {
1172 			mpt_prt(mpt, "failed to enable port 0");
1173 			continue;
1174 		}
1175 
1176 		if (mpt->verbose > 1) {
1177 			mpt_prt(mpt, "enabled port 0");
1178 		}
1179 
1180 		/* Everything worked */
1181 		break;
1182 	}
1183 
1184 	if (try >= MPT_MAX_TRYS) {
1185 		mpt_prt(mpt, "failed to initialize IOC");
1186 		return (EIO);
1187 	}
1188 
1189 	if (mpt->verbose > 1) {
1190 		mpt_prt(mpt, "enabling interrupts");
1191 	}
1192 
1193 	mpt_enable_ints(mpt);
1194 	return (0);
1195 }
1196