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 /*
239814ff7fSYong-Feng Du  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24e18306b1SDan McDonald  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
25f7d0d869SDan McDonald  * Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved.
26ed7418aeSAndy Giles  * Copyright (c) 2014, Tegile Systems Inc. All rights reserved.
27*882fdc88SHans Rosenfeld  * Copyright (c) 2019, Joyent, Inc.
285b504601Sjiang wu - Sun Microsystems - Beijing China  */
295b504601Sjiang wu - Sun Microsystems - Beijing China 
305b504601Sjiang wu - Sun Microsystems - Beijing China /*
31c8f74a56SAda  * Copyright (c) 2000 to 2010, LSI Corporation.
325b504601Sjiang wu - Sun Microsystems - Beijing China  * All rights reserved.
335b504601Sjiang wu - Sun Microsystems - Beijing China  *
345b504601Sjiang wu - Sun Microsystems - Beijing China  * Redistribution and use in source and binary forms of all code within
355b504601Sjiang wu - Sun Microsystems - Beijing China  * this file that is exclusively owned by LSI, with or without
365b504601Sjiang wu - Sun Microsystems - Beijing China  * modification, is permitted provided that, in addition to the CDDL 1.0
375b504601Sjiang wu - Sun Microsystems - Beijing China  * License requirements, the following conditions are met:
385b504601Sjiang wu - Sun Microsystems - Beijing China  *
395b504601Sjiang wu - Sun Microsystems - Beijing China  *    Neither the name of the author nor the names of its contributors may be
405b504601Sjiang wu - Sun Microsystems - Beijing China  *    used to endorse or promote products derived from this software without
415b504601Sjiang wu - Sun Microsystems - Beijing China  *    specific prior written permission.
425b504601Sjiang wu - Sun Microsystems - Beijing China  *
435b504601Sjiang wu - Sun Microsystems - Beijing China  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
445b504601Sjiang wu - Sun Microsystems - Beijing China  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
455b504601Sjiang wu - Sun Microsystems - Beijing China  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
465b504601Sjiang wu - Sun Microsystems - Beijing China  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
475b504601Sjiang wu - Sun Microsystems - Beijing China  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
485b504601Sjiang wu - Sun Microsystems - Beijing China  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
495b504601Sjiang wu - Sun Microsystems - Beijing China  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
505b504601Sjiang wu - Sun Microsystems - Beijing China  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
515b504601Sjiang wu - Sun Microsystems - Beijing China  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
525b504601Sjiang wu - Sun Microsystems - Beijing China  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
535b504601Sjiang wu - Sun Microsystems - Beijing China  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
545b504601Sjiang wu - Sun Microsystems - Beijing China  * DAMAGE.
555b504601Sjiang wu - Sun Microsystems - Beijing China  */
565b504601Sjiang wu - Sun Microsystems - Beijing China 
575b504601Sjiang wu - Sun Microsystems - Beijing China /*
585b504601Sjiang wu - Sun Microsystems - Beijing China  * mptsas_impl - This file contains all the basic functions for communicating
595b504601Sjiang wu - Sun Microsystems - Beijing China  * to MPT based hardware.
605b504601Sjiang wu - Sun Microsystems - Beijing China  */
615b504601Sjiang wu - Sun Microsystems - Beijing China 
625b504601Sjiang wu - Sun Microsystems - Beijing China #if defined(lint) || defined(DEBUG)
635b504601Sjiang wu - Sun Microsystems - Beijing China #define	MPTSAS_DEBUG
645b504601Sjiang wu - Sun Microsystems - Beijing China #endif
655b504601Sjiang wu - Sun Microsystems - Beijing China 
665b504601Sjiang wu - Sun Microsystems - Beijing China /*
675b504601Sjiang wu - Sun Microsystems - Beijing China  * standard header files
685b504601Sjiang wu - Sun Microsystems - Beijing China  */
695b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/note.h>
705b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/scsi.h>
715b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/pci.h>
725b504601Sjiang wu - Sun Microsystems - Beijing China 
735b504601Sjiang wu - Sun Microsystems - Beijing China #pragma pack(1)
745b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
755b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
765b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
775b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
785b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
795b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
8076a4caf6SAda #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
815b504601Sjiang wu - Sun Microsystems - Beijing China #pragma pack()
825b504601Sjiang wu - Sun Microsystems - Beijing China 
835b504601Sjiang wu - Sun Microsystems - Beijing China /*
845b504601Sjiang wu - Sun Microsystems - Beijing China  * private header files.
855b504601Sjiang wu - Sun Microsystems - Beijing China  */
865b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
87f2e8686eSxun ni - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h>
885b504601Sjiang wu - Sun Microsystems - Beijing China 
895b504601Sjiang wu - Sun Microsystems - Beijing China /*
905b504601Sjiang wu - Sun Microsystems - Beijing China  * FMA header files.
915b504601Sjiang wu - Sun Microsystems - Beijing China  */
925b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/fm/io/ddi.h>
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
mptsas_ioc_event_cmdq_add(mptsas_t * mpt,m_event_struct_t * cmd)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
mptsas_ioc_event_cmdq_delete(mptsas_t * mpt,m_event_struct_t * cmd)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 *
mptsas_ioc_event_find_by_cmd(mptsas_t * mpt,struct mptsas_cmd * cmd)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
mptsas_destroy_ioc_event_cmd(mptsas_t * mpt)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
mptsas_start_config_page_access(mptsas_t * mpt,mptsas_cmd_t * cmd)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;
207940efceeSAndy Giles 	uint32_t		length, flagslength;
208940efceeSAndy Giles 	uint64_t		request_desc;
2095b504601Sjiang wu - Sun Microsystems - Beijing China 
2105b504601Sjiang wu - Sun Microsystems - Beijing China 	ASSERT(mutex_owned(&mpt->m_mutex));
2115b504601Sjiang wu - Sun Microsystems - Beijing China 
2125b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
2135b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Point to the correct message and clear it as well as the global
2145b504601Sjiang wu - Sun Microsystems - Beijing China 	 * config page memory.
2155b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
2165b504601Sjiang wu - Sun Microsystems - Beijing China 	request = (pMpi2ConfigRequest_t)(mpt->m_req_frame +
2175b504601Sjiang wu - Sun Microsystems - Beijing China 	    (mpt->m_req_frame_size * cmd->cmd_slot));
2185b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(request, mpt->m_req_frame_size);
2195b504601Sjiang wu - Sun Microsystems - Beijing China 
2205b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
2215b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Form the request message.
2225b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
2235b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &request->Function,
2245b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_FUNCTION_CONFIG);
2255b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &request->Action, config->action);
2265b504601Sjiang wu - Sun Microsystems - Beijing China 	direction = MPI2_SGE_FLAGS_IOC_TO_HOST;
2275b504601Sjiang wu - Sun Microsystems - Beijing China 	length = 0;
2285b504601Sjiang wu - Sun Microsystems - Beijing China 	sge = (pMpi2SGESimple64_t)&request->PageBufferSGE;
2295b504601Sjiang wu - Sun Microsystems - Beijing China 	if (config->action == MPI2_CONFIG_ACTION_PAGE_HEADER) {
2305b504601Sjiang wu - Sun Microsystems - Beijing China 		if (config->page_type > MPI2_CONFIG_PAGETYPE_MASK) {
2315b504601Sjiang wu - Sun Microsystems - Beijing China 			ddi_put8(mpt->m_acc_req_frame_hdl,
2325b504601Sjiang wu - Sun Microsystems - Beijing China 			    &request->Header.PageType,
2335b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_CONFIG_PAGETYPE_EXTENDED);
2345b504601Sjiang wu - Sun Microsystems - Beijing China 			ddi_put8(mpt->m_acc_req_frame_hdl,
2355b504601Sjiang wu - Sun Microsystems - Beijing China 			    &request->ExtPageType, config->page_type);
2365b504601Sjiang wu - Sun Microsystems - Beijing China 		} else {
2375b504601Sjiang wu - Sun Microsystems - Beijing China 			ddi_put8(mpt->m_acc_req_frame_hdl,
2385b504601Sjiang wu - Sun Microsystems - Beijing China 			    &request->Header.PageType, config->page_type);
2395b504601Sjiang wu - Sun Microsystems - Beijing China 		}
2405b504601Sjiang wu - Sun Microsystems - Beijing China 	} else {
2415b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put8(mpt->m_acc_req_frame_hdl, &request->ExtPageType,
2425b504601Sjiang wu - Sun Microsystems - Beijing China 		    config->ext_page_type);
2435b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put16(mpt->m_acc_req_frame_hdl, &request->ExtPageLength,
2445b504601Sjiang wu - Sun Microsystems - Beijing China 		    config->ext_page_length);
2455b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put8(mpt->m_acc_req_frame_hdl, &request->Header.PageType,
2465b504601Sjiang wu - Sun Microsystems - Beijing China 		    config->page_type);
2475b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put8(mpt->m_acc_req_frame_hdl, &request->Header.PageLength,
2485b504601Sjiang wu - Sun Microsystems - Beijing China 		    config->page_length);
2495b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put8(mpt->m_acc_req_frame_hdl,
2505b504601Sjiang wu - Sun Microsystems - Beijing China 		    &request->Header.PageVersion, config->page_version);
2515b504601Sjiang wu - Sun Microsystems - Beijing China 		if ((config->page_type & MPI2_CONFIG_PAGETYPE_MASK) ==
2525b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_CONFIG_PAGETYPE_EXTENDED) {
2535b504601Sjiang wu - Sun Microsystems - Beijing China 			length = config->ext_page_length * 4;
2545b504601Sjiang wu - Sun Microsystems - Beijing China 		} else {
2555b504601Sjiang wu - Sun Microsystems - Beijing China 			length = config->page_length * 4;
2565b504601Sjiang wu - Sun Microsystems - Beijing China 		}
2575b504601Sjiang wu - Sun Microsystems - Beijing China 
2585b504601Sjiang wu - Sun Microsystems - Beijing China 		if (config->action == MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {
2595b504601Sjiang wu - Sun Microsystems - Beijing China 			direction = MPI2_SGE_FLAGS_HOST_TO_IOC;
2605b504601Sjiang wu - Sun Microsystems - Beijing China 		}
2615b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.Low,
2625b504601Sjiang wu - Sun Microsystems - Beijing China 		    (uint32_t)cmd->cmd_dma_addr);
2635b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.High,
2645b504601Sjiang wu - Sun Microsystems - Beijing China 		    (uint32_t)(cmd->cmd_dma_addr >> 32));
2655b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2665b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &request->Header.PageNumber,
2675b504601Sjiang wu - Sun Microsystems - Beijing China 	    config->page_number);
2685b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_acc_req_frame_hdl, &request->PageAddress,
2695b504601Sjiang wu - Sun Microsystems - Beijing China 	    config->page_address);
2705b504601Sjiang wu - Sun Microsystems - Beijing China 	flagslength = ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT |
2715b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_END_OF_BUFFER |
2725b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
2735b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
2745b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_64_BIT_ADDRESSING |
2755b504601Sjiang wu - Sun Microsystems - Beijing China 	    direction |
2765b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
2775b504601Sjiang wu - Sun Microsystems - Beijing China 	flagslength |= length;
2785b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_acc_req_frame_hdl, &sge->FlagsLength, flagslength);
2795b504601Sjiang wu - Sun Microsystems - Beijing China 
2805b504601Sjiang wu - Sun Microsystems - Beijing China 	(void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0,
2815b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SYNC_FORDEV);
282940efceeSAndy Giles 	request_desc = (cmd->cmd_slot << 16) +
2835b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
284a0ac5a9eSToomas Soome 	cmd->cmd_rfm = 0;
285940efceeSAndy Giles 	MPTSAS_START_CMD(mpt, request_desc);
2865b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
2875b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_SUCCESS) ||
2885b504601Sjiang wu - Sun Microsystems - Beijing China 	    (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
2895b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_SUCCESS)) {
2905b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
2915b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2925b504601Sjiang wu - Sun Microsystems - Beijing China }
2935b504601Sjiang wu - Sun Microsystems - Beijing China 
2945b504601Sjiang wu - Sun Microsystems - Beijing China int
mptsas_access_config_page(mptsas_t * mpt,uint8_t action,uint8_t page_type,uint8_t page_number,uint32_t page_address,int (* callback)(mptsas_t *,caddr_t,ddi_acc_handle_t,uint16_t,uint32_t,va_list),...)2955b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_access_config_page(mptsas_t *mpt, uint8_t action, uint8_t page_type,
2965b504601Sjiang wu - Sun Microsystems - Beijing China     uint8_t page_number, uint32_t page_address, int (*callback) (mptsas_t *,
2975b504601Sjiang wu - Sun Microsystems - Beijing China     caddr_t, ddi_acc_handle_t, uint16_t, uint32_t, va_list), ...)
2985b504601Sjiang wu - Sun Microsystems - Beijing China {
2995b504601Sjiang wu - Sun Microsystems - Beijing China 	va_list			ap;
3005b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_attr_t		attrs;
3015b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_cookie_t	cookie;
3025b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_acc_handle_t	accessp;
303a9b51062SAda 	size_t			len = 0;
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;
312f7d0d869SDan McDonald 	boolean_t		free_dma = B_FALSE;
3135b504601Sjiang wu - Sun Microsystems - Beijing China 
3145b504601Sjiang wu - Sun Microsystems - Beijing China 	va_start(ap, callback);
3155b504601Sjiang wu - Sun Microsystems - Beijing China 	ASSERT(mutex_owned(&mpt->m_mutex));
3165b504601Sjiang wu - Sun Microsystems - Beijing China 
3175b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
3185b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Get a command from the pool.
3195b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
3205b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((rval = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
3215b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_NOTE, "command pool is full for config "
3225b504601Sjiang wu - Sun Microsystems - Beijing China 		    "page request");
3235b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
3245b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
3255b504601Sjiang wu - Sun Microsystems - Beijing China 	}
3265b504601Sjiang wu - Sun Microsystems - Beijing China 	config_flags |= MPTSAS_REQUEST_POOL_CMD;
3275b504601Sjiang wu - Sun Microsystems - Beijing China 
3285b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero((caddr_t)cmd, sizeof (*cmd));
3295b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero((caddr_t)pkt, scsi_pkt_size());
3305b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero((caddr_t)&config, sizeof (config));
3315b504601Sjiang wu - Sun Microsystems - Beijing China 
3325b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
3335b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Save the data for this request to be used in the call to start the
3345b504601Sjiang wu - Sun Microsystems - Beijing China 	 * config header request.
3355b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
3365b504601Sjiang wu - Sun Microsystems - Beijing China 	config.action = MPI2_CONFIG_ACTION_PAGE_HEADER;
3375b504601Sjiang wu - Sun Microsystems - Beijing China 	config.page_type = page_type;
3385b504601Sjiang wu - Sun Microsystems - Beijing China 	config.page_number = page_number;
3395b504601Sjiang wu - Sun Microsystems - Beijing China 	config.page_address = page_address;
3405b504601Sjiang wu - Sun Microsystems - Beijing China 
3415b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
3425b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Form a blank cmd/pkt to store the acknowledgement message
3435b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
3445b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_ha_private	= (opaque_t)&config;
3455b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_flags		= FLAG_HEAD;
3465b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_time		= 60;
3475b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_pkt		= pkt;
3485b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_flags		= CFLAG_CMDIOC | CFLAG_CONFIG;
3495b504601Sjiang wu - Sun Microsystems - Beijing China 
3505b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
3515b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Save the config header request message in a slot.
3525b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
3535b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_save_cmd(mpt, cmd) == TRUE) {
3545b504601Sjiang wu - Sun Microsystems - Beijing China 		cmd->cmd_flags |= CFLAG_PREPARED;
3555b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_start_config_page_access(mpt, cmd);
3565b504601Sjiang wu - Sun Microsystems - Beijing China 	} else {
3575b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_waitq_add(mpt, cmd);
3585b504601Sjiang wu - Sun Microsystems - Beijing China 	}
3595b504601Sjiang wu - Sun Microsystems - Beijing China 
3605b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
361c8f74a56SAda 	 * If this is a request for a RAID info page, or any page called during
362c8f74a56SAda 	 * the RAID info page request, poll because these config page requests
363c8f74a56SAda 	 * are nested.  Poll to avoid data corruption due to one page's data
364c8f74a56SAda 	 * overwriting the outer page request's data.  This can happen when
365c8f74a56SAda 	 * the mutex is released in cv_wait.
3665b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
367c8f74a56SAda 	if ((page_type == MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG) ||
368c8f74a56SAda 	    (page_type == MPI2_CONFIG_PAGETYPE_RAID_VOLUME) ||
369c8f74a56SAda 	    (page_type == MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK)) {
370c8f74a56SAda 		(void) mptsas_poll(mpt, cmd, pkt->pkt_time * 1000);
371c8f74a56SAda 	} else {
372c8f74a56SAda 		while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
373c8f74a56SAda 			cv_wait(&mpt->m_config_cv, &mpt->m_mutex);
374c8f74a56SAda 		}
3755b504601Sjiang wu - Sun Microsystems - Beijing China 	}
3765b504601Sjiang wu - Sun Microsystems - Beijing China 
3775b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
3785b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Check if the header request completed without timing out
3795b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
3805b504601Sjiang wu - Sun Microsystems - Beijing China 	if (cmd->cmd_flags & CFLAG_TIMEOUT) {
381*882fdc88SHans Rosenfeld 		config_flags |= MPTSAS_CMD_TIMEOUT;
3825b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "config header request timeout");
3835b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
3845b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
3855b504601Sjiang wu - Sun Microsystems - Beijing China 	}
3865b504601Sjiang wu - Sun Microsystems - Beijing China 
3875b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
3885b504601Sjiang wu - Sun Microsystems - Beijing China 	 * cmd_rfm points to the reply message if a reply was given.  Check the
3895b504601Sjiang wu - Sun Microsystems - Beijing China 	 * IOCStatus to make sure everything went OK with the header request.
3905b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
3915b504601Sjiang wu - Sun Microsystems - Beijing China 	if (cmd->cmd_rfm) {
3925b504601Sjiang wu - Sun Microsystems - Beijing China 		config_flags |= MPTSAS_ADDRESS_REPLY;
3935b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
3945b504601Sjiang wu - Sun Microsystems - Beijing China 		    DDI_DMA_SYNC_FORCPU);
3955b504601Sjiang wu - Sun Microsystems - Beijing China 		reply = (pMpi2ConfigReply_t)(mpt->m_reply_frame + (cmd->cmd_rfm
396940efceeSAndy Giles 		    - (mpt->m_reply_frame_dma_addr & 0xffffffffu)));
3975b504601Sjiang wu - Sun Microsystems - Beijing China 		config.page_type = ddi_get8(mpt->m_acc_reply_frame_hdl,
3985b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->Header.PageType);
3995b504601Sjiang wu - Sun Microsystems - Beijing China 		config.page_number = ddi_get8(mpt->m_acc_reply_frame_hdl,
4005b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->Header.PageNumber);
4015b504601Sjiang wu - Sun Microsystems - Beijing China 		config.page_length = ddi_get8(mpt->m_acc_reply_frame_hdl,
4025b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->Header.PageLength);
4035b504601Sjiang wu - Sun Microsystems - Beijing China 		config.page_version = ddi_get8(mpt->m_acc_reply_frame_hdl,
4045b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->Header.PageVersion);
4055b504601Sjiang wu - Sun Microsystems - Beijing China 		config.ext_page_type = ddi_get8(mpt->m_acc_reply_frame_hdl,
4065b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->ExtPageType);
4075b504601Sjiang wu - Sun Microsystems - Beijing China 		config.ext_page_length = ddi_get16(mpt->m_acc_reply_frame_hdl,
4085b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->ExtPageLength);
4095b504601Sjiang wu - Sun Microsystems - Beijing China 
4105b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
4115b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->IOCStatus);
4125b504601Sjiang wu - Sun Microsystems - Beijing China 		iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
4135b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->IOCLogInfo);
4145b504601Sjiang wu - Sun Microsystems - Beijing China 
4155b504601Sjiang wu - Sun Microsystems - Beijing China 		if (iocstatus) {
4165b504601Sjiang wu - Sun Microsystems - Beijing China 			NDBG13(("mptsas_access_config_page header: "
4175b504601Sjiang wu - Sun Microsystems - Beijing China 			    "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
4185b504601Sjiang wu - Sun Microsystems - Beijing China 			    iocloginfo));
4195b504601Sjiang wu - Sun Microsystems - Beijing China 			rval = DDI_FAILURE;
4205b504601Sjiang wu - Sun Microsystems - Beijing China 			goto page_done;
4215b504601Sjiang wu - Sun Microsystems - Beijing China 		}
4225b504601Sjiang wu - Sun Microsystems - Beijing China 
4235b504601Sjiang wu - Sun Microsystems - Beijing China 		if ((config.page_type & MPI2_CONFIG_PAGETYPE_MASK) ==
4245b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_CONFIG_PAGETYPE_EXTENDED)
4255b504601Sjiang wu - Sun Microsystems - Beijing China 			len = (config.ext_page_length * 4);
4265b504601Sjiang wu - Sun Microsystems - Beijing China 		else
4275b504601Sjiang wu - Sun Microsystems - Beijing China 			len = (config.page_length * 4);
4285b504601Sjiang wu - Sun Microsystems - Beijing China 
4295b504601Sjiang wu - Sun Microsystems - Beijing China 	}
4305b504601Sjiang wu - Sun Microsystems - Beijing China 
4315b504601Sjiang wu - Sun Microsystems - Beijing China 	if (pkt->pkt_reason == CMD_RESET) {
4325b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "ioc reset abort config header "
4335b504601Sjiang wu - Sun Microsystems - Beijing China 		    "request");
4345b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
4355b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
4365b504601Sjiang wu - Sun Microsystems - Beijing China 	}
4375b504601Sjiang wu - Sun Microsystems - Beijing China 
4385b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
4395b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Put the reply frame back on the free queue, increment the free
4405b504601Sjiang wu - Sun Microsystems - Beijing China 	 * index, and write the new index to the free index register.  But only
4415b504601Sjiang wu - Sun Microsystems - Beijing China 	 * if this reply is an ADDRESS reply.
4425b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
4435b504601Sjiang wu - Sun Microsystems - Beijing China 	if (config_flags & MPTSAS_ADDRESS_REPLY) {
4445b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_acc_free_queue_hdl,
44508eb0b82SYong-Feng Du 		    &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
4465b504601Sjiang wu - Sun Microsystems - Beijing China 		    cmd->cmd_rfm);
4475b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
4485b504601Sjiang wu - Sun Microsystems - Beijing China 		    DDI_DMA_SYNC_FORDEV);
44908eb0b82SYong-Feng Du 		if (++mpt->m_free_index == mpt->m_free_queue_depth) {
45008eb0b82SYong-Feng Du 			mpt->m_free_index = 0;
4515b504601Sjiang wu - Sun Microsystems - Beijing China 		}
4525b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
45308eb0b82SYong-Feng Du 		    mpt->m_free_index);
4545b504601Sjiang wu - Sun Microsystems - Beijing China 		config_flags &= (~MPTSAS_ADDRESS_REPLY);
4555b504601Sjiang wu - Sun Microsystems - Beijing China 	}
4565b504601Sjiang wu - Sun Microsystems - Beijing China 
4575b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
4585b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Allocate DMA buffer here.  Store the info regarding this buffer in
4595b504601Sjiang wu - Sun Microsystems - Beijing China 	 * the cmd struct so that it can be used for this specific command and
4605b504601Sjiang wu - Sun Microsystems - Beijing China 	 * de-allocated after the command completes.  The size of the reply
4615b504601Sjiang wu - Sun Microsystems - Beijing China 	 * will not be larger than the reply frame size.
4625b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
4635b504601Sjiang wu - Sun Microsystems - Beijing China 	attrs = mpt->m_msg_dma_attr;
4645b504601Sjiang wu - Sun Microsystems - Beijing China 	attrs.dma_attr_sgllen = 1;
4655b504601Sjiang wu - Sun Microsystems - Beijing China 	attrs.dma_attr_granular = (uint32_t)len;
4665b504601Sjiang wu - Sun Microsystems - Beijing China 
467a9b51062SAda 	if (mptsas_dma_addr_create(mpt, attrs,
468a9b51062SAda 	    &cmd->cmd_dmahandle, &accessp, &page_memp,
469a9b51062SAda 	    len, &cookie) == FALSE) {
470f7d0d869SDan McDonald 		rval = DDI_FAILURE;
471ed7418aeSAndy Giles 		mptsas_log(mpt, CE_WARN,
472ed7418aeSAndy Giles 		    "mptsas_dma_addr_create(len=0x%x) failed", (int)len);
4735b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
4745b504601Sjiang wu - Sun Microsystems - Beijing China 	}
475f7d0d869SDan McDonald 	/* NOW we can safely call mptsas_dma_addr_destroy(). */
476f7d0d869SDan McDonald 	free_dma = B_TRUE;
477f7d0d869SDan McDonald 
4785b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_dma_addr = cookie.dmac_laddress;
4795b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(page_memp, len);
4805b504601Sjiang wu - Sun Microsystems - Beijing China 
4815b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
4825b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Save the data for this request to be used in the call to start the
4835b504601Sjiang wu - Sun Microsystems - Beijing China 	 * config page read
4845b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
4855b504601Sjiang wu - Sun Microsystems - Beijing China 	config.action = action;
4865b504601Sjiang wu - Sun Microsystems - Beijing China 	config.page_address = page_address;
4875b504601Sjiang wu - Sun Microsystems - Beijing China 
4885b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
4895b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Re-use the cmd that was used to get the header.  Reset some of the
4905b504601Sjiang wu - Sun Microsystems - Beijing China 	 * values.
4915b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
4925b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero((caddr_t)pkt, scsi_pkt_size());
4935b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_ha_private	= (opaque_t)&config;
4945b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_flags		= FLAG_HEAD;
4955b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_time		= 60;
4965b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_flags		= CFLAG_PREPARED | CFLAG_CMDIOC | CFLAG_CONFIG;
4975b504601Sjiang wu - Sun Microsystems - Beijing China 
4985b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
4995b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Send the config page request.  cmd is re-used from header request.
5005b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
5015b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_start_config_page_access(mpt, cmd);
5025b504601Sjiang wu - Sun Microsystems - Beijing China 
5035b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
504c8f74a56SAda 	 * If this is a request for a RAID info page, or any page called during
505c8f74a56SAda 	 * the RAID info page request, poll because these config page requests
506c8f74a56SAda 	 * are nested.  Poll to avoid data corruption due to one page's data
507c8f74a56SAda 	 * overwriting the outer page request's data.  This can happen when
508c8f74a56SAda 	 * the mutex is released in cv_wait.
5095b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
510c8f74a56SAda 	if ((page_type == MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG) ||
511c8f74a56SAda 	    (page_type == MPI2_CONFIG_PAGETYPE_RAID_VOLUME) ||
512c8f74a56SAda 	    (page_type == MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK)) {
513c8f74a56SAda 		(void) mptsas_poll(mpt, cmd, pkt->pkt_time * 1000);
514c8f74a56SAda 	} else {
515c8f74a56SAda 		while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
516c8f74a56SAda 			cv_wait(&mpt->m_config_cv, &mpt->m_mutex);
517c8f74a56SAda 		}
5185b504601Sjiang wu - Sun Microsystems - Beijing China 	}
5195b504601Sjiang wu - Sun Microsystems - Beijing China 
5205b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
5215b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Check if the request completed without timing out
5225b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
5235b504601Sjiang wu - Sun Microsystems - Beijing China 	if (cmd->cmd_flags & CFLAG_TIMEOUT) {
524*882fdc88SHans Rosenfeld 		config_flags |= MPTSAS_CMD_TIMEOUT;
5255b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "config page request timeout");
5265b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
5275b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
5285b504601Sjiang wu - Sun Microsystems - Beijing China 	}
5295b504601Sjiang wu - Sun Microsystems - Beijing China 
5305b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
5315b504601Sjiang wu - Sun Microsystems - Beijing China 	 * cmd_rfm points to the reply message if a reply was given.  The reply
5325b504601Sjiang wu - Sun Microsystems - Beijing China 	 * frame and the config page are returned from this function in the
5335b504601Sjiang wu - Sun Microsystems - Beijing China 	 * param list.
5345b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
5355b504601Sjiang wu - Sun Microsystems - Beijing China 	if (cmd->cmd_rfm) {
5365b504601Sjiang wu - Sun Microsystems - Beijing China 		config_flags |= MPTSAS_ADDRESS_REPLY;
5375b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
5385b504601Sjiang wu - Sun Microsystems - Beijing China 		    DDI_DMA_SYNC_FORCPU);
5395b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
5405b504601Sjiang wu - Sun Microsystems - Beijing China 		    DDI_DMA_SYNC_FORCPU);
5415b504601Sjiang wu - Sun Microsystems - Beijing China 		reply = (pMpi2ConfigReply_t)(mpt->m_reply_frame + (cmd->cmd_rfm
542940efceeSAndy Giles 		    - (mpt->m_reply_frame_dma_addr & 0xffffffffu)));
5435b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
5445b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->IOCStatus);
5455b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = MPTSAS_IOCSTATUS(iocstatus);
5465b504601Sjiang wu - Sun Microsystems - Beijing China 		iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
5475b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->IOCLogInfo);
5485b504601Sjiang wu - Sun Microsystems - Beijing China 	}
5495b504601Sjiang wu - Sun Microsystems - Beijing China 
5505b504601Sjiang wu - Sun Microsystems - Beijing China 	if (callback(mpt, page_memp, accessp, iocstatus, iocloginfo, ap)) {
5515b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
5525b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
5535b504601Sjiang wu - Sun Microsystems - Beijing China 	}
5545b504601Sjiang wu - Sun Microsystems - Beijing China 
5555b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_fma_check(mpt, cmd);
5565b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
5575b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Check the DMA/ACC handles and then free the DMA buffer.
5585b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
5595b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((mptsas_check_dma_handle(cmd->cmd_dmahandle) != DDI_SUCCESS) ||
5605b504601Sjiang wu - Sun Microsystems - Beijing China 	    (mptsas_check_acc_handle(accessp) != DDI_SUCCESS)) {
5615b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
5625b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
5635b504601Sjiang wu - Sun Microsystems - Beijing China 	}
5645b504601Sjiang wu - Sun Microsystems - Beijing China 
5655b504601Sjiang wu - Sun Microsystems - Beijing China 	if (pkt->pkt_reason == CMD_TRAN_ERR) {
5665b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "config fma error");
5675b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
5685b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
5695b504601Sjiang wu - Sun Microsystems - Beijing China 	}
5705b504601Sjiang wu - Sun Microsystems - Beijing China 	if (pkt->pkt_reason == CMD_RESET) {
5715b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "ioc reset abort config request");
5725b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
5735b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
5745b504601Sjiang wu - Sun Microsystems - Beijing China 	}
5755b504601Sjiang wu - Sun Microsystems - Beijing China 
5765b504601Sjiang wu - Sun Microsystems - Beijing China page_done:
5775b504601Sjiang wu - Sun Microsystems - Beijing China 	va_end(ap);
5785b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
5795b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Put the reply frame back on the free queue, increment the free
5805b504601Sjiang wu - Sun Microsystems - Beijing China 	 * index, and write the new index to the free index register.  But only
5815b504601Sjiang wu - Sun Microsystems - Beijing China 	 * if this reply is an ADDRESS reply.
5825b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
5835b504601Sjiang wu - Sun Microsystems - Beijing China 	if (config_flags & MPTSAS_ADDRESS_REPLY) {
5845b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_acc_free_queue_hdl,
58508eb0b82SYong-Feng Du 		    &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
5865b504601Sjiang wu - Sun Microsystems - Beijing China 		    cmd->cmd_rfm);
5875b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
5885b504601Sjiang wu - Sun Microsystems - Beijing China 		    DDI_DMA_SYNC_FORDEV);
58908eb0b82SYong-Feng Du 		if (++mpt->m_free_index == mpt->m_free_queue_depth) {
59008eb0b82SYong-Feng Du 			mpt->m_free_index = 0;
5915b504601Sjiang wu - Sun Microsystems - Beijing China 		}
5925b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
59308eb0b82SYong-Feng Du 		    mpt->m_free_index);
5945b504601Sjiang wu - Sun Microsystems - Beijing China 	}
5955b504601Sjiang wu - Sun Microsystems - Beijing China 
596f7d0d869SDan McDonald 	if (free_dma)
597f7d0d869SDan McDonald 		mptsas_dma_addr_destroy(&cmd->cmd_dmahandle, &accessp);
5985b504601Sjiang wu - Sun Microsystems - Beijing China 
5995b504601Sjiang wu - Sun Microsystems - Beijing China 	if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) {
6005b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_remove_cmd(mpt, cmd);
6015b504601Sjiang wu - Sun Microsystems - Beijing China 		config_flags &= (~MPTSAS_REQUEST_POOL_CMD);
6025b504601Sjiang wu - Sun Microsystems - Beijing China 	}
6035b504601Sjiang wu - Sun Microsystems - Beijing China 	if (config_flags & MPTSAS_REQUEST_POOL_CMD)
6045b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_return_to_pool(mpt, cmd);
6055b504601Sjiang wu - Sun Microsystems - Beijing China 
6065b504601Sjiang wu - Sun Microsystems - Beijing China 	if (config_flags & MPTSAS_CMD_TIMEOUT) {
607a9b51062SAda 		mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
6085b504601Sjiang wu - Sun Microsystems - Beijing China 		if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
6095b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed");
6105b504601Sjiang wu - Sun Microsystems - Beijing China 		}
6115b504601Sjiang wu - Sun Microsystems - Beijing China 	}
6125b504601Sjiang wu - Sun Microsystems - Beijing China 
6135b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
6145b504601Sjiang wu - Sun Microsystems - Beijing China }
6155b504601Sjiang wu - Sun Microsystems - Beijing China 
6165b504601Sjiang wu - Sun Microsystems - Beijing China int
mptsas_send_config_request_msg(mptsas_t * mpt,uint8_t action,uint8_t pagetype,uint32_t pageaddress,uint8_t pagenumber,uint8_t pageversion,uint8_t pagelength,uint32_t SGEflagslength,uint64_t SGEaddress)6175b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_send_config_request_msg(mptsas_t *mpt, uint8_t action, uint8_t pagetype,
61815ada8fcSRobert Mustacchi     uint32_t pageaddress, uint8_t pagenumber, uint8_t pageversion,
61915ada8fcSRobert Mustacchi     uint8_t pagelength, uint32_t SGEflagslength, uint64_t SGEaddress)
6205b504601Sjiang wu - Sun Microsystems - Beijing China {
6215b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2ConfigRequest_t	config;
6225b504601Sjiang wu - Sun Microsystems - Beijing China 	int			send_numbytes;
6235b504601Sjiang wu - Sun Microsystems - Beijing China 
6245b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(mpt->m_hshk_memp, sizeof (MPI2_CONFIG_REQUEST));
6255b504601Sjiang wu - Sun Microsystems - Beijing China 	config = (pMpi2ConfigRequest_t)mpt->m_hshk_memp;
6265b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Function, MPI2_FUNCTION_CONFIG);
6275b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Action, action);
6285b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageNumber, pagenumber);
6295b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageType, pagetype);
6305b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_hshk_acc_hdl, &config->PageAddress, pageaddress);
6315b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageVersion, pageversion);
6325b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageLength, pagelength);
6335b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_hshk_acc_hdl,
6345b504601Sjiang wu - Sun Microsystems - Beijing China 	    &config->PageBufferSGE.MpiSimple.FlagsLength, SGEflagslength);
6355b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_hshk_acc_hdl,
636940efceeSAndy Giles 	    &config->PageBufferSGE.MpiSimple.u.Address64.Low, SGEaddress);
637940efceeSAndy Giles 	ddi_put32(mpt->m_hshk_acc_hdl,
638940efceeSAndy Giles 	    &config->PageBufferSGE.MpiSimple.u.Address64.High,
639940efceeSAndy Giles 	    SGEaddress >> 32);
6405b504601Sjiang wu - Sun Microsystems - Beijing China 	send_numbytes = sizeof (MPI2_CONFIG_REQUEST);
6415b504601Sjiang wu - Sun Microsystems - Beijing China 
6425b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
6435b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Post message via handshake
6445b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
6455b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_send_handshake_msg(mpt, (caddr_t)config, send_numbytes,
6465b504601Sjiang wu - Sun Microsystems - Beijing China 	    mpt->m_hshk_acc_hdl)) {
6475b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
6485b504601Sjiang wu - Sun Microsystems - Beijing China 	}
6495b504601Sjiang wu - Sun Microsystems - Beijing China 	return (0);
6505b504601Sjiang wu - Sun Microsystems - Beijing China }
6515b504601Sjiang wu - Sun Microsystems - Beijing China 
6525b504601Sjiang wu - Sun Microsystems - Beijing China int
mptsas_send_extended_config_request_msg(mptsas_t * mpt,uint8_t action,uint8_t extpagetype,uint32_t pageaddress,uint8_t pagenumber,uint8_t pageversion,uint16_t extpagelength,uint32_t SGEflagslength,uint64_t SGEaddress)6535b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_send_extended_config_request_msg(mptsas_t *mpt, uint8_t action,
65415ada8fcSRobert Mustacchi     uint8_t extpagetype, uint32_t pageaddress, uint8_t pagenumber,
65515ada8fcSRobert Mustacchi     uint8_t pageversion, uint16_t extpagelength,
65615ada8fcSRobert Mustacchi     uint32_t SGEflagslength, uint64_t SGEaddress)
6575b504601Sjiang wu - Sun Microsystems - Beijing China {
6585b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2ConfigRequest_t	config;
6595b504601Sjiang wu - Sun Microsystems - Beijing China 	int			send_numbytes;
6605b504601Sjiang wu - Sun Microsystems - Beijing China 
6615b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(mpt->m_hshk_memp, sizeof (MPI2_CONFIG_REQUEST));
6625b504601Sjiang wu - Sun Microsystems - Beijing China 	config = (pMpi2ConfigRequest_t)mpt->m_hshk_memp;
6635b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Function, MPI2_FUNCTION_CONFIG);
6645b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Action, action);
6655b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageNumber, pagenumber);
666