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