xref: /dragonfly/sys/dev/disk/mpt/mpt.c (revision 1de703da)
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.2 2003/06/17 04:28:28 dillon 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 <dev/mpt/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 	req->sequence = 0;
236 	req->ccb = NULL;
237 	req->debug = REQ_FREE;
238 	SLIST_INSERT_HEAD(&mpt->request_free_list, req, link);
239 }
240 
241 /* Get a command buffer from the free queue */
242 request_t *
243 mpt_get_request(mpt_softc_t *mpt)
244 {
245 	request_t *req;
246 	req = SLIST_FIRST(&mpt->request_free_list);
247 	if (req != NULL) {
248 		if (req != &mpt->request_pool[req->index]) {
249 			panic("mpt_get_request: corrupted request free list\n");
250 		}
251 		if (req->ccb != NULL) {
252 			panic("mpt_get_request: corrupted request free list (ccb)\n");
253 		}
254 		SLIST_REMOVE_HEAD(&mpt->request_free_list, link);
255 		req->debug = REQ_IN_PROGRESS;
256 	}
257 	return req;
258 }
259 
260 /* Pass the command to the IOC */
261 void
262 mpt_send_cmd(mpt_softc_t *mpt, request_t *req)
263 {
264 	req->sequence = mpt->sequence++;
265 	if (mpt->verbose > 1) {
266 		u_int32_t *pReq;
267 		pReq = req->req_vbuf;
268 		device_printf(mpt->dev, "Send Request %d (0x%lx):\n",
269 		    req->index, (long) req->req_pbuf);
270 		device_printf(mpt->dev, "%08X %08X %08X %08X\n",
271 		    pReq[0], pReq[1], pReq[2], pReq[3]);
272 		device_printf(mpt->dev, "%08X %08X %08X %08X\n",
273 		    pReq[4], pReq[5], pReq[6], pReq[7]);
274 		device_printf(mpt->dev, "%08X %08X %08X %08X\n",
275 		    pReq[8], pReq[9], pReq[10], pReq[11]);
276 		device_printf(mpt->dev, "%08X %08X %08X %08X\n",
277 		    pReq[12], pReq[13], pReq[14], pReq[15]);
278 	}
279 	bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap,
280 	   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 		device_printf(mpt->dev,
321 		    "handshake aborted due to invalid doorbell state\n");
322 		mpt_print_db(data);
323 		return(EBUSY);
324 	}
325 
326 	/* We move things in 32 bit chunks */
327 	len = (len + 3) >> 2;
328 	data32 = cmd;
329 
330 	/* Clear any left over pending doorbell interupts */
331 	if (MPT_DB_INTR(mpt_rd_intr(mpt)))
332 		mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
333 
334 	/*
335 	 * Tell the handshake reg. we are going to send a command
336          * and how long it is going to be.
337 	 */
338 	data = (MPI_FUNCTION_HANDSHAKE << MPI_DOORBELL_FUNCTION_SHIFT) |
339 	    (len << MPI_DOORBELL_ADD_DWORDS_SHIFT);
340 	mpt_write(mpt, MPT_OFFSET_DOORBELL, data);
341 
342 	/* Wait for the chip to notice */
343 	if (mpt_wait_db_int(mpt) != MPT_OK) {
344 		device_printf(mpt->dev, "mpt_send_handshake_cmd timeout1!\n");
345 		return ETIMEDOUT;
346 	}
347 
348 	/* Clear the interrupt */
349 	mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
350 
351 	if (mpt_wait_db_ack(mpt) != MPT_OK) {
352 		device_printf(mpt->dev, "mpt_send_handshake_cmd timeout2!\n");
353 		return ETIMEDOUT;
354 	}
355 
356 	/* Send the command */
357 	for (i = 0; i < len; i++) {
358 		mpt_write(mpt, MPT_OFFSET_DOORBELL, *data32++);
359 		if (mpt_wait_db_ack(mpt) != MPT_OK) {
360 			device_printf(mpt->dev,
361 			    "mpt_send_handshake_cmd timeout! index = %d\n", i);
362 			return ETIMEDOUT;
363 		}
364 	}
365 	return MPT_OK;
366 }
367 
368 /* Get the response from the handshake register */
369 int
370 mpt_recv_handshake_reply(mpt_softc_t *mpt, size_t reply_len, void *reply)
371 {
372 	int left, reply_left;
373 	u_int16_t *data16;
374 	MSG_DEFAULT_REPLY *hdr;
375 
376 	/* We move things out in 16 bit chunks */
377 	reply_len >>= 1;
378 	data16 = (u_int16_t *)reply;
379 
380 	hdr = (MSG_DEFAULT_REPLY *)reply;
381 
382 	/* Get first word */
383 	if (mpt_wait_db_int(mpt) != MPT_OK) {
384 		device_printf(mpt->dev, "mpt_recv_handshake_cmd timeout1!\n");
385 		return ETIMEDOUT;
386 	}
387 	*data16++ = mpt_read(mpt, MPT_OFFSET_DOORBELL) & MPT_DB_DATA_MASK;
388 	mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
389 
390 	/* Get Second Word */
391 	if (mpt_wait_db_int(mpt) != MPT_OK) {
392 		device_printf(mpt->dev, "mpt_recv_handshake_cmd timeout2!\n");
393 		return ETIMEDOUT;
394 	}
395 	*data16++ = mpt_read(mpt, MPT_OFFSET_DOORBELL) & MPT_DB_DATA_MASK;
396 	mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
397 
398 	/* With the second word, we can now look at the length */
399 	if (mpt->verbose > 1 && ((reply_len >> 1) != hdr->MsgLength)) {
400 		device_printf(mpt->dev,
401 			"reply length does not match message length: "
402 			"got 0x%02x, expected 0x%02lx\n",
403 			hdr->MsgLength << 2, (long) (reply_len << 1));
404 	}
405 
406 	/* Get rest of the reply; but don't overflow the provided buffer */
407 	left = (hdr->MsgLength << 1) - 2;
408 	reply_left =  reply_len - 2;
409 	while (left--) {
410 		u_int16_t datum;
411 
412 		if (mpt_wait_db_int(mpt) != MPT_OK) {
413 			device_printf(mpt->dev,
414 			    "mpt_recv_handshake_cmd timeout3!\n");
415 			return ETIMEDOUT;
416 		}
417 		datum = mpt_read(mpt, MPT_OFFSET_DOORBELL);
418 
419 		if (reply_left-- > 0)
420 			*data16++ = datum & MPT_DB_DATA_MASK;
421 
422 		mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
423 	}
424 
425 	/* One more wait & clear at the end */
426 	if (mpt_wait_db_int(mpt) != MPT_OK) {
427 		device_printf(mpt->dev, "mpt_recv_handshake_cmd timeout4!\n");
428 		return ETIMEDOUT;
429 	}
430 	mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
431 
432 	if ((hdr->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
433 		if (mpt->verbose > 1)
434 			mpt_print_reply(hdr);
435 		return (MPT_FAIL | hdr->IOCStatus);
436 	}
437 
438 	return (0);
439 }
440 
441 static int
442 mpt_get_iocfacts(mpt_softc_t *mpt, MSG_IOC_FACTS_REPLY *freplp)
443 {
444 	MSG_IOC_FACTS f_req;
445 	int error;
446 
447 	bzero(&f_req, sizeof f_req);
448 	f_req.Function = MPI_FUNCTION_IOC_FACTS;
449 	f_req.MsgContext =  0x12071942;
450 	error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req);
451 	if (error)
452 		return(error);
453 	error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp);
454 	return (error);
455 }
456 
457 static int
458 mpt_get_portfacts(mpt_softc_t *mpt, MSG_PORT_FACTS_REPLY *freplp)
459 {
460 	MSG_PORT_FACTS f_req;
461 	int error;
462 
463 	/* XXX: Only getting PORT FACTS for Port 0 */
464 	bzero(&f_req, sizeof f_req);
465 	f_req.Function = MPI_FUNCTION_PORT_FACTS;
466 	f_req.MsgContext =  0x12071943;
467 	error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req);
468 	if (error)
469 		return(error);
470 	error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp);
471 	return (error);
472 }
473 
474 /*
475  * Send the initialization request. This is where we specify how many
476  * SCSI busses and how many devices per bus we wish to emulate.
477  * This is also the command that specifies the max size of the reply
478  * frames from the IOC that we will be allocating.
479  */
480 static int
481 mpt_send_ioc_init(mpt_softc_t *mpt, u_int32_t who)
482 {
483 	int error = 0;
484 	MSG_IOC_INIT init;
485 	MSG_IOC_INIT_REPLY reply;
486 
487 	bzero(&init, sizeof init);
488 	init.WhoInit = who;
489 	init.Function = MPI_FUNCTION_IOC_INIT;
490 	if (mpt->is_fc) {
491 		init.MaxDevices = 255;
492 	} else {
493 		init.MaxDevices = 16;
494 	}
495 	init.MaxBuses = 1;
496 	init.ReplyFrameSize = MPT_REPLY_SIZE;
497 	init.MsgContext = 0x12071941;
498 
499 	if ((error = mpt_send_handshake_cmd(mpt, sizeof init, &init)) != 0) {
500 		return(error);
501 	}
502 
503 	error = mpt_recv_handshake_reply(mpt, sizeof reply, &reply);
504 	return (error);
505 }
506 
507 
508 /*
509  * Utiltity routine to read configuration headers and pages
510  */
511 
512 static int
513 mpt_read_cfg_header(mpt_softc_t *, int, int, int, fCONFIG_PAGE_HEADER *);
514 
515 static int
516 mpt_read_cfg_header(mpt_softc_t *mpt, int PageType, int PageNumber,
517     int PageAddress, fCONFIG_PAGE_HEADER *rslt)
518 {
519 	int count;
520 	request_t *req;
521 	MSG_CONFIG *cfgp;
522 	MSG_CONFIG_REPLY *reply;
523 
524 	req = mpt_get_request(mpt);
525 
526 	cfgp = req->req_vbuf;
527 	bzero(cfgp, sizeof *cfgp);
528 
529 	cfgp->Action = MPI_CONFIG_ACTION_PAGE_HEADER;
530 	cfgp->Function = MPI_FUNCTION_CONFIG;
531 	cfgp->Header.PageNumber = (U8) PageNumber;
532 	cfgp->Header.PageType = (U8) PageType;
533 	cfgp->PageAddress = PageAddress;
534 	MPI_pSGE_SET_FLAGS(((SGE_SIMPLE32 *) &cfgp->PageBufferSGE),
535 	    (MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
536 	    MPI_SGE_FLAGS_SIMPLE_ELEMENT | MPI_SGE_FLAGS_END_OF_LIST));
537 	cfgp->MsgContext = req->index | 0x80000000;
538 
539 	mpt_check_doorbell(mpt);
540 	mpt_send_cmd(mpt, req);
541 	count = 0;
542 	do {
543 		DELAY(500);
544 		mpt_intr(mpt);
545 		if (++count == 1000) {
546 			device_printf(mpt->dev, "read_cfg_header timed out\n");
547 			return (-1);
548 		}
549 	} while (req->debug == REQ_ON_CHIP);
550 
551 	reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
552         if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
553 		device_printf(mpt->dev,
554 		    "mpt_read_cfg_header: Config Info Status %x\n",
555 		    reply->IOCStatus);
556 		mpt_free_reply(mpt, (req->sequence << 1));
557 		return (-1);
558 	}
559 	bcopy(&reply->Header, rslt, sizeof (fCONFIG_PAGE_HEADER));
560 	mpt_free_reply(mpt, (req->sequence << 1));
561 	mpt_free_request(mpt, req);
562 	return (0);
563 }
564 
565 #define	CFG_DATA_OFF	128
566 
567 int
568 mpt_read_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr)
569 {
570 	int count;
571 	request_t *req;
572 	SGE_SIMPLE32 *se;
573 	MSG_CONFIG *cfgp;
574 	size_t amt;
575 	MSG_CONFIG_REPLY *reply;
576 
577 	req = mpt_get_request(mpt);
578 
579 	cfgp = req->req_vbuf;
580 	bzero(cfgp, MPT_REQUEST_AREA);
581 	cfgp->Action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
582 	cfgp->Function = MPI_FUNCTION_CONFIG;
583 	cfgp->Header = *hdr;
584  	amt = (cfgp->Header.PageLength * sizeof (u_int32_t));
585 	cfgp->Header.PageType &= MPI_CONFIG_PAGETYPE_MASK;
586 	cfgp->PageAddress = PageAddress;
587 	se = (SGE_SIMPLE32 *) &cfgp->PageBufferSGE;
588 	se->Address = req->req_pbuf + CFG_DATA_OFF;
589 	MPI_pSGE_SET_LENGTH(se, amt);
590 	MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
591 	    MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
592 	    MPI_SGE_FLAGS_END_OF_LIST));
593 
594 	cfgp->MsgContext = req->index | 0x80000000;
595 
596 	mpt_check_doorbell(mpt);
597 	mpt_send_cmd(mpt, req);
598 	count = 0;
599 	do {
600 		DELAY(500);
601 		mpt_intr(mpt);
602 		if (++count == 1000) {
603 			device_printf(mpt->dev, "read_cfg_page timed out\n");
604 			return (-1);
605 		}
606 	} while (req->debug == REQ_ON_CHIP);
607 
608 	reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
609         if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
610 		device_printf(mpt->dev,
611 		    "mpt_read_cfg_page: Config Info Status %x\n",
612 		    reply->IOCStatus);
613 		mpt_free_reply(mpt, (req->sequence << 1));
614 		return (-1);
615 	}
616 	mpt_free_reply(mpt, (req->sequence << 1));
617 	bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap,
618 	    BUS_DMASYNC_POSTREAD);
619 	if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
620 	    cfgp->Header.PageNumber == 0) {
621 		amt = sizeof (fCONFIG_PAGE_SCSI_PORT_0);
622 	} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
623 	    cfgp->Header.PageNumber == 1) {
624 		amt = sizeof (fCONFIG_PAGE_SCSI_PORT_1);
625 	} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
626 	    cfgp->Header.PageNumber == 2) {
627 		amt = sizeof (fCONFIG_PAGE_SCSI_PORT_2);
628 	} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE  &&
629 	    cfgp->Header.PageNumber == 0) {
630 		amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_0);
631 	} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE  &&
632 	    cfgp->Header.PageNumber == 1) {
633 		amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_1);
634 	}
635 	bcopy(((caddr_t)req->req_vbuf)+CFG_DATA_OFF, hdr, amt);
636 	mpt_free_request(mpt, req);
637 	return (0);
638 }
639 
640 int
641 mpt_write_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr)
642 {
643 	int count, hdr_attr;
644 	request_t *req;
645 	SGE_SIMPLE32 *se;
646 	MSG_CONFIG *cfgp;
647 	size_t amt;
648 	MSG_CONFIG_REPLY *reply;
649 
650 	req = mpt_get_request(mpt);
651 
652 	cfgp = req->req_vbuf;
653 	bzero(cfgp, sizeof *cfgp);
654 
655 	hdr_attr = hdr->PageType & MPI_CONFIG_PAGEATTR_MASK;
656 	if (hdr_attr != MPI_CONFIG_PAGEATTR_CHANGEABLE &&
657 	    hdr_attr != MPI_CONFIG_PAGEATTR_PERSISTENT) {
658 		device_printf(mpt->dev, "page type 0x%x not changeable\n",
659 		    hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
660 		return (-1);
661 	}
662 	hdr->PageType &= MPI_CONFIG_PAGETYPE_MASK;
663 
664 	cfgp->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
665 	cfgp->Function = MPI_FUNCTION_CONFIG;
666 	cfgp->Header = *hdr;
667  	amt = (cfgp->Header.PageLength * sizeof (u_int32_t));
668 	cfgp->PageAddress = PageAddress;
669 
670 	se = (SGE_SIMPLE32 *) &cfgp->PageBufferSGE;
671 	se->Address = req->req_pbuf + CFG_DATA_OFF;
672 	MPI_pSGE_SET_LENGTH(se, amt);
673 	MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
674 	    MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
675 	    MPI_SGE_FLAGS_END_OF_LIST | MPI_SGE_FLAGS_HOST_TO_IOC));
676 
677 	cfgp->MsgContext = req->index | 0x80000000;
678 
679 	if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
680 	    cfgp->Header.PageNumber == 0) {
681 		amt = sizeof (fCONFIG_PAGE_SCSI_PORT_0);
682 	} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
683 	    cfgp->Header.PageNumber == 1) {
684 		amt = sizeof (fCONFIG_PAGE_SCSI_PORT_1);
685 	} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
686 	    cfgp->Header.PageNumber == 2) {
687 		amt = sizeof (fCONFIG_PAGE_SCSI_PORT_2);
688 	} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE  &&
689 	    cfgp->Header.PageNumber == 0) {
690 		amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_0);
691 	} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE  &&
692 	    cfgp->Header.PageNumber == 1) {
693 		amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_1);
694 	}
695 	bcopy(hdr, ((caddr_t)req->req_vbuf)+CFG_DATA_OFF, amt);
696 	/* Restore stripped out attributes */
697 	hdr->PageType |= hdr_attr;
698 
699 	mpt_check_doorbell(mpt);
700 	mpt_send_cmd(mpt, req);
701 	count = 0;
702 	do {
703 		DELAY(500);
704 		mpt_intr(mpt);
705 		if (++count == 1000) {
706 			hdr->PageType |= hdr_attr;
707 			device_printf(mpt->dev,
708 			    "mpt_write_cfg_page timed out\n");
709 			return (-1);
710 		}
711 	} while (req->debug == REQ_ON_CHIP);
712 
713 	reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
714         if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
715 		device_printf(mpt->dev,
716 		    "mpt_write_cfg_page: Config Info Status %x\n",
717 		    reply->IOCStatus);
718 		mpt_free_reply(mpt, (req->sequence << 1));
719 		return (-1);
720 	}
721 	mpt_free_reply(mpt, (req->sequence << 1));
722 
723 	mpt_free_request(mpt, req);
724 	return (0);
725 }
726 
727 /*
728  * Read SCSI configuration information
729  */
730 static int
731 mpt_read_config_info_spi(mpt_softc_t *mpt)
732 {
733 	int rv, i;
734 
735 	rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 0,
736 	    0, &mpt->mpt_port_page0.Header);
737 	if (rv) {
738 		return (-1);
739 	}
740 	if (mpt->verbose > 1) {
741 		device_printf(mpt->dev, "SPI Port Page 0 Header: %x %x %x %x\n",
742 		    mpt->mpt_port_page0.Header.PageVersion,
743 		    mpt->mpt_port_page0.Header.PageLength,
744 		    mpt->mpt_port_page0.Header.PageNumber,
745 		    mpt->mpt_port_page0.Header.PageType);
746 	}
747 
748 	rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 1,
749 	    0, &mpt->mpt_port_page1.Header);
750 	if (rv) {
751 		return (-1);
752 	}
753 	if (mpt->verbose > 1) {
754 		device_printf(mpt->dev, "SPI Port Page 1 Header: %x %x %x %x\n",
755 		    mpt->mpt_port_page1.Header.PageVersion,
756 		    mpt->mpt_port_page1.Header.PageLength,
757 		    mpt->mpt_port_page1.Header.PageNumber,
758 		    mpt->mpt_port_page1.Header.PageType);
759 	}
760 
761 	rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 2,
762 	    0, &mpt->mpt_port_page2.Header);
763 	if (rv) {
764 		return (-1);
765 	}
766 
767 	if (mpt->verbose > 1) {
768 		device_printf(mpt->dev, "SPI Port Page 2 Header: %x %x %x %x\n",
769 		    mpt->mpt_port_page1.Header.PageVersion,
770 		    mpt->mpt_port_page1.Header.PageLength,
771 		    mpt->mpt_port_page1.Header.PageNumber,
772 		    mpt->mpt_port_page1.Header.PageType);
773 	}
774 
775 	for (i = 0; i < 16; i++) {
776 		rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
777 		    0, i, &mpt->mpt_dev_page0[i].Header);
778 		if (rv) {
779 			return (-1);
780 		}
781 		if (mpt->verbose > 1) {
782 			device_printf(mpt->dev,
783 			    "SPI Target %d Device Page 0 Header: %x %x %x %x\n",
784 			    i, mpt->mpt_dev_page0[i].Header.PageVersion,
785 			    mpt->mpt_dev_page0[i].Header.PageLength,
786 			    mpt->mpt_dev_page0[i].Header.PageNumber,
787 			    mpt->mpt_dev_page0[i].Header.PageType);
788 		}
789 
790 		rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
791 		    1, i, &mpt->mpt_dev_page1[i].Header);
792 		if (rv) {
793 			return (-1);
794 		}
795 		if (mpt->verbose > 1) {
796 			device_printf(mpt->dev,
797 			    "SPI Target %d Device Page 1 Header: %x %x %x %x\n",
798 			    i, mpt->mpt_dev_page1[i].Header.PageVersion,
799 			    mpt->mpt_dev_page1[i].Header.PageLength,
800 			    mpt->mpt_dev_page1[i].Header.PageNumber,
801 			    mpt->mpt_dev_page1[i].Header.PageType);
802 		}
803 	}
804 
805 	/*
806 	 * At this point, we don't *have* to fail. As long as we have
807 	 * valid config header information, we can (barely) lurch
808 	 * along.
809 	 */
810 
811 	rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page0.Header);
812 	if (rv) {
813 		device_printf(mpt->dev, "failed to read SPI Port Page 0\n");
814 	} else if (mpt->verbose > 1) {
815 		device_printf(mpt->dev,
816 		    "SPI Port Page 0: Capabilities %x PhysicalInterface %x\n",
817 		    mpt->mpt_port_page0.Capabilities,
818 		    mpt->mpt_port_page0.PhysicalInterface);
819 	}
820 
821 	rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page1.Header);
822 	if (rv) {
823 		device_printf(mpt->dev, "failed to read SPI Port Page 1\n");
824 	} else if (mpt->verbose > 1) {
825 		device_printf(mpt->dev,
826 		    "SPI Port Page 1: Configuration %x OnBusTimerValue %x\n",
827 		    mpt->mpt_port_page1.Configuration,
828 		    mpt->mpt_port_page1.OnBusTimerValue);
829 	}
830 
831 	rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page2.Header);
832 	if (rv) {
833 		device_printf(mpt->dev, "failed to read SPI Port Page 2\n");
834 	} else if (mpt->verbose > 1) {
835 		device_printf(mpt->dev,
836 		    "SPI Port Page 2: Flags %x Settings %x\n",
837 		    mpt->mpt_port_page2.PortFlags,
838 		    mpt->mpt_port_page2.PortSettings);
839 		for (i = 0; i < 16; i++) {
840 			device_printf(mpt->dev,
841 		  	    "SPI Port Page 2 Tgt %d: timo %x SF %x Flags %x\n",
842 			    i, mpt->mpt_port_page2.DeviceSettings[i].Timeout,
843 			    mpt->mpt_port_page2.DeviceSettings[i].SyncFactor,
844 			    mpt->mpt_port_page2.DeviceSettings[i].DeviceFlags);
845 		}
846 	}
847 
848 	for (i = 0; i < 16; i++) {
849 		rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page0[i].Header);
850 		if (rv) {
851 			device_printf(mpt->dev,
852 			    "cannot read SPI Tgt %d Device Page 0\n", i);
853 			continue;
854 		}
855 		if (mpt->verbose > 1) {
856 			device_printf(mpt->dev,
857 			    "SPI Tgt %d Page 0: NParms %x Information %x\n",
858 			    i, mpt->mpt_dev_page0[i].NegotiatedParameters,
859 			    mpt->mpt_dev_page0[i].Information);
860 		}
861 		rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page1[i].Header);
862 		if (rv) {
863 			device_printf(mpt->dev,
864 			    "cannot read SPI Tgt %d Device Page 1\n", i);
865 			continue;
866 		}
867 		if (mpt->verbose > 1) {
868 			device_printf(mpt->dev,
869 			    "SPI Tgt %d Page 1: RParms %x Configuration %x\n",
870 			    i, mpt->mpt_dev_page1[i].RequestedParameters,
871 			    mpt->mpt_dev_page1[i].Configuration);
872 		}
873 	}
874 	return (0);
875 }
876 
877 /*
878  * Validate SPI configuration information.
879  *
880  * In particular, validate SPI Port Page 1.
881  */
882 static int
883 mpt_set_initial_config_spi(mpt_softc_t *mpt)
884 {
885 	int i, pp1val = ((1 << mpt->mpt_ini_id) << 16) | mpt->mpt_ini_id;
886 
887 	mpt->mpt_disc_enable = 0xff;
888 	mpt->mpt_tag_enable = 0;
889 
890 	if (mpt->mpt_port_page1.Configuration != pp1val) {
891 		fCONFIG_PAGE_SCSI_PORT_1 tmp;
892 		device_printf(mpt->dev,
893 		    "SPI Port Page 1 Config value bad (%x)- should be %x\n",
894 		    mpt->mpt_port_page1.Configuration, pp1val);
895 		tmp = mpt->mpt_port_page1;
896 		tmp.Configuration = pp1val;
897 		if (mpt_write_cfg_page(mpt, 0, &tmp.Header)) {
898 			return (-1);
899 		}
900 		if (mpt_read_cfg_page(mpt, 0, &tmp.Header)) {
901 			return (-1);
902 		}
903 		if (tmp.Configuration != pp1val) {
904 			device_printf(mpt->dev,
905 			    "failed to reset SPI Port Page 1 Config value\n");
906 			return (-1);
907 		}
908 		mpt->mpt_port_page1 = tmp;
909 	}
910 
911 	for (i = 0; i < 16; i++) {
912 		fCONFIG_PAGE_SCSI_DEVICE_1 tmp;
913 		tmp = mpt->mpt_dev_page1[i];
914 		tmp.RequestedParameters = 0;
915 		tmp.Configuration = 0;
916 		if (mpt->verbose > 1) {
917 			device_printf(mpt->dev,
918 			    "Set Tgt %d SPI DevicePage 1 values to %x 0 %x\n",
919 			    i, tmp.RequestedParameters, tmp.Configuration);
920 		}
921 		if (mpt_write_cfg_page(mpt, i, &tmp.Header)) {
922 			return (-1);
923 		}
924 		if (mpt_read_cfg_page(mpt, i, &tmp.Header)) {
925 			return (-1);
926 		}
927 		mpt->mpt_dev_page1[i] = tmp;
928 		if (mpt->verbose > 1) {
929 			device_printf(mpt->dev,
930 		 	    "SPI Tgt %d Page 1: RParm %x Configuration %x\n", i,
931 			    mpt->mpt_dev_page1[i].RequestedParameters,
932 			    mpt->mpt_dev_page1[i].Configuration);
933 		}
934 	}
935 	return (0);
936 }
937 
938 /*
939  * Enable IOC port
940  */
941 static int
942 mpt_send_port_enable(mpt_softc_t *mpt, int port)
943 {
944 	int count;
945 	request_t *req;
946 	MSG_PORT_ENABLE *enable_req;
947 
948 	req = mpt_get_request(mpt);
949 
950 	enable_req = req->req_vbuf;
951 	bzero(enable_req, sizeof *enable_req);
952 
953 	enable_req->Function   = MPI_FUNCTION_PORT_ENABLE;
954 	enable_req->MsgContext = req->index | 0x80000000;
955 	enable_req->PortNumber = port;
956 
957 	mpt_check_doorbell(mpt);
958 	if (mpt->verbose > 1) {
959 		device_printf(mpt->dev, "enabling port %d\n", port);
960 	}
961 	mpt_send_cmd(mpt, req);
962 
963 	count = 0;
964 	do {
965 		DELAY(500);
966 		mpt_intr(mpt);
967 		if (++count == 100000) {
968 			device_printf(mpt->dev, "port enable timed out\n");
969 			return (-1);
970 		}
971 	} while (req->debug == REQ_ON_CHIP);
972 	mpt_free_request(mpt, req);
973 	return (0);
974 }
975 
976 /*
977  * Enable/Disable asynchronous event reporting.
978  *
979  * NB: this is the first command we send via shared memory
980  * instead of the handshake register.
981  */
982 static int
983 mpt_send_event_request(mpt_softc_t *mpt, int onoff)
984 {
985 	request_t *req;
986 	MSG_EVENT_NOTIFY *enable_req;
987 
988 	req = mpt_get_request(mpt);
989 
990 	enable_req = req->req_vbuf;
991 	bzero(enable_req, sizeof *enable_req);
992 
993 	enable_req->Function   = MPI_FUNCTION_EVENT_NOTIFICATION;
994 	enable_req->MsgContext = req->index | 0x80000000;
995 	enable_req->Switch     = onoff;
996 
997 	mpt_check_doorbell(mpt);
998 	if (mpt->verbose > 1) {
999 		device_printf(mpt->dev, "%sabling async events\n",
1000 		    onoff? "en" : "dis");
1001 	}
1002 	mpt_send_cmd(mpt, req);
1003 
1004 	return (0);
1005 }
1006 
1007 /*
1008  * Un-mask the interupts on the chip.
1009  */
1010 void
1011 mpt_enable_ints(mpt_softc_t *mpt)
1012 {
1013 	/* Unmask every thing except door bell int */
1014 	mpt_write(mpt, MPT_OFFSET_INTR_MASK, MPT_INTR_DB_MASK);
1015 }
1016 
1017 /*
1018  * Mask the interupts on the chip.
1019  */
1020 void
1021 mpt_disable_ints(mpt_softc_t *mpt)
1022 {
1023 	/* Mask all interrupts */
1024 	mpt_write(mpt, MPT_OFFSET_INTR_MASK,
1025 	    MPT_INTR_REPLY_MASK | MPT_INTR_DB_MASK);
1026 }
1027 
1028 /* (Re)Initialize the chip for use */
1029 int
1030 mpt_init(mpt_softc_t *mpt, u_int32_t who)
1031 {
1032         int try;
1033         MSG_IOC_FACTS_REPLY facts;
1034         MSG_PORT_FACTS_REPLY pfp;
1035 	u_int32_t pptr;
1036         int val;
1037 
1038 	/* Put all request buffers (back) on the free list */
1039         SLIST_INIT(&mpt->request_free_list);
1040 	for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++) {
1041 		mpt_free_request(mpt, &mpt->request_pool[val]);
1042 	}
1043 
1044 	if (mpt->verbose > 1) {
1045 		device_printf(mpt->dev, "doorbell req = %s\n",
1046 		    mpt_ioc_diag(mpt_read(mpt, MPT_OFFSET_DOORBELL)));
1047 	}
1048 
1049 	/*
1050 	 * Start by making sure we're not at FAULT or RESET state
1051 	 */
1052 	switch (mpt_rd_db(mpt) & MPT_DB_STATE_MASK) {
1053 	case MPT_DB_STATE_RESET:
1054 	case MPT_DB_STATE_FAULT:
1055 		if (mpt_reset(mpt) != MPT_OK) {
1056 			return (EIO);
1057 		}
1058 	default:
1059 		break;
1060 	}
1061 
1062 	for (try = 0; try < MPT_MAX_TRYS; try++) {
1063 		/*
1064 		 * No need to reset if the IOC is already in the READY state.
1065 		 *
1066 		 * Force reset if initialization failed previously.
1067 		 * Note that a hard_reset of the second channel of a '929
1068 		 * will stop operation of the first channel.  Hopefully, if the
1069 		 * first channel is ok, the second will not require a hard
1070 		 * reset.
1071 		 */
1072 		if ((mpt_rd_db(mpt) & MPT_DB_STATE_MASK) !=
1073 		    MPT_DB_STATE_READY) {
1074 			if (mpt_reset(mpt) != MPT_OK) {
1075 				DELAY(10000);
1076 				continue;
1077 			}
1078 		}
1079 
1080 		if (mpt_get_iocfacts(mpt, &facts) != MPT_OK) {
1081 			device_printf(mpt->dev, "mpt_get_iocfacts failed\n");
1082 			continue;
1083 		}
1084 
1085 		if (mpt->verbose > 1) {
1086 			device_printf(mpt->dev,
1087 			    "IOCFACTS: GlobalCredits=%d BlockSize=%u "
1088 			    "Request Frame Size %u\n", facts.GlobalCredits,
1089 			    facts.BlockSize, facts.RequestFrameSize);
1090 		}
1091 		mpt->mpt_global_credits = facts.GlobalCredits;
1092 		mpt->request_frame_size = facts.RequestFrameSize;
1093 
1094 		if (mpt_get_portfacts(mpt, &pfp) != MPT_OK) {
1095 			device_printf(mpt->dev, "mpt_get_portfacts failed\n");
1096 			continue;
1097 		}
1098 
1099 		if (mpt->verbose > 1) {
1100 			device_printf(mpt->dev,
1101 			    "PORTFACTS: Type %x PFlags %x IID %d MaxDev %d\n",
1102 			    pfp.PortType, pfp.ProtocolFlags, pfp.PortSCSIID,
1103 			    pfp.MaxDevices);
1104 		}
1105 
1106 		if (pfp.PortType != MPI_PORTFACTS_PORTTYPE_SCSI &&
1107 		    pfp.PortType != MPI_PORTFACTS_PORTTYPE_FC) {
1108 			device_printf(mpt->dev, "Unsupported Port Type (%x)\n",
1109 			    pfp.PortType);
1110 			return (ENXIO);
1111 		}
1112 		if (!(pfp.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
1113 			device_printf(mpt->dev, "initiator role unsupported\n");
1114 			return (ENXIO);
1115 		}
1116 		if (pfp.PortType == MPI_PORTFACTS_PORTTYPE_FC) {
1117 			mpt->is_fc = 1;
1118 		} else {
1119 			mpt->is_fc = 0;
1120 		}
1121 		mpt->mpt_ini_id = pfp.PortSCSIID;
1122 
1123 		if (mpt_send_ioc_init(mpt, who) != MPT_OK) {
1124 			device_printf(mpt->dev, "mpt_send_ioc_init failed\n");
1125 			continue;
1126 		}
1127 
1128 		if (mpt->verbose > 1) {
1129 			device_printf(mpt->dev, "mpt_send_ioc_init ok\n");
1130 		}
1131 
1132 		if (mpt_wait_state(mpt, MPT_DB_STATE_RUNNING) != MPT_OK) {
1133 			device_printf(mpt->dev,
1134 			    "IOC failed to go to run state\n");
1135 			continue;
1136 		}
1137 		if (mpt->verbose > 1) {
1138 			device_printf(mpt->dev, "IOC now at RUNSTATE\n");
1139 		}
1140 
1141 		/*
1142 		 * Give it reply buffers
1143 		 *
1144 		 * Do *not* except global credits.
1145 		 */
1146 		for (val = 0, pptr = mpt->reply_phys;
1147 		    (pptr + MPT_REPLY_SIZE) < (mpt->reply_phys + PAGE_SIZE);
1148 		     pptr += MPT_REPLY_SIZE) {
1149 			mpt_free_reply(mpt, pptr);
1150 			if (++val == mpt->mpt_global_credits - 1)
1151 				break;
1152 		}
1153 
1154 		/*
1155 		 * Enable asynchronous event reporting
1156 		 */
1157 		mpt_send_event_request(mpt, 1);
1158 
1159 
1160 		/*
1161 		 * Read set up initial configuration information
1162 		 * (SPI only for now)
1163 		 */
1164 
1165 		if (mpt->is_fc == 0) {
1166 			if (mpt_read_config_info_spi(mpt)) {
1167 				return (EIO);
1168 			}
1169 			if (mpt_set_initial_config_spi(mpt)) {
1170 				return (EIO);
1171 			}
1172 		}
1173 
1174 		/*
1175 		 * Now enable the port
1176 		 */
1177 		if (mpt_send_port_enable(mpt, 0) != MPT_OK) {
1178 			device_printf(mpt->dev, "failed to enable port 0\n");
1179 			continue;
1180 		}
1181 
1182 		if (mpt->verbose > 1) {
1183 			device_printf(mpt->dev, "enabled port 0\n");
1184 		}
1185 
1186 		/* Everything worked */
1187 		break;
1188 	}
1189 
1190 	if (try >= MPT_MAX_TRYS) {
1191 		device_printf(mpt->dev, "failed to initialize IOC\n");
1192 		return (EIO);
1193 	}
1194 
1195 	if (mpt->verbose > 1) {
1196 		device_printf(mpt->dev, "enabling interrupts\n");
1197 	}
1198 
1199 	mpt_enable_ints(mpt);
1200 	return (0);
1201 }
1202