4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright (c) 2014, Tegile Systems Inc. All rights reserved.
26 * Copyright (c) 2017, Joyent, Inc.
30 * Copyright (c) 2000 to 2009, LSI Corporation.
31 * All rights reserved.
33 * Redistribution and use in source and binary forms of all code within
34 * this file that is exclusively owned by LSI, with or without
35 * modification, is permitted provided that, in addition to the CDDL 1.0
36 * License requirements, the following conditions are met:
38 * Neither the name of the author nor the names of its contributors may be
39 * used to endorse or promote products derived from this software without
40 * specific prior written permission.
42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
45 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
46 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
47 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
48 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
49 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
50 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
51 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
52 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
57 * mptsas_init - This file contains all the functions used to initialize
58 * MPT2.0 based hardware.
66 * standard header files
69 #include <sys/scsi/scsi.h>
72 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
73 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
74 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
75 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
76 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
77 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
80 * private header files.
82 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
84 static int mptsas_ioc_do_get_facts(mptsas_t
*mpt
, caddr_t memp
, int var
,
85 ddi_acc_handle_t accessp
);
86 static int mptsas_ioc_do_get_facts_reply(mptsas_t
*mpt
, caddr_t memp
, int var
,
87 ddi_acc_handle_t accessp
);
88 static int mptsas_ioc_do_get_port_facts(mptsas_t
*mpt
, caddr_t memp
, int var
,
89 ddi_acc_handle_t accessp
);
90 static int mptsas_ioc_do_get_port_facts_reply(mptsas_t
*mpt
, caddr_t memp
,
91 int var
, ddi_acc_handle_t accessp
);
92 static int mptsas_ioc_do_enable_port(mptsas_t
*mpt
, caddr_t memp
, int var
,
93 ddi_acc_handle_t accessp
);
94 static int mptsas_ioc_do_enable_port_reply(mptsas_t
*mpt
, caddr_t memp
, int var
,
95 ddi_acc_handle_t accessp
);
96 static int mptsas_ioc_do_enable_event_notification(mptsas_t
*mpt
, caddr_t memp
,
97 int var
, ddi_acc_handle_t accessp
);
98 static int mptsas_ioc_do_enable_event_notification_reply(mptsas_t
*mpt
,
99 caddr_t memp
, int var
, ddi_acc_handle_t accessp
);
100 static int mptsas_do_ioc_init(mptsas_t
*mpt
, caddr_t memp
, int var
,
101 ddi_acc_handle_t accessp
);
102 static int mptsas_do_ioc_init_reply(mptsas_t
*mpt
, caddr_t memp
, int var
,
103 ddi_acc_handle_t accessp
);
106 mptsas_devid_type_string(mptsas_t
*mpt
)
108 switch (mpt
->m_devid
) {
109 case MPI2_MFGPAGE_DEVID_SAS2008
:
111 case MPI2_MFGPAGE_DEVID_SAS2004
:
113 case MPI2_MFGPAGE_DEVID_SAS2108_1
:
114 case MPI2_MFGPAGE_DEVID_SAS2108_2
:
115 case MPI2_MFGPAGE_DEVID_SAS2108_3
:
117 case MPI2_MFGPAGE_DEVID_SAS2116_1
:
118 case MPI2_MFGPAGE_DEVID_SAS2116_2
:
120 case MPI2_MFGPAGE_DEVID_SAS2208_1
:
121 case MPI2_MFGPAGE_DEVID_SAS2208_2
:
122 case MPI2_MFGPAGE_DEVID_SAS2208_3
:
123 case MPI2_MFGPAGE_DEVID_SAS2208_4
:
124 case MPI2_MFGPAGE_DEVID_SAS2208_5
:
125 case MPI2_MFGPAGE_DEVID_SAS2208_6
:
127 case MPI2_MFGPAGE_DEVID_SAS2308_1
:
128 case MPI2_MFGPAGE_DEVID_SAS2308_2
:
129 case MPI2_MFGPAGE_DEVID_SAS2308_3
:
131 case MPI25_MFGPAGE_DEVID_SAS3004
:
133 case MPI25_MFGPAGE_DEVID_SAS3008
:
135 case MPI25_MFGPAGE_DEVID_SAS3108_1
:
136 case MPI25_MFGPAGE_DEVID_SAS3108_2
:
137 case MPI25_MFGPAGE_DEVID_SAS3108_5
:
138 case MPI25_MFGPAGE_DEVID_SAS3108_6
:
146 mptsas_ioc_get_facts(mptsas_t
*mpt
)
149 * Send get facts messages
151 if (mptsas_do_dma(mpt
, sizeof (MPI2_IOC_FACTS_REQUEST
), 0,
152 mptsas_ioc_do_get_facts
)) {
153 return (DDI_FAILURE
);
157 * Get facts reply messages
159 if (mptsas_do_dma(mpt
, sizeof (MPI2_IOC_FACTS_REPLY
), 0,
160 mptsas_ioc_do_get_facts_reply
)) {
161 return (DDI_FAILURE
);
164 return (DDI_SUCCESS
);
168 mptsas_ioc_do_get_facts(mptsas_t
*mpt
, caddr_t memp
, int var
,
169 ddi_acc_handle_t accessp
)
172 _NOTE(ARGUNUSED(var
))
174 pMpi2IOCFactsRequest_t facts
;
177 bzero(memp
, sizeof (*facts
));
178 facts
= (void *)memp
;
179 ddi_put8(accessp
, &facts
->Function
, MPI2_FUNCTION_IOC_FACTS
);
180 numbytes
= sizeof (*facts
);
183 * Post message via handshake
185 if (mptsas_send_handshake_msg(mpt
, memp
, numbytes
, accessp
)) {
186 return (DDI_FAILURE
);
189 return (DDI_SUCCESS
);
193 mptsas_ioc_do_get_facts_reply(mptsas_t
*mpt
, caddr_t memp
, int var
,
194 ddi_acc_handle_t accessp
)
197 _NOTE(ARGUNUSED(var
))
200 pMpi2IOCFactsReply_t factsreply
;
204 uint16_t numReplyFrames
;
205 uint16_t queueSize
, queueDiff
;
208 uint32_t capabilities
;
211 bzero(memp
, sizeof (*factsreply
));
212 factsreply
= (void *)memp
;
213 numbytes
= sizeof (*factsreply
);
216 * get ioc facts reply message
218 if (mptsas_get_handshake_msg(mpt
, memp
, numbytes
, accessp
)) {
219 return (DDI_FAILURE
);
222 if (iocstatus
= ddi_get16(accessp
, &factsreply
->IOCStatus
)) {
223 mptsas_log(mpt
, CE_WARN
, "mptsas_ioc_do_get_facts_reply: "
224 "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus
,
225 ddi_get32(accessp
, &factsreply
->IOCLogInfo
));
226 return (DDI_FAILURE
);
230 * store key values from reply to mpt structure
232 mpt
->m_fwversion
= ddi_get32(accessp
, &factsreply
->FWVersion
.Word
);
233 mpt
->m_productid
= ddi_get16(accessp
, &factsreply
->ProductID
);
236 (void) sprintf(buf
, "%u.%u.%u.%u",
237 ddi_get8(accessp
, &factsreply
->FWVersion
.Struct
.Major
),
238 ddi_get8(accessp
, &factsreply
->FWVersion
.Struct
.Minor
),
239 ddi_get8(accessp
, &factsreply
->FWVersion
.Struct
.Unit
),
240 ddi_get8(accessp
, &factsreply
->FWVersion
.Struct
.Dev
));
241 mptsas_log(mpt
, CE_NOTE
, "?MPT Firmware version v%s (%s)\n",
242 buf
, mptsas_devid_type_string(mpt
));
243 (void) ddi_prop_update_string(DDI_DEV_T_NONE
, mpt
->m_dip
,
244 "firmware-version", buf
);
247 * Set up request info.
249 mpt
->m_max_requests
= ddi_get16(accessp
,
250 &factsreply
->RequestCredit
) - 1;
251 mpt
->m_req_frame_size
= ddi_get16(accessp
,
252 &factsreply
->IOCRequestFrameSize
) * 4;
255 * Size of reply free queue should be the number of requests
256 * plus some additional for events (32). Make sure number of
257 * reply frames is not a multiple of 16 so that the queue sizes
258 * are calculated correctly later to be a multiple of 16.
260 mpt
->m_reply_frame_size
= ddi_get8(accessp
,
261 &factsreply
->ReplyFrameSize
) * 4;
262 numReplyFrames
= mpt
->m_max_requests
+ 32;
263 if (!(numReplyFrames
% 16)) {
266 mpt
->m_max_replies
= numReplyFrames
;
267 queueSize
= numReplyFrames
;
268 queueSize
+= 16 - (queueSize
% 16);
269 mpt
->m_free_queue_depth
= queueSize
;
272 * Size of reply descriptor post queue should be the number of
273 * request frames + the number of reply frames + 1 and needs to
274 * be a multiple of 16. This size can be no larger than
275 * MaxReplyDescriptorPostQueueDepth from IOCFacts. If the
276 * calculated queue size is larger than allowed, subtract a
277 * multiple of 16 from m_max_requests, m_max_replies, and
278 * m_reply_free_depth.
280 queueSize
= mpt
->m_max_requests
+ numReplyFrames
+ 1;
281 if (queueSize
% 16) {
282 queueSize
+= 16 - (queueSize
% 16);
284 mpt
->m_post_queue_depth
= ddi_get16(accessp
,
285 &factsreply
->MaxReplyDescriptorPostQueueDepth
);
286 if (queueSize
> mpt
->m_post_queue_depth
) {
287 queueDiff
= queueSize
- mpt
->m_post_queue_depth
;
288 if (queueDiff
% 16) {
289 queueDiff
+= 16 - (queueDiff
% 16);
291 mpt
->m_max_requests
-= queueDiff
;
292 mpt
->m_max_replies
-= queueDiff
;
293 mpt
->m_free_queue_depth
-= queueDiff
;
294 queueSize
-= queueDiff
;
296 mpt
->m_post_queue_depth
= queueSize
;
299 * Set up max chain depth.
301 mpt
->m_max_chain_depth
= ddi_get8(accessp
,
302 &factsreply
->MaxChainDepth
);
303 mpt
->m_ioc_capabilities
= ddi_get32(accessp
,
304 &factsreply
->IOCCapabilities
);
307 * Set flag to check for SAS3 support.
309 msgversion
= ddi_get16(accessp
, &factsreply
->MsgVersion
);
310 if (msgversion
>= MPI2_VERSION_02_05
) {
311 mptsas_log(mpt
, CE_NOTE
, "?mpt_sas%d SAS 3 Supported\n",
315 mptsas_log(mpt
, CE_NOTE
, "?mpt_sas%d MPI Version 0x%x\n",
316 mpt
->m_instance
, msgversion
);
320 * Calculate max frames per request based on DMA S/G length.
322 simple_sge_main
= MPTSAS_MAX_FRAME_SGES64(mpt
) - 1;
323 simple_sge_next
= mpt
->m_req_frame_size
/ MPTSAS_SGE_SIZE(mpt
) - 1;
325 mpt
->m_max_request_frames
= (MPTSAS_MAX_DMA_SEGS
-
326 simple_sge_main
) / simple_sge_next
+ 1;
327 if (((MPTSAS_MAX_DMA_SEGS
- simple_sge_main
) %
328 simple_sge_next
) > 1) {
329 mpt
->m_max_request_frames
++;
333 * Check if controller supports FW diag buffers and set flag to enable
336 capabilities
= ddi_get32(accessp
, &factsreply
->IOCCapabilities
);
337 if (capabilities
& MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER
) {
338 mpt
->m_fw_diag_buffer_list
[MPI2_DIAG_BUF_TYPE_TRACE
].enabled
=
341 if (capabilities
& MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER
) {
342 mpt
->m_fw_diag_buffer_list
[MPI2_DIAG_BUF_TYPE_SNAPSHOT
].
345 if (capabilities
& MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER
) {
346 mpt
->m_fw_diag_buffer_list
[MPI2_DIAG_BUF_TYPE_EXTENDED
].
351 * Check if controller supports replaying events when issuing Message
352 * Unit Reset and set flag to enable MUR.
354 if (capabilities
& MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY
) {
355 mpt
->m_event_replay
= TRUE
;
359 * Check if controller supports IR.
361 if (capabilities
& MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID
) {
362 mpt
->m_ir_capable
= TRUE
;
365 return (DDI_SUCCESS
);
369 mptsas_ioc_get_port_facts(mptsas_t
*mpt
, int port
)
372 * Send get port facts message
374 if (mptsas_do_dma(mpt
, sizeof (MPI2_PORT_FACTS_REQUEST
), port
,
375 mptsas_ioc_do_get_port_facts
)) {
376 return (DDI_FAILURE
);
380 * Get port facts reply message
382 if (mptsas_do_dma(mpt
, sizeof (MPI2_PORT_FACTS_REPLY
), port
,
383 mptsas_ioc_do_get_port_facts_reply
)) {
384 return (DDI_FAILURE
);
387 return (DDI_SUCCESS
);
391 mptsas_ioc_do_get_port_facts(mptsas_t
*mpt
, caddr_t memp
, int var
,
392 ddi_acc_handle_t accessp
)
394 pMpi2PortFactsRequest_t facts
;
397 bzero(memp
, sizeof (*facts
));
398 facts
= (void *)memp
;
399 ddi_put8(accessp
, &facts
->Function
, MPI2_FUNCTION_PORT_FACTS
);
400 ddi_put8(accessp
, &facts
->PortNumber
, var
);
401 numbytes
= sizeof (*facts
);
404 * Send port facts message via handshake
406 if (mptsas_send_handshake_msg(mpt
, memp
, numbytes
, accessp
)) {
407 return (DDI_FAILURE
);
410 return (DDI_SUCCESS
);
414 mptsas_ioc_do_get_port_facts_reply(mptsas_t
*mpt
, caddr_t memp
, int var
,
415 ddi_acc_handle_t accessp
)
418 _NOTE(ARGUNUSED(var
))
420 pMpi2PortFactsReply_t factsreply
;
424 bzero(memp
, sizeof (*factsreply
));
425 factsreply
= (void *)memp
;
426 numbytes
= sizeof (*factsreply
);
429 * Get port facts reply message via handshake
431 if (mptsas_get_handshake_msg(mpt
, memp
, numbytes
, accessp
)) {
432 return (DDI_FAILURE
);
435 if (iocstatus
= ddi_get16(accessp
, &factsreply
->IOCStatus
)) {
436 mptsas_log(mpt
, CE_WARN
, "mptsas_ioc_do_get_port_facts_reply: "
437 "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus
,
438 ddi_get32(accessp
, &factsreply
->IOCLogInfo
));
439 return (DDI_FAILURE
);
442 return (DDI_SUCCESS
);
446 mptsas_ioc_enable_port(mptsas_t
*mpt
)
449 * Send enable port message
451 if (mptsas_do_dma(mpt
, sizeof (MPI2_PORT_ENABLE_REQUEST
), 0,
452 mptsas_ioc_do_enable_port
)) {
453 return (DDI_FAILURE
);
457 * Get enable port reply message
459 if (mptsas_do_dma(mpt
, sizeof (MPI2_PORT_ENABLE_REPLY
), 0,
460 mptsas_ioc_do_enable_port_reply
)) {
461 return (DDI_FAILURE
);
464 return (DDI_SUCCESS
);
468 mptsas_ioc_do_enable_port(mptsas_t
*mpt
, caddr_t memp
, int var
,
469 ddi_acc_handle_t accessp
)
472 _NOTE(ARGUNUSED(var
))
474 pMpi2PortEnableRequest_t enable
;
477 bzero(memp
, sizeof (*enable
));
478 enable
= (void *)memp
;
479 ddi_put8(accessp
, &enable
->Function
, MPI2_FUNCTION_PORT_ENABLE
);
480 numbytes
= sizeof (*enable
);
483 * Send message via handshake
485 if (mptsas_send_handshake_msg(mpt
, memp
, numbytes
, accessp
)) {
486 return (DDI_FAILURE
);
489 return (DDI_SUCCESS
);
493 mptsas_ioc_do_enable_port_reply(mptsas_t
*mpt
, caddr_t memp
, int var
,
494 ddi_acc_handle_t accessp
)
497 _NOTE(ARGUNUSED(var
))
502 pMpi2PortEnableReply_t portreply
;
504 numbytes
= sizeof (MPI2_PORT_ENABLE_REPLY
);
505 bzero(memp
, numbytes
);
506 portreply
= (void *)memp
;
509 * Get message via handshake
511 if (mptsas_get_handshake_msg(mpt
, memp
, numbytes
, accessp
)) {
512 return (DDI_FAILURE
);
515 if (iocstatus
= ddi_get16(accessp
, &portreply
->IOCStatus
)) {
516 mptsas_log(mpt
, CE_WARN
, "mptsas_ioc_do_enable_port_reply: "
517 "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus
,
518 ddi_get32(accessp
, &portreply
->IOCLogInfo
));
519 return (DDI_FAILURE
);
522 return (DDI_SUCCESS
);
526 mptsas_ioc_enable_event_notification(mptsas_t
*mpt
)
528 ASSERT(mutex_owned(&mpt
->m_mutex
));
531 * Send enable event notification message
533 if (mptsas_do_dma(mpt
, sizeof (MPI2_EVENT_NOTIFICATION_REQUEST
), 0,
534 mptsas_ioc_do_enable_event_notification
)) {
535 return (DDI_FAILURE
);
539 * Get enable event reply message
541 if (mptsas_do_dma(mpt
, sizeof (MPI2_EVENT_NOTIFICATION_REPLY
), 0,
542 mptsas_ioc_do_enable_event_notification_reply
)) {
543 return (DDI_FAILURE
);
546 return (DDI_SUCCESS
);
550 mptsas_ioc_do_enable_event_notification(mptsas_t
*mpt
, caddr_t memp
, int var
,
551 ddi_acc_handle_t accessp
)
554 _NOTE(ARGUNUSED(var
))
557 pMpi2EventNotificationRequest_t event
;
560 bzero(memp
, sizeof (*event
));
561 event
= (void *)memp
;
562 ddi_put8(accessp
, &event
->Function
, MPI2_FUNCTION_EVENT_NOTIFICATION
);
563 numbytes
= sizeof (*event
);
566 * Send message via handshake
568 if (mptsas_send_handshake_msg(mpt
, memp
, numbytes
, accessp
)) {
569 return (DDI_FAILURE
);
572 return (DDI_SUCCESS
);
576 mptsas_ioc_do_enable_event_notification_reply(mptsas_t
*mpt
, caddr_t memp
,
577 int var
, ddi_acc_handle_t accessp
)
580 _NOTE(ARGUNUSED(var
))
584 pMpi2EventNotificationReply_t eventsreply
;
586 numbytes
= sizeof (MPI2_EVENT_NOTIFICATION_REPLY
);
587 bzero(memp
, numbytes
);
588 eventsreply
= (void *)memp
;
591 * Get message via handshake
593 if (mptsas_get_handshake_msg(mpt
, memp
, numbytes
, accessp
)) {
594 return (DDI_FAILURE
);
597 if (iocstatus
= ddi_get16(accessp
, &eventsreply
->IOCStatus
)) {
598 mptsas_log(mpt
, CE_WARN
,
599 "mptsas_ioc_do_enable_event_notification_reply: "
600 "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus
,
601 ddi_get32(accessp
, &eventsreply
->IOCLogInfo
));
602 return (DDI_FAILURE
);
605 return (DDI_SUCCESS
);
609 mptsas_ioc_init(mptsas_t
*mpt
)
612 * Send ioc init message
614 if (mptsas_do_dma(mpt
, sizeof (MPI2_IOC_INIT_REQUEST
), 0,
615 mptsas_do_ioc_init
)) {
616 return (DDI_FAILURE
);
620 * Get ioc init reply message
622 if (mptsas_do_dma(mpt
, sizeof (MPI2_IOC_INIT_REPLY
), 0,
623 mptsas_do_ioc_init_reply
)) {
624 return (DDI_FAILURE
);
627 return (DDI_SUCCESS
);
631 mptsas_do_ioc_init(mptsas_t
*mpt
, caddr_t memp
, int var
,
632 ddi_acc_handle_t accessp
)
635 _NOTE(ARGUNUSED(var
))
638 pMpi2IOCInitRequest_t init
;
643 bzero(memp
, sizeof (*init
));
645 ddi_put8(accessp
, &init
->Function
, MPI2_FUNCTION_IOC_INIT
);
646 ddi_put8(accessp
, &init
->WhoInit
, MPI2_WHOINIT_HOST_DRIVER
);
647 ddi_put16(accessp
, &init
->MsgVersion
, MPI2_VERSION
);
648 ddi_put16(accessp
, &init
->HeaderVersion
, MPI2_HEADER_VERSION
);
649 ddi_put16(accessp
, &init
->SystemRequestFrameSize
,
650 mpt
->m_req_frame_size
/ 4);
651 ddi_put16(accessp
, &init
->ReplyDescriptorPostQueueDepth
,
652 mpt
->m_post_queue_depth
);
653 ddi_put16(accessp
, &init
->ReplyFreeQueueDepth
,
654 mpt
->m_free_queue_depth
);
657 * These addresses are set using the DMA cookie addresses from when the
658 * memory was allocated. Sense buffer hi address should be 0.
660 ddi_put32(accessp
, &init
->SenseBufferAddressHigh
,
661 (uint32_t)(mpt
->m_req_sense_dma_addr
>> 32));
662 ddi_put32(accessp
, &init
->SystemReplyAddressHigh
,
663 (uint32_t)(mpt
->m_reply_frame_dma_addr
>> 32));
664 ddi_put32(accessp
, &init
->SystemRequestFrameBaseAddress
.High
,
665 (uint32_t)(mpt
->m_req_frame_dma_addr
>> 32));
666 ddi_put32(accessp
, &init
->SystemRequestFrameBaseAddress
.Low
,
667 (uint32_t)mpt
->m_req_frame_dma_addr
);
668 ddi_put32(accessp
, &init
->ReplyDescriptorPostQueueAddress
.High
,
669 (uint32_t)(mpt
->m_post_queue_dma_addr
>> 32));
670 ddi_put32(accessp
, &init
->ReplyDescriptorPostQueueAddress
.Low
,
671 (uint32_t)mpt
->m_post_queue_dma_addr
);
672 ddi_put32(accessp
, &init
->ReplyFreeQueueAddress
.High
,
673 (uint32_t)(mpt
->m_free_queue_dma_addr
>> 32));
674 ddi_put32(accessp
, &init
->ReplyFreeQueueAddress
.Low
,
675 (uint32_t)mpt
->m_free_queue_dma_addr
);
678 * Fill in the timestamp with the number of milliseconds since midnight
679 * of January 1, 1970 UT (Greenwich Mean Time). Time is returned in
680 * seconds and nanoseconds. Translate both to milliseconds and add
681 * them together to get total milliseconds.
684 mSec
= time
.tv_sec
* MILLISEC
;
685 mSec
+= (time
.tv_nsec
/ MICROSEC
);
686 ddi_put32(accessp
, &init
->TimeStamp
.High
, (uint32_t)(mSec
>> 32));
687 ddi_put32(accessp
, &init
->TimeStamp
.Low
, (uint32_t)mSec
);
689 numbytes
= sizeof (*init
);
692 * Post message via handshake
694 if (mptsas_send_handshake_msg(mpt
, memp
, numbytes
, accessp
)) {
695 return (DDI_FAILURE
);
698 return (DDI_SUCCESS
);
702 mptsas_do_ioc_init_reply(mptsas_t
*mpt
, caddr_t memp
, int var
,
703 ddi_acc_handle_t accessp
)
706 _NOTE(ARGUNUSED(var
))
709 pMpi2IOCInitReply_t initreply
;
713 numbytes
= sizeof (MPI2_IOC_INIT_REPLY
);
714 bzero(memp
, numbytes
);
715 initreply
= (void *)memp
;
718 * Get reply message via handshake
720 if (mptsas_get_handshake_msg(mpt
, memp
, numbytes
, accessp
)) {
721 return (DDI_FAILURE
);
724 if (iocstatus
= ddi_get16(accessp
, &initreply
->IOCStatus
)) {
725 mptsas_log(mpt
, CE_WARN
, "mptsas_do_ioc_init_reply: "
726 "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus
,
727 ddi_get32(accessp
, &initreply
->IOCLogInfo
));
728 return (DDI_FAILURE
);
731 if ((ddi_get32(mpt
->m_datap
, &mpt
->m_reg
->Doorbell
)) &
732 MPI2_IOC_STATE_OPERATIONAL
) {
733 mptsas_log(mpt
, CE_NOTE
,
734 "?mpt%d: IOC Operational.\n", mpt
->m_instance
);
736 return (DDI_FAILURE
);
739 return (DDI_SUCCESS
);