1 /* $FreeBSD: src/sys/dev/mpt/mpt.c,v 1.3.2.3 2002/09/24 21:37:24 mjacob Exp $ */
2 /* $DragonFly: src/sys/dev/disk/mpt/mpt.c,v 1.3 2003/08/07 21:16:53 dillon Exp $ */
4 * Generic routines for LSI '909 FC adapters.
7 * Copyright (c) 2000, 2001 by Greg Ansley
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
31 * Additional Copyright (c) 2002 by Matthew Jacob under same license.
34 #include "mpt_freebsd.h"
36 #define MPT_MAX_TRYS 3
37 #define MPT_MAX_WAIT 300000
39 static int maxwait_ack = 0;
40 static int maxwait_int = 0;
41 static int maxwait_state = 0;
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);
46 static __inline u_int32_t
47 mpt_rd_db(mpt_softc_t *mpt)
49 return mpt_read(mpt, MPT_OFFSET_DOORBELL);
52 static __inline u_int32_t
53 mpt_rd_intr(mpt_softc_t *mpt)
55 return mpt_read(mpt, MPT_OFFSET_INTR_STATUS);
58 /* Busy wait for a door bell to be read by IOC */
60 mpt_wait_db_ack(mpt_softc_t *mpt)
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;
74 /* Busy wait for a door bell interrupt */
76 mpt_wait_db_int(mpt_softc_t *mpt)
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;
89 /* Wait for IOC to transition to a give state */
91 mpt_check_doorbell(mpt_softc_t *mpt)
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");
100 /* Wait for IOC to transition to a give state */
102 mpt_wait_state(mpt_softc_t *mpt, enum DB_STATE_BITS state)
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;
118 /* Issue the reset COMMAND to the IOC */
120 mpt_soft_reset(mpt_softc_t *mpt)
123 device_printf(mpt->dev,"soft reset\n");
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");
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.
137 if (MPT_DB_IS_IN_USE(mpt_rd_db(mpt))) {
138 device_printf(mpt->dev, "soft reset failed: doorbell wedged\n");
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");
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");
160 /* This is a magic diagnostic reset that resets all the ARM
161 * processors in the chip.
164 mpt_hard_reset(mpt_softc_t *mpt)
166 /* This extra read comes for the Linux source
167 * released by LSI. It's function is undocumented!
170 device_printf(mpt->dev, "hard reset\n");
172 mpt_read(mpt, MPT_OFFSET_FUBAR);
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);
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);
186 /* Disable Diagnostic Register */
187 mpt_write(mpt, MPT_OFFSET_SEQUENCE, 0xFF);
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);
197 /* Note that if there is no valid firmware to run, the doorbell will
198 remain in the reset state (0x00000000) */
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.
208 mpt_reset(mpt_softc_t *mpt)
212 /* Try a soft reset */
213 if ((ret = mpt_soft_reset(mpt)) != MPT_OK) {
214 /* Failed; do a hard reset */
217 /* Wait for the IOC to reload and come out of reset state */
218 ret = mpt_wait_state(mpt, MPT_DB_STATE_READY);
220 device_printf(mpt->dev, "failed to reset device\n");
227 /* Return a command buffer to the free queue */
229 mpt_free_request(mpt_softc_t *mpt, request_t *req)
231 if (req == NULL || req != &mpt->request_pool[req->index]) {
232 panic("mpt_free_request bad req ptr\n");
237 req->debug = REQ_FREE;
238 SLIST_INSERT_HEAD(&mpt->request_free_list, req, link);
241 /* Get a command buffer from the free queue */
243 mpt_get_request(mpt_softc_t *mpt)
246 req = SLIST_FIRST(&mpt->request_free_list);
248 if (req != &mpt->request_pool[req->index]) {
249 panic("mpt_get_request: corrupted request free list\n");
251 if (req->ccb != NULL) {
252 panic("mpt_get_request: corrupted request free list (ccb)\n");
254 SLIST_REMOVE_HEAD(&mpt->request_free_list, link);
255 req->debug = REQ_IN_PROGRESS;
260 /* Pass the command to the IOC */
262 mpt_send_cmd(mpt_softc_t *mpt, request_t *req)
264 req->sequence = mpt->sequence++;
265 if (mpt->verbose > 1) {
267 pReq = req->req_vbuf;
268 device_printf(mpt->dev, "Send Request %d (0x%lx):\n",
269 req->index, (long) req->req_pbuf);
270 device_printf(mpt->dev, "%08X %08X %08X %08X\n",
271 pReq[0], pReq[1], pReq[2], pReq[3]);
272 device_printf(mpt->dev, "%08X %08X %08X %08X\n",
273 pReq[4], pReq[5], pReq[6], pReq[7]);
274 device_printf(mpt->dev, "%08X %08X %08X %08X\n",
275 pReq[8], pReq[9], pReq[10], pReq[11]);
276 device_printf(mpt->dev, "%08X %08X %08X %08X\n",
277 pReq[12], pReq[13], pReq[14], pReq[15]);
279 bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap,
280 BUS_DMASYNC_PREWRITE);
281 req->debug = REQ_ON_CHIP;
282 mpt_write(mpt, MPT_OFFSET_REQUEST_Q, (u_int32_t) req->req_pbuf);
286 * Give the reply buffer back to the IOC after we have
287 * finished processing it.
290 mpt_free_reply(mpt_softc_t *mpt, u_int32_t ptr)
292 mpt_write(mpt, MPT_OFFSET_REPLY_Q, ptr);
295 /* Get a reply from the IOC */
297 mpt_pop_reply_queue(mpt_softc_t *mpt)
299 return mpt_read(mpt, MPT_OFFSET_REPLY_Q);
303 * Send a command to the IOC via the handshake register.
305 * Only done at initialization time and for certain unusual
306 * commands such as device/bus reset as specified by LSI.
309 mpt_send_handshake_cmd(mpt_softc_t *mpt, size_t len, void *cmd)
312 u_int32_t data, *data32;
314 /* Check condition of the IOC */
315 data = mpt_rd_db(mpt);
316 if (((MPT_STATE(data) != MPT_DB_STATE_READY) &&
317 (MPT_STATE(data) != MPT_DB_STATE_RUNNING) &&
318 (MPT_STATE(data) != MPT_DB_STATE_FAULT)) ||
319 ( MPT_DB_IS_IN_USE(data) )) {
320 device_printf(mpt->dev,
321 "handshake aborted due to invalid doorbell state\n");
326 /* We move things in 32 bit chunks */
327 len = (len + 3) >> 2;
330 /* Clear any left over pending doorbell interupts */
331 if (MPT_DB_INTR(mpt_rd_intr(mpt)))
332 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
335 * Tell the handshake reg. we are going to send a command
336 * and how long it is going to be.
338 data = (MPI_FUNCTION_HANDSHAKE << MPI_DOORBELL_FUNCTION_SHIFT) |
339 (len << MPI_DOORBELL_ADD_DWORDS_SHIFT);
340 mpt_write(mpt, MPT_OFFSET_DOORBELL, data);
342 /* Wait for the chip to notice */
343 if (mpt_wait_db_int(mpt) != MPT_OK) {
344 device_printf(mpt->dev, "mpt_send_handshake_cmd timeout1!\n");
348 /* Clear the interrupt */
349 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
351 if (mpt_wait_db_ack(mpt) != MPT_OK) {
352 device_printf(mpt->dev, "mpt_send_handshake_cmd timeout2!\n");
356 /* Send the command */
357 for (i = 0; i < len; i++) {
358 mpt_write(mpt, MPT_OFFSET_DOORBELL, *data32++);
359 if (mpt_wait_db_ack(mpt) != MPT_OK) {
360 device_printf(mpt->dev,
361 "mpt_send_handshake_cmd timeout! index = %d\n", i);
368 /* Get the response from the handshake register */
370 mpt_recv_handshake_reply(mpt_softc_t *mpt, size_t reply_len, void *reply)
372 int left, reply_left;
374 MSG_DEFAULT_REPLY *hdr;
376 /* We move things out in 16 bit chunks */
378 data16 = (u_int16_t *)reply;
380 hdr = (MSG_DEFAULT_REPLY *)reply;
383 if (mpt_wait_db_int(mpt) != MPT_OK) {
384 device_printf(mpt->dev, "mpt_recv_handshake_cmd timeout1!\n");
387 *data16++ = mpt_read(mpt, MPT_OFFSET_DOORBELL) & MPT_DB_DATA_MASK;
388 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
390 /* Get Second Word */
391 if (mpt_wait_db_int(mpt) != MPT_OK) {
392 device_printf(mpt->dev, "mpt_recv_handshake_cmd timeout2!\n");
395 *data16++ = mpt_read(mpt, MPT_OFFSET_DOORBELL) & MPT_DB_DATA_MASK;
396 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
398 /* With the second word, we can now look at the length */
399 if (mpt->verbose > 1 && ((reply_len >> 1) != hdr->MsgLength)) {
400 device_printf(mpt->dev,
401 "reply length does not match message length: "
402 "got 0x%02x, expected 0x%02lx\n",
403 hdr->MsgLength << 2, (long) (reply_len << 1));
406 /* Get rest of the reply; but don't overflow the provided buffer */
407 left = (hdr->MsgLength << 1) - 2;
408 reply_left = reply_len - 2;
412 if (mpt_wait_db_int(mpt) != MPT_OK) {
413 device_printf(mpt->dev,
414 "mpt_recv_handshake_cmd timeout3!\n");
417 datum = mpt_read(mpt, MPT_OFFSET_DOORBELL);
419 if (reply_left-- > 0)
420 *data16++ = datum & MPT_DB_DATA_MASK;
422 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
425 /* One more wait & clear at the end */
426 if (mpt_wait_db_int(mpt) != MPT_OK) {
427 device_printf(mpt->dev, "mpt_recv_handshake_cmd timeout4!\n");
430 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
432 if ((hdr->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
433 if (mpt->verbose > 1)
434 mpt_print_reply(hdr);
435 return (MPT_FAIL | hdr->IOCStatus);
442 mpt_get_iocfacts(mpt_softc_t *mpt, MSG_IOC_FACTS_REPLY *freplp)
447 bzero(&f_req, sizeof f_req);
448 f_req.Function = MPI_FUNCTION_IOC_FACTS;
449 f_req.MsgContext = 0x12071942;
450 error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req);
453 error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp);
458 mpt_get_portfacts(mpt_softc_t *mpt, MSG_PORT_FACTS_REPLY *freplp)
460 MSG_PORT_FACTS f_req;
463 /* XXX: Only getting PORT FACTS for Port 0 */
464 bzero(&f_req, sizeof f_req);
465 f_req.Function = MPI_FUNCTION_PORT_FACTS;
466 f_req.MsgContext = 0x12071943;
467 error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req);
470 error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp);
475 * Send the initialization request. This is where we specify how many
476 * SCSI busses and how many devices per bus we wish to emulate.
477 * This is also the command that specifies the max size of the reply
478 * frames from the IOC that we will be allocating.
481 mpt_send_ioc_init(mpt_softc_t *mpt, u_int32_t who)
485 MSG_IOC_INIT_REPLY reply;
487 bzero(&init, sizeof init);
489 init.Function = MPI_FUNCTION_IOC_INIT;
491 init.MaxDevices = 255;
493 init.MaxDevices = 16;
496 init.ReplyFrameSize = MPT_REPLY_SIZE;
497 init.MsgContext = 0x12071941;
499 if ((error = mpt_send_handshake_cmd(mpt, sizeof init, &init)) != 0) {
503 error = mpt_recv_handshake_reply(mpt, sizeof reply, &reply);
509 * Utiltity routine to read configuration headers and pages
513 mpt_read_cfg_header(mpt_softc_t *, int, int, int, fCONFIG_PAGE_HEADER *);
516 mpt_read_cfg_header(mpt_softc_t *mpt, int PageType, int PageNumber,
517 int PageAddress, fCONFIG_PAGE_HEADER *rslt)
522 MSG_CONFIG_REPLY *reply;
524 req = mpt_get_request(mpt);
526 cfgp = req->req_vbuf;
527 bzero(cfgp, sizeof *cfgp);
529 cfgp->Action = MPI_CONFIG_ACTION_PAGE_HEADER;
530 cfgp->Function = MPI_FUNCTION_CONFIG;
531 cfgp->Header.PageNumber = (U8) PageNumber;
532 cfgp->Header.PageType = (U8) PageType;
533 cfgp->PageAddress = PageAddress;
534 MPI_pSGE_SET_FLAGS(((SGE_SIMPLE32 *) &cfgp->PageBufferSGE),
535 (MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
536 MPI_SGE_FLAGS_SIMPLE_ELEMENT | MPI_SGE_FLAGS_END_OF_LIST));
537 cfgp->MsgContext = req->index | 0x80000000;
539 mpt_check_doorbell(mpt);
540 mpt_send_cmd(mpt, req);
545 if (++count == 1000) {
546 device_printf(mpt->dev, "read_cfg_header timed out\n");
549 } while (req->debug == REQ_ON_CHIP);
551 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
552 if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
553 device_printf(mpt->dev,
554 "mpt_read_cfg_header: Config Info Status %x\n",
556 mpt_free_reply(mpt, (req->sequence << 1));
559 bcopy(&reply->Header, rslt, sizeof (fCONFIG_PAGE_HEADER));
560 mpt_free_reply(mpt, (req->sequence << 1));
561 mpt_free_request(mpt, req);
565 #define CFG_DATA_OFF 128
568 mpt_read_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr)
575 MSG_CONFIG_REPLY *reply;
577 req = mpt_get_request(mpt);
579 cfgp = req->req_vbuf;
580 bzero(cfgp, MPT_REQUEST_AREA);
581 cfgp->Action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
582 cfgp->Function = MPI_FUNCTION_CONFIG;
584 amt = (cfgp->Header.PageLength * sizeof (u_int32_t));
585 cfgp->Header.PageType &= MPI_CONFIG_PAGETYPE_MASK;
586 cfgp->PageAddress = PageAddress;
587 se = (SGE_SIMPLE32 *) &cfgp->PageBufferSGE;
588 se->Address = req->req_pbuf + CFG_DATA_OFF;
589 MPI_pSGE_SET_LENGTH(se, amt);
590 MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
591 MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
592 MPI_SGE_FLAGS_END_OF_LIST));
594 cfgp->MsgContext = req->index | 0x80000000;
596 mpt_check_doorbell(mpt);
597 mpt_send_cmd(mpt, req);
602 if (++count == 1000) {
603 device_printf(mpt->dev, "read_cfg_page timed out\n");
606 } while (req->debug == REQ_ON_CHIP);
608 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
609 if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
610 device_printf(mpt->dev,
611 "mpt_read_cfg_page: Config Info Status %x\n",
613 mpt_free_reply(mpt, (req->sequence << 1));
616 mpt_free_reply(mpt, (req->sequence << 1));
617 bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap,
618 BUS_DMASYNC_POSTREAD);
619 if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
620 cfgp->Header.PageNumber == 0) {
621 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_0);
622 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
623 cfgp->Header.PageNumber == 1) {
624 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_1);
625 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
626 cfgp->Header.PageNumber == 2) {
627 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_2);
628 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
629 cfgp->Header.PageNumber == 0) {
630 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_0);
631 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
632 cfgp->Header.PageNumber == 1) {
633 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_1);
635 bcopy(((caddr_t)req->req_vbuf)+CFG_DATA_OFF, hdr, amt);
636 mpt_free_request(mpt, req);
641 mpt_write_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr)
648 MSG_CONFIG_REPLY *reply;
650 req = mpt_get_request(mpt);
652 cfgp = req->req_vbuf;
653 bzero(cfgp, sizeof *cfgp);
655 hdr_attr = hdr->PageType & MPI_CONFIG_PAGEATTR_MASK;
656 if (hdr_attr != MPI_CONFIG_PAGEATTR_CHANGEABLE &&
657 hdr_attr != MPI_CONFIG_PAGEATTR_PERSISTENT) {
658 device_printf(mpt->dev, "page type 0x%x not changeable\n",
659 hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
662 hdr->PageType &= MPI_CONFIG_PAGETYPE_MASK;
664 cfgp->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
665 cfgp->Function = MPI_FUNCTION_CONFIG;
667 amt = (cfgp->Header.PageLength * sizeof (u_int32_t));
668 cfgp->PageAddress = PageAddress;
670 se = (SGE_SIMPLE32 *) &cfgp->PageBufferSGE;
671 se->Address = req->req_pbuf + CFG_DATA_OFF;
672 MPI_pSGE_SET_LENGTH(se, amt);
673 MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
674 MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
675 MPI_SGE_FLAGS_END_OF_LIST | MPI_SGE_FLAGS_HOST_TO_IOC));
677 cfgp->MsgContext = req->index | 0x80000000;
679 if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
680 cfgp->Header.PageNumber == 0) {
681 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_0);
682 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
683 cfgp->Header.PageNumber == 1) {
684 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_1);
685 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
686 cfgp->Header.PageNumber == 2) {
687 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_2);
688 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
689 cfgp->Header.PageNumber == 0) {
690 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_0);
691 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
692 cfgp->Header.PageNumber == 1) {
693 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_1);
695 bcopy(hdr, ((caddr_t)req->req_vbuf)+CFG_DATA_OFF, amt);
696 /* Restore stripped out attributes */
697 hdr->PageType |= hdr_attr;
699 mpt_check_doorbell(mpt);
700 mpt_send_cmd(mpt, req);
705 if (++count == 1000) {
706 hdr->PageType |= hdr_attr;
707 device_printf(mpt->dev,
708 "mpt_write_cfg_page timed out\n");
711 } while (req->debug == REQ_ON_CHIP);
713 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
714 if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
715 device_printf(mpt->dev,
716 "mpt_write_cfg_page: Config Info Status %x\n",
718 mpt_free_reply(mpt, (req->sequence << 1));
721 mpt_free_reply(mpt, (req->sequence << 1));
723 mpt_free_request(mpt, req);
728 * Read SCSI configuration information
731 mpt_read_config_info_spi(mpt_softc_t *mpt)
735 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 0,
736 0, &mpt->mpt_port_page0.Header);
740 if (mpt->verbose > 1) {
741 device_printf(mpt->dev, "SPI Port Page 0 Header: %x %x %x %x\n",
742 mpt->mpt_port_page0.Header.PageVersion,
743 mpt->mpt_port_page0.Header.PageLength,
744 mpt->mpt_port_page0.Header.PageNumber,
745 mpt->mpt_port_page0.Header.PageType);
748 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 1,
749 0, &mpt->mpt_port_page1.Header);
753 if (mpt->verbose > 1) {
754 device_printf(mpt->dev, "SPI Port Page 1 Header: %x %x %x %x\n",
755 mpt->mpt_port_page1.Header.PageVersion,
756 mpt->mpt_port_page1.Header.PageLength,
757 mpt->mpt_port_page1.Header.PageNumber,
758 mpt->mpt_port_page1.Header.PageType);
761 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 2,
762 0, &mpt->mpt_port_page2.Header);
767 if (mpt->verbose > 1) {
768 device_printf(mpt->dev, "SPI Port Page 2 Header: %x %x %x %x\n",
769 mpt->mpt_port_page1.Header.PageVersion,
770 mpt->mpt_port_page1.Header.PageLength,
771 mpt->mpt_port_page1.Header.PageNumber,
772 mpt->mpt_port_page1.Header.PageType);
775 for (i = 0; i < 16; i++) {
776 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
777 0, i, &mpt->mpt_dev_page0[i].Header);
781 if (mpt->verbose > 1) {
782 device_printf(mpt->dev,
783 "SPI Target %d Device Page 0 Header: %x %x %x %x\n",
784 i, mpt->mpt_dev_page0[i].Header.PageVersion,
785 mpt->mpt_dev_page0[i].Header.PageLength,
786 mpt->mpt_dev_page0[i].Header.PageNumber,
787 mpt->mpt_dev_page0[i].Header.PageType);
790 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
791 1, i, &mpt->mpt_dev_page1[i].Header);
795 if (mpt->verbose > 1) {
796 device_printf(mpt->dev,
797 "SPI Target %d Device Page 1 Header: %x %x %x %x\n",
798 i, mpt->mpt_dev_page1[i].Header.PageVersion,
799 mpt->mpt_dev_page1[i].Header.PageLength,
800 mpt->mpt_dev_page1[i].Header.PageNumber,
801 mpt->mpt_dev_page1[i].Header.PageType);
806 * At this point, we don't *have* to fail. As long as we have
807 * valid config header information, we can (barely) lurch
811 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page0.Header);
813 device_printf(mpt->dev, "failed to read SPI Port Page 0\n");
814 } else if (mpt->verbose > 1) {
815 device_printf(mpt->dev,
816 "SPI Port Page 0: Capabilities %x PhysicalInterface %x\n",
817 mpt->mpt_port_page0.Capabilities,
818 mpt->mpt_port_page0.PhysicalInterface);
821 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page1.Header);
823 device_printf(mpt->dev, "failed to read SPI Port Page 1\n");
824 } else if (mpt->verbose > 1) {
825 device_printf(mpt->dev,
826 "SPI Port Page 1: Configuration %x OnBusTimerValue %x\n",
827 mpt->mpt_port_page1.Configuration,
828 mpt->mpt_port_page1.OnBusTimerValue);
831 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page2.Header);
833 device_printf(mpt->dev, "failed to read SPI Port Page 2\n");
834 } else if (mpt->verbose > 1) {
835 device_printf(mpt->dev,
836 "SPI Port Page 2: Flags %x Settings %x\n",
837 mpt->mpt_port_page2.PortFlags,
838 mpt->mpt_port_page2.PortSettings);
839 for (i = 0; i < 16; i++) {
840 device_printf(mpt->dev,
841 "SPI Port Page 2 Tgt %d: timo %x SF %x Flags %x\n",
842 i, mpt->mpt_port_page2.DeviceSettings[i].Timeout,
843 mpt->mpt_port_page2.DeviceSettings[i].SyncFactor,
844 mpt->mpt_port_page2.DeviceSettings[i].DeviceFlags);
848 for (i = 0; i < 16; i++) {
849 rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page0[i].Header);
851 device_printf(mpt->dev,
852 "cannot read SPI Tgt %d Device Page 0\n", i);
855 if (mpt->verbose > 1) {
856 device_printf(mpt->dev,
857 "SPI Tgt %d Page 0: NParms %x Information %x\n",
858 i, mpt->mpt_dev_page0[i].NegotiatedParameters,
859 mpt->mpt_dev_page0[i].Information);
861 rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page1[i].Header);
863 device_printf(mpt->dev,
864 "cannot read SPI Tgt %d Device Page 1\n", i);
867 if (mpt->verbose > 1) {
868 device_printf(mpt->dev,
869 "SPI Tgt %d Page 1: RParms %x Configuration %x\n",
870 i, mpt->mpt_dev_page1[i].RequestedParameters,
871 mpt->mpt_dev_page1[i].Configuration);
878 * Validate SPI configuration information.
880 * In particular, validate SPI Port Page 1.
883 mpt_set_initial_config_spi(mpt_softc_t *mpt)
885 int i, pp1val = ((1 << mpt->mpt_ini_id) << 16) | mpt->mpt_ini_id;
887 mpt->mpt_disc_enable = 0xff;
888 mpt->mpt_tag_enable = 0;
890 if (mpt->mpt_port_page1.Configuration != pp1val) {
891 fCONFIG_PAGE_SCSI_PORT_1 tmp;
892 device_printf(mpt->dev,
893 "SPI Port Page 1 Config value bad (%x)- should be %x\n",
894 mpt->mpt_port_page1.Configuration, pp1val);
895 tmp = mpt->mpt_port_page1;
896 tmp.Configuration = pp1val;
897 if (mpt_write_cfg_page(mpt, 0, &tmp.Header)) {
900 if (mpt_read_cfg_page(mpt, 0, &tmp.Header)) {
903 if (tmp.Configuration != pp1val) {
904 device_printf(mpt->dev,
905 "failed to reset SPI Port Page 1 Config value\n");
908 mpt->mpt_port_page1 = tmp;
911 for (i = 0; i < 16; i++) {
912 fCONFIG_PAGE_SCSI_DEVICE_1 tmp;
913 tmp = mpt->mpt_dev_page1[i];
914 tmp.RequestedParameters = 0;
915 tmp.Configuration = 0;
916 if (mpt->verbose > 1) {
917 device_printf(mpt->dev,
918 "Set Tgt %d SPI DevicePage 1 values to %x 0 %x\n",
919 i, tmp.RequestedParameters, tmp.Configuration);
921 if (mpt_write_cfg_page(mpt, i, &tmp.Header)) {
924 if (mpt_read_cfg_page(mpt, i, &tmp.Header)) {
927 mpt->mpt_dev_page1[i] = tmp;
928 if (mpt->verbose > 1) {
929 device_printf(mpt->dev,
930 "SPI Tgt %d Page 1: RParm %x Configuration %x\n", i,
931 mpt->mpt_dev_page1[i].RequestedParameters,
932 mpt->mpt_dev_page1[i].Configuration);
942 mpt_send_port_enable(mpt_softc_t *mpt, int port)
946 MSG_PORT_ENABLE *enable_req;
948 req = mpt_get_request(mpt);
950 enable_req = req->req_vbuf;
951 bzero(enable_req, sizeof *enable_req);
953 enable_req->Function = MPI_FUNCTION_PORT_ENABLE;
954 enable_req->MsgContext = req->index | 0x80000000;
955 enable_req->PortNumber = port;
957 mpt_check_doorbell(mpt);
958 if (mpt->verbose > 1) {
959 device_printf(mpt->dev, "enabling port %d\n", port);
961 mpt_send_cmd(mpt, req);
967 if (++count == 100000) {
968 device_printf(mpt->dev, "port enable timed out\n");
971 } while (req->debug == REQ_ON_CHIP);
972 mpt_free_request(mpt, req);
977 * Enable/Disable asynchronous event reporting.
979 * NB: this is the first command we send via shared memory
980 * instead of the handshake register.
983 mpt_send_event_request(mpt_softc_t *mpt, int onoff)
986 MSG_EVENT_NOTIFY *enable_req;
988 req = mpt_get_request(mpt);
990 enable_req = req->req_vbuf;
991 bzero(enable_req, sizeof *enable_req);
993 enable_req->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
994 enable_req->MsgContext = req->index | 0x80000000;
995 enable_req->Switch = onoff;
997 mpt_check_doorbell(mpt);
998 if (mpt->verbose > 1) {
999 device_printf(mpt->dev, "%sabling async events\n",
1000 onoff? "en" : "dis");
1002 mpt_send_cmd(mpt, req);
1008 * Un-mask the interupts on the chip.
1011 mpt_enable_ints(mpt_softc_t *mpt)
1013 /* Unmask every thing except door bell int */
1014 mpt_write(mpt, MPT_OFFSET_INTR_MASK, MPT_INTR_DB_MASK);
1018 * Mask the interupts on the chip.
1021 mpt_disable_ints(mpt_softc_t *mpt)
1023 /* Mask all interrupts */
1024 mpt_write(mpt, MPT_OFFSET_INTR_MASK,
1025 MPT_INTR_REPLY_MASK | MPT_INTR_DB_MASK);
1028 /* (Re)Initialize the chip for use */
1030 mpt_init(mpt_softc_t *mpt, u_int32_t who)
1033 MSG_IOC_FACTS_REPLY facts;
1034 MSG_PORT_FACTS_REPLY pfp;
1038 /* Put all request buffers (back) on the free list */
1039 SLIST_INIT(&mpt->request_free_list);
1040 for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++) {
1041 mpt_free_request(mpt, &mpt->request_pool[val]);
1044 if (mpt->verbose > 1) {
1045 device_printf(mpt->dev, "doorbell req = %s\n",
1046 mpt_ioc_diag(mpt_read(mpt, MPT_OFFSET_DOORBELL)));
1050 * Start by making sure we're not at FAULT or RESET state
1052 switch (mpt_rd_db(mpt) & MPT_DB_STATE_MASK) {
1053 case MPT_DB_STATE_RESET:
1054 case MPT_DB_STATE_FAULT:
1055 if (mpt_reset(mpt) != MPT_OK) {
1062 for (try = 0; try < MPT_MAX_TRYS; try++) {
1064 * No need to reset if the IOC is already in the READY state.
1066 * Force reset if initialization failed previously.
1067 * Note that a hard_reset of the second channel of a '929
1068 * will stop operation of the first channel. Hopefully, if the
1069 * first channel is ok, the second will not require a hard
1072 if ((mpt_rd_db(mpt) & MPT_DB_STATE_MASK) !=
1073 MPT_DB_STATE_READY) {
1074 if (mpt_reset(mpt) != MPT_OK) {
1080 if (mpt_get_iocfacts(mpt, &facts) != MPT_OK) {
1081 device_printf(mpt->dev, "mpt_get_iocfacts failed\n");
1085 if (mpt->verbose > 1) {
1086 device_printf(mpt->dev,
1087 "IOCFACTS: GlobalCredits=%d BlockSize=%u "
1088 "Request Frame Size %u\n", facts.GlobalCredits,
1089 facts.BlockSize, facts.RequestFrameSize);
1091 mpt->mpt_global_credits = facts.GlobalCredits;
1092 mpt->request_frame_size = facts.RequestFrameSize;
1094 if (mpt_get_portfacts(mpt, &pfp) != MPT_OK) {
1095 device_printf(mpt->dev, "mpt_get_portfacts failed\n");
1099 if (mpt->verbose > 1) {
1100 device_printf(mpt->dev,
1101 "PORTFACTS: Type %x PFlags %x IID %d MaxDev %d\n",
1102 pfp.PortType, pfp.ProtocolFlags, pfp.PortSCSIID,
1106 if (pfp.PortType != MPI_PORTFACTS_PORTTYPE_SCSI &&
1107 pfp.PortType != MPI_PORTFACTS_PORTTYPE_FC) {
1108 device_printf(mpt->dev, "Unsupported Port Type (%x)\n",
1112 if (!(pfp.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
1113 device_printf(mpt->dev, "initiator role unsupported\n");
1116 if (pfp.PortType == MPI_PORTFACTS_PORTTYPE_FC) {
1121 mpt->mpt_ini_id = pfp.PortSCSIID;
1123 if (mpt_send_ioc_init(mpt, who) != MPT_OK) {
1124 device_printf(mpt->dev, "mpt_send_ioc_init failed\n");
1128 if (mpt->verbose > 1) {
1129 device_printf(mpt->dev, "mpt_send_ioc_init ok\n");
1132 if (mpt_wait_state(mpt, MPT_DB_STATE_RUNNING) != MPT_OK) {
1133 device_printf(mpt->dev,
1134 "IOC failed to go to run state\n");
1137 if (mpt->verbose > 1) {
1138 device_printf(mpt->dev, "IOC now at RUNSTATE\n");
1142 * Give it reply buffers
1144 * Do *not* except global credits.
1146 for (val = 0, pptr = mpt->reply_phys;
1147 (pptr + MPT_REPLY_SIZE) < (mpt->reply_phys + PAGE_SIZE);
1148 pptr += MPT_REPLY_SIZE) {
1149 mpt_free_reply(mpt, pptr);
1150 if (++val == mpt->mpt_global_credits - 1)
1155 * Enable asynchronous event reporting
1157 mpt_send_event_request(mpt, 1);
1161 * Read set up initial configuration information
1162 * (SPI only for now)
1165 if (mpt->is_fc == 0) {
1166 if (mpt_read_config_info_spi(mpt)) {
1169 if (mpt_set_initial_config_spi(mpt)) {
1175 * Now enable the port
1177 if (mpt_send_port_enable(mpt, 0) != MPT_OK) {
1178 device_printf(mpt->dev, "failed to enable port 0\n");
1182 if (mpt->verbose > 1) {
1183 device_printf(mpt->dev, "enabled port 0\n");
1186 /* Everything worked */
1190 if (try >= MPT_MAX_TRYS) {
1191 device_printf(mpt->dev, "failed to initialize IOC\n");
1195 if (mpt->verbose > 1) {
1196 device_printf(mpt->dev, "enabling interrupts\n");
1199 mpt_enable_ints(mpt);