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