mpt.c revision 101704
1/* $FreeBSD: head/sys/dev/mpt/mpt.c 101704 2002-08-11 23:34:20Z mjacob $ */
2/*
3 * Generic routines for LSI '909 FC  adapters.
4 * FreeBSD Version.
5 *
6 * Copyright (c) 2000, 2001 by Greg Ansley
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice immediately at the beginning of the file, without modification,
13 *    this list of conditions, and the following disclaimer.
14 * 2. The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29/*
30 * Additional Copyright (c) 2002 by Matthew Jacob under same license.
31 */
32
33#include <dev/mpt/mpt_freebsd.h>
34#include <dev/mpt/mpt.h>
35#define MPT_MAX_TRYS 3
36#define MPT_MAX_WAIT 300000
37
38static int maxwait_ack = 0;
39static int maxwait_int = 0;
40static int maxwait_state = 0;
41
42static __inline u_int32_t mpt_rd_db(struct mpt_softc *mpt);
43static __inline  u_int32_t mpt_rd_intr(struct mpt_softc *mpt);
44
45static __inline u_int32_t
46mpt_rd_db(struct mpt_softc *mpt)
47{
48	return mpt_read(mpt, MPT_OFFSET_DOORBELL);
49}
50
51static __inline u_int32_t
52mpt_rd_intr(struct mpt_softc *mpt)
53{
54	return mpt_read(mpt, MPT_OFFSET_INTR_STATUS);
55}
56
57/* Busy wait for a door bell to be read by IOC */
58static int
59mpt_wait_db_ack(struct mpt_softc *mpt)
60{
61	int i;
62	for (i=0; i < MPT_MAX_WAIT; i++) {
63		if (!MPT_DB_IS_BUSY(mpt_rd_intr(mpt))) {
64			maxwait_ack = i > maxwait_ack ? i : maxwait_ack;
65			return MPT_OK;
66		}
67
68		DELAY(100);
69	}
70	return MPT_FAIL;
71}
72
73/* Busy wait for a door bell interrupt */
74static int
75mpt_wait_db_int(struct mpt_softc *mpt)
76{
77	int i;
78	for (i=0; i < MPT_MAX_WAIT; i++) {
79		if (MPT_DB_INTR(mpt_rd_intr(mpt))) {
80			maxwait_int = i > maxwait_int ? i : maxwait_int;
81			return MPT_OK;
82		}
83		DELAY(100);
84	}
85	return MPT_FAIL;
86}
87
88/* Wait for IOC to transition to a give state */
89void
90mpt_check_doorbell(struct mpt_softc *mpt)
91{
92	u_int32_t db = mpt_rd_db(mpt);
93	if (MPT_STATE(db) != MPT_DB_STATE_RUNNING) {
94		device_printf(mpt->dev, "Device not running!\n");
95		mpt_print_db(db);
96	}
97}
98
99/* Wait for IOC to transition to a give state */
100static int
101mpt_wait_state(struct mpt_softc *mpt, enum DB_STATE_BITS state)
102{
103	int i;
104
105	for (i = 0; i < MPT_MAX_WAIT; i++) {
106		u_int32_t db = mpt_rd_db(mpt);
107		if (MPT_STATE(db) == state) {
108			maxwait_state = i > maxwait_state ? i : maxwait_state;
109			return (MPT_OK);
110		}
111		DELAY(100);
112	}
113	return (MPT_FAIL);
114}
115
116
117/* Issue the reset COMMAND to the IOC */
118int
119mpt_soft_reset(struct mpt_softc *mpt)
120{
121	if (mpt->verbose) {
122		device_printf(mpt->dev,"soft reset\n");
123	}
124
125	/* Have to use hard reset if we are not in Running state */
126	if (MPT_STATE(mpt_rd_db(mpt)) != MPT_DB_STATE_RUNNING) {
127		device_printf(mpt->dev,
128		    "soft reset failed: device not running\n");
129		return MPT_FAIL;
130	}
131
132	/* If door bell is in use we don't have a chance of getting
133	 * a word in since the IOC probably crashed in message
134	 * processing. So don't waste our time.
135	 */
136	if (MPT_DB_IS_IN_USE(mpt_rd_db(mpt))) {
137		device_printf(mpt->dev, "soft reset failed: doorbell wedged\n");
138		return MPT_FAIL;
139	}
140
141	/* Send the reset request to the IOC */
142	mpt_write(mpt, MPT_OFFSET_DOORBELL,
143	    MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET << MPI_DOORBELL_FUNCTION_SHIFT);
144	if (mpt_wait_db_ack(mpt) != MPT_OK) {
145		device_printf(mpt->dev, "soft reset failed: ack timeout\n");
146		return MPT_FAIL;
147	}
148
149	/* Wait for the IOC to reload and come out of reset state */
150	if (mpt_wait_state(mpt, MPT_DB_STATE_READY) != MPT_OK) {
151		device_printf(mpt->dev,
152		    "soft reset failed: device did not start running\n");
153		return MPT_FAIL;
154	}
155
156	return MPT_OK;
157}
158
159/* This is a magic diagnostic reset that resets all the ARM
160 * processors in the chip.
161 */
162void
163mpt_hard_reset(struct mpt_softc *mpt)
164{
165	/* This extra read comes for the Linux source
166	 * released by LSI. It's function is undocumented!
167	 */
168	if (mpt->verbose) {
169		device_printf(mpt->dev, "hard reset\n");
170	}
171	mpt_read(mpt, MPT_OFFSET_FUBAR);
172
173	/* Enable diagnostic registers */
174	mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_1);
175	mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_2);
176	mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_3);
177	mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_4);
178	mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_5);
179
180	/* Diag. port is now active so we can now hit the reset bit */
181	mpt_write(mpt, MPT_OFFSET_DIAGNOSTIC, MPT_DIAG_RESET_IOC);
182
183	DELAY(10000);
184
185	/* Disable Diagnostic Register */
186	mpt_write(mpt, MPT_OFFSET_SEQUENCE, 0xFF);
187
188	/* Restore the config register values */
189	/*   Hard resets are known to screw up the BAR for diagnostic
190	     memory accesses (Mem1). */
191	mpt_set_config_regs(mpt);
192	if (mpt->mpt2 != NULL) {
193		mpt_set_config_regs(mpt->mpt2);
194	}
195
196	/* Note that if there is no valid firmware to run, the doorbell will
197	   remain in the reset state (0x00000000) */
198}
199
200/*
201 * Reset the IOC when needed. Try software command first then if needed
202 * poke at the magic diagnostic reset. Note that a hard reset resets
203 * *both* IOCs on dual function chips (FC929 && LSI1030) as well as
204 * fouls up the PCI configuration registers.
205 */
206int
207mpt_reset(struct mpt_softc *mpt)
208{
209	int ret;
210
211	/* Try a soft reset */
212	if ((ret = mpt_soft_reset(mpt)) != MPT_OK) {
213		/* Failed; do a hard reset */
214		mpt_hard_reset(mpt);
215
216		/* Wait for the IOC to reload and come out of reset state */
217		ret = mpt_wait_state(mpt, MPT_DB_STATE_READY);
218		if (ret != MPT_OK) {
219			device_printf(mpt->dev, "failed to reset device\n");
220		}
221	}
222
223	return ret;
224}
225
226/* Return a command buffer to the free queue */
227void
228mpt_free_request(struct mpt_softc *mpt, request_t *req)
229{
230	if (req == NULL || req != &mpt->requests[req->index]) {
231		panic("mpt_free_request bad req ptr\n");
232		return;
233	}
234	req->ccb = NULL;
235	req->debug = REQ_FREE;
236	SLIST_INSERT_HEAD(&mpt->request_free_list, req, link);
237}
238
239/* Get a command buffer from the free queue */
240request_t *
241mpt_get_request(struct mpt_softc *mpt)
242{
243	request_t *req;
244	req = SLIST_FIRST(&mpt->request_free_list);
245	if (req != NULL) {
246		if (req != &mpt->requests[req->index]) {
247			panic("mpt_get_request: corrupted request free list\n");
248		}
249		if (req->ccb != NULL) {
250			panic("mpt_get_request: corrupted request free list (ccb)\n");
251		}
252		SLIST_REMOVE_HEAD(&mpt->request_free_list, link);
253		req->debug = REQ_IN_PROGRESS;
254	}
255	return req;
256}
257
258/* Pass the command to the IOC */
259void
260mpt_send_cmd(struct mpt_softc *mpt, request_t *req)
261{
262	req->sequence = mpt->sequence++;
263	if (mpt->verbose > 1) {
264		u_int32_t *pReq;
265		pReq = req->req_vbuf;
266		device_printf(mpt->dev, "Send Request %d (0x%x):\n",
267		    req->index, req->req_pbuf);
268		device_printf(mpt->dev, "%08X %08X %08X %08X\n",
269		    pReq[0], pReq[1], pReq[2], pReq[3]);
270		device_printf(mpt->dev, "%08X %08X %08X %08X\n",
271		    pReq[4], pReq[5], pReq[6], pReq[7]);
272		device_printf(mpt->dev, "%08X %08X %08X %08X\n",
273		    pReq[8], pReq[9], pReq[10], pReq[11]);
274		device_printf(mpt->dev, "%08X %08X %08X %08X\n",
275		    pReq[12], pReq[13], pReq[14], pReq[15]);
276	}
277	bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap,
278	   BUS_DMASYNC_PREWRITE);
279	req->debug = REQ_ON_CHIP;
280	mpt_write(mpt, MPT_OFFSET_REQUEST_Q, (u_int32_t) req->req_pbuf);
281}
282
283/*
284 * Give the reply buffer back to the IOC after we have
285 * finished processing it.
286 */
287void
288mpt_free_reply(struct mpt_softc *mpt, u_int32_t ptr)
289{
290     mpt_write(mpt, MPT_OFFSET_REPLY_Q, ptr);
291}
292
293/* Get a reply from the IOC */
294u_int32_t
295mpt_pop_reply_queue(struct mpt_softc *mpt)
296{
297     return mpt_read(mpt, MPT_OFFSET_REPLY_Q);
298}
299
300/*
301 * Send a command to the IOC via the handshake register.
302 *
303 * Only done at initialization time and for certain unusual
304 * commands such as device/bus reset as specified by LSI.
305 */
306int
307mpt_send_handshake_cmd(struct mpt_softc *mpt, size_t len, void *cmd)
308{
309	int i;
310	u_int32_t data, *data32;
311
312	/* Check condition of the IOC */
313	data = mpt_rd_db(mpt);
314	if (((MPT_STATE(data) != MPT_DB_STATE_READY)	&&
315	     (MPT_STATE(data) != MPT_DB_STATE_RUNNING)	&&
316	     (MPT_STATE(data) != MPT_DB_STATE_FAULT))	||
317	    (  MPT_DB_IS_IN_USE(data) )) {
318		device_printf(mpt->dev,
319		    "handshake aborted due to invalid doorbell state\n");
320		mpt_print_db(data);
321		return(EBUSY);
322	}
323
324	/* We move things in 32 bit chunks */
325	len = (len + 3) >> 2;
326	data32 = cmd;
327
328	/* Clear any left over pending doorbell interupts */
329	if (MPT_DB_INTR(mpt_rd_intr(mpt)))
330		mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
331
332	/*
333	 * Tell the handshake reg. we are going to send a command
334         * and how long it is going to be.
335	 */
336	data = (MPI_FUNCTION_HANDSHAKE << MPI_DOORBELL_FUNCTION_SHIFT) |
337	    (len << MPI_DOORBELL_ADD_DWORDS_SHIFT);
338	mpt_write(mpt, MPT_OFFSET_DOORBELL, data);
339
340	/* Wait for the chip to notice */
341	if (mpt_wait_db_int(mpt) != MPT_OK) {
342		device_printf(mpt->dev, "mpt_send_handshake_cmd timeout1!\n");
343		return ETIMEDOUT;
344	}
345
346	/* Clear the interrupt */
347	mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
348
349	if (mpt_wait_db_ack(mpt) != MPT_OK) {
350		device_printf(mpt->dev, "mpt_send_handshake_cmd timeout2!\n");
351		return ETIMEDOUT;
352	}
353
354	/* Send the command */
355	for (i = 0; i < len; i++) {
356		mpt_write(mpt, MPT_OFFSET_DOORBELL, *data32++);
357		if (mpt_wait_db_ack(mpt) != MPT_OK) {
358			device_printf(mpt->dev,
359			    "mpt_send_handshake_cmd timeout! index = %d\n", i);
360			return ETIMEDOUT;
361		}
362	}
363	return MPT_OK;
364}
365
366/* Get the response from the handshake register */
367int
368mpt_recv_handshake_reply(struct mpt_softc *mpt, size_t reply_len, void *reply)
369{
370	int left, reply_left;
371	u_int16_t *data16;
372	MSG_DEFAULT_REPLY *hdr;
373
374	/* We move things out in 16 bit chunks */
375	reply_len >>= 1;
376	data16 = (u_int16_t *)reply;
377
378	hdr = (MSG_DEFAULT_REPLY *)reply;
379
380	/* Get first word */
381	if (mpt_wait_db_int(mpt) != MPT_OK) {
382		device_printf(mpt->dev, "mpt_recv_handshake_cmd timeout1!\n");
383		return ETIMEDOUT;
384	}
385	*data16++ = mpt_read(mpt, MPT_OFFSET_DOORBELL) & MPT_DB_DATA_MASK;
386	mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
387
388	/* Get Second Word */
389	if (mpt_wait_db_int(mpt) != MPT_OK) {
390		device_printf(mpt->dev, "mpt_recv_handshake_cmd timeout2!\n");
391		return ETIMEDOUT;
392	}
393	*data16++ = mpt_read(mpt, MPT_OFFSET_DOORBELL) & MPT_DB_DATA_MASK;
394	mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
395
396	/* With the second word, we can now look at the length */
397	if (mpt->verbose > 1 && ((reply_len >> 1) != hdr->MsgLength)) {
398		device_printf(mpt->dev,
399			"reply length does not match message length: "
400			"got 0x%02x, expected 0x%02x\n",
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			device_printf(mpt->dev,
412			    "mpt_recv_handshake_cmd timeout3!\n");
413			return ETIMEDOUT;
414		}
415		datum = mpt_read(mpt, MPT_OFFSET_DOORBELL);
416
417		if (reply_left-- > 0)
418			*data16++ = datum & MPT_DB_DATA_MASK;
419
420		mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
421	}
422
423	/* One more wait & clear at the end */
424	if (mpt_wait_db_int(mpt) != MPT_OK) {
425		device_printf(mpt->dev, "mpt_recv_handshake_cmd timeout4!\n");
426		return ETIMEDOUT;
427	}
428	mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
429
430	if ((hdr->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
431		if (mpt->verbose > 1)
432			mpt_print_reply(hdr);
433		return (MPT_FAIL | hdr->IOCStatus);
434	}
435
436	return (0);
437}
438
439/* Get API statistics from the chip */
440static int
441mpt_get_iocfacts(struct mpt_softc *mpt, MSG_IOC_FACTS_REPLY *freplp)
442{
443	MSG_IOC_FACTS f_req;
444	int error;
445
446	bzero(&f_req, sizeof f_req);
447	f_req.Function = MPI_FUNCTION_IOC_FACTS;
448	f_req.MsgContext =  0x12071942;
449	error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req);
450	if (error)
451		return(error);
452	error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp);
453	return (error);
454}
455
456/*
457 * Send the initialization request. This is where we specify how many
458 * SCSI busses and how many devices per bus we wish to emulate.
459 * This is also the command that specifies the max size of the reply
460 * frames from the IOC that we will be allocating.
461 */
462static int
463mpt_send_ioc_init(struct mpt_softc *mpt, u_int32_t who)
464{
465	int error = 0;
466	MSG_IOC_INIT init;
467	MSG_IOC_INIT_REPLY reply;
468
469	bzero(&init, sizeof init);
470	init.WhoInit = who;
471	init.Function = MPI_FUNCTION_IOC_INIT;
472	if (mpt->is_fc) {
473		init.MaxDevices = 255;
474	} else {
475		init.MaxDevices = 16;
476	}
477	init.MaxBuses = 1;
478	init.ReplyFrameSize = MPT_REPLY_SIZE;
479	init.MsgContext = 0x12071941;
480
481	if ((error = mpt_send_handshake_cmd(mpt, sizeof init, &init)) != 0) {
482		return(error);
483	}
484
485	error = mpt_recv_handshake_reply(mpt, sizeof reply, &reply);
486	return (error);
487}
488
489/* Send the port enable to allow the IOC to join the FC loop */
490static int
491mpt_send_port_enable(struct mpt_softc *mpt, int port)
492{
493	int count;
494	request_t *req;
495	MSG_PORT_ENABLE *enable_req;
496
497	req = mpt_get_request(mpt);
498
499	enable_req = req->req_vbuf;
500	bzero(enable_req, sizeof *enable_req);
501
502	enable_req->Function   = MPI_FUNCTION_PORT_ENABLE;
503	enable_req->MsgContext = req->index | 0x80000000;
504	enable_req->PortNumber = port;
505
506	mpt_check_doorbell(mpt);
507	if (mpt->verbose > 1) {
508		device_printf(mpt->dev, "enabling port %d\n", port);
509	}
510	mpt_send_cmd(mpt, req);
511
512	count = 0;
513	do {
514		DELAY(500);
515		mpt_intr(mpt);
516		if (++count == 1000) {
517			device_printf(mpt->dev, "port enable timed out\n");
518			return (-1);
519		}
520	} while (req->debug == REQ_ON_CHIP);
521	mpt_free_request(mpt, req);
522	return (0);
523}
524
525/*
526 * Enable/Disable asynchronous event reporting.
527 *
528 * NB: this is the first command we send via shared memory
529 * instead of the handshake register.
530 */
531static int
532mpt_send_event_request(struct mpt_softc *mpt, int onoff)
533{
534	request_t *req;
535	MSG_EVENT_NOTIFY *enable_req;
536
537	req = mpt_get_request(mpt);
538
539	enable_req = req->req_vbuf;
540	bzero(enable_req, sizeof *enable_req);
541
542	enable_req->Function   = MPI_FUNCTION_EVENT_NOTIFICATION;
543	enable_req->MsgContext = req->index | 0x80000000;
544	enable_req->Switch     = onoff;
545
546	mpt_check_doorbell(mpt);
547	if (mpt->verbose > 1) {
548		device_printf(mpt->dev, "%sabling async events\n",
549		    onoff? "en" : "dis");
550	}
551	mpt_send_cmd(mpt, req);
552
553	return (0);
554}
555
556/*
557 * Un-mask the interupts on the chip.
558 */
559void
560mpt_enable_ints(struct mpt_softc *mpt)
561{
562	/* Unmask every thing except door bell int */
563	mpt_write(mpt, MPT_OFFSET_INTR_MASK, MPT_INTR_DB_MASK);
564}
565
566/*
567 * Mask the interupts on the chip.
568 */
569void
570mpt_disable_ints(struct mpt_softc *mpt)
571{
572	/* Mask all interrupts */
573	mpt_write(mpt, MPT_OFFSET_INTR_MASK,
574	    MPT_INTR_REPLY_MASK | MPT_INTR_DB_MASK);
575}
576
577/* (Re)Initialize the chip for use */
578int
579mpt_init(struct mpt_softc *mpt, u_int32_t who)
580{
581        int try;
582        MSG_IOC_FACTS_REPLY facts;
583	u_int32_t pptr;
584        int val;
585
586	/* Put all request buffers (back) on the free list */
587        SLIST_INIT(&mpt->request_free_list);
588	for (val = 0; val < MPT_MAX_REQUESTS; val++) {
589		mpt_free_request(mpt, &mpt->requests[val]);
590	}
591
592	if (mpt->verbose > 1) {
593		device_printf(mpt->dev, "doorbell req = %s\n",
594		    mpt_ioc_diag(mpt_read(mpt, MPT_OFFSET_DOORBELL)));
595	}
596
597	/*
598	 * Start by making sure we're not at FAULT or RESET state
599	 */
600	switch (mpt_rd_db(mpt) & MPT_DB_STATE_MASK) {
601	case MPT_DB_STATE_RESET:
602	case MPT_DB_STATE_FAULT:
603		if (mpt_reset(mpt) != MPT_OK) {
604			return (EIO);
605		}
606	default:
607		break;
608	}
609
610
611	for (try = 0; try < MPT_MAX_TRYS; try++) {
612		/*
613		 * No need to reset if the IOC is already in the READY state.
614		 *
615		 * Force reset if initialization failed previously.
616		 * Note that a hard_reset of the second channel of a '929
617		 * will stop operation of the first channel.  Hopefully, if the
618		 * first channel is ok, the second will not require a hard
619		 * reset.
620		 */
621		if ((mpt_rd_db(mpt) & MPT_DB_STATE_MASK) !=
622		    MPT_DB_STATE_READY) {
623			if (mpt_reset(mpt) != MPT_OK) {
624				DELAY(10000);
625				continue;
626			}
627		}
628
629		if (mpt_get_iocfacts(mpt, &facts) != MPT_OK) {
630			device_printf(mpt->dev, "mpt_get_iocfacts failed\n");
631			continue;
632		} else if (mpt->verbose > 1) {
633			device_printf(mpt->dev,
634			    "mpt_get_iocfacts: GlobalCredits=%d BlockSize=%u "
635			    "Request Frame Size %u\n", facts.GlobalCredits,
636			    facts.BlockSize, facts.RequestFrameSize);
637		}
638		mpt->mpt_global_credits = facts.GlobalCredits;
639		mpt->blk_size = facts.BlockSize;
640		mpt->request_frame_size = facts.RequestFrameSize;
641
642		if (mpt_send_ioc_init(mpt, who) != MPT_OK) {
643			device_printf(mpt->dev, "mpt_send_ioc_init failed\n");
644			continue;
645		} else if (mpt->verbose > 1) {
646			device_printf(mpt->dev, "mpt_send_ioc_init ok\n");
647		}
648
649		if (mpt_wait_state(mpt, MPT_DB_STATE_RUNNING) != MPT_OK) {
650			device_printf(mpt->dev,
651			    "IOC failed to go to run state\n");
652			continue;
653		} else if (mpt->verbose > 1) {
654			device_printf(mpt->dev, "IOC now at RUNSTATE\n");
655		}
656
657		/*
658		 * Give it reply buffers
659		 *
660		 * Do *not* except global credits.
661		 */
662		for (val = 0, pptr = mpt->reply_phys;
663		    (pptr + MPT_REPLY_SIZE) < (mpt->reply_phys + PAGE_SIZE);
664		     pptr += MPT_REPLY_SIZE) {
665			mpt_free_reply(mpt, pptr);
666			if (++val == mpt->mpt_global_credits - 1)
667				break;
668		}
669
670		mpt_send_event_request(mpt, 1);
671
672		if (mpt_send_port_enable(mpt, 0) != MPT_OK) {
673			device_printf(mpt->dev, "failed to enable port 0\n");
674			continue;
675		} else if (mpt->verbose > 1) {
676			device_printf(mpt->dev, "enabled port 0\n");
677		}
678
679		/* Everything worked */
680		break;
681	}
682
683	if (try >= MPT_MAX_TRYS) {
684		device_printf(mpt->dev, "failed to initialize IOC\n");
685		return (EIO);
686	}
687
688	if (mpt->verbose > 1) {
689		device_printf(mpt->dev, "enabling interrupts\n");
690	}
691
692	mpt_enable_ints(mpt);
693	return (0);
694}
695