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