Merge commit '9276b3991ba20d5a5660887ba81b0bc7bed25a0c'
[unleashed.git] / usr / src / uts / common / io / scsi / adapters / mpt_sas / mptsas_init.c
blobe9c76a9b18799aa2ea27a5244f37a076ea3baaf8
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
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
53 * DAMAGE.
57 * mptsas_init - This file contains all the functions used to initialize
58 * MPT2.0 based hardware.
61 #if defined(DEBUG)
62 #define MPTSAS_DEBUG
63 #endif
66 * standard header files
68 #include <sys/note.h>
69 #include <sys/scsi/scsi.h>
71 #pragma pack(1)
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>
78 #pragma pack()
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);
105 static const char *
106 mptsas_devid_type_string(mptsas_t *mpt)
108 switch (mpt->m_devid) {
109 case MPI2_MFGPAGE_DEVID_SAS2008:
110 return ("SAS2008");
111 case MPI2_MFGPAGE_DEVID_SAS2004:
112 return ("SAS2004");
113 case MPI2_MFGPAGE_DEVID_SAS2108_1:
114 case MPI2_MFGPAGE_DEVID_SAS2108_2:
115 case MPI2_MFGPAGE_DEVID_SAS2108_3:
116 return ("SAS2108");
117 case MPI2_MFGPAGE_DEVID_SAS2116_1:
118 case MPI2_MFGPAGE_DEVID_SAS2116_2:
119 return ("SAS2116");
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:
126 return ("SAS2208");
127 case MPI2_MFGPAGE_DEVID_SAS2308_1:
128 case MPI2_MFGPAGE_DEVID_SAS2308_2:
129 case MPI2_MFGPAGE_DEVID_SAS2308_3:
130 return ("SAS2308");
131 case MPI25_MFGPAGE_DEVID_SAS3004:
132 return ("SAS3004");
133 case MPI25_MFGPAGE_DEVID_SAS3008:
134 return ("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:
139 return ("SAS3108");
140 default:
141 return ("?");
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);
167 static int
168 mptsas_ioc_do_get_facts(mptsas_t *mpt, caddr_t memp, int var,
169 ddi_acc_handle_t accessp)
171 #ifndef __lock_lint
172 _NOTE(ARGUNUSED(var))
173 #endif
174 pMpi2IOCFactsRequest_t facts;
175 int numbytes;
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);
192 static int
193 mptsas_ioc_do_get_facts_reply(mptsas_t *mpt, caddr_t memp, int var,
194 ddi_acc_handle_t accessp)
196 #ifndef __lock_lint
197 _NOTE(ARGUNUSED(var))
198 #endif
200 pMpi2IOCFactsReply_t factsreply;
201 int numbytes;
202 uint_t iocstatus;
203 char buf[32];
204 uint16_t numReplyFrames;
205 uint16_t queueSize, queueDiff;
206 int simple_sge_main;
207 int simple_sge_next;
208 uint32_t capabilities;
209 uint16_t msgversion;
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)) {
264 numReplyFrames--;
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",
312 mpt->m_instance);
313 mpt->m_MPI25 = TRUE;
314 } else {
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
334 * each type.
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 =
339 TRUE;
341 if (capabilities & MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER) {
342 mpt->m_fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_SNAPSHOT].
343 enabled = TRUE;
345 if (capabilities & MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER) {
346 mpt->m_fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_EXTENDED].
347 enabled = TRUE;
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);
390 static int
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;
395 int numbytes;
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);
413 static int
414 mptsas_ioc_do_get_port_facts_reply(mptsas_t *mpt, caddr_t memp, int var,
415 ddi_acc_handle_t accessp)
417 #ifndef __lock_lint
418 _NOTE(ARGUNUSED(var))
419 #endif
420 pMpi2PortFactsReply_t factsreply;
421 int numbytes;
422 uint_t iocstatus;
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);
467 static int
468 mptsas_ioc_do_enable_port(mptsas_t *mpt, caddr_t memp, int var,
469 ddi_acc_handle_t accessp)
471 #ifndef __lock_lint
472 _NOTE(ARGUNUSED(var))
473 #endif
474 pMpi2PortEnableRequest_t enable;
475 int numbytes;
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);
492 static int
493 mptsas_ioc_do_enable_port_reply(mptsas_t *mpt, caddr_t memp, int var,
494 ddi_acc_handle_t accessp)
496 #ifndef __lock_lint
497 _NOTE(ARGUNUSED(var))
498 #endif
500 int numbytes;
501 uint_t iocstatus;
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);
549 static int
550 mptsas_ioc_do_enable_event_notification(mptsas_t *mpt, caddr_t memp, int var,
551 ddi_acc_handle_t accessp)
553 #ifndef __lock_lint
554 _NOTE(ARGUNUSED(var))
555 #endif
557 pMpi2EventNotificationRequest_t event;
558 int numbytes;
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);
575 static int
576 mptsas_ioc_do_enable_event_notification_reply(mptsas_t *mpt, caddr_t memp,
577 int var, ddi_acc_handle_t accessp)
579 #ifndef __lock_lint
580 _NOTE(ARGUNUSED(var))
581 #endif
582 int numbytes;
583 uint_t iocstatus;
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);
630 static int
631 mptsas_do_ioc_init(mptsas_t *mpt, caddr_t memp, int var,
632 ddi_acc_handle_t accessp)
634 #ifndef __lock_lint
635 _NOTE(ARGUNUSED(var))
636 #endif
638 pMpi2IOCInitRequest_t init;
639 int numbytes;
640 timespec_t time;
641 uint64_t mSec;
643 bzero(memp, sizeof (*init));
644 init = (void *)memp;
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.
683 gethrestime(&time);
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);
701 static int
702 mptsas_do_ioc_init_reply(mptsas_t *mpt, caddr_t memp, int var,
703 ddi_acc_handle_t accessp)
705 #ifndef __lock_lint
706 _NOTE(ARGUNUSED(var))
707 #endif
709 pMpi2IOCInitReply_t initreply;
710 int numbytes;
711 uint_t iocstatus;
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);
735 } else {
736 return (DDI_FAILURE);
739 return (DDI_SUCCESS);