Home | History | Annotate | Line # | Download | only in ic
mpt.c revision 1.2
      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