1 /* $NetBSD: mpt.c,v 1.12 2009/03/18 17:06:49 cegger Exp $ */
4 * Copyright (c) 2000, 2001 by Greg Ansley
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice immediately at the beginning of the file, without modification,
11 * this list of conditions, and the following disclaimer.
12 * 2. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
19 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * Additional Copyright (c) 2002 by Matthew Jacob under same license.
35 * Generic routines for LSI Fusion adapters.
37 * Adapted from the FreeBSD "mpt" driver by Jason R. Thorpe for
38 * Wasabi Systems, Inc.
40 * Additional contributions by Garrett D'Amore on behalf of TELES AG.
43 #include <sys/cdefs.h>
44 __KERNEL_RCSID(0, "$NetBSD: mpt.c,v 1.12 2009/03/18 17:06:49 cegger Exp $");
46 #include <dev/ic/mpt.h>
48 #define MPT_MAX_TRYS 3
49 #define MPT_MAX_WAIT 300000
51 static int maxwait_ack
= 0;
52 static int maxwait_int
= 0;
53 static int maxwait_state
= 0;
55 static inline u_int32_t
56 mpt_rd_db(mpt_softc_t
*mpt
)
58 return mpt_read(mpt
, MPT_OFFSET_DOORBELL
);
61 static inline u_int32_t
62 mpt_rd_intr(mpt_softc_t
*mpt
)
64 return mpt_read(mpt
, MPT_OFFSET_INTR_STATUS
);
67 /* Busy wait for a door bell to be read by IOC */
69 mpt_wait_db_ack(mpt_softc_t
*mpt
)
72 for (i
=0; i
< MPT_MAX_WAIT
; i
++) {
73 if (!MPT_DB_IS_BUSY(mpt_rd_intr(mpt
))) {
74 maxwait_ack
= i
> maxwait_ack
? i
: maxwait_ack
;
83 /* Busy wait for a door bell interrupt */
85 mpt_wait_db_int(mpt_softc_t
*mpt
)
88 for (i
=0; i
< MPT_MAX_WAIT
; i
++) {
89 if (MPT_DB_INTR(mpt_rd_intr(mpt
))) {
90 maxwait_int
= i
> maxwait_int
? i
: maxwait_int
;
98 /* Wait for IOC to transition to a give state */
100 mpt_check_doorbell(mpt_softc_t
*mpt
)
102 u_int32_t db
= mpt_rd_db(mpt
);
103 if (MPT_STATE(db
) != MPT_DB_STATE_RUNNING
) {
104 mpt_prt(mpt
, "Device not running");
109 /* Wait for IOC to transition to a give state */
111 mpt_wait_state(mpt_softc_t
*mpt
, enum DB_STATE_BITS state
)
115 for (i
= 0; i
< MPT_MAX_WAIT
; i
++) {
116 u_int32_t db
= mpt_rd_db(mpt
);
117 if (MPT_STATE(db
) == state
) {
118 maxwait_state
= i
> maxwait_state
? i
: maxwait_state
;
127 /* Issue the reset COMMAND to the IOC */
129 mpt_soft_reset(mpt_softc_t
*mpt
)
132 mpt_prt(mpt
, "soft reset");
135 /* Have to use hard reset if we are not in Running state */
136 if (MPT_STATE(mpt_rd_db(mpt
)) != MPT_DB_STATE_RUNNING
) {
137 mpt_prt(mpt
, "soft reset failed: device not running");
141 /* If door bell is in use we don't have a chance of getting
142 * a word in since the IOC probably crashed in message
143 * processing. So don't waste our time.
145 if (MPT_DB_IS_IN_USE(mpt_rd_db(mpt
))) {
146 mpt_prt(mpt
, "soft reset failed: doorbell wedged");
150 /* Send the reset request to the IOC */
151 mpt_write(mpt
, MPT_OFFSET_DOORBELL
,
152 MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
<< MPI_DOORBELL_FUNCTION_SHIFT
);
153 if (mpt_wait_db_ack(mpt
) != MPT_OK
) {
154 mpt_prt(mpt
, "soft reset failed: ack timeout");
158 /* Wait for the IOC to reload and come out of reset state */
159 if (mpt_wait_state(mpt
, MPT_DB_STATE_READY
) != MPT_OK
) {
160 mpt_prt(mpt
, "soft reset failed: device did not start running");
167 /* This is a magic diagnostic reset that resets all the ARM
168 * processors in the chip.
171 mpt_hard_reset(mpt_softc_t
*mpt
)
174 mpt_prt(mpt
, "hard reset");
176 mpt_write(mpt
, MPT_OFFSET_SEQUENCE
, 0xff);
178 /* Enable diagnostic registers */
179 mpt_write(mpt
, MPT_OFFSET_SEQUENCE
, MPT_DIAG_SEQUENCE_1
);
180 mpt_write(mpt
, MPT_OFFSET_SEQUENCE
, MPT_DIAG_SEQUENCE_2
);
181 mpt_write(mpt
, MPT_OFFSET_SEQUENCE
, MPT_DIAG_SEQUENCE_3
);
182 mpt_write(mpt
, MPT_OFFSET_SEQUENCE
, MPT_DIAG_SEQUENCE_4
);
183 mpt_write(mpt
, MPT_OFFSET_SEQUENCE
, MPT_DIAG_SEQUENCE_5
);
185 /* Diag. port is now active so we can now hit the reset bit */
186 mpt_write(mpt
, MPT_OFFSET_DIAGNOSTIC
, MPT_DIAG_RESET_IOC
);
190 /* Disable Diagnostic Register */
191 mpt_write(mpt
, MPT_OFFSET_SEQUENCE
, 0xFF);
195 * Reset the IOC when needed. Try software command first then if needed
196 * poke at the magic diagnostic reset. Note that a hard reset resets
197 * *both* IOCs on dual function chips (FC929 && LSI1030) as well as
198 * fouls up the PCI configuration registers.
201 mpt_reset(mpt_softc_t
*mpt
)
205 /* Try a soft reset */
206 if ((ret
= mpt_soft_reset(mpt
)) != MPT_OK
) {
207 /* Failed; do a hard reset */
210 /* Wait for the IOC to reload and come out of reset state */
211 ret
= mpt_wait_state(mpt
, MPT_DB_STATE_READY
);
213 mpt_prt(mpt
, "failed to reset device");
220 /* Return a command buffer to the free queue */
222 mpt_free_request(mpt_softc_t
*mpt
, request_t
*req
)
224 if (req
== NULL
|| req
!= &mpt
->request_pool
[req
->index
]) {
225 panic("mpt_free_request bad req ptr\n");
230 req
->debug
= REQ_FREE
;
231 SLIST_INSERT_HEAD(&mpt
->request_free_list
, req
, link
);
234 /* Get a command buffer from the free queue */
236 mpt_get_request(mpt_softc_t
*mpt
)
239 req
= SLIST_FIRST(&mpt
->request_free_list
);
241 if (req
!= &mpt
->request_pool
[req
->index
]) {
242 panic("mpt_get_request: corrupted request free list\n");
244 if (req
->xfer
!= NULL
) {
245 panic("mpt_get_request: corrupted request free list (xfer)\n");
247 SLIST_REMOVE_HEAD(&mpt
->request_free_list
, link
);
248 req
->debug
= REQ_IN_PROGRESS
;
253 /* Pass the command to the IOC */
255 mpt_send_cmd(mpt_softc_t
*mpt
, request_t
*req
)
257 req
->sequence
= mpt
->sequence
++;
258 if (mpt
->verbose
> 1) {
260 pReq
= req
->req_vbuf
;
261 mpt_prt(mpt
, "Send Request %d (0x%x):",
262 req
->index
, req
->req_pbuf
);
263 mpt_prt(mpt
, "%08x %08x %08x %08x",
264 pReq
[0], pReq
[1], pReq
[2], pReq
[3]);
265 mpt_prt(mpt
, "%08x %08x %08x %08x",
266 pReq
[4], pReq
[5], pReq
[6], pReq
[7]);
267 mpt_prt(mpt
, "%08x %08x %08x %08x",
268 pReq
[8], pReq
[9], pReq
[10], pReq
[11]);
269 mpt_prt(mpt
, "%08x %08x %08x %08x",
270 pReq
[12], pReq
[13], pReq
[14], pReq
[15]);
272 MPT_SYNC_REQ(mpt
, req
, BUS_DMASYNC_PREREAD
|BUS_DMASYNC_PREWRITE
);
273 req
->debug
= REQ_ON_CHIP
;
274 mpt_write(mpt
, MPT_OFFSET_REQUEST_Q
, (u_int32_t
) req
->req_pbuf
);
278 * Give the reply buffer back to the IOC after we have
279 * finished processing it.
282 mpt_free_reply(mpt_softc_t
*mpt
, u_int32_t ptr
)
284 mpt_write(mpt
, MPT_OFFSET_REPLY_Q
, ptr
);
287 /* Get a reply from the IOC */
289 mpt_pop_reply_queue(mpt_softc_t
*mpt
)
291 return mpt_read(mpt
, MPT_OFFSET_REPLY_Q
);
295 * Send a command to the IOC via the handshake register.
297 * Only done at initialization time and for certain unusual
298 * commands such as device/bus reset as specified by LSI.
301 mpt_send_handshake_cmd(mpt_softc_t
*mpt
, size_t len
, void *cmd
)
304 u_int32_t data
, *data32
;
306 /* Check condition of the IOC */
307 data
= mpt_rd_db(mpt
);
308 if (((MPT_STATE(data
) != MPT_DB_STATE_READY
) &&
309 (MPT_STATE(data
) != MPT_DB_STATE_RUNNING
) &&
310 (MPT_STATE(data
) != MPT_DB_STATE_FAULT
)) ||
311 ( MPT_DB_IS_IN_USE(data
) )) {
312 mpt_prt(mpt
, "handshake aborted due to invalid doorbell state");
317 /* We move things in 32 bit chunks */
318 len
= (len
+ 3) >> 2;
321 /* Clear any left over pending doorbell interrupts */
322 if (MPT_DB_INTR(mpt_rd_intr(mpt
)))
323 mpt_write(mpt
, MPT_OFFSET_INTR_STATUS
, 0);
326 * Tell the handshake reg. we are going to send a command
327 * and how long it is going to be.
329 data
= (MPI_FUNCTION_HANDSHAKE
<< MPI_DOORBELL_FUNCTION_SHIFT
) |
330 (len
<< MPI_DOORBELL_ADD_DWORDS_SHIFT
);
331 mpt_write(mpt
, MPT_OFFSET_DOORBELL
, data
);
333 /* Wait for the chip to notice */
334 if (mpt_wait_db_int(mpt
) != MPT_OK
) {
335 mpt_prt(mpt
, "mpt_send_handshake_cmd timeout1");
339 /* Clear the interrupt */
340 mpt_write(mpt
, MPT_OFFSET_INTR_STATUS
, 0);
342 if (mpt_wait_db_ack(mpt
) != MPT_OK
) {
343 mpt_prt(mpt
, "mpt_send_handshake_cmd timeout2");
347 /* Send the command */
348 for (i
= 0; i
< len
; i
++) {
349 mpt_write(mpt
, MPT_OFFSET_DOORBELL
, *data32
++);
350 if (mpt_wait_db_ack(mpt
) != MPT_OK
) {
352 "mpt_send_handshake_cmd timeout! index = %d", i
);
359 /* Get the response from the handshake register */
361 mpt_recv_handshake_reply(mpt_softc_t
*mpt
, size_t reply_len
, void *reply
)
363 int left
, reply_left
;
365 MSG_DEFAULT_REPLY
*hdr
;
367 /* We move things out in 16 bit chunks */
369 data16
= (u_int16_t
*)reply
;
371 hdr
= (MSG_DEFAULT_REPLY
*)reply
;
374 if (mpt_wait_db_int(mpt
) != MPT_OK
) {
375 mpt_prt(mpt
, "mpt_recv_handshake_cmd timeout1");
378 *data16
++ = mpt_read(mpt
, MPT_OFFSET_DOORBELL
) & MPT_DB_DATA_MASK
;
379 mpt_write(mpt
, MPT_OFFSET_INTR_STATUS
, 0);
381 /* Get Second Word */
382 if (mpt_wait_db_int(mpt
) != MPT_OK
) {
383 mpt_prt(mpt
, "mpt_recv_handshake_cmd timeout2");
386 *data16
++ = mpt_read(mpt
, MPT_OFFSET_DOORBELL
) & MPT_DB_DATA_MASK
;
387 mpt_write(mpt
, MPT_OFFSET_INTR_STATUS
, 0);
389 /* With the second word, we can now look at the length */
390 if (mpt
->verbose
> 1 && ((reply_len
>> 1) != hdr
->MsgLength
)) {
391 mpt_prt(mpt
, "reply length does not match message length: "
392 "got 0x%02x, expected 0x%02x",
393 hdr
->MsgLength
<< 2, reply_len
<< 1);
396 /* Get rest of the reply; but don't overflow the provided buffer */
397 left
= (hdr
->MsgLength
<< 1) - 2;
398 reply_left
= reply_len
- 2;
402 if (mpt_wait_db_int(mpt
) != MPT_OK
) {
403 mpt_prt(mpt
, "mpt_recv_handshake_cmd timeout3");
406 datum
= mpt_read(mpt
, MPT_OFFSET_DOORBELL
);
408 if (reply_left
-- > 0)
409 *data16
++ = datum
& MPT_DB_DATA_MASK
;
411 mpt_write(mpt
, MPT_OFFSET_INTR_STATUS
, 0);
414 /* One more wait & clear at the end */
415 if (mpt_wait_db_int(mpt
) != MPT_OK
) {
416 mpt_prt(mpt
, "mpt_recv_handshake_cmd timeout4");
419 mpt_write(mpt
, MPT_OFFSET_INTR_STATUS
, 0);
421 if ((hdr
->IOCStatus
& MPI_IOCSTATUS_MASK
) != MPI_IOCSTATUS_SUCCESS
) {
422 if (mpt
->verbose
> 1)
423 mpt_print_reply(hdr
);
424 return (MPT_FAIL
| hdr
->IOCStatus
);
431 mpt_get_iocfacts(mpt_softc_t
*mpt
, MSG_IOC_FACTS_REPLY
*freplp
)
436 memset(&f_req
, 0, sizeof f_req
);
437 f_req
.Function
= MPI_FUNCTION_IOC_FACTS
;
438 f_req
.MsgContext
= 0x12071942;
439 error
= mpt_send_handshake_cmd(mpt
, sizeof f_req
, &f_req
);
442 error
= mpt_recv_handshake_reply(mpt
, sizeof (*freplp
), freplp
);
447 mpt_get_portfacts(mpt_softc_t
*mpt
, MSG_PORT_FACTS_REPLY
*freplp
)
449 MSG_PORT_FACTS f_req
;
452 /* XXX: Only getting PORT FACTS for Port 0 */
453 memset(&f_req
, 0, sizeof f_req
);
454 f_req
.Function
= MPI_FUNCTION_PORT_FACTS
;
455 f_req
.MsgContext
= 0x12071943;
456 error
= mpt_send_handshake_cmd(mpt
, sizeof f_req
, &f_req
);
459 error
= mpt_recv_handshake_reply(mpt
, sizeof (*freplp
), freplp
);
464 * Send the initialization request. This is where we specify how many
465 * SCSI busses and how many devices per bus we wish to emulate.
466 * This is also the command that specifies the max size of the reply
467 * frames from the IOC that we will be allocating.
470 mpt_send_ioc_init(mpt_softc_t
*mpt
, u_int32_t who
)
474 MSG_IOC_INIT_REPLY reply
;
476 memset(&init
, 0, sizeof init
);
478 init
.Function
= MPI_FUNCTION_IOC_INIT
;
479 init
.MaxDevices
= mpt
->mpt_max_devices
;
481 init
.ReplyFrameSize
= MPT_REPLY_SIZE
;
482 init
.MsgContext
= 0x12071941;
484 if ((error
= mpt_send_handshake_cmd(mpt
, sizeof init
, &init
)) != 0) {
488 error
= mpt_recv_handshake_reply(mpt
, sizeof reply
, &reply
);
494 * Utiltity routine to read configuration headers and pages
498 mpt_read_cfg_header(mpt_softc_t
*, int, int, int, fCONFIG_PAGE_HEADER
*);
501 mpt_read_cfg_header(mpt_softc_t
*mpt
, int PageType
, int PageNumber
,
502 int PageAddress
, fCONFIG_PAGE_HEADER
*rslt
)
507 MSG_CONFIG_REPLY
*reply
;
509 req
= mpt_get_request(mpt
);
511 cfgp
= req
->req_vbuf
;
512 memset(cfgp
, 0, sizeof *cfgp
);
514 cfgp
->Action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
515 cfgp
->Function
= MPI_FUNCTION_CONFIG
;
516 cfgp
->Header
.PageNumber
= (U8
) PageNumber
;
517 cfgp
->Header
.PageType
= (U8
) PageType
;
518 cfgp
->PageAddress
= PageAddress
;
519 MPI_pSGE_SET_FLAGS(((SGE_SIMPLE32
*) &cfgp
->PageBufferSGE
),
520 (MPI_SGE_FLAGS_LAST_ELEMENT
| MPI_SGE_FLAGS_END_OF_BUFFER
|
521 MPI_SGE_FLAGS_SIMPLE_ELEMENT
| MPI_SGE_FLAGS_END_OF_LIST
));
522 cfgp
->MsgContext
= req
->index
| 0x80000000;
524 mpt_check_doorbell(mpt
);
525 mpt_send_cmd(mpt
, req
);
530 if (++count
== 1000) {
531 mpt_prt(mpt
, "read_cfg_header timed out");
534 } while (req
->debug
== REQ_ON_CHIP
);
536 reply
= (MSG_CONFIG_REPLY
*) MPT_REPLY_PTOV(mpt
, req
->sequence
);
537 if ((reply
->IOCStatus
& MPI_IOCSTATUS_MASK
) != MPI_IOCSTATUS_SUCCESS
) {
538 mpt_prt(mpt
, "mpt_read_cfg_header: Config Info Status %x",
540 mpt_free_reply(mpt
, (req
->sequence
<< 1));
543 memcpy(rslt
, &reply
->Header
, sizeof (fCONFIG_PAGE_HEADER
));
544 mpt_free_reply(mpt
, (req
->sequence
<< 1));
545 mpt_free_request(mpt
, req
);
549 #define CFG_DATA_OFF 128
552 mpt_read_cfg_page(mpt_softc_t
*mpt
, int PageAddress
, fCONFIG_PAGE_HEADER
*hdr
)
559 MSG_CONFIG_REPLY
*reply
;
561 req
= mpt_get_request(mpt
);
563 cfgp
= req
->req_vbuf
;
564 memset(cfgp
, 0, MPT_REQUEST_AREA
);
565 cfgp
->Action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
566 cfgp
->Function
= MPI_FUNCTION_CONFIG
;
568 amt
= (cfgp
->Header
.PageLength
* sizeof (u_int32_t
));
569 cfgp
->Header
.PageType
&= MPI_CONFIG_PAGETYPE_MASK
;
570 cfgp
->PageAddress
= PageAddress
;
571 se
= (SGE_SIMPLE32
*) &cfgp
->PageBufferSGE
;
572 se
->Address
= req
->req_pbuf
+ CFG_DATA_OFF
;
573 MPI_pSGE_SET_LENGTH(se
, amt
);
574 MPI_pSGE_SET_FLAGS(se
, (MPI_SGE_FLAGS_SIMPLE_ELEMENT
|
575 MPI_SGE_FLAGS_LAST_ELEMENT
| MPI_SGE_FLAGS_END_OF_BUFFER
|
576 MPI_SGE_FLAGS_END_OF_LIST
));
578 cfgp
->MsgContext
= req
->index
| 0x80000000;
580 mpt_check_doorbell(mpt
);
581 mpt_send_cmd(mpt
, req
);
586 if (++count
== 1000) {
587 mpt_prt(mpt
, "read_cfg_page timed out");
590 } while (req
->debug
== REQ_ON_CHIP
);
592 reply
= (MSG_CONFIG_REPLY
*) MPT_REPLY_PTOV(mpt
, req
->sequence
);
593 if ((reply
->IOCStatus
& MPI_IOCSTATUS_MASK
) != MPI_IOCSTATUS_SUCCESS
) {
594 mpt_prt(mpt
, "mpt_read_cfg_page: Config Info Status %x",
596 mpt_free_reply(mpt
, (req
->sequence
<< 1));
599 mpt_free_reply(mpt
, (req
->sequence
<< 1));
601 bus_dmamap_sync(mpt
->request_dmat
, mpt
->request_dmap
,
602 BUS_DMASYNC_POSTREAD
);
604 if (cfgp
->Header
.PageType
== MPI_CONFIG_PAGETYPE_SCSI_PORT
&&
605 cfgp
->Header
.PageNumber
== 0) {
606 amt
= sizeof (fCONFIG_PAGE_SCSI_PORT_0
);
607 } else if (cfgp
->Header
.PageType
== MPI_CONFIG_PAGETYPE_SCSI_PORT
&&
608 cfgp
->Header
.PageNumber
== 1) {
609 amt
= sizeof (fCONFIG_PAGE_SCSI_PORT_1
);
610 } else if (cfgp
->Header
.PageType
== MPI_CONFIG_PAGETYPE_SCSI_PORT
&&
611 cfgp
->Header
.PageNumber
== 2) {
612 amt
= sizeof (fCONFIG_PAGE_SCSI_PORT_2
);
613 } else if (cfgp
->Header
.PageType
== MPI_CONFIG_PAGETYPE_SCSI_DEVICE
&&
614 cfgp
->Header
.PageNumber
== 0) {
615 amt
= sizeof (fCONFIG_PAGE_SCSI_DEVICE_0
);
616 } else if (cfgp
->Header
.PageType
== MPI_CONFIG_PAGETYPE_SCSI_DEVICE
&&
617 cfgp
->Header
.PageNumber
== 1) {
618 amt
= sizeof (fCONFIG_PAGE_SCSI_DEVICE_1
);
620 memcpy(hdr
, (char *)req
->req_vbuf
+ CFG_DATA_OFF
, amt
);
621 mpt_free_request(mpt
, req
);
626 mpt_write_cfg_page(mpt_softc_t
*mpt
, int PageAddress
, fCONFIG_PAGE_HEADER
*hdr
)
633 MSG_CONFIG_REPLY
*reply
;
635 req
= mpt_get_request(mpt
);
637 cfgp
= req
->req_vbuf
;
638 memset(cfgp
, 0, sizeof *cfgp
);
640 hdr_attr
= hdr
->PageType
& MPI_CONFIG_PAGEATTR_MASK
;
641 if (hdr_attr
!= MPI_CONFIG_PAGEATTR_CHANGEABLE
&&
642 hdr_attr
!= MPI_CONFIG_PAGEATTR_PERSISTENT
) {
643 mpt_prt(mpt
, "page type 0x%x not changeable",
644 hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
);
647 hdr
->PageType
&= MPI_CONFIG_PAGETYPE_MASK
;
649 cfgp
->Action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
650 cfgp
->Function
= MPI_FUNCTION_CONFIG
;
652 amt
= (cfgp
->Header
.PageLength
* sizeof (u_int32_t
));
653 cfgp
->PageAddress
= PageAddress
;
655 se
= (SGE_SIMPLE32
*) &cfgp
->PageBufferSGE
;
656 se
->Address
= req
->req_pbuf
+ CFG_DATA_OFF
;
657 MPI_pSGE_SET_LENGTH(se
, amt
);
658 MPI_pSGE_SET_FLAGS(se
, (MPI_SGE_FLAGS_SIMPLE_ELEMENT
|
659 MPI_SGE_FLAGS_LAST_ELEMENT
| MPI_SGE_FLAGS_END_OF_BUFFER
|
660 MPI_SGE_FLAGS_END_OF_LIST
| MPI_SGE_FLAGS_HOST_TO_IOC
));
662 cfgp
->MsgContext
= req
->index
| 0x80000000;
664 if (cfgp
->Header
.PageType
== MPI_CONFIG_PAGETYPE_SCSI_PORT
&&
665 cfgp
->Header
.PageNumber
== 0) {
666 amt
= sizeof (fCONFIG_PAGE_SCSI_PORT_0
);
667 } else if (cfgp
->Header
.PageType
== MPI_CONFIG_PAGETYPE_SCSI_PORT
&&
668 cfgp
->Header
.PageNumber
== 1) {
669 amt
= sizeof (fCONFIG_PAGE_SCSI_PORT_1
);
670 } else if (cfgp
->Header
.PageType
== MPI_CONFIG_PAGETYPE_SCSI_PORT
&&
671 cfgp
->Header
.PageNumber
== 2) {
672 amt
= sizeof (fCONFIG_PAGE_SCSI_PORT_2
);
673 } else if (cfgp
->Header
.PageType
== MPI_CONFIG_PAGETYPE_SCSI_DEVICE
&&
674 cfgp
->Header
.PageNumber
== 0) {
675 amt
= sizeof (fCONFIG_PAGE_SCSI_DEVICE_0
);
676 } else if (cfgp
->Header
.PageType
== MPI_CONFIG_PAGETYPE_SCSI_DEVICE
&&
677 cfgp
->Header
.PageNumber
== 1) {
678 amt
= sizeof (fCONFIG_PAGE_SCSI_DEVICE_1
);
680 memcpy((char *)req
->req_vbuf
+ CFG_DATA_OFF
, hdr
, amt
);
681 /* Restore stripped out attributes */
682 hdr
->PageType
|= hdr_attr
;
684 mpt_check_doorbell(mpt
);
685 mpt_send_cmd(mpt
, req
);
690 if (++count
== 1000) {
691 hdr
->PageType
|= hdr_attr
;
692 mpt_prt(mpt
, "mpt_write_cfg_page timed out");
695 } while (req
->debug
== REQ_ON_CHIP
);
697 reply
= (MSG_CONFIG_REPLY
*) MPT_REPLY_PTOV(mpt
, req
->sequence
);
698 if ((reply
->IOCStatus
& MPI_IOCSTATUS_MASK
) != MPI_IOCSTATUS_SUCCESS
) {
699 mpt_prt(mpt
, "mpt_write_cfg_page: Config Info Status %x",
701 mpt_free_reply(mpt
, (req
->sequence
<< 1));
704 mpt_free_reply(mpt
, (req
->sequence
<< 1));
706 mpt_free_request(mpt
, req
);
711 * Read SCSI configuration information
714 mpt_read_config_info_spi(mpt_softc_t
*mpt
)
718 rv
= mpt_read_cfg_header(mpt
, MPI_CONFIG_PAGETYPE_SCSI_PORT
, 0,
719 0, &mpt
->mpt_port_page0
.Header
);
723 if (mpt
->verbose
> 1) {
724 mpt_prt(mpt
, "SPI Port Page 0 Header: %x %x %x %x",
725 mpt
->mpt_port_page0
.Header
.PageVersion
,
726 mpt
->mpt_port_page0
.Header
.PageLength
,
727 mpt
->mpt_port_page0
.Header
.PageNumber
,
728 mpt
->mpt_port_page0
.Header
.PageType
);
731 rv
= mpt_read_cfg_header(mpt
, MPI_CONFIG_PAGETYPE_SCSI_PORT
, 1,
732 0, &mpt
->mpt_port_page1
.Header
);
736 if (mpt
->verbose
> 1) {
737 mpt_prt(mpt
, "SPI Port Page 1 Header: %x %x %x %x",
738 mpt
->mpt_port_page1
.Header
.PageVersion
,
739 mpt
->mpt_port_page1
.Header
.PageLength
,
740 mpt
->mpt_port_page1
.Header
.PageNumber
,
741 mpt
->mpt_port_page1
.Header
.PageType
);
744 rv
= mpt_read_cfg_header(mpt
, MPI_CONFIG_PAGETYPE_SCSI_PORT
, 2,
745 0, &mpt
->mpt_port_page2
.Header
);
750 if (mpt
->verbose
> 1) {
751 mpt_prt(mpt
, "SPI Port Page 2 Header: %x %x %x %x",
752 mpt
->mpt_port_page1
.Header
.PageVersion
,
753 mpt
->mpt_port_page1
.Header
.PageLength
,
754 mpt
->mpt_port_page1
.Header
.PageNumber
,
755 mpt
->mpt_port_page1
.Header
.PageType
);
758 for (i
= 0; i
< 16; i
++) {
759 rv
= mpt_read_cfg_header(mpt
, MPI_CONFIG_PAGETYPE_SCSI_DEVICE
,
760 0, i
, &mpt
->mpt_dev_page0
[i
].Header
);
764 if (mpt
->verbose
> 1) {
766 "SPI Target %d Device Page 0 Header: %x %x %x %x",
767 i
, mpt
->mpt_dev_page0
[i
].Header
.PageVersion
,
768 mpt
->mpt_dev_page0
[i
].Header
.PageLength
,
769 mpt
->mpt_dev_page0
[i
].Header
.PageNumber
,
770 mpt
->mpt_dev_page0
[i
].Header
.PageType
);
773 rv
= mpt_read_cfg_header(mpt
, MPI_CONFIG_PAGETYPE_SCSI_DEVICE
,
774 1, i
, &mpt
->mpt_dev_page1
[i
].Header
);
778 if (mpt
->verbose
> 1) {
780 "SPI Target %d Device Page 1 Header: %x %x %x %x",
781 i
, mpt
->mpt_dev_page1
[i
].Header
.PageVersion
,
782 mpt
->mpt_dev_page1
[i
].Header
.PageLength
,
783 mpt
->mpt_dev_page1
[i
].Header
.PageNumber
,
784 mpt
->mpt_dev_page1
[i
].Header
.PageType
);
789 * At this point, we don't *have* to fail. As long as we have
790 * valid config header information, we can (barely) lurch
794 rv
= mpt_read_cfg_page(mpt
, 0, &mpt
->mpt_port_page0
.Header
);
796 mpt_prt(mpt
, "failed to read SPI Port Page 0");
797 } else if (mpt
->verbose
> 1) {
799 "SPI Port Page 0: Capabilities %x PhysicalInterface %x",
800 mpt
->mpt_port_page0
.Capabilities
,
801 mpt
->mpt_port_page0
.PhysicalInterface
);
804 rv
= mpt_read_cfg_page(mpt
, 0, &mpt
->mpt_port_page1
.Header
);
806 mpt_prt(mpt
, "failed to read SPI Port Page 1");
807 } else if (mpt
->verbose
> 1) {
809 "SPI Port Page 1: Configuration %x OnBusTimerValue %x",
810 mpt
->mpt_port_page1
.Configuration
,
811 mpt
->mpt_port_page1
.OnBusTimerValue
);
814 rv
= mpt_read_cfg_page(mpt
, 0, &mpt
->mpt_port_page2
.Header
);
816 mpt_prt(mpt
, "failed to read SPI Port Page 2");
817 } else if (mpt
->verbose
> 1) {
819 "SPI Port Page 2: Flags %x Settings %x",
820 mpt
->mpt_port_page2
.PortFlags
,
821 mpt
->mpt_port_page2
.PortSettings
);
822 for (i
= 0; i
< 16; i
++) {
824 "SPI Port Page 2 Tgt %d: timo %x SF %x Flags %x",
825 i
, mpt
->mpt_port_page2
.DeviceSettings
[i
].Timeout
,
826 mpt
->mpt_port_page2
.DeviceSettings
[i
].SyncFactor
,
827 mpt
->mpt_port_page2
.DeviceSettings
[i
].DeviceFlags
);
831 for (i
= 0; i
< 16; i
++) {
832 rv
= mpt_read_cfg_page(mpt
, i
, &mpt
->mpt_dev_page0
[i
].Header
);
834 mpt_prt(mpt
, "cannot read SPI Tgt %d Device Page 0", i
);
837 if (mpt
->verbose
> 1) {
839 "SPI Tgt %d Page 0: NParms %x Information %x",
840 i
, mpt
->mpt_dev_page0
[i
].NegotiatedParameters
,
841 mpt
->mpt_dev_page0
[i
].Information
);
843 rv
= mpt_read_cfg_page(mpt
, i
, &mpt
->mpt_dev_page1
[i
].Header
);
845 mpt_prt(mpt
, "cannot read SPI Tgt %d Device Page 1", i
);
848 if (mpt
->verbose
> 1) {
850 "SPI Tgt %d Page 1: RParms %x Configuration %x",
851 i
, mpt
->mpt_dev_page1
[i
].RequestedParameters
,
852 mpt
->mpt_dev_page1
[i
].Configuration
);
859 * Validate SPI configuration information.
861 * In particular, validate SPI Port Page 1.
864 mpt_set_initial_config_spi(mpt_softc_t
*mpt
)
866 int i
, pp1val
= ((1 << mpt
->mpt_ini_id
) << 16) | mpt
->mpt_ini_id
;
868 mpt
->mpt_disc_enable
= 0xff;
869 mpt
->mpt_tag_enable
= 0;
871 if (mpt
->mpt_port_page1
.Configuration
!= pp1val
) {
872 fCONFIG_PAGE_SCSI_PORT_1 tmp
;
874 "SPI Port Page 1 Config value bad (%x)- should be %x",
875 mpt
->mpt_port_page1
.Configuration
, pp1val
);
876 tmp
= mpt
->mpt_port_page1
;
877 tmp
.Configuration
= pp1val
;
878 if (mpt_write_cfg_page(mpt
, 0, &tmp
.Header
)) {
881 if (mpt_read_cfg_page(mpt
, 0, &tmp
.Header
)) {
884 if (tmp
.Configuration
!= pp1val
) {
886 "failed to reset SPI Port Page 1 Config value");
889 mpt
->mpt_port_page1
= tmp
;
892 for (i
= 0; i
< 16; i
++) {
893 fCONFIG_PAGE_SCSI_DEVICE_1 tmp
;
894 tmp
= mpt
->mpt_dev_page1
[i
];
895 tmp
.RequestedParameters
= 0;
896 tmp
.Configuration
= 0;
897 if (mpt
->verbose
> 1) {
899 "Set Tgt %d SPI DevicePage 1 values to %x 0 %x",
900 i
, tmp
.RequestedParameters
, tmp
.Configuration
);
902 if (mpt_write_cfg_page(mpt
, i
, &tmp
.Header
)) {
905 if (mpt_read_cfg_page(mpt
, i
, &tmp
.Header
)) {
908 mpt
->mpt_dev_page1
[i
] = tmp
;
909 if (mpt
->verbose
> 1) {
911 "SPI Tgt %d Page 1: RParm %x Configuration %x", i
,
912 mpt
->mpt_dev_page1
[i
].RequestedParameters
,
913 mpt
->mpt_dev_page1
[i
].Configuration
);
923 mpt_send_port_enable(mpt_softc_t
*mpt
, int port
)
927 MSG_PORT_ENABLE
*enable_req
;
929 req
= mpt_get_request(mpt
);
931 enable_req
= req
->req_vbuf
;
932 memset(enable_req
, 0, sizeof *enable_req
);
934 enable_req
->Function
= MPI_FUNCTION_PORT_ENABLE
;
935 enable_req
->MsgContext
= req
->index
| 0x80000000;
936 enable_req
->PortNumber
= port
;
938 mpt_check_doorbell(mpt
);
939 if (mpt
->verbose
> 1) {
940 mpt_prt(mpt
, "enabling port %d", port
);
942 mpt_send_cmd(mpt
, req
);
948 if (++count
== 100000) {
949 mpt_prt(mpt
, "port enable timed out");
952 } while (req
->debug
== REQ_ON_CHIP
);
953 mpt_free_request(mpt
, req
);
958 * Enable/Disable asynchronous event reporting.
960 * NB: this is the first command we send via shared memory
961 * instead of the handshake register.
964 mpt_send_event_request(mpt_softc_t
*mpt
, int onoff
)
967 MSG_EVENT_NOTIFY
*enable_req
;
969 req
= mpt_get_request(mpt
);
971 enable_req
= req
->req_vbuf
;
972 memset(enable_req
, 0, sizeof *enable_req
);
974 enable_req
->Function
= MPI_FUNCTION_EVENT_NOTIFICATION
;
975 enable_req
->MsgContext
= req
->index
| 0x80000000;
976 enable_req
->Switch
= onoff
;
978 mpt_check_doorbell(mpt
);
979 if (mpt
->verbose
> 1) {
980 mpt_prt(mpt
, "%sabling async events", onoff
? "en" : "dis");
982 mpt_send_cmd(mpt
, req
);
988 * Un-mask the interrupts on the chip.
991 mpt_enable_ints(mpt_softc_t
*mpt
)
993 /* Unmask every thing except door bell int */
994 mpt_write(mpt
, MPT_OFFSET_INTR_MASK
, MPT_INTR_DB_MASK
);
998 * Mask the interrupts on the chip.
1001 mpt_disable_ints(mpt_softc_t
*mpt
)
1003 /* Mask all interrupts */
1004 mpt_write(mpt
, MPT_OFFSET_INTR_MASK
,
1005 MPT_INTR_REPLY_MASK
| MPT_INTR_DB_MASK
);
1008 /* (Re)Initialize the chip for use */
1010 mpt_hw_init(mpt_softc_t
*mpt
)
1016 * Start by making sure we're not at FAULT or RESET state
1018 for (try = 0; try < MPT_MAX_TRYS
; try++) {
1020 db
= mpt_rd_db(mpt
);
1022 switch (MPT_STATE(db
)) {
1023 case MPT_DB_STATE_READY
:
1027 /* if peer has already reset us, don't do it again! */
1028 if (MPT_WHO(db
) == MPT_DB_INIT_PCIPEER
)
1031 case MPT_DB_STATE_RESET
:
1032 case MPT_DB_STATE_FAULT
:
1033 if (mpt_reset(mpt
) != MPT_OK
) {
1044 mpt_init(mpt_softc_t
*mpt
, u_int32_t who
)
1047 MSG_IOC_FACTS_REPLY facts
;
1048 MSG_PORT_FACTS_REPLY pfp
;
1052 /* Put all request buffers (back) on the free list */
1053 SLIST_INIT(&mpt
->request_free_list
);
1054 for (val
= 0; val
< MPT_MAX_REQUESTS(mpt
); val
++) {
1055 mpt_free_request(mpt
, &mpt
->request_pool
[val
]);
1058 if (mpt
->verbose
> 1) {
1059 mpt_prt(mpt
, "doorbell req = %s",
1060 mpt_ioc_diag(mpt_read(mpt
, MPT_OFFSET_DOORBELL
)));
1064 * Start by making sure we're not at FAULT or RESET state
1066 if (mpt_hw_init(mpt
) != 0)
1069 for (try = 0; try < MPT_MAX_TRYS
; try++) {
1071 * No need to reset if the IOC is already in the READY state.
1074 if (mpt_get_iocfacts(mpt
, &facts
) != MPT_OK
) {
1075 mpt_prt(mpt
, "mpt_get_iocfacts failed");
1079 if (mpt
->verbose
> 1) {
1081 "IOCFACTS: GlobalCredits=%d BlockSize=%u "
1082 "Request Frame Size %u\n", facts
.GlobalCredits
,
1083 facts
.BlockSize
, facts
.RequestFrameSize
);
1085 mpt
->mpt_max_devices
= facts
.MaxDevices
;
1086 mpt
->mpt_global_credits
= facts
.GlobalCredits
;
1087 mpt
->request_frame_size
= facts
.RequestFrameSize
;
1089 if (mpt_get_portfacts(mpt
, &pfp
) != MPT_OK
) {
1090 mpt_prt(mpt
, "mpt_get_portfacts failed");
1094 if (mpt
->verbose
> 1) {
1096 "PORTFACTS: Type %x PFlags %x IID %d MaxDev %d\n",
1097 pfp
.PortType
, pfp
.ProtocolFlags
, pfp
.PortSCSIID
,
1101 if (!(pfp
.ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_INITIATOR
)) {
1102 mpt_prt(mpt
, "initiator role unsupported");
1106 switch (pfp
.PortType
) {
1107 case MPI_PORTFACTS_PORTTYPE_FC
:
1109 mpt
->mpt_max_devices
= 255;
1111 case MPI_PORTFACTS_PORTTYPE_SCSI
:
1113 /* some SPI controllers (VMWare, Sun) lie */
1114 mpt
->mpt_max_devices
= 16;
1116 case MPI_PORTFACTS_PORTTYPE_SAS
:
1120 mpt_prt(mpt
, "Unsupported Port Type (%x)",
1125 mpt
->mpt_ini_id
= pfp
.PortSCSIID
;
1127 if (mpt_send_ioc_init(mpt
, who
) != MPT_OK
) {
1128 mpt_prt(mpt
, "mpt_send_ioc_init failed");
1132 if (mpt
->verbose
> 1) {
1133 mpt_prt(mpt
, "mpt_send_ioc_init ok");
1136 if (mpt_wait_state(mpt
, MPT_DB_STATE_RUNNING
) != MPT_OK
) {
1137 mpt_prt(mpt
, "IOC failed to go to run state");
1140 if (mpt
->verbose
> 1) {
1141 mpt_prt(mpt
, "IOC now at RUNSTATE");
1145 * Give it reply buffers
1147 * Do *not* except global credits.
1149 for (val
= 0, pptr
= mpt
->reply_phys
;
1150 (pptr
+ MPT_REPLY_SIZE
) < (mpt
->reply_phys
+ PAGE_SIZE
);
1151 pptr
+= MPT_REPLY_SIZE
) {
1152 mpt_free_reply(mpt
, pptr
);
1153 if (++val
== mpt
->mpt_global_credits
- 1)
1158 * Enable asynchronous event reporting
1160 mpt_send_event_request(mpt
, 1);
1164 * Read set up initial configuration information
1165 * (SPI only for now)
1169 if (mpt_read_config_info_spi(mpt
)) {
1172 if (mpt_set_initial_config_spi(mpt
)) {
1178 * Now enable the port
1180 if (mpt_send_port_enable(mpt
, 0) != MPT_OK
) {
1181 mpt_prt(mpt
, "failed to enable port 0");
1185 if (mpt
->verbose
> 1) {
1186 mpt_prt(mpt
, "enabled port 0");
1189 /* Everything worked */
1193 if (try >= MPT_MAX_TRYS
) {
1194 mpt_prt(mpt
, "failed to initialize IOC");
1198 if (mpt
->verbose
> 1) {
1199 mpt_prt(mpt
, "enabling interrupts");
1202 mpt_enable_ints(mpt
);