1 /* $FreeBSD: src/sys/dev/mpt/mpt.c,v 1.3.2.3 2002/09/24 21:37:24 mjacob Exp $ */
3 * Generic routines for LSI '909 FC adapters.
6 * Copyright (c) 2000, 2001 by Greg Ansley
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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
30 * Additional Copyright (c) 2002 by Matthew Jacob under same license.
33 #include <dev/mpt/mpt_freebsd.h>
35 #define MPT_MAX_TRYS 3
36 #define MPT_MAX_WAIT 300000
38 static int maxwait_ack = 0;
39 static int maxwait_int = 0;
40 static int maxwait_state = 0;
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);
45 static __inline u_int32_t
46 mpt_rd_db(mpt_softc_t *mpt)
48 return mpt_read(mpt, MPT_OFFSET_DOORBELL);
51 static __inline u_int32_t
52 mpt_rd_intr(mpt_softc_t *mpt)
54 return mpt_read(mpt, MPT_OFFSET_INTR_STATUS);
57 /* Busy wait for a door bell to be read by IOC */
59 mpt_wait_db_ack(mpt_softc_t *mpt)
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;
73 /* Busy wait for a door bell interrupt */
75 mpt_wait_db_int(mpt_softc_t *mpt)
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;
88 /* Wait for IOC to transition to a give state */
90 mpt_check_doorbell(mpt_softc_t *mpt)
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");
99 /* Wait for IOC to transition to a give state */
101 mpt_wait_state(mpt_softc_t *mpt, enum DB_STATE_BITS state)
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;
117 /* Issue the reset COMMAND to the IOC */
119 mpt_soft_reset(mpt_softc_t *mpt)
122 device_printf(mpt->dev,"soft reset\n");
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");
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.
136 if (MPT_DB_IS_IN_USE(mpt_rd_db(mpt))) {
137 device_printf(mpt->dev, "soft reset failed: doorbell wedged\n");
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");
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");
159 /* This is a magic diagnostic reset that resets all the ARM
160 * processors in the chip.
163 mpt_hard_reset(mpt_softc_t *mpt)
165 /* This extra read comes for the Linux source
166 * released by LSI. It's function is undocumented!
169 device_printf(mpt->dev, "hard reset\n");
171 mpt_read(mpt, MPT_OFFSET_FUBAR);
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);
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);
185 /* Disable Diagnostic Register */
186 mpt_write(mpt, MPT_OFFSET_SEQUENCE, 0xFF);
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);
196 /* Note that if there is no valid firmware to run, the doorbell will
197 remain in the reset state (0x00000000) */
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.
207 mpt_reset(mpt_softc_t *mpt)
211 /* Try a soft reset */
212 if ((ret = mpt_soft_reset(mpt)) != MPT_OK) {
213 /* Failed; do a hard reset */
216 /* Wait for the IOC to reload and come out of reset state */
217 ret = mpt_wait_state(mpt, MPT_DB_STATE_READY);
219 device_printf(mpt->dev, "failed to reset device\n");
226 /* Return a command buffer to the free queue */
228 mpt_free_request(mpt_softc_t *mpt, request_t *req)
230 if (req == NULL || req != &mpt->request_pool[req->index]) {
231 panic("mpt_free_request bad req ptr\n");
236 req->debug = REQ_FREE;
237 SLIST_INSERT_HEAD(&mpt->request_free_list, req, link);
240 /* Get a command buffer from the free queue */
242 mpt_get_request(mpt_softc_t *mpt)
245 req = SLIST_FIRST(&mpt->request_free_list);
247 if (req != &mpt->request_pool[req->index]) {
248 panic("mpt_get_request: corrupted request free list\n");
250 if (req->ccb != NULL) {
251 panic("mpt_get_request: corrupted request free list (ccb)\n");
253 SLIST_REMOVE_HEAD(&mpt->request_free_list, link);
254 req->debug = REQ_IN_PROGRESS;
259 /* Pass the command to the IOC */
261 mpt_send_cmd(mpt_softc_t *mpt, request_t *req)
263 req->sequence = mpt->sequence++;
264 if (mpt->verbose > 1) {
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]);
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);
285 * Give the reply buffer back to the IOC after we have
286 * finished processing it.
289 mpt_free_reply(mpt_softc_t *mpt, u_int32_t ptr)
291 mpt_write(mpt, MPT_OFFSET_REPLY_Q, ptr);
294 /* Get a reply from the IOC */
296 mpt_pop_reply_queue(mpt_softc_t *mpt)
298 return mpt_read(mpt, MPT_OFFSET_REPLY_Q);
302 * Send a command to the IOC via the handshake register.
304 * Only done at initialization time and for certain unusual
305 * commands such as device/bus reset as specified by LSI.
308 mpt_send_handshake_cmd(mpt_softc_t *mpt, size_t len, void *cmd)
311 u_int32_t data, *data32;
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");
325 /* We move things in 32 bit chunks */
326 len = (len + 3) >> 2;
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);
334 * Tell the handshake reg. we are going to send a command
335 * and how long it is going to be.
337 data = (MPI_FUNCTION_HANDSHAKE << MPI_DOORBELL_FUNCTION_SHIFT) |
338 (len << MPI_DOORBELL_ADD_DWORDS_SHIFT);
339 mpt_write(mpt, MPT_OFFSET_DOORBELL, data);
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");
347 /* Clear the interrupt */
348 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
350 if (mpt_wait_db_ack(mpt) != MPT_OK) {
351 device_printf(mpt->dev, "mpt_send_handshake_cmd timeout2!\n");
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);
367 /* Get the response from the handshake register */
369 mpt_recv_handshake_reply(mpt_softc_t *mpt, size_t reply_len, void *reply)
371 int left, reply_left;
373 MSG_DEFAULT_REPLY *hdr;
375 /* We move things out in 16 bit chunks */
377 data16 = (u_int16_t *)reply;
379 hdr = (MSG_DEFAULT_REPLY *)reply;
382 if (mpt_wait_db_int(mpt) != MPT_OK) {
383 device_printf(mpt->dev, "mpt_recv_handshake_cmd timeout1!\n");
386 *data16++ = mpt_read(mpt, MPT_OFFSET_DOORBELL) & MPT_DB_DATA_MASK;
387 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
389 /* Get Second Word */
390 if (mpt_wait_db_int(mpt) != MPT_OK) {
391 device_printf(mpt->dev, "mpt_recv_handshake_cmd timeout2!\n");
394 *data16++ = mpt_read(mpt, MPT_OFFSET_DOORBELL) & MPT_DB_DATA_MASK;
395 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
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));
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;
411 if (mpt_wait_db_int(mpt) != MPT_OK) {
412 device_printf(mpt->dev,
413 "mpt_recv_handshake_cmd timeout3!\n");
416 datum = mpt_read(mpt, MPT_OFFSET_DOORBELL);
418 if (reply_left-- > 0)
419 *data16++ = datum & MPT_DB_DATA_MASK;
421 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
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");
429 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
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);
441 mpt_get_iocfacts(mpt_softc_t *mpt, MSG_IOC_FACTS_REPLY *freplp)
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);
452 error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp);
457 mpt_get_portfacts(mpt_softc_t *mpt, MSG_PORT_FACTS_REPLY *freplp)
459 MSG_PORT_FACTS f_req;
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);
469 error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp);
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.
480 mpt_send_ioc_init(mpt_softc_t *mpt, u_int32_t who)
484 MSG_IOC_INIT_REPLY reply;
486 bzero(&init, sizeof init);
488 init.Function = MPI_FUNCTION_IOC_INIT;
490 init.MaxDevices = 255;
492 init.MaxDevices = 16;
495 init.ReplyFrameSize = MPT_REPLY_SIZE;
496 init.MsgContext = 0x12071941;
498 if ((error = mpt_send_handshake_cmd(mpt, sizeof init, &init)) != 0) {
502 error = mpt_recv_handshake_reply(mpt, sizeof reply, &reply);
508 * Utiltity routine to read configuration headers and pages
512 mpt_read_cfg_header(mpt_softc_t *, int, int, int, fCONFIG_PAGE_HEADER *);
515 mpt_read_cfg_header(mpt_softc_t *mpt, int PageType, int PageNumber,
516 int PageAddress, fCONFIG_PAGE_HEADER *rslt)
521 MSG_CONFIG_REPLY *reply;
523 req = mpt_get_request(mpt);
525 cfgp = req->req_vbuf;
526 bzero(cfgp, sizeof *cfgp);
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;
538 mpt_check_doorbell(mpt);
539 mpt_send_cmd(mpt, req);
544 if (++count == 1000) {
545 device_printf(mpt->dev, "read_cfg_header timed out\n");
548 } while (req->debug == REQ_ON_CHIP);
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",
555 mpt_free_reply(mpt, (req->sequence << 1));
558 bcopy(&reply->Header, rslt, sizeof (fCONFIG_PAGE_HEADER));
559 mpt_free_reply(mpt, (req->sequence << 1));
560 mpt_free_request(mpt, req);
564 #define CFG_DATA_OFF 128
567 mpt_read_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr)
574 MSG_CONFIG_REPLY *reply;
576 req = mpt_get_request(mpt);
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;
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));
593 cfgp->MsgContext = req->index | 0x80000000;
595 mpt_check_doorbell(mpt);
596 mpt_send_cmd(mpt, req);
601 if (++count == 1000) {
602 device_printf(mpt->dev, "read_cfg_page timed out\n");
605 } while (req->debug == REQ_ON_CHIP);
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",
612 mpt_free_reply(mpt, (req->sequence << 1));
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);
634 bcopy(((caddr_t)req->req_vbuf)+CFG_DATA_OFF, hdr, amt);
635 mpt_free_request(mpt, req);
640 mpt_write_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr)
647 MSG_CONFIG_REPLY *reply;
649 req = mpt_get_request(mpt);
651 cfgp = req->req_vbuf;
652 bzero(cfgp, sizeof *cfgp);
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);
661 hdr->PageType &= MPI_CONFIG_PAGETYPE_MASK;
663 cfgp->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
664 cfgp->Function = MPI_FUNCTION_CONFIG;
666 amt = (cfgp->Header.PageLength * sizeof (u_int32_t));
667 cfgp->PageAddress = PageAddress;
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));
676 cfgp->MsgContext = req->index | 0x80000000;
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);
694 bcopy(hdr, ((caddr_t)req->req_vbuf)+CFG_DATA_OFF, amt);
695 /* Restore stripped out attributes */
696 hdr->PageType |= hdr_attr;
698 mpt_check_doorbell(mpt);
699 mpt_send_cmd(mpt, req);
704 if (++count == 1000) {
705 hdr->PageType |= hdr_attr;
706 device_printf(mpt->dev,
707 "mpt_write_cfg_page timed out\n");
710 } while (req->debug == REQ_ON_CHIP);
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",
717 mpt_free_reply(mpt, (req->sequence << 1));
720 mpt_free_reply(mpt, (req->sequence << 1));
722 mpt_free_request(mpt, req);
727 * Read SCSI configuration information
730 mpt_read_config_info_spi(mpt_softc_t *mpt)
734 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 0,
735 0, &mpt->mpt_port_page0.Header);
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);
747 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 1,
748 0, &mpt->mpt_port_page1.Header);
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);
760 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 2,
761 0, &mpt->mpt_port_page2.Header);
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);
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);
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);
789 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
790 1, i, &mpt->mpt_dev_page1[i].Header);
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);
805 * At this point, we don't *have* to fail. As long as we have
806 * valid config header information, we can (barely) lurch
810 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page0.Header);
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);
820 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page1.Header);
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);
830 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page2.Header);
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);
847 for (i = 0; i < 16; i++) {
848 rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page0[i].Header);
850 device_printf(mpt->dev,
851 "cannot read SPI Tgt %d Device Page 0\n", i);
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);
860 rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page1[i].Header);
862 device_printf(mpt->dev,
863 "cannot read SPI Tgt %d Device Page 1\n", i);
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);
877 * Validate SPI configuration information.
879 * In particular, validate SPI Port Page 1.
882 mpt_set_initial_config_spi(mpt_softc_t *mpt)
884 int i, pp1val = ((1 << mpt->mpt_ini_id) << 16) | mpt->mpt_ini_id;
886 mpt->mpt_disc_enable = 0xff;
887 mpt->mpt_tag_enable = 0;
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)) {
899 if (mpt_read_cfg_page(mpt, 0, &tmp.Header)) {
902 if (tmp.Configuration != pp1val) {
903 device_printf(mpt->dev,
904 "failed to reset SPI Port Page 1 Config value\n");
907 mpt->mpt_port_page1 = tmp;
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);
920 if (mpt_write_cfg_page(mpt, i, &tmp.Header)) {
923 if (mpt_read_cfg_page(mpt, i, &tmp.Header)) {
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);
941 mpt_send_port_enable(mpt_softc_t *mpt, int port)
945 MSG_PORT_ENABLE *enable_req;
947 req = mpt_get_request(mpt);
949 enable_req = req->req_vbuf;
950 bzero(enable_req, sizeof *enable_req);
952 enable_req->Function = MPI_FUNCTION_PORT_ENABLE;
953 enable_req->MsgContext = req->index | 0x80000000;
954 enable_req->PortNumber = port;
956 mpt_check_doorbell(mpt);
957 if (mpt->verbose > 1) {
958 device_printf(mpt->dev, "enabling port %d\n", port);
960 mpt_send_cmd(mpt, req);
966 if (++count == 100000) {
967 device_printf(mpt->dev, "port enable timed out\n");
970 } while (req->debug == REQ_ON_CHIP);
971 mpt_free_request(mpt, req);
976 * Enable/Disable asynchronous event reporting.
978 * NB: this is the first command we send via shared memory
979 * instead of the handshake register.
982 mpt_send_event_request(mpt_softc_t *mpt, int onoff)
985 MSG_EVENT_NOTIFY *enable_req;
987 req = mpt_get_request(mpt);
989 enable_req = req->req_vbuf;
990 bzero(enable_req, sizeof *enable_req);
992 enable_req->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
993 enable_req->MsgContext = req->index | 0x80000000;
994 enable_req->Switch = onoff;
996 mpt_check_doorbell(mpt);
997 if (mpt->verbose > 1) {
998 device_printf(mpt->dev, "%sabling async events\n",
999 onoff? "en" : "dis");
1001 mpt_send_cmd(mpt, req);
1007 * Un-mask the interupts on the chip.
1010 mpt_enable_ints(mpt_softc_t *mpt)
1012 /* Unmask every thing except door bell int */
1013 mpt_write(mpt, MPT_OFFSET_INTR_MASK, MPT_INTR_DB_MASK);
1017 * Mask the interupts on the chip.
1020 mpt_disable_ints(mpt_softc_t *mpt)
1022 /* Mask all interrupts */
1023 mpt_write(mpt, MPT_OFFSET_INTR_MASK,
1024 MPT_INTR_REPLY_MASK | MPT_INTR_DB_MASK);
1027 /* (Re)Initialize the chip for use */
1029 mpt_init(mpt_softc_t *mpt, u_int32_t who)
1032 MSG_IOC_FACTS_REPLY facts;
1033 MSG_PORT_FACTS_REPLY pfp;
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]);
1043 if (mpt->verbose > 1) {
1044 device_printf(mpt->dev, "doorbell req = %s\n",
1045 mpt_ioc_diag(mpt_read(mpt, MPT_OFFSET_DOORBELL)));
1049 * Start by making sure we're not at FAULT or RESET state
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) {
1061 for (try = 0; try < MPT_MAX_TRYS; try++) {
1063 * No need to reset if the IOC is already in the READY state.
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
1071 if ((mpt_rd_db(mpt) & MPT_DB_STATE_MASK) !=
1072 MPT_DB_STATE_READY) {
1073 if (mpt_reset(mpt) != MPT_OK) {
1079 if (mpt_get_iocfacts(mpt, &facts) != MPT_OK) {
1080 device_printf(mpt->dev, "mpt_get_iocfacts failed\n");
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);
1090 mpt->mpt_global_credits = facts.GlobalCredits;
1091 mpt->request_frame_size = facts.RequestFrameSize;
1093 if (mpt_get_portfacts(mpt, &pfp) != MPT_OK) {
1094 device_printf(mpt->dev, "mpt_get_portfacts failed\n");
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,
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",
1111 if (!(pfp.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
1112 device_printf(mpt->dev, "initiator role unsupported\n");
1115 if (pfp.PortType == MPI_PORTFACTS_PORTTYPE_FC) {
1120 mpt->mpt_ini_id = pfp.PortSCSIID;
1122 if (mpt_send_ioc_init(mpt, who) != MPT_OK) {
1123 device_printf(mpt->dev, "mpt_send_ioc_init failed\n");
1127 if (mpt->verbose > 1) {
1128 device_printf(mpt->dev, "mpt_send_ioc_init ok\n");
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");
1136 if (mpt->verbose > 1) {
1137 device_printf(mpt->dev, "IOC now at RUNSTATE\n");
1141 * Give it reply buffers
1143 * Do *not* except global credits.
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)
1154 * Enable asynchronous event reporting
1156 mpt_send_event_request(mpt, 1);
1160 * Read set up initial configuration information
1161 * (SPI only for now)
1164 if (mpt->is_fc == 0) {
1165 if (mpt_read_config_info_spi(mpt)) {
1168 if (mpt_set_initial_config_spi(mpt)) {
1174 * Now enable the port
1176 if (mpt_send_port_enable(mpt, 0) != MPT_OK) {
1177 device_printf(mpt->dev, "failed to enable port 0\n");
1181 if (mpt->verbose > 1) {
1182 device_printf(mpt->dev, "enabled port 0\n");
1185 /* Everything worked */
1189 if (try >= MPT_MAX_TRYS) {
1190 device_printf(mpt->dev, "failed to initialize IOC\n");
1194 if (mpt->verbose > 1) {
1195 device_printf(mpt->dev, "enabling interrupts\n");
1198 mpt_enable_ints(mpt);