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