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