kernel tree reorganization stage 1: Major cvs repository work (not logged as
[dragonfly.git] / sys / dev / disk / mpt / mpt.c
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.3 2003/08/07 21:16:53 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 "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 }