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