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