1 /* $FreeBSD: src/sys/dev/mpt/mpt.c,v 1.3.2.3 2002/09/24 21:37:24 mjacob Exp $ */
2 /* $DragonFly: src/sys/dev/disk/mpt/mpt.c,v 1.4 2004/09/19 00:25:57 joerg Exp $ */
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");
235 callout_stop(&req->timeout);
238 req->debug = REQ_FREE;
239 SLIST_INSERT_HEAD(&mpt->request_free_list, req, link);
242 /* Get a command buffer from the free queue */
244 mpt_get_request(mpt_softc_t *mpt)
247 req = SLIST_FIRST(&mpt->request_free_list);
249 if (req != &mpt->request_pool[req->index]) {
250 panic("mpt_get_request: corrupted request free list\n");
252 if (req->ccb != NULL) {
253 panic("mpt_get_request: corrupted request free list (ccb)\n");
255 SLIST_REMOVE_HEAD(&mpt->request_free_list, link);
256 req->debug = REQ_IN_PROGRESS;
261 /* Pass the command to the IOC */
263 mpt_send_cmd(mpt_softc_t *mpt, request_t *req)
265 req->sequence = mpt->sequence++;
266 if (mpt->verbose > 1) {
268 pReq = req->req_vbuf;
269 device_printf(mpt->dev, "Send Request %d (0x%lx):\n",
270 req->index, (long) req->req_pbuf);
271 device_printf(mpt->dev, "%08X %08X %08X %08X\n",
272 pReq[0], pReq[1], pReq[2], pReq[3]);
273 device_printf(mpt->dev, "%08X %08X %08X %08X\n",
274 pReq[4], pReq[5], pReq[6], pReq[7]);
275 device_printf(mpt->dev, "%08X %08X %08X %08X\n",
276 pReq[8], pReq[9], pReq[10], pReq[11]);
277 device_printf(mpt->dev, "%08X %08X %08X %08X\n",
278 pReq[12], pReq[13], pReq[14], pReq[15]);
280 bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap,
281 BUS_DMASYNC_PREWRITE);
282 req->debug = REQ_ON_CHIP;
283 mpt_write(mpt, MPT_OFFSET_REQUEST_Q, (u_int32_t) req->req_pbuf);
287 * Give the reply buffer back to the IOC after we have
288 * finished processing it.
291 mpt_free_reply(mpt_softc_t *mpt, u_int32_t ptr)
293 mpt_write(mpt, MPT_OFFSET_REPLY_Q, ptr);
296 /* Get a reply from the IOC */
298 mpt_pop_reply_queue(mpt_softc_t *mpt)
300 return mpt_read(mpt, MPT_OFFSET_REPLY_Q);
304 * Send a command to the IOC via the handshake register.
306 * Only done at initialization time and for certain unusual
307 * commands such as device/bus reset as specified by LSI.
310 mpt_send_handshake_cmd(mpt_softc_t *mpt, size_t len, void *cmd)
313 u_int32_t data, *data32;
315 /* Check condition of the IOC */
316 data = mpt_rd_db(mpt);
317 if (((MPT_STATE(data) != MPT_DB_STATE_READY) &&
318 (MPT_STATE(data) != MPT_DB_STATE_RUNNING) &&
319 (MPT_STATE(data) != MPT_DB_STATE_FAULT)) ||
320 ( MPT_DB_IS_IN_USE(data) )) {
321 device_printf(mpt->dev,
322 "handshake aborted due to invalid doorbell state\n");
327 /* We move things in 32 bit chunks */
328 len = (len + 3) >> 2;
331 /* Clear any left over pending doorbell interupts */
332 if (MPT_DB_INTR(mpt_rd_intr(mpt)))
333 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
336 * Tell the handshake reg. we are going to send a command
337 * and how long it is going to be.
339 data = (MPI_FUNCTION_HANDSHAKE << MPI_DOORBELL_FUNCTION_SHIFT) |
340 (len << MPI_DOORBELL_ADD_DWORDS_SHIFT);
341 mpt_write(mpt, MPT_OFFSET_DOORBELL, data);
343 /* Wait for the chip to notice */
344 if (mpt_wait_db_int(mpt) != MPT_OK) {
345 device_printf(mpt->dev, "mpt_send_handshake_cmd timeout1!\n");
349 /* Clear the interrupt */
350 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
352 if (mpt_wait_db_ack(mpt) != MPT_OK) {
353 device_printf(mpt->dev, "mpt_send_handshake_cmd timeout2!\n");
357 /* Send the command */
358 for (i = 0; i < len; i++) {
359 mpt_write(mpt, MPT_OFFSET_DOORBELL, *data32++);
360 if (mpt_wait_db_ack(mpt) != MPT_OK) {
361 device_printf(mpt->dev,
362 "mpt_send_handshake_cmd timeout! index = %d\n", i);
369 /* Get the response from the handshake register */
371 mpt_recv_handshake_reply(mpt_softc_t *mpt, size_t reply_len, void *reply)
373 int left, reply_left;
375 MSG_DEFAULT_REPLY *hdr;
377 /* We move things out in 16 bit chunks */
379 data16 = (u_int16_t *)reply;
381 hdr = (MSG_DEFAULT_REPLY *)reply;
384 if (mpt_wait_db_int(mpt) != MPT_OK) {
385 device_printf(mpt->dev, "mpt_recv_handshake_cmd timeout1!\n");
388 *data16++ = mpt_read(mpt, MPT_OFFSET_DOORBELL) & MPT_DB_DATA_MASK;
389 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
391 /* Get Second Word */
392 if (mpt_wait_db_int(mpt) != MPT_OK) {
393 device_printf(mpt->dev, "mpt_recv_handshake_cmd timeout2!\n");
396 *data16++ = mpt_read(mpt, MPT_OFFSET_DOORBELL) & MPT_DB_DATA_MASK;
397 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
399 /* With the second word, we can now look at the length */
400 if (mpt->verbose > 1 && ((reply_len >> 1) != hdr->MsgLength)) {
401 device_printf(mpt->dev,
402 "reply length does not match message length: "
403 "got 0x%02x, expected 0x%02lx\n",
404 hdr->MsgLength << 2, (long) (reply_len << 1));
407 /* Get rest of the reply; but don't overflow the provided buffer */
408 left = (hdr->MsgLength << 1) - 2;
409 reply_left = reply_len - 2;
413 if (mpt_wait_db_int(mpt) != MPT_OK) {
414 device_printf(mpt->dev,
415 "mpt_recv_handshake_cmd timeout3!\n");
418 datum = mpt_read(mpt, MPT_OFFSET_DOORBELL);
420 if (reply_left-- > 0)
421 *data16++ = datum & MPT_DB_DATA_MASK;
423 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
426 /* One more wait & clear at the end */
427 if (mpt_wait_db_int(mpt) != MPT_OK) {
428 device_printf(mpt->dev, "mpt_recv_handshake_cmd timeout4!\n");
431 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
433 if ((hdr->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
434 if (mpt->verbose > 1)
435 mpt_print_reply(hdr);
436 return (MPT_FAIL | hdr->IOCStatus);
443 mpt_get_iocfacts(mpt_softc_t *mpt, MSG_IOC_FACTS_REPLY *freplp)
448 bzero(&f_req, sizeof f_req);
449 f_req.Function = MPI_FUNCTION_IOC_FACTS;
450 f_req.MsgContext = 0x12071942;
451 error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req);
454 error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp);
459 mpt_get_portfacts(mpt_softc_t *mpt, MSG_PORT_FACTS_REPLY *freplp)
461 MSG_PORT_FACTS f_req;
464 /* XXX: Only getting PORT FACTS for Port 0 */
465 bzero(&f_req, sizeof f_req);
466 f_req.Function = MPI_FUNCTION_PORT_FACTS;
467 f_req.MsgContext = 0x12071943;
468 error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req);
471 error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp);
476 * Send the initialization request. This is where we specify how many
477 * SCSI busses and how many devices per bus we wish to emulate.
478 * This is also the command that specifies the max size of the reply
479 * frames from the IOC that we will be allocating.
482 mpt_send_ioc_init(mpt_softc_t *mpt, u_int32_t who)
486 MSG_IOC_INIT_REPLY reply;
488 bzero(&init, sizeof init);
490 init.Function = MPI_FUNCTION_IOC_INIT;
492 init.MaxDevices = 255;
494 init.MaxDevices = 16;
497 init.ReplyFrameSize = MPT_REPLY_SIZE;
498 init.MsgContext = 0x12071941;
500 if ((error = mpt_send_handshake_cmd(mpt, sizeof init, &init)) != 0) {
504 error = mpt_recv_handshake_reply(mpt, sizeof reply, &reply);
510 * Utiltity routine to read configuration headers and pages
514 mpt_read_cfg_header(mpt_softc_t *, int, int, int, fCONFIG_PAGE_HEADER *);
517 mpt_read_cfg_header(mpt_softc_t *mpt, int PageType, int PageNumber,
518 int PageAddress, fCONFIG_PAGE_HEADER *rslt)
523 MSG_CONFIG_REPLY *reply;
525 req = mpt_get_request(mpt);
527 cfgp = req->req_vbuf;
528 bzero(cfgp, sizeof *cfgp);
530 cfgp->Action = MPI_CONFIG_ACTION_PAGE_HEADER;
531 cfgp->Function = MPI_FUNCTION_CONFIG;
532 cfgp->Header.PageNumber = (U8) PageNumber;
533 cfgp->Header.PageType = (U8) PageType;
534 cfgp->PageAddress = PageAddress;
535 MPI_pSGE_SET_FLAGS(((SGE_SIMPLE32 *) &cfgp->PageBufferSGE),
536 (MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
537 MPI_SGE_FLAGS_SIMPLE_ELEMENT | MPI_SGE_FLAGS_END_OF_LIST));
538 cfgp->MsgContext = req->index | 0x80000000;
540 mpt_check_doorbell(mpt);
541 mpt_send_cmd(mpt, req);
546 if (++count == 1000) {
547 device_printf(mpt->dev, "read_cfg_header timed out\n");
550 } while (req->debug == REQ_ON_CHIP);
552 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
553 if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
554 device_printf(mpt->dev,
555 "mpt_read_cfg_header: Config Info Status %x\n",
557 mpt_free_reply(mpt, (req->sequence << 1));
560 bcopy(&reply->Header, rslt, sizeof (fCONFIG_PAGE_HEADER));
561 mpt_free_reply(mpt, (req->sequence << 1));
562 mpt_free_request(mpt, req);
566 #define CFG_DATA_OFF 128
569 mpt_read_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr)
576 MSG_CONFIG_REPLY *reply;
578 req = mpt_get_request(mpt);
580 cfgp = req->req_vbuf;
581 bzero(cfgp, MPT_REQUEST_AREA);
582 cfgp->Action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
583 cfgp->Function = MPI_FUNCTION_CONFIG;
585 amt = (cfgp->Header.PageLength * sizeof (u_int32_t));
586 cfgp->Header.PageType &= MPI_CONFIG_PAGETYPE_MASK;
587 cfgp->PageAddress = PageAddress;
588 se = (SGE_SIMPLE32 *) &cfgp->PageBufferSGE;
589 se->Address = req->req_pbuf + CFG_DATA_OFF;
590 MPI_pSGE_SET_LENGTH(se, amt);
591 MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
592 MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
593 MPI_SGE_FLAGS_END_OF_LIST));
595 cfgp->MsgContext = req->index | 0x80000000;
597 mpt_check_doorbell(mpt);
598 mpt_send_cmd(mpt, req);
603 if (++count == 1000) {
604 device_printf(mpt->dev, "read_cfg_page timed out\n");
607 } while (req->debug == REQ_ON_CHIP);
609 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
610 if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
611 device_printf(mpt->dev,
612 "mpt_read_cfg_page: Config Info Status %x\n",
614 mpt_free_reply(mpt, (req->sequence << 1));
617 mpt_free_reply(mpt, (req->sequence << 1));
618 bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap,
619 BUS_DMASYNC_POSTREAD);
620 if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
621 cfgp->Header.PageNumber == 0) {
622 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_0);
623 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
624 cfgp->Header.PageNumber == 1) {
625 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_1);
626 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
627 cfgp->Header.PageNumber == 2) {
628 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_2);
629 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
630 cfgp->Header.PageNumber == 0) {
631 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_0);
632 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
633 cfgp->Header.PageNumber == 1) {
634 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_1);
636 bcopy(((caddr_t)req->req_vbuf)+CFG_DATA_OFF, hdr, amt);
637 mpt_free_request(mpt, req);
642 mpt_write_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr)
649 MSG_CONFIG_REPLY *reply;
651 req = mpt_get_request(mpt);
653 cfgp = req->req_vbuf;
654 bzero(cfgp, sizeof *cfgp);
656 hdr_attr = hdr->PageType & MPI_CONFIG_PAGEATTR_MASK;
657 if (hdr_attr != MPI_CONFIG_PAGEATTR_CHANGEABLE &&
658 hdr_attr != MPI_CONFIG_PAGEATTR_PERSISTENT) {
659 device_printf(mpt->dev, "page type 0x%x not changeable\n",
660 hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
663 hdr->PageType &= MPI_CONFIG_PAGETYPE_MASK;
665 cfgp->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
666 cfgp->Function = MPI_FUNCTION_CONFIG;
668 amt = (cfgp->Header.PageLength * sizeof (u_int32_t));
669 cfgp->PageAddress = PageAddress;
671 se = (SGE_SIMPLE32 *) &cfgp->PageBufferSGE;
672 se->Address = req->req_pbuf + CFG_DATA_OFF;
673 MPI_pSGE_SET_LENGTH(se, amt);
674 MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
675 MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
676 MPI_SGE_FLAGS_END_OF_LIST | MPI_SGE_FLAGS_HOST_TO_IOC));
678 cfgp->MsgContext = req->index | 0x80000000;
680 if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
681 cfgp->Header.PageNumber == 0) {
682 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_0);
683 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
684 cfgp->Header.PageNumber == 1) {
685 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_1);
686 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
687 cfgp->Header.PageNumber == 2) {
688 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_2);
689 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
690 cfgp->Header.PageNumber == 0) {
691 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_0);
692 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
693 cfgp->Header.PageNumber == 1) {
694 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_1);
696 bcopy(hdr, ((caddr_t)req->req_vbuf)+CFG_DATA_OFF, amt);
697 /* Restore stripped out attributes */
698 hdr->PageType |= hdr_attr;
700 mpt_check_doorbell(mpt);
701 mpt_send_cmd(mpt, req);
706 if (++count == 1000) {
707 hdr->PageType |= hdr_attr;
708 device_printf(mpt->dev,
709 "mpt_write_cfg_page timed out\n");
712 } while (req->debug == REQ_ON_CHIP);
714 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
715 if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
716 device_printf(mpt->dev,
717 "mpt_write_cfg_page: Config Info Status %x\n",
719 mpt_free_reply(mpt, (req->sequence << 1));
722 mpt_free_reply(mpt, (req->sequence << 1));
724 mpt_free_request(mpt, req);
729 * Read SCSI configuration information
732 mpt_read_config_info_spi(mpt_softc_t *mpt)
736 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 0,
737 0, &mpt->mpt_port_page0.Header);
741 if (mpt->verbose > 1) {
742 device_printf(mpt->dev, "SPI Port Page 0 Header: %x %x %x %x\n",
743 mpt->mpt_port_page0.Header.PageVersion,
744 mpt->mpt_port_page0.Header.PageLength,
745 mpt->mpt_port_page0.Header.PageNumber,
746 mpt->mpt_port_page0.Header.PageType);
749 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 1,
750 0, &mpt->mpt_port_page1.Header);
754 if (mpt->verbose > 1) {
755 device_printf(mpt->dev, "SPI Port Page 1 Header: %x %x %x %x\n",
756 mpt->mpt_port_page1.Header.PageVersion,
757 mpt->mpt_port_page1.Header.PageLength,
758 mpt->mpt_port_page1.Header.PageNumber,
759 mpt->mpt_port_page1.Header.PageType);
762 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 2,
763 0, &mpt->mpt_port_page2.Header);
768 if (mpt->verbose > 1) {
769 device_printf(mpt->dev, "SPI Port Page 2 Header: %x %x %x %x\n",
770 mpt->mpt_port_page1.Header.PageVersion,
771 mpt->mpt_port_page1.Header.PageLength,
772 mpt->mpt_port_page1.Header.PageNumber,
773 mpt->mpt_port_page1.Header.PageType);
776 for (i = 0; i < 16; i++) {
777 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
778 0, i, &mpt->mpt_dev_page0[i].Header);
782 if (mpt->verbose > 1) {
783 device_printf(mpt->dev,
784 "SPI Target %d Device Page 0 Header: %x %x %x %x\n",
785 i, mpt->mpt_dev_page0[i].Header.PageVersion,
786 mpt->mpt_dev_page0[i].Header.PageLength,
787 mpt->mpt_dev_page0[i].Header.PageNumber,
788 mpt->mpt_dev_page0[i].Header.PageType);
791 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
792 1, i, &mpt->mpt_dev_page1[i].Header);
796 if (mpt->verbose > 1) {
797 device_printf(mpt->dev,
798 "SPI Target %d Device Page 1 Header: %x %x %x %x\n",
799 i, mpt->mpt_dev_page1[i].Header.PageVersion,
800 mpt->mpt_dev_page1[i].Header.PageLength,
801 mpt->mpt_dev_page1[i].Header.PageNumber,
802 mpt->mpt_dev_page1[i].Header.PageType);
807 * At this point, we don't *have* to fail. As long as we have
808 * valid config header information, we can (barely) lurch
812 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page0.Header);
814 device_printf(mpt->dev, "failed to read SPI Port Page 0\n");
815 } else if (mpt->verbose > 1) {
816 device_printf(mpt->dev,
817 "SPI Port Page 0: Capabilities %x PhysicalInterface %x\n",
818 mpt->mpt_port_page0.Capabilities,
819 mpt->mpt_port_page0.PhysicalInterface);
822 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page1.Header);
824 device_printf(mpt->dev, "failed to read SPI Port Page 1\n");
825 } else if (mpt->verbose > 1) {
826 device_printf(mpt->dev,
827 "SPI Port Page 1: Configuration %x OnBusTimerValue %x\n",
828 mpt->mpt_port_page1.Configuration,
829 mpt->mpt_port_page1.OnBusTimerValue);
832 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page2.Header);
834 device_printf(mpt->dev, "failed to read SPI Port Page 2\n");
835 } else if (mpt->verbose > 1) {
836 device_printf(mpt->dev,
837 "SPI Port Page 2: Flags %x Settings %x\n",
838 mpt->mpt_port_page2.PortFlags,
839 mpt->mpt_port_page2.PortSettings);
840 for (i = 0; i < 16; i++) {
841 device_printf(mpt->dev,
842 "SPI Port Page 2 Tgt %d: timo %x SF %x Flags %x\n",
843 i, mpt->mpt_port_page2.DeviceSettings[i].Timeout,
844 mpt->mpt_port_page2.DeviceSettings[i].SyncFactor,
845 mpt->mpt_port_page2.DeviceSettings[i].DeviceFlags);
849 for (i = 0; i < 16; i++) {
850 rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page0[i].Header);
852 device_printf(mpt->dev,
853 "cannot read SPI Tgt %d Device Page 0\n", i);
856 if (mpt->verbose > 1) {
857 device_printf(mpt->dev,
858 "SPI Tgt %d Page 0: NParms %x Information %x\n",
859 i, mpt->mpt_dev_page0[i].NegotiatedParameters,
860 mpt->mpt_dev_page0[i].Information);
862 rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page1[i].Header);
864 device_printf(mpt->dev,
865 "cannot read SPI Tgt %d Device Page 1\n", i);
868 if (mpt->verbose > 1) {
869 device_printf(mpt->dev,
870 "SPI Tgt %d Page 1: RParms %x Configuration %x\n",
871 i, mpt->mpt_dev_page1[i].RequestedParameters,
872 mpt->mpt_dev_page1[i].Configuration);
879 * Validate SPI configuration information.
881 * In particular, validate SPI Port Page 1.
884 mpt_set_initial_config_spi(mpt_softc_t *mpt)
886 int i, pp1val = ((1 << mpt->mpt_ini_id) << 16) | mpt->mpt_ini_id;
888 mpt->mpt_disc_enable = 0xff;
889 mpt->mpt_tag_enable = 0;
891 if (mpt->mpt_port_page1.Configuration != pp1val) {
892 fCONFIG_PAGE_SCSI_PORT_1 tmp;
893 device_printf(mpt->dev,
894 "SPI Port Page 1 Config value bad (%x)- should be %x\n",
895 mpt->mpt_port_page1.Configuration, pp1val);
896 tmp = mpt->mpt_port_page1;
897 tmp.Configuration = pp1val;
898 if (mpt_write_cfg_page(mpt, 0, &tmp.Header)) {
901 if (mpt_read_cfg_page(mpt, 0, &tmp.Header)) {
904 if (tmp.Configuration != pp1val) {
905 device_printf(mpt->dev,
906 "failed to reset SPI Port Page 1 Config value\n");
909 mpt->mpt_port_page1 = tmp;
912 for (i = 0; i < 16; i++) {
913 fCONFIG_PAGE_SCSI_DEVICE_1 tmp;
914 tmp = mpt->mpt_dev_page1[i];
915 tmp.RequestedParameters = 0;
916 tmp.Configuration = 0;
917 if (mpt->verbose > 1) {
918 device_printf(mpt->dev,
919 "Set Tgt %d SPI DevicePage 1 values to %x 0 %x\n",
920 i, tmp.RequestedParameters, tmp.Configuration);
922 if (mpt_write_cfg_page(mpt, i, &tmp.Header)) {
925 if (mpt_read_cfg_page(mpt, i, &tmp.Header)) {
928 mpt->mpt_dev_page1[i] = tmp;
929 if (mpt->verbose > 1) {
930 device_printf(mpt->dev,
931 "SPI Tgt %d Page 1: RParm %x Configuration %x\n", i,
932 mpt->mpt_dev_page1[i].RequestedParameters,
933 mpt->mpt_dev_page1[i].Configuration);
943 mpt_send_port_enable(mpt_softc_t *mpt, int port)
947 MSG_PORT_ENABLE *enable_req;
949 req = mpt_get_request(mpt);
951 enable_req = req->req_vbuf;
952 bzero(enable_req, sizeof *enable_req);
954 enable_req->Function = MPI_FUNCTION_PORT_ENABLE;
955 enable_req->MsgContext = req->index | 0x80000000;
956 enable_req->PortNumber = port;
958 mpt_check_doorbell(mpt);
959 if (mpt->verbose > 1) {
960 device_printf(mpt->dev, "enabling port %d\n", port);
962 mpt_send_cmd(mpt, req);
968 if (++count == 100000) {
969 device_printf(mpt->dev, "port enable timed out\n");
972 } while (req->debug == REQ_ON_CHIP);
973 mpt_free_request(mpt, req);
978 * Enable/Disable asynchronous event reporting.
980 * NB: this is the first command we send via shared memory
981 * instead of the handshake register.
984 mpt_send_event_request(mpt_softc_t *mpt, int onoff)
987 MSG_EVENT_NOTIFY *enable_req;
989 req = mpt_get_request(mpt);
991 enable_req = req->req_vbuf;
992 bzero(enable_req, sizeof *enable_req);
994 enable_req->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
995 enable_req->MsgContext = req->index | 0x80000000;
996 enable_req->Switch = onoff;
998 mpt_check_doorbell(mpt);
999 if (mpt->verbose > 1) {
1000 device_printf(mpt->dev, "%sabling async events\n",
1001 onoff? "en" : "dis");
1003 mpt_send_cmd(mpt, req);
1009 * Un-mask the interupts on the chip.
1012 mpt_enable_ints(mpt_softc_t *mpt)
1014 /* Unmask every thing except door bell int */
1015 mpt_write(mpt, MPT_OFFSET_INTR_MASK, MPT_INTR_DB_MASK);
1019 * Mask the interupts on the chip.
1022 mpt_disable_ints(mpt_softc_t *mpt)
1024 /* Mask all interrupts */
1025 mpt_write(mpt, MPT_OFFSET_INTR_MASK,
1026 MPT_INTR_REPLY_MASK | MPT_INTR_DB_MASK);
1029 /* (Re)Initialize the chip for use */
1031 mpt_init(mpt_softc_t *mpt, u_int32_t who)
1034 MSG_IOC_FACTS_REPLY facts;
1035 MSG_PORT_FACTS_REPLY pfp;
1039 /* Put all request buffers (back) on the free list */
1040 SLIST_INIT(&mpt->request_free_list);
1041 for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++) {
1042 callout_init(&mpt->request_pool[val].timeout);
1043 mpt_free_request(mpt, &mpt->request_pool[val]);
1046 if (mpt->verbose > 1) {
1047 device_printf(mpt->dev, "doorbell req = %s\n",
1048 mpt_ioc_diag(mpt_read(mpt, MPT_OFFSET_DOORBELL)));
1052 * Start by making sure we're not at FAULT or RESET state
1054 switch (mpt_rd_db(mpt) & MPT_DB_STATE_MASK) {
1055 case MPT_DB_STATE_RESET:
1056 case MPT_DB_STATE_FAULT:
1057 if (mpt_reset(mpt) != MPT_OK) {
1064 for (try = 0; try < MPT_MAX_TRYS; try++) {
1066 * No need to reset if the IOC is already in the READY state.
1068 * Force reset if initialization failed previously.
1069 * Note that a hard_reset of the second channel of a '929
1070 * will stop operation of the first channel. Hopefully, if the
1071 * first channel is ok, the second will not require a hard
1074 if ((mpt_rd_db(mpt) & MPT_DB_STATE_MASK) !=
1075 MPT_DB_STATE_READY) {
1076 if (mpt_reset(mpt) != MPT_OK) {
1082 if (mpt_get_iocfacts(mpt, &facts) != MPT_OK) {
1083 device_printf(mpt->dev, "mpt_get_iocfacts failed\n");
1087 if (mpt->verbose > 1) {
1088 device_printf(mpt->dev,
1089 "IOCFACTS: GlobalCredits=%d BlockSize=%u "
1090 "Request Frame Size %u\n", facts.GlobalCredits,
1091 facts.BlockSize, facts.RequestFrameSize);
1093 mpt->mpt_global_credits = facts.GlobalCredits;
1094 mpt->request_frame_size = facts.RequestFrameSize;
1096 if (mpt_get_portfacts(mpt, &pfp) != MPT_OK) {
1097 device_printf(mpt->dev, "mpt_get_portfacts failed\n");
1101 if (mpt->verbose > 1) {
1102 device_printf(mpt->dev,
1103 "PORTFACTS: Type %x PFlags %x IID %d MaxDev %d\n",
1104 pfp.PortType, pfp.ProtocolFlags, pfp.PortSCSIID,
1108 if (pfp.PortType != MPI_PORTFACTS_PORTTYPE_SCSI &&
1109 pfp.PortType != MPI_PORTFACTS_PORTTYPE_FC) {
1110 device_printf(mpt->dev, "Unsupported Port Type (%x)\n",
1114 if (!(pfp.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
1115 device_printf(mpt->dev, "initiator role unsupported\n");
1118 if (pfp.PortType == MPI_PORTFACTS_PORTTYPE_FC) {
1123 mpt->mpt_ini_id = pfp.PortSCSIID;
1125 if (mpt_send_ioc_init(mpt, who) != MPT_OK) {
1126 device_printf(mpt->dev, "mpt_send_ioc_init failed\n");
1130 if (mpt->verbose > 1) {
1131 device_printf(mpt->dev, "mpt_send_ioc_init ok\n");
1134 if (mpt_wait_state(mpt, MPT_DB_STATE_RUNNING) != MPT_OK) {
1135 device_printf(mpt->dev,
1136 "IOC failed to go to run state\n");
1139 if (mpt->verbose > 1) {
1140 device_printf(mpt->dev, "IOC now at RUNSTATE\n");
1144 * Give it reply buffers
1146 * Do *not* except global credits.
1148 for (val = 0, pptr = mpt->reply_phys;
1149 (pptr + MPT_REPLY_SIZE) < (mpt->reply_phys + PAGE_SIZE);
1150 pptr += MPT_REPLY_SIZE) {
1151 mpt_free_reply(mpt, pptr);
1152 if (++val == mpt->mpt_global_credits - 1)
1157 * Enable asynchronous event reporting
1159 mpt_send_event_request(mpt, 1);
1163 * Read set up initial configuration information
1164 * (SPI only for now)
1167 if (mpt->is_fc == 0) {
1168 if (mpt_read_config_info_spi(mpt)) {
1171 if (mpt_set_initial_config_spi(mpt)) {
1177 * Now enable the port
1179 if (mpt_send_port_enable(mpt, 0) != MPT_OK) {
1180 device_printf(mpt->dev, "failed to enable port 0\n");
1184 if (mpt->verbose > 1) {
1185 device_printf(mpt->dev, "enabled port 0\n");
1188 /* Everything worked */
1192 if (try >= MPT_MAX_TRYS) {
1193 device_printf(mpt->dev, "failed to initialize IOC\n");
1197 if (mpt->verbose > 1) {
1198 device_printf(mpt->dev, "enabling interrupts\n");
1201 mpt_enable_ints(mpt);