15b504601Sjiang wu - Sun Microsystems - Beijing China /*
25b504601Sjiang wu - Sun Microsystems - Beijing China  * CDDL HEADER START
35b504601Sjiang wu - Sun Microsystems - Beijing China  *
45b504601Sjiang wu - Sun Microsystems - Beijing China  * The contents of this file are subject to the terms of the
55b504601Sjiang wu - Sun Microsystems - Beijing China  * Common Development and Distribution License (the "License").
65b504601Sjiang wu - Sun Microsystems - Beijing China  * You may not use this file except in compliance with the License.
75b504601Sjiang wu - Sun Microsystems - Beijing China  *
85b504601Sjiang wu - Sun Microsystems - Beijing China  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95b504601Sjiang wu - Sun Microsystems - Beijing China  * or http://www.opensolaris.org/os/licensing.
105b504601Sjiang wu - Sun Microsystems - Beijing China  * See the License for the specific language governing permissions
115b504601Sjiang wu - Sun Microsystems - Beijing China  * and limitations under the License.
125b504601Sjiang wu - Sun Microsystems - Beijing China  *
135b504601Sjiang wu - Sun Microsystems - Beijing China  * When distributing Covered Code, include this CDDL HEADER in each
145b504601Sjiang wu - Sun Microsystems - Beijing China  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155b504601Sjiang wu - Sun Microsystems - Beijing China  * If applicable, add the following below this CDDL HEADER, with the
165b504601Sjiang wu - Sun Microsystems - Beijing China  * fields enclosed by brackets "[]" replaced with your own identifying
175b504601Sjiang wu - Sun Microsystems - Beijing China  * information: Portions Copyright [yyyy] [name of copyright owner]
185b504601Sjiang wu - Sun Microsystems - Beijing China  *
195b504601Sjiang wu - Sun Microsystems - Beijing China  * CDDL HEADER END
205b504601Sjiang wu - Sun Microsystems - Beijing China  */
215b504601Sjiang wu - Sun Microsystems - Beijing China 
225b504601Sjiang wu - Sun Microsystems - Beijing China /*
23*c8f74a56SAda  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
245b504601Sjiang wu - Sun Microsystems - Beijing China  * Use is subject to license terms.
255b504601Sjiang wu - Sun Microsystems - Beijing China  */
265b504601Sjiang wu - Sun Microsystems - Beijing China 
275b504601Sjiang wu - Sun Microsystems - Beijing China /*
28*c8f74a56SAda  * Copyright (c) 2000 to 2010, LSI Corporation.
295b504601Sjiang wu - Sun Microsystems - Beijing China  * All rights reserved.
305b504601Sjiang wu - Sun Microsystems - Beijing China  *
315b504601Sjiang wu - Sun Microsystems - Beijing China  * Redistribution and use in source and binary forms of all code within
325b504601Sjiang wu - Sun Microsystems - Beijing China  * this file that is exclusively owned by LSI, with or without
335b504601Sjiang wu - Sun Microsystems - Beijing China  * modification, is permitted provided that, in addition to the CDDL 1.0
345b504601Sjiang wu - Sun Microsystems - Beijing China  * License requirements, the following conditions are met:
355b504601Sjiang wu - Sun Microsystems - Beijing China  *
365b504601Sjiang wu - Sun Microsystems - Beijing China  *    Neither the name of the author nor the names of its contributors may be
375b504601Sjiang wu - Sun Microsystems - Beijing China  *    used to endorse or promote products derived from this software without
385b504601Sjiang wu - Sun Microsystems - Beijing China  *    specific prior written permission.
395b504601Sjiang wu - Sun Microsystems - Beijing China  *
405b504601Sjiang wu - Sun Microsystems - Beijing China  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
415b504601Sjiang wu - Sun Microsystems - Beijing China  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
425b504601Sjiang wu - Sun Microsystems - Beijing China  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
435b504601Sjiang wu - Sun Microsystems - Beijing China  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
445b504601Sjiang wu - Sun Microsystems - Beijing China  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
455b504601Sjiang wu - Sun Microsystems - Beijing China  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
465b504601Sjiang wu - Sun Microsystems - Beijing China  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
475b504601Sjiang wu - Sun Microsystems - Beijing China  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
485b504601Sjiang wu - Sun Microsystems - Beijing China  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
495b504601Sjiang wu - Sun Microsystems - Beijing China  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
505b504601Sjiang wu - Sun Microsystems - Beijing China  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
515b504601Sjiang wu - Sun Microsystems - Beijing China  * DAMAGE.
525b504601Sjiang wu - Sun Microsystems - Beijing China  */
535b504601Sjiang wu - Sun Microsystems - Beijing China 
545b504601Sjiang wu - Sun Microsystems - Beijing China /*
555b504601Sjiang wu - Sun Microsystems - Beijing China  * mptsas_impl - This file contains all the basic functions for communicating
565b504601Sjiang wu - Sun Microsystems - Beijing China  * to MPT based hardware.
575b504601Sjiang wu - Sun Microsystems - Beijing China  */
585b504601Sjiang wu - Sun Microsystems - Beijing China 
595b504601Sjiang wu - Sun Microsystems - Beijing China #if defined(lint) || defined(DEBUG)
605b504601Sjiang wu - Sun Microsystems - Beijing China #define	MPTSAS_DEBUG
615b504601Sjiang wu - Sun Microsystems - Beijing China #endif
625b504601Sjiang wu - Sun Microsystems - Beijing China 
635b504601Sjiang wu - Sun Microsystems - Beijing China /*
645b504601Sjiang wu - Sun Microsystems - Beijing China  * standard header files
655b504601Sjiang wu - Sun Microsystems - Beijing China  */
665b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/note.h>
675b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/scsi.h>
685b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/pci.h>
695b504601Sjiang wu - Sun Microsystems - Beijing China 
705b504601Sjiang wu - Sun Microsystems - Beijing China #pragma pack(1)
715b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
725b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
735b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
745b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
755b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
765b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
7776a4caf6SAda #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
785b504601Sjiang wu - Sun Microsystems - Beijing China #pragma pack()
795b504601Sjiang wu - Sun Microsystems - Beijing China 
805b504601Sjiang wu - Sun Microsystems - Beijing China /*
815b504601Sjiang wu - Sun Microsystems - Beijing China  * private header files.
825b504601Sjiang wu - Sun Microsystems - Beijing China  */
835b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
845b504601Sjiang wu - Sun Microsystems - Beijing China 
855b504601Sjiang wu - Sun Microsystems - Beijing China /*
865b504601Sjiang wu - Sun Microsystems - Beijing China  * FMA header files.
875b504601Sjiang wu - Sun Microsystems - Beijing China  */
885b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/fm/io/ddi.h>
895b504601Sjiang wu - Sun Microsystems - Beijing China 
905b504601Sjiang wu - Sun Microsystems - Beijing China #if defined(MPTSAS_DEBUG)
915b504601Sjiang wu - Sun Microsystems - Beijing China extern uint32_t mptsas_debug_flags;
925b504601Sjiang wu - Sun Microsystems - Beijing China #endif
935b504601Sjiang wu - Sun Microsystems - Beijing China 
945b504601Sjiang wu - Sun Microsystems - Beijing China /*
955b504601Sjiang wu - Sun Microsystems - Beijing China  *  prototypes
965b504601Sjiang wu - Sun Microsystems - Beijing China  */
975b504601Sjiang wu - Sun Microsystems - Beijing China static void mptsas_ioc_event_cmdq_add(mptsas_t *mpt, m_event_struct_t *cmd);
985b504601Sjiang wu - Sun Microsystems - Beijing China static void mptsas_ioc_event_cmdq_delete(mptsas_t *mpt, m_event_struct_t *cmd);
995b504601Sjiang wu - Sun Microsystems - Beijing China static m_event_struct_t *mptsas_ioc_event_find_by_cmd(mptsas_t *mpt,
1005b504601Sjiang wu - Sun Microsystems - Beijing China     struct mptsas_cmd *cmd);
1015b504601Sjiang wu - Sun Microsystems - Beijing China 
1025b504601Sjiang wu - Sun Microsystems - Beijing China /*
1035b504601Sjiang wu - Sun Microsystems - Beijing China  * add ioc evnet cmd into the queue
1045b504601Sjiang wu - Sun Microsystems - Beijing China  */
1055b504601Sjiang wu - Sun Microsystems - Beijing China static void
1065b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_event_cmdq_add(mptsas_t *mpt, m_event_struct_t *cmd)
1075b504601Sjiang wu - Sun Microsystems - Beijing China {
1085b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((cmd->m_event_linkp = mpt->m_ioc_event_cmdq) == NULL) {
1095b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_ioc_event_cmdtail = &cmd->m_event_linkp;
1105b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_ioc_event_cmdq = cmd;
1115b504601Sjiang wu - Sun Microsystems - Beijing China 	} else {
1125b504601Sjiang wu - Sun Microsystems - Beijing China 		cmd->m_event_linkp = NULL;
1135b504601Sjiang wu - Sun Microsystems - Beijing China 		*(mpt->m_ioc_event_cmdtail) = cmd;
1145b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_ioc_event_cmdtail = &cmd->m_event_linkp;
1155b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1165b504601Sjiang wu - Sun Microsystems - Beijing China }
1175b504601Sjiang wu - Sun Microsystems - Beijing China 
1185b504601Sjiang wu - Sun Microsystems - Beijing China /*
1195b504601Sjiang wu - Sun Microsystems - Beijing China  * remove specified cmd from the ioc event queue
1205b504601Sjiang wu - Sun Microsystems - Beijing China  */
1215b504601Sjiang wu - Sun Microsystems - Beijing China static void
1225b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_event_cmdq_delete(mptsas_t *mpt, m_event_struct_t *cmd)
1235b504601Sjiang wu - Sun Microsystems - Beijing China {
1245b504601Sjiang wu - Sun Microsystems - Beijing China 	m_event_struct_t	*prev = mpt->m_ioc_event_cmdq;
1255b504601Sjiang wu - Sun Microsystems - Beijing China 	if (prev == cmd) {
1265b504601Sjiang wu - Sun Microsystems - Beijing China 		if ((mpt->m_ioc_event_cmdq = cmd->m_event_linkp) == NULL) {
1275b504601Sjiang wu - Sun Microsystems - Beijing China 			mpt->m_ioc_event_cmdtail = &mpt->m_ioc_event_cmdq;
1285b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1295b504601Sjiang wu - Sun Microsystems - Beijing China 		cmd->m_event_linkp = NULL;
1305b504601Sjiang wu - Sun Microsystems - Beijing China 		return;
1315b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1325b504601Sjiang wu - Sun Microsystems - Beijing China 	while (prev != NULL) {
1335b504601Sjiang wu - Sun Microsystems - Beijing China 		if (prev->m_event_linkp == cmd) {
1345b504601Sjiang wu - Sun Microsystems - Beijing China 			prev->m_event_linkp = cmd->m_event_linkp;
1355b504601Sjiang wu - Sun Microsystems - Beijing China 			if (cmd->m_event_linkp == NULL) {
1365b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_ioc_event_cmdtail = &prev->m_event_linkp;
1375b504601Sjiang wu - Sun Microsystems - Beijing China 			}
1385b504601Sjiang wu - Sun Microsystems - Beijing China 
1395b504601Sjiang wu - Sun Microsystems - Beijing China 			cmd->m_event_linkp = NULL;
1405b504601Sjiang wu - Sun Microsystems - Beijing China 			return;
1415b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1425b504601Sjiang wu - Sun Microsystems - Beijing China 		prev = prev->m_event_linkp;
1435b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1445b504601Sjiang wu - Sun Microsystems - Beijing China }
1455b504601Sjiang wu - Sun Microsystems - Beijing China 
1465b504601Sjiang wu - Sun Microsystems - Beijing China static m_event_struct_t *
1475b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_event_find_by_cmd(mptsas_t *mpt, struct mptsas_cmd *cmd)
1485b504601Sjiang wu - Sun Microsystems - Beijing China {
1495b504601Sjiang wu - Sun Microsystems - Beijing China 	m_event_struct_t	*ioc_cmd = NULL;
1505b504601Sjiang wu - Sun Microsystems - Beijing China 
1515b504601Sjiang wu - Sun Microsystems - Beijing China 	ioc_cmd = mpt->m_ioc_event_cmdq;
1525b504601Sjiang wu - Sun Microsystems - Beijing China 	while (ioc_cmd != NULL) {
1535b504601Sjiang wu - Sun Microsystems - Beijing China 		if (&(ioc_cmd->m_event_cmd) == cmd) {
1545b504601Sjiang wu - Sun Microsystems - Beijing China 			return (ioc_cmd);
1555b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1565b504601Sjiang wu - Sun Microsystems - Beijing China 		ioc_cmd = ioc_cmd->m_event_linkp;
1575b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1585b504601Sjiang wu - Sun Microsystems - Beijing China 	ioc_cmd = NULL;
1595b504601Sjiang wu - Sun Microsystems - Beijing China 	return (ioc_cmd);
1605b504601Sjiang wu - Sun Microsystems - Beijing China }
1615b504601Sjiang wu - Sun Microsystems - Beijing China 
1625b504601Sjiang wu - Sun Microsystems - Beijing China void
1635b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_destroy_ioc_event_cmd(mptsas_t *mpt)
1645b504601Sjiang wu - Sun Microsystems - Beijing China {
1655b504601Sjiang wu - Sun Microsystems - Beijing China 	m_event_struct_t	*ioc_cmd = NULL;
1665b504601Sjiang wu - Sun Microsystems - Beijing China 	m_event_struct_t	*ioc_cmd_tmp = NULL;
1675b504601Sjiang wu - Sun Microsystems - Beijing China 	ioc_cmd = mpt->m_ioc_event_cmdq;
1685b504601Sjiang wu - Sun Microsystems - Beijing China 
1695b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1705b504601Sjiang wu - Sun Microsystems - Beijing China 	 * because the IOC event queue is resource of per instance for driver,
1715b504601Sjiang wu - Sun Microsystems - Beijing China 	 * it's not only ACK event commands used it, but also some others used
1725b504601Sjiang wu - Sun Microsystems - Beijing China 	 * it. We need destroy all ACK event commands when IOC reset, but can't
1735b504601Sjiang wu - Sun Microsystems - Beijing China 	 * disturb others.So we use filter to clear the ACK event cmd in ioc
1745b504601Sjiang wu - Sun Microsystems - Beijing China 	 * event queue, and other requests should be reserved, and they would
1755b504601Sjiang wu - Sun Microsystems - Beijing China 	 * be free by its owner.
1765b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1775b504601Sjiang wu - Sun Microsystems - Beijing China 	while (ioc_cmd != NULL) {
1785b504601Sjiang wu - Sun Microsystems - Beijing China 		if (ioc_cmd->m_event_cmd.cmd_flags & CFLAG_CMDACK) {
1795b504601Sjiang wu - Sun Microsystems - Beijing China 			NDBG20(("destroy!! remove Ack Flag ioc_cmd\n"));
1805b504601Sjiang wu - Sun Microsystems - Beijing China 			if ((mpt->m_ioc_event_cmdq =
1815b504601Sjiang wu - Sun Microsystems - Beijing China 			    ioc_cmd->m_event_linkp) == NULL)
1825b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_ioc_event_cmdtail =
1835b504601Sjiang wu - Sun Microsystems - Beijing China 				    &mpt->m_ioc_event_cmdq;
1845b504601Sjiang wu - Sun Microsystems - Beijing China 			ioc_cmd_tmp = ioc_cmd;
1855b504601Sjiang wu - Sun Microsystems - Beijing China 			ioc_cmd = ioc_cmd->m_event_linkp;
1865b504601Sjiang wu - Sun Microsystems - Beijing China 			kmem_free(ioc_cmd_tmp, M_EVENT_STRUCT_SIZE);
1875b504601Sjiang wu - Sun Microsystems - Beijing China 		} else {
1885b504601Sjiang wu - Sun Microsystems - Beijing China 			/*
1895b504601Sjiang wu - Sun Microsystems - Beijing China 			 * it's not ack cmd, so continue to check next one
1905b504601Sjiang wu - Sun Microsystems - Beijing China 			 */
1915b504601Sjiang wu - Sun Microsystems - Beijing China 
1925b504601Sjiang wu - Sun Microsystems - Beijing China 			NDBG20(("destroy!! it's not Ack Flag, continue\n"));
1935b504601Sjiang wu - Sun Microsystems - Beijing China 			ioc_cmd = ioc_cmd->m_event_linkp;
1945b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1955b504601Sjiang wu - Sun Microsystems - Beijing China 
1965b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1975b504601Sjiang wu - Sun Microsystems - Beijing China }
1985b504601Sjiang wu - Sun Microsystems - Beijing China 
1995b504601Sjiang wu - Sun Microsystems - Beijing China void
2005b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_start_config_page_access(mptsas_t *mpt, mptsas_cmd_t *cmd)
2015b504601Sjiang wu - Sun Microsystems - Beijing China {
2025b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2ConfigRequest_t	request;
2035b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2SGESimple64_t	sge;
2045b504601Sjiang wu - Sun Microsystems - Beijing China 	struct scsi_pkt		*pkt = cmd->cmd_pkt;
2055b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_config_request_t	*config = pkt->pkt_ha_private;
2065b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t			direction;
2075b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		length, flagslength, request_desc_low;
2085b504601Sjiang wu - Sun Microsystems - Beijing China 
2095b504601Sjiang wu - Sun Microsystems - Beijing China 	ASSERT(mutex_owned(&mpt->m_mutex));
2105b504601Sjiang wu - Sun Microsystems - Beijing China 
2115b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
2125b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Point to the correct message and clear it as well as the global
2135b504601Sjiang wu - Sun Microsystems - Beijing China 	 * config page memory.
2145b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
2155b504601Sjiang wu - Sun Microsystems - Beijing China 	request = (pMpi2ConfigRequest_t)(mpt->m_req_frame +
2165b504601Sjiang wu - Sun Microsystems - Beijing China 	    (mpt->m_req_frame_size * cmd->cmd_slot));
2175b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(request, mpt->m_req_frame_size);
2185b504601Sjiang wu - Sun Microsystems - Beijing China 
2195b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
2205b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Form the request message.
2215b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
2225b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &request->Function,
2235b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_FUNCTION_CONFIG);
2245b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &request->Action, config->action);
2255b504601Sjiang wu - Sun Microsystems - Beijing China 	direction = MPI2_SGE_FLAGS_IOC_TO_HOST;
2265b504601Sjiang wu - Sun Microsystems - Beijing China 	length = 0;
2275b504601Sjiang wu - Sun Microsystems - Beijing China 	sge = (pMpi2SGESimple64_t)&request->PageBufferSGE;
2285b504601Sjiang wu - Sun Microsystems - Beijing China 	if (config->action == MPI2_CONFIG_ACTION_PAGE_HEADER) {
2295b504601Sjiang wu - Sun Microsystems - Beijing China 		if (config->page_type > MPI2_CONFIG_PAGETYPE_MASK) {
2305b504601Sjiang wu - Sun Microsystems - Beijing China 			ddi_put8(mpt->m_acc_req_frame_hdl,
2315b504601Sjiang wu - Sun Microsystems - Beijing China 			    &request->Header.PageType,
2325b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_CONFIG_PAGETYPE_EXTENDED);
2335b504601Sjiang wu - Sun Microsystems - Beijing China 			ddi_put8(mpt->m_acc_req_frame_hdl,
2345b504601Sjiang wu - Sun Microsystems - Beijing China 			    &request->ExtPageType, config->page_type);
2355b504601Sjiang wu - Sun Microsystems - Beijing China 		} else {
2365b504601Sjiang wu - Sun Microsystems - Beijing China 			ddi_put8(mpt->m_acc_req_frame_hdl,
2375b504601Sjiang wu - Sun Microsystems - Beijing China 			    &request->Header.PageType, config->page_type);
2385b504601Sjiang wu - Sun Microsystems - Beijing China 		}
2395b504601Sjiang wu - Sun Microsystems - Beijing China 	} else {
2405b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put8(mpt->m_acc_req_frame_hdl, &request->ExtPageType,
2415b504601Sjiang wu - Sun Microsystems - Beijing China 		    config->ext_page_type);
2425b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put16(mpt->m_acc_req_frame_hdl, &request->ExtPageLength,
2435b504601Sjiang wu - Sun Microsystems - Beijing China 		    config->ext_page_length);
2445b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put8(mpt->m_acc_req_frame_hdl, &request->Header.PageType,
2455b504601Sjiang wu - Sun Microsystems - Beijing China 		    config->page_type);
2465b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put8(mpt->m_acc_req_frame_hdl, &request->Header.PageLength,
2475b504601Sjiang wu - Sun Microsystems - Beijing China 		    config->page_length);
2485b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put8(mpt->m_acc_req_frame_hdl,
2495b504601Sjiang wu - Sun Microsystems - Beijing China 		    &request->Header.PageVersion, config->page_version);
2505b504601Sjiang wu - Sun Microsystems - Beijing China 		if ((config->page_type & MPI2_CONFIG_PAGETYPE_MASK) ==
2515b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_CONFIG_PAGETYPE_EXTENDED) {
2525b504601Sjiang wu - Sun Microsystems - Beijing China 			length = config->ext_page_length * 4;
2535b504601Sjiang wu - Sun Microsystems - Beijing China 		} else {
2545b504601Sjiang wu - Sun Microsystems - Beijing China 			length = config->page_length * 4;
2555b504601Sjiang wu - Sun Microsystems - Beijing China 		}
2565b504601Sjiang wu - Sun Microsystems - Beijing China 
2575b504601Sjiang wu - Sun Microsystems - Beijing China 		if (config->action == MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {
2585b504601Sjiang wu - Sun Microsystems - Beijing China 			direction = MPI2_SGE_FLAGS_HOST_TO_IOC;
2595b504601Sjiang wu - Sun Microsystems - Beijing China 		}
2605b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.Low,
2615b504601Sjiang wu - Sun Microsystems - Beijing China 		    (uint32_t)cmd->cmd_dma_addr);
2625b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.High,
2635b504601Sjiang wu - Sun Microsystems - Beijing China 		    (uint32_t)(cmd->cmd_dma_addr >> 32));
2645b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2655b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &request->Header.PageNumber,
2665b504601Sjiang wu - Sun Microsystems - Beijing China 	    config->page_number);
2675b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_acc_req_frame_hdl, &request->PageAddress,
2685b504601Sjiang wu - Sun Microsystems - Beijing China 	    config->page_address);
2695b504601Sjiang wu - Sun Microsystems - Beijing China 	flagslength = ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT |
2705b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_END_OF_BUFFER |
2715b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
2725b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
2735b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_64_BIT_ADDRESSING |
2745b504601Sjiang wu - Sun Microsystems - Beijing China 	    direction |
2755b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
2765b504601Sjiang wu - Sun Microsystems - Beijing China 	flagslength |= length;
2775b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_acc_req_frame_hdl, &sge->FlagsLength, flagslength);
2785b504601Sjiang wu - Sun Microsystems - Beijing China 
2795b504601Sjiang wu - Sun Microsystems - Beijing China 	(void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0,
2805b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SYNC_FORDEV);
2815b504601Sjiang wu - Sun Microsystems - Beijing China 	request_desc_low = (cmd->cmd_slot << 16) +
2825b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
2835b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_rfm = NULL;
2845b504601Sjiang wu - Sun Microsystems - Beijing China 	MPTSAS_START_CMD(mpt, request_desc_low, 0);
2855b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
2865b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_SUCCESS) ||
2875b504601Sjiang wu - Sun Microsystems - Beijing China 	    (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
2885b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_SUCCESS)) {
2895b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
2905b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2915b504601Sjiang wu - Sun Microsystems - Beijing China }
2925b504601Sjiang wu - Sun Microsystems - Beijing China 
2935b504601Sjiang wu - Sun Microsystems - Beijing China int
2945b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_access_config_page(mptsas_t *mpt, uint8_t action, uint8_t page_type,
2955b504601Sjiang wu - Sun Microsystems - Beijing China     uint8_t page_number, uint32_t page_address, int (*callback) (mptsas_t *,
2965b504601Sjiang wu - Sun Microsystems - Beijing China     caddr_t, ddi_acc_handle_t, uint16_t, uint32_t, va_list), ...)
2975b504601Sjiang wu - Sun Microsystems - Beijing China {
2985b504601Sjiang wu - Sun Microsystems - Beijing China 	va_list			ap;
2995b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_attr_t		attrs;
3005b504601Sjiang wu - Sun Microsystems - Beijing China 	uint_t			ncookie;
3015b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_cookie_t	cookie;
3025b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_acc_handle_t	accessp;
3035b504601Sjiang wu - Sun Microsystems - Beijing China 	size_t			len = 0, alloc_len;
3045b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_config_request_t	config;
3055b504601Sjiang wu - Sun Microsystems - Beijing China 	int			rval = DDI_SUCCESS, config_flags = 0;
3065b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_cmd_t		*cmd;
3075b504601Sjiang wu - Sun Microsystems - Beijing China 	struct scsi_pkt		*pkt;
3085b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2ConfigReply_t	reply;
3095b504601Sjiang wu - Sun Microsystems - Beijing China 	uint16_t		iocstatus = 0;
3105b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		iocloginfo;
3115b504601Sjiang wu - Sun Microsystems - Beijing China 	caddr_t			page_memp;
3125b504601Sjiang wu - Sun Microsystems - Beijing China 
3135b504601Sjiang wu - Sun Microsystems - Beijing China 	va_start(ap, callback);
3145b504601Sjiang wu - Sun Microsystems - Beijing China 	ASSERT(mutex_owned(&mpt->m_mutex));
3155b504601Sjiang wu - Sun Microsystems - Beijing China 
3165b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
3175b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Get a command from the pool.
3185b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
3195b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((rval = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
3205b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_NOTE, "command pool is full for config "
3215b504601Sjiang wu - Sun Microsystems - Beijing China 		    "page request");
3225b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
3235b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
3245b504601Sjiang wu - Sun Microsystems - Beijing China 	}
3255b504601Sjiang wu - Sun Microsystems - Beijing China 	config_flags |= MPTSAS_REQUEST_POOL_CMD;
3265b504601Sjiang wu - Sun Microsystems - Beijing China 
3275b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero((caddr_t)cmd, sizeof (*cmd));
3285b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero((caddr_t)pkt, scsi_pkt_size());
3295b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero((caddr_t)&config, sizeof (config));
3305b504601Sjiang wu - Sun Microsystems - Beijing China 
3315b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
3325b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Save the data for this request to be used in the call to start the
3335b504601Sjiang wu - Sun Microsystems - Beijing China 	 * config header request.
3345b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
3355b504601Sjiang wu - Sun Microsystems - Beijing China 	config.action = MPI2_CONFIG_ACTION_PAGE_HEADER;
3365b504601Sjiang wu - Sun Microsystems - Beijing China 	config.page_type = page_type;
3375b504601Sjiang wu - Sun Microsystems - Beijing China 	config.page_number = page_number;
3385b504601Sjiang wu - Sun Microsystems - Beijing China 	config.page_address = page_address;
3395b504601Sjiang wu - Sun Microsystems - Beijing China 
3405b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
3415b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Form a blank cmd/pkt to store the acknowledgement message
3425b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
3435b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_ha_private	= (opaque_t)&config;
3445b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_flags		= FLAG_HEAD;
3455b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_time		= 60;
3465b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_pkt		= pkt;
3475b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_flags		= CFLAG_CMDIOC | CFLAG_CONFIG;
3485b504601Sjiang wu - Sun Microsystems - Beijing China 
3495b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
3505b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Save the config header request message in a slot.
3515b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
3525b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_save_cmd(mpt, cmd) == TRUE) {
3535b504601Sjiang wu - Sun Microsystems - Beijing China 		cmd->cmd_flags |= CFLAG_PREPARED;
3545b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_start_config_page_access(mpt, cmd);
3555b504601Sjiang wu - Sun Microsystems - Beijing China 	} else {
3565b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_waitq_add(mpt, cmd);
3575b504601Sjiang wu - Sun Microsystems - Beijing China 	}
3585b504601Sjiang wu - Sun Microsystems - Beijing China 
3595b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
360*c8f74a56SAda 	 * If this is a request for a RAID info page, or any page called during
361*c8f74a56SAda 	 * the RAID info page request, poll because these config page requests
362*c8f74a56SAda 	 * are nested.  Poll to avoid data corruption due to one page's data
363*c8f74a56SAda 	 * overwriting the outer page request's data.  This can happen when
364*c8f74a56SAda 	 * the mutex is released in cv_wait.
3655b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
366*c8f74a56SAda 	if ((page_type == MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG) ||
367*c8f74a56SAda 	    (page_type == MPI2_CONFIG_PAGETYPE_RAID_VOLUME) ||
368*c8f74a56SAda 	    (page_type == MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK)) {
369*c8f74a56SAda 		(void) mptsas_poll(mpt, cmd, pkt->pkt_time * 1000);
370*c8f74a56SAda 	} else {
371*c8f74a56SAda 		while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
372*c8f74a56SAda 			cv_wait(&mpt->m_config_cv, &mpt->m_mutex);
373*c8f74a56SAda 		}
3745b504601Sjiang wu - Sun Microsystems - Beijing China 	}
3755b504601Sjiang wu - Sun Microsystems - Beijing China 
3765b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
3775b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Check if the header request completed without timing out
3785b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
3795b504601Sjiang wu - Sun Microsystems - Beijing China 	if (cmd->cmd_flags & CFLAG_TIMEOUT) {
3805b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "config header request timeout");
3815b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
3825b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
3835b504601Sjiang wu - Sun Microsystems - Beijing China 	}
3845b504601Sjiang wu - Sun Microsystems - Beijing China 
3855b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
3865b504601Sjiang wu - Sun Microsystems - Beijing China 	 * cmd_rfm points to the reply message if a reply was given.  Check the
3875b504601Sjiang wu - Sun Microsystems - Beijing China 	 * IOCStatus to make sure everything went OK with the header request.
3885b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
3895b504601Sjiang wu - Sun Microsystems - Beijing China 	if (cmd->cmd_rfm) {
3905b504601Sjiang wu - Sun Microsystems - Beijing China 		config_flags |= MPTSAS_ADDRESS_REPLY;
3915b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
3925b504601Sjiang wu - Sun Microsystems - Beijing China 		    DDI_DMA_SYNC_FORCPU);
3935b504601Sjiang wu - Sun Microsystems - Beijing China 		reply = (pMpi2ConfigReply_t)(mpt->m_reply_frame + (cmd->cmd_rfm
3945b504601Sjiang wu - Sun Microsystems - Beijing China 		    - mpt->m_reply_frame_dma_addr));
3955b504601Sjiang wu - Sun Microsystems - Beijing China 		config.page_type = ddi_get8(mpt->m_acc_reply_frame_hdl,
3965b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->Header.PageType);
3975b504601Sjiang wu - Sun Microsystems - Beijing China 		config.page_number = ddi_get8(mpt->m_acc_reply_frame_hdl,
3985b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->Header.PageNumber);
3995b504601Sjiang wu - Sun Microsystems - Beijing China 		config.page_length = ddi_get8(mpt->m_acc_reply_frame_hdl,
4005b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->Header.PageLength);
4015b504601Sjiang wu - Sun Microsystems - Beijing China 		config.page_version = ddi_get8(mpt->m_acc_reply_frame_hdl,
4025b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->Header.PageVersion);
4035b504601Sjiang wu - Sun Microsystems - Beijing China 		config.ext_page_type = ddi_get8(mpt->m_acc_reply_frame_hdl,
4045b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->ExtPageType);
4055b504601Sjiang wu - Sun Microsystems - Beijing China 		config.ext_page_length = ddi_get16(mpt->m_acc_reply_frame_hdl,
4065b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->ExtPageLength);
4075b504601Sjiang wu - Sun Microsystems - Beijing China 
4085b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
4095b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->IOCStatus);
4105b504601Sjiang wu - Sun Microsystems - Beijing China 		iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
4115b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->IOCLogInfo);
4125b504601Sjiang wu - Sun Microsystems - Beijing China 
4135b504601Sjiang wu - Sun Microsystems - Beijing China 		if (iocstatus) {
4145b504601Sjiang wu - Sun Microsystems - Beijing China 			NDBG13(("mptsas_access_config_page header: "
4155b504601Sjiang wu - Sun Microsystems - Beijing China 			    "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
4165b504601Sjiang wu - Sun Microsystems - Beijing China 			    iocloginfo));
4175b504601Sjiang wu - Sun Microsystems - Beijing China 			rval = DDI_FAILURE;
4185b504601Sjiang wu - Sun Microsystems - Beijing China 			goto page_done;
4195b504601Sjiang wu - Sun Microsystems - Beijing China 		}
4205b504601Sjiang wu - Sun Microsystems - Beijing China 
4215b504601Sjiang wu - Sun Microsystems - Beijing China 		if ((config.page_type & MPI2_CONFIG_PAGETYPE_MASK) ==
4225b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_CONFIG_PAGETYPE_EXTENDED)
4235b504601Sjiang wu - Sun Microsystems - Beijing China 			len = (config.ext_page_length * 4);
4245b504601Sjiang wu - Sun Microsystems - Beijing China 		else
4255b504601Sjiang wu - Sun Microsystems - Beijing China 			len = (config.page_length * 4);
4265b504601Sjiang wu - Sun Microsystems - Beijing China 
4275b504601Sjiang wu - Sun Microsystems - Beijing China 	}
4285b504601Sjiang wu - Sun Microsystems - Beijing China 
4295b504601Sjiang wu - Sun Microsystems - Beijing China 	if (pkt->pkt_reason == CMD_RESET) {
4305b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "ioc reset abort config header "
4315b504601Sjiang wu - Sun Microsystems - Beijing China 		    "request");
4325b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
4335b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
4345b504601Sjiang wu - Sun Microsystems - Beijing China 	}
4355b504601Sjiang wu - Sun Microsystems - Beijing China 
4365b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
4375b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Put the reply frame back on the free queue, increment the free
4385b504601Sjiang wu - Sun Microsystems - Beijing China 	 * index, and write the new index to the free index register.  But only
4395b504601Sjiang wu - Sun Microsystems - Beijing China 	 * if this reply is an ADDRESS reply.
4405b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
4415b504601Sjiang wu - Sun Microsystems - Beijing China 	if (config_flags & MPTSAS_ADDRESS_REPLY) {
4425b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_acc_free_queue_hdl,
44308eb0b82SYong-Feng Du 		    &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
4445b504601Sjiang wu - Sun Microsystems - Beijing China 		    cmd->cmd_rfm);
4455b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
4465b504601Sjiang wu - Sun Microsystems - Beijing China 		    DDI_DMA_SYNC_FORDEV);
44708eb0b82SYong-Feng Du 		if (++mpt->m_free_index == mpt->m_free_queue_depth) {
44808eb0b82SYong-Feng Du 			mpt->m_free_index = 0;
4495b504601Sjiang wu - Sun Microsystems - Beijing China 		}
4505b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
45108eb0b82SYong-Feng Du 		    mpt->m_free_index);
4525b504601Sjiang wu - Sun Microsystems - Beijing China 		config_flags &= (~MPTSAS_ADDRESS_REPLY);
4535b504601Sjiang wu - Sun Microsystems - Beijing China 	}
4545b504601Sjiang wu - Sun Microsystems - Beijing China 
4555b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
4565b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Allocate DMA buffer here.  Store the info regarding this buffer in
4575b504601Sjiang wu - Sun Microsystems - Beijing China 	 * the cmd struct so that it can be used for this specific command and
4585b504601Sjiang wu - Sun Microsystems - Beijing China 	 * de-allocated after the command completes.  The size of the reply
4595b504601Sjiang wu - Sun Microsystems - Beijing China 	 * will not be larger than the reply frame size.
4605b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
4615b504601Sjiang wu - Sun Microsystems - Beijing China 	attrs = mpt->m_msg_dma_attr;
4625b504601Sjiang wu - Sun Microsystems - Beijing China 	attrs.dma_attr_sgllen = 1;
4635b504601Sjiang wu - Sun Microsystems - Beijing China 	attrs.dma_attr_granular = (uint32_t)len;
4645b504601Sjiang wu - Sun Microsystems - Beijing China 
4655b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_alloc_handle(mpt->m_dip, &attrs,
4665b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SLEEP, NULL, &cmd->cmd_dmahandle) != DDI_SUCCESS) {
4675b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "unable to allocate dma handle for "
4685b504601Sjiang wu - Sun Microsystems - Beijing China 		    "config page.");
4695b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
4705b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
4715b504601Sjiang wu - Sun Microsystems - Beijing China 	}
4725b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_mem_alloc(cmd->cmd_dmahandle, len,
4735b504601Sjiang wu - Sun Microsystems - Beijing China 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
4745b504601Sjiang wu - Sun Microsystems - Beijing China 	    &page_memp, &alloc_len, &accessp) != DDI_SUCCESS) {
4755b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&cmd->cmd_dmahandle);
4765b504601Sjiang wu - Sun Microsystems - Beijing China 		cmd->cmd_dmahandle = NULL;
4775b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "unable to allocate config page "
4785b504601Sjiang wu - Sun Microsystems - Beijing China 		    "structure.");
4795b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
4805b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
4815b504601Sjiang wu - Sun Microsystems - Beijing China 	}
4825b504601Sjiang wu - Sun Microsystems - Beijing China 
4835b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_addr_bind_handle(cmd->cmd_dmahandle, NULL, page_memp,
4845b504601Sjiang wu - Sun Microsystems - Beijing China 	    alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
4855b504601Sjiang wu - Sun Microsystems - Beijing China 	    &cookie, &ncookie) != DDI_DMA_MAPPED) {
4865b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_mem_free(&accessp);
4875b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&cmd->cmd_dmahandle);
4885b504601Sjiang wu - Sun Microsystems - Beijing China 		cmd->cmd_dmahandle = NULL;
4895b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "unable to bind DMA resources for "
4905b504601Sjiang wu - Sun Microsystems - Beijing China 		    "config page.");
4915b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
4925b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
4935b504601Sjiang wu - Sun Microsystems - Beijing China 	}
4945b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_dma_addr = cookie.dmac_laddress;
4955b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(page_memp, len);
4965b504601Sjiang wu - Sun Microsystems - Beijing China 
4975b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
4985b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Save the data for this request to be used in the call to start the
4995b504601Sjiang wu - Sun Microsystems - Beijing China 	 * config page read
5005b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
5015b504601Sjiang wu - Sun Microsystems - Beijing China 	config.action = action;
5025b504601Sjiang wu - Sun Microsystems - Beijing China 	config.page_address = page_address;
5035b504601Sjiang wu - Sun Microsystems - Beijing China 
5045b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
5055b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Re-use the cmd that was used to get the header.  Reset some of the
5065b504601Sjiang wu - Sun Microsystems - Beijing China 	 * values.
5075b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
5085b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero((caddr_t)pkt, scsi_pkt_size());
5095b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_ha_private	= (opaque_t)&config;
5105b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_flags		= FLAG_HEAD;
5115b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_time		= 60;
5125b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_flags		= CFLAG_PREPARED | CFLAG_CMDIOC | CFLAG_CONFIG;
5135b504601Sjiang wu - Sun Microsystems - Beijing China 
5145b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
5155b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Send the config page request.  cmd is re-used from header request.
5165b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
5175b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_start_config_page_access(mpt, cmd);
5185b504601Sjiang wu - Sun Microsystems - Beijing China 
5195b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
520*c8f74a56SAda 	 * If this is a request for a RAID info page, or any page called during
521*c8f74a56SAda 	 * the RAID info page request, poll because these config page requests
522*c8f74a56SAda 	 * are nested.  Poll to avoid data corruption due to one page's data
523*c8f74a56SAda 	 * overwriting the outer page request's data.  This can happen when
524*c8f74a56SAda 	 * the mutex is released in cv_wait.
5255b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
526*c8f74a56SAda 	if ((page_type == MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG) ||
527*c8f74a56SAda 	    (page_type == MPI2_CONFIG_PAGETYPE_RAID_VOLUME) ||
528*c8f74a56SAda 	    (page_type == MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK)) {
529*c8f74a56SAda 		(void) mptsas_poll(mpt, cmd, pkt->pkt_time * 1000);
530*c8f74a56SAda 	} else {
531*c8f74a56SAda 		while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
532*c8f74a56SAda 			cv_wait(&mpt->m_config_cv, &mpt->m_mutex);
533*c8f74a56SAda 		}
5345b504601Sjiang wu - Sun Microsystems - Beijing China 	}
5355b504601Sjiang wu - Sun Microsystems - Beijing China 
5365b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
5375b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Check if the request completed without timing out
5385b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
5395b504601Sjiang wu - Sun Microsystems - Beijing China 	if (cmd->cmd_flags & CFLAG_TIMEOUT) {
5405b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "config page request timeout");
5415b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
5425b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
5435b504601Sjiang wu - Sun Microsystems - Beijing China 	}
5445b504601Sjiang wu - Sun Microsystems - Beijing China 
5455b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
5465b504601Sjiang wu - Sun Microsystems - Beijing China 	 * cmd_rfm points to the reply message if a reply was given.  The reply
5475b504601Sjiang wu - Sun Microsystems - Beijing China 	 * frame and the config page are returned from this function in the
5485b504601Sjiang wu - Sun Microsystems - Beijing China 	 * param list.
5495b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
5505b504601Sjiang wu - Sun Microsystems - Beijing China 	if (cmd->cmd_rfm) {
5515b504601Sjiang wu - Sun Microsystems - Beijing China 		config_flags |= MPTSAS_ADDRESS_REPLY;
5525b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
5535b504601Sjiang wu - Sun Microsystems - Beijing China 		    DDI_DMA_SYNC_FORCPU);
5545b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
5555b504601Sjiang wu - Sun Microsystems - Beijing China 		    DDI_DMA_SYNC_FORCPU);
5565b504601Sjiang wu - Sun Microsystems - Beijing China 		reply = (pMpi2ConfigReply_t)(mpt->m_reply_frame + (cmd->cmd_rfm
5575b504601Sjiang wu - Sun Microsystems - Beijing China 		    - mpt->m_reply_frame_dma_addr));
5585b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
5595b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->IOCStatus);
5605b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = MPTSAS_IOCSTATUS(iocstatus);
5615b504601Sjiang wu - Sun Microsystems - Beijing China 		iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
5625b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->IOCLogInfo);
5635b504601Sjiang wu - Sun Microsystems - Beijing China 	}
5645b504601Sjiang wu - Sun Microsystems - Beijing China 
5655b504601Sjiang wu - Sun Microsystems - Beijing China 	if (callback(mpt, page_memp, accessp, iocstatus, iocloginfo, ap)) {
5665b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
5675b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
5685b504601Sjiang wu - Sun Microsystems - Beijing China 	}
5695b504601Sjiang wu - Sun Microsystems - Beijing China 
5705b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_fma_check(mpt, cmd);
5715b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
5725b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Check the DMA/ACC handles and then free the DMA buffer.
5735b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
5745b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((mptsas_check_dma_handle(cmd->cmd_dmahandle) != DDI_SUCCESS) ||
5755b504601Sjiang wu - Sun Microsystems - Beijing China 	    (mptsas_check_acc_handle(accessp) != DDI_SUCCESS)) {
5765b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
5775b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
5785b504601Sjiang wu - Sun Microsystems - Beijing China 	}
5795b504601Sjiang wu - Sun Microsystems - Beijing China 
5805b504601Sjiang wu - Sun Microsystems - Beijing China 	if (pkt->pkt_reason == CMD_TRAN_ERR) {
5815b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "config fma error");
5825b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
5835b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
5845b504601Sjiang wu - Sun Microsystems - Beijing China 	}
5855b504601Sjiang wu - Sun Microsystems - Beijing China 	if (pkt->pkt_reason == CMD_RESET) {
5865b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "ioc reset abort config request");
5875b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
5885b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
5895b504601Sjiang wu - Sun Microsystems - Beijing China 	}
5905b504601Sjiang wu - Sun Microsystems - Beijing China 
5915b504601Sjiang wu - Sun Microsystems - Beijing China page_done:
5925b504601Sjiang wu - Sun Microsystems - Beijing China 	va_end(ap);
5935b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
5945b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Put the reply frame back on the free queue, increment the free
5955b504601Sjiang wu - Sun Microsystems - Beijing China 	 * index, and write the new index to the free index register.  But only
5965b504601Sjiang wu - Sun Microsystems - Beijing China 	 * if this reply is an ADDRESS reply.
5975b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
5985b504601Sjiang wu - Sun Microsystems - Beijing China 	if (config_flags & MPTSAS_ADDRESS_REPLY) {
5995b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_acc_free_queue_hdl,
60008eb0b82SYong-Feng Du 		    &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
6015b504601Sjiang wu - Sun Microsystems - Beijing China 		    cmd->cmd_rfm);
6025b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
6035b504601Sjiang wu - Sun Microsystems - Beijing China 		    DDI_DMA_SYNC_FORDEV);
60408eb0b82SYong-Feng Du 		if (++mpt->m_free_index == mpt->m_free_queue_depth) {
60508eb0b82SYong-Feng Du 			mpt->m_free_index = 0;
6065b504601Sjiang wu - Sun Microsystems - Beijing China 		}
6075b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
60808eb0b82SYong-Feng Du 		    mpt->m_free_index);
6095b504601Sjiang wu - Sun Microsystems - Beijing China 	}
6105b504601Sjiang wu - Sun Microsystems - Beijing China 
6115b504601Sjiang wu - Sun Microsystems - Beijing China 	if (cmd->cmd_dmahandle != NULL) {
6125b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_unbind_handle(cmd->cmd_dmahandle);
6135b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_mem_free(&accessp);
6145b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&cmd->cmd_dmahandle);
6155b504601Sjiang wu - Sun Microsystems - Beijing China 	}
6165b504601Sjiang wu - Sun Microsystems - Beijing China 
6175b504601Sjiang wu - Sun Microsystems - Beijing China 	if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) {
6185b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_remove_cmd(mpt, cmd);
6195b504601Sjiang wu - Sun Microsystems - Beijing China 		config_flags &= (~MPTSAS_REQUEST_POOL_CMD);
6205b504601Sjiang wu - Sun Microsystems - Beijing China 	}
6215b504601Sjiang wu - Sun Microsystems - Beijing China 	if (config_flags & MPTSAS_REQUEST_POOL_CMD)
6225b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_return_to_pool(mpt, cmd);
6235b504601Sjiang wu - Sun Microsystems - Beijing China 
6245b504601Sjiang wu - Sun Microsystems - Beijing China 	if (config_flags & MPTSAS_CMD_TIMEOUT) {
6255b504601Sjiang wu - Sun Microsystems - Beijing China 		if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
6265b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed");
6275b504601Sjiang wu - Sun Microsystems - Beijing China 		}
6285b504601Sjiang wu - Sun Microsystems - Beijing China 	}
6295b504601Sjiang wu - Sun Microsystems - Beijing China 
6305b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
6315b504601Sjiang wu - Sun Microsystems - Beijing China }
6325b504601Sjiang wu - Sun Microsystems - Beijing China 
6335b504601Sjiang wu - Sun Microsystems - Beijing China int
6345b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_send_config_request_msg(mptsas_t *mpt, uint8_t action, uint8_t pagetype,
6355b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t pageaddress, uint8_t pagenumber, uint8_t pageversion,
6365b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t pagelength, uint32_t SGEflagslength, uint32_t SGEaddress32)
6375b504601Sjiang wu - Sun Microsystems - Beijing China {
6385b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2ConfigRequest_t	config;
6395b504601Sjiang wu - Sun Microsystems - Beijing China 	int			send_numbytes;
6405b504601Sjiang wu - Sun Microsystems - Beijing China 
6415b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(mpt->m_hshk_memp, sizeof (MPI2_CONFIG_REQUEST));
6425b504601Sjiang wu - Sun Microsystems - Beijing China 	config = (pMpi2ConfigRequest_t)mpt->m_hshk_memp;
6435b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Function, MPI2_FUNCTION_CONFIG);
6445b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Action, action);
6455b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageNumber, pagenumber);
6465b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageType, pagetype);
6475b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_hshk_acc_hdl, &config->PageAddress, pageaddress);
6485b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageVersion, pageversion);
6495b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageLength, pagelength);
6505b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_hshk_acc_hdl,
6515b504601Sjiang wu - Sun Microsystems - Beijing China 	    &config->PageBufferSGE.MpiSimple.FlagsLength, SGEflagslength);
6525b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_hshk_acc_hdl,
6535b504601Sjiang wu - Sun Microsystems - Beijing China 	    &config->PageBufferSGE.MpiSimple.u.Address32, SGEaddress32);
6545b504601Sjiang wu - Sun Microsystems - Beijing China 	send_numbytes = sizeof (MPI2_CONFIG_REQUEST);
6555b504601Sjiang wu - Sun Microsystems - Beijing China 
6565b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
6575b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Post message via handshake
6585b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
6595b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_send_handshake_msg(mpt, (caddr_t)config, send_numbytes,
6605b504601Sjiang wu - Sun Microsystems - Beijing China 	    mpt->m_hshk_acc_hdl)) {
6615b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
6625b504601Sjiang wu - Sun Microsystems - Beijing China 	}
6635b504601Sjiang wu - Sun Microsystems - Beijing China 	return (0);
6645b504601Sjiang wu - Sun Microsystems - Beijing China }
6655b504601Sjiang wu - Sun Microsystems - Beijing China 
6665b504601Sjiang wu - Sun Microsystems - Beijing China int
6675b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_send_extended_config_request_msg(mptsas_t *mpt, uint8_t action,
6685b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t extpagetype, uint32_t pageaddress, uint8_t pagenumber,
6695b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t pageversion, uint16_t extpagelength,
6705b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t SGEflagslength, uint32_t SGEaddress32)
6715b504601Sjiang wu - Sun Microsystems - Beijing China {
6725b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2ConfigRequest_t	config;
6735b504601Sjiang wu - Sun Microsystems - Beijing China 	int			send_numbytes;
6745b504601Sjiang wu - Sun Microsystems - Beijing China 
6755b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(mpt->m_hshk_memp, sizeof (MPI2_CONFIG_REQUEST));
6765b504601Sjiang wu - Sun Microsystems - Beijing China 	config = (pMpi2ConfigRequest_t)mpt->m_hshk_memp;
6775b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Function, MPI2_FUNCTION_CONFIG);
6785b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Action, action);
6795b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageNumber, pagenumber);
6805b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageType,
6815b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_CONFIG_PAGETYPE_EXTENDED);
6825b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->ExtPageType, extpagetype);
6835b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_hshk_acc_hdl, &config->PageAddress, pageaddress);
6845b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageVersion, pageversion);
6855b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put16(mpt->m_hshk_acc_hdl, &config->ExtPageLength, extpagelength);
6865b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_hshk_acc_hdl,
6875b504601Sjiang wu - Sun Microsystems - Beijing China 	    &config->PageBufferSGE.MpiSimple.FlagsLength, SGEflagslength);
6885b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_hshk_acc_hdl,
6895b504601Sjiang wu - Sun Microsystems - Beijing China 	    &config->PageBufferSGE.MpiSimple.u.Address32, SGEaddress32);
6905b504601Sjiang wu - Sun Microsystems - Beijing China 	send_numbytes = sizeof (MPI2_CONFIG_REQUEST);
6915b504601Sjiang wu - Sun Microsystems - Beijing China 
6925b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
6935b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Post message via handshake
6945b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
6955b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_send_handshake_msg(mpt, (caddr_t)config, send_numbytes,
6965b504601Sjiang wu - Sun Microsystems - Beijing China 	    mpt->m_hshk_acc_hdl)) {
6975b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
6985b504601Sjiang wu - Sun Microsystems - Beijing China 	}
6995b504601Sjiang wu - Sun Microsystems - Beijing China 	return (0);
7005b504601Sjiang wu - Sun Microsystems - Beijing China }
7015b504601Sjiang wu - Sun Microsystems - Beijing China 
7025b504601Sjiang wu - Sun Microsystems - Beijing China int
7035b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_wait_for_response(mptsas_t *mpt)
7045b504601Sjiang wu - Sun Microsystems - Beijing China {
7055b504601Sjiang wu - Sun Microsystems - Beijing China 	int	polls = 0;
7065b504601Sjiang wu - Sun Microsystems - Beijing China 
7075b504601Sjiang wu - Sun Microsystems - Beijing China 	while ((ddi_get32(mpt->m_datap,
7085b504601Sjiang wu - Sun Microsystems - Beijing China 	    &mpt->m_reg->HostInterruptStatus) & MPI2_HIS_IOP_DOORBELL_STATUS)) {
7095b504601Sjiang wu - Sun Microsystems - Beijing China 		drv_usecwait(1000);
7105b504601Sjiang wu - Sun Microsystems - Beijing China 		if (polls++ > 60000) {
7115b504601Sjiang wu - Sun Microsystems - Beijing China 			return (-1);
7125b504601Sjiang wu - Sun Microsystems - Beijing China 		}
7135b504601Sjiang wu - Sun Microsystems - Beijing China 	}
7145b504601Sjiang wu - Sun Microsystems - Beijing China 	return (0);
7155b504601Sjiang wu - Sun Microsystems - Beijing China }
7165b504601Sjiang wu - Sun Microsystems - Beijing China 
7175b504601Sjiang wu - Sun Microsystems - Beijing China int
7185b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_wait_for_doorbell(mptsas_t *mpt)
7195b504601Sjiang wu - Sun Microsystems - Beijing China {
7205b504601Sjiang wu - Sun Microsystems - Beijing China 	int	polls = 0;
7215b504601Sjiang wu - Sun Microsystems - Beijing China 
7225b504601Sjiang wu - Sun Microsystems - Beijing China 	while ((ddi_get32(mpt->m_datap,
7235b504601Sjiang wu - Sun Microsystems - Beijing China 	    &mpt->m_reg->HostInterruptStatus) & MPI2_HIM_DIM) == 0) {
7245b504601Sjiang wu - Sun Microsystems - Beijing China 		drv_usecwait(1000);
7255b504601Sjiang wu - Sun Microsystems - Beijing China 		if (polls++ > 300000) {
7265b504601Sjiang wu - Sun Microsystems - Beijing China 			return (-1);
7275b504601Sjiang wu - Sun Microsystems - Beijing China 		}
7285b504601Sjiang wu - Sun Microsystems - Beijing China 	}
7295b504601Sjiang wu - Sun Microsystems - Beijing China 	return (0);
7305b504601Sjiang wu - Sun Microsystems - Beijing China }
7315b504601Sjiang wu - Sun Microsystems - Beijing China 
7325b504601Sjiang wu - Sun Microsystems - Beijing China int
7335b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_send_handshake_msg(mptsas_t *mpt, caddr_t memp, int numbytes,
7345b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_acc_handle_t accessp)
7355b504601Sjiang wu - Sun Microsystems - Beijing China {
7365b504601Sjiang wu - Sun Microsystems - Beijing China 	int	i;
7375b504601Sjiang wu - Sun Microsystems - Beijing China 
7385b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
7395b504601Sjiang wu - Sun Microsystems - Beijing China 	 * clean pending doorbells
7405b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
7415b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptStatus, 0);
7425b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_datap, &mpt->m_reg->Doorbell,
7435b504601Sjiang wu - Sun Microsystems - Beijing China 	    ((MPI2_FUNCTION_HANDSHAKE << MPI2_DOORBELL_FUNCTION_SHIFT) |
7445b504601Sjiang wu - Sun Microsystems - Beijing China 	    ((numbytes / 4) << MPI2_DOORBELL_ADD_DWORDS_SHIFT)));
7455b504601Sjiang wu - Sun Microsystems - Beijing China 
7465b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_ioc_wait_for_doorbell(mpt)) {
7475b504601Sjiang wu - Sun Microsystems - Beijing China 		NDBG19(("mptsas_send_handshake failed.  Doorbell not ready\n"));
7485b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
7495b504601Sjiang wu - Sun Microsystems - Beijing China 	}
7505b504601Sjiang wu - Sun Microsystems - Beijing China 
7515b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
7525b504601Sjiang wu - Sun Microsystems - Beijing China 	 * clean pending doorbells again
7535b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
7545b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptStatus, 0);
7555b504601Sjiang wu - Sun Microsystems - Beijing China 
7565b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_ioc_wait_for_response(mpt)) {
7575b504601Sjiang wu - Sun Microsystems - Beijing China 		NDBG19(("mptsas_send_handshake failed.  Doorbell not "
7585b504601Sjiang wu - Sun Microsystems - Beijing China 		    "cleared\n"));
7595b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
7605b504601Sjiang wu - Sun Microsystems - Beijing China 	}
7615b504601Sjiang wu - Sun Microsystems - Beijing China 
7625b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
7635b504601Sjiang wu - Sun Microsystems - Beijing China 	 * post handshake message
7645b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
7655b504601Sjiang wu - Sun Microsystems - Beijing China 	for (i = 0; (i < numbytes / 4); i++, memp += 4) {
7665b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_datap, &mpt->m_reg->Doorbell,
7675b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get32(accessp, (uint32_t *)((void *)(memp))));
7685b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_ioc_wait_for_response(mpt)) {
7695b504601Sjiang wu - Sun Microsystems - Beijing China 			NDBG19(("mptsas_send_handshake failed posting "
7705b504601Sjiang wu - Sun Microsystems - Beijing China 			    "message\n"));
7715b504601Sjiang wu - Sun Microsystems - Beijing China 			return (-1);
7725b504601Sjiang wu - Sun Microsystems - Beijing China 		}
7735b504601Sjiang wu - Sun Microsystems - Beijing China 	}
7745b504601Sjiang wu - Sun Microsystems - Beijing China 
7755b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) {
7765b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
7775b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_acc_err_clear(mpt->m_datap, DDI_FME_VER0);
7785b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
7795b504601Sjiang wu - Sun Microsystems - Beijing China 	}
7805b504601Sjiang wu - Sun Microsystems - Beijing China 
7815b504601Sjiang wu - Sun Microsystems - Beijing China 	return (0);
7825b504601Sjiang wu - Sun Microsystems - Beijing China }
7835b504601Sjiang wu - Sun Microsystems - Beijing China 
7845b504601Sjiang wu - Sun Microsystems - Beijing China int
7855b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_handshake_msg(mptsas_t *mpt, caddr_t memp, int numbytes,
7865b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_acc_handle_t accessp)
7875b504601Sjiang wu - Sun Microsystems - Beijing China {
7885b504601Sjiang wu - Sun Microsystems - Beijing China 	int		i, totalbytes, bytesleft;
7895b504601Sjiang wu - Sun Microsystems - Beijing China 	uint16_t	val;
7905b504601Sjiang wu - Sun Microsystems - Beijing China 
7915b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
7925b504601Sjiang wu - Sun Microsystems - Beijing China 	 * wait for doorbell
7935b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
7945b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_ioc_wait_for_doorbell(mpt)) {
7955b504601Sjiang wu - Sun Microsystems - Beijing China 		NDBG19(("mptsas_get_handshake failed.  Doorbell not ready\n"));
7965b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
7975b504601Sjiang wu - Sun Microsystems - Beijing China 	}
7985b504601Sjiang wu - Sun Microsystems - Beijing China 
7995b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
8005b504601Sjiang wu - Sun Microsystems - Beijing China 	 * get first 2 bytes of handshake message to determine how much
8015b504601Sjiang wu - Sun Microsystems - Beijing China 	 * data we will be getting
8025b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
8035b504601Sjiang wu - Sun Microsystems - Beijing China 	for (i = 0; i < 2; i++, memp += 2) {
8045b504601Sjiang wu - Sun Microsystems - Beijing China 		val = (ddi_get32(mpt->m_datap,
8055b504601Sjiang wu - Sun Microsystems - Beijing China 		    &mpt->m_reg->Doorbell) & MPI2_DOORBELL_DATA_MASK);
8065b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptStatus, 0);
8075b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_ioc_wait_for_doorbell(mpt)) {
8085b504601Sjiang wu - Sun Microsystems - Beijing China 			NDBG19(("mptsas_get_handshake failure getting initial"
8095b504601Sjiang wu - Sun Microsystems - Beijing China 			    " data\n"));
8105b504601Sjiang wu - Sun Microsystems - Beijing China 			return (-1);
8115b504601Sjiang wu - Sun Microsystems - Beijing China 		}
8125b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put16(accessp, (uint16_t *)((void *)(memp)), val);
8135b504601Sjiang wu - Sun Microsystems - Beijing China 		if (i == 1) {
8145b504601Sjiang wu - Sun Microsystems - Beijing China 			totalbytes = (val & 0xFF) * 2;
8155b504601Sjiang wu - Sun Microsystems - Beijing China 		}
8165b504601Sjiang wu - Sun Microsystems - Beijing China 	}
8175b504601Sjiang wu - Sun Microsystems - Beijing China 
8185b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
8195b504601Sjiang wu - Sun Microsystems - Beijing China 	 * If we are expecting less bytes than the message wants to send
8205b504601Sjiang wu - Sun Microsystems - Beijing China 	 * we simply save as much as we expected and then throw out the rest
8215b504601Sjiang wu - Sun Microsystems - Beijing China 	 * later
8225b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
8235b504601Sjiang wu - Sun Microsystems - Beijing China 	if (totalbytes > (numbytes / 2)) {
8245b504601Sjiang wu - Sun Microsystems - Beijing China 		bytesleft = ((numbytes / 2) - 2);
8255b504601Sjiang wu - Sun Microsystems - Beijing China 	} else {
8265b504601Sjiang wu - Sun Microsystems - Beijing China 		bytesleft = (totalbytes - 2);
8275b504601Sjiang wu - Sun Microsystems - Beijing China 	}
8285b504601Sjiang wu - Sun Microsystems - Beijing China 
8295b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
8305b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Get the rest of the data
8315b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
8325b504601Sjiang wu - Sun Microsystems - Beijing China 	for (i = 0; i < bytesleft; i++, memp += 2) {
8335b504601Sjiang wu - Sun Microsystems - Beijing China 		val = (ddi_get32(mpt->m_datap,
8345b504601Sjiang wu - Sun Microsystems - Beijing China 		    &mpt->m_reg->Doorbell) & MPI2_DOORBELL_DATA_MASK);
8355b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptStatus, 0);
8365b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_ioc_wait_for_doorbell(mpt)) {
8375b504601Sjiang wu - Sun Microsystems - Beijing China 			NDBG19(("mptsas_get_handshake failure getting"
8385b504601Sjiang wu - Sun Microsystems - Beijing China 			    " main data\n"));
8395b504601Sjiang wu - Sun Microsystems - Beijing China 			return (-1);
8405b504601Sjiang wu - Sun Microsystems - Beijing China 		}
8415b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put16(accessp, (uint16_t *)((void *)(memp)), val);
8425b504601Sjiang wu - Sun Microsystems - Beijing China 	}
8435b504601Sjiang wu - Sun Microsystems - Beijing China 
8445b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
8455b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Sometimes the device will send more data than is expected
8465b504601Sjiang wu - Sun Microsystems - Beijing China 	 * This data is not used by us but needs to be cleared from
8475b504601Sjiang wu - Sun Microsystems - Beijing China 	 * ioc doorbell.  So we just read the values and throw
8485b504601Sjiang wu - Sun Microsystems - Beijing China 	 * them out.
8495b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
8505b504601Sjiang wu - Sun Microsystems - Beijing China 	if (totalbytes > (numbytes / 2)) {
8515b504601Sjiang wu - Sun Microsystems - Beijing China 		for (i = (numbytes / 2); i < totalbytes; i++) {
8525b504601Sjiang wu - Sun Microsystems - Beijing China 			val = (ddi_get32(mpt->m_datap,
8535b504601Sjiang wu - Sun Microsystems - Beijing China 			    &mpt->m_reg->Doorbell) &
8545b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_DOORBELL_DATA_MASK);
8555b504601Sjiang wu - Sun Microsystems - Beijing China 			ddi_put32(mpt->m_datap,
8565b504601Sjiang wu - Sun Microsystems - Beijing China 			    &mpt->m_reg->HostInterruptStatus, 0);
8575b504601Sjiang wu - Sun Microsystems - Beijing China 			if (mptsas_ioc_wait_for_doorbell(mpt)) {
8585b504601Sjiang wu - Sun Microsystems - Beijing China 				NDBG19(("mptsas_get_handshake failure getting "
8595b504601Sjiang wu - Sun Microsystems - Beijing China 				    "extra garbage data\n"));
8605b504601Sjiang wu - Sun Microsystems - Beijing China 				return (-1);
8615b504601Sjiang wu - Sun Microsystems - Beijing China 			}
8625b504601Sjiang wu - Sun Microsystems - Beijing China 		}
8635b504601Sjiang wu - Sun Microsystems - Beijing China 	}
8645b504601Sjiang wu - Sun Microsystems - Beijing China 
8655b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptStatus, 0);
8665b504601Sjiang wu - Sun Microsystems - Beijing China 
8675b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) {
8685b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
8695b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_acc_err_clear(mpt->m_datap, DDI_FME_VER0);
8705b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
8715b504601Sjiang wu - Sun Microsystems - Beijing China 	}
8725b504601Sjiang wu - Sun Microsystems - Beijing China 
8735b504601Sjiang wu - Sun Microsystems - Beijing China 	return (0);
8745b504601Sjiang wu - Sun Microsystems - Beijing China }
8755b504601Sjiang wu - Sun Microsystems - Beijing China 
8765b504601Sjiang wu - Sun Microsystems - Beijing China int
8775b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_kick_start(mptsas_t *mpt)
8785b504601Sjiang wu - Sun Microsystems - Beijing China {
8795b504601Sjiang wu - Sun Microsystems - Beijing China 	int		polls = 0;
8805b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t	diag_reg, ioc_state, saved_HCB_size;
8815b504601Sjiang wu - Sun Microsystems - Beijing China 
8825b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
8835b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Start a hard reset.  Write magic number and wait 900 uSeconds.
8845b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
8855b504601Sjiang wu - Sun Microsystems - Beijing China 	MPTSAS_ENABLE_DRWE(mpt);
8865b504601Sjiang wu - Sun Microsystems - Beijing China 	drv_usecwait(900);
8875b504601Sjiang wu - Sun Microsystems - Beijing China 
8885b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
8895b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Read the current Diag Reg and save the Host Controlled Boot size.
8905b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
8915b504601Sjiang wu - Sun Microsystems - Beijing China 	diag_reg = ddi_get32(mpt->m_datap, &mpt->m_reg->HostDiagnostic);
8925b504601Sjiang wu - Sun Microsystems - Beijing China 	saved_HCB_size = ddi_get32(mpt->m_datap, &mpt->m_reg->HCBSize);
8935b504601Sjiang wu - Sun Microsystems - Beijing China 
8945b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
89576a4caf6SAda 	 * Set Reset Adapter bit and wait 50 mSeconds.
8965b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
8975b504601Sjiang wu - Sun Microsystems - Beijing China 	diag_reg |= MPI2_DIAG_RESET_ADAPTER;
8985b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_datap, &mpt->m_reg->HostDiagnostic, diag_reg);
89976a4caf6SAda 	drv_usecwait(50000);
9005b504601Sjiang wu - Sun Microsystems - Beijing China 
9015b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
9025b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Poll, waiting for Reset Adapter bit to clear.  300 Seconds max
9035b504601Sjiang wu - Sun Microsystems - Beijing China 	 * (600000 * 500 = 300,000,000 uSeconds, 300 seconds).
9045b504601Sjiang wu - Sun Microsystems - Beijing China 	 * If no more adapter (all FF's), just return failure.
9055b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
9065b504601Sjiang wu - Sun Microsystems - Beijing China 	for (polls = 0; polls < 600000; polls++) {
9075b504601Sjiang wu - Sun Microsystems - Beijing China 		diag_reg = ddi_get32(mpt->m_datap,
9085b504601Sjiang wu - Sun Microsystems - Beijing China 		    &mpt->m_reg->HostDiagnostic);
9095b504601Sjiang wu - Sun Microsystems - Beijing China 		if (diag_reg == 0xFFFFFFFF) {
9105b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
9115b504601Sjiang wu - Sun Microsystems - Beijing China 			ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
9125b504601Sjiang wu - Sun Microsystems - Beijing China 			return (DDI_FAILURE);
9135b504601Sjiang wu - Sun Microsystems - Beijing China 		}
9145b504601Sjiang wu - Sun Microsystems - Beijing China 		if (!(diag_reg & MPI2_DIAG_RESET_ADAPTER)) {
9155b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
9165b504601Sjiang wu - Sun Microsystems - Beijing China 		}
9175b504601Sjiang wu - Sun Microsystems - Beijing China 		drv_usecwait(500);
9185b504601Sjiang wu - Sun Microsystems - Beijing China 	}
9195b504601Sjiang wu - Sun Microsystems - Beijing China 	if (polls == 600000) {
9205b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
9215b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
9225b504601Sjiang wu - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
9235b504601Sjiang wu - Sun Microsystems - Beijing China 	}
9245b504601Sjiang wu - Sun Microsystems - Beijing China 
9255b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
9265b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Check if adapter is in Host Boot Mode.  If so, restart adapter
9275b504601Sjiang wu - Sun Microsystems - Beijing China 	 * assuming the HCB points to good FW.
9285b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Set BootDeviceSel to HCDW (Host Code and Data Window).
9295b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
9305b504601Sjiang wu - Sun Microsystems - Beijing China 	if (diag_reg & MPI2_DIAG_HCB_MODE) {
9315b504601Sjiang wu - Sun Microsystems - Beijing China 		diag_reg &= ~MPI2_DIAG_BOOT_DEVICE_SELECT_MASK;
9325b504601Sjiang wu - Sun Microsystems - Beijing China 		diag_reg |= MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW;
9335b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_datap, &mpt->m_reg->HostDiagnostic, diag_reg);
9345b504601Sjiang wu - Sun Microsystems - Beijing China 
9355b504601Sjiang wu - Sun Microsystems - Beijing China 		/*
9365b504601Sjiang wu - Sun Microsystems - Beijing China 		 * Re-enable the HCDW.
9375b504601Sjiang wu - Sun Microsystems - Beijing China 		 */
9385b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_datap, &mpt->m_reg->HCBSize,
9395b504601Sjiang wu - Sun Microsystems - Beijing China 		    (saved_HCB_size | MPI2_HCB_SIZE_HCB_ENABLE));
9405b504601Sjiang wu - Sun Microsystems - Beijing China 	}
9415b504601Sjiang wu - Sun Microsystems - Beijing China 
9425b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
9435b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Restart the adapter.
9445b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
9455b504601Sjiang wu - Sun Microsystems - Beijing China 	diag_reg &= ~MPI2_DIAG_HOLD_IOC_RESET;
9465b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_datap, &mpt->m_reg->HostDiagnostic, diag_reg);
9475b504601Sjiang wu - Sun Microsystems - Beijing China 
9485b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
9495b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Disable writes to the Host Diag register.
9505b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
9515b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_datap, &mpt->m_reg->WriteSequence,
9525b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_WRSEQ_FLUSH_KEY_VALUE);
9535b504601Sjiang wu - Sun Microsystems - Beijing China 
9545b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
95576a4caf6SAda 	 * Wait 60 seconds max for FW to come to ready state.
9565b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
95776a4caf6SAda 	for (polls = 0; polls < 60000; polls++) {
9585b504601Sjiang wu - Sun Microsystems - Beijing China 		ioc_state = ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell);
9595b504601Sjiang wu - Sun Microsystems - Beijing China 		if (ioc_state == 0xFFFFFFFF) {
9605b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
9615b504601Sjiang wu - Sun Microsystems - Beijing China 			ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
9625b504601Sjiang wu - Sun Microsystems - Beijing China 			return (DDI_FAILURE);
9635b504601Sjiang wu - Sun Microsystems - Beijing China 		}
9645b504601Sjiang wu - Sun Microsystems - Beijing China 		if ((ioc_state & MPI2_IOC_STATE_MASK) ==
9655b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_IOC_STATE_READY) {
9665b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
9675b504601Sjiang wu - Sun Microsystems - Beijing China 		}
9685b504601Sjiang wu - Sun Microsystems - Beijing China 		drv_usecwait(1000);
9695b504601Sjiang wu - Sun Microsystems - Beijing China 	}
97076a4caf6SAda 	if (polls == 60000) {
9715b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
9725b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
9735b504601Sjiang wu - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
9745b504601Sjiang wu - Sun Microsystems - Beijing China 	}
9755b504601Sjiang wu - Sun Microsystems - Beijing China 
9765b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
9775b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Clear the ioc ack events queue.
9785b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
9795b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_destroy_ioc_event_cmd(mpt);
9805b504601Sjiang wu - Sun Microsystems - Beijing China 
9815b504601Sjiang wu - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
9825b504601Sjiang wu - Sun Microsystems - Beijing China }
9835b504601Sjiang wu - Sun Microsystems - Beijing China 
9845b504601Sjiang wu - Sun Microsystems - Beijing China int
9855b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_reset(mptsas_t *mpt)
9865b504601Sjiang wu - Sun Microsystems - Beijing China {
9875b504601Sjiang wu - Sun Microsystems - Beijing China #ifdef SLM
9885b504601Sjiang wu - Sun Microsystems - Beijing China 	int		polls = 0;
9895b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t	reset_msg;
9905b504601Sjiang wu - Sun Microsystems - Beijing China 
9915b504601Sjiang wu - Sun Microsystems - Beijing China #endif
9925b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t	ioc_state;
9935b504601Sjiang wu - Sun Microsystems - Beijing China 	ioc_state = ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell);
9945b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
9955b504601Sjiang wu - Sun Microsystems - Beijing China 	 * If chip is already in ready state then there is nothing to do.
9965b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
9975b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ioc_state == MPI2_IOC_STATE_READY) {
9985b504601Sjiang wu - Sun Microsystems - Beijing China 		return (MPTSAS_NO_RESET);
9995b504601Sjiang wu - Sun Microsystems - Beijing China 	}
10005b504601Sjiang wu - Sun Microsystems - Beijing China 
10015b504601Sjiang wu - Sun Microsystems - Beijing China /*
10025b504601Sjiang wu - Sun Microsystems - Beijing China  * SLM-test; skip MUR for now
10035b504601Sjiang wu - Sun Microsystems - Beijing China  */
10045b504601Sjiang wu - Sun Microsystems - Beijing China #ifdef SLM
10055b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
10065b504601Sjiang wu - Sun Microsystems - Beijing China 	 * If the chip is already operational, we just need to send
10075b504601Sjiang wu - Sun Microsystems - Beijing China 	 * it a message unit reset to put it back in the ready state
10085b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
10095b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ioc_state & MPI2_IOC_STATE_OPERATIONAL) {
10105b504601Sjiang wu - Sun Microsystems - Beijing China 		reset_msg = MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET;
10115b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_datap, &mpt->m_reg->Doorbell,
10125b504601Sjiang wu - Sun Microsystems - Beijing China 		    (reset_msg << MPI2_DOORBELL_FUNCTION_SHIFT));
10135b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_ioc_wait_for_response(mpt)) {
10145b504601Sjiang wu - Sun Microsystems - Beijing China 			NDBG19(("mptsas_ioc_reset failure sending "
10155b504601Sjiang wu - Sun Microsystems - Beijing China 			    "message_unit_reset\n"));
10165b504601Sjiang wu - Sun Microsystems - Beijing China 			goto hard_reset;
10175b504601Sjiang wu - Sun Microsystems - Beijing China 		}
10185b504601Sjiang wu - Sun Microsystems - Beijing China 
10195b504601Sjiang wu - Sun Microsystems - Beijing China 		/*
102076a4caf6SAda 		 * Wait no more than 60 seconds for chip to become ready.
10215b504601Sjiang wu - Sun Microsystems - Beijing China 		 */
10225b504601Sjiang wu - Sun Microsystems - Beijing China 		while ((ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell) &
10235b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_IOC_STATE_READY) == 0x0) {
10245b504601Sjiang wu - Sun Microsystems - Beijing China 			drv_usecwait(1000);
102576a4caf6SAda 			if (polls++ > 60000) {
10265b504601Sjiang wu - Sun Microsystems - Beijing China 				goto hard_reset;
10275b504601Sjiang wu - Sun Microsystems - Beijing China 			}
10285b504601Sjiang wu - Sun Microsystems - Beijing China 		}
10295b504601Sjiang wu - Sun Microsystems - Beijing China 		/*
10305b504601Sjiang wu - Sun Microsystems - Beijing China 		 * the message unit reset would do reset operations
10315b504601Sjiang wu - Sun Microsystems - Beijing China 		 * clear reply and request queue, so we should clear
10325b504601Sjiang wu - Sun Microsystems - Beijing China 		 * ACK event cmd.
10335b504601Sjiang wu - Sun Microsystems - Beijing China 		 */
10345b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_destroy_ioc_event_cmd(mpt);
10355b504601Sjiang wu - Sun Microsystems - Beijing China 		return (MPTSAS_NO_RESET);
10365b504601Sjiang wu - Sun Microsystems - Beijing China 	}
10375b504601Sjiang wu - Sun Microsystems - Beijing China 
10385b504601Sjiang wu - Sun Microsystems - Beijing China hard_reset:
10395b504601Sjiang wu - Sun Microsystems - Beijing China #endif
10405b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_kick_start(mpt) == DDI_FAILURE) {
10415b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
10425b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
10435b504601Sjiang wu - Sun Microsystems - Beijing China 		return (MPTSAS_RESET_FAIL);
10445b504601Sjiang wu - Sun Microsystems - Beijing China 	}
10455b504601Sjiang wu - Sun Microsystems - Beijing China 	return (MPTSAS_SUCCESS_HARDRESET);
10465b504601Sjiang wu - Sun Microsystems - Beijing China }
10475b504601Sjiang wu - Sun Microsystems - Beijing China 
10485b504601Sjiang wu - Sun Microsystems - Beijing China 
10495b504601Sjiang wu - Sun Microsystems - Beijing China int
10505b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_request_from_pool(mptsas_t *mpt, mptsas_cmd_t **cmd,
10515b504601Sjiang wu - Sun Microsystems - Beijing China     struct scsi_pkt **pkt)
10525b504601Sjiang wu - Sun Microsystems - Beijing China {
10535b504601Sjiang wu - Sun Microsystems - Beijing China 	m_event_struct_t	*ioc_cmd = NULL;
10545b504601Sjiang wu - Sun Microsystems - Beijing China 
10555b504601Sjiang wu - Sun Microsystems - Beijing China 	ioc_cmd = kmem_zalloc(M_EVENT_STRUCT_SIZE, KM_SLEEP);
10565b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ioc_cmd == NULL) {
10575b504601Sjiang wu - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
10585b504601Sjiang wu - Sun Microsystems - Beijing China 	}
10595b504601Sjiang wu - Sun Microsystems - Beijing China 	ioc_cmd->m_event_linkp = NULL;
10605b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_ioc_event_cmdq_add(mpt, ioc_cmd);
10615b504601Sjiang wu - Sun Microsystems - Beijing China 	*cmd = &(ioc_cmd->m_event_cmd);
10625b504601Sjiang wu - Sun Microsystems - Beijing China 	*pkt = &(ioc_cmd->m_event_pkt);
10635b504601Sjiang wu - Sun Microsystems - Beijing China 
10645b504601Sjiang wu - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
10655b504601Sjiang wu - Sun Microsystems - Beijing China }
10665b504601Sjiang wu - Sun Microsystems - Beijing China 
10675b504601Sjiang wu - Sun Microsystems - Beijing China void
10685b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_return_to_pool(mptsas_t *mpt, mptsas_cmd_t *cmd)
10695b504601Sjiang wu - Sun Microsystems - Beijing China {
10705b504601Sjiang wu - Sun Microsystems - Beijing China 	m_event_struct_t	*ioc_cmd = NULL;
10715b504601Sjiang wu - Sun Microsystems - Beijing China 
10725b504601Sjiang wu - Sun Microsystems - Beijing China 	ioc_cmd = mptsas_ioc_event_find_by_cmd(mpt, cmd);
10735b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ioc_cmd == NULL) {
10745b504601Sjiang wu - Sun Microsystems - Beijing China 		return;
10755b504601Sjiang wu - Sun Microsystems - Beijing China 	}
10765b504601Sjiang wu - Sun Microsystems - Beijing China 
10775b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_ioc_event_cmdq_delete(mpt, ioc_cmd);
10785b504601Sjiang wu - Sun Microsystems - Beijing China 	kmem_free(ioc_cmd, M_EVENT_STRUCT_SIZE);
10795b504601Sjiang wu - Sun Microsystems - Beijing China 	ioc_cmd = NULL;
10805b504601Sjiang wu - Sun Microsystems - Beijing China }
10815b504601Sjiang wu - Sun Microsystems - Beijing China 
10825b504601Sjiang wu - Sun Microsystems - Beijing China /*
10835b504601Sjiang wu - Sun Microsystems - Beijing China  * NOTE: We should be able to queue TM requests in the controller to make this
10845b504601Sjiang wu - Sun Microsystems - Beijing China  * a lot faster.  If resetting all targets, for example, we can load the hi
10855b504601Sjiang wu - Sun Microsystems - Beijing China  * priority queue with its limit and the controller will reply as they are
10865b504601Sjiang wu - Sun Microsystems - Beijing China  * completed.  This way, we don't have to poll for one reply at a time.
10875b504601Sjiang wu - Sun Microsystems - Beijing China  * Think about enhancing this later.
10885b504601Sjiang wu - Sun Microsystems - Beijing China  */
10895b504601Sjiang wu - Sun Microsystems - Beijing China int
10905b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_task_management(mptsas_t *mpt, int task_type, uint16_t dev_handle,
1091*c8f74a56SAda 	int lun, uint8_t *reply, uint32_t reply_size, int mode)
10925b504601Sjiang wu - Sun Microsystems - Beijing China {
10935b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
10945b504601Sjiang wu - Sun Microsystems - Beijing China 	 * In order to avoid allocating variables on the stack,
10955b504601Sjiang wu - Sun Microsystems - Beijing China 	 * we make use of the pre-existing mptsas_cmd_t and
10965b504601Sjiang wu - Sun Microsystems - Beijing China 	 * scsi_pkt which are included in the mptsas_t which
10975b504601Sjiang wu - Sun Microsystems - Beijing China 	 * is passed to this routine.
10985b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
10995b504601Sjiang wu - Sun Microsystems - Beijing China 
11005b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2SCSITaskManagementRequest_t	task;
11015b504601Sjiang wu - Sun Microsystems - Beijing China 	int					rval = FALSE;
11025b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_cmd_t				*cmd;
11035b504601Sjiang wu - Sun Microsystems - Beijing China 	struct scsi_pkt				*pkt;
11045b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_slots_t				*slots = mpt->m_active;
1105*c8f74a56SAda 	uint32_t				request_desc_low, i;
1106*c8f74a56SAda 	pMPI2DefaultReply_t			reply_msg;
11075b504601Sjiang wu - Sun Microsystems - Beijing China 
11085b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
11095b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Can't start another task management routine.
11105b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
11115b504601Sjiang wu - Sun Microsystems - Beijing China 	if (slots->m_slot[MPTSAS_TM_SLOT(mpt)] != NULL) {
11125b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "Can only start 1 task management"
11135b504601Sjiang wu - Sun Microsystems - Beijing China 		    " command at a time\n");
11145b504601Sjiang wu - Sun Microsystems - Beijing China 		return (FALSE);
11155b504601Sjiang wu - Sun Microsystems - Beijing China 	}
11165b504601Sjiang wu - Sun Microsystems - Beijing China 
11175b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd = &(mpt->m_event_task_mgmt.m_event_cmd);
11185b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt = &(mpt->m_event_task_mgmt.m_event_pkt);
11195b504601Sjiang wu - Sun Microsystems - Beijing China 
11205b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero((caddr_t)cmd, sizeof (*cmd));
11215b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero((caddr_t)pkt, scsi_pkt_size());
11225b504601Sjiang wu - Sun Microsystems - Beijing China 
11235b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_cdbp		= (opaque_t)&cmd->cmd_cdb[0];
11245b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_scbp		= (opaque_t)&cmd->cmd_scb;
11255b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_ha_private	= (opaque_t)cmd;
11265b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_flags		= (FLAG_NOINTR | FLAG_HEAD);
11275b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_time		= 60;
11285b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_address.a_target = dev_handle;
11295b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_address.a_lun = (uchar_t)lun;
11305b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_pkt		= pkt;
11315b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_scblen		= 1;
11325b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_flags		= CFLAG_TM_CMD;
11335b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_slot		= MPTSAS_TM_SLOT(mpt);
11345b504601Sjiang wu - Sun Microsystems - Beijing China 
11355b504601Sjiang wu - Sun Microsystems - Beijing China 	slots->m_slot[MPTSAS_TM_SLOT(mpt)] = cmd;
11365b504601Sjiang wu - Sun Microsystems - Beijing China 
11375b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
11385b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Store the TM message in memory location corresponding to the TM slot
11395b504601Sjiang wu - Sun Microsystems - Beijing China 	 * number.
11405b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
11415b504601Sjiang wu - Sun Microsystems - Beijing China 	task = (pMpi2SCSITaskManagementRequest_t)(mpt->m_req_frame +
11425b504601Sjiang wu - Sun Microsystems - Beijing China 	    (mpt->m_req_frame_size * cmd->cmd_slot));
11435b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(task, mpt->m_req_frame_size);
11445b504601Sjiang wu - Sun Microsystems - Beijing China 
11455b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
11465b504601Sjiang wu - Sun Microsystems - Beijing China 	 * form message for requested task
11475b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
11485b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_init_std_hdr(mpt->m_acc_req_frame_hdl, task, dev_handle, lun, 0,
11495b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_FUNCTION_SCSI_TASK_MGMT);
11505b504601Sjiang wu - Sun Microsystems - Beijing China 
11515b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
11525b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Set the task type
11535b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
11545b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &task->TaskType, task_type);
11555b504601Sjiang wu - Sun Microsystems - Beijing China 
11565b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
11575b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Send TM request using High Priority Queue.
11585b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
11595b504601Sjiang wu - Sun Microsystems - Beijing China 	(void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0,
11605b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SYNC_FORDEV);
11615b504601Sjiang wu - Sun Microsystems - Beijing China 	request_desc_low = (cmd->cmd_slot << 16) +
11625b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
11635b504601Sjiang wu - Sun Microsystems - Beijing China 	MPTSAS_START_CMD(mpt, request_desc_low, 0);
11645b504601Sjiang wu - Sun Microsystems - Beijing China 	rval = mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME);
11655b504601Sjiang wu - Sun Microsystems - Beijing China 
11665b504601Sjiang wu - Sun Microsystems - Beijing China 	if (pkt->pkt_reason == CMD_INCOMPLETE)
11675b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = FALSE;
11685b504601Sjiang wu - Sun Microsystems - Beijing China 
1169*c8f74a56SAda 	/*
1170*c8f74a56SAda 	 * If a reply frame was used and there is a reply buffer to copy the
1171*c8f74a56SAda 	 * reply data into, copy it.  If this fails, log a message, but don't
1172*c8f74a56SAda 	 * fail the TM request.
1173*c8f74a56SAda 	 */
1174*c8f74a56SAda 	if (cmd->cmd_rfm && reply) {
1175*c8f74a56SAda 		(void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
1176*c8f74a56SAda 		    DDI_DMA_SYNC_FORCPU);
1177*c8f74a56SAda 		reply_msg = (pMPI2DefaultReply_t)
1178*c8f74a56SAda 		    (mpt->m_reply_frame + (cmd->cmd_rfm -
1179*c8f74a56SAda 		    mpt->m_reply_frame_dma_addr));
1180*c8f74a56SAda 		if (reply_size > sizeof (MPI2_SCSI_TASK_MANAGE_REPLY)) {
1181*c8f74a56SAda 			reply_size = sizeof (MPI2_SCSI_TASK_MANAGE_REPLY);
1182*c8f74a56SAda 		}
1183*c8f74a56SAda 		mutex_exit(&mpt->m_mutex);
1184*c8f74a56SAda 		for (i = 0; i < reply_size; i++) {
1185*c8f74a56SAda 			if (ddi_copyout((uint8_t *)reply_msg + i, reply + i, 1,
1186*c8f74a56SAda 			    mode)) {
1187*c8f74a56SAda 				mptsas_log(mpt, CE_WARN, "failed to copy out "
1188*c8f74a56SAda 				    "reply data for TM request");
1189*c8f74a56SAda 				break;
1190*c8f74a56SAda 			}
1191*c8f74a56SAda 		}
1192*c8f74a56SAda 		mutex_enter(&mpt->m_mutex);
1193*c8f74a56SAda 	}
1194*c8f74a56SAda 
11955b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
11965b504601Sjiang wu - Sun Microsystems - Beijing China 	 * clear the TM slot before returning
11975b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
11985b504601Sjiang wu - Sun Microsystems - Beijing China 	slots->m_slot[MPTSAS_TM_SLOT(mpt)] = NULL;
11995b504601Sjiang wu - Sun Microsystems - Beijing China 
12005b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
12015b504601Sjiang wu - Sun Microsystems - Beijing China 	 * If we lost our task management command
12025b504601Sjiang wu - Sun Microsystems - Beijing China 	 * we need to reset the ioc
12035b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
12045b504601Sjiang wu - Sun Microsystems - Beijing China 	if (rval == FALSE) {
12055b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "mptsas_ioc_task_management failed "
12065b504601Sjiang wu - Sun Microsystems - Beijing China 		    "try to reset ioc to recovery!");
12075b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_restart_ioc(mpt)) {
12085b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed");
12095b504601Sjiang wu - Sun Microsystems - Beijing China 			rval = FAILED;
12105b504601Sjiang wu - Sun Microsystems - Beijing China 		}
12115b504601Sjiang wu - Sun Microsystems - Beijing China 	}
12125b504601Sjiang wu - Sun Microsystems - Beijing China 
12135b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
12145b504601Sjiang wu - Sun Microsystems - Beijing China }
12155b504601Sjiang wu - Sun Microsystems - Beijing China 
12165b504601Sjiang wu - Sun Microsystems - Beijing China int
12175b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_update_flash(mptsas_t *mpt, caddr_t ptrbuffer, uint32_t size,
12185b504601Sjiang wu - Sun Microsystems - Beijing China     uint8_t type, int mode)
12195b504601Sjiang wu - Sun Microsystems - Beijing China {
12205b504601Sjiang wu - Sun Microsystems - Beijing China 
12215b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
12225b504601Sjiang wu - Sun Microsystems - Beijing China 	 * In order to avoid allocating variables on the stack,
12235b504601Sjiang wu - Sun Microsystems - Beijing China 	 * we make use of the pre-existing mptsas_cmd_t and
12245b504601Sjiang wu - Sun Microsystems - Beijing China 	 * scsi_pkt which are included in the mptsas_t which
12255b504601Sjiang wu - Sun Microsystems - Beijing China 	 * is passed to this routine.
12265b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
12275b504601Sjiang wu - Sun Microsystems - Beijing China 
12285b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_attr_t		flsh_dma_attrs;
12295b504601Sjiang wu - Sun Microsystems - Beijing China 	uint_t			flsh_ncookie;
12305b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_cookie_t	flsh_cookie;
12315b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_handle_t	flsh_dma_handle;
12325b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_acc_handle_t	flsh_accessp;
12335b504601Sjiang wu - Sun Microsystems - Beijing China 	size_t			flsh_alloc_len;
12345b504601Sjiang wu - Sun Microsystems - Beijing China 	caddr_t			memp, flsh_memp;
12355b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		flagslength;
12365b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2FWDownloadRequest	fwdownload;
12375b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2FWDownloadTCSGE_t	tcsge;
12385b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2SGESimple64_t	sge;
12395b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_cmd_t		*cmd;
12405b504601Sjiang wu - Sun Microsystems - Beijing China 	struct scsi_pkt		*pkt;
12415b504601Sjiang wu - Sun Microsystems - Beijing China 	int			i;
12425b504601Sjiang wu - Sun Microsystems - Beijing China 	int			rvalue = 0;
12435b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		request_desc_low;
12445b504601Sjiang wu - Sun Microsystems - Beijing China 
12455b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
12465b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "mptsas_update_flash(): allocation "
12475b504601Sjiang wu - Sun Microsystems - Beijing China 		    "failed. event ack command pool is full\n");
12485b504601Sjiang wu - Sun Microsystems - Beijing China 		return (rvalue);
12495b504601Sjiang wu - Sun Microsystems - Beijing China 	}
12505b504601Sjiang wu - Sun Microsystems - Beijing China 
12515b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero((caddr_t)cmd, sizeof (*cmd));
12525b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero((caddr_t)pkt, scsi_pkt_size());
12535b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->ioc_cmd_slot = (uint32_t)rvalue;
12545b504601Sjiang wu - Sun Microsystems - Beijing China 
12555b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
12565b504601Sjiang wu - Sun Microsystems - Beijing China 	 * dynamically create a customized dma attribute structure
12575b504601Sjiang wu - Sun Microsystems - Beijing China 	 * that describes the flash file.
12585b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
12595b504601Sjiang wu - Sun Microsystems - Beijing China 	flsh_dma_attrs = mpt->m_msg_dma_attr;
12605b504601Sjiang wu - Sun Microsystems - Beijing China 	flsh_dma_attrs.dma_attr_sgllen = 1;
12615b504601Sjiang wu - Sun Microsystems - Beijing China 
12625b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_alloc_handle(mpt->m_dip, &flsh_dma_attrs,
12635b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SLEEP, NULL, &flsh_dma_handle) != DDI_SUCCESS) {
12645b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN,
12655b504601Sjiang wu - Sun Microsystems - Beijing China 		    "(unable to allocate dma handle.");
12665b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_return_to_pool(mpt, cmd);
12675b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
12685b504601Sjiang wu - Sun Microsystems - Beijing China 	}
12695b504601Sjiang wu - Sun Microsystems - Beijing China 
12705b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_mem_alloc(flsh_dma_handle, size,
12715b504601Sjiang wu - Sun Microsystems - Beijing China 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
12725b504601Sjiang wu - Sun Microsystems - Beijing China 	    &flsh_memp, &flsh_alloc_len, &flsh_accessp) != DDI_SUCCESS) {
12735b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&flsh_dma_handle);
12745b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN,
12755b504601Sjiang wu - Sun Microsystems - Beijing China 		    "unable to allocate flash structure.");
12765b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_return_to_pool(mpt, cmd);
12775b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
12785b504601Sjiang wu - Sun Microsystems - Beijing China 	}
12795b504601Sjiang wu - Sun Microsystems - Beijing China 
12805b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_addr_bind_handle(flsh_dma_handle, NULL, flsh_memp,
12815b504601Sjiang wu - Sun Microsystems - Beijing China 	    flsh_alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
12825b504601Sjiang wu - Sun Microsystems - Beijing China 	    NULL, &flsh_cookie, &flsh_ncookie) != DDI_DMA_MAPPED) {
12835b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_mem_free(&flsh_accessp);
12845b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&flsh_dma_handle);
12855b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "unable to bind DMA resources.");
12865b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_return_to_pool(mpt, cmd);
12875b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
12885b504601Sjiang wu - Sun Microsystems - Beijing China 	}
12895b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(flsh_memp, size);
12905b504601Sjiang wu - Sun Microsystems - Beijing China 
12915b504601Sjiang wu - Sun Microsystems - Beijing China 	for (i = 0; i < size; i++) {
12925b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_copyin(ptrbuffer + i, flsh_memp + i, 1, mode);
12935b504601Sjiang wu - Sun Microsystems - Beijing China 	}
12945b504601Sjiang wu - Sun Microsystems - Beijing China 	(void) ddi_dma_sync(flsh_dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV);
12955b504601Sjiang wu - Sun Microsystems - Beijing China 
12965b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
12975b504601Sjiang wu - Sun Microsystems - Beijing China 	 * form a cmd/pkt to store the fw download message
12985b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
12995b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_cdbp		= (opaque_t)&cmd->cmd_cdb[0];
13005b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_scbp		= (opaque_t)&cmd->cmd_scb;
13015b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_ha_private	= (opaque_t)cmd;
13025b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_flags		= FLAG_HEAD;
13035b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_time		= 60;
13045b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_pkt		= pkt;
13055b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_scblen		= 1;
13065b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_flags		= CFLAG_CMDIOC | CFLAG_FW_CMD;
13075b504601Sjiang wu - Sun Microsystems - Beijing China 
13085b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
13095b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Save the command in a slot
13105b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
13115b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_save_cmd(mpt, cmd) == FALSE) {
13125b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_unbind_handle(flsh_dma_handle);
13135b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_mem_free(&flsh_accessp);
13145b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&flsh_dma_handle);
13155b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_return_to_pool(mpt, cmd);
13165b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
13175b504601Sjiang wu - Sun Microsystems - Beijing China 	}
13185b504601Sjiang wu - Sun Microsystems - Beijing China 
13195b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
13205b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Fill in fw download message
13215b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
13225b504601Sjiang wu - Sun Microsystems - Beijing China 	ASSERT(cmd->cmd_slot != 0);
13235b504601Sjiang wu - Sun Microsystems - Beijing China 	memp = mpt->m_req_frame + (mpt->m_req_frame_size * cmd->cmd_slot);
13245b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(memp, mpt->m_req_frame_size);
13255b504601Sjiang wu - Sun Microsystems - Beijing China 	fwdownload = (void *)memp;
13265b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &fwdownload->Function,
13275b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_FUNCTION_FW_DOWNLOAD);
13285b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &fwdownload->ImageType, type);
13295b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &fwdownload->MsgFlags,
13305b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT);
13315b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_acc_req_frame_hdl, &fwdownload->TotalImageSize, size);
13325b504601Sjiang wu - Sun Microsystems - Beijing China 
13335b504601Sjiang wu - Sun Microsystems - Beijing China 	tcsge = (pMpi2FWDownloadTCSGE_t)&fwdownload->SGL;
13345b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &tcsge->ContextSize, 0);
13355b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &tcsge->DetailsLength, 12);
13365b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &tcsge->Flags, 0);
13375b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_acc_req_frame_hdl, &tcsge->ImageOffset, 0);
13385b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_acc_req_frame_hdl, &tcsge->ImageSize, size);
13395b504601Sjiang wu - Sun Microsystems - Beijing China 
13405b504601Sjiang wu - Sun Microsystems - Beijing China 	sge = (pMpi2SGESimple64_t)(tcsge + 1);
13415b504601Sjiang wu - Sun Microsystems - Beijing China 	flagslength = size;
13425b504601Sjiang wu - Sun Microsystems - Beijing China 	flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT |
13435b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_END_OF_BUFFER |
13445b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
13455b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
13465b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_64_BIT_ADDRESSING |
13475b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_HOST_TO_IOC |
13485b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
13495b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_acc_req_frame_hdl, &sge->FlagsLength, flagslength);
13505b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.Low,
13515b504601Sjiang wu - Sun Microsystems - Beijing China 	    flsh_cookie.dmac_address);
13525b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.High,
13535b504601Sjiang wu - Sun Microsystems - Beijing China 	    (uint32_t)(flsh_cookie.dmac_laddress >> 32));
13545b504601Sjiang wu - Sun Microsystems - Beijing China 
13555b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
13565b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Start command
13575b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
13585b504601Sjiang wu - Sun Microsystems - Beijing China 	(void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0,
13595b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SYNC_FORDEV);
13605b504601Sjiang wu - Sun Microsystems - Beijing China 	request_desc_low = (cmd->cmd_slot << 16) +
13615b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
13625b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_rfm = NULL;
13635b504601Sjiang wu - Sun Microsystems - Beijing China 	MPTSAS_START_CMD(mpt, request_desc_low, 0);
13645b504601Sjiang wu - Sun Microsystems - Beijing China 
13655b504601Sjiang wu - Sun Microsystems - Beijing China 	rvalue = 0;
1366d3d50737SRafael Vanoni 	(void) cv_reltimedwait(&mpt->m_fw_cv, &mpt->m_mutex,
1367d3d50737SRafael Vanoni 	    drv_usectohz(60 * MICROSEC), TR_CLOCK_TICK);
13685b504601Sjiang wu - Sun Microsystems - Beijing China 	if (!(cmd->cmd_flags & CFLAG_FINISHED)) {
13695b504601Sjiang wu - Sun Microsystems - Beijing China 		if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
13705b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed");
13715b504601Sjiang wu - Sun Microsystems - Beijing China 		}
13725b504601Sjiang wu - Sun Microsystems - Beijing China 		rvalue = -1;
13735b504601Sjiang wu - Sun Microsystems - Beijing China 	}
13745b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_remove_cmd(mpt, cmd);
13755b504601Sjiang wu - Sun Microsystems - Beijing China 
13765b504601Sjiang wu - Sun Microsystems - Beijing China 	(void) ddi_dma_unbind_handle(flsh_dma_handle);
13775b504601Sjiang wu - Sun Microsystems - Beijing China 	(void) ddi_dma_mem_free(&flsh_accessp);
13785b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_free_handle(&flsh_dma_handle);
13795b504601Sjiang wu - Sun Microsystems - Beijing China 
13805b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rvalue);
13815b504601Sjiang wu - Sun Microsystems - Beijing China }
13825b504601Sjiang wu - Sun Microsystems - Beijing China 
13835b504601Sjiang wu - Sun Microsystems - Beijing China static int
13845b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_sasdevpage_0_cb(mptsas_t *mpt, caddr_t page_memp,
13855b504601Sjiang wu - Sun Microsystems - Beijing China     ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo,
13865b504601Sjiang wu - Sun Microsystems - Beijing China     va_list ap)
13875b504601Sjiang wu - Sun Microsystems - Beijing China {
13885b504601Sjiang wu - Sun Microsystems - Beijing China #ifndef __lock_lint
13895b504601Sjiang wu - Sun Microsystems - Beijing China 	_NOTE(ARGUNUSED(ap))
13905b504601Sjiang wu - Sun Microsystems - Beijing China #endif
13915b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2SasDevicePage0_t	sasdevpage;
13925b504601Sjiang wu - Sun Microsystems - Beijing China 	int			rval = DDI_SUCCESS, i;
13935b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t			*sas_addr = NULL;
13945b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t			tmp_sas_wwn[SAS_WWN_BYTE_SIZE];
13955b504601Sjiang wu - Sun Microsystems - Beijing China 	uint16_t		*devhdl;
13965b504601Sjiang wu - Sun Microsystems - Beijing China 	uint64_t		*sas_wwn;
13975b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		*dev_info;
13985b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t			*physport, *phynum;
13995b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		page_address;
14005b504601Sjiang wu - Sun Microsystems - Beijing China 
14015b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) &&
14025b504601Sjiang wu - Sun Microsystems - Beijing China 	    (iocstatus != MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)) {
14035b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "mptsas_get_sas_device_page0 "
14045b504601Sjiang wu - Sun Microsystems - Beijing China 		    "header: IOCStatus=0x%x, IOCLogInfo=0x%x",
14055b504601Sjiang wu - Sun Microsystems - Beijing China 		    iocstatus, iocloginfo);
14065b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
14075b504601Sjiang wu - Sun Microsystems - Beijing China 		return (rval);
14085b504601Sjiang wu - Sun Microsystems - Beijing China 	}
14095b504601Sjiang wu - Sun Microsystems - Beijing China 	page_address = va_arg(ap, uint32_t);
14105b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
14115b504601Sjiang wu - Sun Microsystems - Beijing China 	 * The INVALID_PAGE status is normal if using GET_NEXT_HANDLE and there
14125b504601Sjiang wu - Sun Microsystems - Beijing China 	 * are no more pages.  If everything is OK up to this point but the
14135b504601Sjiang wu - Sun Microsystems - Beijing China 	 * status is INVALID_PAGE, change rval to FAILURE and quit.  Also,
14145b504601Sjiang wu - Sun Microsystems - Beijing China 	 * signal that device traversal is complete.
14155b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
14165b504601Sjiang wu - Sun Microsystems - Beijing China 	if (iocstatus == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) {
14175b504601Sjiang wu - Sun Microsystems - Beijing China 		if ((page_address & MPI2_SAS_DEVICE_PGAD_FORM_MASK) ==
14185b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE) {
14195b504601Sjiang wu - Sun Microsystems - Beijing China 			mpt->m_done_traverse_dev = 1;
14205b504601Sjiang wu - Sun Microsystems - Beijing China 		}
14215b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
14225b504601Sjiang wu - Sun Microsystems - Beijing China 		return (rval);
14235b504601Sjiang wu - Sun Microsystems - Beijing China 	}
14245b504601Sjiang wu - Sun Microsystems - Beijing China 	devhdl = va_arg(ap, uint16_t *);
14255b504601Sjiang wu - Sun Microsystems - Beijing China 	sas_wwn = va_arg(ap, uint64_t *);
14265b504601Sjiang wu - Sun Microsystems - Beijing China 	dev_info = va_arg(ap, uint32_t *);
14275b504601Sjiang wu - Sun Microsystems - Beijing China 	physport = va_arg(ap, uint8_t *);
14285b504601Sjiang wu - Sun Microsystems - Beijing China 	phynum = va_arg(ap, uint8_t *);
14295b504601Sjiang wu - Sun Microsystems - Beijing China 
14305b504601Sjiang wu - Sun Microsystems - Beijing China 	sasdevpage = (pMpi2SasDevicePage0_t)page_memp;
14315b504601Sjiang wu - Sun Microsystems - Beijing China 
14325b504601Sjiang wu - Sun Microsystems - Beijing China 	*dev_info = ddi_get32(accessp, &sasdevpage->DeviceInfo);
14335b504601Sjiang wu - Sun Microsystems - Beijing China 	*devhdl = ddi_get16(accessp, &sasdevpage->DevHandle);
14345b504601Sjiang wu - Sun Microsystems - Beijing China 	sas_addr = (uint8_t *)(&sasdevpage->SASAddress);
14355b504601Sjiang wu - Sun Microsystems - Beijing China 	for (i = 0; i < SAS_WWN_BYTE_SIZE; i++) {
14365b504601Sjiang wu - Sun Microsystems - Beijing China 		tmp_sas_wwn[i] = ddi_get8(accessp, sas_addr + i);
14375b504601Sjiang wu - Sun Microsystems - Beijing China 	}
14385b504601Sjiang wu - Sun Microsystems - Beijing China 	bcopy(tmp_sas_wwn, sas_wwn, SAS_WWN_BYTE_SIZE);
14395b504601Sjiang wu - Sun Microsystems - Beijing China 	*sas_wwn = LE_64(*sas_wwn);
14405b504601Sjiang wu - Sun Microsystems - Beijing China 	*physport = ddi_get8(accessp, &sasdevpage->PhysicalPort);
14415b504601Sjiang wu - Sun Microsystems - Beijing China 	*phynum = ddi_get8(accessp, &sasdevpage->PhyNum);
14425b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
14435b504601Sjiang wu - Sun Microsystems - Beijing China }
14445b504601Sjiang wu - Sun Microsystems - Beijing China 
14455b504601Sjiang wu - Sun Microsystems - Beijing China /*
14465b504601Sjiang wu - Sun Microsystems - Beijing China  * Request MPI configuration page SAS device page 0 to get DevHandle, device
14475b504601Sjiang wu - Sun Microsystems - Beijing China  * info and SAS address.
14485b504601Sjiang wu - Sun Microsystems - Beijing China  */
14495b504601Sjiang wu - Sun Microsystems - Beijing China int
14505b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_sas_device_page0(mptsas_t *mpt, uint32_t page_address,
14515b504601Sjiang wu - Sun Microsystems - Beijing China     uint16_t *dev_handle, uint64_t *sas_wwn, uint32_t *dev_info,
14525b504601Sjiang wu - Sun Microsystems - Beijing China     uint8_t *physport, uint8_t *phynum)
14535b504601Sjiang wu - Sun Microsystems - Beijing China {
14545b504601Sjiang wu - Sun Microsystems - Beijing China 	int rval = DDI_SUCCESS;
14555b504601Sjiang wu - Sun Microsystems - Beijing China 
14565b504601Sjiang wu - Sun Microsystems - Beijing China 	ASSERT(mutex_owned(&mpt->m_mutex));
14575b504601Sjiang wu - Sun Microsystems - Beijing China 
14585b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
14595b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Get the header and config page.  reply contains the reply frame,
14605b504601Sjiang wu - Sun Microsystems - Beijing China 	 * which holds status info for the request.
14615b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
14625b504601Sjiang wu - Sun Microsystems - Beijing China 	rval = mptsas_access_config_page(mpt,
14635b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_CONFIG_ACTION_PAGE_READ_CURRENT,
14645b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE, 0, page_address,
14655b504601Sjiang wu - Sun Microsystems - Beijing China 	    mptsas_sasdevpage_0_cb, page_address, dev_handle, sas_wwn,
14665b504601Sjiang wu - Sun Microsystems - Beijing China 	    dev_info, physport, phynum);
14675b504601Sjiang wu - Sun Microsystems - Beijing China 
14685b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
14695b504601Sjiang wu - Sun Microsystems - Beijing China }
14705b504601Sjiang wu - Sun Microsystems - Beijing China 
14715b504601Sjiang wu - Sun Microsystems - Beijing China static int
14725b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_sasexpdpage_0_cb(mptsas_t *mpt, caddr_t page_memp,
14735b504601Sjiang wu - Sun Microsystems - Beijing China     ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo,
14745b504601Sjiang wu - Sun Microsystems - Beijing China     va_list ap)
14755b504601Sjiang wu - Sun Microsystems - Beijing China {
14765b504601Sjiang wu - Sun Microsystems - Beijing China #ifndef __lock_lint
14775b504601Sjiang wu - Sun Microsystems - Beijing China 	_NOTE(ARGUNUSED(ap))
14785b504601Sjiang wu - Sun Microsystems - Beijing China #endif
14795b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2ExpanderPage0_t	expddevpage;
14805b504601Sjiang wu - Sun Microsystems - Beijing China 	int			rval = DDI_SUCCESS, i;
14815b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t			*sas_addr = NULL;
14825b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t			tmp_sas_wwn[SAS_WWN_BYTE_SIZE];
14835b504601Sjiang wu - Sun Microsystems - Beijing China 	uint16_t		*devhdl;
14845b504601Sjiang wu - Sun Microsystems - Beijing China 	uint64_t		*sas_wwn;
14855b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t			physport, *phymask;
14865b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		page_address;
14875b504601Sjiang wu - Sun Microsystems - Beijing China 
14885b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) &&
14895b504601Sjiang wu - Sun Microsystems - Beijing China 	    (iocstatus != MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)) {
14905b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "mptsas_get_sas_expander_page0 "
14915b504601Sjiang wu - Sun Microsystems - Beijing China 		    "config: IOCStatus=0x%x, IOCLogInfo=0x%x",
14925b504601Sjiang wu - Sun Microsystems - Beijing China 		    iocstatus, iocloginfo);
14935b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
14945b504601Sjiang wu - Sun Microsystems - Beijing China 		return (rval);
14955b504601Sjiang wu - Sun Microsystems - Beijing China 	}
14965b504601Sjiang wu - Sun Microsystems - Beijing China 	page_address = va_arg(ap, uint32_t);
14975b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
14985b504601Sjiang wu - Sun Microsystems - Beijing China 	 * The INVALID_PAGE status is normal if using GET_NEXT_HANDLE and there
14995b504601Sjiang wu - Sun Microsystems - Beijing China 	 * are no more pages.  If everything is OK up to this point but the
15005b504601Sjiang wu - Sun Microsystems - Beijing China 	 * status is INVALID_PAGE, change rval to FAILURE and quit.  Also,
15015b504601Sjiang wu - Sun Microsystems - Beijing China 	 * signal that device traversal is complete.
15025b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
15035b504601Sjiang wu - Sun Microsystems - Beijing China 	if (iocstatus == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) {
15045b504601Sjiang wu - Sun Microsystems - Beijing China 		if ((page_address & MPI2_SAS_EXPAND_PGAD_FORM_MASK) ==
15055b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL) {
15065b504601Sjiang wu - Sun Microsystems - Beijing China 			mpt->m_done_traverse_smp = 1;
15075b504601Sjiang wu - Sun Microsystems - Beijing China 		}
15085b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
15095b504601Sjiang wu - Sun Microsystems - Beijing China 		return (rval);
15105b504601Sjiang wu - Sun Microsystems - Beijing China 	}
15115b504601Sjiang wu - Sun Microsystems - Beijing China 	devhdl = va_arg(ap, uint16_t *);
15125b504601Sjiang wu - Sun Microsystems - Beijing China 	sas_wwn = va_arg(ap, uint64_t *);
15135b504601Sjiang wu - Sun Microsystems - Beijing China 	phymask = va_arg(ap, uint8_t *);
15145b504601Sjiang wu - Sun Microsystems - Beijing China 
15155b504601Sjiang wu - Sun Microsystems - Beijing China 	expddevpage = (pMpi2ExpanderPage0_t)page_memp;
15165b504601Sjiang wu - Sun Microsystems - Beijing China 
15175b504601Sjiang wu - Sun Microsystems - Beijing China 	*devhdl = ddi_get16(accessp, &expddevpage->DevHandle);
15185b504601Sjiang wu - Sun Microsystems - Beijing China 	physport = ddi_get8(accessp, &expddevpage->PhysicalPort);
15195b504601Sjiang wu - Sun Microsystems - Beijing China 	*phymask = mptsas_physport_to_phymask(mpt, physport);
15205b504601Sjiang wu - Sun Microsystems - Beijing China 	sas_addr = (uint8_t *)(&expddevpage->SASAddress);
15215b504601Sjiang wu - Sun Microsystems - Beijing China 	for (i = 0; i < SAS_WWN_BYTE_SIZE; i++) {
15225b504601Sjiang wu - Sun Microsystems - Beijing China 		tmp_sas_wwn[i] = ddi_get8(accessp, sas_addr + i);
15235b504601Sjiang wu - Sun Microsystems - Beijing China 	}
15245b504601Sjiang wu - Sun Microsystems - Beijing China 	bcopy(tmp_sas_wwn, sas_wwn, SAS_WWN_BYTE_SIZE);
15255b504601Sjiang wu - Sun Microsystems - Beijing China 	*sas_wwn = LE_64(*sas_wwn);
15265b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
15275b504601Sjiang wu - Sun Microsystems - Beijing China }
15285b504601Sjiang wu - Sun Microsystems - Beijing China 
15295b504601Sjiang wu - Sun Microsystems - Beijing China /*
15305b504601Sjiang wu - Sun Microsystems - Beijing China  * Request MPI configuration page SAS device page 0 to get DevHandle, phymask
15315b504601Sjiang wu - Sun Microsystems - Beijing China  * and SAS address.
15325b504601Sjiang wu - Sun Microsystems - Beijing China  */
15335b504601Sjiang wu - Sun Microsystems - Beijing China int
15345b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_sas_expander_page0(mptsas_t *mpt, uint32_t page_address,
15355b504601Sjiang wu - Sun Microsystems - Beijing China     mptsas_smp_t *info)
15365b504601Sjiang wu - Sun Microsystems - Beijing China {
15375b504601Sjiang wu - Sun Microsystems - Beijing China 	int			rval = DDI_SUCCESS;
15385b504601Sjiang wu - Sun Microsystems - Beijing China 
15395b504601Sjiang wu - Sun Microsystems - Beijing China 	ASSERT(mutex_owned(&mpt->m_mutex));
15405b504601Sjiang wu - Sun Microsystems - Beijing China 
15415b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
15425b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Get the header and config page.  reply contains the reply frame,
15435b504601Sjiang wu - Sun Microsystems - Beijing China 	 * which holds status info for the request.
15445b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
15455b504601Sjiang wu - Sun Microsystems - Beijing China 	rval = mptsas_access_config_page(mpt,
15465b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_CONFIG_ACTION_PAGE_READ_CURRENT,
15475b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER, 0, page_address,
15485b504601Sjiang wu - Sun Microsystems - Beijing China 	    mptsas_sasexpdpage_0_cb, page_address, &info->m_devhdl,
15495b504601Sjiang wu - Sun Microsystems - Beijing China 	    &info->m_sasaddr, &info->m_phymask);
15505b504601Sjiang wu - Sun Microsystems - Beijing China 
15515b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
15525b504601Sjiang wu - Sun Microsystems - Beijing China }
15535b504601Sjiang wu - Sun Microsystems - Beijing China 
15545b504601Sjiang wu - Sun Microsystems - Beijing China static int
15555b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_sasportpage_0_cb(mptsas_t *mpt, caddr_t page_memp,
15565b504601Sjiang wu - Sun Microsystems - Beijing China     ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo,
15575b504601Sjiang wu - Sun Microsystems - Beijing China     va_list ap)
15585b504601Sjiang wu - Sun Microsystems - Beijing China {
15595b504601Sjiang wu - Sun Microsystems - Beijing China #ifndef __lock_lint
15605b504601Sjiang wu - Sun Microsystems - Beijing China 	_NOTE(ARGUNUSED(ap))
15615b504601Sjiang wu - Sun Microsystems - Beijing China #endif
15625b504601Sjiang wu - Sun Microsystems - Beijing China 	int	rval = DDI_SUCCESS, i;
15635b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t	*sas_addr = NULL;
15645b504601Sjiang wu - Sun Microsystems - Beijing China 	uint64_t *sas_wwn;
15655b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t	tmp_sas_wwn[SAS_WWN_BYTE_SIZE];
15665b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t *portwidth;
15675b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2SasPortPage0_t sasportpage;
15685b504601Sjiang wu - Sun Microsystems - Beijing China 
15695b504601Sjiang wu - Sun Microsystems - Beijing China 	if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
15705b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "mptsas_get_sas_port_page0 "
15715b504601Sjiang wu - Sun Microsystems - Beijing China 		    "config: IOCStatus=0x%x, IOCLogInfo=0x%x",
15725b504601Sjiang wu - Sun Microsystems - Beijing China 		    iocstatus, iocloginfo);
15735b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
15745b504601Sjiang wu - Sun Microsystems - Beijing China 		return (rval);
15755b504601Sjiang wu - Sun Microsystems - Beijing China 	}
15765b504601Sjiang wu - Sun Microsystems - Beijing China 	sas_wwn = va_arg(ap, uint64_t *);
15775b504601Sjiang wu - Sun Microsystems - Beijing China 	portwidth = va_arg(ap, uint8_t *);
15785b504601Sjiang wu - Sun Microsystems - Beijing China 
15795b504601Sjiang wu - Sun Microsystems - Beijing China 	sasportpage = (pMpi2SasPortPage0_t)page_memp;
15805b504601Sjiang wu - Sun Microsystems - Beijing China 	sas_addr = (uint8_t *)(&sasportpage->SASAddress);
15815b504601Sjiang wu - Sun Microsystems - Beijing China 	for (i = 0; i < SAS_WWN_BYTE_SIZE; i++) {
15825b504601Sjiang wu - Sun Microsystems - Beijing China 		tmp_sas_wwn[i] = ddi_get8(accessp, sas_addr + i);
15835b504601Sjiang wu - Sun Microsystems - Beijing China 	}
15845b504601Sjiang wu - Sun Microsystems - Beijing China 	bcopy(tmp_sas_wwn, sas_wwn, SAS_WWN_BYTE_SIZE);
15855b504601Sjiang wu - Sun Microsystems - Beijing China 	*sas_wwn = LE_64(*sas_wwn);
15865b504601Sjiang wu - Sun Microsystems - Beijing China 	*portwidth = ddi_get8(accessp, &sasportpage->PortWidth);
15875b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
15885b504601Sjiang wu - Sun Microsystems - Beijing China }
15895b504601Sjiang wu - Sun Microsystems - Beijing China 
15905b504601Sjiang wu - Sun Microsystems - Beijing China /*
15915b504601Sjiang wu - Sun Microsystems - Beijing China  * Request MPI configuration page SAS port page 0 to get initiator SAS address
15925b504601Sjiang wu - Sun Microsystems - Beijing China  * and port width.
15935b504601Sjiang wu - Sun Microsystems - Beijing China  */
15945b504601Sjiang wu - Sun Microsystems - Beijing China int
15955b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_sas_port_page0(mptsas_t *mpt, uint32_t page_address,
15965b504601Sjiang wu - Sun Microsystems - Beijing China     uint64_t *sas_wwn, uint8_t *portwidth)
15975b504601Sjiang wu - Sun Microsystems - Beijing China {
15985b504601Sjiang wu - Sun Microsystems - Beijing China 	int rval = DDI_SUCCESS;
15995b504601Sjiang wu - Sun Microsystems - Beijing China 
16005b504601Sjiang wu - Sun Microsystems - Beijing China 	ASSERT(mutex_owned(&mpt->m_mutex));
16015b504601Sjiang wu - Sun Microsystems - Beijing China 
16025b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
16035b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Get the header and config page.  reply contains the reply frame,
16045b504601Sjiang wu - Sun Microsystems - Beijing China 	 * which holds status info for the request.
16055b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
16065b504601Sjiang wu - Sun Microsystems - Beijing China 	rval = mptsas_access_config_page(mpt,
16075b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_CONFIG_ACTION_PAGE_READ_CURRENT,
16085b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_CONFIG_EXTPAGETYPE_SAS_PORT, 0, page_address,
16095b504601Sjiang wu - Sun Microsystems - Beijing China 	    mptsas_sasportpage_0_cb, sas_wwn, portwidth);
16105b504601Sjiang wu - Sun Microsystems - Beijing China 
16115b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
16125b504601Sjiang wu - Sun Microsystems - Beijing China }
16135b504601Sjiang wu - Sun Microsystems - Beijing China 
16145b504601Sjiang wu - Sun Microsystems - Beijing China static int
16155b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_sasiou_page_0_cb(mptsas_t *mpt, caddr_t page_memp,
16165b504601Sjiang wu - Sun Microsystems - Beijing China     ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo,
16175b504601Sjiang wu - Sun Microsystems - Beijing China     va_list ap)
16185b504601Sjiang wu - Sun Microsystems - Beijing China {
16195b504601Sjiang wu - Sun Microsystems - Beijing China #ifndef __lock_lint
16205b504601Sjiang wu - Sun Microsystems - Beijing China 	_NOTE(ARGUNUSED(ap))
16215b504601Sjiang wu - Sun Microsystems - Beijing China #endif
16225b504601Sjiang wu - Sun Microsystems - Beijing China 	int rval = DDI_SUCCESS;
16235b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2SasIOUnitPage0_t sasioupage0;
16245b504601Sjiang wu - Sun Microsystems - Beijing China 	int i, num_phys;
16255b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t cpdi[8], *retrypage0, *readpage1;
16265b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t port_flags;
16275b504601Sjiang wu - Sun Microsystems - Beijing China 
16285b504601Sjiang wu - Sun Microsystems - Beijing China 	if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
16295b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "mptsas_get_sas_io_unit_page0 "
16305b504601Sjiang wu - Sun Microsystems - Beijing China 		    "config: IOCStatus=0x%x, IOCLogInfo=0x%x",
16315b504601Sjiang wu - Sun Microsystems - Beijing China 		    iocstatus, iocloginfo);
16325b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
16335b504601Sjiang wu - Sun Microsystems - Beijing China 		return (rval);
16345b504601Sjiang wu - Sun Microsystems - Beijing China 	}
16355b504601Sjiang wu - Sun Microsystems - Beijing China 	readpage1 = va_arg(ap, uint32_t *);
16365b504601Sjiang wu - Sun Microsystems - Beijing China 	retrypage0 = va_arg(ap, uint32_t *);
16375b504601Sjiang wu - Sun Microsystems - Beijing China 
16385b504601Sjiang wu - Sun Microsystems - Beijing China 	sasioupage0 = (pMpi2SasIOUnitPage0_t)page_memp;
16395b504601Sjiang wu - Sun Microsystems - Beijing China 
16405b504601Sjiang wu - Sun Microsystems - Beijing China 	num_phys = ddi_get8(accessp, &sasioupage0->NumPhys);
16415b504601Sjiang wu - Sun Microsystems - Beijing China 	for (i = 0; i < num_phys; i++) {
16425b504601Sjiang wu - Sun Microsystems - Beijing China 		cpdi[i] = ddi_get32(accessp,
16435b504601Sjiang wu - Sun Microsystems - Beijing China 		    &sasioupage0->PhyData[i].
16445b504601Sjiang wu - Sun Microsystems - Beijing China 		    ControllerPhyDeviceInfo);
16455b504601Sjiang wu - Sun Microsystems - Beijing China 		port_flags = ddi_get8(accessp,
16465b504601Sjiang wu - Sun Microsystems - Beijing China 		    &sasioupage0->PhyData[i].PortFlags);
16475b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_phy_info[i].port_num =
16485b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get8(accessp,
16495b504601Sjiang wu - Sun Microsystems - Beijing China 		    &sasioupage0->PhyData[i].Port);
16505b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_phy_info[i].ctrl_devhdl =
16515b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get16(accessp, &sasioupage0->
16525b504601Sjiang wu - Sun Microsystems - Beijing China 		    PhyData[i].ControllerDevHandle);
16535b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_phy_info[i].attached_devhdl =
16545b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get16(accessp, &sasioupage0->
16555b504601Sjiang wu - Sun Microsystems - Beijing China 		    PhyData[i].AttachedDevHandle);
16565b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_phy_info[i].phy_device_type = cpdi[i];
16575b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_phy_info[i].port_flags = port_flags;
16585b504601Sjiang wu - Sun Microsystems - Beijing China 
16595b504601Sjiang wu - Sun Microsystems - Beijing China 		if (port_flags & DISCOVERY_IN_PROGRESS) {
16605b504601Sjiang wu - Sun Microsystems - Beijing China 			*retrypage0 = *retrypage0 + 1;
16615b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
16625b504601Sjiang wu - Sun Microsystems - Beijing China 		} else {
16635b504601Sjiang wu - Sun Microsystems - Beijing China 			*retrypage0 = 0;
16645b504601Sjiang wu - Sun Microsystems - Beijing China 		}
16655b504601Sjiang wu - Sun Microsystems - Beijing China 		if (!(port_flags & AUTO_PORT_CONFIGURATION)) {
16665b504601Sjiang wu - Sun Microsystems - Beijing China 			/*
16675b504601Sjiang wu - Sun Microsystems - Beijing China 			 * some PHY configuration described in
16685b504601Sjiang wu - Sun Microsystems - Beijing China 			 * SAS IO Unit Page1
16695b504601Sjiang wu - Sun Microsystems - Beijing China 			 */
16705b504601Sjiang wu - Sun Microsystems - Beijing China 			*readpage1 = 1;
16715b504601Sjiang wu - Sun Microsystems - Beijing China 		}
16725b504601Sjiang wu - Sun Microsystems - Beijing China 	}
16735b504601Sjiang wu - Sun Microsystems - Beijing China 
16745b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
16755b504601Sjiang wu - Sun Microsystems - Beijing China }
16765b504601Sjiang wu - Sun Microsystems - Beijing China 
16775b504601Sjiang wu - Sun Microsystems - Beijing China static int
16785b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_sasiou_page_1_cb(mptsas_t *mpt, caddr_t page_memp,
16795b504601Sjiang wu - Sun Microsystems - Beijing China     ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo,
16805b504601Sjiang wu - Sun Microsystems - Beijing China     va_list ap)
16815b504601Sjiang wu - Sun Microsystems - Beijing China {
16825b504601Sjiang wu - Sun Microsystems - Beijing China #ifndef __lock_lint
16835b504601Sjiang wu - Sun Microsystems - Beijing China 	_NOTE(ARGUNUSED(ap))
16845b504601Sjiang wu - Sun Microsystems - Beijing China #endif
16855b504601Sjiang wu - Sun Microsystems - Beijing China 	int rval = DDI_SUCCESS;
16865b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2SasIOUnitPage1_t sasioupage1;
16875b504601Sjiang wu - Sun Microsystems - Beijing China 	int i, num_phys;
16885b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t cpdi[8];
16895b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t port_flags;
16905b504601Sjiang wu - Sun Microsystems - Beijing China 
16915b504601Sjiang wu - Sun Microsystems - Beijing China 	if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
16925b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "mptsas_get_sas_io_unit_page1 "
16935b504601Sjiang wu - Sun Microsystems - Beijing China 		    "config: IOCStatus=0x%x, IOCLogInfo=0x%x",
16945b504601Sjiang wu - Sun Microsystems - Beijing China 		    iocstatus, iocloginfo);
16955b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
16965b504601Sjiang wu - Sun Microsystems - Beijing China 		return (rval);
16975b504601Sjiang wu - Sun Microsystems - Beijing China 	}
16985b504601Sjiang wu - Sun Microsystems - Beijing China 
16995b504601Sjiang wu - Sun Microsystems - Beijing China 	sasioupage1 = (pMpi2SasIOUnitPage1_t)page_memp;
17005b504601Sjiang wu - Sun Microsystems - Beijing China 	num_phys = ddi_get8(accessp, &sasioupage1->NumPhys);
17015b504601Sjiang wu - Sun Microsystems - Beijing China 	for (i = 0; i < num_phys; i++) {
17025b504601Sjiang wu - Sun Microsystems - Beijing China 		cpdi[i] = ddi_get32(accessp, &sasioupage1->PhyData[i].
17035b504601Sjiang wu - Sun Microsystems - Beijing China 		    ControllerPhyDeviceInfo);
17045b504601Sjiang wu - Sun Microsystems - Beijing China 		port_flags = ddi_get8(accessp,
17055b504601Sjiang wu - Sun Microsystems - Beijing China 		    &sasioupage1->PhyData[i].PortFlags);
17065b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_phy_info[i].port_num =
17075b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get8(accessp,
17085b504601Sjiang wu - Sun Microsystems - Beijing China 		    &sasioupage1->PhyData[i].Port);
17095b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_phy_info[i].port_flags = port_flags;
17105b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_phy_info[i].phy_device_type = cpdi[i];
17115b504601Sjiang wu - Sun Microsystems - Beijing China 
17125b504601Sjiang wu - Sun Microsystems - Beijing China 	}
17135b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
17145b504601Sjiang wu - Sun Microsystems - Beijing China }
17155b504601Sjiang wu - Sun Microsystems - Beijing China 
17165b504601Sjiang wu - Sun Microsystems - Beijing China /*
17175b504601Sjiang wu - Sun Microsystems - Beijing China  * Read IO unit page 0 to get information for each PHY. If needed, Read IO Unit
17185b504601Sjiang wu - Sun Microsystems - Beijing China  * page1 to update the PHY information.  This is the message passing method of
17195b504601Sjiang wu - Sun Microsystems - Beijing China  * this function which should be called except during initialization.
17205b504601Sjiang wu - Sun Microsystems - Beijing China  */
17215b504601Sjiang wu - Sun Microsystems - Beijing China int
17225b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_sas_io_unit_page(mptsas_t *mpt)
17235b504601Sjiang wu - Sun Microsystems - Beijing China {
17245b504601Sjiang wu - Sun Microsystems - Beijing China 	int rval = DDI_SUCCESS, state;
17255b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t readpage1 = 0, retrypage0 = 0;
17265b504601Sjiang wu - Sun Microsystems - Beijing China 
17275b504601Sjiang wu - Sun Microsystems - Beijing China 	ASSERT(mutex_owned(&mpt->m_mutex));
17285b504601Sjiang wu - Sun Microsystems - Beijing China 
17295b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
17305b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Now we cycle through the state machine.  Here's what happens:
17315b504601Sjiang wu - Sun Microsystems - Beijing China 	 * 1. Read IO unit page 0 and set phy information
17325b504601Sjiang wu - Sun Microsystems - Beijing China 	 * 2. See if Read IO unit page1 is needed because of port configuration
17335b504601Sjiang wu - Sun Microsystems - Beijing China 	 * 3. Read IO unit page 1 and update phy information.
17345b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
17355b504601Sjiang wu - Sun Microsystems - Beijing China 	state = IOUC_READ_PAGE0;
17365b504601Sjiang wu - Sun Microsystems - Beijing China 	while (state != IOUC_DONE) {
17375b504601Sjiang wu - Sun Microsystems - Beijing China 		if (state == IOUC_READ_PAGE0) {
17385b504601Sjiang wu - Sun Microsystems - Beijing China 			rval = mptsas_access_config_page(mpt,
17395b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_CONFIG_ACTION_PAGE_READ_CURRENT,
17405b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 0, 0,
17415b504601Sjiang wu - Sun Microsystems - Beijing China 			    mptsas_sasiou_page_0_cb, &readpage1,
17425b504601Sjiang wu - Sun Microsystems - Beijing China 			    &retrypage0);
17435b504601Sjiang wu - Sun Microsystems - Beijing China 		} else if (state == IOUC_READ_PAGE1) {
17445b504601Sjiang wu - Sun Microsystems - Beijing China 			rval = mptsas_access_config_page(mpt,
17455b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_CONFIG_ACTION_PAGE_READ_CURRENT,
17465b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 1, 0,
17475b504601Sjiang wu - Sun Microsystems - Beijing China 			    mptsas_sasiou_page_1_cb);
17485b504601Sjiang wu - Sun Microsystems - Beijing China 		}
17495b504601Sjiang wu - Sun Microsystems - Beijing China 
17505b504601Sjiang wu - Sun Microsystems - Beijing China 		if (rval == DDI_SUCCESS) {
17515b504601Sjiang wu - Sun Microsystems - Beijing China 			switch (state) {
17525b504601Sjiang wu - Sun Microsystems - Beijing China 			case IOUC_READ_PAGE0:
17535b504601Sjiang wu - Sun Microsystems - Beijing China 				/*
17545b504601Sjiang wu - Sun Microsystems - Beijing China 				 * retry 30 times if discovery is in process
17555b504601Sjiang wu - Sun Microsystems - Beijing China 				 */
17565b504601Sjiang wu - Sun Microsystems - Beijing China 				if (retrypage0 && (retrypage0 < 30)) {
17575b504601Sjiang wu - Sun Microsystems - Beijing China 					drv_usecwait(1000 * 100);
17585b504601Sjiang wu - Sun Microsystems - Beijing China 					state = IOUC_READ_PAGE0;
17595b504601Sjiang wu - Sun Microsystems - Beijing China 					break;
17605b504601Sjiang wu - Sun Microsystems - Beijing China 				} else if (retrypage0 == 30) {
17615b504601Sjiang wu - Sun Microsystems - Beijing China 					mptsas_log(mpt, CE_WARN,
17625b504601Sjiang wu - Sun Microsystems - Beijing China 					    "!Discovery in progress, can't "
17635b504601Sjiang wu - Sun Microsystems - Beijing China 					    "verify IO unit config, then "
17645b504601Sjiang wu - Sun Microsystems - Beijing China 					    "after 30 times retry, give "
17655b504601Sjiang wu - Sun Microsystems - Beijing China 					    "up!");
17665b504601Sjiang wu - Sun Microsystems - Beijing China 					state = IOUC_DONE;
17675b504601Sjiang wu - Sun Microsystems - Beijing China 					rval = DDI_FAILURE;
17685b504601Sjiang wu - Sun Microsystems - Beijing China 					break;
17695b504601Sjiang wu - Sun Microsystems - Beijing China 				}
17705b504601Sjiang wu - Sun Microsystems - Beijing China 
17715b504601Sjiang wu - Sun Microsystems - Beijing China 				if (readpage1 == 0) {
17725b504601Sjiang wu - Sun Microsystems - Beijing China 					state = IOUC_DONE;
17735b504601Sjiang wu - Sun Microsystems - Beijing China 					rval = DDI_SUCCESS;
17745b504601Sjiang wu - Sun Microsystems - Beijing China 					break;
17755b504601Sjiang wu - Sun Microsystems - Beijing China 				}
17765b504601Sjiang wu - Sun Microsystems - Beijing China 
17775b504601Sjiang wu - Sun Microsystems - Beijing China 				state = IOUC_READ_PAGE1;
17785b504601Sjiang wu - Sun Microsystems - Beijing China 				break;
17795b504601Sjiang wu - Sun Microsystems - Beijing China 
17805b504601Sjiang wu - Sun Microsystems - Beijing China 			case IOUC_READ_PAGE1:
17815b504601Sjiang wu - Sun Microsystems - Beijing China 				state = IOUC_DONE;
17825b504601Sjiang wu - Sun Microsystems - Beijing China 				rval = DDI_SUCCESS;
17835b504601Sjiang wu - Sun Microsystems - Beijing China 				break;
17845b504601Sjiang wu - Sun Microsystems - Beijing China 			}
17855b504601Sjiang wu - Sun Microsystems - Beijing China 		} else {
17865b504601Sjiang wu - Sun Microsystems - Beijing China 			return (rval);
17875b504601Sjiang wu - Sun Microsystems - Beijing China 		}
17885b504601Sjiang wu - Sun Microsystems - Beijing China 	}
17895b504601Sjiang wu - Sun Microsystems - Beijing China 
17905b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
17915b504601Sjiang wu - Sun Microsystems - Beijing China }
17925b504601Sjiang wu - Sun Microsystems - Beijing China 
179308eb0b82SYong-Feng Du static int
179408eb0b82SYong-Feng Du mptsas_biospage_3_cb(mptsas_t *mpt, caddr_t page_memp,
179508eb0b82SYong-Feng Du     ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo,
179608eb0b82SYong-Feng Du     va_list ap)
179708eb0b82SYong-Feng Du {
179808eb0b82SYong-Feng Du #ifndef __lock_lint
179908eb0b82SYong-Feng Du 	_NOTE(ARGUNUSED(ap))
180008eb0b82SYong-Feng Du #endif
180108eb0b82SYong-Feng Du 	pMpi2BiosPage3_t	sasbiospage;
180208eb0b82SYong-Feng Du 	int			rval = DDI_SUCCESS;
180308eb0b82SYong-Feng Du 	uint32_t		*bios_version;
180408eb0b82SYong-Feng Du 
180508eb0b82SYong-Feng Du 	if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) &&
180608eb0b82SYong-Feng Du 	    (iocstatus != MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)) {
180708eb0b82SYong-Feng Du 		mptsas_log(mpt, CE_WARN, "mptsas_get_bios_page3 header: "
180808eb0b82SYong-Feng Du 		    "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus, iocloginfo);
180908eb0b82SYong-Feng Du 		rval = DDI_FAILURE;
181008eb0b82SYong-Feng Du 		return (rval);
181108eb0b82SYong-Feng Du 	}
181208eb0b82SYong-Feng Du 	bios_version = va_arg(ap, uint32_t *);
181308eb0b82SYong-Feng Du 	sasbiospage = (pMpi2BiosPage3_t)page_memp;
181408eb0b82SYong-Feng Du 	*bios_version = ddi_get32(accessp, &sasbiospage->BiosVersion);
181508eb0b82SYong-Feng Du 
181608eb0b82SYong-Feng Du 	return (rval);
181708eb0b82SYong-Feng Du }
181808eb0b82SYong-Feng Du 
181908eb0b82SYong-Feng Du /*
182008eb0b82SYong-Feng Du  * Request MPI configuration page BIOS page 3 to get BIOS version.  Since all
182108eb0b82SYong-Feng Du  * other information in this page is not needed, just ignore it.
182208eb0b82SYong-Feng Du  */
182308eb0b82SYong-Feng Du int
182408eb0b82SYong-Feng Du mptsas_get_bios_page3(mptsas_t *mpt, uint32_t *bios_version)
182508eb0b82SYong-Feng Du {
182608eb0b82SYong-Feng Du 	int rval = DDI_SUCCESS;
182708eb0b82SYong-Feng Du 
182808eb0b82SYong-Feng Du 	ASSERT(mutex_owned(&mpt->m_mutex));
182908eb0b82SYong-Feng Du 
183008eb0b82SYong-Feng Du 	/*
183108eb0b82SYong-Feng Du 	 * Get the header and config page.  reply contains the reply frame,
183208eb0b82SYong-Feng Du 	 * which holds status info for the request.
183308eb0b82SYong-Feng Du 	 */
183408eb0b82SYong-Feng Du 	rval = mptsas_access_config_page(mpt,
183508eb0b82SYong-Feng Du 	    MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, MPI2_CONFIG_PAGETYPE_BIOS, 3,
183608eb0b82SYong-Feng Du 	    0, mptsas_biospage_3_cb, bios_version);
183708eb0b82SYong-Feng Du 
183808eb0b82SYong-Feng Du 	return (rval);
183908eb0b82SYong-Feng Du }
184008eb0b82SYong-Feng Du 
18415b504601Sjiang wu - Sun Microsystems - Beijing China /*
18425b504601Sjiang wu - Sun Microsystems - Beijing China  * Read IO unit page 0 to get information for each PHY. If needed, Read IO Unit
18435b504601Sjiang wu - Sun Microsystems - Beijing China  * page1 to update the PHY information.  This is the handshaking version of
18445b504601Sjiang wu - Sun Microsystems - Beijing China  * this function, which should be called during initialization only.
18455b504601Sjiang wu - Sun Microsystems - Beijing China  */
18465b504601Sjiang wu - Sun Microsystems - Beijing China int
18475b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_sas_io_unit_page_hndshk(mptsas_t *mpt)
18485b504601Sjiang wu - Sun Microsystems - Beijing China {
18495b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_attr_t		recv_dma_attrs, page_dma_attrs;
18505b504601Sjiang wu - Sun Microsystems - Beijing China 	uint_t			recv_ncookie, page_ncookie;
18515b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_cookie_t	recv_cookie, page_cookie;
18525b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_handle_t	recv_dma_handle, page_dma_handle;
18535b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_acc_handle_t	recv_accessp, page_accessp;
18545b504601Sjiang wu - Sun Microsystems - Beijing China 	size_t			recv_alloc_len, page_alloc_len;
18555b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2ConfigReply_t	configreply;
18565b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2SasIOUnitPage0_t	sasioupage0;
18575b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2SasIOUnitPage1_t	sasioupage1;
18585b504601Sjiang wu - Sun Microsystems - Beijing China 	int			recv_numbytes;
18595b504601Sjiang wu - Sun Microsystems - Beijing China 	caddr_t			recv_memp, page_memp;
18605b504601Sjiang wu - Sun Microsystems - Beijing China 	int			recv_dmastate = 0;
18615b504601Sjiang wu - Sun Microsystems - Beijing China 	int			page_dmastate = 0;
18625b504601Sjiang wu - Sun Microsystems - Beijing China 	int			i, num_phys;
18635b504601Sjiang wu - Sun Microsystems - Beijing China 	int			page0_size =
18645b504601Sjiang wu - Sun Microsystems - Beijing China 	    sizeof (MPI2_CONFIG_PAGE_SASIOUNIT_0) +
18655b504601Sjiang wu - Sun Microsystems - Beijing China 	    (sizeof (MPI2_SAS_IO_UNIT0_PHY_DATA) * 7);
18665b504601Sjiang wu - Sun Microsystems - Beijing China 	int			page1_size =
18675b504601Sjiang wu - Sun Microsystems - Beijing China 	    sizeof (MPI2_CONFIG_PAGE_SASIOUNIT_1) +
18685b504601Sjiang wu - Sun Microsystems - Beijing China 	    (sizeof (MPI2_SAS_IO_UNIT1_PHY_DATA) * 7);
18695b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		flags_length;
18705b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		cpdi[8], readpage1 = 0, retrypage0 = 0;
18715b504601Sjiang wu - Sun Microsystems - Beijing China 	uint16_t		iocstatus;
18725b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t			port_flags, page_number, action;
18735b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		reply_size = 256; /* Big enough for any page */
18745b504601Sjiang wu - Sun Microsystems - Beijing China 	uint_t			state;
18755b504601Sjiang wu - Sun Microsystems - Beijing China 	int			rval = DDI_FAILURE;
18765b504601Sjiang wu - Sun Microsystems - Beijing China 
18775b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
18785b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Initialize our "state machine".  This is a bit convoluted,
18795b504601Sjiang wu - Sun Microsystems - Beijing China 	 * but it keeps us from having to do the ddi allocations numerous
18805b504601Sjiang wu - Sun Microsystems - Beijing China 	 * times.
18815b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
18825b504601Sjiang wu - Sun Microsystems - Beijing China 
18835b504601Sjiang wu - Sun Microsystems - Beijing China 	NDBG20(("mptsas_get_sas_io_unit_page_hndshk enter"));
18845b504601Sjiang wu - Sun Microsystems - Beijing China 	ASSERT(mutex_owned(&mpt->m_mutex));
18855b504601Sjiang wu - Sun Microsystems - Beijing China 	state = IOUC_READ_PAGE0;
18865b504601Sjiang wu - Sun Microsystems - Beijing China 
18875b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
18885b504601Sjiang wu - Sun Microsystems - Beijing China 	 * dynamically create a customized dma attribute structure
18895b504601Sjiang wu - Sun Microsystems - Beijing China 	 * that describes mpt's config reply page request structure.
18905b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
18915b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dma_attrs = mpt->m_msg_dma_attr;
18925b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dma_attrs.dma_attr_sgllen = 1;
18935b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_REPLY));
18945b504601Sjiang wu - Sun Microsystems - Beijing China 
18955b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_alloc_handle(mpt->m_dip, &recv_dma_attrs,
18965b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SLEEP, NULL, &recv_dma_handle) != DDI_SUCCESS) {
18975b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
18985b504601Sjiang wu - Sun Microsystems - Beijing China 	}
18995b504601Sjiang wu - Sun Microsystems - Beijing China 
19005b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dmastate |= MPTSAS_DMA_HANDLE_ALLOCD;
19015b504601Sjiang wu - Sun Microsystems - Beijing China 
19025b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_mem_alloc(recv_dma_handle,
19035b504601Sjiang wu - Sun Microsystems - Beijing China 	    (sizeof (MPI2_CONFIG_REPLY)),
19045b504601Sjiang wu - Sun Microsystems - Beijing China 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
19055b504601Sjiang wu - Sun Microsystems - Beijing China 	    &recv_memp, &recv_alloc_len, &recv_accessp) != DDI_SUCCESS) {
19065b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
19075b504601Sjiang wu - Sun Microsystems - Beijing China 	}
19085b504601Sjiang wu - Sun Microsystems - Beijing China 
19095b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dmastate |= MPTSAS_DMA_MEMORY_ALLOCD;
19105b504601Sjiang wu - Sun Microsystems - Beijing China 
19115b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_addr_bind_handle(recv_dma_handle, NULL, recv_memp,
19125b504601Sjiang wu - Sun Microsystems - Beijing China 	    recv_alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
19135b504601Sjiang wu - Sun Microsystems - Beijing China 	    NULL, &recv_cookie, &recv_ncookie) != DDI_DMA_MAPPED) {
19145b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
19155b504601Sjiang wu - Sun Microsystems - Beijing China 	}
19165b504601Sjiang wu - Sun Microsystems - Beijing China 
19175b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dmastate |= MPTSAS_DMA_HANDLE_BOUND;
19185b504601Sjiang wu - Sun Microsystems - Beijing China 
19195b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dma_attrs = mpt->m_msg_dma_attr;
19205b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dma_attrs.dma_attr_sgllen = 1;
19215b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dma_attrs.dma_attr_granular = reply_size;
19225b504601Sjiang wu - Sun Microsystems - Beijing China 
19235b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_alloc_handle(mpt->m_dip, &page_dma_attrs,
19245b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SLEEP, NULL, &page_dma_handle) != DDI_SUCCESS) {
19255b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
19265b504601Sjiang wu - Sun Microsystems - Beijing China 	}
19275b504601Sjiang wu - Sun Microsystems - Beijing China 
19285b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dmastate |= MPTSAS_DMA_HANDLE_ALLOCD;
19295b504601Sjiang wu - Sun Microsystems - Beijing China 
19305b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
19315b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Page 0 size is larger, so just use that for both.
19325b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
19335b504601Sjiang wu - Sun Microsystems - Beijing China 
19345b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_mem_alloc(page_dma_handle, reply_size,
19355b504601Sjiang wu - Sun Microsystems - Beijing China 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
19365b504601Sjiang wu - Sun Microsystems - Beijing China 	    &page_memp, &page_alloc_len, &page_accessp) != DDI_SUCCESS) {
19375b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
19385b504601Sjiang wu - Sun Microsystems - Beijing China 	}
19395b504601Sjiang wu - Sun Microsystems - Beijing China 
19405b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dmastate |= MPTSAS_DMA_MEMORY_ALLOCD;
19415b504601Sjiang wu - Sun Microsystems - Beijing China 
19425b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_addr_bind_handle(page_dma_handle, NULL, page_memp,
19435b504601Sjiang wu - Sun Microsystems - Beijing China 	    page_alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
19445b504601Sjiang wu - Sun Microsystems - Beijing China 	    NULL, &page_cookie, &page_ncookie) != DDI_DMA_MAPPED) {
19455b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
19465b504601Sjiang wu - Sun Microsystems - Beijing China 	}
19475b504601Sjiang wu - Sun Microsystems - Beijing China 
19485b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dmastate |= MPTSAS_DMA_HANDLE_BOUND;
19495b504601Sjiang wu - Sun Microsystems - Beijing China 
19505b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
19515b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Now we cycle through the state machine.  Here's what happens:
19525b504601Sjiang wu - Sun Microsystems - Beijing China 	 * 1. Read IO unit page 0 and set phy information
19535b504601Sjiang wu - Sun Microsystems - Beijing China 	 * 2. See if Read IO unit page1 is needed because of port configuration
19545b504601Sjiang wu - Sun Microsystems - Beijing China 	 * 3. Read IO unit page 1 and update phy information.
19555b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
19565b504601Sjiang wu - Sun Microsystems - Beijing China 
19575b504601Sjiang wu - Sun Microsystems - Beijing China 	sasioupage0 = (pMpi2SasIOUnitPage0_t)page_memp;
19585b504601Sjiang wu - Sun Microsystems - Beijing China 	sasioupage1 = (pMpi2SasIOUnitPage1_t)page_memp;
19595b504601Sjiang wu - Sun Microsystems - Beijing China 
19605b504601Sjiang wu - Sun Microsystems - Beijing China 	while (state != IOUC_DONE) {
19615b504601Sjiang wu - Sun Microsystems - Beijing China 		switch (state) {
19625b504601Sjiang wu - Sun Microsystems - Beijing China 		case IOUC_READ_PAGE0:
19635b504601Sjiang wu - Sun Microsystems - Beijing China 			page_number = 0;
19645b504601Sjiang wu - Sun Microsystems - Beijing China 			action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
19655b504601Sjiang wu - Sun Microsystems - Beijing China 			flags_length = (uint32_t)page0_size;
19665b504601Sjiang wu - Sun Microsystems - Beijing China 			flags_length |= ((uint32_t)(
19675b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_LAST_ELEMENT |
19685b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_END_OF_BUFFER |
19695b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
19705b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
19715b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_32_BIT_ADDRESSING |
19725b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_IOC_TO_HOST |
19735b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_END_OF_LIST) <<
19745b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SHIFT);
19755b504601Sjiang wu - Sun Microsystems - Beijing China 
19765b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
19775b504601Sjiang wu - Sun Microsystems - Beijing China 
19785b504601Sjiang wu - Sun Microsystems - Beijing China 		case IOUC_READ_PAGE1:
19795b504601Sjiang wu - Sun Microsystems - Beijing China 			page_number = 1;
19805b504601Sjiang wu - Sun Microsystems - Beijing China 			action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
19815b504601Sjiang wu - Sun Microsystems - Beijing China 			flags_length = (uint32_t)page1_size;
19825b504601Sjiang wu - Sun Microsystems - Beijing China 			flags_length |= ((uint32_t)(
19835b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_LAST_ELEMENT |
19845b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_END_OF_BUFFER |
19855b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
19865b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
19875b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_32_BIT_ADDRESSING |
19885b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_IOC_TO_HOST |
19895b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_END_OF_LIST) <<
19905b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SHIFT);
19915b504601Sjiang wu - Sun Microsystems - Beijing China 
19925b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
19935b504601Sjiang wu - Sun Microsystems - Beijing China 		default:
19945b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
19955b504601Sjiang wu - Sun Microsystems - Beijing China 		}
19965b504601Sjiang wu - Sun Microsystems - Beijing China 
19975b504601Sjiang wu - Sun Microsystems - Beijing China 		bzero(recv_memp, sizeof (MPI2_CONFIG_REPLY));
19985b504601Sjiang wu - Sun Microsystems - Beijing China 		configreply = (pMpi2ConfigReply_t)recv_memp;
19995b504601Sjiang wu - Sun Microsystems - Beijing China 		recv_numbytes = sizeof (MPI2_CONFIG_REPLY);
20005b504601Sjiang wu - Sun Microsystems - Beijing China 
20015b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_send_extended_config_request_msg(mpt,
20025b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_CONFIG_ACTION_PAGE_HEADER,
20035b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT,
20045b504601Sjiang wu - Sun Microsystems - Beijing China 		    0, page_number, 0, 0, 0, 0)) {
20055b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
20065b504601Sjiang wu - Sun Microsystems - Beijing China 		}
20075b504601Sjiang wu - Sun Microsystems - Beijing China 
20085b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes,
20095b504601Sjiang wu - Sun Microsystems - Beijing China 		    recv_accessp)) {
20105b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
20115b504601Sjiang wu - Sun Microsystems - Beijing China 		}
20125b504601Sjiang wu - Sun Microsystems - Beijing China 
20135b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = ddi_get16(recv_accessp, &configreply->IOCStatus);
20145b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = MPTSAS_IOCSTATUS(iocstatus);
20155b504601Sjiang wu - Sun Microsystems - Beijing China 
20165b504601Sjiang wu - Sun Microsystems - Beijing China 		if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
20175b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_log(mpt, CE_WARN,
20185b504601Sjiang wu - Sun Microsystems - Beijing China 			    "mptsas_get_sas_io_unit_page_hndshk: read page "
20195b504601Sjiang wu - Sun Microsystems - Beijing China 			    "header iocstatus = 0x%x", iocstatus);
20205b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
20215b504601Sjiang wu - Sun Microsystems - Beijing China 		}
20225b504601Sjiang wu - Sun Microsystems - Beijing China 
20235b504601Sjiang wu - Sun Microsystems - Beijing China 		if (action != MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {
20245b504601Sjiang wu - Sun Microsystems - Beijing China 			bzero(page_memp, reply_size);
20255b504601Sjiang wu - Sun Microsystems - Beijing China 		}
20265b504601Sjiang wu - Sun Microsystems - Beijing China 
20275b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_send_extended_config_request_msg(mpt, action,
20285b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 0, page_number,
20295b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get8(recv_accessp, &configreply->Header.PageVersion),
20305b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get16(recv_accessp, &configreply->ExtPageLength),
20315b504601Sjiang wu - Sun Microsystems - Beijing China 		    flags_length, page_cookie.dmac_address)) {
20325b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
20335b504601Sjiang wu - Sun Microsystems - Beijing China 		}
20345b504601Sjiang wu - Sun Microsystems - Beijing China 
20355b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes,
20365b504601Sjiang wu - Sun Microsystems - Beijing China 		    recv_accessp)) {
20375b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
20385b504601Sjiang wu - Sun Microsystems - Beijing China 		}
20395b504601Sjiang wu - Sun Microsystems - Beijing China 
20405b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = ddi_get16(recv_accessp, &configreply->IOCStatus);
20415b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = MPTSAS_IOCSTATUS(iocstatus);
20425b504601Sjiang wu - Sun Microsystems - Beijing China 
20435b504601Sjiang wu - Sun Microsystems - Beijing China 		if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
20445b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_log(mpt, CE_WARN,
20455b504601Sjiang wu - Sun Microsystems - Beijing China 			    "mptsas_get_sas_io_unit_page_hndshk: IO unit "
20465b504601Sjiang wu - Sun Microsystems - Beijing China 			    "config failed for action %d, iocstatus = 0x%x",
20475b504601Sjiang wu - Sun Microsystems - Beijing China 			    action, iocstatus);
20485b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
20495b504601Sjiang wu - Sun Microsystems - Beijing China 		}
20505b504601Sjiang wu - Sun Microsystems - Beijing China 
20515b504601Sjiang wu - Sun Microsystems - Beijing China 		switch (state) {
20525b504601Sjiang wu - Sun Microsystems - Beijing China 		case IOUC_READ_PAGE0:
20535b504601Sjiang wu - Sun Microsystems - Beijing China 			if ((ddi_dma_sync(page_dma_handle, 0, 0,
20545b504601Sjiang wu - Sun Microsystems - Beijing China 			    DDI_DMA_SYNC_FORCPU)) != DDI_SUCCESS) {
20555b504601Sjiang wu - Sun Microsystems - Beijing China 				goto cleanup;
20565b504601Sjiang wu - Sun Microsystems - Beijing China 			}
20575b504601Sjiang wu - Sun Microsystems - Beijing China 
20585b504601Sjiang wu - Sun Microsystems - Beijing China 			num_phys = ddi_get8(page_accessp,
20595b504601Sjiang wu - Sun Microsystems - Beijing China 			    &sasioupage0->NumPhys);
20605b504601Sjiang wu - Sun Microsystems - Beijing China 			for (i = 0; i < num_phys; i++) {
20615b504601Sjiang wu - Sun Microsystems - Beijing China 				cpdi[i] = ddi_get32(page_accessp,
20625b504601Sjiang wu - Sun Microsystems - Beijing China 				    &sasioupage0->PhyData[i].
20635b504601Sjiang wu - Sun Microsystems - Beijing China 				    ControllerPhyDeviceInfo);
20645b504601Sjiang wu - Sun Microsystems - Beijing China 				port_flags = ddi_get8(page_accessp,
20655b504601Sjiang wu - Sun Microsystems - Beijing China 				    &sasioupage0->PhyData[i].PortFlags);
20665b504601Sjiang wu - Sun Microsystems - Beijing China 
20675b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_phy_info[i].port_num =
20685b504601Sjiang wu - Sun Microsystems - Beijing China 				    ddi_get8(page_accessp,
20695b504601Sjiang wu - Sun Microsystems - Beijing China 				    &sasioupage0->PhyData[i].Port);
20705b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_phy_info[i].ctrl_devhdl =
20715b504601Sjiang wu - Sun Microsystems - Beijing China 				    ddi_get16(page_accessp, &sasioupage0->
20725b504601Sjiang wu - Sun Microsystems - Beijing China 				    PhyData[i].ControllerDevHandle);
20735b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_phy_info[i].attached_devhdl =
20745b504601Sjiang wu - Sun Microsystems - Beijing China 				    ddi_get16(page_accessp, &sasioupage0->
20755b504601Sjiang wu - Sun Microsystems - Beijing China 				    PhyData[i].AttachedDevHandle);
20765b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_phy_info[i].phy_device_type = cpdi[i];
20775b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_phy_info[i].port_flags = port_flags;
20785b504601Sjiang wu - Sun Microsystems - Beijing China 
20795b504601Sjiang wu - Sun Microsystems - Beijing China 				if (port_flags & DISCOVERY_IN_PROGRESS) {
20805b504601Sjiang wu - Sun Microsystems - Beijing China 					retrypage0++;
20815b504601Sjiang wu - Sun Microsystems - Beijing China 					NDBG20(("Discovery in progress, can't "
20825b504601Sjiang wu - Sun Microsystems - Beijing China 					    "verify IO unit config, then NO.%d"
20835b504601Sjiang wu - Sun Microsystems - Beijing China 					    " times retry", retrypage0));
20845b504601Sjiang wu - Sun Microsystems - Beijing China 					break;
20855b504601Sjiang wu - Sun Microsystems - Beijing China 				} else {
20865b504601Sjiang wu - Sun Microsystems - Beijing China 					retrypage0 = 0;
20875b504601Sjiang wu - Sun Microsystems - Beijing China 				}
20885b504601Sjiang wu - Sun Microsystems - Beijing China 				if (!(port_flags & AUTO_PORT_CONFIGURATION)) {
20895b504601Sjiang wu - Sun Microsystems - Beijing China 					/*
20905b504601Sjiang wu - Sun Microsystems - Beijing China 					 * some PHY configuration described in
20915b504601Sjiang wu - Sun Microsystems - Beijing China 					 * SAS IO Unit Page1
20925b504601Sjiang wu - Sun Microsystems - Beijing China 					 */
20935b504601Sjiang wu - Sun Microsystems - Beijing China 					readpage1 = 1;
20945b504601Sjiang wu - Sun Microsystems - Beijing China 				}
20955b504601Sjiang wu - Sun Microsystems - Beijing China 			}
20965b504601Sjiang wu - Sun Microsystems - Beijing China 
20975b504601Sjiang wu - Sun Microsystems - Beijing China 			/*
20985b504601Sjiang wu - Sun Microsystems - Beijing China 			 * retry 30 times if discovery is in process
20995b504601Sjiang wu - Sun Microsystems - Beijing China 			 */
21005b504601Sjiang wu - Sun Microsystems - Beijing China 			if (retrypage0 && (retrypage0 < 30)) {
21015b504601Sjiang wu - Sun Microsystems - Beijing China 				drv_usecwait(1000 * 100);
21025b504601Sjiang wu - Sun Microsystems - Beijing China 				state = IOUC_READ_PAGE0;
21035b504601Sjiang wu - Sun Microsystems - Beijing China 				break;
21045b504601Sjiang wu - Sun Microsystems - Beijing China 			} else if (retrypage0 == 30) {
21055b504601Sjiang wu - Sun Microsystems - Beijing China 				mptsas_log(mpt, CE_WARN,
21065b504601Sjiang wu - Sun Microsystems - Beijing China 				    "!Discovery in progress, can't "
21075b504601Sjiang wu - Sun Microsystems - Beijing China 				    "verify IO unit config, then after"
21085b504601Sjiang wu - Sun Microsystems - Beijing China 				    " 30 times retry, give up!");
21095b504601Sjiang wu - Sun Microsystems - Beijing China 				state = IOUC_DONE;
21105b504601Sjiang wu - Sun Microsystems - Beijing China 				rval = DDI_FAILURE;
21115b504601Sjiang wu - Sun Microsystems - Beijing China 				break;
21125b504601Sjiang wu - Sun Microsystems - Beijing China 			}
21135b504601Sjiang wu - Sun Microsystems - Beijing China 
21145b504601Sjiang wu - Sun Microsystems - Beijing China 			if (readpage1 == 0) {
21155b504601Sjiang wu - Sun Microsystems - Beijing China 				state = IOUC_DONE;
21165b504601Sjiang wu - Sun Microsystems - Beijing China 				rval = DDI_SUCCESS;
21175b504601Sjiang wu - Sun Microsystems - Beijing China 				break;
21185b504601Sjiang wu - Sun Microsystems - Beijing China 			}
21195b504601Sjiang wu - Sun Microsystems - Beijing China 
21205b504601Sjiang wu - Sun Microsystems - Beijing China 			state = IOUC_READ_PAGE1;
21215b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
21225b504601Sjiang wu - Sun Microsystems - Beijing China 
21235b504601Sjiang wu - Sun Microsystems - Beijing China 		case IOUC_READ_PAGE1:
21245b504601Sjiang wu - Sun Microsystems - Beijing China 			if ((ddi_dma_sync(page_dma_handle, 0, 0,
21255b504601Sjiang wu - Sun Microsystems - Beijing China 			    DDI_DMA_SYNC_FORCPU)) != DDI_SUCCESS) {
21265b504601Sjiang wu - Sun Microsystems - Beijing China 				goto cleanup;
21275b504601Sjiang wu - Sun Microsystems - Beijing China 			}
21285b504601Sjiang wu - Sun Microsystems - Beijing China 
21295b504601Sjiang wu - Sun Microsystems - Beijing China 			num_phys = ddi_get8(page_accessp,
21305b504601Sjiang wu - Sun Microsystems - Beijing China 			    &sasioupage1->NumPhys);
21315b504601Sjiang wu - Sun Microsystems - Beijing China 
21325b504601Sjiang wu - Sun Microsystems - Beijing China 			for (i = 0; i < num_phys; i++) {
21335b504601Sjiang wu - Sun Microsystems - Beijing China 				cpdi[i] = ddi_get32(page_accessp,
21345b504601Sjiang wu - Sun Microsystems - Beijing China 				    &sasioupage1->PhyData[i].
21355b504601Sjiang wu - Sun Microsystems - Beijing China 				    ControllerPhyDeviceInfo);
21365b504601Sjiang wu - Sun Microsystems - Beijing China 				port_flags = ddi_get8(page_accessp,
21375b504601Sjiang wu - Sun Microsystems - Beijing China 				    &sasioupage1->PhyData[i].PortFlags);
21385b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_phy_info[i].port_num =
21395b504601Sjiang wu - Sun Microsystems - Beijing China 				    ddi_get8(page_accessp,
21405b504601Sjiang wu - Sun Microsystems - Beijing China 				    &sasioupage1->PhyData[i].Port);
21415b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_phy_info[i].port_flags = port_flags;
21425b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_phy_info[i].phy_device_type = cpdi[i];
21435b504601Sjiang wu - Sun Microsystems - Beijing China 
21445b504601Sjiang wu - Sun Microsystems - Beijing China 			}
21455b504601Sjiang wu - Sun Microsystems - Beijing China 
21465b504601Sjiang wu - Sun Microsystems - Beijing China 			state = IOUC_DONE;
21475b504601Sjiang wu - Sun Microsystems - Beijing China 			rval = DDI_SUCCESS;
21485b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
21495b504601Sjiang wu - Sun Microsystems - Beijing China 		}
21505b504601Sjiang wu - Sun Microsystems - Beijing China 	}
21515b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((mptsas_check_dma_handle(recv_dma_handle) != DDI_SUCCESS) ||
21525b504601Sjiang wu - Sun Microsystems - Beijing China 	    (mptsas_check_dma_handle(page_dma_handle) != DDI_SUCCESS)) {
21535b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
21545b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
21555b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
21565b504601Sjiang wu - Sun Microsystems - Beijing China 	}
21575b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((mptsas_check_acc_handle(recv_accessp) != DDI_SUCCESS) ||
21585b504601Sjiang wu - Sun Microsystems - Beijing China 	    (mptsas_check_acc_handle(page_accessp) != DDI_SUCCESS)) {
21595b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
21605b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
21615b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
21625b504601Sjiang wu - Sun Microsystems - Beijing China 	}
21635b504601Sjiang wu - Sun Microsystems - Beijing China 
21645b504601Sjiang wu - Sun Microsystems - Beijing China cleanup:
21655b504601Sjiang wu - Sun Microsystems - Beijing China 	if (recv_dmastate & MPTSAS_DMA_HANDLE_BOUND)
21665b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_unbind_handle(recv_dma_handle);
21675b504601Sjiang wu - Sun Microsystems - Beijing China 	if (page_dmastate & MPTSAS_DMA_HANDLE_BOUND)
21685b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_unbind_handle(page_dma_handle);
21695b504601Sjiang wu - Sun Microsystems - Beijing China 	if (recv_dmastate & MPTSAS_DMA_MEMORY_ALLOCD)
21705b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_mem_free(&recv_accessp);
21715b504601Sjiang wu - Sun Microsystems - Beijing China 	if (page_dmastate & MPTSAS_DMA_MEMORY_ALLOCD)
21725b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_mem_free(&page_accessp);
21735b504601Sjiang wu - Sun Microsystems - Beijing China 	if (recv_dmastate & MPTSAS_DMA_HANDLE_ALLOCD)
21745b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&recv_dma_handle);
21755b504601Sjiang wu - Sun Microsystems - Beijing China 	if (page_dmastate & MPTSAS_DMA_HANDLE_ALLOCD)
21765b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&page_dma_handle);
21775b504601Sjiang wu - Sun Microsystems - Beijing China 
21785b504601Sjiang wu - Sun Microsystems - Beijing China 	if (rval != DDI_SUCCESS) {
21795b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
21805b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
21815b504601Sjiang wu - Sun Microsystems - Beijing China 	}
21825b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
21835b504601Sjiang wu - Sun Microsystems - Beijing China }
21845b504601Sjiang wu - Sun Microsystems - Beijing China 
21855b504601Sjiang wu - Sun Microsystems - Beijing China /*
21865b504601Sjiang wu - Sun Microsystems - Beijing China  * Check if the PHYs are currently in target mode. If they are not, we don't
21875b504601Sjiang wu - Sun Microsystems - Beijing China  * need to change anything.  Otherwise, we need to modify the appropriate bits
21885b504601Sjiang wu - Sun Microsystems - Beijing China  * and write them to IO unit page 1.  Once that is done, an IO unit reset is
21895b504601Sjiang wu - Sun Microsystems - Beijing China  * necessary to begin operating in initiator mode.  Since this function is only
21905b504601Sjiang wu - Sun Microsystems - Beijing China  * called during the initialization process, use handshaking.
21915b504601Sjiang wu - Sun Microsystems - Beijing China  */
21925b504601Sjiang wu - Sun Microsystems - Beijing China int
21935b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_set_initiator_mode(mptsas_t *mpt)
21945b504601Sjiang wu - Sun Microsystems - Beijing China {
21955b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_attr_t		recv_dma_attrs, page_dma_attrs;
21965b504601Sjiang wu - Sun Microsystems - Beijing China 	uint_t			recv_ncookie, page_ncookie;
21975b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_cookie_t	recv_cookie, page_cookie;
21985b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_handle_t	recv_dma_handle, page_dma_handle;
21995b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_acc_handle_t	recv_accessp, page_accessp;
22005b504601Sjiang wu - Sun Microsystems - Beijing China 	size_t			recv_alloc_len, page_alloc_len;
22015b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2ConfigReply_t	configreply;
22025b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2SasIOUnitPage1_t	sasioupage1;
22035b504601Sjiang wu - Sun Microsystems - Beijing China 	int			recv_numbytes;
22045b504601Sjiang wu - Sun Microsystems - Beijing China 	caddr_t			recv_memp, page_memp;
22055b504601Sjiang wu - Sun Microsystems - Beijing China 	int			recv_dmastate = 0;
22065b504601Sjiang wu - Sun Microsystems - Beijing China 	int			page_dmastate = 0;
22075b504601Sjiang wu - Sun Microsystems - Beijing China 	int			i;
22085b504601Sjiang wu - Sun Microsystems - Beijing China 	int			page1_size =
22095b504601Sjiang wu - Sun Microsystems - Beijing China 	    sizeof (MPI2_CONFIG_PAGE_SASIOUNIT_1) +
22105b504601Sjiang wu - Sun Microsystems - Beijing China 	    (sizeof (MPI2_SAS_IO_UNIT0_PHY_DATA) * 7);
22115b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		flags_length;
22125b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		cpdi[8], reprogram = 0;
22135b504601Sjiang wu - Sun Microsystems - Beijing China 	uint16_t		iocstatus;
22145b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t			port_flags, page_number, action;
22155b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		reply_size = 256; /* Big enough for any page */
22165b504601Sjiang wu - Sun Microsystems - Beijing China 	uint_t			state;
22175b504601Sjiang wu - Sun Microsystems - Beijing China 	int			rval = DDI_FAILURE;
22185b504601Sjiang wu - Sun Microsystems - Beijing China 
22195b504601Sjiang wu - Sun Microsystems - Beijing China 	ASSERT(mutex_owned(&mpt->m_mutex));
22205b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
22215b504601Sjiang wu - Sun Microsystems - Beijing China 	 * get each PHY informations from SAS IO Unit Pages.  Use handshakiing
22225b504601Sjiang wu - Sun Microsystems - Beijing China 	 * to get SAS IO Unit Page information since this is during init.
22235b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
22245b504601Sjiang wu - Sun Microsystems - Beijing China 	rval = mptsas_get_sas_io_unit_page_hndshk(mpt);
22255b504601Sjiang wu - Sun Microsystems - Beijing China 	if (rval != DDI_SUCCESS)
22265b504601Sjiang wu - Sun Microsystems - Beijing China 		return (rval);
22275b504601Sjiang wu - Sun Microsystems - Beijing China 
22285b504601Sjiang wu - Sun Microsystems - Beijing China 	for (i = 0; i < mpt->m_num_phys; i++) {
22295b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mpt->m_phy_info[i].phy_device_type &
22305b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_SAS_DEVICE_INFO_SSP_TARGET) {
22315b504601Sjiang wu - Sun Microsystems - Beijing China 			reprogram = 1;
22325b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
22335b504601Sjiang wu - Sun Microsystems - Beijing China 		}
22345b504601Sjiang wu - Sun Microsystems - Beijing China 	}
22355b504601Sjiang wu - Sun Microsystems - Beijing China 	if (reprogram == 0)
22365b504601Sjiang wu - Sun Microsystems - Beijing China 		return (DDI_SUCCESS);
22375b504601Sjiang wu - Sun Microsystems - Beijing China 
22385b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
22395b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Initialize our "state machine".  This is a bit convoluted,
22405b504601Sjiang wu - Sun Microsystems - Beijing China 	 * but it keeps us from having to do the ddi allocations numerous
22415b504601Sjiang wu - Sun Microsystems - Beijing China 	 * times.
22425b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
22435b504601Sjiang wu - Sun Microsystems - Beijing China 
22445b504601Sjiang wu - Sun Microsystems - Beijing China 	state = IOUC_READ_PAGE1;
22455b504601Sjiang wu - Sun Microsystems - Beijing China 
22465b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
22475b504601Sjiang wu - Sun Microsystems - Beijing China 	 * dynamically create a customized dma attribute structure
22485b504601Sjiang wu - Sun Microsystems - Beijing China 	 * that describes mpt's config reply page request structure.
22495b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
22505b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dma_attrs = mpt->m_msg_dma_attr;
22515b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dma_attrs.dma_attr_sgllen = 1;
22525b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_REPLY));
22535b504601Sjiang wu - Sun Microsystems - Beijing China 
22545b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_alloc_handle(mpt->m_dip, &recv_dma_attrs,
22555b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SLEEP, NULL, &recv_dma_handle) != DDI_SUCCESS) {
22565b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
22575b504601Sjiang wu - Sun Microsystems - Beijing China 	}
22585b504601Sjiang wu - Sun Microsystems - Beijing China 
22595b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dmastate |= MPTSAS_DMA_HANDLE_ALLOCD;
22605b504601Sjiang wu - Sun Microsystems - Beijing China 
22615b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_mem_alloc(recv_dma_handle,
22625b504601Sjiang wu - Sun Microsystems - Beijing China 	    (sizeof (MPI2_CONFIG_REPLY)),
22635b504601Sjiang wu - Sun Microsystems - Beijing China 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
22645b504601Sjiang wu - Sun Microsystems - Beijing China 	    &recv_memp, &recv_alloc_len, &recv_accessp) != DDI_SUCCESS) {
22655b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
22665b504601Sjiang wu - Sun Microsystems - Beijing China 	}
22675b504601Sjiang wu - Sun Microsystems - Beijing China 
22685b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dmastate |= MPTSAS_DMA_MEMORY_ALLOCD;
22695b504601Sjiang wu - Sun Microsystems - Beijing China 
22705b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_addr_bind_handle(recv_dma_handle, NULL, recv_memp,
22715b504601Sjiang wu - Sun Microsystems - Beijing China 	    recv_alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
22725b504601Sjiang wu - Sun Microsystems - Beijing China 	    NULL, &recv_cookie, &recv_ncookie) != DDI_DMA_MAPPED) {
22735b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
22745b504601Sjiang wu - Sun Microsystems - Beijing China 	}
22755b504601Sjiang wu - Sun Microsystems - Beijing China 
22765b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dmastate |= MPTSAS_DMA_HANDLE_BOUND;
22775b504601Sjiang wu - Sun Microsystems - Beijing China 
22785b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dma_attrs = mpt->m_msg_dma_attr;
22795b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dma_attrs.dma_attr_sgllen = 1;
22805b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dma_attrs.dma_attr_granular = reply_size;
22815b504601Sjiang wu - Sun Microsystems - Beijing China 
22825b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_alloc_handle(mpt->m_dip, &page_dma_attrs,
22835b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SLEEP, NULL, &page_dma_handle) != DDI_SUCCESS) {
22845b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
22855b504601Sjiang wu - Sun Microsystems - Beijing China 	}
22865b504601Sjiang wu - Sun Microsystems - Beijing China 
22875b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dmastate |= MPTSAS_DMA_HANDLE_ALLOCD;
22885b504601Sjiang wu - Sun Microsystems - Beijing China 
22895b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_mem_alloc(page_dma_handle, reply_size,
22905b504601Sjiang wu - Sun Microsystems - Beijing China 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
22915b504601Sjiang wu - Sun Microsystems - Beijing China 	    &page_memp, &page_alloc_len, &page_accessp) != DDI_SUCCESS) {
22925b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
22935b504601Sjiang wu - Sun Microsystems - Beijing China 	}
22945b504601Sjiang wu - Sun Microsystems - Beijing China 
22955b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dmastate |= MPTSAS_DMA_MEMORY_ALLOCD;
22965b504601Sjiang wu - Sun Microsystems - Beijing China 
22975b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_addr_bind_handle(page_dma_handle, NULL, page_memp,
22985b504601Sjiang wu - Sun Microsystems - Beijing China 	    page_alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
22995b504601Sjiang wu - Sun Microsystems - Beijing China 	    NULL, &page_cookie, &page_ncookie) != DDI_DMA_MAPPED) {
23005b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
23015b504601Sjiang wu - Sun Microsystems - Beijing China 	}
23025b504601Sjiang wu - Sun Microsystems - Beijing China 
23035b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dmastate |= MPTSAS_DMA_HANDLE_BOUND;
23045b504601Sjiang wu - Sun Microsystems - Beijing China 
23055b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
23065b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Now we cycle through the state machine.  Here's what happens:
23075b504601Sjiang wu - Sun Microsystems - Beijing China 	 * 1. Read IO unit page 1.
23085b504601Sjiang wu - Sun Microsystems - Beijing China 	 * 2. Change the appropriate bits
23095b504601Sjiang wu - Sun Microsystems - Beijing China 	 * 3. Write the updated settings to IO unit page 1.
23105b504601Sjiang wu - Sun Microsystems - Beijing China 	 * 4. Reset the IO unit.
23115b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
23125b504601Sjiang wu - Sun Microsystems - Beijing China 
23135b504601Sjiang wu - Sun Microsystems - Beijing China 	sasioupage1 = (pMpi2SasIOUnitPage1_t)page_memp;
23145b504601Sjiang wu - Sun Microsystems - Beijing China 
23155b504601Sjiang wu - Sun Microsystems - Beijing China 	while (state != IOUC_DONE) {
23165b504601Sjiang wu - Sun Microsystems - Beijing China 		switch (state) {
23175b504601Sjiang wu - Sun Microsystems - Beijing China 		case IOUC_READ_PAGE1:
23185b504601Sjiang wu - Sun Microsystems - Beijing China 			page_number = 1;
23195b504601Sjiang wu - Sun Microsystems - Beijing China 			action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
23205b504601Sjiang wu - Sun Microsystems - Beijing China 			flags_length = (uint32_t)page1_size;
23215b504601Sjiang wu - Sun Microsystems - Beijing China 			flags_length |= ((uint32_t)(
23225b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_LAST_ELEMENT |
23235b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_END_OF_BUFFER |
23245b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
23255b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
23265b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_32_BIT_ADDRESSING |
23275b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_IOC_TO_HOST |
23285b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_END_OF_LIST) <<
23295b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SHIFT);
23305b504601Sjiang wu - Sun Microsystems - Beijing China 
23315b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
23325b504601Sjiang wu - Sun Microsystems - Beijing China 
23335b504601Sjiang wu - Sun Microsystems - Beijing China 		case IOUC_WRITE_PAGE1:
23345b504601Sjiang wu - Sun Microsystems - Beijing China 			page_number = 1;
23355b504601Sjiang wu - Sun Microsystems - Beijing China 			action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
23365b504601Sjiang wu - Sun Microsystems - Beijing China 			flags_length = (uint32_t)page1_size;
23375b504601Sjiang wu - Sun Microsystems - Beijing China 			flags_length |= ((uint32_t)(
23385b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_LAST_ELEMENT |
23395b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_END_OF_BUFFER |
23405b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
23415b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
23425b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_32_BIT_ADDRESSING |
23435b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_HOST_TO_IOC |
23445b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_END_OF_LIST) <<
23455b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SHIFT);
23465b504601Sjiang wu - Sun Microsystems - Beijing China 
23475b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
23485b504601Sjiang wu - Sun Microsystems - Beijing China 		}
23495b504601Sjiang wu - Sun Microsystems - Beijing China 
23505b504601Sjiang wu - Sun Microsystems - Beijing China 		bzero(recv_memp, sizeof (MPI2_CONFIG_REPLY));
23515b504601Sjiang wu - Sun Microsystems - Beijing China 		configreply = (pMpi2ConfigReply_t)recv_memp;
23525b504601Sjiang wu - Sun Microsystems - Beijing China 		recv_numbytes = sizeof (MPI2_CONFIG_REPLY);
23535b504601Sjiang wu - Sun Microsystems - Beijing China 
23545b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_send_extended_config_request_msg(mpt,
23555b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_CONFIG_ACTION_PAGE_HEADER,
23565b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT,
23575b504601Sjiang wu - Sun Microsystems - Beijing China 		    0, page_number, 0, 0, 0, 0)) {
23585b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
23595b504601Sjiang wu - Sun Microsystems - Beijing China 		}
23605b504601Sjiang wu - Sun Microsystems - Beijing China 
23615b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes,
23625b504601Sjiang wu - Sun Microsystems - Beijing China 		    recv_accessp)) {
23635b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
23645b504601Sjiang wu - Sun Microsystems - Beijing China 		}
23655b504601Sjiang wu - Sun Microsystems - Beijing China 
23665b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = ddi_get16(recv_accessp, &configreply->IOCStatus);
23675b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = MPTSAS_IOCSTATUS(iocstatus);
23685b504601Sjiang wu - Sun Microsystems - Beijing China 
23695b504601Sjiang wu - Sun Microsystems - Beijing China 		if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
23705b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_log(mpt, CE_WARN,
23715b504601Sjiang wu - Sun Microsystems - Beijing China 			    "mptsas_set_initiator_mode: read page hdr iocstatus"
23725b504601Sjiang wu - Sun Microsystems - Beijing China 			    ": 0x%x", iocstatus);
23735b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
23745b504601Sjiang wu - Sun Microsystems - Beijing China 		}
23755b504601Sjiang wu - Sun Microsystems - Beijing China 
23765b504601Sjiang wu - Sun Microsystems - Beijing China 		if (action != MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {
23775b504601Sjiang wu - Sun Microsystems - Beijing China 			bzero(page_memp, reply_size);
23785b504601Sjiang wu - Sun Microsystems - Beijing China 		}
23795b504601Sjiang wu - Sun Microsystems - Beijing China 
23805b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_send_extended_config_request_msg(mpt, action,
23815b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 0, page_number,
23825b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get8(recv_accessp, &configreply->Header.PageVersion),
23835b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get16(recv_accessp, &configreply->ExtPageLength),
23845b504601Sjiang wu - Sun Microsystems - Beijing China 		    flags_length, page_cookie.dmac_address)) {
23855b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
23865b504601Sjiang wu - Sun Microsystems - Beijing China 		}
23875b504601Sjiang wu - Sun Microsystems - Beijing China 
23885b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes,
23895b504601Sjiang wu - Sun Microsystems - Beijing China 		    recv_accessp)) {
23905b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
23915b504601Sjiang wu - Sun Microsystems - Beijing China 		}
23925b504601Sjiang wu - Sun Microsystems - Beijing China 
23935b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = ddi_get16(recv_accessp, &configreply->IOCStatus);
23945b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = MPTSAS_IOCSTATUS(iocstatus);
23955b504601Sjiang wu - Sun Microsystems - Beijing China 
23965b504601Sjiang wu - Sun Microsystems - Beijing China 		if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
23975b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_log(mpt, CE_WARN,
23985b504601Sjiang wu - Sun Microsystems - Beijing China 			    "mptsas_set_initiator_mode: IO unit config failed "
23995b504601Sjiang wu - Sun Microsystems - Beijing China 			    "for action %d, iocstatus = 0x%x", action,
24005b504601Sjiang wu - Sun Microsystems - Beijing China 			    iocstatus);
24015b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
24025b504601Sjiang wu - Sun Microsystems - Beijing China 		}
24035b504601Sjiang wu - Sun Microsystems - Beijing China 
24045b504601Sjiang wu - Sun Microsystems - Beijing China 		switch (state) {
24055b504601Sjiang wu - Sun Microsystems - Beijing China 		case IOUC_READ_PAGE1:
24065b504601Sjiang wu - Sun Microsystems - Beijing China 			if ((ddi_dma_sync(page_dma_handle, 0, 0,
24075b504601Sjiang wu - Sun Microsystems - Beijing China 			    DDI_DMA_SYNC_FORCPU)) != DDI_SUCCESS) {
24085b504601Sjiang wu - Sun Microsystems - Beijing China 				goto cleanup;
24095b504601Sjiang wu - Sun Microsystems - Beijing China 			}
24105b504601Sjiang wu - Sun Microsystems - Beijing China 
24115b504601Sjiang wu - Sun Microsystems - Beijing China 			/*
24125b504601Sjiang wu - Sun Microsystems - Beijing China 			 * All the PHYs should have the same settings, so we
24135b504601Sjiang wu - Sun Microsystems - Beijing China 			 * really only need to read 1 and use its config for
24145b504601Sjiang wu - Sun Microsystems - Beijing China 			 * every PHY.
24155b504601Sjiang wu - Sun Microsystems - Beijing China 			 */
24165b504601Sjiang wu - Sun Microsystems - Beijing China 
24175b504601Sjiang wu - Sun Microsystems - Beijing China 			cpdi[0] = ddi_get32(page_accessp,
24185b504601Sjiang wu - Sun Microsystems - Beijing China 			    &sasioupage1->PhyData[0].ControllerPhyDeviceInfo);
24195b504601Sjiang wu - Sun Microsystems - Beijing China 			port_flags = ddi_get8(page_accessp,
24205b504601Sjiang wu - Sun Microsystems - Beijing China 			    &sasioupage1->PhyData[0].PortFlags);
24215b504601Sjiang wu - Sun Microsystems - Beijing China 			port_flags |=
24225b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SASIOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG;
24235b504601Sjiang wu - Sun Microsystems - Beijing China 
24245b504601Sjiang wu - Sun Microsystems - Beijing China 			/*
24255b504601Sjiang wu - Sun Microsystems - Beijing China 			 * Write the configuration to SAS I/O unit page 1
24265b504601Sjiang wu - Sun Microsystems - Beijing China 			 */
24275b504601Sjiang wu - Sun Microsystems - Beijing China 
24285b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_log(mpt, CE_NOTE,
24295b504601Sjiang wu - Sun Microsystems - Beijing China 			    "?IO unit in target mode, changing to initiator");
24305b504601Sjiang wu - Sun Microsystems - Beijing China 
24315b504601Sjiang wu - Sun Microsystems - Beijing China 			/*
24325b504601Sjiang wu - Sun Microsystems - Beijing China 			 * Modify the PHY settings for initiator mode
24335b504601Sjiang wu - Sun Microsystems - Beijing China 			 */
24345b504601Sjiang wu - Sun Microsystems - Beijing China 
24355b504601Sjiang wu - Sun Microsystems - Beijing China 			cpdi[0] &= ~MPI2_SAS_DEVICE_INFO_SSP_TARGET;
24365b504601Sjiang wu - Sun Microsystems - Beijing China 			cpdi[0] |= (MPI2_SAS_DEVICE_INFO_SSP_INITIATOR |
24375b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SAS_DEVICE_INFO_STP_INITIATOR |
24385b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SAS_DEVICE_INFO_SMP_INITIATOR);
24395b504601Sjiang wu - Sun Microsystems - Beijing China 
24405b504601Sjiang wu - Sun Microsystems - Beijing China 			for (i = 0; i < mpt->m_num_phys; i++) {
24415b504601Sjiang wu - Sun Microsystems - Beijing China 				ddi_put32(page_accessp,
24425b504601Sjiang wu - Sun Microsystems - Beijing China 				    &sasioupage1->PhyData[i].
24435b504601Sjiang wu - Sun Microsystems - Beijing China 				    ControllerPhyDeviceInfo, cpdi[0]);
24445b504601Sjiang wu - Sun Microsystems - Beijing China 				ddi_put8(page_accessp,
24455b504601Sjiang wu - Sun Microsystems - Beijing China 				    &sasioupage1->PhyData[i].
24465b504601Sjiang wu - Sun Microsystems - Beijing China 				    PortFlags, port_flags);
24475b504601Sjiang wu - Sun Microsystems - Beijing China 				/*
24485b504601Sjiang wu - Sun Microsystems - Beijing China 				 * update phy information
24495b504601Sjiang wu - Sun Microsystems - Beijing China 				 */
24505b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_phy_info[i].phy_device_type = cpdi[0];
24515b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_phy_info[i].port_flags = port_flags;
24525b504601Sjiang wu - Sun Microsystems - Beijing China 			}
24535b504601Sjiang wu - Sun Microsystems - Beijing China 
24545b504601Sjiang wu - Sun Microsystems - Beijing China 			if ((ddi_dma_sync(page_dma_handle, 0, 0,
24555b504601Sjiang wu - Sun Microsystems - Beijing China 			    DDI_DMA_SYNC_FORDEV)) != DDI_SUCCESS) {
24565b504601Sjiang wu - Sun Microsystems - Beijing China 				goto cleanup;
24575b504601Sjiang wu - Sun Microsystems - Beijing China 			}
24585b504601Sjiang wu - Sun Microsystems - Beijing China 
24595b504601Sjiang wu - Sun Microsystems - Beijing China 			state = IOUC_WRITE_PAGE1;
24605b504601Sjiang wu - Sun Microsystems - Beijing China 
24615b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
24625b504601Sjiang wu - Sun Microsystems - Beijing China 
24635b504601Sjiang wu - Sun Microsystems - Beijing China 		case IOUC_WRITE_PAGE1:
24645b504601Sjiang wu - Sun Microsystems - Beijing China 			/*
24655b504601Sjiang wu - Sun Microsystems - Beijing China 			 * If we're here, we wrote IO unit page 1 succesfully.
24665b504601Sjiang wu - Sun Microsystems - Beijing China 			 */
24675b504601Sjiang wu - Sun Microsystems - Beijing China 			state = IOUC_DONE;
24685b504601Sjiang wu - Sun Microsystems - Beijing China 
24695b504601Sjiang wu - Sun Microsystems - Beijing China 			rval = DDI_SUCCESS;
24705b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
24715b504601Sjiang wu - Sun Microsystems - Beijing China 		}
24725b504601Sjiang wu - Sun Microsystems - Beijing China 	}
24735b504601Sjiang wu - Sun Microsystems - Beijing China 
24745b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
24755b504601Sjiang wu - Sun Microsystems - Beijing China 	 * We need to do a Message Unit Reset in order to activate the changes.
24765b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
24775b504601Sjiang wu - Sun Microsystems - Beijing China 	mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET;
24785b504601Sjiang wu - Sun Microsystems - Beijing China 	rval = mptsas_init_chip(mpt, FALSE);
24795b504601Sjiang wu - Sun Microsystems - Beijing China 
24805b504601Sjiang wu - Sun Microsystems - Beijing China cleanup:
24815b504601Sjiang wu - Sun Microsystems - Beijing China 	if (recv_dmastate & MPTSAS_DMA_HANDLE_BOUND)
24825b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_unbind_handle(recv_dma_handle);
24835b504601Sjiang wu - Sun Microsystems - Beijing China 	if (page_dmastate & MPTSAS_DMA_HANDLE_BOUND)
24845b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_unbind_handle(page_dma_handle);
24855b504601Sjiang wu - Sun Microsystems - Beijing China 	if (recv_dmastate & MPTSAS_DMA_MEMORY_ALLOCD)
24865b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_mem_free(&recv_accessp);
24875b504601Sjiang wu - Sun Microsystems - Beijing China 	if (page_dmastate & MPTSAS_DMA_MEMORY_ALLOCD)
24885b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_mem_free(&page_accessp);
24895b504601Sjiang wu - Sun Microsystems - Beijing China 	if (recv_dmastate & MPTSAS_DMA_HANDLE_ALLOCD)
24905b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&recv_dma_handle);
24915b504601Sjiang wu - Sun Microsystems - Beijing China 	if (page_dmastate & MPTSAS_DMA_HANDLE_ALLOCD)
24925b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&page_dma_handle);
24935b504601Sjiang wu - Sun Microsystems - Beijing China 
24945b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
24955b504601Sjiang wu - Sun Microsystems - Beijing China }
24965b504601Sjiang wu - Sun Microsystems - Beijing China 
24975b504601Sjiang wu - Sun Microsystems - Beijing China /*
24985b504601Sjiang wu - Sun Microsystems - Beijing China  * mptsas_get_manufacture_page5
24995b504601Sjiang wu - Sun Microsystems - Beijing China  *
25005b504601Sjiang wu - Sun Microsystems - Beijing China  * This function will retrieve the base WWID from the adapter.  Since this
25015b504601Sjiang wu - Sun Microsystems - Beijing China  * function is only called during the initialization process, use handshaking.
25025b504601Sjiang wu - Sun Microsystems - Beijing China  */
25035b504601Sjiang wu - Sun Microsystems - Beijing China int
25045b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_manufacture_page5(mptsas_t *mpt)
25055b504601Sjiang wu - Sun Microsystems - Beijing China {
25065b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_attr_t			recv_dma_attrs, page_dma_attrs;
25075b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_cookie_t		recv_cookie, page_cookie;
25085b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_handle_t		recv_dma_handle, page_dma_handle;
25095b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_acc_handle_t		recv_accessp, page_accessp;
25105b504601Sjiang wu - Sun Microsystems - Beijing China 	size_t				recv_alloc_len, page_alloc_len;
25115b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2ConfigReply_t		configreply;
25125b504601Sjiang wu - Sun Microsystems - Beijing China 	uint_t				recv_ncookie, page_ncookie;
25135b504601Sjiang wu - Sun Microsystems - Beijing China 	caddr_t				recv_memp, page_memp;
25145b504601Sjiang wu - Sun Microsystems - Beijing China 	int				recv_numbytes;
25155b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2ManufacturingPage5_t	m5;
25165b504601Sjiang wu - Sun Microsystems - Beijing China 	int				recv_dmastate = 0;
25175b504601Sjiang wu - Sun Microsystems - Beijing China 	int				page_dmastate = 0;
25185b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t			flagslength;
25195b504601Sjiang wu - Sun Microsystems - Beijing China 	int				rval = DDI_SUCCESS;
25205b504601Sjiang wu - Sun Microsystems - Beijing China 	uint_t				iocstatus;
25215b504601Sjiang wu - Sun Microsystems - Beijing China 
25225b504601Sjiang wu - Sun Microsystems - Beijing China 	MPTSAS_DISABLE_INTR(mpt);
25235b504601Sjiang wu - Sun Microsystems - Beijing China 
25245b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_send_config_request_msg(mpt, MPI2_CONFIG_ACTION_PAGE_HEADER,
25255b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_CONFIG_PAGETYPE_MANUFACTURING, 0, 5, 0, 0, 0, 0)) {
25265b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
25275b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
25285b504601Sjiang wu - Sun Microsystems - Beijing China 	}
25295b504601Sjiang wu - Sun Microsystems - Beijing China 
25305b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
25315b504601Sjiang wu - Sun Microsystems - Beijing China 	 * dynamically create a customized dma attribute structure
25325b504601Sjiang wu - Sun Microsystems - Beijing China 	 * that describes the MPT's config reply page request structure.
25335b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
25345b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dma_attrs = mpt->m_msg_dma_attr;
25355b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dma_attrs.dma_attr_sgllen = 1;
25365b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_REPLY));
25375b504601Sjiang wu - Sun Microsystems - Beijing China 
25385b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_alloc_handle(mpt->m_dip, &recv_dma_attrs,
25395b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SLEEP, NULL, &recv_dma_handle) != DDI_SUCCESS) {
25405b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN,
25415b504601Sjiang wu - Sun Microsystems - Beijing China 		    "(unable to allocate dma handle.");
25425b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
25435b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
25445b504601Sjiang wu - Sun Microsystems - Beijing China 	}
25455b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dmastate |= MPTSAS_DMA_HANDLE_ALLOCD;
25465b504601Sjiang wu - Sun Microsystems - Beijing China 
25475b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_mem_alloc(recv_dma_handle,
25485b504601Sjiang wu - Sun Microsystems - Beijing China 	    (sizeof (MPI2_CONFIG_REPLY)),
25495b504601Sjiang wu - Sun Microsystems - Beijing China 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
25505b504601Sjiang wu - Sun Microsystems - Beijing China 	    &recv_memp, &recv_alloc_len, &recv_accessp) != DDI_SUCCESS) {
25515b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN,
25525b504601Sjiang wu - Sun Microsystems - Beijing China 		    "unable to allocate config_reply structure.");
25535b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
25545b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
25555b504601Sjiang wu - Sun Microsystems - Beijing China 	}
25565b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dmastate |= MPTSAS_DMA_MEMORY_ALLOCD;
25575b504601Sjiang wu - Sun Microsystems - Beijing China 
25585b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_addr_bind_handle(recv_dma_handle, NULL, recv_memp,
25595b504601Sjiang wu - Sun Microsystems - Beijing China 	    recv_alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
25605b504601Sjiang wu - Sun Microsystems - Beijing China 	    NULL, &recv_cookie, &recv_ncookie) != DDI_DMA_MAPPED) {
25615b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "unable to bind DMA resources.");
25625b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
25635b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
25645b504601Sjiang wu - Sun Microsystems - Beijing China 	}
25655b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dmastate |= MPTSAS_DMA_HANDLE_BOUND;
25665b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(recv_memp, sizeof (MPI2_CONFIG_REPLY));
25675b504601Sjiang wu - Sun Microsystems - Beijing China 	configreply = (pMpi2ConfigReply_t)recv_memp;
25685b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_numbytes = sizeof (MPI2_CONFIG_REPLY);
25695b504601Sjiang wu - Sun Microsystems - Beijing China 
25705b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
25715b504601Sjiang wu - Sun Microsystems - Beijing China 	 * get config reply message
25725b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
25735b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes,
25745b504601Sjiang wu - Sun Microsystems - Beijing China 	    recv_accessp)) {
25755b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
25765b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
25775b504601Sjiang wu - Sun Microsystems - Beijing China 	}
25785b504601Sjiang wu - Sun Microsystems - Beijing China 
25795b504601Sjiang wu - Sun Microsystems - Beijing China 	if (iocstatus = ddi_get16(recv_accessp, &configreply->IOCStatus)) {
25805b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "mptsas_get_manufacture_page5 update: "
25815b504601Sjiang wu - Sun Microsystems - Beijing China 		    "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
25825b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get32(recv_accessp, &configreply->IOCLogInfo));
25835b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
25845b504601Sjiang wu - Sun Microsystems - Beijing China 	}
25855b504601Sjiang wu - Sun Microsystems - Beijing China 
25865b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
25875b504601Sjiang wu - Sun Microsystems - Beijing China 	 * dynamically create a customized dma attribute structure
25885b504601Sjiang wu - Sun Microsystems - Beijing China 	 * that describes the MPT's config page structure.
25895b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
25905b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dma_attrs = mpt->m_msg_dma_attr;
25915b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dma_attrs.dma_attr_sgllen = 1;
25925b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_PAGE_MAN_5));
25935b504601Sjiang wu - Sun Microsystems - Beijing China 
25945b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_alloc_handle(mpt->m_dip, &page_dma_attrs,
25955b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SLEEP, NULL, &page_dma_handle) != DDI_SUCCESS) {
25965b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN,
25975b504601Sjiang wu - Sun Microsystems - Beijing China 		    "(unable to allocate dma handle.");
25985b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
25995b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
26005b504601Sjiang wu - Sun Microsystems - Beijing China 	}
26015b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dmastate |= MPTSAS_DMA_HANDLE_ALLOCD;
26025b504601Sjiang wu - Sun Microsystems - Beijing China 
26035b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_mem_alloc(page_dma_handle,
26045b504601Sjiang wu - Sun Microsystems - Beijing China 	    (sizeof (MPI2_CONFIG_PAGE_MAN_5)),
26055b504601Sjiang wu - Sun Microsystems - Beijing China 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
26065b504601Sjiang wu - Sun Microsystems - Beijing China 	    &page_memp, &page_alloc_len, &page_accessp) != DDI_SUCCESS) {
26075b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN,
26085b504601Sjiang wu - Sun Microsystems - Beijing China 		    "unable to allocate manufacturing page structure.");
26095b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
26105b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
26115b504601Sjiang wu - Sun Microsystems - Beijing China 	}
26125b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dmastate |= MPTSAS_DMA_MEMORY_ALLOCD;
26135b504601Sjiang wu - Sun Microsystems - Beijing China 
26145b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_addr_bind_handle(page_dma_handle, NULL, page_memp,
26155b504601Sjiang wu - Sun Microsystems - Beijing China 	    page_alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
26165b504601Sjiang wu - Sun Microsystems - Beijing China 	    NULL, &page_cookie, &page_ncookie) != DDI_DMA_MAPPED) {
26175b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "unable to bind DMA resources.");
26185b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
26195b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
26205b504601Sjiang wu - Sun Microsystems - Beijing China 	}
26215b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dmastate |= MPTSAS_DMA_HANDLE_BOUND;
26225b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(page_memp, sizeof (MPI2_CONFIG_PAGE_MAN_5));
26235b504601Sjiang wu - Sun Microsystems - Beijing China 	m5 = (pMpi2ManufacturingPage5_t)page_memp;
26245b504601Sjiang wu - Sun Microsystems - Beijing China 
26255b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
26265b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Give reply address to IOC to store config page in and send
26275b504601Sjiang wu - Sun Microsystems - Beijing China 	 * config request out.
26285b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
26295b504601Sjiang wu - Sun Microsystems - Beijing China 
26305b504601Sjiang wu - Sun Microsystems - Beijing China 	flagslength = sizeof (MPI2_CONFIG_PAGE_MAN_5);
26315b504601Sjiang wu - Sun Microsystems - Beijing China 	flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT |
26325b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
26335b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_SYSTEM_ADDRESS | MPI2_SGE_FLAGS_32_BIT_ADDRESSING |
26345b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_IOC_TO_HOST |
26355b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
26365b504601Sjiang wu - Sun Microsystems - Beijing China 
26375b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_send_config_request_msg(mpt,
26385b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_CONFIG_ACTION_PAGE_READ_CURRENT,
26395b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_CONFIG_PAGETYPE_MANUFACTURING, 0, 5,
26405b504601Sjiang wu - Sun Microsystems - Beijing China 	    ddi_get8(recv_accessp, &configreply->Header.PageVersion),
26415b504601Sjiang wu - Sun Microsystems - Beijing China 	    ddi_get8(recv_accessp, &configreply->Header.PageLength),
26425b504601Sjiang wu - Sun Microsystems - Beijing China 	    flagslength, page_cookie.dmac_address)) {
26435b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
26445b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
26455b504601Sjiang wu - Sun Microsystems - Beijing China 	}
26465b504601Sjiang wu - Sun Microsystems - Beijing China 
26475b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
26485b504601Sjiang wu - Sun Microsystems - Beijing China 	 * get reply view handshake
26495b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
26505b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes,
26515b504601Sjiang wu - Sun Microsystems - Beijing China 	    recv_accessp)) {
26525b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
26535b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
26545b504601Sjiang wu - Sun Microsystems - Beijing China 	}
26555b504601Sjiang wu - Sun Microsystems - Beijing China 
26565b504601Sjiang wu - Sun Microsystems - Beijing China 	if (iocstatus = ddi_get16(recv_accessp, &configreply->IOCStatus)) {
26575b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "mptsas_get_manufacture_page5 config: "
26585b504601Sjiang wu - Sun Microsystems - Beijing China 		    "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
26595b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get32(recv_accessp, &configreply->IOCLogInfo));
26605b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
26615b504601Sjiang wu - Sun Microsystems - Beijing China 	}
26625b504601Sjiang wu - Sun Microsystems - Beijing China 
26635b504601Sjiang wu - Sun Microsystems - Beijing China 	(void) ddi_dma_sync(page_dma_handle, 0, 0, DDI_DMA_SYNC_FORCPU);
26645b504601Sjiang wu - Sun Microsystems - Beijing China 
26655b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
26665b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Fusion-MPT stores fields in little-endian format.  This is
26675b504601Sjiang wu - Sun Microsystems - Beijing China 	 * why the low-order 32 bits are stored first.
26685b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
26695b504601Sjiang wu - Sun Microsystems - Beijing China 	mpt->un.sasaddr.m_base_wwid_lo =
26705b504601Sjiang wu - Sun Microsystems - Beijing China 	    ddi_get32(page_accessp, (uint32_t *)(void *)&m5->Phy[0].WWID);
26715b504601Sjiang wu - Sun Microsystems - Beijing China 	mpt->un.sasaddr.m_base_wwid_hi =
26725b504601Sjiang wu - Sun Microsystems - Beijing China 	    ddi_get32(page_accessp, (uint32_t *)(void *)&m5->Phy[0].WWID + 1);
26735b504601Sjiang wu - Sun Microsystems - Beijing China 
26745b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_prop_update_int64(DDI_DEV_T_NONE, mpt->m_dip,
26755b504601Sjiang wu - Sun Microsystems - Beijing China 	    "base-wwid", mpt->un.m_base_wwid) != DDI_PROP_SUCCESS) {
26765b504601Sjiang wu - Sun Microsystems - Beijing China 		NDBG2(("%s%d: failed to create base-wwid property",
26775b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_driver_name(mpt->m_dip), ddi_get_instance(mpt->m_dip)));
26785b504601Sjiang wu - Sun Microsystems - Beijing China 	}
26795b504601Sjiang wu - Sun Microsystems - Beijing China 
26805b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
26815b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Set the number of PHYs present.
26825b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
26835b504601Sjiang wu - Sun Microsystems - Beijing China 	mpt->m_num_phys = ddi_get8(page_accessp, (uint8_t *)&m5->NumPhys);
26845b504601Sjiang wu - Sun Microsystems - Beijing China 
26855b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_prop_update_int(DDI_DEV_T_NONE, mpt->m_dip,
26865b504601Sjiang wu - Sun Microsystems - Beijing China 	    "num-phys", mpt->m_num_phys) != DDI_PROP_SUCCESS) {
26875b504601Sjiang wu - Sun Microsystems - Beijing China 		NDBG2(("%s%d: failed to create num-phys property",
26885b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_driver_name(mpt->m_dip), ddi_get_instance(mpt->m_dip)));
26895b504601Sjiang wu - Sun Microsystems - Beijing China 	}
26905b504601Sjiang wu - Sun Microsystems - Beijing China 
26915b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_log(mpt, CE_NOTE, "!mpt%d: Initiator WWNs: 0x%016llx-0x%016llx",
26925b504601Sjiang wu - Sun Microsystems - Beijing China 	    mpt->m_instance, (unsigned long long)mpt->un.m_base_wwid,
26935b504601Sjiang wu - Sun Microsystems - Beijing China 	    (unsigned long long)mpt->un.m_base_wwid + mpt->m_num_phys - 1);
26945b504601Sjiang wu - Sun Microsystems - Beijing China 
26955b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((mptsas_check_dma_handle(recv_dma_handle) != DDI_SUCCESS) ||
26965b504601Sjiang wu - Sun Microsystems - Beijing China 	    (mptsas_check_dma_handle(page_dma_handle) != DDI_SUCCESS)) {
26975b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
26985b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
26995b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
27005b504601Sjiang wu - Sun Microsystems - Beijing China 	}
27015b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((mptsas_check_acc_handle(recv_accessp) != DDI_SUCCESS) ||
27025b504601Sjiang wu - Sun Microsystems - Beijing China 	    (mptsas_check_acc_handle(page_accessp) != DDI_SUCCESS)) {
27035b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
27045b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
27055b504601Sjiang wu - Sun Microsystems - Beijing China 	}
27065b504601Sjiang wu - Sun Microsystems - Beijing China done:
27075b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
27085b504601Sjiang wu - Sun Microsystems - Beijing China 	 * free up memory
27095b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
27105b504601Sjiang wu - Sun Microsystems - Beijing China 	if (recv_dmastate & MPTSAS_DMA_HANDLE_BOUND)
27115b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_unbind_handle(recv_dma_handle);
27125b504601Sjiang wu - Sun Microsystems - Beijing China 	if (page_dmastate & MPTSAS_DMA_HANDLE_BOUND)
27135b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_unbind_handle(page_dma_handle);
27145b504601Sjiang wu - Sun Microsystems - Beijing China 	if (recv_dmastate & MPTSAS_DMA_MEMORY_ALLOCD)
27155b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_mem_free(&recv_accessp);
27165b504601Sjiang wu - Sun Microsystems - Beijing China 	if (page_dmastate & MPTSAS_DMA_MEMORY_ALLOCD)
27175b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_mem_free(&page_accessp);
27185b504601Sjiang wu - Sun Microsystems - Beijing China 	if (recv_dmastate & MPTSAS_DMA_HANDLE_ALLOCD)
27195b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&recv_dma_handle);
27205b504601Sjiang wu - Sun Microsystems - Beijing China 	if (page_dmastate & MPTSAS_DMA_HANDLE_ALLOCD)
27215b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&page_dma_handle);
27225b504601Sjiang wu - Sun Microsystems - Beijing China 
27235b504601Sjiang wu - Sun Microsystems - Beijing China 	MPTSAS_ENABLE_INTR(mpt);
27245b504601Sjiang wu - Sun Microsystems - Beijing China 
27255b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
27265b504601Sjiang wu - Sun Microsystems - Beijing China }
2727