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