1*5b504601Sjiang wu - Sun Microsystems - Beijing China /*
2*5b504601Sjiang wu - Sun Microsystems - Beijing China  * CDDL HEADER START
3*5b504601Sjiang wu - Sun Microsystems - Beijing China  *
4*5b504601Sjiang wu - Sun Microsystems - Beijing China  * The contents of this file are subject to the terms of the
5*5b504601Sjiang wu - Sun Microsystems - Beijing China  * Common Development and Distribution License (the "License").
6*5b504601Sjiang wu - Sun Microsystems - Beijing China  * You may not use this file except in compliance with the License.
7*5b504601Sjiang wu - Sun Microsystems - Beijing China  *
8*5b504601Sjiang wu - Sun Microsystems - Beijing China  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5b504601Sjiang wu - Sun Microsystems - Beijing China  * or http://www.opensolaris.org/os/licensing.
10*5b504601Sjiang wu - Sun Microsystems - Beijing China  * See the License for the specific language governing permissions
11*5b504601Sjiang wu - Sun Microsystems - Beijing China  * and limitations under the License.
12*5b504601Sjiang wu - Sun Microsystems - Beijing China  *
13*5b504601Sjiang wu - Sun Microsystems - Beijing China  * When distributing Covered Code, include this CDDL HEADER in each
14*5b504601Sjiang wu - Sun Microsystems - Beijing China  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5b504601Sjiang wu - Sun Microsystems - Beijing China  * If applicable, add the following below this CDDL HEADER, with the
16*5b504601Sjiang wu - Sun Microsystems - Beijing China  * fields enclosed by brackets "[]" replaced with your own identifying
17*5b504601Sjiang wu - Sun Microsystems - Beijing China  * information: Portions Copyright [yyyy] [name of copyright owner]
18*5b504601Sjiang wu - Sun Microsystems - Beijing China  *
19*5b504601Sjiang wu - Sun Microsystems - Beijing China  * CDDL HEADER END
20*5b504601Sjiang wu - Sun Microsystems - Beijing China  */
21*5b504601Sjiang wu - Sun Microsystems - Beijing China 
22*5b504601Sjiang wu - Sun Microsystems - Beijing China /*
23*5b504601Sjiang wu - Sun Microsystems - Beijing China  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*5b504601Sjiang wu - Sun Microsystems - Beijing China  * Use is subject to license terms.
25*5b504601Sjiang wu - Sun Microsystems - Beijing China  */
26*5b504601Sjiang wu - Sun Microsystems - Beijing China 
27*5b504601Sjiang wu - Sun Microsystems - Beijing China /*
28*5b504601Sjiang wu - Sun Microsystems - Beijing China  * Copyright (c) 2000 to 2009, LSI Corporation.
29*5b504601Sjiang wu - Sun Microsystems - Beijing China  * All rights reserved.
30*5b504601Sjiang wu - Sun Microsystems - Beijing China  *
31*5b504601Sjiang wu - Sun Microsystems - Beijing China  * Redistribution and use in source and binary forms of all code within
32*5b504601Sjiang wu - Sun Microsystems - Beijing China  * this file that is exclusively owned by LSI, with or without
33*5b504601Sjiang wu - Sun Microsystems - Beijing China  * modification, is permitted provided that, in addition to the CDDL 1.0
34*5b504601Sjiang wu - Sun Microsystems - Beijing China  * License requirements, the following conditions are met:
35*5b504601Sjiang wu - Sun Microsystems - Beijing China  *
36*5b504601Sjiang wu - Sun Microsystems - Beijing China  *    Neither the name of the author nor the names of its contributors may be
37*5b504601Sjiang wu - Sun Microsystems - Beijing China  *    used to endorse or promote products derived from this software without
38*5b504601Sjiang wu - Sun Microsystems - Beijing China  *    specific prior written permission.
39*5b504601Sjiang wu - Sun Microsystems - Beijing China  *
40*5b504601Sjiang wu - Sun Microsystems - Beijing China  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41*5b504601Sjiang wu - Sun Microsystems - Beijing China  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42*5b504601Sjiang wu - Sun Microsystems - Beijing China  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
43*5b504601Sjiang wu - Sun Microsystems - Beijing China  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
44*5b504601Sjiang wu - Sun Microsystems - Beijing China  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
45*5b504601Sjiang wu - Sun Microsystems - Beijing China  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
46*5b504601Sjiang wu - Sun Microsystems - Beijing China  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
47*5b504601Sjiang wu - Sun Microsystems - Beijing China  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
48*5b504601Sjiang wu - Sun Microsystems - Beijing China  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49*5b504601Sjiang wu - Sun Microsystems - Beijing China  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50*5b504601Sjiang wu - Sun Microsystems - Beijing China  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
51*5b504601Sjiang wu - Sun Microsystems - Beijing China  * DAMAGE.
52*5b504601Sjiang wu - Sun Microsystems - Beijing China  */
53*5b504601Sjiang wu - Sun Microsystems - Beijing China 
54*5b504601Sjiang wu - Sun Microsystems - Beijing China /*
55*5b504601Sjiang wu - Sun Microsystems - Beijing China  * mptsas_impl - This file contains all the basic functions for communicating
56*5b504601Sjiang wu - Sun Microsystems - Beijing China  * to MPT based hardware.
57*5b504601Sjiang wu - Sun Microsystems - Beijing China  */
58*5b504601Sjiang wu - Sun Microsystems - Beijing China 
59*5b504601Sjiang wu - Sun Microsystems - Beijing China #if defined(lint) || defined(DEBUG)
60*5b504601Sjiang wu - Sun Microsystems - Beijing China #define	MPTSAS_DEBUG
61*5b504601Sjiang wu - Sun Microsystems - Beijing China #endif
62*5b504601Sjiang wu - Sun Microsystems - Beijing China 
63*5b504601Sjiang wu - Sun Microsystems - Beijing China /*
64*5b504601Sjiang wu - Sun Microsystems - Beijing China  * standard header files
65*5b504601Sjiang wu - Sun Microsystems - Beijing China  */
66*5b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/note.h>
67*5b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/scsi.h>
68*5b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/pci.h>
69*5b504601Sjiang wu - Sun Microsystems - Beijing China 
70*5b504601Sjiang wu - Sun Microsystems - Beijing China #pragma pack(1)
71*5b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
72*5b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
73*5b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
74*5b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
75*5b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
76*5b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
77*5b504601Sjiang wu - Sun Microsystems - Beijing China #pragma pack()
78*5b504601Sjiang wu - Sun Microsystems - Beijing China 
79*5b504601Sjiang wu - Sun Microsystems - Beijing China /*
80*5b504601Sjiang wu - Sun Microsystems - Beijing China  * private header files.
81*5b504601Sjiang wu - Sun Microsystems - Beijing China  */
82*5b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
83*5b504601Sjiang wu - Sun Microsystems - Beijing China 
84*5b504601Sjiang wu - Sun Microsystems - Beijing China /*
85*5b504601Sjiang wu - Sun Microsystems - Beijing China  * FMA header files.
86*5b504601Sjiang wu - Sun Microsystems - Beijing China  */
87*5b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/fm/io/ddi.h>
88*5b504601Sjiang wu - Sun Microsystems - Beijing China 
89*5b504601Sjiang wu - Sun Microsystems - Beijing China #if defined(MPTSAS_DEBUG)
90*5b504601Sjiang wu - Sun Microsystems - Beijing China extern uint32_t mptsas_debug_flags;
91*5b504601Sjiang wu - Sun Microsystems - Beijing China #endif
92*5b504601Sjiang wu - Sun Microsystems - Beijing China 
93*5b504601Sjiang wu - Sun Microsystems - Beijing China /*
94*5b504601Sjiang wu - Sun Microsystems - Beijing China  *  prototypes
95*5b504601Sjiang wu - Sun Microsystems - Beijing China  */
96*5b504601Sjiang wu - Sun Microsystems - Beijing China static void mptsas_ioc_event_cmdq_add(mptsas_t *mpt, m_event_struct_t *cmd);
97*5b504601Sjiang wu - Sun Microsystems - Beijing China static void mptsas_ioc_event_cmdq_delete(mptsas_t *mpt, m_event_struct_t *cmd);
98*5b504601Sjiang wu - Sun Microsystems - Beijing China static m_event_struct_t *mptsas_ioc_event_find_by_cmd(mptsas_t *mpt,
99*5b504601Sjiang wu - Sun Microsystems - Beijing China     struct mptsas_cmd *cmd);
100*5b504601Sjiang wu - Sun Microsystems - Beijing China 
101*5b504601Sjiang wu - Sun Microsystems - Beijing China /*
102*5b504601Sjiang wu - Sun Microsystems - Beijing China  * add ioc evnet cmd into the queue
103*5b504601Sjiang wu - Sun Microsystems - Beijing China  */
104*5b504601Sjiang wu - Sun Microsystems - Beijing China static void
105*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_event_cmdq_add(mptsas_t *mpt, m_event_struct_t *cmd)
106*5b504601Sjiang wu - Sun Microsystems - Beijing China {
107*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((cmd->m_event_linkp = mpt->m_ioc_event_cmdq) == NULL) {
108*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_ioc_event_cmdtail = &cmd->m_event_linkp;
109*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_ioc_event_cmdq = cmd;
110*5b504601Sjiang wu - Sun Microsystems - Beijing China 	} else {
111*5b504601Sjiang wu - Sun Microsystems - Beijing China 		cmd->m_event_linkp = NULL;
112*5b504601Sjiang wu - Sun Microsystems - Beijing China 		*(mpt->m_ioc_event_cmdtail) = cmd;
113*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_ioc_event_cmdtail = &cmd->m_event_linkp;
114*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
115*5b504601Sjiang wu - Sun Microsystems - Beijing China }
116*5b504601Sjiang wu - Sun Microsystems - Beijing China 
117*5b504601Sjiang wu - Sun Microsystems - Beijing China /*
118*5b504601Sjiang wu - Sun Microsystems - Beijing China  * remove specified cmd from the ioc event queue
119*5b504601Sjiang wu - Sun Microsystems - Beijing China  */
120*5b504601Sjiang wu - Sun Microsystems - Beijing China static void
121*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_event_cmdq_delete(mptsas_t *mpt, m_event_struct_t *cmd)
122*5b504601Sjiang wu - Sun Microsystems - Beijing China {
123*5b504601Sjiang wu - Sun Microsystems - Beijing China 	m_event_struct_t	*prev = mpt->m_ioc_event_cmdq;
124*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (prev == cmd) {
125*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if ((mpt->m_ioc_event_cmdq = cmd->m_event_linkp) == NULL) {
126*5b504601Sjiang wu - Sun Microsystems - Beijing China 			mpt->m_ioc_event_cmdtail = &mpt->m_ioc_event_cmdq;
127*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
128*5b504601Sjiang wu - Sun Microsystems - Beijing China 		cmd->m_event_linkp = NULL;
129*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return;
130*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
131*5b504601Sjiang wu - Sun Microsystems - Beijing China 	while (prev != NULL) {
132*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (prev->m_event_linkp == cmd) {
133*5b504601Sjiang wu - Sun Microsystems - Beijing China 			prev->m_event_linkp = cmd->m_event_linkp;
134*5b504601Sjiang wu - Sun Microsystems - Beijing China 			if (cmd->m_event_linkp == NULL) {
135*5b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_ioc_event_cmdtail = &prev->m_event_linkp;
136*5b504601Sjiang wu - Sun Microsystems - Beijing China 			}
137*5b504601Sjiang wu - Sun Microsystems - Beijing China 
138*5b504601Sjiang wu - Sun Microsystems - Beijing China 			cmd->m_event_linkp = NULL;
139*5b504601Sjiang wu - Sun Microsystems - Beijing China 			return;
140*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
141*5b504601Sjiang wu - Sun Microsystems - Beijing China 		prev = prev->m_event_linkp;
142*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
143*5b504601Sjiang wu - Sun Microsystems - Beijing China }
144*5b504601Sjiang wu - Sun Microsystems - Beijing China 
145*5b504601Sjiang wu - Sun Microsystems - Beijing China static m_event_struct_t *
146*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_event_find_by_cmd(mptsas_t *mpt, struct mptsas_cmd *cmd)
147*5b504601Sjiang wu - Sun Microsystems - Beijing China {
148*5b504601Sjiang wu - Sun Microsystems - Beijing China 	m_event_struct_t	*ioc_cmd = NULL;
149*5b504601Sjiang wu - Sun Microsystems - Beijing China 
150*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ioc_cmd = mpt->m_ioc_event_cmdq;
151*5b504601Sjiang wu - Sun Microsystems - Beijing China 	while (ioc_cmd != NULL) {
152*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (&(ioc_cmd->m_event_cmd) == cmd) {
153*5b504601Sjiang wu - Sun Microsystems - Beijing China 			return (ioc_cmd);
154*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
155*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ioc_cmd = ioc_cmd->m_event_linkp;
156*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
157*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ioc_cmd = NULL;
158*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (ioc_cmd);
159*5b504601Sjiang wu - Sun Microsystems - Beijing China }
160*5b504601Sjiang wu - Sun Microsystems - Beijing China 
161*5b504601Sjiang wu - Sun Microsystems - Beijing China void
162*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_destroy_ioc_event_cmd(mptsas_t *mpt)
163*5b504601Sjiang wu - Sun Microsystems - Beijing China {
164*5b504601Sjiang wu - Sun Microsystems - Beijing China 	m_event_struct_t	*ioc_cmd = NULL;
165*5b504601Sjiang wu - Sun Microsystems - Beijing China 	m_event_struct_t	*ioc_cmd_tmp = NULL;
166*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ioc_cmd = mpt->m_ioc_event_cmdq;
167*5b504601Sjiang wu - Sun Microsystems - Beijing China 
168*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
169*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * because the IOC event queue is resource of per instance for driver,
170*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * it's not only ACK event commands used it, but also some others used
171*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * it. We need destroy all ACK event commands when IOC reset, but can't
172*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * disturb others.So we use filter to clear the ACK event cmd in ioc
173*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * event queue, and other requests should be reserved, and they would
174*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * be free by its owner.
175*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
176*5b504601Sjiang wu - Sun Microsystems - Beijing China 	while (ioc_cmd != NULL) {
177*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (ioc_cmd->m_event_cmd.cmd_flags & CFLAG_CMDACK) {
178*5b504601Sjiang wu - Sun Microsystems - Beijing China 			NDBG20(("destroy!! remove Ack Flag ioc_cmd\n"));
179*5b504601Sjiang wu - Sun Microsystems - Beijing China 			if ((mpt->m_ioc_event_cmdq =
180*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    ioc_cmd->m_event_linkp) == NULL)
181*5b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_ioc_event_cmdtail =
182*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    &mpt->m_ioc_event_cmdq;
183*5b504601Sjiang wu - Sun Microsystems - Beijing China 			ioc_cmd_tmp = ioc_cmd;
184*5b504601Sjiang wu - Sun Microsystems - Beijing China 			ioc_cmd = ioc_cmd->m_event_linkp;
185*5b504601Sjiang wu - Sun Microsystems - Beijing China 			kmem_free(ioc_cmd_tmp, M_EVENT_STRUCT_SIZE);
186*5b504601Sjiang wu - Sun Microsystems - Beijing China 		} else {
187*5b504601Sjiang wu - Sun Microsystems - Beijing China 			/*
188*5b504601Sjiang wu - Sun Microsystems - Beijing China 			 * it's not ack cmd, so continue to check next one
189*5b504601Sjiang wu - Sun Microsystems - Beijing China 			 */
190*5b504601Sjiang wu - Sun Microsystems - Beijing China 
191*5b504601Sjiang wu - Sun Microsystems - Beijing China 			NDBG20(("destroy!! it's not Ack Flag, continue\n"));
192*5b504601Sjiang wu - Sun Microsystems - Beijing China 			ioc_cmd = ioc_cmd->m_event_linkp;
193*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
194*5b504601Sjiang wu - Sun Microsystems - Beijing China 
195*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
196*5b504601Sjiang wu - Sun Microsystems - Beijing China }
197*5b504601Sjiang wu - Sun Microsystems - Beijing China 
198*5b504601Sjiang wu - Sun Microsystems - Beijing China void
199*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_start_config_page_access(mptsas_t *mpt, mptsas_cmd_t *cmd)
200*5b504601Sjiang wu - Sun Microsystems - Beijing China {
201*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2ConfigRequest_t	request;
202*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2SGESimple64_t	sge;
203*5b504601Sjiang wu - Sun Microsystems - Beijing China 	struct scsi_pkt		*pkt = cmd->cmd_pkt;
204*5b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_config_request_t	*config = pkt->pkt_ha_private;
205*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t			direction;
206*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		length, flagslength, request_desc_low;
207*5b504601Sjiang wu - Sun Microsystems - Beijing China 
208*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ASSERT(mutex_owned(&mpt->m_mutex));
209*5b504601Sjiang wu - Sun Microsystems - Beijing China 
210*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
211*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Point to the correct message and clear it as well as the global
212*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * config page memory.
213*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
214*5b504601Sjiang wu - Sun Microsystems - Beijing China 	request = (pMpi2ConfigRequest_t)(mpt->m_req_frame +
215*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    (mpt->m_req_frame_size * cmd->cmd_slot));
216*5b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(request, mpt->m_req_frame_size);
217*5b504601Sjiang wu - Sun Microsystems - Beijing China 
218*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
219*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Form the request message.
220*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
221*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &request->Function,
222*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_FUNCTION_CONFIG);
223*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &request->Action, config->action);
224*5b504601Sjiang wu - Sun Microsystems - Beijing China 	direction = MPI2_SGE_FLAGS_IOC_TO_HOST;
225*5b504601Sjiang wu - Sun Microsystems - Beijing China 	length = 0;
226*5b504601Sjiang wu - Sun Microsystems - Beijing China 	sge = (pMpi2SGESimple64_t)&request->PageBufferSGE;
227*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (config->action == MPI2_CONFIG_ACTION_PAGE_HEADER) {
228*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (config->page_type > MPI2_CONFIG_PAGETYPE_MASK) {
229*5b504601Sjiang wu - Sun Microsystems - Beijing China 			ddi_put8(mpt->m_acc_req_frame_hdl,
230*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    &request->Header.PageType,
231*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_CONFIG_PAGETYPE_EXTENDED);
232*5b504601Sjiang wu - Sun Microsystems - Beijing China 			ddi_put8(mpt->m_acc_req_frame_hdl,
233*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    &request->ExtPageType, config->page_type);
234*5b504601Sjiang wu - Sun Microsystems - Beijing China 		} else {
235*5b504601Sjiang wu - Sun Microsystems - Beijing China 			ddi_put8(mpt->m_acc_req_frame_hdl,
236*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    &request->Header.PageType, config->page_type);
237*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
238*5b504601Sjiang wu - Sun Microsystems - Beijing China 	} else {
239*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put8(mpt->m_acc_req_frame_hdl, &request->ExtPageType,
240*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    config->ext_page_type);
241*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put16(mpt->m_acc_req_frame_hdl, &request->ExtPageLength,
242*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    config->ext_page_length);
243*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put8(mpt->m_acc_req_frame_hdl, &request->Header.PageType,
244*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    config->page_type);
245*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put8(mpt->m_acc_req_frame_hdl, &request->Header.PageLength,
246*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    config->page_length);
247*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put8(mpt->m_acc_req_frame_hdl,
248*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &request->Header.PageVersion, config->page_version);
249*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if ((config->page_type & MPI2_CONFIG_PAGETYPE_MASK) ==
250*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_CONFIG_PAGETYPE_EXTENDED) {
251*5b504601Sjiang wu - Sun Microsystems - Beijing China 			length = config->ext_page_length * 4;
252*5b504601Sjiang wu - Sun Microsystems - Beijing China 		} else {
253*5b504601Sjiang wu - Sun Microsystems - Beijing China 			length = config->page_length * 4;
254*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
255*5b504601Sjiang wu - Sun Microsystems - Beijing China 
256*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (config->action == MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {
257*5b504601Sjiang wu - Sun Microsystems - Beijing China 			direction = MPI2_SGE_FLAGS_HOST_TO_IOC;
258*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
259*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.Low,
260*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    (uint32_t)cmd->cmd_dma_addr);
261*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.High,
262*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    (uint32_t)(cmd->cmd_dma_addr >> 32));
263*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
264*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &request->Header.PageNumber,
265*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    config->page_number);
266*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_acc_req_frame_hdl, &request->PageAddress,
267*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    config->page_address);
268*5b504601Sjiang wu - Sun Microsystems - Beijing China 	flagslength = ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT |
269*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_END_OF_BUFFER |
270*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
271*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
272*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_64_BIT_ADDRESSING |
273*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    direction |
274*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
275*5b504601Sjiang wu - Sun Microsystems - Beijing China 	flagslength |= length;
276*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_acc_req_frame_hdl, &sge->FlagsLength, flagslength);
277*5b504601Sjiang wu - Sun Microsystems - Beijing China 
278*5b504601Sjiang wu - Sun Microsystems - Beijing China 	(void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0,
279*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SYNC_FORDEV);
280*5b504601Sjiang wu - Sun Microsystems - Beijing China 	request_desc_low = (cmd->cmd_slot << 16) +
281*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
282*5b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_rfm = NULL;
283*5b504601Sjiang wu - Sun Microsystems - Beijing China 	MPTSAS_START_CMD(mpt, request_desc_low, 0);
284*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
285*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_SUCCESS) ||
286*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
287*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_SUCCESS)) {
288*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
289*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
290*5b504601Sjiang wu - Sun Microsystems - Beijing China }
291*5b504601Sjiang wu - Sun Microsystems - Beijing China 
292*5b504601Sjiang wu - Sun Microsystems - Beijing China int
293*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_access_config_page(mptsas_t *mpt, uint8_t action, uint8_t page_type,
294*5b504601Sjiang wu - Sun Microsystems - Beijing China     uint8_t page_number, uint32_t page_address, int (*callback) (mptsas_t *,
295*5b504601Sjiang wu - Sun Microsystems - Beijing China     caddr_t, ddi_acc_handle_t, uint16_t, uint32_t, va_list), ...)
296*5b504601Sjiang wu - Sun Microsystems - Beijing China {
297*5b504601Sjiang wu - Sun Microsystems - Beijing China 	va_list			ap;
298*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_attr_t		attrs;
299*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint_t			ncookie;
300*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_cookie_t	cookie;
301*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_acc_handle_t	accessp;
302*5b504601Sjiang wu - Sun Microsystems - Beijing China 	size_t			len = 0, alloc_len;
303*5b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_config_request_t	config;
304*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			rval = DDI_SUCCESS, config_flags = 0;
305*5b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_cmd_t		*cmd;
306*5b504601Sjiang wu - Sun Microsystems - Beijing China 	struct scsi_pkt		*pkt;
307*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		reply_index;
308*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2ConfigReply_t	reply;
309*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint16_t		iocstatus = 0;
310*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		iocloginfo;
311*5b504601Sjiang wu - Sun Microsystems - Beijing China 	caddr_t			page_memp;
312*5b504601Sjiang wu - Sun Microsystems - Beijing China 
313*5b504601Sjiang wu - Sun Microsystems - Beijing China 	va_start(ap, callback);
314*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ASSERT(mutex_owned(&mpt->m_mutex));
315*5b504601Sjiang wu - Sun Microsystems - Beijing China 
316*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
317*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Get a command from the pool.
318*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
319*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((rval = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
320*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_NOTE, "command pool is full for config "
321*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "page request");
322*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
323*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
324*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
325*5b504601Sjiang wu - Sun Microsystems - Beijing China 	config_flags |= MPTSAS_REQUEST_POOL_CMD;
326*5b504601Sjiang wu - Sun Microsystems - Beijing China 
327*5b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero((caddr_t)cmd, sizeof (*cmd));
328*5b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero((caddr_t)pkt, scsi_pkt_size());
329*5b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero((caddr_t)&config, sizeof (config));
330*5b504601Sjiang wu - Sun Microsystems - Beijing China 
331*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
332*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Save the data for this request to be used in the call to start the
333*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * config header request.
334*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
335*5b504601Sjiang wu - Sun Microsystems - Beijing China 	config.action = MPI2_CONFIG_ACTION_PAGE_HEADER;
336*5b504601Sjiang wu - Sun Microsystems - Beijing China 	config.page_type = page_type;
337*5b504601Sjiang wu - Sun Microsystems - Beijing China 	config.page_number = page_number;
338*5b504601Sjiang wu - Sun Microsystems - Beijing China 	config.page_address = page_address;
339*5b504601Sjiang wu - Sun Microsystems - Beijing China 
340*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
341*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Form a blank cmd/pkt to store the acknowledgement message
342*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
343*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_ha_private	= (opaque_t)&config;
344*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_flags		= FLAG_HEAD;
345*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_time		= 60;
346*5b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_pkt		= pkt;
347*5b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_flags		= CFLAG_CMDIOC | CFLAG_CONFIG;
348*5b504601Sjiang wu - Sun Microsystems - Beijing China 
349*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
350*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Save the config header request message in a slot.
351*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
352*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_save_cmd(mpt, cmd) == TRUE) {
353*5b504601Sjiang wu - Sun Microsystems - Beijing China 		cmd->cmd_flags |= CFLAG_PREPARED;
354*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_start_config_page_access(mpt, cmd);
355*5b504601Sjiang wu - Sun Microsystems - Beijing China 	} else {
356*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_waitq_add(mpt, cmd);
357*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
358*5b504601Sjiang wu - Sun Microsystems - Beijing China 
359*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
360*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Wait for the command to complete or timeout.
361*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
362*5b504601Sjiang wu - Sun Microsystems - Beijing China 	while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
363*5b504601Sjiang wu - Sun Microsystems - Beijing China 		cv_wait(&mpt->m_config_cv, &mpt->m_mutex);
364*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
365*5b504601Sjiang wu - Sun Microsystems - Beijing China 
366*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
367*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Check if the header request completed without timing out
368*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
369*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (cmd->cmd_flags & CFLAG_TIMEOUT) {
370*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "config header request timeout");
371*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
372*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
373*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
374*5b504601Sjiang wu - Sun Microsystems - Beijing China 
375*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
376*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * cmd_rfm points to the reply message if a reply was given.  Check the
377*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * IOCStatus to make sure everything went OK with the header request.
378*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
379*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (cmd->cmd_rfm) {
380*5b504601Sjiang wu - Sun Microsystems - Beijing China 		config_flags |= MPTSAS_ADDRESS_REPLY;
381*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
382*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    DDI_DMA_SYNC_FORCPU);
383*5b504601Sjiang wu - Sun Microsystems - Beijing China 		reply = (pMpi2ConfigReply_t)(mpt->m_reply_frame + (cmd->cmd_rfm
384*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    - mpt->m_reply_frame_dma_addr));
385*5b504601Sjiang wu - Sun Microsystems - Beijing China 		config.page_type = ddi_get8(mpt->m_acc_reply_frame_hdl,
386*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->Header.PageType);
387*5b504601Sjiang wu - Sun Microsystems - Beijing China 		config.page_number = ddi_get8(mpt->m_acc_reply_frame_hdl,
388*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->Header.PageNumber);
389*5b504601Sjiang wu - Sun Microsystems - Beijing China 		config.page_length = ddi_get8(mpt->m_acc_reply_frame_hdl,
390*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->Header.PageLength);
391*5b504601Sjiang wu - Sun Microsystems - Beijing China 		config.page_version = ddi_get8(mpt->m_acc_reply_frame_hdl,
392*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->Header.PageVersion);
393*5b504601Sjiang wu - Sun Microsystems - Beijing China 		config.ext_page_type = ddi_get8(mpt->m_acc_reply_frame_hdl,
394*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->ExtPageType);
395*5b504601Sjiang wu - Sun Microsystems - Beijing China 		config.ext_page_length = ddi_get16(mpt->m_acc_reply_frame_hdl,
396*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->ExtPageLength);
397*5b504601Sjiang wu - Sun Microsystems - Beijing China 
398*5b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
399*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->IOCStatus);
400*5b504601Sjiang wu - Sun Microsystems - Beijing China 		iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
401*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->IOCLogInfo);
402*5b504601Sjiang wu - Sun Microsystems - Beijing China 
403*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (iocstatus) {
404*5b504601Sjiang wu - Sun Microsystems - Beijing China 			NDBG13(("mptsas_access_config_page header: "
405*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
406*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    iocloginfo));
407*5b504601Sjiang wu - Sun Microsystems - Beijing China 			rval = DDI_FAILURE;
408*5b504601Sjiang wu - Sun Microsystems - Beijing China 			goto page_done;
409*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
410*5b504601Sjiang wu - Sun Microsystems - Beijing China 
411*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if ((config.page_type & MPI2_CONFIG_PAGETYPE_MASK) ==
412*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_CONFIG_PAGETYPE_EXTENDED)
413*5b504601Sjiang wu - Sun Microsystems - Beijing China 			len = (config.ext_page_length * 4);
414*5b504601Sjiang wu - Sun Microsystems - Beijing China 		else
415*5b504601Sjiang wu - Sun Microsystems - Beijing China 			len = (config.page_length * 4);
416*5b504601Sjiang wu - Sun Microsystems - Beijing China 
417*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
418*5b504601Sjiang wu - Sun Microsystems - Beijing China 
419*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (pkt->pkt_reason == CMD_RESET) {
420*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "ioc reset abort config header "
421*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "request");
422*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
423*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
424*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
425*5b504601Sjiang wu - Sun Microsystems - Beijing China 
426*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
427*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Put the reply frame back on the free queue, increment the free
428*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * index, and write the new index to the free index register.  But only
429*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * if this reply is an ADDRESS reply.
430*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
431*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (config_flags & MPTSAS_ADDRESS_REPLY) {
432*5b504601Sjiang wu - Sun Microsystems - Beijing China 		reply_index = mpt->m_free_index;
433*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_acc_free_queue_hdl,
434*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &((uint32_t *)(void *)mpt->m_free_queue)[reply_index],
435*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    cmd->cmd_rfm);
436*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
437*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    DDI_DMA_SYNC_FORDEV);
438*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (++reply_index == mpt->m_free_queue_depth) {
439*5b504601Sjiang wu - Sun Microsystems - Beijing China 			reply_index = 0;
440*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
441*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_free_index = reply_index;
442*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
443*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    reply_index);
444*5b504601Sjiang wu - Sun Microsystems - Beijing China 		config_flags &= (~MPTSAS_ADDRESS_REPLY);
445*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
446*5b504601Sjiang wu - Sun Microsystems - Beijing China 
447*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
448*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Allocate DMA buffer here.  Store the info regarding this buffer in
449*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * the cmd struct so that it can be used for this specific command and
450*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * de-allocated after the command completes.  The size of the reply
451*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * will not be larger than the reply frame size.
452*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
453*5b504601Sjiang wu - Sun Microsystems - Beijing China 	attrs = mpt->m_msg_dma_attr;
454*5b504601Sjiang wu - Sun Microsystems - Beijing China 	attrs.dma_attr_sgllen = 1;
455*5b504601Sjiang wu - Sun Microsystems - Beijing China 	attrs.dma_attr_granular = (uint32_t)len;
456*5b504601Sjiang wu - Sun Microsystems - Beijing China 
457*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_alloc_handle(mpt->m_dip, &attrs,
458*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SLEEP, NULL, &cmd->cmd_dmahandle) != DDI_SUCCESS) {
459*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "unable to allocate dma handle for "
460*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "config page.");
461*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
462*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
463*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
464*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_mem_alloc(cmd->cmd_dmahandle, len,
465*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
466*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &page_memp, &alloc_len, &accessp) != DDI_SUCCESS) {
467*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&cmd->cmd_dmahandle);
468*5b504601Sjiang wu - Sun Microsystems - Beijing China 		cmd->cmd_dmahandle = NULL;
469*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "unable to allocate config page "
470*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "structure.");
471*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
472*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
473*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
474*5b504601Sjiang wu - Sun Microsystems - Beijing China 
475*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_addr_bind_handle(cmd->cmd_dmahandle, NULL, page_memp,
476*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
477*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &cookie, &ncookie) != DDI_DMA_MAPPED) {
478*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_mem_free(&accessp);
479*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&cmd->cmd_dmahandle);
480*5b504601Sjiang wu - Sun Microsystems - Beijing China 		cmd->cmd_dmahandle = NULL;
481*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "unable to bind DMA resources for "
482*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "config page.");
483*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
484*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
485*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
486*5b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_dma_addr = cookie.dmac_laddress;
487*5b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(page_memp, len);
488*5b504601Sjiang wu - Sun Microsystems - Beijing China 
489*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
490*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Save the data for this request to be used in the call to start the
491*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * config page read
492*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
493*5b504601Sjiang wu - Sun Microsystems - Beijing China 	config.action = action;
494*5b504601Sjiang wu - Sun Microsystems - Beijing China 	config.page_address = page_address;
495*5b504601Sjiang wu - Sun Microsystems - Beijing China 
496*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
497*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Re-use the cmd that was used to get the header.  Reset some of the
498*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * values.
499*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
500*5b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero((caddr_t)pkt, scsi_pkt_size());
501*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_ha_private	= (opaque_t)&config;
502*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_flags		= FLAG_HEAD;
503*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_time		= 60;
504*5b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_flags		= CFLAG_PREPARED | CFLAG_CMDIOC | CFLAG_CONFIG;
505*5b504601Sjiang wu - Sun Microsystems - Beijing China 
506*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
507*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Send the config page request.  cmd is re-used from header request.
508*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
509*5b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_start_config_page_access(mpt, cmd);
510*5b504601Sjiang wu - Sun Microsystems - Beijing China 
511*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
512*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Wait for the command to complete or timeout.
513*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
514*5b504601Sjiang wu - Sun Microsystems - Beijing China 	while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
515*5b504601Sjiang wu - Sun Microsystems - Beijing China 		cv_wait(&mpt->m_config_cv, &mpt->m_mutex);
516*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
517*5b504601Sjiang wu - Sun Microsystems - Beijing China 
518*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
519*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Check if the request completed without timing out
520*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
521*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (cmd->cmd_flags & CFLAG_TIMEOUT) {
522*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "config page request timeout");
523*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
524*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
525*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
526*5b504601Sjiang wu - Sun Microsystems - Beijing China 
527*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
528*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * cmd_rfm points to the reply message if a reply was given.  The reply
529*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * frame and the config page are returned from this function in the
530*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * param list.
531*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
532*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (cmd->cmd_rfm) {
533*5b504601Sjiang wu - Sun Microsystems - Beijing China 		config_flags |= MPTSAS_ADDRESS_REPLY;
534*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
535*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    DDI_DMA_SYNC_FORCPU);
536*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
537*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    DDI_DMA_SYNC_FORCPU);
538*5b504601Sjiang wu - Sun Microsystems - Beijing China 		reply = (pMpi2ConfigReply_t)(mpt->m_reply_frame + (cmd->cmd_rfm
539*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    - mpt->m_reply_frame_dma_addr));
540*5b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
541*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->IOCStatus);
542*5b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = MPTSAS_IOCSTATUS(iocstatus);
543*5b504601Sjiang wu - Sun Microsystems - Beijing China 		iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
544*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &reply->IOCLogInfo);
545*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
546*5b504601Sjiang wu - Sun Microsystems - Beijing China 
547*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (callback(mpt, page_memp, accessp, iocstatus, iocloginfo, ap)) {
548*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
549*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
550*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
551*5b504601Sjiang wu - Sun Microsystems - Beijing China 
552*5b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_fma_check(mpt, cmd);
553*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
554*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Check the DMA/ACC handles and then free the DMA buffer.
555*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
556*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((mptsas_check_dma_handle(cmd->cmd_dmahandle) != DDI_SUCCESS) ||
557*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    (mptsas_check_acc_handle(accessp) != DDI_SUCCESS)) {
558*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
559*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
560*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
561*5b504601Sjiang wu - Sun Microsystems - Beijing China 
562*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (pkt->pkt_reason == CMD_TRAN_ERR) {
563*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "config fma error");
564*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
565*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
566*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
567*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (pkt->pkt_reason == CMD_RESET) {
568*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "ioc reset abort config request");
569*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
570*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto page_done;
571*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
572*5b504601Sjiang wu - Sun Microsystems - Beijing China 
573*5b504601Sjiang wu - Sun Microsystems - Beijing China page_done:
574*5b504601Sjiang wu - Sun Microsystems - Beijing China 	va_end(ap);
575*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
576*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Put the reply frame back on the free queue, increment the free
577*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * index, and write the new index to the free index register.  But only
578*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * if this reply is an ADDRESS reply.
579*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
580*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (config_flags & MPTSAS_ADDRESS_REPLY) {
581*5b504601Sjiang wu - Sun Microsystems - Beijing China 		reply_index = mpt->m_free_index;
582*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_acc_free_queue_hdl,
583*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &((uint32_t *)(void *)mpt->m_free_queue)[reply_index],
584*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    cmd->cmd_rfm);
585*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
586*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    DDI_DMA_SYNC_FORDEV);
587*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (++reply_index == mpt->m_free_queue_depth) {
588*5b504601Sjiang wu - Sun Microsystems - Beijing China 			reply_index = 0;
589*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
590*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_free_index = reply_index;
591*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
592*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    reply_index);
593*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
594*5b504601Sjiang wu - Sun Microsystems - Beijing China 
595*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (cmd->cmd_dmahandle != NULL) {
596*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_unbind_handle(cmd->cmd_dmahandle);
597*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_mem_free(&accessp);
598*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&cmd->cmd_dmahandle);
599*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
600*5b504601Sjiang wu - Sun Microsystems - Beijing China 
601*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) {
602*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_remove_cmd(mpt, cmd);
603*5b504601Sjiang wu - Sun Microsystems - Beijing China 		config_flags &= (~MPTSAS_REQUEST_POOL_CMD);
604*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
605*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (config_flags & MPTSAS_REQUEST_POOL_CMD)
606*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_return_to_pool(mpt, cmd);
607*5b504601Sjiang wu - Sun Microsystems - Beijing China 
608*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (config_flags & MPTSAS_CMD_TIMEOUT) {
609*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
610*5b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed");
611*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
612*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
613*5b504601Sjiang wu - Sun Microsystems - Beijing China 
614*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
615*5b504601Sjiang wu - Sun Microsystems - Beijing China }
616*5b504601Sjiang wu - Sun Microsystems - Beijing China 
617*5b504601Sjiang wu - Sun Microsystems - Beijing China int
618*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_send_config_request_msg(mptsas_t *mpt, uint8_t action, uint8_t pagetype,
619*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t pageaddress, uint8_t pagenumber, uint8_t pageversion,
620*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t pagelength, uint32_t SGEflagslength, uint32_t SGEaddress32)
621*5b504601Sjiang wu - Sun Microsystems - Beijing China {
622*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2ConfigRequest_t	config;
623*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			send_numbytes;
624*5b504601Sjiang wu - Sun Microsystems - Beijing China 
625*5b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(mpt->m_hshk_memp, sizeof (MPI2_CONFIG_REQUEST));
626*5b504601Sjiang wu - Sun Microsystems - Beijing China 	config = (pMpi2ConfigRequest_t)mpt->m_hshk_memp;
627*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Function, MPI2_FUNCTION_CONFIG);
628*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Action, action);
629*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageNumber, pagenumber);
630*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageType, pagetype);
631*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_hshk_acc_hdl, &config->PageAddress, pageaddress);
632*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageVersion, pageversion);
633*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageLength, pagelength);
634*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_hshk_acc_hdl,
635*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &config->PageBufferSGE.MpiSimple.FlagsLength, SGEflagslength);
636*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_hshk_acc_hdl,
637*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &config->PageBufferSGE.MpiSimple.u.Address32, SGEaddress32);
638*5b504601Sjiang wu - Sun Microsystems - Beijing China 	send_numbytes = sizeof (MPI2_CONFIG_REQUEST);
639*5b504601Sjiang wu - Sun Microsystems - Beijing China 
640*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
641*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Post message via handshake
642*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
643*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_send_handshake_msg(mpt, (caddr_t)config, send_numbytes,
644*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    mpt->m_hshk_acc_hdl)) {
645*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
646*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
647*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (0);
648*5b504601Sjiang wu - Sun Microsystems - Beijing China }
649*5b504601Sjiang wu - Sun Microsystems - Beijing China 
650*5b504601Sjiang wu - Sun Microsystems - Beijing China int
651*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_send_extended_config_request_msg(mptsas_t *mpt, uint8_t action,
652*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t extpagetype, uint32_t pageaddress, uint8_t pagenumber,
653*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t pageversion, uint16_t extpagelength,
654*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t SGEflagslength, uint32_t SGEaddress32)
655*5b504601Sjiang wu - Sun Microsystems - Beijing China {
656*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2ConfigRequest_t	config;
657*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			send_numbytes;
658*5b504601Sjiang wu - Sun Microsystems - Beijing China 
659*5b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(mpt->m_hshk_memp, sizeof (MPI2_CONFIG_REQUEST));
660*5b504601Sjiang wu - Sun Microsystems - Beijing China 	config = (pMpi2ConfigRequest_t)mpt->m_hshk_memp;
661*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Function, MPI2_FUNCTION_CONFIG);
662*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Action, action);
663*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageNumber, pagenumber);
664*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageType,
665*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_CONFIG_PAGETYPE_EXTENDED);
666*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->ExtPageType, extpagetype);
667*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_hshk_acc_hdl, &config->PageAddress, pageaddress);
668*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageVersion, pageversion);
669*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put16(mpt->m_hshk_acc_hdl, &config->ExtPageLength, extpagelength);
670*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_hshk_acc_hdl,
671*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &config->PageBufferSGE.MpiSimple.FlagsLength, SGEflagslength);
672*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_hshk_acc_hdl,
673*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &config->PageBufferSGE.MpiSimple.u.Address32, SGEaddress32);
674*5b504601Sjiang wu - Sun Microsystems - Beijing China 	send_numbytes = sizeof (MPI2_CONFIG_REQUEST);
675*5b504601Sjiang wu - Sun Microsystems - Beijing China 
676*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
677*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Post message via handshake
678*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
679*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_send_handshake_msg(mpt, (caddr_t)config, send_numbytes,
680*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    mpt->m_hshk_acc_hdl)) {
681*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
682*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
683*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (0);
684*5b504601Sjiang wu - Sun Microsystems - Beijing China }
685*5b504601Sjiang wu - Sun Microsystems - Beijing China 
686*5b504601Sjiang wu - Sun Microsystems - Beijing China int
687*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_wait_for_response(mptsas_t *mpt)
688*5b504601Sjiang wu - Sun Microsystems - Beijing China {
689*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int	polls = 0;
690*5b504601Sjiang wu - Sun Microsystems - Beijing China 
691*5b504601Sjiang wu - Sun Microsystems - Beijing China 	while ((ddi_get32(mpt->m_datap,
692*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &mpt->m_reg->HostInterruptStatus) & MPI2_HIS_IOP_DOORBELL_STATUS)) {
693*5b504601Sjiang wu - Sun Microsystems - Beijing China 		drv_usecwait(1000);
694*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (polls++ > 60000) {
695*5b504601Sjiang wu - Sun Microsystems - Beijing China 			return (-1);
696*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
697*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
698*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (0);
699*5b504601Sjiang wu - Sun Microsystems - Beijing China }
700*5b504601Sjiang wu - Sun Microsystems - Beijing China 
701*5b504601Sjiang wu - Sun Microsystems - Beijing China int
702*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_wait_for_doorbell(mptsas_t *mpt)
703*5b504601Sjiang wu - Sun Microsystems - Beijing China {
704*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int	polls = 0;
705*5b504601Sjiang wu - Sun Microsystems - Beijing China 
706*5b504601Sjiang wu - Sun Microsystems - Beijing China 	while ((ddi_get32(mpt->m_datap,
707*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &mpt->m_reg->HostInterruptStatus) & MPI2_HIM_DIM) == 0) {
708*5b504601Sjiang wu - Sun Microsystems - Beijing China 		drv_usecwait(1000);
709*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (polls++ > 300000) {
710*5b504601Sjiang wu - Sun Microsystems - Beijing China 			return (-1);
711*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
712*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
713*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (0);
714*5b504601Sjiang wu - Sun Microsystems - Beijing China }
715*5b504601Sjiang wu - Sun Microsystems - Beijing China 
716*5b504601Sjiang wu - Sun Microsystems - Beijing China int
717*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_send_handshake_msg(mptsas_t *mpt, caddr_t memp, int numbytes,
718*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_acc_handle_t accessp)
719*5b504601Sjiang wu - Sun Microsystems - Beijing China {
720*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int	i;
721*5b504601Sjiang wu - Sun Microsystems - Beijing China 
722*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
723*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * clean pending doorbells
724*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
725*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptStatus, 0);
726*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_datap, &mpt->m_reg->Doorbell,
727*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    ((MPI2_FUNCTION_HANDSHAKE << MPI2_DOORBELL_FUNCTION_SHIFT) |
728*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    ((numbytes / 4) << MPI2_DOORBELL_ADD_DWORDS_SHIFT)));
729*5b504601Sjiang wu - Sun Microsystems - Beijing China 
730*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_ioc_wait_for_doorbell(mpt)) {
731*5b504601Sjiang wu - Sun Microsystems - Beijing China 		NDBG19(("mptsas_send_handshake failed.  Doorbell not ready\n"));
732*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
733*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
734*5b504601Sjiang wu - Sun Microsystems - Beijing China 
735*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
736*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * clean pending doorbells again
737*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
738*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptStatus, 0);
739*5b504601Sjiang wu - Sun Microsystems - Beijing China 
740*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_ioc_wait_for_response(mpt)) {
741*5b504601Sjiang wu - Sun Microsystems - Beijing China 		NDBG19(("mptsas_send_handshake failed.  Doorbell not "
742*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "cleared\n"));
743*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
744*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
745*5b504601Sjiang wu - Sun Microsystems - Beijing China 
746*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
747*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * post handshake message
748*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
749*5b504601Sjiang wu - Sun Microsystems - Beijing China 	for (i = 0; (i < numbytes / 4); i++, memp += 4) {
750*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_datap, &mpt->m_reg->Doorbell,
751*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get32(accessp, (uint32_t *)((void *)(memp))));
752*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_ioc_wait_for_response(mpt)) {
753*5b504601Sjiang wu - Sun Microsystems - Beijing China 			NDBG19(("mptsas_send_handshake failed posting "
754*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    "message\n"));
755*5b504601Sjiang wu - Sun Microsystems - Beijing China 			return (-1);
756*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
757*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
758*5b504601Sjiang wu - Sun Microsystems - Beijing China 
759*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) {
760*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
761*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_acc_err_clear(mpt->m_datap, DDI_FME_VER0);
762*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
763*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
764*5b504601Sjiang wu - Sun Microsystems - Beijing China 
765*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (0);
766*5b504601Sjiang wu - Sun Microsystems - Beijing China }
767*5b504601Sjiang wu - Sun Microsystems - Beijing China 
768*5b504601Sjiang wu - Sun Microsystems - Beijing China int
769*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_handshake_msg(mptsas_t *mpt, caddr_t memp, int numbytes,
770*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_acc_handle_t accessp)
771*5b504601Sjiang wu - Sun Microsystems - Beijing China {
772*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int		i, totalbytes, bytesleft;
773*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint16_t	val;
774*5b504601Sjiang wu - Sun Microsystems - Beijing China 
775*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
776*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * wait for doorbell
777*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
778*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_ioc_wait_for_doorbell(mpt)) {
779*5b504601Sjiang wu - Sun Microsystems - Beijing China 		NDBG19(("mptsas_get_handshake failed.  Doorbell not ready\n"));
780*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
781*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
782*5b504601Sjiang wu - Sun Microsystems - Beijing China 
783*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
784*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * get first 2 bytes of handshake message to determine how much
785*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * data we will be getting
786*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
787*5b504601Sjiang wu - Sun Microsystems - Beijing China 	for (i = 0; i < 2; i++, memp += 2) {
788*5b504601Sjiang wu - Sun Microsystems - Beijing China 		val = (ddi_get32(mpt->m_datap,
789*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &mpt->m_reg->Doorbell) & MPI2_DOORBELL_DATA_MASK);
790*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptStatus, 0);
791*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_ioc_wait_for_doorbell(mpt)) {
792*5b504601Sjiang wu - Sun Microsystems - Beijing China 			NDBG19(("mptsas_get_handshake failure getting initial"
793*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    " data\n"));
794*5b504601Sjiang wu - Sun Microsystems - Beijing China 			return (-1);
795*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
796*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put16(accessp, (uint16_t *)((void *)(memp)), val);
797*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (i == 1) {
798*5b504601Sjiang wu - Sun Microsystems - Beijing China 			totalbytes = (val & 0xFF) * 2;
799*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
800*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
801*5b504601Sjiang wu - Sun Microsystems - Beijing China 
802*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
803*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * If we are expecting less bytes than the message wants to send
804*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * we simply save as much as we expected and then throw out the rest
805*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * later
806*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
807*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (totalbytes > (numbytes / 2)) {
808*5b504601Sjiang wu - Sun Microsystems - Beijing China 		bytesleft = ((numbytes / 2) - 2);
809*5b504601Sjiang wu - Sun Microsystems - Beijing China 	} else {
810*5b504601Sjiang wu - Sun Microsystems - Beijing China 		bytesleft = (totalbytes - 2);
811*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
812*5b504601Sjiang wu - Sun Microsystems - Beijing China 
813*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
814*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Get the rest of the data
815*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
816*5b504601Sjiang wu - Sun Microsystems - Beijing China 	for (i = 0; i < bytesleft; i++, memp += 2) {
817*5b504601Sjiang wu - Sun Microsystems - Beijing China 		val = (ddi_get32(mpt->m_datap,
818*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &mpt->m_reg->Doorbell) & MPI2_DOORBELL_DATA_MASK);
819*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptStatus, 0);
820*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_ioc_wait_for_doorbell(mpt)) {
821*5b504601Sjiang wu - Sun Microsystems - Beijing China 			NDBG19(("mptsas_get_handshake failure getting"
822*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    " main data\n"));
823*5b504601Sjiang wu - Sun Microsystems - Beijing China 			return (-1);
824*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
825*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put16(accessp, (uint16_t *)((void *)(memp)), val);
826*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
827*5b504601Sjiang wu - Sun Microsystems - Beijing China 
828*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
829*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Sometimes the device will send more data than is expected
830*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * This data is not used by us but needs to be cleared from
831*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * ioc doorbell.  So we just read the values and throw
832*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * them out.
833*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
834*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (totalbytes > (numbytes / 2)) {
835*5b504601Sjiang wu - Sun Microsystems - Beijing China 		for (i = (numbytes / 2); i < totalbytes; i++) {
836*5b504601Sjiang wu - Sun Microsystems - Beijing China 			val = (ddi_get32(mpt->m_datap,
837*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    &mpt->m_reg->Doorbell) &
838*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_DOORBELL_DATA_MASK);
839*5b504601Sjiang wu - Sun Microsystems - Beijing China 			ddi_put32(mpt->m_datap,
840*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    &mpt->m_reg->HostInterruptStatus, 0);
841*5b504601Sjiang wu - Sun Microsystems - Beijing China 			if (mptsas_ioc_wait_for_doorbell(mpt)) {
842*5b504601Sjiang wu - Sun Microsystems - Beijing China 				NDBG19(("mptsas_get_handshake failure getting "
843*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    "extra garbage data\n"));
844*5b504601Sjiang wu - Sun Microsystems - Beijing China 				return (-1);
845*5b504601Sjiang wu - Sun Microsystems - Beijing China 			}
846*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
847*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
848*5b504601Sjiang wu - Sun Microsystems - Beijing China 
849*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptStatus, 0);
850*5b504601Sjiang wu - Sun Microsystems - Beijing China 
851*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) {
852*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
853*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_acc_err_clear(mpt->m_datap, DDI_FME_VER0);
854*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
855*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
856*5b504601Sjiang wu - Sun Microsystems - Beijing China 
857*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (0);
858*5b504601Sjiang wu - Sun Microsystems - Beijing China }
859*5b504601Sjiang wu - Sun Microsystems - Beijing China 
860*5b504601Sjiang wu - Sun Microsystems - Beijing China int
861*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_kick_start(mptsas_t *mpt)
862*5b504601Sjiang wu - Sun Microsystems - Beijing China {
863*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int		polls = 0;
864*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t	diag_reg, ioc_state, saved_HCB_size;
865*5b504601Sjiang wu - Sun Microsystems - Beijing China 
866*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
867*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Start a hard reset.  Write magic number and wait 900 uSeconds.
868*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
869*5b504601Sjiang wu - Sun Microsystems - Beijing China 	MPTSAS_ENABLE_DRWE(mpt);
870*5b504601Sjiang wu - Sun Microsystems - Beijing China 	drv_usecwait(900);
871*5b504601Sjiang wu - Sun Microsystems - Beijing China 
872*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
873*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Read the current Diag Reg and save the Host Controlled Boot size.
874*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
875*5b504601Sjiang wu - Sun Microsystems - Beijing China 	diag_reg = ddi_get32(mpt->m_datap, &mpt->m_reg->HostDiagnostic);
876*5b504601Sjiang wu - Sun Microsystems - Beijing China 	saved_HCB_size = ddi_get32(mpt->m_datap, &mpt->m_reg->HCBSize);
877*5b504601Sjiang wu - Sun Microsystems - Beijing China 
878*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
879*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Set Reset Adapter bit and wait 30 mSeconds.
880*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
881*5b504601Sjiang wu - Sun Microsystems - Beijing China 	diag_reg |= MPI2_DIAG_RESET_ADAPTER;
882*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_datap, &mpt->m_reg->HostDiagnostic, diag_reg);
883*5b504601Sjiang wu - Sun Microsystems - Beijing China 	drv_usecwait(30000);
884*5b504601Sjiang wu - Sun Microsystems - Beijing China 
885*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
886*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Poll, waiting for Reset Adapter bit to clear.  300 Seconds max
887*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * (600000 * 500 = 300,000,000 uSeconds, 300 seconds).
888*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * If no more adapter (all FF's), just return failure.
889*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
890*5b504601Sjiang wu - Sun Microsystems - Beijing China 	for (polls = 0; polls < 600000; polls++) {
891*5b504601Sjiang wu - Sun Microsystems - Beijing China 		diag_reg = ddi_get32(mpt->m_datap,
892*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &mpt->m_reg->HostDiagnostic);
893*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (diag_reg == 0xFFFFFFFF) {
894*5b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
895*5b504601Sjiang wu - Sun Microsystems - Beijing China 			ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
896*5b504601Sjiang wu - Sun Microsystems - Beijing China 			return (DDI_FAILURE);
897*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
898*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (!(diag_reg & MPI2_DIAG_RESET_ADAPTER)) {
899*5b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
900*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
901*5b504601Sjiang wu - Sun Microsystems - Beijing China 		drv_usecwait(500);
902*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
903*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (polls == 600000) {
904*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
905*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
906*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
907*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
908*5b504601Sjiang wu - Sun Microsystems - Beijing China 
909*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
910*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Check if adapter is in Host Boot Mode.  If so, restart adapter
911*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * assuming the HCB points to good FW.
912*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Set BootDeviceSel to HCDW (Host Code and Data Window).
913*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
914*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (diag_reg & MPI2_DIAG_HCB_MODE) {
915*5b504601Sjiang wu - Sun Microsystems - Beijing China 		diag_reg &= ~MPI2_DIAG_BOOT_DEVICE_SELECT_MASK;
916*5b504601Sjiang wu - Sun Microsystems - Beijing China 		diag_reg |= MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW;
917*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_datap, &mpt->m_reg->HostDiagnostic, diag_reg);
918*5b504601Sjiang wu - Sun Microsystems - Beijing China 
919*5b504601Sjiang wu - Sun Microsystems - Beijing China 		/*
920*5b504601Sjiang wu - Sun Microsystems - Beijing China 		 * Re-enable the HCDW.
921*5b504601Sjiang wu - Sun Microsystems - Beijing China 		 */
922*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_datap, &mpt->m_reg->HCBSize,
923*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    (saved_HCB_size | MPI2_HCB_SIZE_HCB_ENABLE));
924*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
925*5b504601Sjiang wu - Sun Microsystems - Beijing China 
926*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
927*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Restart the adapter.
928*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
929*5b504601Sjiang wu - Sun Microsystems - Beijing China 	diag_reg &= ~MPI2_DIAG_HOLD_IOC_RESET;
930*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_datap, &mpt->m_reg->HostDiagnostic, diag_reg);
931*5b504601Sjiang wu - Sun Microsystems - Beijing China 
932*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
933*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Disable writes to the Host Diag register.
934*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
935*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_datap, &mpt->m_reg->WriteSequence,
936*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_WRSEQ_FLUSH_KEY_VALUE);
937*5b504601Sjiang wu - Sun Microsystems - Beijing China 
938*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
939*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Wait 20 seconds max for FW to come to ready state.
940*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
941*5b504601Sjiang wu - Sun Microsystems - Beijing China 	for (polls = 0; polls < 20000; polls++) {
942*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ioc_state = ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell);
943*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (ioc_state == 0xFFFFFFFF) {
944*5b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
945*5b504601Sjiang wu - Sun Microsystems - Beijing China 			ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
946*5b504601Sjiang wu - Sun Microsystems - Beijing China 			return (DDI_FAILURE);
947*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
948*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if ((ioc_state & MPI2_IOC_STATE_MASK) ==
949*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_IOC_STATE_READY) {
950*5b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
951*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
952*5b504601Sjiang wu - Sun Microsystems - Beijing China 		drv_usecwait(1000);
953*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
954*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (polls == 20000) {
955*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
956*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
957*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
958*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
959*5b504601Sjiang wu - Sun Microsystems - Beijing China 
960*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
961*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Clear the ioc ack events queue.
962*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
963*5b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_destroy_ioc_event_cmd(mpt);
964*5b504601Sjiang wu - Sun Microsystems - Beijing China 
965*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
966*5b504601Sjiang wu - Sun Microsystems - Beijing China }
967*5b504601Sjiang wu - Sun Microsystems - Beijing China 
968*5b504601Sjiang wu - Sun Microsystems - Beijing China int
969*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_reset(mptsas_t *mpt)
970*5b504601Sjiang wu - Sun Microsystems - Beijing China {
971*5b504601Sjiang wu - Sun Microsystems - Beijing China #ifdef SLM
972*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int		polls = 0;
973*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t	reset_msg;
974*5b504601Sjiang wu - Sun Microsystems - Beijing China 
975*5b504601Sjiang wu - Sun Microsystems - Beijing China #endif
976*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t	ioc_state;
977*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ioc_state = ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell);
978*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
979*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * If chip is already in ready state then there is nothing to do.
980*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
981*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ioc_state == MPI2_IOC_STATE_READY) {
982*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (MPTSAS_NO_RESET);
983*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
984*5b504601Sjiang wu - Sun Microsystems - Beijing China 
985*5b504601Sjiang wu - Sun Microsystems - Beijing China /*
986*5b504601Sjiang wu - Sun Microsystems - Beijing China  * SLM-test; skip MUR for now
987*5b504601Sjiang wu - Sun Microsystems - Beijing China  */
988*5b504601Sjiang wu - Sun Microsystems - Beijing China #ifdef SLM
989*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
990*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * If the chip is already operational, we just need to send
991*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * it a message unit reset to put it back in the ready state
992*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
993*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ioc_state & MPI2_IOC_STATE_OPERATIONAL) {
994*5b504601Sjiang wu - Sun Microsystems - Beijing China 		reset_msg = MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET;
995*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_put32(mpt->m_datap, &mpt->m_reg->Doorbell,
996*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    (reset_msg << MPI2_DOORBELL_FUNCTION_SHIFT));
997*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_ioc_wait_for_response(mpt)) {
998*5b504601Sjiang wu - Sun Microsystems - Beijing China 			NDBG19(("mptsas_ioc_reset failure sending "
999*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    "message_unit_reset\n"));
1000*5b504601Sjiang wu - Sun Microsystems - Beijing China 			goto hard_reset;
1001*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1002*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1003*5b504601Sjiang wu - Sun Microsystems - Beijing China 		/*
1004*5b504601Sjiang wu - Sun Microsystems - Beijing China 		 * Wait for chip to become ready
1005*5b504601Sjiang wu - Sun Microsystems - Beijing China 		 */
1006*5b504601Sjiang wu - Sun Microsystems - Beijing China 		while ((ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell) &
1007*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_IOC_STATE_READY) == 0x0) {
1008*5b504601Sjiang wu - Sun Microsystems - Beijing China 			drv_usecwait(1000);
1009*5b504601Sjiang wu - Sun Microsystems - Beijing China 			if (polls++ > 20000) {
1010*5b504601Sjiang wu - Sun Microsystems - Beijing China 				goto hard_reset;
1011*5b504601Sjiang wu - Sun Microsystems - Beijing China 			}
1012*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1013*5b504601Sjiang wu - Sun Microsystems - Beijing China 		/*
1014*5b504601Sjiang wu - Sun Microsystems - Beijing China 		 * the message unit reset would do reset operations
1015*5b504601Sjiang wu - Sun Microsystems - Beijing China 		 * clear reply and request queue, so we should clear
1016*5b504601Sjiang wu - Sun Microsystems - Beijing China 		 * ACK event cmd.
1017*5b504601Sjiang wu - Sun Microsystems - Beijing China 		 */
1018*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_destroy_ioc_event_cmd(mpt);
1019*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (MPTSAS_NO_RESET);
1020*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1021*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1022*5b504601Sjiang wu - Sun Microsystems - Beijing China hard_reset:
1023*5b504601Sjiang wu - Sun Microsystems - Beijing China #endif
1024*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_kick_start(mpt) == DDI_FAILURE) {
1025*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
1026*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
1027*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (MPTSAS_RESET_FAIL);
1028*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1029*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (MPTSAS_SUCCESS_HARDRESET);
1030*5b504601Sjiang wu - Sun Microsystems - Beijing China }
1031*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1032*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1033*5b504601Sjiang wu - Sun Microsystems - Beijing China int
1034*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_request_from_pool(mptsas_t *mpt, mptsas_cmd_t **cmd,
1035*5b504601Sjiang wu - Sun Microsystems - Beijing China     struct scsi_pkt **pkt)
1036*5b504601Sjiang wu - Sun Microsystems - Beijing China {
1037*5b504601Sjiang wu - Sun Microsystems - Beijing China 	m_event_struct_t	*ioc_cmd = NULL;
1038*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1039*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ioc_cmd = kmem_zalloc(M_EVENT_STRUCT_SIZE, KM_SLEEP);
1040*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ioc_cmd == NULL) {
1041*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
1042*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1043*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ioc_cmd->m_event_linkp = NULL;
1044*5b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_ioc_event_cmdq_add(mpt, ioc_cmd);
1045*5b504601Sjiang wu - Sun Microsystems - Beijing China 	*cmd = &(ioc_cmd->m_event_cmd);
1046*5b504601Sjiang wu - Sun Microsystems - Beijing China 	*pkt = &(ioc_cmd->m_event_pkt);
1047*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1048*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
1049*5b504601Sjiang wu - Sun Microsystems - Beijing China }
1050*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1051*5b504601Sjiang wu - Sun Microsystems - Beijing China void
1052*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_return_to_pool(mptsas_t *mpt, mptsas_cmd_t *cmd)
1053*5b504601Sjiang wu - Sun Microsystems - Beijing China {
1054*5b504601Sjiang wu - Sun Microsystems - Beijing China 	m_event_struct_t	*ioc_cmd = NULL;
1055*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1056*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ioc_cmd = mptsas_ioc_event_find_by_cmd(mpt, cmd);
1057*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ioc_cmd == NULL) {
1058*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return;
1059*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1060*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1061*5b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_ioc_event_cmdq_delete(mpt, ioc_cmd);
1062*5b504601Sjiang wu - Sun Microsystems - Beijing China 	kmem_free(ioc_cmd, M_EVENT_STRUCT_SIZE);
1063*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ioc_cmd = NULL;
1064*5b504601Sjiang wu - Sun Microsystems - Beijing China }
1065*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1066*5b504601Sjiang wu - Sun Microsystems - Beijing China /*
1067*5b504601Sjiang wu - Sun Microsystems - Beijing China  * NOTE: We should be able to queue TM requests in the controller to make this
1068*5b504601Sjiang wu - Sun Microsystems - Beijing China  * a lot faster.  If resetting all targets, for example, we can load the hi
1069*5b504601Sjiang wu - Sun Microsystems - Beijing China  * priority queue with its limit and the controller will reply as they are
1070*5b504601Sjiang wu - Sun Microsystems - Beijing China  * completed.  This way, we don't have to poll for one reply at a time.
1071*5b504601Sjiang wu - Sun Microsystems - Beijing China  * Think about enhancing this later.
1072*5b504601Sjiang wu - Sun Microsystems - Beijing China  */
1073*5b504601Sjiang wu - Sun Microsystems - Beijing China int
1074*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_task_management(mptsas_t *mpt, int task_type, uint16_t dev_handle,
1075*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int lun)
1076*5b504601Sjiang wu - Sun Microsystems - Beijing China {
1077*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1078*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * In order to avoid allocating variables on the stack,
1079*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * we make use of the pre-existing mptsas_cmd_t and
1080*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * scsi_pkt which are included in the mptsas_t which
1081*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * is passed to this routine.
1082*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1083*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1084*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2SCSITaskManagementRequest_t	task;
1085*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int					rval = FALSE;
1086*5b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_cmd_t				*cmd;
1087*5b504601Sjiang wu - Sun Microsystems - Beijing China 	struct scsi_pkt				*pkt;
1088*5b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_slots_t				*slots = mpt->m_active;
1089*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t				request_desc_low, int_mask;
1090*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1091*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1092*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Can't start another task management routine.
1093*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1094*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (slots->m_slot[MPTSAS_TM_SLOT(mpt)] != NULL) {
1095*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "Can only start 1 task management"
1096*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    " command at a time\n");
1097*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (FALSE);
1098*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1099*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1100*5b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd = &(mpt->m_event_task_mgmt.m_event_cmd);
1101*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt = &(mpt->m_event_task_mgmt.m_event_pkt);
1102*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1103*5b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero((caddr_t)cmd, sizeof (*cmd));
1104*5b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero((caddr_t)pkt, scsi_pkt_size());
1105*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1106*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_cdbp		= (opaque_t)&cmd->cmd_cdb[0];
1107*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_scbp		= (opaque_t)&cmd->cmd_scb;
1108*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_ha_private	= (opaque_t)cmd;
1109*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_flags		= (FLAG_NOINTR | FLAG_HEAD);
1110*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_time		= 60;
1111*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_address.a_target = dev_handle;
1112*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_address.a_lun = (uchar_t)lun;
1113*5b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_pkt		= pkt;
1114*5b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_scblen		= 1;
1115*5b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_flags		= CFLAG_TM_CMD;
1116*5b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_slot		= MPTSAS_TM_SLOT(mpt);
1117*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1118*5b504601Sjiang wu - Sun Microsystems - Beijing China 	slots->m_slot[MPTSAS_TM_SLOT(mpt)] = cmd;
1119*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1120*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1121*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Store the TM message in memory location corresponding to the TM slot
1122*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * number.
1123*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1124*5b504601Sjiang wu - Sun Microsystems - Beijing China 	task = (pMpi2SCSITaskManagementRequest_t)(mpt->m_req_frame +
1125*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    (mpt->m_req_frame_size * cmd->cmd_slot));
1126*5b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(task, mpt->m_req_frame_size);
1127*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1128*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1129*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * form message for requested task
1130*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1131*5b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_init_std_hdr(mpt->m_acc_req_frame_hdl, task, dev_handle, lun, 0,
1132*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_FUNCTION_SCSI_TASK_MGMT);
1133*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1134*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1135*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Set the task type
1136*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1137*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &task->TaskType, task_type);
1138*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1139*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1140*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Get the current interrupt mask.  When re-enabling ints, set mask to
1141*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * saved value.
1142*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1143*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int_mask = ddi_get32(mpt->m_datap, &mpt->m_reg->HostInterruptMask);
1144*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1145*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1146*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Send TM request using High Priority Queue.
1147*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1148*5b504601Sjiang wu - Sun Microsystems - Beijing China 	MPTSAS_DISABLE_INTR(mpt);
1149*5b504601Sjiang wu - Sun Microsystems - Beijing China 	(void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0,
1150*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SYNC_FORDEV);
1151*5b504601Sjiang wu - Sun Microsystems - Beijing China 	request_desc_low = (cmd->cmd_slot << 16) +
1152*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
1153*5b504601Sjiang wu - Sun Microsystems - Beijing China 	MPTSAS_START_CMD(mpt, request_desc_low, 0);
1154*5b504601Sjiang wu - Sun Microsystems - Beijing China 	rval = mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME);
1155*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, int_mask);
1156*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1157*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (pkt->pkt_reason == CMD_INCOMPLETE)
1158*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = FALSE;
1159*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1160*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1161*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * clear the TM slot before returning
1162*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1163*5b504601Sjiang wu - Sun Microsystems - Beijing China 	slots->m_slot[MPTSAS_TM_SLOT(mpt)] = NULL;
1164*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1165*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1166*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * If we lost our task management command
1167*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * we need to reset the ioc
1168*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1169*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (rval == FALSE) {
1170*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "mptsas_ioc_task_management failed "
1171*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "try to reset ioc to recovery!");
1172*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_restart_ioc(mpt)) {
1173*5b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed");
1174*5b504601Sjiang wu - Sun Microsystems - Beijing China 			rval = FAILED;
1175*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1176*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1177*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1178*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
1179*5b504601Sjiang wu - Sun Microsystems - Beijing China }
1180*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1181*5b504601Sjiang wu - Sun Microsystems - Beijing China int
1182*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_update_flash(mptsas_t *mpt, caddr_t ptrbuffer, uint32_t size,
1183*5b504601Sjiang wu - Sun Microsystems - Beijing China     uint8_t type, int mode)
1184*5b504601Sjiang wu - Sun Microsystems - Beijing China {
1185*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1186*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1187*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * In order to avoid allocating variables on the stack,
1188*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * we make use of the pre-existing mptsas_cmd_t and
1189*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * scsi_pkt which are included in the mptsas_t which
1190*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * is passed to this routine.
1191*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1192*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1193*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_attr_t		flsh_dma_attrs;
1194*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint_t			flsh_ncookie;
1195*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_cookie_t	flsh_cookie;
1196*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_handle_t	flsh_dma_handle;
1197*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_acc_handle_t	flsh_accessp;
1198*5b504601Sjiang wu - Sun Microsystems - Beijing China 	size_t			flsh_alloc_len;
1199*5b504601Sjiang wu - Sun Microsystems - Beijing China 	caddr_t			memp, flsh_memp;
1200*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		flagslength;
1201*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2FWDownloadRequest	fwdownload;
1202*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2FWDownloadTCSGE_t	tcsge;
1203*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2SGESimple64_t	sge;
1204*5b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_cmd_t		*cmd;
1205*5b504601Sjiang wu - Sun Microsystems - Beijing China 	struct scsi_pkt		*pkt;
1206*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			i;
1207*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			rvalue = 0;
1208*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		request_desc_low;
1209*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1210*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
1211*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "mptsas_update_flash(): allocation "
1212*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "failed. event ack command pool is full\n");
1213*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (rvalue);
1214*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1215*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1216*5b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero((caddr_t)cmd, sizeof (*cmd));
1217*5b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero((caddr_t)pkt, scsi_pkt_size());
1218*5b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->ioc_cmd_slot = (uint32_t)rvalue;
1219*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1220*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1221*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * dynamically create a customized dma attribute structure
1222*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * that describes the flash file.
1223*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1224*5b504601Sjiang wu - Sun Microsystems - Beijing China 	flsh_dma_attrs = mpt->m_msg_dma_attr;
1225*5b504601Sjiang wu - Sun Microsystems - Beijing China 	flsh_dma_attrs.dma_attr_sgllen = 1;
1226*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1227*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_alloc_handle(mpt->m_dip, &flsh_dma_attrs,
1228*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SLEEP, NULL, &flsh_dma_handle) != DDI_SUCCESS) {
1229*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN,
1230*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "(unable to allocate dma handle.");
1231*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_return_to_pool(mpt, cmd);
1232*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
1233*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1234*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1235*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_mem_alloc(flsh_dma_handle, size,
1236*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
1237*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &flsh_memp, &flsh_alloc_len, &flsh_accessp) != DDI_SUCCESS) {
1238*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&flsh_dma_handle);
1239*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN,
1240*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "unable to allocate flash structure.");
1241*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_return_to_pool(mpt, cmd);
1242*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
1243*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1244*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1245*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_addr_bind_handle(flsh_dma_handle, NULL, flsh_memp,
1246*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    flsh_alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
1247*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    NULL, &flsh_cookie, &flsh_ncookie) != DDI_DMA_MAPPED) {
1248*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_mem_free(&flsh_accessp);
1249*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&flsh_dma_handle);
1250*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "unable to bind DMA resources.");
1251*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_return_to_pool(mpt, cmd);
1252*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
1253*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1254*5b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(flsh_memp, size);
1255*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1256*5b504601Sjiang wu - Sun Microsystems - Beijing China 	for (i = 0; i < size; i++) {
1257*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_copyin(ptrbuffer + i, flsh_memp + i, 1, mode);
1258*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1259*5b504601Sjiang wu - Sun Microsystems - Beijing China 	(void) ddi_dma_sync(flsh_dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV);
1260*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1261*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1262*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * form a cmd/pkt to store the fw download message
1263*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1264*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_cdbp		= (opaque_t)&cmd->cmd_cdb[0];
1265*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_scbp		= (opaque_t)&cmd->cmd_scb;
1266*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_ha_private	= (opaque_t)cmd;
1267*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_flags		= FLAG_HEAD;
1268*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pkt->pkt_time		= 60;
1269*5b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_pkt		= pkt;
1270*5b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_scblen		= 1;
1271*5b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_flags		= CFLAG_CMDIOC | CFLAG_FW_CMD;
1272*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1273*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1274*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Save the command in a slot
1275*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1276*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_save_cmd(mpt, cmd) == FALSE) {
1277*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_unbind_handle(flsh_dma_handle);
1278*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_mem_free(&flsh_accessp);
1279*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&flsh_dma_handle);
1280*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_return_to_pool(mpt, cmd);
1281*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (-1);
1282*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1283*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1284*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1285*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Fill in fw download message
1286*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1287*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ASSERT(cmd->cmd_slot != 0);
1288*5b504601Sjiang wu - Sun Microsystems - Beijing China 	memp = mpt->m_req_frame + (mpt->m_req_frame_size * cmd->cmd_slot);
1289*5b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(memp, mpt->m_req_frame_size);
1290*5b504601Sjiang wu - Sun Microsystems - Beijing China 	fwdownload = (void *)memp;
1291*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &fwdownload->Function,
1292*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_FUNCTION_FW_DOWNLOAD);
1293*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &fwdownload->ImageType, type);
1294*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &fwdownload->MsgFlags,
1295*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT);
1296*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_acc_req_frame_hdl, &fwdownload->TotalImageSize, size);
1297*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1298*5b504601Sjiang wu - Sun Microsystems - Beijing China 	tcsge = (pMpi2FWDownloadTCSGE_t)&fwdownload->SGL;
1299*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &tcsge->ContextSize, 0);
1300*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &tcsge->DetailsLength, 12);
1301*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put8(mpt->m_acc_req_frame_hdl, &tcsge->Flags, 0);
1302*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_acc_req_frame_hdl, &tcsge->ImageOffset, 0);
1303*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_acc_req_frame_hdl, &tcsge->ImageSize, size);
1304*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1305*5b504601Sjiang wu - Sun Microsystems - Beijing China 	sge = (pMpi2SGESimple64_t)(tcsge + 1);
1306*5b504601Sjiang wu - Sun Microsystems - Beijing China 	flagslength = size;
1307*5b504601Sjiang wu - Sun Microsystems - Beijing China 	flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT |
1308*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_END_OF_BUFFER |
1309*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1310*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
1311*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_64_BIT_ADDRESSING |
1312*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_HOST_TO_IOC |
1313*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
1314*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_acc_req_frame_hdl, &sge->FlagsLength, flagslength);
1315*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.Low,
1316*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    flsh_cookie.dmac_address);
1317*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.High,
1318*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    (uint32_t)(flsh_cookie.dmac_laddress >> 32));
1319*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1320*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1321*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Start command
1322*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1323*5b504601Sjiang wu - Sun Microsystems - Beijing China 	(void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0,
1324*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SYNC_FORDEV);
1325*5b504601Sjiang wu - Sun Microsystems - Beijing China 	request_desc_low = (cmd->cmd_slot << 16) +
1326*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1327*5b504601Sjiang wu - Sun Microsystems - Beijing China 	cmd->cmd_rfm = NULL;
1328*5b504601Sjiang wu - Sun Microsystems - Beijing China 	MPTSAS_START_CMD(mpt, request_desc_low, 0);
1329*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1330*5b504601Sjiang wu - Sun Microsystems - Beijing China 	rvalue = 0;
1331*5b504601Sjiang wu - Sun Microsystems - Beijing China 	(void) cv_timedwait(&mpt->m_fw_cv, &mpt->m_mutex,
1332*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPTSAS_CV_TIMEOUT(60));
1333*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (!(cmd->cmd_flags & CFLAG_FINISHED)) {
1334*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
1335*5b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed");
1336*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1337*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rvalue = -1;
1338*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1339*5b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_remove_cmd(mpt, cmd);
1340*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1341*5b504601Sjiang wu - Sun Microsystems - Beijing China 	(void) ddi_dma_unbind_handle(flsh_dma_handle);
1342*5b504601Sjiang wu - Sun Microsystems - Beijing China 	(void) ddi_dma_mem_free(&flsh_accessp);
1343*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_free_handle(&flsh_dma_handle);
1344*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1345*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rvalue);
1346*5b504601Sjiang wu - Sun Microsystems - Beijing China }
1347*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1348*5b504601Sjiang wu - Sun Microsystems - Beijing China static int
1349*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_sasdevpage_0_cb(mptsas_t *mpt, caddr_t page_memp,
1350*5b504601Sjiang wu - Sun Microsystems - Beijing China     ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo,
1351*5b504601Sjiang wu - Sun Microsystems - Beijing China     va_list ap)
1352*5b504601Sjiang wu - Sun Microsystems - Beijing China {
1353*5b504601Sjiang wu - Sun Microsystems - Beijing China #ifndef __lock_lint
1354*5b504601Sjiang wu - Sun Microsystems - Beijing China 	_NOTE(ARGUNUSED(ap))
1355*5b504601Sjiang wu - Sun Microsystems - Beijing China #endif
1356*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2SasDevicePage0_t	sasdevpage;
1357*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			rval = DDI_SUCCESS, i;
1358*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t			*sas_addr = NULL;
1359*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t			tmp_sas_wwn[SAS_WWN_BYTE_SIZE];
1360*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint16_t		*devhdl;
1361*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint64_t		*sas_wwn;
1362*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		*dev_info;
1363*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t			*physport, *phynum;
1364*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		page_address;
1365*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1366*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) &&
1367*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    (iocstatus != MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)) {
1368*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "mptsas_get_sas_device_page0 "
1369*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "header: IOCStatus=0x%x, IOCLogInfo=0x%x",
1370*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    iocstatus, iocloginfo);
1371*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
1372*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (rval);
1373*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1374*5b504601Sjiang wu - Sun Microsystems - Beijing China 	page_address = va_arg(ap, uint32_t);
1375*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1376*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * The INVALID_PAGE status is normal if using GET_NEXT_HANDLE and there
1377*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * are no more pages.  If everything is OK up to this point but the
1378*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * status is INVALID_PAGE, change rval to FAILURE and quit.  Also,
1379*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * signal that device traversal is complete.
1380*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1381*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (iocstatus == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) {
1382*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if ((page_address & MPI2_SAS_DEVICE_PGAD_FORM_MASK) ==
1383*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE) {
1384*5b504601Sjiang wu - Sun Microsystems - Beijing China 			mpt->m_done_traverse_dev = 1;
1385*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1386*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
1387*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (rval);
1388*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1389*5b504601Sjiang wu - Sun Microsystems - Beijing China 	devhdl = va_arg(ap, uint16_t *);
1390*5b504601Sjiang wu - Sun Microsystems - Beijing China 	sas_wwn = va_arg(ap, uint64_t *);
1391*5b504601Sjiang wu - Sun Microsystems - Beijing China 	dev_info = va_arg(ap, uint32_t *);
1392*5b504601Sjiang wu - Sun Microsystems - Beijing China 	physport = va_arg(ap, uint8_t *);
1393*5b504601Sjiang wu - Sun Microsystems - Beijing China 	phynum = va_arg(ap, uint8_t *);
1394*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1395*5b504601Sjiang wu - Sun Microsystems - Beijing China 	sasdevpage = (pMpi2SasDevicePage0_t)page_memp;
1396*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1397*5b504601Sjiang wu - Sun Microsystems - Beijing China 	*dev_info = ddi_get32(accessp, &sasdevpage->DeviceInfo);
1398*5b504601Sjiang wu - Sun Microsystems - Beijing China 	*devhdl = ddi_get16(accessp, &sasdevpage->DevHandle);
1399*5b504601Sjiang wu - Sun Microsystems - Beijing China 	sas_addr = (uint8_t *)(&sasdevpage->SASAddress);
1400*5b504601Sjiang wu - Sun Microsystems - Beijing China 	for (i = 0; i < SAS_WWN_BYTE_SIZE; i++) {
1401*5b504601Sjiang wu - Sun Microsystems - Beijing China 		tmp_sas_wwn[i] = ddi_get8(accessp, sas_addr + i);
1402*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1403*5b504601Sjiang wu - Sun Microsystems - Beijing China 	bcopy(tmp_sas_wwn, sas_wwn, SAS_WWN_BYTE_SIZE);
1404*5b504601Sjiang wu - Sun Microsystems - Beijing China 	*sas_wwn = LE_64(*sas_wwn);
1405*5b504601Sjiang wu - Sun Microsystems - Beijing China 	*physport = ddi_get8(accessp, &sasdevpage->PhysicalPort);
1406*5b504601Sjiang wu - Sun Microsystems - Beijing China 	*phynum = ddi_get8(accessp, &sasdevpage->PhyNum);
1407*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
1408*5b504601Sjiang wu - Sun Microsystems - Beijing China }
1409*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1410*5b504601Sjiang wu - Sun Microsystems - Beijing China /*
1411*5b504601Sjiang wu - Sun Microsystems - Beijing China  * Request MPI configuration page SAS device page 0 to get DevHandle, device
1412*5b504601Sjiang wu - Sun Microsystems - Beijing China  * info and SAS address.
1413*5b504601Sjiang wu - Sun Microsystems - Beijing China  */
1414*5b504601Sjiang wu - Sun Microsystems - Beijing China int
1415*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_sas_device_page0(mptsas_t *mpt, uint32_t page_address,
1416*5b504601Sjiang wu - Sun Microsystems - Beijing China     uint16_t *dev_handle, uint64_t *sas_wwn, uint32_t *dev_info,
1417*5b504601Sjiang wu - Sun Microsystems - Beijing China     uint8_t *physport, uint8_t *phynum)
1418*5b504601Sjiang wu - Sun Microsystems - Beijing China {
1419*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int rval = DDI_SUCCESS;
1420*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1421*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ASSERT(mutex_owned(&mpt->m_mutex));
1422*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1423*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1424*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Get the header and config page.  reply contains the reply frame,
1425*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * which holds status info for the request.
1426*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1427*5b504601Sjiang wu - Sun Microsystems - Beijing China 	rval = mptsas_access_config_page(mpt,
1428*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_CONFIG_ACTION_PAGE_READ_CURRENT,
1429*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE, 0, page_address,
1430*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    mptsas_sasdevpage_0_cb, page_address, dev_handle, sas_wwn,
1431*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    dev_info, physport, phynum);
1432*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1433*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
1434*5b504601Sjiang wu - Sun Microsystems - Beijing China }
1435*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1436*5b504601Sjiang wu - Sun Microsystems - Beijing China static int
1437*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_sasexpdpage_0_cb(mptsas_t *mpt, caddr_t page_memp,
1438*5b504601Sjiang wu - Sun Microsystems - Beijing China     ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo,
1439*5b504601Sjiang wu - Sun Microsystems - Beijing China     va_list ap)
1440*5b504601Sjiang wu - Sun Microsystems - Beijing China {
1441*5b504601Sjiang wu - Sun Microsystems - Beijing China #ifndef __lock_lint
1442*5b504601Sjiang wu - Sun Microsystems - Beijing China 	_NOTE(ARGUNUSED(ap))
1443*5b504601Sjiang wu - Sun Microsystems - Beijing China #endif
1444*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2ExpanderPage0_t	expddevpage;
1445*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			rval = DDI_SUCCESS, i;
1446*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t			*sas_addr = NULL;
1447*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t			tmp_sas_wwn[SAS_WWN_BYTE_SIZE];
1448*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint16_t		*devhdl;
1449*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint64_t		*sas_wwn;
1450*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t			physport, *phymask;
1451*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		page_address;
1452*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1453*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) &&
1454*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    (iocstatus != MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)) {
1455*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "mptsas_get_sas_expander_page0 "
1456*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "config: IOCStatus=0x%x, IOCLogInfo=0x%x",
1457*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    iocstatus, iocloginfo);
1458*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
1459*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (rval);
1460*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1461*5b504601Sjiang wu - Sun Microsystems - Beijing China 	page_address = va_arg(ap, uint32_t);
1462*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1463*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * The INVALID_PAGE status is normal if using GET_NEXT_HANDLE and there
1464*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * are no more pages.  If everything is OK up to this point but the
1465*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * status is INVALID_PAGE, change rval to FAILURE and quit.  Also,
1466*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * signal that device traversal is complete.
1467*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1468*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (iocstatus == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) {
1469*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if ((page_address & MPI2_SAS_EXPAND_PGAD_FORM_MASK) ==
1470*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL) {
1471*5b504601Sjiang wu - Sun Microsystems - Beijing China 			mpt->m_done_traverse_smp = 1;
1472*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1473*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
1474*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (rval);
1475*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1476*5b504601Sjiang wu - Sun Microsystems - Beijing China 	devhdl = va_arg(ap, uint16_t *);
1477*5b504601Sjiang wu - Sun Microsystems - Beijing China 	sas_wwn = va_arg(ap, uint64_t *);
1478*5b504601Sjiang wu - Sun Microsystems - Beijing China 	phymask = va_arg(ap, uint8_t *);
1479*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1480*5b504601Sjiang wu - Sun Microsystems - Beijing China 	expddevpage = (pMpi2ExpanderPage0_t)page_memp;
1481*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1482*5b504601Sjiang wu - Sun Microsystems - Beijing China 	*devhdl = ddi_get16(accessp, &expddevpage->DevHandle);
1483*5b504601Sjiang wu - Sun Microsystems - Beijing China 	physport = ddi_get8(accessp, &expddevpage->PhysicalPort);
1484*5b504601Sjiang wu - Sun Microsystems - Beijing China 	*phymask = mptsas_physport_to_phymask(mpt, physport);
1485*5b504601Sjiang wu - Sun Microsystems - Beijing China 	sas_addr = (uint8_t *)(&expddevpage->SASAddress);
1486*5b504601Sjiang wu - Sun Microsystems - Beijing China 	for (i = 0; i < SAS_WWN_BYTE_SIZE; i++) {
1487*5b504601Sjiang wu - Sun Microsystems - Beijing China 		tmp_sas_wwn[i] = ddi_get8(accessp, sas_addr + i);
1488*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1489*5b504601Sjiang wu - Sun Microsystems - Beijing China 	bcopy(tmp_sas_wwn, sas_wwn, SAS_WWN_BYTE_SIZE);
1490*5b504601Sjiang wu - Sun Microsystems - Beijing China 	*sas_wwn = LE_64(*sas_wwn);
1491*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
1492*5b504601Sjiang wu - Sun Microsystems - Beijing China }
1493*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1494*5b504601Sjiang wu - Sun Microsystems - Beijing China /*
1495*5b504601Sjiang wu - Sun Microsystems - Beijing China  * Request MPI configuration page SAS device page 0 to get DevHandle, phymask
1496*5b504601Sjiang wu - Sun Microsystems - Beijing China  * and SAS address.
1497*5b504601Sjiang wu - Sun Microsystems - Beijing China  */
1498*5b504601Sjiang wu - Sun Microsystems - Beijing China int
1499*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_sas_expander_page0(mptsas_t *mpt, uint32_t page_address,
1500*5b504601Sjiang wu - Sun Microsystems - Beijing China     mptsas_smp_t *info)
1501*5b504601Sjiang wu - Sun Microsystems - Beijing China {
1502*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			rval = DDI_SUCCESS;
1503*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1504*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ASSERT(mutex_owned(&mpt->m_mutex));
1505*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1506*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1507*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Get the header and config page.  reply contains the reply frame,
1508*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * which holds status info for the request.
1509*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1510*5b504601Sjiang wu - Sun Microsystems - Beijing China 	rval = mptsas_access_config_page(mpt,
1511*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_CONFIG_ACTION_PAGE_READ_CURRENT,
1512*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER, 0, page_address,
1513*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    mptsas_sasexpdpage_0_cb, page_address, &info->m_devhdl,
1514*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &info->m_sasaddr, &info->m_phymask);
1515*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1516*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
1517*5b504601Sjiang wu - Sun Microsystems - Beijing China }
1518*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1519*5b504601Sjiang wu - Sun Microsystems - Beijing China static int
1520*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_sasportpage_0_cb(mptsas_t *mpt, caddr_t page_memp,
1521*5b504601Sjiang wu - Sun Microsystems - Beijing China     ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo,
1522*5b504601Sjiang wu - Sun Microsystems - Beijing China     va_list ap)
1523*5b504601Sjiang wu - Sun Microsystems - Beijing China {
1524*5b504601Sjiang wu - Sun Microsystems - Beijing China #ifndef __lock_lint
1525*5b504601Sjiang wu - Sun Microsystems - Beijing China 	_NOTE(ARGUNUSED(ap))
1526*5b504601Sjiang wu - Sun Microsystems - Beijing China #endif
1527*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int	rval = DDI_SUCCESS, i;
1528*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t	*sas_addr = NULL;
1529*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint64_t *sas_wwn;
1530*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t	tmp_sas_wwn[SAS_WWN_BYTE_SIZE];
1531*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t *portwidth;
1532*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2SasPortPage0_t sasportpage;
1533*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1534*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
1535*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "mptsas_get_sas_port_page0 "
1536*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "config: IOCStatus=0x%x, IOCLogInfo=0x%x",
1537*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    iocstatus, iocloginfo);
1538*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
1539*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (rval);
1540*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1541*5b504601Sjiang wu - Sun Microsystems - Beijing China 	sas_wwn = va_arg(ap, uint64_t *);
1542*5b504601Sjiang wu - Sun Microsystems - Beijing China 	portwidth = va_arg(ap, uint8_t *);
1543*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1544*5b504601Sjiang wu - Sun Microsystems - Beijing China 	sasportpage = (pMpi2SasPortPage0_t)page_memp;
1545*5b504601Sjiang wu - Sun Microsystems - Beijing China 	sas_addr = (uint8_t *)(&sasportpage->SASAddress);
1546*5b504601Sjiang wu - Sun Microsystems - Beijing China 	for (i = 0; i < SAS_WWN_BYTE_SIZE; i++) {
1547*5b504601Sjiang wu - Sun Microsystems - Beijing China 		tmp_sas_wwn[i] = ddi_get8(accessp, sas_addr + i);
1548*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1549*5b504601Sjiang wu - Sun Microsystems - Beijing China 	bcopy(tmp_sas_wwn, sas_wwn, SAS_WWN_BYTE_SIZE);
1550*5b504601Sjiang wu - Sun Microsystems - Beijing China 	*sas_wwn = LE_64(*sas_wwn);
1551*5b504601Sjiang wu - Sun Microsystems - Beijing China 	*portwidth = ddi_get8(accessp, &sasportpage->PortWidth);
1552*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
1553*5b504601Sjiang wu - Sun Microsystems - Beijing China }
1554*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1555*5b504601Sjiang wu - Sun Microsystems - Beijing China /*
1556*5b504601Sjiang wu - Sun Microsystems - Beijing China  * Request MPI configuration page SAS port page 0 to get initiator SAS address
1557*5b504601Sjiang wu - Sun Microsystems - Beijing China  * and port width.
1558*5b504601Sjiang wu - Sun Microsystems - Beijing China  */
1559*5b504601Sjiang wu - Sun Microsystems - Beijing China int
1560*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_sas_port_page0(mptsas_t *mpt, uint32_t page_address,
1561*5b504601Sjiang wu - Sun Microsystems - Beijing China     uint64_t *sas_wwn, uint8_t *portwidth)
1562*5b504601Sjiang wu - Sun Microsystems - Beijing China {
1563*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int rval = DDI_SUCCESS;
1564*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1565*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ASSERT(mutex_owned(&mpt->m_mutex));
1566*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1567*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1568*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Get the header and config page.  reply contains the reply frame,
1569*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * which holds status info for the request.
1570*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1571*5b504601Sjiang wu - Sun Microsystems - Beijing China 	rval = mptsas_access_config_page(mpt,
1572*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_CONFIG_ACTION_PAGE_READ_CURRENT,
1573*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_CONFIG_EXTPAGETYPE_SAS_PORT, 0, page_address,
1574*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    mptsas_sasportpage_0_cb, sas_wwn, portwidth);
1575*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1576*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
1577*5b504601Sjiang wu - Sun Microsystems - Beijing China }
1578*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1579*5b504601Sjiang wu - Sun Microsystems - Beijing China static int
1580*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_sasiou_page_0_cb(mptsas_t *mpt, caddr_t page_memp,
1581*5b504601Sjiang wu - Sun Microsystems - Beijing China     ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo,
1582*5b504601Sjiang wu - Sun Microsystems - Beijing China     va_list ap)
1583*5b504601Sjiang wu - Sun Microsystems - Beijing China {
1584*5b504601Sjiang wu - Sun Microsystems - Beijing China #ifndef __lock_lint
1585*5b504601Sjiang wu - Sun Microsystems - Beijing China 	_NOTE(ARGUNUSED(ap))
1586*5b504601Sjiang wu - Sun Microsystems - Beijing China #endif
1587*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int rval = DDI_SUCCESS;
1588*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2SasIOUnitPage0_t sasioupage0;
1589*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int i, num_phys;
1590*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t cpdi[8], *retrypage0, *readpage1;
1591*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t port_flags;
1592*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1593*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
1594*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "mptsas_get_sas_io_unit_page0 "
1595*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "config: IOCStatus=0x%x, IOCLogInfo=0x%x",
1596*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    iocstatus, iocloginfo);
1597*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
1598*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (rval);
1599*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1600*5b504601Sjiang wu - Sun Microsystems - Beijing China 	readpage1 = va_arg(ap, uint32_t *);
1601*5b504601Sjiang wu - Sun Microsystems - Beijing China 	retrypage0 = va_arg(ap, uint32_t *);
1602*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1603*5b504601Sjiang wu - Sun Microsystems - Beijing China 	sasioupage0 = (pMpi2SasIOUnitPage0_t)page_memp;
1604*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1605*5b504601Sjiang wu - Sun Microsystems - Beijing China 	num_phys = ddi_get8(accessp, &sasioupage0->NumPhys);
1606*5b504601Sjiang wu - Sun Microsystems - Beijing China 	for (i = 0; i < num_phys; i++) {
1607*5b504601Sjiang wu - Sun Microsystems - Beijing China 		cpdi[i] = ddi_get32(accessp,
1608*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &sasioupage0->PhyData[i].
1609*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    ControllerPhyDeviceInfo);
1610*5b504601Sjiang wu - Sun Microsystems - Beijing China 		port_flags = ddi_get8(accessp,
1611*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &sasioupage0->PhyData[i].PortFlags);
1612*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_phy_info[i].port_num =
1613*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get8(accessp,
1614*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &sasioupage0->PhyData[i].Port);
1615*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_phy_info[i].ctrl_devhdl =
1616*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get16(accessp, &sasioupage0->
1617*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    PhyData[i].ControllerDevHandle);
1618*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_phy_info[i].attached_devhdl =
1619*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get16(accessp, &sasioupage0->
1620*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    PhyData[i].AttachedDevHandle);
1621*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_phy_info[i].phy_device_type = cpdi[i];
1622*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_phy_info[i].port_flags = port_flags;
1623*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1624*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (port_flags & DISCOVERY_IN_PROGRESS) {
1625*5b504601Sjiang wu - Sun Microsystems - Beijing China 			*retrypage0 = *retrypage0 + 1;
1626*5b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
1627*5b504601Sjiang wu - Sun Microsystems - Beijing China 		} else {
1628*5b504601Sjiang wu - Sun Microsystems - Beijing China 			*retrypage0 = 0;
1629*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1630*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (!(port_flags & AUTO_PORT_CONFIGURATION)) {
1631*5b504601Sjiang wu - Sun Microsystems - Beijing China 			/*
1632*5b504601Sjiang wu - Sun Microsystems - Beijing China 			 * some PHY configuration described in
1633*5b504601Sjiang wu - Sun Microsystems - Beijing China 			 * SAS IO Unit Page1
1634*5b504601Sjiang wu - Sun Microsystems - Beijing China 			 */
1635*5b504601Sjiang wu - Sun Microsystems - Beijing China 			*readpage1 = 1;
1636*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1637*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1638*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1639*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
1640*5b504601Sjiang wu - Sun Microsystems - Beijing China }
1641*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1642*5b504601Sjiang wu - Sun Microsystems - Beijing China static int
1643*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_sasiou_page_1_cb(mptsas_t *mpt, caddr_t page_memp,
1644*5b504601Sjiang wu - Sun Microsystems - Beijing China     ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo,
1645*5b504601Sjiang wu - Sun Microsystems - Beijing China     va_list ap)
1646*5b504601Sjiang wu - Sun Microsystems - Beijing China {
1647*5b504601Sjiang wu - Sun Microsystems - Beijing China #ifndef __lock_lint
1648*5b504601Sjiang wu - Sun Microsystems - Beijing China 	_NOTE(ARGUNUSED(ap))
1649*5b504601Sjiang wu - Sun Microsystems - Beijing China #endif
1650*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int rval = DDI_SUCCESS;
1651*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2SasIOUnitPage1_t sasioupage1;
1652*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int i, num_phys;
1653*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t cpdi[8];
1654*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t port_flags;
1655*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1656*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
1657*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "mptsas_get_sas_io_unit_page1 "
1658*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "config: IOCStatus=0x%x, IOCLogInfo=0x%x",
1659*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    iocstatus, iocloginfo);
1660*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
1661*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (rval);
1662*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1663*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1664*5b504601Sjiang wu - Sun Microsystems - Beijing China 	sasioupage1 = (pMpi2SasIOUnitPage1_t)page_memp;
1665*5b504601Sjiang wu - Sun Microsystems - Beijing China 	num_phys = ddi_get8(accessp, &sasioupage1->NumPhys);
1666*5b504601Sjiang wu - Sun Microsystems - Beijing China 	for (i = 0; i < num_phys; i++) {
1667*5b504601Sjiang wu - Sun Microsystems - Beijing China 		cpdi[i] = ddi_get32(accessp, &sasioupage1->PhyData[i].
1668*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    ControllerPhyDeviceInfo);
1669*5b504601Sjiang wu - Sun Microsystems - Beijing China 		port_flags = ddi_get8(accessp,
1670*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &sasioupage1->PhyData[i].PortFlags);
1671*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_phy_info[i].port_num =
1672*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get8(accessp,
1673*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    &sasioupage1->PhyData[i].Port);
1674*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_phy_info[i].port_flags = port_flags;
1675*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mpt->m_phy_info[i].phy_device_type = cpdi[i];
1676*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1677*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1678*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
1679*5b504601Sjiang wu - Sun Microsystems - Beijing China }
1680*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1681*5b504601Sjiang wu - Sun Microsystems - Beijing China /*
1682*5b504601Sjiang wu - Sun Microsystems - Beijing China  * Read IO unit page 0 to get information for each PHY. If needed, Read IO Unit
1683*5b504601Sjiang wu - Sun Microsystems - Beijing China  * page1 to update the PHY information.  This is the message passing method of
1684*5b504601Sjiang wu - Sun Microsystems - Beijing China  * this function which should be called except during initialization.
1685*5b504601Sjiang wu - Sun Microsystems - Beijing China  */
1686*5b504601Sjiang wu - Sun Microsystems - Beijing China int
1687*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_sas_io_unit_page(mptsas_t *mpt)
1688*5b504601Sjiang wu - Sun Microsystems - Beijing China {
1689*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int rval = DDI_SUCCESS, state;
1690*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t readpage1 = 0, retrypage0 = 0;
1691*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1692*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ASSERT(mutex_owned(&mpt->m_mutex));
1693*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1694*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1695*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Now we cycle through the state machine.  Here's what happens:
1696*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * 1. Read IO unit page 0 and set phy information
1697*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * 2. See if Read IO unit page1 is needed because of port configuration
1698*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * 3. Read IO unit page 1 and update phy information.
1699*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1700*5b504601Sjiang wu - Sun Microsystems - Beijing China 	state = IOUC_READ_PAGE0;
1701*5b504601Sjiang wu - Sun Microsystems - Beijing China 	while (state != IOUC_DONE) {
1702*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (state == IOUC_READ_PAGE0) {
1703*5b504601Sjiang wu - Sun Microsystems - Beijing China 			rval = mptsas_access_config_page(mpt,
1704*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_CONFIG_ACTION_PAGE_READ_CURRENT,
1705*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 0, 0,
1706*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    mptsas_sasiou_page_0_cb, &readpage1,
1707*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    &retrypage0);
1708*5b504601Sjiang wu - Sun Microsystems - Beijing China 		} else if (state == IOUC_READ_PAGE1) {
1709*5b504601Sjiang wu - Sun Microsystems - Beijing China 			rval = mptsas_access_config_page(mpt,
1710*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_CONFIG_ACTION_PAGE_READ_CURRENT,
1711*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 1, 0,
1712*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    mptsas_sasiou_page_1_cb);
1713*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1714*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1715*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (rval == DDI_SUCCESS) {
1716*5b504601Sjiang wu - Sun Microsystems - Beijing China 			switch (state) {
1717*5b504601Sjiang wu - Sun Microsystems - Beijing China 			case IOUC_READ_PAGE0:
1718*5b504601Sjiang wu - Sun Microsystems - Beijing China 				/*
1719*5b504601Sjiang wu - Sun Microsystems - Beijing China 				 * retry 30 times if discovery is in process
1720*5b504601Sjiang wu - Sun Microsystems - Beijing China 				 */
1721*5b504601Sjiang wu - Sun Microsystems - Beijing China 				if (retrypage0 && (retrypage0 < 30)) {
1722*5b504601Sjiang wu - Sun Microsystems - Beijing China 					drv_usecwait(1000 * 100);
1723*5b504601Sjiang wu - Sun Microsystems - Beijing China 					state = IOUC_READ_PAGE0;
1724*5b504601Sjiang wu - Sun Microsystems - Beijing China 					break;
1725*5b504601Sjiang wu - Sun Microsystems - Beijing China 				} else if (retrypage0 == 30) {
1726*5b504601Sjiang wu - Sun Microsystems - Beijing China 					mptsas_log(mpt, CE_WARN,
1727*5b504601Sjiang wu - Sun Microsystems - Beijing China 					    "!Discovery in progress, can't "
1728*5b504601Sjiang wu - Sun Microsystems - Beijing China 					    "verify IO unit config, then "
1729*5b504601Sjiang wu - Sun Microsystems - Beijing China 					    "after 30 times retry, give "
1730*5b504601Sjiang wu - Sun Microsystems - Beijing China 					    "up!");
1731*5b504601Sjiang wu - Sun Microsystems - Beijing China 					state = IOUC_DONE;
1732*5b504601Sjiang wu - Sun Microsystems - Beijing China 					rval = DDI_FAILURE;
1733*5b504601Sjiang wu - Sun Microsystems - Beijing China 					break;
1734*5b504601Sjiang wu - Sun Microsystems - Beijing China 				}
1735*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1736*5b504601Sjiang wu - Sun Microsystems - Beijing China 				if (readpage1 == 0) {
1737*5b504601Sjiang wu - Sun Microsystems - Beijing China 					state = IOUC_DONE;
1738*5b504601Sjiang wu - Sun Microsystems - Beijing China 					rval = DDI_SUCCESS;
1739*5b504601Sjiang wu - Sun Microsystems - Beijing China 					break;
1740*5b504601Sjiang wu - Sun Microsystems - Beijing China 				}
1741*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1742*5b504601Sjiang wu - Sun Microsystems - Beijing China 				state = IOUC_READ_PAGE1;
1743*5b504601Sjiang wu - Sun Microsystems - Beijing China 				break;
1744*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1745*5b504601Sjiang wu - Sun Microsystems - Beijing China 			case IOUC_READ_PAGE1:
1746*5b504601Sjiang wu - Sun Microsystems - Beijing China 				state = IOUC_DONE;
1747*5b504601Sjiang wu - Sun Microsystems - Beijing China 				rval = DDI_SUCCESS;
1748*5b504601Sjiang wu - Sun Microsystems - Beijing China 				break;
1749*5b504601Sjiang wu - Sun Microsystems - Beijing China 			}
1750*5b504601Sjiang wu - Sun Microsystems - Beijing China 		} else {
1751*5b504601Sjiang wu - Sun Microsystems - Beijing China 			return (rval);
1752*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1753*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1754*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1755*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
1756*5b504601Sjiang wu - Sun Microsystems - Beijing China }
1757*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1758*5b504601Sjiang wu - Sun Microsystems - Beijing China /*
1759*5b504601Sjiang wu - Sun Microsystems - Beijing China  * Read IO unit page 0 to get information for each PHY. If needed, Read IO Unit
1760*5b504601Sjiang wu - Sun Microsystems - Beijing China  * page1 to update the PHY information.  This is the handshaking version of
1761*5b504601Sjiang wu - Sun Microsystems - Beijing China  * this function, which should be called during initialization only.
1762*5b504601Sjiang wu - Sun Microsystems - Beijing China  */
1763*5b504601Sjiang wu - Sun Microsystems - Beijing China int
1764*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_sas_io_unit_page_hndshk(mptsas_t *mpt)
1765*5b504601Sjiang wu - Sun Microsystems - Beijing China {
1766*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_attr_t		recv_dma_attrs, page_dma_attrs;
1767*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint_t			recv_ncookie, page_ncookie;
1768*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_cookie_t	recv_cookie, page_cookie;
1769*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_handle_t	recv_dma_handle, page_dma_handle;
1770*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_acc_handle_t	recv_accessp, page_accessp;
1771*5b504601Sjiang wu - Sun Microsystems - Beijing China 	size_t			recv_alloc_len, page_alloc_len;
1772*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2ConfigReply_t	configreply;
1773*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2SasIOUnitPage0_t	sasioupage0;
1774*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2SasIOUnitPage1_t	sasioupage1;
1775*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			recv_numbytes;
1776*5b504601Sjiang wu - Sun Microsystems - Beijing China 	caddr_t			recv_memp, page_memp;
1777*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			recv_dmastate = 0;
1778*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			page_dmastate = 0;
1779*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			i, num_phys;
1780*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			page0_size =
1781*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    sizeof (MPI2_CONFIG_PAGE_SASIOUNIT_0) +
1782*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    (sizeof (MPI2_SAS_IO_UNIT0_PHY_DATA) * 7);
1783*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			page1_size =
1784*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    sizeof (MPI2_CONFIG_PAGE_SASIOUNIT_1) +
1785*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    (sizeof (MPI2_SAS_IO_UNIT1_PHY_DATA) * 7);
1786*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		flags_length;
1787*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		cpdi[8], readpage1 = 0, retrypage0 = 0;
1788*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint16_t		iocstatus;
1789*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t			port_flags, page_number, action;
1790*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		reply_size = 256; /* Big enough for any page */
1791*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint_t			state;
1792*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			rval = DDI_FAILURE;
1793*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1794*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1795*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Initialize our "state machine".  This is a bit convoluted,
1796*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * but it keeps us from having to do the ddi allocations numerous
1797*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * times.
1798*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1799*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1800*5b504601Sjiang wu - Sun Microsystems - Beijing China 	NDBG20(("mptsas_get_sas_io_unit_page_hndshk enter"));
1801*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ASSERT(mutex_owned(&mpt->m_mutex));
1802*5b504601Sjiang wu - Sun Microsystems - Beijing China 	state = IOUC_READ_PAGE0;
1803*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1804*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1805*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * dynamically create a customized dma attribute structure
1806*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * that describes mpt's config reply page request structure.
1807*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1808*5b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dma_attrs = mpt->m_msg_dma_attr;
1809*5b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dma_attrs.dma_attr_sgllen = 1;
1810*5b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_REPLY));
1811*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1812*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_alloc_handle(mpt->m_dip, &recv_dma_attrs,
1813*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SLEEP, NULL, &recv_dma_handle) != DDI_SUCCESS) {
1814*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
1815*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1816*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1817*5b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dmastate |= MPTSAS_DMA_HANDLE_ALLOCD;
1818*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1819*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_mem_alloc(recv_dma_handle,
1820*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    (sizeof (MPI2_CONFIG_REPLY)),
1821*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
1822*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &recv_memp, &recv_alloc_len, &recv_accessp) != DDI_SUCCESS) {
1823*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
1824*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1825*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1826*5b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dmastate |= MPTSAS_DMA_MEMORY_ALLOCD;
1827*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1828*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_addr_bind_handle(recv_dma_handle, NULL, recv_memp,
1829*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    recv_alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
1830*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    NULL, &recv_cookie, &recv_ncookie) != DDI_DMA_MAPPED) {
1831*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
1832*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1833*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1834*5b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dmastate |= MPTSAS_DMA_HANDLE_BOUND;
1835*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1836*5b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dma_attrs = mpt->m_msg_dma_attr;
1837*5b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dma_attrs.dma_attr_sgllen = 1;
1838*5b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dma_attrs.dma_attr_granular = reply_size;
1839*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1840*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_alloc_handle(mpt->m_dip, &page_dma_attrs,
1841*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SLEEP, NULL, &page_dma_handle) != DDI_SUCCESS) {
1842*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
1843*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1844*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1845*5b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dmastate |= MPTSAS_DMA_HANDLE_ALLOCD;
1846*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1847*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1848*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Page 0 size is larger, so just use that for both.
1849*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1850*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1851*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_mem_alloc(page_dma_handle, reply_size,
1852*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
1853*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &page_memp, &page_alloc_len, &page_accessp) != DDI_SUCCESS) {
1854*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
1855*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1856*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1857*5b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dmastate |= MPTSAS_DMA_MEMORY_ALLOCD;
1858*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1859*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_addr_bind_handle(page_dma_handle, NULL, page_memp,
1860*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    page_alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
1861*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    NULL, &page_cookie, &page_ncookie) != DDI_DMA_MAPPED) {
1862*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
1863*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
1864*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1865*5b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dmastate |= MPTSAS_DMA_HANDLE_BOUND;
1866*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1867*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
1868*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Now we cycle through the state machine.  Here's what happens:
1869*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * 1. Read IO unit page 0 and set phy information
1870*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * 2. See if Read IO unit page1 is needed because of port configuration
1871*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * 3. Read IO unit page 1 and update phy information.
1872*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
1873*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1874*5b504601Sjiang wu - Sun Microsystems - Beijing China 	sasioupage0 = (pMpi2SasIOUnitPage0_t)page_memp;
1875*5b504601Sjiang wu - Sun Microsystems - Beijing China 	sasioupage1 = (pMpi2SasIOUnitPage1_t)page_memp;
1876*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1877*5b504601Sjiang wu - Sun Microsystems - Beijing China 	while (state != IOUC_DONE) {
1878*5b504601Sjiang wu - Sun Microsystems - Beijing China 		switch (state) {
1879*5b504601Sjiang wu - Sun Microsystems - Beijing China 		case IOUC_READ_PAGE0:
1880*5b504601Sjiang wu - Sun Microsystems - Beijing China 			page_number = 0;
1881*5b504601Sjiang wu - Sun Microsystems - Beijing China 			action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1882*5b504601Sjiang wu - Sun Microsystems - Beijing China 			flags_length = (uint32_t)page0_size;
1883*5b504601Sjiang wu - Sun Microsystems - Beijing China 			flags_length |= ((uint32_t)(
1884*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_LAST_ELEMENT |
1885*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_END_OF_BUFFER |
1886*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1887*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
1888*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_32_BIT_ADDRESSING |
1889*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_IOC_TO_HOST |
1890*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_END_OF_LIST) <<
1891*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SHIFT);
1892*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1893*5b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
1894*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1895*5b504601Sjiang wu - Sun Microsystems - Beijing China 		case IOUC_READ_PAGE1:
1896*5b504601Sjiang wu - Sun Microsystems - Beijing China 			page_number = 1;
1897*5b504601Sjiang wu - Sun Microsystems - Beijing China 			action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1898*5b504601Sjiang wu - Sun Microsystems - Beijing China 			flags_length = (uint32_t)page1_size;
1899*5b504601Sjiang wu - Sun Microsystems - Beijing China 			flags_length |= ((uint32_t)(
1900*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_LAST_ELEMENT |
1901*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_END_OF_BUFFER |
1902*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1903*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
1904*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_32_BIT_ADDRESSING |
1905*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_IOC_TO_HOST |
1906*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_END_OF_LIST) <<
1907*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SHIFT);
1908*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1909*5b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
1910*5b504601Sjiang wu - Sun Microsystems - Beijing China 		default:
1911*5b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
1912*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1913*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1914*5b504601Sjiang wu - Sun Microsystems - Beijing China 		bzero(recv_memp, sizeof (MPI2_CONFIG_REPLY));
1915*5b504601Sjiang wu - Sun Microsystems - Beijing China 		configreply = (pMpi2ConfigReply_t)recv_memp;
1916*5b504601Sjiang wu - Sun Microsystems - Beijing China 		recv_numbytes = sizeof (MPI2_CONFIG_REPLY);
1917*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1918*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_send_extended_config_request_msg(mpt,
1919*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_CONFIG_ACTION_PAGE_HEADER,
1920*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT,
1921*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    0, page_number, 0, 0, 0, 0)) {
1922*5b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
1923*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1924*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1925*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes,
1926*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    recv_accessp)) {
1927*5b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
1928*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1929*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1930*5b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = ddi_get16(recv_accessp, &configreply->IOCStatus);
1931*5b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = MPTSAS_IOCSTATUS(iocstatus);
1932*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1933*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
1934*5b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_log(mpt, CE_WARN,
1935*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    "mptsas_get_sas_io_unit_page_hndshk: read page "
1936*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    "header iocstatus = 0x%x", iocstatus);
1937*5b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
1938*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1939*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1940*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (action != MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {
1941*5b504601Sjiang wu - Sun Microsystems - Beijing China 			bzero(page_memp, reply_size);
1942*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1943*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1944*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_send_extended_config_request_msg(mpt, action,
1945*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 0, page_number,
1946*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get8(recv_accessp, &configreply->Header.PageVersion),
1947*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get16(recv_accessp, &configreply->ExtPageLength),
1948*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    flags_length, page_cookie.dmac_address)) {
1949*5b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
1950*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1951*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1952*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes,
1953*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    recv_accessp)) {
1954*5b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
1955*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1956*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1957*5b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = ddi_get16(recv_accessp, &configreply->IOCStatus);
1958*5b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = MPTSAS_IOCSTATUS(iocstatus);
1959*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1960*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
1961*5b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_log(mpt, CE_WARN,
1962*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    "mptsas_get_sas_io_unit_page_hndshk: IO unit "
1963*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    "config failed for action %d, iocstatus = 0x%x",
1964*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    action, iocstatus);
1965*5b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
1966*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
1967*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1968*5b504601Sjiang wu - Sun Microsystems - Beijing China 		switch (state) {
1969*5b504601Sjiang wu - Sun Microsystems - Beijing China 		case IOUC_READ_PAGE0:
1970*5b504601Sjiang wu - Sun Microsystems - Beijing China 			if ((ddi_dma_sync(page_dma_handle, 0, 0,
1971*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    DDI_DMA_SYNC_FORCPU)) != DDI_SUCCESS) {
1972*5b504601Sjiang wu - Sun Microsystems - Beijing China 				goto cleanup;
1973*5b504601Sjiang wu - Sun Microsystems - Beijing China 			}
1974*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1975*5b504601Sjiang wu - Sun Microsystems - Beijing China 			num_phys = ddi_get8(page_accessp,
1976*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    &sasioupage0->NumPhys);
1977*5b504601Sjiang wu - Sun Microsystems - Beijing China 			for (i = 0; i < num_phys; i++) {
1978*5b504601Sjiang wu - Sun Microsystems - Beijing China 				cpdi[i] = ddi_get32(page_accessp,
1979*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    &sasioupage0->PhyData[i].
1980*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    ControllerPhyDeviceInfo);
1981*5b504601Sjiang wu - Sun Microsystems - Beijing China 				port_flags = ddi_get8(page_accessp,
1982*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    &sasioupage0->PhyData[i].PortFlags);
1983*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1984*5b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_phy_info[i].port_num =
1985*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    ddi_get8(page_accessp,
1986*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    &sasioupage0->PhyData[i].Port);
1987*5b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_phy_info[i].ctrl_devhdl =
1988*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    ddi_get16(page_accessp, &sasioupage0->
1989*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    PhyData[i].ControllerDevHandle);
1990*5b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_phy_info[i].attached_devhdl =
1991*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    ddi_get16(page_accessp, &sasioupage0->
1992*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    PhyData[i].AttachedDevHandle);
1993*5b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_phy_info[i].phy_device_type = cpdi[i];
1994*5b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_phy_info[i].port_flags = port_flags;
1995*5b504601Sjiang wu - Sun Microsystems - Beijing China 
1996*5b504601Sjiang wu - Sun Microsystems - Beijing China 				if (port_flags & DISCOVERY_IN_PROGRESS) {
1997*5b504601Sjiang wu - Sun Microsystems - Beijing China 					retrypage0++;
1998*5b504601Sjiang wu - Sun Microsystems - Beijing China 					NDBG20(("Discovery in progress, can't "
1999*5b504601Sjiang wu - Sun Microsystems - Beijing China 					    "verify IO unit config, then NO.%d"
2000*5b504601Sjiang wu - Sun Microsystems - Beijing China 					    " times retry", retrypage0));
2001*5b504601Sjiang wu - Sun Microsystems - Beijing China 					break;
2002*5b504601Sjiang wu - Sun Microsystems - Beijing China 				} else {
2003*5b504601Sjiang wu - Sun Microsystems - Beijing China 					retrypage0 = 0;
2004*5b504601Sjiang wu - Sun Microsystems - Beijing China 				}
2005*5b504601Sjiang wu - Sun Microsystems - Beijing China 				if (!(port_flags & AUTO_PORT_CONFIGURATION)) {
2006*5b504601Sjiang wu - Sun Microsystems - Beijing China 					/*
2007*5b504601Sjiang wu - Sun Microsystems - Beijing China 					 * some PHY configuration described in
2008*5b504601Sjiang wu - Sun Microsystems - Beijing China 					 * SAS IO Unit Page1
2009*5b504601Sjiang wu - Sun Microsystems - Beijing China 					 */
2010*5b504601Sjiang wu - Sun Microsystems - Beijing China 					readpage1 = 1;
2011*5b504601Sjiang wu - Sun Microsystems - Beijing China 				}
2012*5b504601Sjiang wu - Sun Microsystems - Beijing China 			}
2013*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2014*5b504601Sjiang wu - Sun Microsystems - Beijing China 			/*
2015*5b504601Sjiang wu - Sun Microsystems - Beijing China 			 * retry 30 times if discovery is in process
2016*5b504601Sjiang wu - Sun Microsystems - Beijing China 			 */
2017*5b504601Sjiang wu - Sun Microsystems - Beijing China 			if (retrypage0 && (retrypage0 < 30)) {
2018*5b504601Sjiang wu - Sun Microsystems - Beijing China 				drv_usecwait(1000 * 100);
2019*5b504601Sjiang wu - Sun Microsystems - Beijing China 				state = IOUC_READ_PAGE0;
2020*5b504601Sjiang wu - Sun Microsystems - Beijing China 				break;
2021*5b504601Sjiang wu - Sun Microsystems - Beijing China 			} else if (retrypage0 == 30) {
2022*5b504601Sjiang wu - Sun Microsystems - Beijing China 				mptsas_log(mpt, CE_WARN,
2023*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    "!Discovery in progress, can't "
2024*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    "verify IO unit config, then after"
2025*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    " 30 times retry, give up!");
2026*5b504601Sjiang wu - Sun Microsystems - Beijing China 				state = IOUC_DONE;
2027*5b504601Sjiang wu - Sun Microsystems - Beijing China 				rval = DDI_FAILURE;
2028*5b504601Sjiang wu - Sun Microsystems - Beijing China 				break;
2029*5b504601Sjiang wu - Sun Microsystems - Beijing China 			}
2030*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2031*5b504601Sjiang wu - Sun Microsystems - Beijing China 			if (readpage1 == 0) {
2032*5b504601Sjiang wu - Sun Microsystems - Beijing China 				state = IOUC_DONE;
2033*5b504601Sjiang wu - Sun Microsystems - Beijing China 				rval = DDI_SUCCESS;
2034*5b504601Sjiang wu - Sun Microsystems - Beijing China 				break;
2035*5b504601Sjiang wu - Sun Microsystems - Beijing China 			}
2036*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2037*5b504601Sjiang wu - Sun Microsystems - Beijing China 			state = IOUC_READ_PAGE1;
2038*5b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
2039*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2040*5b504601Sjiang wu - Sun Microsystems - Beijing China 		case IOUC_READ_PAGE1:
2041*5b504601Sjiang wu - Sun Microsystems - Beijing China 			if ((ddi_dma_sync(page_dma_handle, 0, 0,
2042*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    DDI_DMA_SYNC_FORCPU)) != DDI_SUCCESS) {
2043*5b504601Sjiang wu - Sun Microsystems - Beijing China 				goto cleanup;
2044*5b504601Sjiang wu - Sun Microsystems - Beijing China 			}
2045*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2046*5b504601Sjiang wu - Sun Microsystems - Beijing China 			num_phys = ddi_get8(page_accessp,
2047*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    &sasioupage1->NumPhys);
2048*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2049*5b504601Sjiang wu - Sun Microsystems - Beijing China 			for (i = 0; i < num_phys; i++) {
2050*5b504601Sjiang wu - Sun Microsystems - Beijing China 				cpdi[i] = ddi_get32(page_accessp,
2051*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    &sasioupage1->PhyData[i].
2052*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    ControllerPhyDeviceInfo);
2053*5b504601Sjiang wu - Sun Microsystems - Beijing China 				port_flags = ddi_get8(page_accessp,
2054*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    &sasioupage1->PhyData[i].PortFlags);
2055*5b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_phy_info[i].port_num =
2056*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    ddi_get8(page_accessp,
2057*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    &sasioupage1->PhyData[i].Port);
2058*5b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_phy_info[i].port_flags = port_flags;
2059*5b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_phy_info[i].phy_device_type = cpdi[i];
2060*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2061*5b504601Sjiang wu - Sun Microsystems - Beijing China 			}
2062*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2063*5b504601Sjiang wu - Sun Microsystems - Beijing China 			state = IOUC_DONE;
2064*5b504601Sjiang wu - Sun Microsystems - Beijing China 			rval = DDI_SUCCESS;
2065*5b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
2066*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
2067*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2068*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((mptsas_check_dma_handle(recv_dma_handle) != DDI_SUCCESS) ||
2069*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    (mptsas_check_dma_handle(page_dma_handle) != DDI_SUCCESS)) {
2070*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
2071*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
2072*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
2073*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2074*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((mptsas_check_acc_handle(recv_accessp) != DDI_SUCCESS) ||
2075*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    (mptsas_check_acc_handle(page_accessp) != DDI_SUCCESS)) {
2076*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
2077*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
2078*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
2079*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2080*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2081*5b504601Sjiang wu - Sun Microsystems - Beijing China cleanup:
2082*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (recv_dmastate & MPTSAS_DMA_HANDLE_BOUND)
2083*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_unbind_handle(recv_dma_handle);
2084*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (page_dmastate & MPTSAS_DMA_HANDLE_BOUND)
2085*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_unbind_handle(page_dma_handle);
2086*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (recv_dmastate & MPTSAS_DMA_MEMORY_ALLOCD)
2087*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_mem_free(&recv_accessp);
2088*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (page_dmastate & MPTSAS_DMA_MEMORY_ALLOCD)
2089*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_mem_free(&page_accessp);
2090*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (recv_dmastate & MPTSAS_DMA_HANDLE_ALLOCD)
2091*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&recv_dma_handle);
2092*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (page_dmastate & MPTSAS_DMA_HANDLE_ALLOCD)
2093*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&page_dma_handle);
2094*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2095*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (rval != DDI_SUCCESS) {
2096*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
2097*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
2098*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2099*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
2100*5b504601Sjiang wu - Sun Microsystems - Beijing China }
2101*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2102*5b504601Sjiang wu - Sun Microsystems - Beijing China /*
2103*5b504601Sjiang wu - Sun Microsystems - Beijing China  * Check if the PHYs are currently in target mode. If they are not, we don't
2104*5b504601Sjiang wu - Sun Microsystems - Beijing China  * need to change anything.  Otherwise, we need to modify the appropriate bits
2105*5b504601Sjiang wu - Sun Microsystems - Beijing China  * and write them to IO unit page 1.  Once that is done, an IO unit reset is
2106*5b504601Sjiang wu - Sun Microsystems - Beijing China  * necessary to begin operating in initiator mode.  Since this function is only
2107*5b504601Sjiang wu - Sun Microsystems - Beijing China  * called during the initialization process, use handshaking.
2108*5b504601Sjiang wu - Sun Microsystems - Beijing China  */
2109*5b504601Sjiang wu - Sun Microsystems - Beijing China int
2110*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_set_initiator_mode(mptsas_t *mpt)
2111*5b504601Sjiang wu - Sun Microsystems - Beijing China {
2112*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_attr_t		recv_dma_attrs, page_dma_attrs;
2113*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint_t			recv_ncookie, page_ncookie;
2114*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_cookie_t	recv_cookie, page_cookie;
2115*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_handle_t	recv_dma_handle, page_dma_handle;
2116*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_acc_handle_t	recv_accessp, page_accessp;
2117*5b504601Sjiang wu - Sun Microsystems - Beijing China 	size_t			recv_alloc_len, page_alloc_len;
2118*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2ConfigReply_t	configreply;
2119*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2SasIOUnitPage1_t	sasioupage1;
2120*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			recv_numbytes;
2121*5b504601Sjiang wu - Sun Microsystems - Beijing China 	caddr_t			recv_memp, page_memp;
2122*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			recv_dmastate = 0;
2123*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			page_dmastate = 0;
2124*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			i;
2125*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			page1_size =
2126*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    sizeof (MPI2_CONFIG_PAGE_SASIOUNIT_1) +
2127*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    (sizeof (MPI2_SAS_IO_UNIT0_PHY_DATA) * 7);
2128*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		flags_length;
2129*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		cpdi[8], reprogram = 0;
2130*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint16_t		iocstatus;
2131*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint8_t			port_flags, page_number, action;
2132*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t		reply_size = 256; /* Big enough for any page */
2133*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint_t			state;
2134*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int			rval = DDI_FAILURE;
2135*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2136*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ASSERT(mutex_owned(&mpt->m_mutex));
2137*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
2138*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * get each PHY informations from SAS IO Unit Pages.  Use handshakiing
2139*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * to get SAS IO Unit Page information since this is during init.
2140*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
2141*5b504601Sjiang wu - Sun Microsystems - Beijing China 	rval = mptsas_get_sas_io_unit_page_hndshk(mpt);
2142*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (rval != DDI_SUCCESS)
2143*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (rval);
2144*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2145*5b504601Sjiang wu - Sun Microsystems - Beijing China 	for (i = 0; i < mpt->m_num_phys; i++) {
2146*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mpt->m_phy_info[i].phy_device_type &
2147*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_SAS_DEVICE_INFO_SSP_TARGET) {
2148*5b504601Sjiang wu - Sun Microsystems - Beijing China 			reprogram = 1;
2149*5b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
2150*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
2151*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2152*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (reprogram == 0)
2153*5b504601Sjiang wu - Sun Microsystems - Beijing China 		return (DDI_SUCCESS);
2154*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2155*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
2156*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Initialize our "state machine".  This is a bit convoluted,
2157*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * but it keeps us from having to do the ddi allocations numerous
2158*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * times.
2159*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
2160*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2161*5b504601Sjiang wu - Sun Microsystems - Beijing China 	state = IOUC_READ_PAGE1;
2162*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2163*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
2164*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * dynamically create a customized dma attribute structure
2165*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * that describes mpt's config reply page request structure.
2166*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
2167*5b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dma_attrs = mpt->m_msg_dma_attr;
2168*5b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dma_attrs.dma_attr_sgllen = 1;
2169*5b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_REPLY));
2170*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2171*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_alloc_handle(mpt->m_dip, &recv_dma_attrs,
2172*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SLEEP, NULL, &recv_dma_handle) != DDI_SUCCESS) {
2173*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
2174*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2175*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2176*5b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dmastate |= MPTSAS_DMA_HANDLE_ALLOCD;
2177*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2178*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_mem_alloc(recv_dma_handle,
2179*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    (sizeof (MPI2_CONFIG_REPLY)),
2180*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
2181*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &recv_memp, &recv_alloc_len, &recv_accessp) != DDI_SUCCESS) {
2182*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
2183*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2184*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2185*5b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dmastate |= MPTSAS_DMA_MEMORY_ALLOCD;
2186*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2187*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_addr_bind_handle(recv_dma_handle, NULL, recv_memp,
2188*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    recv_alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
2189*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    NULL, &recv_cookie, &recv_ncookie) != DDI_DMA_MAPPED) {
2190*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
2191*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2192*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2193*5b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dmastate |= MPTSAS_DMA_HANDLE_BOUND;
2194*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2195*5b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dma_attrs = mpt->m_msg_dma_attr;
2196*5b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dma_attrs.dma_attr_sgllen = 1;
2197*5b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dma_attrs.dma_attr_granular = reply_size;
2198*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2199*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_alloc_handle(mpt->m_dip, &page_dma_attrs,
2200*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SLEEP, NULL, &page_dma_handle) != DDI_SUCCESS) {
2201*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
2202*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2203*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2204*5b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dmastate |= MPTSAS_DMA_HANDLE_ALLOCD;
2205*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2206*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_mem_alloc(page_dma_handle, reply_size,
2207*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
2208*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &page_memp, &page_alloc_len, &page_accessp) != DDI_SUCCESS) {
2209*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
2210*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2211*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2212*5b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dmastate |= MPTSAS_DMA_MEMORY_ALLOCD;
2213*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2214*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_addr_bind_handle(page_dma_handle, NULL, page_memp,
2215*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    page_alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
2216*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    NULL, &page_cookie, &page_ncookie) != DDI_DMA_MAPPED) {
2217*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto cleanup;
2218*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2219*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2220*5b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dmastate |= MPTSAS_DMA_HANDLE_BOUND;
2221*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2222*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
2223*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Now we cycle through the state machine.  Here's what happens:
2224*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * 1. Read IO unit page 1.
2225*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * 2. Change the appropriate bits
2226*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * 3. Write the updated settings to IO unit page 1.
2227*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * 4. Reset the IO unit.
2228*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
2229*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2230*5b504601Sjiang wu - Sun Microsystems - Beijing China 	sasioupage1 = (pMpi2SasIOUnitPage1_t)page_memp;
2231*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2232*5b504601Sjiang wu - Sun Microsystems - Beijing China 	while (state != IOUC_DONE) {
2233*5b504601Sjiang wu - Sun Microsystems - Beijing China 		switch (state) {
2234*5b504601Sjiang wu - Sun Microsystems - Beijing China 		case IOUC_READ_PAGE1:
2235*5b504601Sjiang wu - Sun Microsystems - Beijing China 			page_number = 1;
2236*5b504601Sjiang wu - Sun Microsystems - Beijing China 			action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
2237*5b504601Sjiang wu - Sun Microsystems - Beijing China 			flags_length = (uint32_t)page1_size;
2238*5b504601Sjiang wu - Sun Microsystems - Beijing China 			flags_length |= ((uint32_t)(
2239*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_LAST_ELEMENT |
2240*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_END_OF_BUFFER |
2241*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
2242*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
2243*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_32_BIT_ADDRESSING |
2244*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_IOC_TO_HOST |
2245*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_END_OF_LIST) <<
2246*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SHIFT);
2247*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2248*5b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
2249*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2250*5b504601Sjiang wu - Sun Microsystems - Beijing China 		case IOUC_WRITE_PAGE1:
2251*5b504601Sjiang wu - Sun Microsystems - Beijing China 			page_number = 1;
2252*5b504601Sjiang wu - Sun Microsystems - Beijing China 			action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
2253*5b504601Sjiang wu - Sun Microsystems - Beijing China 			flags_length = (uint32_t)page1_size;
2254*5b504601Sjiang wu - Sun Microsystems - Beijing China 			flags_length |= ((uint32_t)(
2255*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_LAST_ELEMENT |
2256*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_END_OF_BUFFER |
2257*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
2258*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
2259*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_32_BIT_ADDRESSING |
2260*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_HOST_TO_IOC |
2261*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_END_OF_LIST) <<
2262*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SGE_FLAGS_SHIFT);
2263*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2264*5b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
2265*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
2266*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2267*5b504601Sjiang wu - Sun Microsystems - Beijing China 		bzero(recv_memp, sizeof (MPI2_CONFIG_REPLY));
2268*5b504601Sjiang wu - Sun Microsystems - Beijing China 		configreply = (pMpi2ConfigReply_t)recv_memp;
2269*5b504601Sjiang wu - Sun Microsystems - Beijing China 		recv_numbytes = sizeof (MPI2_CONFIG_REPLY);
2270*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2271*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_send_extended_config_request_msg(mpt,
2272*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_CONFIG_ACTION_PAGE_HEADER,
2273*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT,
2274*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    0, page_number, 0, 0, 0, 0)) {
2275*5b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
2276*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
2277*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2278*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes,
2279*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    recv_accessp)) {
2280*5b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
2281*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
2282*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2283*5b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = ddi_get16(recv_accessp, &configreply->IOCStatus);
2284*5b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = MPTSAS_IOCSTATUS(iocstatus);
2285*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2286*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
2287*5b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_log(mpt, CE_WARN,
2288*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    "mptsas_set_initiator_mode: read page hdr iocstatus"
2289*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    ": 0x%x", iocstatus);
2290*5b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
2291*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
2292*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2293*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (action != MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {
2294*5b504601Sjiang wu - Sun Microsystems - Beijing China 			bzero(page_memp, reply_size);
2295*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
2296*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2297*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_send_extended_config_request_msg(mpt, action,
2298*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 0, page_number,
2299*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get8(recv_accessp, &configreply->Header.PageVersion),
2300*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get16(recv_accessp, &configreply->ExtPageLength),
2301*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    flags_length, page_cookie.dmac_address)) {
2302*5b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
2303*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
2304*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2305*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes,
2306*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    recv_accessp)) {
2307*5b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
2308*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
2309*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2310*5b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = ddi_get16(recv_accessp, &configreply->IOCStatus);
2311*5b504601Sjiang wu - Sun Microsystems - Beijing China 		iocstatus = MPTSAS_IOCSTATUS(iocstatus);
2312*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2313*5b504601Sjiang wu - Sun Microsystems - Beijing China 		if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
2314*5b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_log(mpt, CE_WARN,
2315*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    "mptsas_set_initiator_mode: IO unit config failed "
2316*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    "for action %d, iocstatus = 0x%x", action,
2317*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    iocstatus);
2318*5b504601Sjiang wu - Sun Microsystems - Beijing China 			goto cleanup;
2319*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
2320*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2321*5b504601Sjiang wu - Sun Microsystems - Beijing China 		switch (state) {
2322*5b504601Sjiang wu - Sun Microsystems - Beijing China 		case IOUC_READ_PAGE1:
2323*5b504601Sjiang wu - Sun Microsystems - Beijing China 			if ((ddi_dma_sync(page_dma_handle, 0, 0,
2324*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    DDI_DMA_SYNC_FORCPU)) != DDI_SUCCESS) {
2325*5b504601Sjiang wu - Sun Microsystems - Beijing China 				goto cleanup;
2326*5b504601Sjiang wu - Sun Microsystems - Beijing China 			}
2327*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2328*5b504601Sjiang wu - Sun Microsystems - Beijing China 			/*
2329*5b504601Sjiang wu - Sun Microsystems - Beijing China 			 * All the PHYs should have the same settings, so we
2330*5b504601Sjiang wu - Sun Microsystems - Beijing China 			 * really only need to read 1 and use its config for
2331*5b504601Sjiang wu - Sun Microsystems - Beijing China 			 * every PHY.
2332*5b504601Sjiang wu - Sun Microsystems - Beijing China 			 */
2333*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2334*5b504601Sjiang wu - Sun Microsystems - Beijing China 			cpdi[0] = ddi_get32(page_accessp,
2335*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    &sasioupage1->PhyData[0].ControllerPhyDeviceInfo);
2336*5b504601Sjiang wu - Sun Microsystems - Beijing China 			port_flags = ddi_get8(page_accessp,
2337*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    &sasioupage1->PhyData[0].PortFlags);
2338*5b504601Sjiang wu - Sun Microsystems - Beijing China 			port_flags |=
2339*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SASIOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG;
2340*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2341*5b504601Sjiang wu - Sun Microsystems - Beijing China 			/*
2342*5b504601Sjiang wu - Sun Microsystems - Beijing China 			 * Write the configuration to SAS I/O unit page 1
2343*5b504601Sjiang wu - Sun Microsystems - Beijing China 			 */
2344*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2345*5b504601Sjiang wu - Sun Microsystems - Beijing China 			mptsas_log(mpt, CE_NOTE,
2346*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    "?IO unit in target mode, changing to initiator");
2347*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2348*5b504601Sjiang wu - Sun Microsystems - Beijing China 			/*
2349*5b504601Sjiang wu - Sun Microsystems - Beijing China 			 * Modify the PHY settings for initiator mode
2350*5b504601Sjiang wu - Sun Microsystems - Beijing China 			 */
2351*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2352*5b504601Sjiang wu - Sun Microsystems - Beijing China 			cpdi[0] &= ~MPI2_SAS_DEVICE_INFO_SSP_TARGET;
2353*5b504601Sjiang wu - Sun Microsystems - Beijing China 			cpdi[0] |= (MPI2_SAS_DEVICE_INFO_SSP_INITIATOR |
2354*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SAS_DEVICE_INFO_STP_INITIATOR |
2355*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    MPI2_SAS_DEVICE_INFO_SMP_INITIATOR);
2356*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2357*5b504601Sjiang wu - Sun Microsystems - Beijing China 			for (i = 0; i < mpt->m_num_phys; i++) {
2358*5b504601Sjiang wu - Sun Microsystems - Beijing China 				ddi_put32(page_accessp,
2359*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    &sasioupage1->PhyData[i].
2360*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    ControllerPhyDeviceInfo, cpdi[0]);
2361*5b504601Sjiang wu - Sun Microsystems - Beijing China 				ddi_put8(page_accessp,
2362*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    &sasioupage1->PhyData[i].
2363*5b504601Sjiang wu - Sun Microsystems - Beijing China 				    PortFlags, port_flags);
2364*5b504601Sjiang wu - Sun Microsystems - Beijing China 				/*
2365*5b504601Sjiang wu - Sun Microsystems - Beijing China 				 * update phy information
2366*5b504601Sjiang wu - Sun Microsystems - Beijing China 				 */
2367*5b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_phy_info[i].phy_device_type = cpdi[0];
2368*5b504601Sjiang wu - Sun Microsystems - Beijing China 				mpt->m_phy_info[i].port_flags = port_flags;
2369*5b504601Sjiang wu - Sun Microsystems - Beijing China 			}
2370*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2371*5b504601Sjiang wu - Sun Microsystems - Beijing China 			if ((ddi_dma_sync(page_dma_handle, 0, 0,
2372*5b504601Sjiang wu - Sun Microsystems - Beijing China 			    DDI_DMA_SYNC_FORDEV)) != DDI_SUCCESS) {
2373*5b504601Sjiang wu - Sun Microsystems - Beijing China 				goto cleanup;
2374*5b504601Sjiang wu - Sun Microsystems - Beijing China 			}
2375*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2376*5b504601Sjiang wu - Sun Microsystems - Beijing China 			state = IOUC_WRITE_PAGE1;
2377*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2378*5b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
2379*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2380*5b504601Sjiang wu - Sun Microsystems - Beijing China 		case IOUC_WRITE_PAGE1:
2381*5b504601Sjiang wu - Sun Microsystems - Beijing China 			/*
2382*5b504601Sjiang wu - Sun Microsystems - Beijing China 			 * If we're here, we wrote IO unit page 1 succesfully.
2383*5b504601Sjiang wu - Sun Microsystems - Beijing China 			 */
2384*5b504601Sjiang wu - Sun Microsystems - Beijing China 			state = IOUC_DONE;
2385*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2386*5b504601Sjiang wu - Sun Microsystems - Beijing China 			rval = DDI_SUCCESS;
2387*5b504601Sjiang wu - Sun Microsystems - Beijing China 			break;
2388*5b504601Sjiang wu - Sun Microsystems - Beijing China 		}
2389*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2390*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2391*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
2392*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * We need to do a Message Unit Reset in order to activate the changes.
2393*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
2394*5b504601Sjiang wu - Sun Microsystems - Beijing China 	mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET;
2395*5b504601Sjiang wu - Sun Microsystems - Beijing China 	rval = mptsas_init_chip(mpt, FALSE);
2396*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2397*5b504601Sjiang wu - Sun Microsystems - Beijing China cleanup:
2398*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (recv_dmastate & MPTSAS_DMA_HANDLE_BOUND)
2399*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_unbind_handle(recv_dma_handle);
2400*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (page_dmastate & MPTSAS_DMA_HANDLE_BOUND)
2401*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_unbind_handle(page_dma_handle);
2402*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (recv_dmastate & MPTSAS_DMA_MEMORY_ALLOCD)
2403*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_mem_free(&recv_accessp);
2404*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (page_dmastate & MPTSAS_DMA_MEMORY_ALLOCD)
2405*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_mem_free(&page_accessp);
2406*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (recv_dmastate & MPTSAS_DMA_HANDLE_ALLOCD)
2407*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&recv_dma_handle);
2408*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (page_dmastate & MPTSAS_DMA_HANDLE_ALLOCD)
2409*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&page_dma_handle);
2410*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2411*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
2412*5b504601Sjiang wu - Sun Microsystems - Beijing China }
2413*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2414*5b504601Sjiang wu - Sun Microsystems - Beijing China /*
2415*5b504601Sjiang wu - Sun Microsystems - Beijing China  * mptsas_get_manufacture_page5
2416*5b504601Sjiang wu - Sun Microsystems - Beijing China  *
2417*5b504601Sjiang wu - Sun Microsystems - Beijing China  * This function will retrieve the base WWID from the adapter.  Since this
2418*5b504601Sjiang wu - Sun Microsystems - Beijing China  * function is only called during the initialization process, use handshaking.
2419*5b504601Sjiang wu - Sun Microsystems - Beijing China  */
2420*5b504601Sjiang wu - Sun Microsystems - Beijing China int
2421*5b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_manufacture_page5(mptsas_t *mpt)
2422*5b504601Sjiang wu - Sun Microsystems - Beijing China {
2423*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_attr_t			recv_dma_attrs, page_dma_attrs;
2424*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_cookie_t		recv_cookie, page_cookie;
2425*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_dma_handle_t		recv_dma_handle, page_dma_handle;
2426*5b504601Sjiang wu - Sun Microsystems - Beijing China 	ddi_acc_handle_t		recv_accessp, page_accessp;
2427*5b504601Sjiang wu - Sun Microsystems - Beijing China 	size_t				recv_alloc_len, page_alloc_len;
2428*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2ConfigReply_t		configreply;
2429*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint_t				recv_ncookie, page_ncookie;
2430*5b504601Sjiang wu - Sun Microsystems - Beijing China 	caddr_t				recv_memp, page_memp;
2431*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int				recv_numbytes;
2432*5b504601Sjiang wu - Sun Microsystems - Beijing China 	pMpi2ManufacturingPage5_t	m5;
2433*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int				recv_dmastate = 0;
2434*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int				page_dmastate = 0;
2435*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint32_t			flagslength;
2436*5b504601Sjiang wu - Sun Microsystems - Beijing China 	int				rval = DDI_SUCCESS;
2437*5b504601Sjiang wu - Sun Microsystems - Beijing China 	uint_t				iocstatus;
2438*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2439*5b504601Sjiang wu - Sun Microsystems - Beijing China 	MPTSAS_DISABLE_INTR(mpt);
2440*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2441*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_send_config_request_msg(mpt, MPI2_CONFIG_ACTION_PAGE_HEADER,
2442*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_CONFIG_PAGETYPE_MANUFACTURING, 0, 5, 0, 0, 0, 0)) {
2443*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
2444*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
2445*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2446*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2447*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
2448*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * dynamically create a customized dma attribute structure
2449*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * that describes the MPT's config reply page request structure.
2450*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
2451*5b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dma_attrs = mpt->m_msg_dma_attr;
2452*5b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dma_attrs.dma_attr_sgllen = 1;
2453*5b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_REPLY));
2454*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2455*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_alloc_handle(mpt->m_dip, &recv_dma_attrs,
2456*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SLEEP, NULL, &recv_dma_handle) != DDI_SUCCESS) {
2457*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN,
2458*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "(unable to allocate dma handle.");
2459*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
2460*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
2461*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2462*5b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dmastate |= MPTSAS_DMA_HANDLE_ALLOCD;
2463*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2464*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_mem_alloc(recv_dma_handle,
2465*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    (sizeof (MPI2_CONFIG_REPLY)),
2466*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
2467*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &recv_memp, &recv_alloc_len, &recv_accessp) != DDI_SUCCESS) {
2468*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN,
2469*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "unable to allocate config_reply structure.");
2470*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
2471*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
2472*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2473*5b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dmastate |= MPTSAS_DMA_MEMORY_ALLOCD;
2474*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2475*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_addr_bind_handle(recv_dma_handle, NULL, recv_memp,
2476*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    recv_alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
2477*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    NULL, &recv_cookie, &recv_ncookie) != DDI_DMA_MAPPED) {
2478*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "unable to bind DMA resources.");
2479*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
2480*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
2481*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2482*5b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_dmastate |= MPTSAS_DMA_HANDLE_BOUND;
2483*5b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(recv_memp, sizeof (MPI2_CONFIG_REPLY));
2484*5b504601Sjiang wu - Sun Microsystems - Beijing China 	configreply = (pMpi2ConfigReply_t)recv_memp;
2485*5b504601Sjiang wu - Sun Microsystems - Beijing China 	recv_numbytes = sizeof (MPI2_CONFIG_REPLY);
2486*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2487*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
2488*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * get config reply message
2489*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
2490*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes,
2491*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    recv_accessp)) {
2492*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
2493*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
2494*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2495*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2496*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (iocstatus = ddi_get16(recv_accessp, &configreply->IOCStatus)) {
2497*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "mptsas_get_manufacture_page5 update: "
2498*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
2499*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get32(recv_accessp, &configreply->IOCLogInfo));
2500*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
2501*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2502*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2503*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
2504*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * dynamically create a customized dma attribute structure
2505*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * that describes the MPT's config page structure.
2506*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
2507*5b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dma_attrs = mpt->m_msg_dma_attr;
2508*5b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dma_attrs.dma_attr_sgllen = 1;
2509*5b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_PAGE_MAN_5));
2510*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2511*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_alloc_handle(mpt->m_dip, &page_dma_attrs,
2512*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    DDI_DMA_SLEEP, NULL, &page_dma_handle) != DDI_SUCCESS) {
2513*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN,
2514*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "(unable to allocate dma handle.");
2515*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
2516*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
2517*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2518*5b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dmastate |= MPTSAS_DMA_HANDLE_ALLOCD;
2519*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2520*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_mem_alloc(page_dma_handle,
2521*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    (sizeof (MPI2_CONFIG_PAGE_MAN_5)),
2522*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
2523*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    &page_memp, &page_alloc_len, &page_accessp) != DDI_SUCCESS) {
2524*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN,
2525*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "unable to allocate manufacturing page structure.");
2526*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
2527*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
2528*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2529*5b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dmastate |= MPTSAS_DMA_MEMORY_ALLOCD;
2530*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2531*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_dma_addr_bind_handle(page_dma_handle, NULL, page_memp,
2532*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    page_alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
2533*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    NULL, &page_cookie, &page_ncookie) != DDI_DMA_MAPPED) {
2534*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "unable to bind DMA resources.");
2535*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
2536*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
2537*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2538*5b504601Sjiang wu - Sun Microsystems - Beijing China 	page_dmastate |= MPTSAS_DMA_HANDLE_BOUND;
2539*5b504601Sjiang wu - Sun Microsystems - Beijing China 	bzero(page_memp, sizeof (MPI2_CONFIG_PAGE_MAN_5));
2540*5b504601Sjiang wu - Sun Microsystems - Beijing China 	m5 = (pMpi2ManufacturingPage5_t)page_memp;
2541*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2542*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
2543*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Give reply address to IOC to store config page in and send
2544*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * config request out.
2545*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
2546*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2547*5b504601Sjiang wu - Sun Microsystems - Beijing China 	flagslength = sizeof (MPI2_CONFIG_PAGE_MAN_5);
2548*5b504601Sjiang wu - Sun Microsystems - Beijing China 	flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT |
2549*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
2550*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_SYSTEM_ADDRESS | MPI2_SGE_FLAGS_32_BIT_ADDRESSING |
2551*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_IOC_TO_HOST |
2552*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
2553*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2554*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_send_config_request_msg(mpt,
2555*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_CONFIG_ACTION_PAGE_READ_CURRENT,
2556*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    MPI2_CONFIG_PAGETYPE_MANUFACTURING, 0, 5,
2557*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    ddi_get8(recv_accessp, &configreply->Header.PageVersion),
2558*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    ddi_get8(recv_accessp, &configreply->Header.PageLength),
2559*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    flagslength, page_cookie.dmac_address)) {
2560*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
2561*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
2562*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2563*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2564*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
2565*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * get reply view handshake
2566*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
2567*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes,
2568*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    recv_accessp)) {
2569*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
2570*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
2571*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2572*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2573*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (iocstatus = ddi_get16(recv_accessp, &configreply->IOCStatus)) {
2574*5b504601Sjiang wu - Sun Microsystems - Beijing China 		mptsas_log(mpt, CE_WARN, "mptsas_get_manufacture_page5 config: "
2575*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
2576*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_get32(recv_accessp, &configreply->IOCLogInfo));
2577*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
2578*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2579*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2580*5b504601Sjiang wu - Sun Microsystems - Beijing China 	(void) ddi_dma_sync(page_dma_handle, 0, 0, DDI_DMA_SYNC_FORCPU);
2581*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2582*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
2583*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Fusion-MPT stores fields in little-endian format.  This is
2584*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * why the low-order 32 bits are stored first.
2585*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
2586*5b504601Sjiang wu - Sun Microsystems - Beijing China 	mpt->un.sasaddr.m_base_wwid_lo =
2587*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    ddi_get32(page_accessp, (uint32_t *)(void *)&m5->Phy[0].WWID);
2588*5b504601Sjiang wu - Sun Microsystems - Beijing China 	mpt->un.sasaddr.m_base_wwid_hi =
2589*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    ddi_get32(page_accessp, (uint32_t *)(void *)&m5->Phy[0].WWID + 1);
2590*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2591*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_prop_update_int64(DDI_DEV_T_NONE, mpt->m_dip,
2592*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    "base-wwid", mpt->un.m_base_wwid) != DDI_PROP_SUCCESS) {
2593*5b504601Sjiang wu - Sun Microsystems - Beijing China 		NDBG2(("%s%d: failed to create base-wwid property",
2594*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_driver_name(mpt->m_dip), ddi_get_instance(mpt->m_dip)));
2595*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2596*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2597*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
2598*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * Set the number of PHYs present.
2599*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
2600*5b504601Sjiang wu - Sun Microsystems - Beijing China 	mpt->m_num_phys = ddi_get8(page_accessp, (uint8_t *)&m5->NumPhys);
2601*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2602*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (ddi_prop_update_int(DDI_DEV_T_NONE, mpt->m_dip,
2603*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    "num-phys", mpt->m_num_phys) != DDI_PROP_SUCCESS) {
2604*5b504601Sjiang wu - Sun Microsystems - Beijing China 		NDBG2(("%s%d: failed to create num-phys property",
2605*5b504601Sjiang wu - Sun Microsystems - Beijing China 		    ddi_driver_name(mpt->m_dip), ddi_get_instance(mpt->m_dip)));
2606*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2607*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2608*5b504601Sjiang wu - Sun Microsystems - Beijing China 	mptsas_log(mpt, CE_NOTE, "!mpt%d: Initiator WWNs: 0x%016llx-0x%016llx",
2609*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    mpt->m_instance, (unsigned long long)mpt->un.m_base_wwid,
2610*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    (unsigned long long)mpt->un.m_base_wwid + mpt->m_num_phys - 1);
2611*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2612*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((mptsas_check_dma_handle(recv_dma_handle) != DDI_SUCCESS) ||
2613*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    (mptsas_check_dma_handle(page_dma_handle) != DDI_SUCCESS)) {
2614*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
2615*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
2616*5b504601Sjiang wu - Sun Microsystems - Beijing China 		goto done;
2617*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2618*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if ((mptsas_check_acc_handle(recv_accessp) != DDI_SUCCESS) ||
2619*5b504601Sjiang wu - Sun Microsystems - Beijing China 	    (mptsas_check_acc_handle(page_accessp) != DDI_SUCCESS)) {
2620*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
2621*5b504601Sjiang wu - Sun Microsystems - Beijing China 		rval = DDI_FAILURE;
2622*5b504601Sjiang wu - Sun Microsystems - Beijing China 	}
2623*5b504601Sjiang wu - Sun Microsystems - Beijing China done:
2624*5b504601Sjiang wu - Sun Microsystems - Beijing China 	/*
2625*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 * free up memory
2626*5b504601Sjiang wu - Sun Microsystems - Beijing China 	 */
2627*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (recv_dmastate & MPTSAS_DMA_HANDLE_BOUND)
2628*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_unbind_handle(recv_dma_handle);
2629*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (page_dmastate & MPTSAS_DMA_HANDLE_BOUND)
2630*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_unbind_handle(page_dma_handle);
2631*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (recv_dmastate & MPTSAS_DMA_MEMORY_ALLOCD)
2632*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_mem_free(&recv_accessp);
2633*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (page_dmastate & MPTSAS_DMA_MEMORY_ALLOCD)
2634*5b504601Sjiang wu - Sun Microsystems - Beijing China 		(void) ddi_dma_mem_free(&page_accessp);
2635*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (recv_dmastate & MPTSAS_DMA_HANDLE_ALLOCD)
2636*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&recv_dma_handle);
2637*5b504601Sjiang wu - Sun Microsystems - Beijing China 	if (page_dmastate & MPTSAS_DMA_HANDLE_ALLOCD)
2638*5b504601Sjiang wu - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&page_dma_handle);
2639*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2640*5b504601Sjiang wu - Sun Microsystems - Beijing China 	MPTSAS_ENABLE_INTR(mpt);
2641*5b504601Sjiang wu - Sun Microsystems - Beijing China 
2642*5b504601Sjiang wu - Sun Microsystems - Beijing China 	return (rval);
2643*5b504601Sjiang wu - Sun Microsystems - Beijing China }
2644