15b504601Sjiang wu - Sun Microsystems - Beijing China /* 25b504601Sjiang wu - Sun Microsystems - Beijing China * CDDL HEADER START 35b504601Sjiang wu - Sun Microsystems - Beijing China * 45b504601Sjiang wu - Sun Microsystems - Beijing China * The contents of this file are subject to the terms of the 55b504601Sjiang wu - Sun Microsystems - Beijing China * Common Development and Distribution License (the "License"). 65b504601Sjiang wu - Sun Microsystems - Beijing China * You may not use this file except in compliance with the License. 75b504601Sjiang wu - Sun Microsystems - Beijing China * 85b504601Sjiang wu - Sun Microsystems - Beijing China * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95b504601Sjiang wu - Sun Microsystems - Beijing China * or http://www.opensolaris.org/os/licensing. 105b504601Sjiang wu - Sun Microsystems - Beijing China * See the License for the specific language governing permissions 115b504601Sjiang wu - Sun Microsystems - Beijing China * and limitations under the License. 125b504601Sjiang wu - Sun Microsystems - Beijing China * 135b504601Sjiang wu - Sun Microsystems - Beijing China * When distributing Covered Code, include this CDDL HEADER in each 145b504601Sjiang wu - Sun Microsystems - Beijing China * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155b504601Sjiang wu - Sun Microsystems - Beijing China * If applicable, add the following below this CDDL HEADER, with the 165b504601Sjiang wu - Sun Microsystems - Beijing China * fields enclosed by brackets "[]" replaced with your own identifying 175b504601Sjiang wu - Sun Microsystems - Beijing China * information: Portions Copyright [yyyy] [name of copyright owner] 185b504601Sjiang wu - Sun Microsystems - Beijing China * 195b504601Sjiang wu - Sun Microsystems - Beijing China * CDDL HEADER END 205b504601Sjiang wu - Sun Microsystems - Beijing China */ 215b504601Sjiang wu - Sun Microsystems - Beijing China 225b504601Sjiang wu - Sun Microsystems - Beijing China /* 239814ff7fSYong-Feng Du * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 24e18306b1SDan McDonald * Copyright 2012 Nexenta Systems, Inc. All rights reserved. 25f7d0d869SDan McDonald * Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved. 26ed7418aeSAndy Giles * Copyright (c) 2014, Tegile Systems Inc. All rights reserved. 27*882fdc88SHans Rosenfeld * Copyright (c) 2019, Joyent, Inc. 285b504601Sjiang wu - Sun Microsystems - Beijing China */ 295b504601Sjiang wu - Sun Microsystems - Beijing China 305b504601Sjiang wu - Sun Microsystems - Beijing China /* 31c8f74a56SAda * Copyright (c) 2000 to 2010, LSI Corporation. 325b504601Sjiang wu - Sun Microsystems - Beijing China * All rights reserved. 335b504601Sjiang wu - Sun Microsystems - Beijing China * 345b504601Sjiang wu - Sun Microsystems - Beijing China * Redistribution and use in source and binary forms of all code within 355b504601Sjiang wu - Sun Microsystems - Beijing China * this file that is exclusively owned by LSI, with or without 365b504601Sjiang wu - Sun Microsystems - Beijing China * modification, is permitted provided that, in addition to the CDDL 1.0 375b504601Sjiang wu - Sun Microsystems - Beijing China * License requirements, the following conditions are met: 385b504601Sjiang wu - Sun Microsystems - Beijing China * 395b504601Sjiang wu - Sun Microsystems - Beijing China * Neither the name of the author nor the names of its contributors may be 405b504601Sjiang wu - Sun Microsystems - Beijing China * used to endorse or promote products derived from this software without 415b504601Sjiang wu - Sun Microsystems - Beijing China * specific prior written permission. 425b504601Sjiang wu - Sun Microsystems - Beijing China * 435b504601Sjiang wu - Sun Microsystems - Beijing China * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 445b504601Sjiang wu - Sun Microsystems - Beijing China * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 455b504601Sjiang wu - Sun Microsystems - Beijing China * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 465b504601Sjiang wu - Sun Microsystems - Beijing China * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 475b504601Sjiang wu - Sun Microsystems - Beijing China * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 485b504601Sjiang wu - Sun Microsystems - Beijing China * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 495b504601Sjiang wu - Sun Microsystems - Beijing China * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 505b504601Sjiang wu - Sun Microsystems - Beijing China * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 515b504601Sjiang wu - Sun Microsystems - Beijing China * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 525b504601Sjiang wu - Sun Microsystems - Beijing China * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 535b504601Sjiang wu - Sun Microsystems - Beijing China * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 545b504601Sjiang wu - Sun Microsystems - Beijing China * DAMAGE. 555b504601Sjiang wu - Sun Microsystems - Beijing China */ 565b504601Sjiang wu - Sun Microsystems - Beijing China 575b504601Sjiang wu - Sun Microsystems - Beijing China /* 585b504601Sjiang wu - Sun Microsystems - Beijing China * mptsas_impl - This file contains all the basic functions for communicating 595b504601Sjiang wu - Sun Microsystems - Beijing China * to MPT based hardware. 605b504601Sjiang wu - Sun Microsystems - Beijing China */ 615b504601Sjiang wu - Sun Microsystems - Beijing China 625b504601Sjiang wu - Sun Microsystems - Beijing China #if defined(lint) || defined(DEBUG) 635b504601Sjiang wu - Sun Microsystems - Beijing China #define MPTSAS_DEBUG 645b504601Sjiang wu - Sun Microsystems - Beijing China #endif 655b504601Sjiang wu - Sun Microsystems - Beijing China 665b504601Sjiang wu - Sun Microsystems - Beijing China /* 675b504601Sjiang wu - Sun Microsystems - Beijing China * standard header files 685b504601Sjiang wu - Sun Microsystems - Beijing China */ 695b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/note.h> 705b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/scsi.h> 715b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/pci.h> 725b504601Sjiang wu - Sun Microsystems - Beijing China 735b504601Sjiang wu - Sun Microsystems - Beijing China #pragma pack(1) 745b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h> 755b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h> 765b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h> 775b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h> 785b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h> 795b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h> 8076a4caf6SAda #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h> 815b504601Sjiang wu - Sun Microsystems - Beijing China #pragma pack() 825b504601Sjiang wu - Sun Microsystems - Beijing China 835b504601Sjiang wu - Sun Microsystems - Beijing China /* 845b504601Sjiang wu - Sun Microsystems - Beijing China * private header files. 855b504601Sjiang wu - Sun Microsystems - Beijing China */ 865b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mptsas_var.h> 87f2e8686eSxun ni - Sun Microsystems - Beijing China #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h> 885b504601Sjiang wu - Sun Microsystems - Beijing China 895b504601Sjiang wu - Sun Microsystems - Beijing China /* 905b504601Sjiang wu - Sun Microsystems - Beijing China * FMA header files. 915b504601Sjiang wu - Sun Microsystems - Beijing China */ 925b504601Sjiang wu - Sun Microsystems - Beijing China #include <sys/fm/io/ddi.h> 935b504601Sjiang wu - Sun Microsystems - Beijing China 945b504601Sjiang wu - Sun Microsystems - Beijing China /* 955b504601Sjiang wu - Sun Microsystems - Beijing China * prototypes 965b504601Sjiang wu - Sun Microsystems - Beijing China */ 975b504601Sjiang wu - Sun Microsystems - Beijing China static void mptsas_ioc_event_cmdq_add(mptsas_t *mpt, m_event_struct_t *cmd); 985b504601Sjiang wu - Sun Microsystems - Beijing China static void mptsas_ioc_event_cmdq_delete(mptsas_t *mpt, m_event_struct_t *cmd); 995b504601Sjiang wu - Sun Microsystems - Beijing China static m_event_struct_t *mptsas_ioc_event_find_by_cmd(mptsas_t *mpt, 1005b504601Sjiang wu - Sun Microsystems - Beijing China struct mptsas_cmd *cmd); 1015b504601Sjiang wu - Sun Microsystems - Beijing China 1025b504601Sjiang wu - Sun Microsystems - Beijing China /* 1035b504601Sjiang wu - Sun Microsystems - Beijing China * add ioc evnet cmd into the queue 1045b504601Sjiang wu - Sun Microsystems - Beijing China */ 1055b504601Sjiang wu - Sun Microsystems - Beijing China static void 1065b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_event_cmdq_add(mptsas_t *mpt, m_event_struct_t *cmd) 1075b504601Sjiang wu - Sun Microsystems - Beijing China { 1085b504601Sjiang wu - Sun Microsystems - Beijing China if ((cmd->m_event_linkp = mpt->m_ioc_event_cmdq) == NULL) { 1095b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_ioc_event_cmdtail = &cmd->m_event_linkp; 1105b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_ioc_event_cmdq = cmd; 1115b504601Sjiang wu - Sun Microsystems - Beijing China } else { 1125b504601Sjiang wu - Sun Microsystems - Beijing China cmd->m_event_linkp = NULL; 1135b504601Sjiang wu - Sun Microsystems - Beijing China *(mpt->m_ioc_event_cmdtail) = cmd; 1145b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_ioc_event_cmdtail = &cmd->m_event_linkp; 1155b504601Sjiang wu - Sun Microsystems - Beijing China } 1165b504601Sjiang wu - Sun Microsystems - Beijing China } 1175b504601Sjiang wu - Sun Microsystems - Beijing China 1185b504601Sjiang wu - Sun Microsystems - Beijing China /* 1195b504601Sjiang wu - Sun Microsystems - Beijing China * remove specified cmd from the ioc event queue 1205b504601Sjiang wu - Sun Microsystems - Beijing China */ 1215b504601Sjiang wu - Sun Microsystems - Beijing China static void 1225b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_event_cmdq_delete(mptsas_t *mpt, m_event_struct_t *cmd) 1235b504601Sjiang wu - Sun Microsystems - Beijing China { 1245b504601Sjiang wu - Sun Microsystems - Beijing China m_event_struct_t *prev = mpt->m_ioc_event_cmdq; 1255b504601Sjiang wu - Sun Microsystems - Beijing China if (prev == cmd) { 1265b504601Sjiang wu - Sun Microsystems - Beijing China if ((mpt->m_ioc_event_cmdq = cmd->m_event_linkp) == NULL) { 1275b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_ioc_event_cmdtail = &mpt->m_ioc_event_cmdq; 1285b504601Sjiang wu - Sun Microsystems - Beijing China } 1295b504601Sjiang wu - Sun Microsystems - Beijing China cmd->m_event_linkp = NULL; 1305b504601Sjiang wu - Sun Microsystems - Beijing China return; 1315b504601Sjiang wu - Sun Microsystems - Beijing China } 1325b504601Sjiang wu - Sun Microsystems - Beijing China while (prev != NULL) { 1335b504601Sjiang wu - Sun Microsystems - Beijing China if (prev->m_event_linkp == cmd) { 1345b504601Sjiang wu - Sun Microsystems - Beijing China prev->m_event_linkp = cmd->m_event_linkp; 1355b504601Sjiang wu - Sun Microsystems - Beijing China if (cmd->m_event_linkp == NULL) { 1365b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_ioc_event_cmdtail = &prev->m_event_linkp; 1375b504601Sjiang wu - Sun Microsystems - Beijing China } 1385b504601Sjiang wu - Sun Microsystems - Beijing China 1395b504601Sjiang wu - Sun Microsystems - Beijing China cmd->m_event_linkp = NULL; 1405b504601Sjiang wu - Sun Microsystems - Beijing China return; 1415b504601Sjiang wu - Sun Microsystems - Beijing China } 1425b504601Sjiang wu - Sun Microsystems - Beijing China prev = prev->m_event_linkp; 1435b504601Sjiang wu - Sun Microsystems - Beijing China } 1445b504601Sjiang wu - Sun Microsystems - Beijing China } 1455b504601Sjiang wu - Sun Microsystems - Beijing China 1465b504601Sjiang wu - Sun Microsystems - Beijing China static m_event_struct_t * 1475b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_event_find_by_cmd(mptsas_t *mpt, struct mptsas_cmd *cmd) 1485b504601Sjiang wu - Sun Microsystems - Beijing China { 1495b504601Sjiang wu - Sun Microsystems - Beijing China m_event_struct_t *ioc_cmd = NULL; 1505b504601Sjiang wu - Sun Microsystems - Beijing China 1515b504601Sjiang wu - Sun Microsystems - Beijing China ioc_cmd = mpt->m_ioc_event_cmdq; 1525b504601Sjiang wu - Sun Microsystems - Beijing China while (ioc_cmd != NULL) { 1535b504601Sjiang wu - Sun Microsystems - Beijing China if (&(ioc_cmd->m_event_cmd) == cmd) { 1545b504601Sjiang wu - Sun Microsystems - Beijing China return (ioc_cmd); 1555b504601Sjiang wu - Sun Microsystems - Beijing China } 1565b504601Sjiang wu - Sun Microsystems - Beijing China ioc_cmd = ioc_cmd->m_event_linkp; 1575b504601Sjiang wu - Sun Microsystems - Beijing China } 1585b504601Sjiang wu - Sun Microsystems - Beijing China ioc_cmd = NULL; 1595b504601Sjiang wu - Sun Microsystems - Beijing China return (ioc_cmd); 1605b504601Sjiang wu - Sun Microsystems - Beijing China } 1615b504601Sjiang wu - Sun Microsystems - Beijing China 1625b504601Sjiang wu - Sun Microsystems - Beijing China void 1635b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_destroy_ioc_event_cmd(mptsas_t *mpt) 1645b504601Sjiang wu - Sun Microsystems - Beijing China { 1655b504601Sjiang wu - Sun Microsystems - Beijing China m_event_struct_t *ioc_cmd = NULL; 1665b504601Sjiang wu - Sun Microsystems - Beijing China m_event_struct_t *ioc_cmd_tmp = NULL; 1675b504601Sjiang wu - Sun Microsystems - Beijing China ioc_cmd = mpt->m_ioc_event_cmdq; 1685b504601Sjiang wu - Sun Microsystems - Beijing China 1695b504601Sjiang wu - Sun Microsystems - Beijing China /* 1705b504601Sjiang wu - Sun Microsystems - Beijing China * because the IOC event queue is resource of per instance for driver, 1715b504601Sjiang wu - Sun Microsystems - Beijing China * it's not only ACK event commands used it, but also some others used 1725b504601Sjiang wu - Sun Microsystems - Beijing China * it. We need destroy all ACK event commands when IOC reset, but can't 1735b504601Sjiang wu - Sun Microsystems - Beijing China * disturb others.So we use filter to clear the ACK event cmd in ioc 1745b504601Sjiang wu - Sun Microsystems - Beijing China * event queue, and other requests should be reserved, and they would 1755b504601Sjiang wu - Sun Microsystems - Beijing China * be free by its owner. 1765b504601Sjiang wu - Sun Microsystems - Beijing China */ 1775b504601Sjiang wu - Sun Microsystems - Beijing China while (ioc_cmd != NULL) { 1785b504601Sjiang wu - Sun Microsystems - Beijing China if (ioc_cmd->m_event_cmd.cmd_flags & CFLAG_CMDACK) { 1795b504601Sjiang wu - Sun Microsystems - Beijing China NDBG20(("destroy!! remove Ack Flag ioc_cmd\n")); 1805b504601Sjiang wu - Sun Microsystems - Beijing China if ((mpt->m_ioc_event_cmdq = 1815b504601Sjiang wu - Sun Microsystems - Beijing China ioc_cmd->m_event_linkp) == NULL) 1825b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_ioc_event_cmdtail = 1835b504601Sjiang wu - Sun Microsystems - Beijing China &mpt->m_ioc_event_cmdq; 1845b504601Sjiang wu - Sun Microsystems - Beijing China ioc_cmd_tmp = ioc_cmd; 1855b504601Sjiang wu - Sun Microsystems - Beijing China ioc_cmd = ioc_cmd->m_event_linkp; 1865b504601Sjiang wu - Sun Microsystems - Beijing China kmem_free(ioc_cmd_tmp, M_EVENT_STRUCT_SIZE); 1875b504601Sjiang wu - Sun Microsystems - Beijing China } else { 1885b504601Sjiang wu - Sun Microsystems - Beijing China /* 1895b504601Sjiang wu - Sun Microsystems - Beijing China * it's not ack cmd, so continue to check next one 1905b504601Sjiang wu - Sun Microsystems - Beijing China */ 1915b504601Sjiang wu - Sun Microsystems - Beijing China 1925b504601Sjiang wu - Sun Microsystems - Beijing China NDBG20(("destroy!! it's not Ack Flag, continue\n")); 1935b504601Sjiang wu - Sun Microsystems - Beijing China ioc_cmd = ioc_cmd->m_event_linkp; 1945b504601Sjiang wu - Sun Microsystems - Beijing China } 1955b504601Sjiang wu - Sun Microsystems - Beijing China 1965b504601Sjiang wu - Sun Microsystems - Beijing China } 1975b504601Sjiang wu - Sun Microsystems - Beijing China } 1985b504601Sjiang wu - Sun Microsystems - Beijing China 1995b504601Sjiang wu - Sun Microsystems - Beijing China void 2005b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_start_config_page_access(mptsas_t *mpt, mptsas_cmd_t *cmd) 2015b504601Sjiang wu - Sun Microsystems - Beijing China { 2025b504601Sjiang wu - Sun Microsystems - Beijing China pMpi2ConfigRequest_t request; 2035b504601Sjiang wu - Sun Microsystems - Beijing China pMpi2SGESimple64_t sge; 2045b504601Sjiang wu - Sun Microsystems - Beijing China struct scsi_pkt *pkt = cmd->cmd_pkt; 2055b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_config_request_t *config = pkt->pkt_ha_private; 2065b504601Sjiang wu - Sun Microsystems - Beijing China uint8_t direction; 207940efceeSAndy Giles uint32_t length, flagslength; 208940efceeSAndy Giles uint64_t request_desc; 2095b504601Sjiang wu - Sun Microsystems - Beijing China 2105b504601Sjiang wu - Sun Microsystems - Beijing China ASSERT(mutex_owned(&mpt->m_mutex)); 2115b504601Sjiang wu - Sun Microsystems - Beijing China 2125b504601Sjiang wu - Sun Microsystems - Beijing China /* 2135b504601Sjiang wu - Sun Microsystems - Beijing China * Point to the correct message and clear it as well as the global 2145b504601Sjiang wu - Sun Microsystems - Beijing China * config page memory. 2155b504601Sjiang wu - Sun Microsystems - Beijing China */ 2165b504601Sjiang wu - Sun Microsystems - Beijing China request = (pMpi2ConfigRequest_t)(mpt->m_req_frame + 2175b504601Sjiang wu - Sun Microsystems - Beijing China (mpt->m_req_frame_size * cmd->cmd_slot)); 2185b504601Sjiang wu - Sun Microsystems - Beijing China bzero(request, mpt->m_req_frame_size); 2195b504601Sjiang wu - Sun Microsystems - Beijing China 2205b504601Sjiang wu - Sun Microsystems - Beijing China /* 2215b504601Sjiang wu - Sun Microsystems - Beijing China * Form the request message. 2225b504601Sjiang wu - Sun Microsystems - Beijing China */ 2235b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_acc_req_frame_hdl, &request->Function, 2245b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_FUNCTION_CONFIG); 2255b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_acc_req_frame_hdl, &request->Action, config->action); 2265b504601Sjiang wu - Sun Microsystems - Beijing China direction = MPI2_SGE_FLAGS_IOC_TO_HOST; 2275b504601Sjiang wu - Sun Microsystems - Beijing China length = 0; 2285b504601Sjiang wu - Sun Microsystems - Beijing China sge = (pMpi2SGESimple64_t)&request->PageBufferSGE; 2295b504601Sjiang wu - Sun Microsystems - Beijing China if (config->action == MPI2_CONFIG_ACTION_PAGE_HEADER) { 2305b504601Sjiang wu - Sun Microsystems - Beijing China if (config->page_type > MPI2_CONFIG_PAGETYPE_MASK) { 2315b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_acc_req_frame_hdl, 2325b504601Sjiang wu - Sun Microsystems - Beijing China &request->Header.PageType, 2335b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_CONFIG_PAGETYPE_EXTENDED); 2345b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_acc_req_frame_hdl, 2355b504601Sjiang wu - Sun Microsystems - Beijing China &request->ExtPageType, config->page_type); 2365b504601Sjiang wu - Sun Microsystems - Beijing China } else { 2375b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_acc_req_frame_hdl, 2385b504601Sjiang wu - Sun Microsystems - Beijing China &request->Header.PageType, config->page_type); 2395b504601Sjiang wu - Sun Microsystems - Beijing China } 2405b504601Sjiang wu - Sun Microsystems - Beijing China } else { 2415b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_acc_req_frame_hdl, &request->ExtPageType, 2425b504601Sjiang wu - Sun Microsystems - Beijing China config->ext_page_type); 2435b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put16(mpt->m_acc_req_frame_hdl, &request->ExtPageLength, 2445b504601Sjiang wu - Sun Microsystems - Beijing China config->ext_page_length); 2455b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_acc_req_frame_hdl, &request->Header.PageType, 2465b504601Sjiang wu - Sun Microsystems - Beijing China config->page_type); 2475b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_acc_req_frame_hdl, &request->Header.PageLength, 2485b504601Sjiang wu - Sun Microsystems - Beijing China config->page_length); 2495b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_acc_req_frame_hdl, 2505b504601Sjiang wu - Sun Microsystems - Beijing China &request->Header.PageVersion, config->page_version); 2515b504601Sjiang wu - Sun Microsystems - Beijing China if ((config->page_type & MPI2_CONFIG_PAGETYPE_MASK) == 2525b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_CONFIG_PAGETYPE_EXTENDED) { 2535b504601Sjiang wu - Sun Microsystems - Beijing China length = config->ext_page_length * 4; 2545b504601Sjiang wu - Sun Microsystems - Beijing China } else { 2555b504601Sjiang wu - Sun Microsystems - Beijing China length = config->page_length * 4; 2565b504601Sjiang wu - Sun Microsystems - Beijing China } 2575b504601Sjiang wu - Sun Microsystems - Beijing China 2585b504601Sjiang wu - Sun Microsystems - Beijing China if (config->action == MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) { 2595b504601Sjiang wu - Sun Microsystems - Beijing China direction = MPI2_SGE_FLAGS_HOST_TO_IOC; 2605b504601Sjiang wu - Sun Microsystems - Beijing China } 2615b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.Low, 2625b504601Sjiang wu - Sun Microsystems - Beijing China (uint32_t)cmd->cmd_dma_addr); 2635b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.High, 2645b504601Sjiang wu - Sun Microsystems - Beijing China (uint32_t)(cmd->cmd_dma_addr >> 32)); 2655b504601Sjiang wu - Sun Microsystems - Beijing China } 2665b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_acc_req_frame_hdl, &request->Header.PageNumber, 2675b504601Sjiang wu - Sun Microsystems - Beijing China config->page_number); 2685b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_acc_req_frame_hdl, &request->PageAddress, 2695b504601Sjiang wu - Sun Microsystems - Beijing China config->page_address); 2705b504601Sjiang wu - Sun Microsystems - Beijing China flagslength = ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT | 2715b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_END_OF_BUFFER | 2725b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 2735b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 2745b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_64_BIT_ADDRESSING | 2755b504601Sjiang wu - Sun Microsystems - Beijing China direction | 2765b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); 2775b504601Sjiang wu - Sun Microsystems - Beijing China flagslength |= length; 2785b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_acc_req_frame_hdl, &sge->FlagsLength, flagslength); 2795b504601Sjiang wu - Sun Microsystems - Beijing China 2805b504601Sjiang wu - Sun Microsystems - Beijing China (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0, 2815b504601Sjiang wu - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV); 282940efceeSAndy Giles request_desc = (cmd->cmd_slot << 16) + 2835b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 284a0ac5a9eSToomas Soome cmd->cmd_rfm = 0; 285940efceeSAndy Giles MPTSAS_START_CMD(mpt, request_desc); 2865b504601Sjiang wu - Sun Microsystems - Beijing China if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 2875b504601Sjiang wu - Sun Microsystems - Beijing China DDI_SUCCESS) || 2885b504601Sjiang wu - Sun Microsystems - Beijing China (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 2895b504601Sjiang wu - Sun Microsystems - Beijing China DDI_SUCCESS)) { 2905b504601Sjiang wu - Sun Microsystems - Beijing China ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 2915b504601Sjiang wu - Sun Microsystems - Beijing China } 2925b504601Sjiang wu - Sun Microsystems - Beijing China } 2935b504601Sjiang wu - Sun Microsystems - Beijing China 2945b504601Sjiang wu - Sun Microsystems - Beijing China int 2955b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_access_config_page(mptsas_t *mpt, uint8_t action, uint8_t page_type, 2965b504601Sjiang wu - Sun Microsystems - Beijing China uint8_t page_number, uint32_t page_address, int (*callback) (mptsas_t *, 2975b504601Sjiang wu - Sun Microsystems - Beijing China caddr_t, ddi_acc_handle_t, uint16_t, uint32_t, va_list), ...) 2985b504601Sjiang wu - Sun Microsystems - Beijing China { 2995b504601Sjiang wu - Sun Microsystems - Beijing China va_list ap; 3005b504601Sjiang wu - Sun Microsystems - Beijing China ddi_dma_attr_t attrs; 3015b504601Sjiang wu - Sun Microsystems - Beijing China ddi_dma_cookie_t cookie; 3025b504601Sjiang wu - Sun Microsystems - Beijing China ddi_acc_handle_t accessp; 303a9b51062SAda size_t len = 0; 3045b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_config_request_t config; 3055b504601Sjiang wu - Sun Microsystems - Beijing China int rval = DDI_SUCCESS, config_flags = 0; 3065b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_cmd_t *cmd; 3075b504601Sjiang wu - Sun Microsystems - Beijing China struct scsi_pkt *pkt; 3085b504601Sjiang wu - Sun Microsystems - Beijing China pMpi2ConfigReply_t reply; 3095b504601Sjiang wu - Sun Microsystems - Beijing China uint16_t iocstatus = 0; 3105b504601Sjiang wu - Sun Microsystems - Beijing China uint32_t iocloginfo; 3115b504601Sjiang wu - Sun Microsystems - Beijing China caddr_t page_memp; 312f7d0d869SDan McDonald boolean_t free_dma = B_FALSE; 3135b504601Sjiang wu - Sun Microsystems - Beijing China 3145b504601Sjiang wu - Sun Microsystems - Beijing China va_start(ap, callback); 3155b504601Sjiang wu - Sun Microsystems - Beijing China ASSERT(mutex_owned(&mpt->m_mutex)); 3165b504601Sjiang wu - Sun Microsystems - Beijing China 3175b504601Sjiang wu - Sun Microsystems - Beijing China /* 3185b504601Sjiang wu - Sun Microsystems - Beijing China * Get a command from the pool. 3195b504601Sjiang wu - Sun Microsystems - Beijing China */ 3205b504601Sjiang wu - Sun Microsystems - Beijing China if ((rval = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 3215b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_NOTE, "command pool is full for config " 3225b504601Sjiang wu - Sun Microsystems - Beijing China "page request"); 3235b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 3245b504601Sjiang wu - Sun Microsystems - Beijing China goto page_done; 3255b504601Sjiang wu - Sun Microsystems - Beijing China } 3265b504601Sjiang wu - Sun Microsystems - Beijing China config_flags |= MPTSAS_REQUEST_POOL_CMD; 3275b504601Sjiang wu - Sun Microsystems - Beijing China 3285b504601Sjiang wu - Sun Microsystems - Beijing China bzero((caddr_t)cmd, sizeof (*cmd)); 3295b504601Sjiang wu - Sun Microsystems - Beijing China bzero((caddr_t)pkt, scsi_pkt_size()); 3305b504601Sjiang wu - Sun Microsystems - Beijing China bzero((caddr_t)&config, sizeof (config)); 3315b504601Sjiang wu - Sun Microsystems - Beijing China 3325b504601Sjiang wu - Sun Microsystems - Beijing China /* 3335b504601Sjiang wu - Sun Microsystems - Beijing China * Save the data for this request to be used in the call to start the 3345b504601Sjiang wu - Sun Microsystems - Beijing China * config header request. 3355b504601Sjiang wu - Sun Microsystems - Beijing China */ 3365b504601Sjiang wu - Sun Microsystems - Beijing China config.action = MPI2_CONFIG_ACTION_PAGE_HEADER; 3375b504601Sjiang wu - Sun Microsystems - Beijing China config.page_type = page_type; 3385b504601Sjiang wu - Sun Microsystems - Beijing China config.page_number = page_number; 3395b504601Sjiang wu - Sun Microsystems - Beijing China config.page_address = page_address; 3405b504601Sjiang wu - Sun Microsystems - Beijing China 3415b504601Sjiang wu - Sun Microsystems - Beijing China /* 3425b504601Sjiang wu - Sun Microsystems - Beijing China * Form a blank cmd/pkt to store the acknowledgement message 3435b504601Sjiang wu - Sun Microsystems - Beijing China */ 3445b504601Sjiang wu - Sun Microsystems - Beijing China pkt->pkt_ha_private = (opaque_t)&config; 3455b504601Sjiang wu - Sun Microsystems - Beijing China pkt->pkt_flags = FLAG_HEAD; 3465b504601Sjiang wu - Sun Microsystems - Beijing China pkt->pkt_time = 60; 3475b504601Sjiang wu - Sun Microsystems - Beijing China cmd->cmd_pkt = pkt; 3485b504601Sjiang wu - Sun Microsystems - Beijing China cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_CONFIG; 3495b504601Sjiang wu - Sun Microsystems - Beijing China 3505b504601Sjiang wu - Sun Microsystems - Beijing China /* 3515b504601Sjiang wu - Sun Microsystems - Beijing China * Save the config header request message in a slot. 3525b504601Sjiang wu - Sun Microsystems - Beijing China */ 3535b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_save_cmd(mpt, cmd) == TRUE) { 3545b504601Sjiang wu - Sun Microsystems - Beijing China cmd->cmd_flags |= CFLAG_PREPARED; 3555b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_start_config_page_access(mpt, cmd); 3565b504601Sjiang wu - Sun Microsystems - Beijing China } else { 3575b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_waitq_add(mpt, cmd); 3585b504601Sjiang wu - Sun Microsystems - Beijing China } 3595b504601Sjiang wu - Sun Microsystems - Beijing China 3605b504601Sjiang wu - Sun Microsystems - Beijing China /* 361c8f74a56SAda * If this is a request for a RAID info page, or any page called during 362c8f74a56SAda * the RAID info page request, poll because these config page requests 363c8f74a56SAda * are nested. Poll to avoid data corruption due to one page's data 364c8f74a56SAda * overwriting the outer page request's data. This can happen when 365c8f74a56SAda * the mutex is released in cv_wait. 3665b504601Sjiang wu - Sun Microsystems - Beijing China */ 367c8f74a56SAda if ((page_type == MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG) || 368c8f74a56SAda (page_type == MPI2_CONFIG_PAGETYPE_RAID_VOLUME) || 369c8f74a56SAda (page_type == MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK)) { 370c8f74a56SAda (void) mptsas_poll(mpt, cmd, pkt->pkt_time * 1000); 371c8f74a56SAda } else { 372c8f74a56SAda while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 373c8f74a56SAda cv_wait(&mpt->m_config_cv, &mpt->m_mutex); 374c8f74a56SAda } 3755b504601Sjiang wu - Sun Microsystems - Beijing China } 3765b504601Sjiang wu - Sun Microsystems - Beijing China 3775b504601Sjiang wu - Sun Microsystems - Beijing China /* 3785b504601Sjiang wu - Sun Microsystems - Beijing China * Check if the header request completed without timing out 3795b504601Sjiang wu - Sun Microsystems - Beijing China */ 3805b504601Sjiang wu - Sun Microsystems - Beijing China if (cmd->cmd_flags & CFLAG_TIMEOUT) { 381*882fdc88SHans Rosenfeld config_flags |= MPTSAS_CMD_TIMEOUT; 3825b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "config header request timeout"); 3835b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 3845b504601Sjiang wu - Sun Microsystems - Beijing China goto page_done; 3855b504601Sjiang wu - Sun Microsystems - Beijing China } 3865b504601Sjiang wu - Sun Microsystems - Beijing China 3875b504601Sjiang wu - Sun Microsystems - Beijing China /* 3885b504601Sjiang wu - Sun Microsystems - Beijing China * cmd_rfm points to the reply message if a reply was given. Check the 3895b504601Sjiang wu - Sun Microsystems - Beijing China * IOCStatus to make sure everything went OK with the header request. 3905b504601Sjiang wu - Sun Microsystems - Beijing China */ 3915b504601Sjiang wu - Sun Microsystems - Beijing China if (cmd->cmd_rfm) { 3925b504601Sjiang wu - Sun Microsystems - Beijing China config_flags |= MPTSAS_ADDRESS_REPLY; 3935b504601Sjiang wu - Sun Microsystems - Beijing China (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 3945b504601Sjiang wu - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORCPU); 3955b504601Sjiang wu - Sun Microsystems - Beijing China reply = (pMpi2ConfigReply_t)(mpt->m_reply_frame + (cmd->cmd_rfm 396940efceeSAndy Giles - (mpt->m_reply_frame_dma_addr & 0xffffffffu))); 3975b504601Sjiang wu - Sun Microsystems - Beijing China config.page_type = ddi_get8(mpt->m_acc_reply_frame_hdl, 3985b504601Sjiang wu - Sun Microsystems - Beijing China &reply->Header.PageType); 3995b504601Sjiang wu - Sun Microsystems - Beijing China config.page_number = ddi_get8(mpt->m_acc_reply_frame_hdl, 4005b504601Sjiang wu - Sun Microsystems - Beijing China &reply->Header.PageNumber); 4015b504601Sjiang wu - Sun Microsystems - Beijing China config.page_length = ddi_get8(mpt->m_acc_reply_frame_hdl, 4025b504601Sjiang wu - Sun Microsystems - Beijing China &reply->Header.PageLength); 4035b504601Sjiang wu - Sun Microsystems - Beijing China config.page_version = ddi_get8(mpt->m_acc_reply_frame_hdl, 4045b504601Sjiang wu - Sun Microsystems - Beijing China &reply->Header.PageVersion); 4055b504601Sjiang wu - Sun Microsystems - Beijing China config.ext_page_type = ddi_get8(mpt->m_acc_reply_frame_hdl, 4065b504601Sjiang wu - Sun Microsystems - Beijing China &reply->ExtPageType); 4075b504601Sjiang wu - Sun Microsystems - Beijing China config.ext_page_length = ddi_get16(mpt->m_acc_reply_frame_hdl, 4085b504601Sjiang wu - Sun Microsystems - Beijing China &reply->ExtPageLength); 4095b504601Sjiang wu - Sun Microsystems - Beijing China 4105b504601Sjiang wu - Sun Microsystems - Beijing China iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 4115b504601Sjiang wu - Sun Microsystems - Beijing China &reply->IOCStatus); 4125b504601Sjiang wu - Sun Microsystems - Beijing China iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 4135b504601Sjiang wu - Sun Microsystems - Beijing China &reply->IOCLogInfo); 4145b504601Sjiang wu - Sun Microsystems - Beijing China 4155b504601Sjiang wu - Sun Microsystems - Beijing China if (iocstatus) { 4165b504601Sjiang wu - Sun Microsystems - Beijing China NDBG13(("mptsas_access_config_page header: " 4175b504601Sjiang wu - Sun Microsystems - Beijing China "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus, 4185b504601Sjiang wu - Sun Microsystems - Beijing China iocloginfo)); 4195b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 4205b504601Sjiang wu - Sun Microsystems - Beijing China goto page_done; 4215b504601Sjiang wu - Sun Microsystems - Beijing China } 4225b504601Sjiang wu - Sun Microsystems - Beijing China 4235b504601Sjiang wu - Sun Microsystems - Beijing China if ((config.page_type & MPI2_CONFIG_PAGETYPE_MASK) == 4245b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_CONFIG_PAGETYPE_EXTENDED) 4255b504601Sjiang wu - Sun Microsystems - Beijing China len = (config.ext_page_length * 4); 4265b504601Sjiang wu - Sun Microsystems - Beijing China else 4275b504601Sjiang wu - Sun Microsystems - Beijing China len = (config.page_length * 4); 4285b504601Sjiang wu - Sun Microsystems - Beijing China 4295b504601Sjiang wu - Sun Microsystems - Beijing China } 4305b504601Sjiang wu - Sun Microsystems - Beijing China 4315b504601Sjiang wu - Sun Microsystems - Beijing China if (pkt->pkt_reason == CMD_RESET) { 4325b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "ioc reset abort config header " 4335b504601Sjiang wu - Sun Microsystems - Beijing China "request"); 4345b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 4355b504601Sjiang wu - Sun Microsystems - Beijing China goto page_done; 4365b504601Sjiang wu - Sun Microsystems - Beijing China } 4375b504601Sjiang wu - Sun Microsystems - Beijing China 4385b504601Sjiang wu - Sun Microsystems - Beijing China /* 4395b504601Sjiang wu - Sun Microsystems - Beijing China * Put the reply frame back on the free queue, increment the free 4405b504601Sjiang wu - Sun Microsystems - Beijing China * index, and write the new index to the free index register. But only 4415b504601Sjiang wu - Sun Microsystems - Beijing China * if this reply is an ADDRESS reply. 4425b504601Sjiang wu - Sun Microsystems - Beijing China */ 4435b504601Sjiang wu - Sun Microsystems - Beijing China if (config_flags & MPTSAS_ADDRESS_REPLY) { 4445b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_acc_free_queue_hdl, 44508eb0b82SYong-Feng Du &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 4465b504601Sjiang wu - Sun Microsystems - Beijing China cmd->cmd_rfm); 4475b504601Sjiang wu - Sun Microsystems - Beijing China (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 4485b504601Sjiang wu - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV); 44908eb0b82SYong-Feng Du if (++mpt->m_free_index == mpt->m_free_queue_depth) { 45008eb0b82SYong-Feng Du mpt->m_free_index = 0; 4515b504601Sjiang wu - Sun Microsystems - Beijing China } 4525b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 45308eb0b82SYong-Feng Du mpt->m_free_index); 4545b504601Sjiang wu - Sun Microsystems - Beijing China config_flags &= (~MPTSAS_ADDRESS_REPLY); 4555b504601Sjiang wu - Sun Microsystems - Beijing China } 4565b504601Sjiang wu - Sun Microsystems - Beijing China 4575b504601Sjiang wu - Sun Microsystems - Beijing China /* 4585b504601Sjiang wu - Sun Microsystems - Beijing China * Allocate DMA buffer here. Store the info regarding this buffer in 4595b504601Sjiang wu - Sun Microsystems - Beijing China * the cmd struct so that it can be used for this specific command and 4605b504601Sjiang wu - Sun Microsystems - Beijing China * de-allocated after the command completes. The size of the reply 4615b504601Sjiang wu - Sun Microsystems - Beijing China * will not be larger than the reply frame size. 4625b504601Sjiang wu - Sun Microsystems - Beijing China */ 4635b504601Sjiang wu - Sun Microsystems - Beijing China attrs = mpt->m_msg_dma_attr; 4645b504601Sjiang wu - Sun Microsystems - Beijing China attrs.dma_attr_sgllen = 1; 4655b504601Sjiang wu - Sun Microsystems - Beijing China attrs.dma_attr_granular = (uint32_t)len; 4665b504601Sjiang wu - Sun Microsystems - Beijing China 467a9b51062SAda if (mptsas_dma_addr_create(mpt, attrs, 468a9b51062SAda &cmd->cmd_dmahandle, &accessp, &page_memp, 469a9b51062SAda len, &cookie) == FALSE) { 470f7d0d869SDan McDonald rval = DDI_FAILURE; 471ed7418aeSAndy Giles mptsas_log(mpt, CE_WARN, 472ed7418aeSAndy Giles "mptsas_dma_addr_create(len=0x%x) failed", (int)len); 4735b504601Sjiang wu - Sun Microsystems - Beijing China goto page_done; 4745b504601Sjiang wu - Sun Microsystems - Beijing China } 475f7d0d869SDan McDonald /* NOW we can safely call mptsas_dma_addr_destroy(). */ 476f7d0d869SDan McDonald free_dma = B_TRUE; 477f7d0d869SDan McDonald 4785b504601Sjiang wu - Sun Microsystems - Beijing China cmd->cmd_dma_addr = cookie.dmac_laddress; 4795b504601Sjiang wu - Sun Microsystems - Beijing China bzero(page_memp, len); 4805b504601Sjiang wu - Sun Microsystems - Beijing China 4815b504601Sjiang wu - Sun Microsystems - Beijing China /* 4825b504601Sjiang wu - Sun Microsystems - Beijing China * Save the data for this request to be used in the call to start the 4835b504601Sjiang wu - Sun Microsystems - Beijing China * config page read 4845b504601Sjiang wu - Sun Microsystems - Beijing China */ 4855b504601Sjiang wu - Sun Microsystems - Beijing China config.action = action; 4865b504601Sjiang wu - Sun Microsystems - Beijing China config.page_address = page_address; 4875b504601Sjiang wu - Sun Microsystems - Beijing China 4885b504601Sjiang wu - Sun Microsystems - Beijing China /* 4895b504601Sjiang wu - Sun Microsystems - Beijing China * Re-use the cmd that was used to get the header. Reset some of the 4905b504601Sjiang wu - Sun Microsystems - Beijing China * values. 4915b504601Sjiang wu - Sun Microsystems - Beijing China */ 4925b504601Sjiang wu - Sun Microsystems - Beijing China bzero((caddr_t)pkt, scsi_pkt_size()); 4935b504601Sjiang wu - Sun Microsystems - Beijing China pkt->pkt_ha_private = (opaque_t)&config; 4945b504601Sjiang wu - Sun Microsystems - Beijing China pkt->pkt_flags = FLAG_HEAD; 4955b504601Sjiang wu - Sun Microsystems - Beijing China pkt->pkt_time = 60; 4965b504601Sjiang wu - Sun Microsystems - Beijing China cmd->cmd_flags = CFLAG_PREPARED | CFLAG_CMDIOC | CFLAG_CONFIG; 4975b504601Sjiang wu - Sun Microsystems - Beijing China 4985b504601Sjiang wu - Sun Microsystems - Beijing China /* 4995b504601Sjiang wu - Sun Microsystems - Beijing China * Send the config page request. cmd is re-used from header request. 5005b504601Sjiang wu - Sun Microsystems - Beijing China */ 5015b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_start_config_page_access(mpt, cmd); 5025b504601Sjiang wu - Sun Microsystems - Beijing China 5035b504601Sjiang wu - Sun Microsystems - Beijing China /* 504c8f74a56SAda * If this is a request for a RAID info page, or any page called during 505c8f74a56SAda * the RAID info page request, poll because these config page requests 506c8f74a56SAda * are nested. Poll to avoid data corruption due to one page's data 507c8f74a56SAda * overwriting the outer page request's data. This can happen when 508c8f74a56SAda * the mutex is released in cv_wait. 5095b504601Sjiang wu - Sun Microsystems - Beijing China */ 510c8f74a56SAda if ((page_type == MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG) || 511c8f74a56SAda (page_type == MPI2_CONFIG_PAGETYPE_RAID_VOLUME) || 512c8f74a56SAda (page_type == MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK)) { 513c8f74a56SAda (void) mptsas_poll(mpt, cmd, pkt->pkt_time * 1000); 514c8f74a56SAda } else { 515c8f74a56SAda while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 516c8f74a56SAda cv_wait(&mpt->m_config_cv, &mpt->m_mutex); 517c8f74a56SAda } 5185b504601Sjiang wu - Sun Microsystems - Beijing China } 5195b504601Sjiang wu - Sun Microsystems - Beijing China 5205b504601Sjiang wu - Sun Microsystems - Beijing China /* 5215b504601Sjiang wu - Sun Microsystems - Beijing China * Check if the request completed without timing out 5225b504601Sjiang wu - Sun Microsystems - Beijing China */ 5235b504601Sjiang wu - Sun Microsystems - Beijing China if (cmd->cmd_flags & CFLAG_TIMEOUT) { 524*882fdc88SHans Rosenfeld config_flags |= MPTSAS_CMD_TIMEOUT; 5255b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "config page request timeout"); 5265b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 5275b504601Sjiang wu - Sun Microsystems - Beijing China goto page_done; 5285b504601Sjiang wu - Sun Microsystems - Beijing China } 5295b504601Sjiang wu - Sun Microsystems - Beijing China 5305b504601Sjiang wu - Sun Microsystems - Beijing China /* 5315b504601Sjiang wu - Sun Microsystems - Beijing China * cmd_rfm points to the reply message if a reply was given. The reply 5325b504601Sjiang wu - Sun Microsystems - Beijing China * frame and the config page are returned from this function in the 5335b504601Sjiang wu - Sun Microsystems - Beijing China * param list. 5345b504601Sjiang wu - Sun Microsystems - Beijing China */ 5355b504601Sjiang wu - Sun Microsystems - Beijing China if (cmd->cmd_rfm) { 5365b504601Sjiang wu - Sun Microsystems - Beijing China config_flags |= MPTSAS_ADDRESS_REPLY; 5375b504601Sjiang wu - Sun Microsystems - Beijing China (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 5385b504601Sjiang wu - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORCPU); 5395b504601Sjiang wu - Sun Microsystems - Beijing China (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 5405b504601Sjiang wu - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORCPU); 5415b504601Sjiang wu - Sun Microsystems - Beijing China reply = (pMpi2ConfigReply_t)(mpt->m_reply_frame + (cmd->cmd_rfm 542940efceeSAndy Giles - (mpt->m_reply_frame_dma_addr & 0xffffffffu))); 5435b504601Sjiang wu - Sun Microsystems - Beijing China iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 5445b504601Sjiang wu - Sun Microsystems - Beijing China &reply->IOCStatus); 5455b504601Sjiang wu - Sun Microsystems - Beijing China iocstatus = MPTSAS_IOCSTATUS(iocstatus); 5465b504601Sjiang wu - Sun Microsystems - Beijing China iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 5475b504601Sjiang wu - Sun Microsystems - Beijing China &reply->IOCLogInfo); 5485b504601Sjiang wu - Sun Microsystems - Beijing China } 5495b504601Sjiang wu - Sun Microsystems - Beijing China 5505b504601Sjiang wu - Sun Microsystems - Beijing China if (callback(mpt, page_memp, accessp, iocstatus, iocloginfo, ap)) { 5515b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 5525b504601Sjiang wu - Sun Microsystems - Beijing China goto page_done; 5535b504601Sjiang wu - Sun Microsystems - Beijing China } 5545b504601Sjiang wu - Sun Microsystems - Beijing China 5555b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_fma_check(mpt, cmd); 5565b504601Sjiang wu - Sun Microsystems - Beijing China /* 5575b504601Sjiang wu - Sun Microsystems - Beijing China * Check the DMA/ACC handles and then free the DMA buffer. 5585b504601Sjiang wu - Sun Microsystems - Beijing China */ 5595b504601Sjiang wu - Sun Microsystems - Beijing China if ((mptsas_check_dma_handle(cmd->cmd_dmahandle) != DDI_SUCCESS) || 5605b504601Sjiang wu - Sun Microsystems - Beijing China (mptsas_check_acc_handle(accessp) != DDI_SUCCESS)) { 5615b504601Sjiang wu - Sun Microsystems - Beijing China ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 5625b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 5635b504601Sjiang wu - Sun Microsystems - Beijing China } 5645b504601Sjiang wu - Sun Microsystems - Beijing China 5655b504601Sjiang wu - Sun Microsystems - Beijing China if (pkt->pkt_reason == CMD_TRAN_ERR) { 5665b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "config fma error"); 5675b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 5685b504601Sjiang wu - Sun Microsystems - Beijing China goto page_done; 5695b504601Sjiang wu - Sun Microsystems - Beijing China } 5705b504601Sjiang wu - Sun Microsystems - Beijing China if (pkt->pkt_reason == CMD_RESET) { 5715b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "ioc reset abort config request"); 5725b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 5735b504601Sjiang wu - Sun Microsystems - Beijing China goto page_done; 5745b504601Sjiang wu - Sun Microsystems - Beijing China } 5755b504601Sjiang wu - Sun Microsystems - Beijing China 5765b504601Sjiang wu - Sun Microsystems - Beijing China page_done: 5775b504601Sjiang wu - Sun Microsystems - Beijing China va_end(ap); 5785b504601Sjiang wu - Sun Microsystems - Beijing China /* 5795b504601Sjiang wu - Sun Microsystems - Beijing China * Put the reply frame back on the free queue, increment the free 5805b504601Sjiang wu - Sun Microsystems - Beijing China * index, and write the new index to the free index register. But only 5815b504601Sjiang wu - Sun Microsystems - Beijing China * if this reply is an ADDRESS reply. 5825b504601Sjiang wu - Sun Microsystems - Beijing China */ 5835b504601Sjiang wu - Sun Microsystems - Beijing China if (config_flags & MPTSAS_ADDRESS_REPLY) { 5845b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_acc_free_queue_hdl, 58508eb0b82SYong-Feng Du &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 5865b504601Sjiang wu - Sun Microsystems - Beijing China cmd->cmd_rfm); 5875b504601Sjiang wu - Sun Microsystems - Beijing China (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 5885b504601Sjiang wu - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV); 58908eb0b82SYong-Feng Du if (++mpt->m_free_index == mpt->m_free_queue_depth) { 59008eb0b82SYong-Feng Du mpt->m_free_index = 0; 5915b504601Sjiang wu - Sun Microsystems - Beijing China } 5925b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 59308eb0b82SYong-Feng Du mpt->m_free_index); 5945b504601Sjiang wu - Sun Microsystems - Beijing China } 5955b504601Sjiang wu - Sun Microsystems - Beijing China 596f7d0d869SDan McDonald if (free_dma) 597f7d0d869SDan McDonald mptsas_dma_addr_destroy(&cmd->cmd_dmahandle, &accessp); 5985b504601Sjiang wu - Sun Microsystems - Beijing China 5995b504601Sjiang wu - Sun Microsystems - Beijing China if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { 6005b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_remove_cmd(mpt, cmd); 6015b504601Sjiang wu - Sun Microsystems - Beijing China config_flags &= (~MPTSAS_REQUEST_POOL_CMD); 6025b504601Sjiang wu - Sun Microsystems - Beijing China } 6035b504601Sjiang wu - Sun Microsystems - Beijing China if (config_flags & MPTSAS_REQUEST_POOL_CMD) 6045b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_return_to_pool(mpt, cmd); 6055b504601Sjiang wu - Sun Microsystems - Beijing China 6065b504601Sjiang wu - Sun Microsystems - Beijing China if (config_flags & MPTSAS_CMD_TIMEOUT) { 607a9b51062SAda mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 6085b504601Sjiang wu - Sun Microsystems - Beijing China if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 6095b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed"); 6105b504601Sjiang wu - Sun Microsystems - Beijing China } 6115b504601Sjiang wu - Sun Microsystems - Beijing China } 6125b504601Sjiang wu - Sun Microsystems - Beijing China 6135b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 6145b504601Sjiang wu - Sun Microsystems - Beijing China } 6155b504601Sjiang wu - Sun Microsystems - Beijing China 6165b504601Sjiang wu - Sun Microsystems - Beijing China int 6175b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_send_config_request_msg(mptsas_t *mpt, uint8_t action, uint8_t pagetype, 61815ada8fcSRobert Mustacchi uint32_t pageaddress, uint8_t pagenumber, uint8_t pageversion, 61915ada8fcSRobert Mustacchi uint8_t pagelength, uint32_t SGEflagslength, uint64_t SGEaddress) 6205b504601Sjiang wu - Sun Microsystems - Beijing China { 6215b504601Sjiang wu - Sun Microsystems - Beijing China pMpi2ConfigRequest_t config; 6225b504601Sjiang wu - Sun Microsystems - Beijing China int send_numbytes; 6235b504601Sjiang wu - Sun Microsystems - Beijing China 6245b504601Sjiang wu - Sun Microsystems - Beijing China bzero(mpt->m_hshk_memp, sizeof (MPI2_CONFIG_REQUEST)); 6255b504601Sjiang wu - Sun Microsystems - Beijing China config = (pMpi2ConfigRequest_t)mpt->m_hshk_memp; 6265b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_hshk_acc_hdl, &config->Function, MPI2_FUNCTION_CONFIG); 6275b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_hshk_acc_hdl, &config->Action, action); 6285b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageNumber, pagenumber); 6295b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageType, pagetype); 6305b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_hshk_acc_hdl, &config->PageAddress, pageaddress); 6315b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageVersion, pageversion); 6325b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageLength, pagelength); 6335b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_hshk_acc_hdl, 6345b504601Sjiang wu - Sun Microsystems - Beijing China &config->PageBufferSGE.MpiSimple.FlagsLength, SGEflagslength); 6355b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_hshk_acc_hdl, 636940efceeSAndy Giles &config->PageBufferSGE.MpiSimple.u.Address64.Low, SGEaddress); 637940efceeSAndy Giles ddi_put32(mpt->m_hshk_acc_hdl, 638940efceeSAndy Giles &config->PageBufferSGE.MpiSimple.u.Address64.High, 639940efceeSAndy Giles SGEaddress >> 32); 6405b504601Sjiang wu - Sun Microsystems - Beijing China send_numbytes = sizeof (MPI2_CONFIG_REQUEST); 6415b504601Sjiang wu - Sun Microsystems - Beijing China 6425b504601Sjiang wu - Sun Microsystems - Beijing China /* 6435b504601Sjiang wu - Sun Microsystems - Beijing China * Post message via handshake 6445b504601Sjiang wu - Sun Microsystems - Beijing China */ 6455b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_send_handshake_msg(mpt, (caddr_t)config, send_numbytes, 6465b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_hshk_acc_hdl)) { 6475b504601Sjiang wu - Sun Microsystems - Beijing China return (-1); 6485b504601Sjiang wu - Sun Microsystems - Beijing China } 6495b504601Sjiang wu - Sun Microsystems - Beijing China return (0); 6505b504601Sjiang wu - Sun Microsystems - Beijing China } 6515b504601Sjiang wu - Sun Microsystems - Beijing China 6525b504601Sjiang wu - Sun Microsystems - Beijing China int 6535b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_send_extended_config_request_msg(mptsas_t *mpt, uint8_t action, 65415ada8fcSRobert Mustacchi uint8_t extpagetype, uint32_t pageaddress, uint8_t pagenumber, 65515ada8fcSRobert Mustacchi uint8_t pageversion, uint16_t extpagelength, 65615ada8fcSRobert Mustacchi uint32_t SGEflagslength, uint64_t SGEaddress) 6575b504601Sjiang wu - Sun Microsystems - Beijing China { 6585b504601Sjiang wu - Sun Microsystems - Beijing China pMpi2ConfigRequest_t config; 6595b504601Sjiang wu - Sun Microsystems - Beijing China int send_numbytes; 6605b504601Sjiang wu - Sun Microsystems - Beijing China 6615b504601Sjiang wu - Sun Microsystems - Beijing China bzero(mpt->m_hshk_memp, sizeof (MPI2_CONFIG_REQUEST)); 6625b504601Sjiang wu - Sun Microsystems - Beijing China config = (pMpi2ConfigRequest_t)mpt->m_hshk_memp; 6635b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_hshk_acc_hdl, &config->Function, MPI2_FUNCTION_CONFIG); 6645b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_hshk_acc_hdl, &config->Action, action); 6655b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageNumber, pagenumber); 6665b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageType, 6675b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_CONFIG_PAGETYPE_EXTENDED); 6685b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_hshk_acc_hdl, &config->ExtPageType, extpagetype); 6695b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_hshk_acc_hdl, &config->PageAddress, pageaddress); 6705b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageVersion, pageversion); 6715b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put16(mpt->m_hshk_acc_hdl, &config->ExtPageLength, extpagelength); 6725b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_hshk_acc_hdl, 6735b504601Sjiang wu - Sun Microsystems - Beijing China &config->PageBufferSGE.MpiSimple.FlagsLength, SGEflagslength); 6745b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_hshk_acc_hdl, 675940efceeSAndy Giles &config->PageBufferSGE.MpiSimple.u.Address64.Low, SGEaddress); 676940efceeSAndy Giles ddi_put32(mpt->m_hshk_acc_hdl, 677940efceeSAndy Giles &config->PageBufferSGE.MpiSimple.u.Address64.High, 678940efceeSAndy Giles SGEaddress >> 32); 6795b504601Sjiang wu - Sun Microsystems - Beijing China send_numbytes = sizeof (MPI2_CONFIG_REQUEST); 6805b504601Sjiang wu - Sun Microsystems - Beijing China 6815b504601Sjiang wu - Sun Microsystems - Beijing China /* 6825b504601Sjiang wu - Sun Microsystems - Beijing China * Post message via handshake 6835b504601Sjiang wu - Sun Microsystems - Beijing China */ 6845b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_send_handshake_msg(mpt, (caddr_t)config, send_numbytes, 6855b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_hshk_acc_hdl)) { 6865b504601Sjiang wu - Sun Microsystems - Beijing China return (-1); 6875b504601Sjiang wu - Sun Microsystems - Beijing China } 6885b504601Sjiang wu - Sun Microsystems - Beijing China return (0); 6895b504601Sjiang wu - Sun Microsystems - Beijing China } 6905b504601Sjiang wu - Sun Microsystems - Beijing China 6915b504601Sjiang wu - Sun Microsystems - Beijing China int 6925b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_wait_for_response(mptsas_t *mpt) 6935b504601Sjiang wu - Sun Microsystems - Beijing China { 6945b504601Sjiang wu - Sun Microsystems - Beijing China int polls = 0; 6955b504601Sjiang wu - Sun Microsystems - Beijing China 6965b504601Sjiang wu - Sun Microsystems - Beijing China while ((ddi_get32(mpt->m_datap, 6975b504601Sjiang wu - Sun Microsystems - Beijing China &mpt->m_reg->HostInterruptStatus) & MPI2_HIS_IOP_DOORBELL_STATUS)) { 6985b504601Sjiang wu - Sun Microsystems - Beijing China drv_usecwait(1000); 6995b504601Sjiang wu - Sun Microsystems - Beijing China if (polls++ > 60000) { 7005b504601Sjiang wu - Sun Microsystems - Beijing China return (-1); 7015b504601Sjiang wu - Sun Microsystems - Beijing China } 7025b504601Sjiang wu - Sun Microsystems - Beijing China } 7035b504601Sjiang wu - Sun Microsystems - Beijing China return (0); 7045b504601Sjiang wu - Sun Microsystems - Beijing China } 7055b504601Sjiang wu - Sun Microsystems - Beijing China 7065b504601Sjiang wu - Sun Microsystems - Beijing China int 7075b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_wait_for_doorbell(mptsas_t *mpt) 7085b504601Sjiang wu - Sun Microsystems - Beijing China { 7095b504601Sjiang wu - Sun Microsystems - Beijing China int polls = 0; 7105b504601Sjiang wu - Sun Microsystems - Beijing China 7115b504601Sjiang wu - Sun Microsystems - Beijing China while ((ddi_get32(mpt->m_datap, 7125b504601Sjiang wu - Sun Microsystems - Beijing China &mpt->m_reg->HostInterruptStatus) & MPI2_HIM_DIM) == 0) { 7135b504601Sjiang wu - Sun Microsystems - Beijing China drv_usecwait(1000); 7145b504601Sjiang wu - Sun Microsystems - Beijing China if (polls++ > 300000) { 7155b504601Sjiang wu - Sun Microsystems - Beijing China return (-1); 7165b504601Sjiang wu - Sun Microsystems - Beijing China } 7175b504601Sjiang wu - Sun Microsystems - Beijing China } 7185b504601Sjiang wu - Sun Microsystems - Beijing China return (0); 7195b504601Sjiang wu - Sun Microsystems - Beijing China } 7205b504601Sjiang wu - Sun Microsystems - Beijing China 7215b504601Sjiang wu - Sun Microsystems - Beijing China int 7225b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_send_handshake_msg(mptsas_t *mpt, caddr_t memp, int numbytes, 72315ada8fcSRobert Mustacchi ddi_acc_handle_t accessp) 7245b504601Sjiang wu - Sun Microsystems - Beijing China { 7255b504601Sjiang wu - Sun Microsystems - Beijing China int i; 7265b504601Sjiang wu - Sun Microsystems - Beijing China 7275b504601Sjiang wu - Sun Microsystems - Beijing China /* 7285b504601Sjiang wu - Sun Microsystems - Beijing China * clean pending doorbells 7295b504601Sjiang wu - Sun Microsystems - Beijing China */ 7305b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptStatus, 0); 7315b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_datap, &mpt->m_reg->Doorbell, 7325b504601Sjiang wu - Sun Microsystems - Beijing China ((MPI2_FUNCTION_HANDSHAKE << MPI2_DOORBELL_FUNCTION_SHIFT) | 7335b504601Sjiang wu - Sun Microsystems - Beijing China ((numbytes / 4) << MPI2_DOORBELL_ADD_DWORDS_SHIFT))); 7345b504601Sjiang wu - Sun Microsystems - Beijing China 7355b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_ioc_wait_for_doorbell(mpt)) { 7365b504601Sjiang wu - Sun Microsystems - Beijing China NDBG19(("mptsas_send_handshake failed. Doorbell not ready\n")); 7375b504601Sjiang wu - Sun Microsystems - Beijing China return (-1); 7385b504601Sjiang wu - Sun Microsystems - Beijing China } 7395b504601Sjiang wu - Sun Microsystems - Beijing China 7405b504601Sjiang wu - Sun Microsystems - Beijing China /* 7415b504601Sjiang wu - Sun Microsystems - Beijing China * clean pending doorbells again 7425b504601Sjiang wu - Sun Microsystems - Beijing China */ 7435b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptStatus, 0); 7445b504601Sjiang wu - Sun Microsystems - Beijing China 7455b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_ioc_wait_for_response(mpt)) { 7465b504601Sjiang wu - Sun Microsystems - Beijing China NDBG19(("mptsas_send_handshake failed. Doorbell not " 7475b504601Sjiang wu - Sun Microsystems - Beijing China "cleared\n")); 7485b504601Sjiang wu - Sun Microsystems - Beijing China return (-1); 7495b504601Sjiang wu - Sun Microsystems - Beijing China } 7505b504601Sjiang wu - Sun Microsystems - Beijing China 7515b504601Sjiang wu - Sun Microsystems - Beijing China /* 7525b504601Sjiang wu - Sun Microsystems - Beijing China * post handshake message 7535b504601Sjiang wu - Sun Microsystems - Beijing China */ 7545b504601Sjiang wu - Sun Microsystems - Beijing China for (i = 0; (i < numbytes / 4); i++, memp += 4) { 7555b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_datap, &mpt->m_reg->Doorbell, 7565b504601Sjiang wu - Sun Microsystems - Beijing China ddi_get32(accessp, (uint32_t *)((void *)(memp)))); 7575b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_ioc_wait_for_response(mpt)) { 7585b504601Sjiang wu - Sun Microsystems - Beijing China NDBG19(("mptsas_send_handshake failed posting " 7595b504601Sjiang wu - Sun Microsystems - Beijing China "message\n")); 7605b504601Sjiang wu - Sun Microsystems - Beijing China return (-1); 7615b504601Sjiang wu - Sun Microsystems - Beijing China } 7625b504601Sjiang wu - Sun Microsystems - Beijing China } 7635b504601Sjiang wu - Sun Microsystems - Beijing China 7645b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) { 7655b504601Sjiang wu - Sun Microsystems - Beijing China ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 7665b504601Sjiang wu - Sun Microsystems - Beijing China ddi_fm_acc_err_clear(mpt->m_datap, DDI_FME_VER0); 7675b504601Sjiang wu - Sun Microsystems - Beijing China return (-1); 7685b504601Sjiang wu - Sun Microsystems - Beijing China } 7695b504601Sjiang wu - Sun Microsystems - Beijing China 7705b504601Sjiang wu - Sun Microsystems - Beijing China return (0); 7715b504601Sjiang wu - Sun Microsystems - Beijing China } 7725b504601Sjiang wu - Sun Microsystems - Beijing China 7735b504601Sjiang wu - Sun Microsystems - Beijing China int 7745b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_handshake_msg(mptsas_t *mpt, caddr_t memp, int numbytes, 77515ada8fcSRobert Mustacchi ddi_acc_handle_t accessp) 7765b504601Sjiang wu - Sun Microsystems - Beijing China { 7775b504601Sjiang wu - Sun Microsystems - Beijing China int i, totalbytes, bytesleft; 7785b504601Sjiang wu - Sun Microsystems - Beijing China uint16_t val; 7795b504601Sjiang wu - Sun Microsystems - Beijing China 7805b504601Sjiang wu - Sun Microsystems - Beijing China /* 7815b504601Sjiang wu - Sun Microsystems - Beijing China * wait for doorbell 7825b504601Sjiang wu - Sun Microsystems - Beijing China */ 7835b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_ioc_wait_for_doorbell(mpt)) { 7845b504601Sjiang wu - Sun Microsystems - Beijing China NDBG19(("mptsas_get_handshake failed. Doorbell not ready\n")); 7855b504601Sjiang wu - Sun Microsystems - Beijing China return (-1); 7865b504601Sjiang wu - Sun Microsystems - Beijing China } 7875b504601Sjiang wu - Sun Microsystems - Beijing China 7885b504601Sjiang wu - Sun Microsystems - Beijing China /* 7895b504601Sjiang wu - Sun Microsystems - Beijing China * get first 2 bytes of handshake message to determine how much 7905b504601Sjiang wu - Sun Microsystems - Beijing China * data we will be getting 7915b504601Sjiang wu - Sun Microsystems - Beijing China */ 7925b504601Sjiang wu - Sun Microsystems - Beijing China for (i = 0; i < 2; i++, memp += 2) { 7935b504601Sjiang wu - Sun Microsystems - Beijing China val = (ddi_get32(mpt->m_datap, 7945b504601Sjiang wu - Sun Microsystems - Beijing China &mpt->m_reg->Doorbell) & MPI2_DOORBELL_DATA_MASK); 7955b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptStatus, 0); 7965b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_ioc_wait_for_doorbell(mpt)) { 7975b504601Sjiang wu - Sun Microsystems - Beijing China NDBG19(("mptsas_get_handshake failure getting initial" 7985b504601Sjiang wu - Sun Microsystems - Beijing China " data\n")); 7995b504601Sjiang wu - Sun Microsystems - Beijing China return (-1); 8005b504601Sjiang wu - Sun Microsystems - Beijing China } 8015b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put16(accessp, (uint16_t *)((void *)(memp)), val); 8025b504601Sjiang wu - Sun Microsystems - Beijing China if (i == 1) { 8035b504601Sjiang wu - Sun Microsystems - Beijing China totalbytes = (val & 0xFF) * 2; 8045b504601Sjiang wu - Sun Microsystems - Beijing China } 8055b504601Sjiang wu - Sun Microsystems - Beijing China } 8065b504601Sjiang wu - Sun Microsystems - Beijing China 8075b504601Sjiang wu - Sun Microsystems - Beijing China /* 8085b504601Sjiang wu - Sun Microsystems - Beijing China * If we are expecting less bytes than the message wants to send 8095b504601Sjiang wu - Sun Microsystems - Beijing China * we simply save as much as we expected and then throw out the rest 8105b504601Sjiang wu - Sun Microsystems - Beijing China * later 8115b504601Sjiang wu - Sun Microsystems - Beijing China */ 8125b504601Sjiang wu - Sun Microsystems - Beijing China if (totalbytes > (numbytes / 2)) { 8135b504601Sjiang wu - Sun Microsystems - Beijing China bytesleft = ((numbytes / 2) - 2); 8145b504601Sjiang wu - Sun Microsystems - Beijing China } else { 8155b504601Sjiang wu - Sun Microsystems - Beijing China bytesleft = (totalbytes - 2); 8165b504601Sjiang wu - Sun Microsystems - Beijing China } 8175b504601Sjiang wu - Sun Microsystems - Beijing China 8185b504601Sjiang wu - Sun Microsystems - Beijing China /* 8195b504601Sjiang wu - Sun Microsystems - Beijing China * Get the rest of the data 8205b504601Sjiang wu - Sun Microsystems - Beijing China */ 8215b504601Sjiang wu - Sun Microsystems - Beijing China for (i = 0; i < bytesleft; i++, memp += 2) { 8225b504601Sjiang wu - Sun Microsystems - Beijing China val = (ddi_get32(mpt->m_datap, 8235b504601Sjiang wu - Sun Microsystems - Beijing China &mpt->m_reg->Doorbell) & MPI2_DOORBELL_DATA_MASK); 8245b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptStatus, 0); 8255b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_ioc_wait_for_doorbell(mpt)) { 8265b504601Sjiang wu - Sun Microsystems - Beijing China NDBG19(("mptsas_get_handshake failure getting" 8275b504601Sjiang wu - Sun Microsystems - Beijing China " main data\n")); 8285b504601Sjiang wu - Sun Microsystems - Beijing China return (-1); 8295b504601Sjiang wu - Sun Microsystems - Beijing China } 8305b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put16(accessp, (uint16_t *)((void *)(memp)), val); 8315b504601Sjiang wu - Sun Microsystems - Beijing China } 8325b504601Sjiang wu - Sun Microsystems - Beijing China 8335b504601Sjiang wu - Sun Microsystems - Beijing China /* 8345b504601Sjiang wu - Sun Microsystems - Beijing China * Sometimes the device will send more data than is expected 8355b504601Sjiang wu - Sun Microsystems - Beijing China * This data is not used by us but needs to be cleared from 8365b504601Sjiang wu - Sun Microsystems - Beijing China * ioc doorbell. So we just read the values and throw 8375b504601Sjiang wu - Sun Microsystems - Beijing China * them out. 8385b504601Sjiang wu - Sun Microsystems - Beijing China */ 8395b504601Sjiang wu - Sun Microsystems - Beijing China if (totalbytes > (numbytes / 2)) { 8405b504601Sjiang wu - Sun Microsystems - Beijing China for (i = (numbytes / 2); i < totalbytes; i++) { 8415b504601Sjiang wu - Sun Microsystems - Beijing China val = (ddi_get32(mpt->m_datap, 8425b504601Sjiang wu - Sun Microsystems - Beijing China &mpt->m_reg->Doorbell) & 8435b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_DOORBELL_DATA_MASK); 8445b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_datap, 8455b504601Sjiang wu - Sun Microsystems - Beijing China &mpt->m_reg->HostInterruptStatus, 0); 8465b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_ioc_wait_for_doorbell(mpt)) { 8475b504601Sjiang wu - Sun Microsystems - Beijing China NDBG19(("mptsas_get_handshake failure getting " 8485b504601Sjiang wu - Sun Microsystems - Beijing China "extra garbage data\n")); 8495b504601Sjiang wu - Sun Microsystems - Beijing China return (-1); 8505b504601Sjiang wu - Sun Microsystems - Beijing China } 8515b504601Sjiang wu - Sun Microsystems - Beijing China } 8525b504601Sjiang wu - Sun Microsystems - Beijing China } 8535b504601Sjiang wu - Sun Microsystems - Beijing China 8545b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptStatus, 0); 8555b504601Sjiang wu - Sun Microsystems - Beijing China 8565b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) { 8575b504601Sjiang wu - Sun Microsystems - Beijing China ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8585b504601Sjiang wu - Sun Microsystems - Beijing China ddi_fm_acc_err_clear(mpt->m_datap, DDI_FME_VER0); 8595b504601Sjiang wu - Sun Microsystems - Beijing China return (-1); 8605b504601Sjiang wu - Sun Microsystems - Beijing China } 8615b504601Sjiang wu - Sun Microsystems - Beijing China 8625b504601Sjiang wu - Sun Microsystems - Beijing China return (0); 8635b504601Sjiang wu - Sun Microsystems - Beijing China } 8645b504601Sjiang wu - Sun Microsystems - Beijing China 8655b504601Sjiang wu - Sun Microsystems - Beijing China int 8665b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_kick_start(mptsas_t *mpt) 8675b504601Sjiang wu - Sun Microsystems - Beijing China { 8685b504601Sjiang wu - Sun Microsystems - Beijing China int polls = 0; 8695b504601Sjiang wu - Sun Microsystems - Beijing China uint32_t diag_reg, ioc_state, saved_HCB_size; 8705b504601Sjiang wu - Sun Microsystems - Beijing China 8715b504601Sjiang wu - Sun Microsystems - Beijing China /* 8722856b5e3SAda * Start a hard reset. Write magic number and wait 500 mSeconds. 8735b504601Sjiang wu - Sun Microsystems - Beijing China */ 8745b504601Sjiang wu - Sun Microsystems - Beijing China MPTSAS_ENABLE_DRWE(mpt); 8752856b5e3SAda drv_usecwait(500000); 8765b504601Sjiang wu - Sun Microsystems - Beijing China 8775b504601Sjiang wu - Sun Microsystems - Beijing China /* 8785b504601Sjiang wu - Sun Microsystems - Beijing China * Read the current Diag Reg and save the Host Controlled Boot size. 8795b504601Sjiang wu - Sun Microsystems - Beijing China */ 8805b504601Sjiang wu - Sun Microsystems - Beijing China diag_reg = ddi_get32(mpt->m_datap, &mpt->m_reg->HostDiagnostic); 8815b504601Sjiang wu - Sun Microsystems - Beijing China saved_HCB_size = ddi_get32(mpt->m_datap, &mpt->m_reg->HCBSize); 8825b504601Sjiang wu - Sun Microsystems - Beijing China 8835b504601Sjiang wu - Sun Microsystems - Beijing China /* 88476a4caf6SAda * Set Reset Adapter bit and wait 50 mSeconds. 8855b504601Sjiang wu - Sun Microsystems - Beijing China */ 8865b504601Sjiang wu - Sun Microsystems - Beijing China diag_reg |= MPI2_DIAG_RESET_ADAPTER; 8875b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_datap, &mpt->m_reg->HostDiagnostic, diag_reg); 88876a4caf6SAda drv_usecwait(50000); 8895b504601Sjiang wu - Sun Microsystems - Beijing China 8905b504601Sjiang wu - Sun Microsystems - Beijing China /* 8915b504601Sjiang wu - Sun Microsystems - Beijing China * Poll, waiting for Reset Adapter bit to clear. 300 Seconds max 8925b504601Sjiang wu - Sun Microsystems - Beijing China * (600000 * 500 = 300,000,000 uSeconds, 300 seconds). 8935b504601Sjiang wu - Sun Microsystems - Beijing China * If no more adapter (all FF's), just return failure. 8945b504601Sjiang wu - Sun Microsystems - Beijing China */ 8955b504601Sjiang wu - Sun Microsystems - Beijing China for (polls = 0; polls < 600000; polls++) { 8965b504601Sjiang wu - Sun Microsystems - Beijing China diag_reg = ddi_get32(mpt->m_datap, 8975b504601Sjiang wu - Sun Microsystems - Beijing China &mpt->m_reg->HostDiagnostic); 8985b504601Sjiang wu - Sun Microsystems - Beijing China if (diag_reg == 0xFFFFFFFF) { 8995b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); 9005b504601Sjiang wu - Sun Microsystems - Beijing China ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); 9015b504601Sjiang wu - Sun Microsystems - Beijing China return (DDI_FAILURE); 9025b504601Sjiang wu - Sun Microsystems - Beijing China } 9035b504601Sjiang wu - Sun Microsystems - Beijing China if (!(diag_reg & MPI2_DIAG_RESET_ADAPTER)) { 9045b504601Sjiang wu - Sun Microsystems - Beijing China break; 9055b504601Sjiang wu - Sun Microsystems - Beijing China } 9065b504601Sjiang wu - Sun Microsystems - Beijing China drv_usecwait(500); 9075b504601Sjiang wu - Sun Microsystems - Beijing China } 9085b504601Sjiang wu - Sun Microsystems - Beijing China if (polls == 600000) { 9095b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); 9105b504601Sjiang wu - Sun Microsystems - Beijing China ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); 9115b504601Sjiang wu - Sun Microsystems - Beijing China return (DDI_FAILURE); 9125b504601Sjiang wu - Sun Microsystems - Beijing China } 9135b504601Sjiang wu - Sun Microsystems - Beijing China 9145b504601Sjiang wu - Sun Microsystems - Beijing China /* 9155b504601Sjiang wu - Sun Microsystems - Beijing China * Check if adapter is in Host Boot Mode. If so, restart adapter 9165b504601Sjiang wu - Sun Microsystems - Beijing China * assuming the HCB points to good FW. 9175b504601Sjiang wu - Sun Microsystems - Beijing China * Set BootDeviceSel to HCDW (Host Code and Data Window). 9185b504601Sjiang wu - Sun Microsystems - Beijing China */ 9195b504601Sjiang wu - Sun Microsystems - Beijing China if (diag_reg & MPI2_DIAG_HCB_MODE) { 9205b504601Sjiang wu - Sun Microsystems - Beijing China diag_reg &= ~MPI2_DIAG_BOOT_DEVICE_SELECT_MASK; 9215b504601Sjiang wu - Sun Microsystems - Beijing China diag_reg |= MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW; 9225b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_datap, &mpt->m_reg->HostDiagnostic, diag_reg); 9235b504601Sjiang wu - Sun Microsystems - Beijing China 9245b504601Sjiang wu - Sun Microsystems - Beijing China /* 9255b504601Sjiang wu - Sun Microsystems - Beijing China * Re-enable the HCDW. 9265b504601Sjiang wu - Sun Microsystems - Beijing China */ 9275b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_datap, &mpt->m_reg->HCBSize, 9285b504601Sjiang wu - Sun Microsystems - Beijing China (saved_HCB_size | MPI2_HCB_SIZE_HCB_ENABLE)); 9295b504601Sjiang wu - Sun Microsystems - Beijing China } 9305b504601Sjiang wu - Sun Microsystems - Beijing China 9315b504601Sjiang wu - Sun Microsystems - Beijing China /* 9325b504601Sjiang wu - Sun Microsystems - Beijing China * Restart the adapter. 9335b504601Sjiang wu - Sun Microsystems - Beijing China */ 9345b504601Sjiang wu - Sun Microsystems - Beijing China diag_reg &= ~MPI2_DIAG_HOLD_IOC_RESET; 9355b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_datap, &mpt->m_reg->HostDiagnostic, diag_reg); 9365b504601Sjiang wu - Sun Microsystems - Beijing China 9375b504601Sjiang wu - Sun Microsystems - Beijing China /* 9385b504601Sjiang wu - Sun Microsystems - Beijing China * Disable writes to the Host Diag register. 9395b504601Sjiang wu - Sun Microsystems - Beijing China */ 9405b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put32(mpt->m_datap, &mpt->m_reg->WriteSequence, 9415b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_WRSEQ_FLUSH_KEY_VALUE); 9425b504601Sjiang wu - Sun Microsystems - Beijing China 9435b504601Sjiang wu - Sun Microsystems - Beijing China /* 94476a4caf6SAda * Wait 60 seconds max for FW to come to ready state. 9455b504601Sjiang wu - Sun Microsystems - Beijing China */ 94676a4caf6SAda for (polls = 0; polls < 60000; polls++) { 9475b504601Sjiang wu - Sun Microsystems - Beijing China ioc_state = ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell); 9485b504601Sjiang wu - Sun Microsystems - Beijing China if (ioc_state == 0xFFFFFFFF) { 9495b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); 9505b504601Sjiang wu - Sun Microsystems - Beijing China ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); 9515b504601Sjiang wu - Sun Microsystems - Beijing China return (DDI_FAILURE); 9525b504601Sjiang wu - Sun Microsystems - Beijing China } 9535b504601Sjiang wu - Sun Microsystems - Beijing China if ((ioc_state & MPI2_IOC_STATE_MASK) == 9545b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_IOC_STATE_READY) { 9555b504601Sjiang wu - Sun Microsystems - Beijing China break; 9565b504601Sjiang wu - Sun Microsystems - Beijing China } 9575b504601Sjiang wu - Sun Microsystems - Beijing China drv_usecwait(1000); 9585b504601Sjiang wu - Sun Microsystems - Beijing China } 95976a4caf6SAda if (polls == 60000) { 9605b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); 9615b504601Sjiang wu - Sun Microsystems - Beijing China ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); 9625b504601Sjiang wu - Sun Microsystems - Beijing China return (DDI_FAILURE); 9635b504601Sjiang wu - Sun Microsystems - Beijing China } 9645b504601Sjiang wu - Sun Microsystems - Beijing China 9655b504601Sjiang wu - Sun Microsystems - Beijing China /* 9665b504601Sjiang wu - Sun Microsystems - Beijing China * Clear the ioc ack events queue. 9675b504601Sjiang wu - Sun Microsystems - Beijing China */ 9685b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_destroy_ioc_event_cmd(mpt); 9695b504601Sjiang wu - Sun Microsystems - Beijing China 9705b504601Sjiang wu - Sun Microsystems - Beijing China return (DDI_SUCCESS); 9715b504601Sjiang wu - Sun Microsystems - Beijing China } 9725b504601Sjiang wu - Sun Microsystems - Beijing China 9735b504601Sjiang wu - Sun Microsystems - Beijing China int 974e18306b1SDan McDonald mptsas_ioc_reset(mptsas_t *mpt, int first_time) 9755b504601Sjiang wu - Sun Microsystems - Beijing China { 9765b504601Sjiang wu - Sun Microsystems - Beijing China int polls = 0; 9775b504601Sjiang wu - Sun Microsystems - Beijing China uint32_t reset_msg; 9785b504601Sjiang wu - Sun Microsystems - Beijing China uint32_t ioc_state; 979a9b51062SAda 9805b504601Sjiang wu - Sun Microsystems - Beijing China ioc_state = ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell); 9815b504601Sjiang wu - Sun Microsystems - Beijing China /* 9825b504601Sjiang wu - Sun Microsystems - Beijing China * If chip is already in ready state then there is nothing to do. 9835b504601Sjiang wu - Sun Microsystems - Beijing China */ 9845b504601Sjiang wu - Sun Microsystems - Beijing China if (ioc_state == MPI2_IOC_STATE_READY) { 9855b504601Sjiang wu - Sun Microsystems - Beijing China return (MPTSAS_NO_RESET); 9865b504601Sjiang wu - Sun Microsystems - Beijing China } 9875b504601Sjiang wu - Sun Microsystems - Beijing China /* 9885b504601Sjiang wu - Sun Microsystems - Beijing China * If the chip is already operational, we just need to send 9895b504601Sjiang wu - Sun Microsystems - Beijing China * it a message unit reset to put it back in the ready state 9905b504601Sjiang wu - Sun Microsystems - Beijing China */ 9915b504601Sjiang wu - Sun Microsystems - Beijing China if (ioc_state & MPI2_IOC_STATE_OPERATIONAL) { 992e18306b1SDan McDonald /* 993e18306b1SDan McDonald * If the first time, try MUR anyway, because we haven't even 994e18306b1SDan McDonald * queried the card for m_event_replay and other capabilities. 995e18306b1SDan McDonald * Other platforms do it this way, we can still do a hard 996e18306b1SDan McDonald * reset if we need to, MUR takes less time than a full 997e18306b1SDan McDonald * adapter reset, and there are reports that some HW 998e18306b1SDan McDonald * combinations will lock up when receiving a hard reset. 999e18306b1SDan McDonald */ 1000e18306b1SDan McDonald if ((first_time || mpt->m_event_replay) && 1001e18306b1SDan McDonald (mpt->m_softstate & MPTSAS_SS_MSG_UNIT_RESET)) { 1002a9b51062SAda mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 1003a9b51062SAda reset_msg = MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET; 1004a9b51062SAda ddi_put32(mpt->m_datap, &mpt->m_reg->Doorbell, 1005a9b51062SAda (reset_msg << MPI2_DOORBELL_FUNCTION_SHIFT)); 1006a9b51062SAda if (mptsas_ioc_wait_for_response(mpt)) { 1007a9b51062SAda NDBG19(("mptsas_ioc_reset failure sending " 1008a9b51062SAda "message_unit_reset\n")); 10095b504601Sjiang wu - Sun Microsystems - Beijing China goto hard_reset; 10105b504601Sjiang wu - Sun Microsystems - Beijing China } 1011a9b51062SAda 1012a9b51062SAda /* 1013a9b51062SAda * Wait no more than 60 seconds for chip to become 1014a9b51062SAda * ready. 1015a9b51062SAda */ 1016a9b51062SAda while ((ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell) & 1017a9b51062SAda MPI2_IOC_STATE_READY) == 0x0) { 1018a9b51062SAda drv_usecwait(1000); 1019a9b51062SAda if (polls++ > 60000) { 1020a9b51062SAda goto hard_reset; 1021a9b51062SAda } 1022a9b51062SAda } 1023a9b51062SAda 1024a9b51062SAda /* 1025a9b51062SAda * Save the last reset mode done on IOC which will be 1026a9b51062SAda * helpful while resuming from suspension. 1027a9b51062SAda */ 1028a9b51062SAda mpt->m_softstate |= MPTSAS_DID_MSG_UNIT_RESET; 1029a9b51062SAda 1030a9b51062SAda /* 1031a9b51062SAda * the message unit reset would do reset operations 1032a9b51062SAda * clear reply and request queue, so we should clear 1033a9b51062SAda * ACK event cmd. 1034a9b51062SAda */ 1035a9b51062SAda mptsas_destroy_ioc_event_cmd(mpt); 1036a9b51062SAda return (MPTSAS_SUCCESS_MUR); 10375b504601Sjiang wu - Sun Microsystems - Beijing China } 10385b504601Sjiang wu - Sun Microsystems - Beijing China } 10395b504601Sjiang wu - Sun Microsystems - Beijing China hard_reset: 1040a9b51062SAda mpt->m_softstate &= ~MPTSAS_DID_MSG_UNIT_RESET; 10415b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_kick_start(mpt) == DDI_FAILURE) { 10425b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); 10435b504601Sjiang wu - Sun Microsystems - Beijing China ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); 10445b504601Sjiang wu - Sun Microsystems - Beijing China return (MPTSAS_RESET_FAIL); 10455b504601Sjiang wu - Sun Microsystems - Beijing China } 10465b504601Sjiang wu - Sun Microsystems - Beijing China return (MPTSAS_SUCCESS_HARDRESET); 10475b504601Sjiang wu - Sun Microsystems - Beijing China } 10485b504601Sjiang wu - Sun Microsystems - Beijing China 10495b504601Sjiang wu - Sun Microsystems - Beijing China 10505b504601Sjiang wu - Sun Microsystems - Beijing China int 10515b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_request_from_pool(mptsas_t *mpt, mptsas_cmd_t **cmd, 10525b504601Sjiang wu - Sun Microsystems - Beijing China struct scsi_pkt **pkt) 10535b504601Sjiang wu - Sun Microsystems - Beijing China { 10545b504601Sjiang wu - Sun Microsystems - Beijing China m_event_struct_t *ioc_cmd = NULL; 10555b504601Sjiang wu - Sun Microsystems - Beijing China 10565b504601Sjiang wu - Sun Microsystems - Beijing China ioc_cmd = kmem_zalloc(M_EVENT_STRUCT_SIZE, KM_SLEEP); 10575b504601Sjiang wu - Sun Microsystems - Beijing China if (ioc_cmd == NULL) { 10585b504601Sjiang wu - Sun Microsystems - Beijing China return (DDI_FAILURE); 10595b504601Sjiang wu - Sun Microsystems - Beijing China } 10605b504601Sjiang wu - Sun Microsystems - Beijing China ioc_cmd->m_event_linkp = NULL; 10615b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_event_cmdq_add(mpt, ioc_cmd); 10625b504601Sjiang wu - Sun Microsystems - Beijing China *cmd = &(ioc_cmd->m_event_cmd); 10635b504601Sjiang wu - Sun Microsystems - Beijing China *pkt = &(ioc_cmd->m_event_pkt); 10645b504601Sjiang wu - Sun Microsystems - Beijing China 10655b504601Sjiang wu - Sun Microsystems - Beijing China return (DDI_SUCCESS); 10665b504601Sjiang wu - Sun Microsystems - Beijing China } 10675b504601Sjiang wu - Sun Microsystems - Beijing China 10685b504601Sjiang wu - Sun Microsystems - Beijing China void 10695b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_return_to_pool(mptsas_t *mpt, mptsas_cmd_t *cmd) 10705b504601Sjiang wu - Sun Microsystems - Beijing China { 10715b504601Sjiang wu - Sun Microsystems - Beijing China m_event_struct_t *ioc_cmd = NULL; 10725b504601Sjiang wu - Sun Microsystems - Beijing China 10735b504601Sjiang wu - Sun Microsystems - Beijing China ioc_cmd = mptsas_ioc_event_find_by_cmd(mpt, cmd); 10745b504601Sjiang wu - Sun Microsystems - Beijing China if (ioc_cmd == NULL) { 10755b504601Sjiang wu - Sun Microsystems - Beijing China return; 10765b504601Sjiang wu - Sun Microsystems - Beijing China } 10775b504601Sjiang wu - Sun Microsystems - Beijing China 10785b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_event_cmdq_delete(mpt, ioc_cmd); 10795b504601Sjiang wu - Sun Microsystems - Beijing China kmem_free(ioc_cmd, M_EVENT_STRUCT_SIZE); 10805b504601Sjiang wu - Sun Microsystems - Beijing China ioc_cmd = NULL; 10815b504601Sjiang wu - Sun Microsystems - Beijing China } 10825b504601Sjiang wu - Sun Microsystems - Beijing China 10835b504601Sjiang wu - Sun Microsystems - Beijing China /* 10845b504601Sjiang wu - Sun Microsystems - Beijing China * NOTE: We should be able to queue TM requests in the controller to make this 10855b504601Sjiang wu - Sun Microsystems - Beijing China * a lot faster. If resetting all targets, for example, we can load the hi 10865b504601Sjiang wu - Sun Microsystems - Beijing China * priority queue with its limit and the controller will reply as they are 10875b504601Sjiang wu - Sun Microsystems - Beijing China * completed. This way, we don't have to poll for one reply at a time. 10885b504601Sjiang wu - Sun Microsystems - Beijing China * Think about enhancing this later. 10895b504601Sjiang wu - Sun Microsystems - Beijing China */ 10905b504601Sjiang wu - Sun Microsystems - Beijing China int 10915b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_ioc_task_management(mptsas_t *mpt, int task_type, uint16_t dev_handle, 109215ada8fcSRobert Mustacchi int lun, uint8_t *reply, uint32_t reply_size, int mode) 10935b504601Sjiang wu - Sun Microsystems - Beijing China { 10945b504601Sjiang wu - Sun Microsystems - Beijing China /* 10955b504601Sjiang wu - Sun Microsystems - Beijing China * In order to avoid allocating variables on the stack, 10965b504601Sjiang wu - Sun Microsystems - Beijing China * we make use of the pre-existing mptsas_cmd_t and 10975b504601Sjiang wu - Sun Microsystems - Beijing China * scsi_pkt which are included in the mptsas_t which 10985b504601Sjiang wu - Sun Microsystems - Beijing China * is passed to this routine. 10995b504601Sjiang wu - Sun Microsystems - Beijing China */ 11005b504601Sjiang wu - Sun Microsystems - Beijing China 11015b504601Sjiang wu - Sun Microsystems - Beijing China pMpi2SCSITaskManagementRequest_t task; 11025b504601Sjiang wu - Sun Microsystems - Beijing China int rval = FALSE; 11035b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_cmd_t *cmd; 11045b504601Sjiang wu - Sun Microsystems - Beijing China struct scsi_pkt *pkt; 11055b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_slots_t *slots = mpt->m_active; 1106940efceeSAndy Giles uint64_t request_desc, i; 1107c8f74a56SAda pMPI2DefaultReply_t reply_msg; 11085b504601Sjiang wu - Sun Microsystems - Beijing China 11095b504601Sjiang wu - Sun Microsystems - Beijing China /* 11105b504601Sjiang wu - Sun Microsystems - Beijing China * Can't start another task management routine. 11115b504601Sjiang wu - Sun Microsystems - Beijing China */ 11125b504601Sjiang wu - Sun Microsystems - Beijing China if (slots->m_slot[MPTSAS_TM_SLOT(mpt)] != NULL) { 11135b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "Can only start 1 task management" 11145b504601Sjiang wu - Sun Microsystems - Beijing China " command at a time\n"); 11155b504601Sjiang wu - Sun Microsystems - Beijing China return (FALSE); 11165b504601Sjiang wu - Sun Microsystems - Beijing China } 11175b504601Sjiang wu - Sun Microsystems - Beijing China 11185b504601Sjiang wu - Sun Microsystems - Beijing China cmd = &(mpt->m_event_task_mgmt.m_event_cmd); 11195b504601Sjiang wu - Sun Microsystems - Beijing China pkt = &(mpt->m_event_task_mgmt.m_event_pkt); 11205b504601Sjiang wu - Sun Microsystems - Beijing China 11215b504601Sjiang wu - Sun Microsystems - Beijing China bzero((caddr_t)cmd, sizeof (*cmd)); 11225b504601Sjiang wu - Sun Microsystems - Beijing China bzero((caddr_t)pkt, scsi_pkt_size()); 11235b504601Sjiang wu - Sun Microsystems - Beijing China 11245b504601Sjiang wu - Sun Microsystems - Beijing China pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb[0]; 11255b504601Sjiang wu - Sun Microsystems - Beijing China pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb; 11265b504601Sjiang wu - Sun Microsystems - Beijing China pkt->pkt_ha_private = (opaque_t)cmd; 11275b504601Sjiang wu - Sun Microsystems - Beijing China pkt->pkt_flags = (FLAG_NOINTR | FLAG_HEAD); 11285b504601Sjiang wu - Sun Microsystems - Beijing China pkt->pkt_time = 60; 11295b504601Sjiang wu - Sun Microsystems - Beijing China pkt->pkt_address.a_target = dev_handle; 11305b504601Sjiang wu - Sun Microsystems - Beijing China pkt->pkt_address.a_lun = (uchar_t)lun; 11315b504601Sjiang wu - Sun Microsystems - Beijing China cmd->cmd_pkt = pkt; 11325b504601Sjiang wu - Sun Microsystems - Beijing China cmd->cmd_scblen = 1; 11335b504601Sjiang wu - Sun Microsystems - Beijing China cmd->cmd_flags = CFLAG_TM_CMD; 11345b504601Sjiang wu - Sun Microsystems - Beijing China cmd->cmd_slot = MPTSAS_TM_SLOT(mpt); 11355b504601Sjiang wu - Sun Microsystems - Beijing China 11365b504601Sjiang wu - Sun Microsystems - Beijing China slots->m_slot[MPTSAS_TM_SLOT(mpt)] = cmd; 11375b504601Sjiang wu - Sun Microsystems - Beijing China 11385b504601Sjiang wu - Sun Microsystems - Beijing China /* 11395b504601Sjiang wu - Sun Microsystems - Beijing China * Store the TM message in memory location corresponding to the TM slot 11405b504601Sjiang wu - Sun Microsystems - Beijing China * number. 11415b504601Sjiang wu - Sun Microsystems - Beijing China */ 11425b504601Sjiang wu - Sun Microsystems - Beijing China task = (pMpi2SCSITaskManagementRequest_t)(mpt->m_req_frame + 11435b504601Sjiang wu - Sun Microsystems - Beijing China (mpt->m_req_frame_size * cmd->cmd_slot)); 11445b504601Sjiang wu - Sun Microsystems - Beijing China bzero(task, mpt->m_req_frame_size); 11455b504601Sjiang wu - Sun Microsystems - Beijing China 11465b504601Sjiang wu - Sun Microsystems - Beijing China /* 11475b504601Sjiang wu - Sun Microsystems - Beijing China * form message for requested task 11485b504601Sjiang wu - Sun Microsystems - Beijing China */ 11495b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_init_std_hdr(mpt->m_acc_req_frame_hdl, task, dev_handle, lun, 0, 11505b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_FUNCTION_SCSI_TASK_MGMT); 11515b504601Sjiang wu - Sun Microsystems - Beijing China 11525b504601Sjiang wu - Sun Microsystems - Beijing China /* 11535b504601Sjiang wu - Sun Microsystems - Beijing China * Set the task type 11545b504601Sjiang wu - Sun Microsystems - Beijing China */ 11555b504601Sjiang wu - Sun Microsystems - Beijing China ddi_put8(mpt->m_acc_req_frame_hdl, &task->TaskType, task_type); 11565b504601Sjiang wu - Sun Microsystems - Beijing China 11575b504601Sjiang wu - Sun Microsystems - Beijing China /* 11585b504601Sjiang wu - Sun Microsystems - Beijing China * Send TM request using High Priority Queue. 11595b504601Sjiang wu - Sun Microsystems - Beijing China */ 11605b504601Sjiang wu - Sun Microsystems - Beijing China (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0, 11615b504601Sjiang wu - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV); 1162940efceeSAndy Giles request_desc = (cmd->cmd_slot << 16) + 11635b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY; 1164940efceeSAndy Giles MPTSAS_START_CMD(mpt, request_desc); 11655b504601Sjiang wu - Sun Microsystems - Beijing China rval = mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME); 11665b504601Sjiang wu - Sun Microsystems - Beijing China 11675b504601Sjiang wu - Sun Microsystems - Beijing China if (pkt->pkt_reason == CMD_INCOMPLETE) 11685b504601Sjiang wu - Sun Microsystems - Beijing China rval = FALSE; 11695b504601Sjiang wu - Sun Microsystems - Beijing China 1170c8f74a56SAda /* 1171c8f74a56SAda * If a reply frame was used and there is a reply buffer to copy the 1172c8f74a56SAda * reply data into, copy it. If this fails, log a message, but don't 1173c8f74a56SAda * fail the TM request. 1174c8f74a56SAda */ 1175c8f74a56SAda if (cmd->cmd_rfm && reply) { 1176c8f74a56SAda (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 1177c8f74a56SAda DDI_DMA_SYNC_FORCPU); 1178c8f74a56SAda reply_msg = (pMPI2DefaultReply_t) 1179c8f74a56SAda (mpt->m_reply_frame + (cmd->cmd_rfm - 1180940efceeSAndy Giles (mpt->m_reply_frame_dma_addr & 0xffffffffu))); 1181c8f74a56SAda if (reply_size > sizeof (MPI2_SCSI_TASK_MANAGE_REPLY)) { 1182c8f74a56SAda reply_size = sizeof (MPI2_SCSI_TASK_MANAGE_REPLY); 1183c8f74a56SAda } 1184c8f74a56SAda mutex_exit(&mpt->m_mutex); 1185c8f74a56SAda for (i = 0; i < reply_size; i++) { 1186c8f74a56SAda if (ddi_copyout((uint8_t *)reply_msg + i, reply + i, 1, 1187c8f74a56SAda mode)) { 1188c8f74a56SAda mptsas_log(mpt, CE_WARN, "failed to copy out " 1189c8f74a56SAda "reply data for TM request"); 1190c8f74a56SAda break; 1191c8f74a56SAda } 1192c8f74a56SAda } 1193c8f74a56SAda mutex_enter(&mpt->m_mutex); 1194c8f74a56SAda } 1195c8f74a56SAda 11965b504601Sjiang wu - Sun Microsystems - Beijing China /* 11975b504601Sjiang wu - Sun Microsystems - Beijing China * clear the TM slot before returning 11985b504601Sjiang wu - Sun Microsystems - Beijing China */ 11995b504601Sjiang wu - Sun Microsystems - Beijing China slots->m_slot[MPTSAS_TM_SLOT(mpt)] = NULL; 12005b504601Sjiang wu - Sun Microsystems - Beijing China 12015b504601Sjiang wu - Sun Microsystems - Beijing China /* 12025b504601Sjiang wu - Sun Microsystems - Beijing China * If we lost our task management command 12035b504601Sjiang wu - Sun Microsystems - Beijing China * we need to reset the ioc 12045b504601Sjiang wu - Sun Microsystems - Beijing China */ 12055b504601Sjiang wu - Sun Microsystems - Beijing China if (rval == FALSE) { 12065b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "mptsas_ioc_task_management failed " 12075b504601Sjiang wu - Sun Microsystems - Beijing China "try to reset ioc to recovery!"); 1208a9b51062SAda mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 12095b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_restart_ioc(mpt)) { 12105b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed"); 12115b504601Sjiang wu - Sun Microsystems - Beijing China rval = FAILED; 12125b504601Sjiang wu - Sun Microsystems - Beijing China } 12135b504601Sjiang wu - Sun Microsystems - Beijing China } 12145b504601Sjiang wu - Sun Microsystems - Beijing China 12155b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 12165b504601Sjiang wu - Sun Microsystems - Beijing China } 12175b504601Sjiang wu - Sun Microsystems - Beijing China 1218ed7418aeSAndy Giles /* 1219ed7418aeSAndy Giles * Complete firmware download frame for v2.0 cards. 1220ed7418aeSAndy Giles */ 1221ed7418aeSAndy Giles static void 1222ed7418aeSAndy Giles mptsas_uflash2(pMpi2FWDownloadRequest fwdownload, 1223ed7418aeSAndy Giles ddi_acc_handle_t acc_hdl, uint32_t size, uint8_t type, 1224ed7418aeSAndy Giles ddi_dma_cookie_t flsh_cookie) 1225ed7418aeSAndy Giles { 1226ed7418aeSAndy Giles pMpi2FWDownloadTCSGE_t tcsge; 1227ed7418aeSAndy Giles pMpi2SGESimple64_t sge; 1228ed7418aeSAndy Giles uint32_t flagslength; 1229ed7418aeSAndy Giles 1230ed7418aeSAndy Giles ddi_put8(acc_hdl, &fwdownload->Function, 1231ed7418aeSAndy Giles MPI2_FUNCTION_FW_DOWNLOAD); 1232ed7418aeSAndy Giles ddi_put8(acc_hdl, &fwdownload->ImageType, type); 1233ed7418aeSAndy Giles ddi_put8(acc_hdl, &fwdownload->MsgFlags, 1234ed7418aeSAndy Giles MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT); 1235ed7418aeSAndy Giles ddi_put32(acc_hdl, &fwdownload->TotalImageSize, size); 1236ed7418aeSAndy Giles 1237ed7418aeSAndy Giles tcsge = (pMpi2FWDownloadTCSGE_t)&fwdownload->SGL; 1238ed7418aeSAndy Giles ddi_put8(acc_hdl, &tcsge->ContextSize, 0); 1239ed7418aeSAndy Giles ddi_put8(acc_hdl, &tcsge->DetailsLength, 12); 1240ed7418aeSAndy Giles ddi_put8(acc_hdl, &tcsge->Flags, 0); 1241ed7418aeSAndy Giles ddi_put32(acc_hdl, &tcsge->ImageOffset, 0); 1242ed7418aeSAndy Giles ddi_put32(acc_hdl, &tcsge->ImageSize, size); 1243ed7418aeSAndy Giles 1244ed7418aeSAndy Giles sge = (pMpi2SGESimple64_t)(tcsge + 1); 1245ed7418aeSAndy Giles flagslength = size; 1246ed7418aeSAndy Giles flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT | 1247ed7418aeSAndy Giles MPI2_SGE_FLAGS_END_OF_BUFFER | 1248ed7418aeSAndy Giles MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 1249ed7418aeSAndy Giles MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 1250ed7418aeSAndy Giles MPI2_SGE_FLAGS_64_BIT_ADDRESSING | 1251ed7418aeSAndy Giles MPI2_SGE_FLAGS_HOST_TO_IOC | 1252ed7418aeSAndy Giles MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); 1253ed7418aeSAndy Giles ddi_put32(acc_hdl, &sge->FlagsLength, flagslength); 1254ed7418aeSAndy Giles ddi_put32(acc_hdl, &sge->Address.Low, 1255ed7418aeSAndy Giles flsh_cookie.dmac_address); 1256ed7418aeSAndy Giles ddi_put32(acc_hdl, &sge->Address.High, 1257ed7418aeSAndy Giles (uint32_t)(flsh_cookie.dmac_laddress >> 32)); 1258ed7418aeSAndy Giles } 1259ed7418aeSAndy Giles 1260ed7418aeSAndy Giles /* 1261ed7418aeSAndy Giles * Complete firmware download frame for v2.5 cards. 1262ed7418aeSAndy Giles */ 1263ed7418aeSAndy Giles static void 1264ed7418aeSAndy Giles mptsas_uflash25(pMpi25FWDownloadRequest fwdownload, 1265ed7418aeSAndy Giles ddi_acc_handle_t acc_hdl, uint32_t size, uint8_t type, 1266ed7418aeSAndy Giles ddi_dma_cookie_t flsh_cookie) 1267ed7418aeSAndy Giles { 1268ed7418aeSAndy Giles pMpi2IeeeSgeSimple64_t sge; 1269ed7418aeSAndy Giles uint8_t flags; 1270ed7418aeSAndy Giles 1271ed7418aeSAndy Giles ddi_put8(acc_hdl, &fwdownload->Function, 1272ed7418aeSAndy Giles MPI2_FUNCTION_FW_DOWNLOAD); 1273ed7418aeSAndy Giles ddi_put8(acc_hdl, &fwdownload->ImageType, type); 1274ed7418aeSAndy Giles ddi_put8(acc_hdl, &fwdownload->MsgFlags, 1275ed7418aeSAndy Giles MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT); 1276ed7418aeSAndy Giles ddi_put32(acc_hdl, &fwdownload->TotalImageSize, size); 1277ed7418aeSAndy Giles 1278ed7418aeSAndy Giles ddi_put32(acc_hdl, &fwdownload->ImageOffset, 0); 1279ed7418aeSAndy Giles ddi_put32(acc_hdl, &fwdownload->ImageSize, size); 1280ed7418aeSAndy Giles 1281ed7418aeSAndy Giles sge = (pMpi2IeeeSgeSimple64_t)&fwdownload->SGL; 1282ed7418aeSAndy Giles flags = MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT | 1283ed7418aeSAndy Giles MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR | 1284ed7418aeSAndy Giles MPI25_IEEE_SGE_FLAGS_END_OF_LIST; 1285ed7418aeSAndy Giles ddi_put8(acc_hdl, &sge->Flags, flags); 1286ed7418aeSAndy Giles ddi_put32(acc_hdl, &sge->Length, size); 1287ed7418aeSAndy Giles ddi_put32(acc_hdl, &sge->Address.Low, 1288ed7418aeSAndy Giles flsh_cookie.dmac_address); 1289ed7418aeSAndy Giles ddi_put32(acc_hdl, &sge->Address.High, 1290ed7418aeSAndy Giles (uint32_t)(flsh_cookie.dmac_laddress >> 32)); 1291ed7418aeSAndy Giles } 1292ed7418aeSAndy Giles 1293ed7418aeSAndy Giles static int mptsas_enable_mpi25_flashupdate = 0; 1294ed7418aeSAndy Giles 12955b504601Sjiang wu - Sun Microsystems - Beijing China int 12965b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_update_flash(mptsas_t *mpt, caddr_t ptrbuffer, uint32_t size, 12975b504601Sjiang wu - Sun Microsystems - Beijing China uint8_t type, int mode) 12985b504601Sjiang wu - Sun Microsystems - Beijing China { 12995b504601Sjiang wu - Sun Microsystems - Beijing China 13005b504601Sjiang wu - Sun Microsystems - Beijing China /* 13015b504601Sjiang wu - Sun Microsystems - Beijing China * In order to avoid allocating variables on the stack, 13025b504601Sjiang wu - Sun Microsystems - Beijing China * we make use of the pre-existing mptsas_cmd_t and 13035b504601Sjiang wu - Sun Microsystems - Beijing China * scsi_pkt which are included in the mptsas_t which 13045b504601Sjiang wu - Sun Microsystems - Beijing China * is passed to this routine. 13055b504601Sjiang wu - Sun Microsystems - Beijing China */ 13065b504601Sjiang wu - Sun Microsystems - Beijing China 13075b504601Sjiang wu - Sun Microsystems - Beijing China ddi_dma_attr_t flsh_dma_attrs; 13085b504601Sjiang wu - Sun Microsystems - Beijing China ddi_dma_cookie_t flsh_cookie; 13095b504601Sjiang wu - Sun Microsystems - Beijing China ddi_dma_handle_t flsh_dma_handle; 13105b504601Sjiang wu - Sun Microsystems - Beijing China ddi_acc_handle_t flsh_accessp; 13115b504601Sjiang wu - Sun Microsystems - Beijing China caddr_t memp, flsh_memp; 13125b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_cmd_t *cmd; 13135b504601Sjiang wu - Sun Microsystems - Beijing China struct scsi_pkt *pkt; 13145b504601Sjiang wu - Sun Microsystems - Beijing China int i; 13155b504601Sjiang wu - Sun Microsystems - Beijing China int rvalue = 0; 1316940efceeSAndy Giles uint64_t request_desc; 13175b504601Sjiang wu - Sun Microsystems - Beijing China 1318ed7418aeSAndy Giles if (mpt->m_MPI25 && !mptsas_enable_mpi25_flashupdate) { 1319ed7418aeSAndy Giles /* 1320ed7418aeSAndy Giles * The code is there but not tested yet. 1321ed7418aeSAndy Giles * User has to know there are risks here. 1322ed7418aeSAndy Giles */ 1323ed7418aeSAndy Giles mptsas_log(mpt, CE_WARN, "mptsas_update_flash(): " 1324ed7418aeSAndy Giles "Updating firmware through MPI 2.5 has not been " 1325ed7418aeSAndy Giles "tested yet!\n" 1326ed7418aeSAndy Giles "To enable set mptsas_enable_mpi25_flashupdate to 1\n"); 1327ed7418aeSAndy Giles return (-1); 1328ed7418aeSAndy Giles } /* Otherwise, you pay your money and you take your chances. */ 1329ed7418aeSAndy Giles 13305b504601Sjiang wu - Sun Microsystems - Beijing China if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 13315b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "mptsas_update_flash(): allocation " 13325b504601Sjiang wu - Sun Microsystems - Beijing China "failed. event ack command pool is full\n"); 13335b504601Sjiang wu - Sun Microsystems - Beijing China return (rvalue); 13345b504601Sjiang wu - Sun Microsystems - Beijing China } 13355b504601Sjiang wu - Sun Microsystems - Beijing China 13365b504601Sjiang wu - Sun Microsystems - Beijing China bzero((caddr_t)cmd, sizeof (*cmd)); 13375b504601Sjiang wu - Sun Microsystems - Beijing China bzero((caddr_t)pkt, scsi_pkt_size()); 13385b504601Sjiang wu - Sun Microsystems - Beijing China cmd->ioc_cmd_slot = (uint32_t)rvalue; 13395b504601Sjiang wu - Sun Microsystems - Beijing China 13405b504601Sjiang wu - Sun Microsystems - Beijing China /* 13415b504601Sjiang wu - Sun Microsystems - Beijing China * dynamically create a customized dma attribute structure 13425b504601Sjiang wu - Sun Microsystems - Beijing China * that describes the flash file. 13435b504601Sjiang wu - Sun Microsystems - Beijing China */ 13445b504601Sjiang wu - Sun Microsystems - Beijing China flsh_dma_attrs = mpt->m_msg_dma_attr; 13455b504601Sjiang wu - Sun Microsystems - Beijing China flsh_dma_attrs.dma_attr_sgllen = 1; 13465b504601Sjiang wu - Sun Microsystems - Beijing China 1347a9b51062SAda if (mptsas_dma_addr_create(mpt, flsh_dma_attrs, &flsh_dma_handle, 1348a9b51062SAda &flsh_accessp, &flsh_memp, size, &flsh_cookie) == FALSE) { 13495b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, 1350a9b51062SAda "(unable to allocate dma resource."); 13515b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_return_to_pool(mpt, cmd); 13525b504601Sjiang wu - Sun Microsystems - Beijing China return (-1); 13535b504601Sjiang wu - Sun Microsystems - Beijing China } 13545b504601Sjiang wu - Sun Microsystems - Beijing China 13555b504601Sjiang wu - Sun Microsystems - Beijing China bzero(flsh_memp, size); 13565b504601Sjiang wu - Sun Microsystems - Beijing China 13575b504601Sjiang wu - Sun Microsystems - Beijing China for (i = 0; i < size; i++) { 13585b504601Sjiang wu - Sun Microsystems - Beijing China (void) ddi_copyin(ptrbuffer + i, flsh_memp + i, 1, mode); 13595b504601Sjiang wu - Sun Microsystems - Beijing China } 13605b504601Sjiang wu - Sun Microsystems - Beijing China (void) ddi_dma_sync(flsh_dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV); 13615b504601Sjiang wu - Sun Microsystems - Beijing China 13625b504601Sjiang wu - Sun Microsystems - Beijing China /* 13635b504601Sjiang wu - Sun Microsystems - Beijing China * form a cmd/pkt to store the fw download message 13645b504601Sjiang wu - Sun Microsystems - Beijing China */ 13655b504601Sjiang wu - Sun Microsystems - Beijing China pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb[0]; 13665b504601Sjiang wu - Sun Microsystems - Beijing China pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb; 13675b504601Sjiang wu - Sun Microsystems - Beijing China pkt->pkt_ha_private = (opaque_t)cmd; 13685b504601Sjiang wu - Sun Microsystems - Beijing China pkt->pkt_flags = FLAG_HEAD; 13695b504601Sjiang wu - Sun Microsystems - Beijing China pkt->pkt_time = 60; 13705b504601Sjiang wu - Sun Microsystems - Beijing China cmd->cmd_pkt = pkt; 13715b504601Sjiang wu - Sun Microsystems - Beijing China cmd->cmd_scblen = 1; 13725b504601Sjiang wu - Sun Microsystems - Beijing China cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_CMD; 13735b504601Sjiang wu - Sun Microsystems - Beijing China 13745b504601Sjiang wu - Sun Microsystems - Beijing China /* 13755b504601Sjiang wu - Sun Microsystems - Beijing China * Save the command in a slot 13765b504601Sjiang wu - Sun Microsystems - Beijing China */ 13775b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_save_cmd(mpt, cmd) == FALSE) { 1378a9b51062SAda mptsas_dma_addr_destroy(&flsh_dma_handle, &flsh_accessp); 13795b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_return_to_pool(mpt, cmd); 13805b504601Sjiang wu - Sun Microsystems - Beijing China return (-1); 13815b504601Sjiang wu - Sun Microsystems - Beijing China } 13825b504601Sjiang wu - Sun Microsystems - Beijing China 13835b504601Sjiang wu - Sun Microsystems - Beijing China /* 13845b504601Sjiang wu - Sun Microsystems - Beijing China * Fill in fw download message 13855b504601Sjiang wu - Sun Microsystems - Beijing China */ 13865b504601Sjiang wu - Sun Microsystems - Beijing China ASSERT(cmd->cmd_slot != 0); 13875b504601Sjiang wu - Sun Microsystems - Beijing China memp = mpt->m_req_frame + (mpt->m_req_frame_size * cmd->cmd_slot); 13885b504601Sjiang wu - Sun Microsystems - Beijing China bzero(memp, mpt->m_req_frame_size); 13895b504601Sjiang wu - Sun Microsystems - Beijing China 1390ed7418aeSAndy Giles if (mpt->m_MPI25) 1391ed7418aeSAndy Giles mptsas_uflash25((pMpi25FWDownloadRequest)memp, 1392ed7418aeSAndy Giles mpt->m_acc_req_frame_hdl, size, type, flsh_cookie); 1393ed7418aeSAndy Giles else 1394ed7418aeSAndy Giles mptsas_uflash2((pMpi2FWDownloadRequest)memp, 1395ed7418aeSAndy Giles mpt->m_acc_req_frame_hdl, size, type, flsh_cookie); 13965b504601Sjiang wu - Sun Microsystems - Beijing China 13975b504601Sjiang wu - Sun Microsystems - Beijing China /* 13985b504601Sjiang wu - Sun Microsystems - Beijing China * Start command 13995b504601Sjiang wu - Sun Microsystems - Beijing China */ 14005b504601Sjiang wu - Sun Microsystems - Beijing China (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0, 14015b504601Sjiang wu - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV); 1402940efceeSAndy Giles request_desc = (cmd->cmd_slot << 16) + 14035b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 1404a0ac5a9eSToomas Soome cmd->cmd_rfm = 0; 1405940efceeSAndy Giles MPTSAS_START_CMD(mpt, request_desc); 14065b504601Sjiang wu - Sun Microsystems - Beijing China 14075b504601Sjiang wu - Sun Microsystems - Beijing China rvalue = 0; 1408d3d50737SRafael Vanoni (void) cv_reltimedwait(&mpt->m_fw_cv, &mpt->m_mutex, 1409d3d50737SRafael Vanoni drv_usectohz(60 * MICROSEC), TR_CLOCK_TICK); 14105b504601Sjiang wu - Sun Microsystems - Beijing China if (!(cmd->cmd_flags & CFLAG_FINISHED)) { 1411a9b51062SAda mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 14125b504601Sjiang wu - Sun Microsystems - Beijing China if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 14135b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed"); 14145b504601Sjiang wu - Sun Microsystems - Beijing China } 14155b504601Sjiang wu - Sun Microsystems - Beijing China rvalue = -1; 14165b504601Sjiang wu - Sun Microsystems - Beijing China } 14175b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_remove_cmd(mpt, cmd); 1418a9b51062SAda mptsas_dma_addr_destroy(&flsh_dma_handle, &flsh_accessp); 14195b504601Sjiang wu - Sun Microsystems - Beijing China 14205b504601Sjiang wu - Sun Microsystems - Beijing China return (rvalue); 14215b504601Sjiang wu - Sun Microsystems - Beijing China } 14225b504601Sjiang wu - Sun Microsystems - Beijing China 14235b504601Sjiang wu - Sun Microsystems - Beijing China static int 14245b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_sasdevpage_0_cb(mptsas_t *mpt, caddr_t page_memp, 14255b504601Sjiang wu - Sun Microsystems - Beijing China ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo, 14265b504601Sjiang wu - Sun Microsystems - Beijing China va_list ap) 14275b504601Sjiang wu - Sun Microsystems - Beijing China { 14285b504601Sjiang wu - Sun Microsystems - Beijing China #ifndef __lock_lint 14295b504601Sjiang wu - Sun Microsystems - Beijing China _NOTE(ARGUNUSED(ap)) 14305b504601Sjiang wu - Sun Microsystems - Beijing China #endif 14315b504601Sjiang wu - Sun Microsystems - Beijing China pMpi2SasDevicePage0_t sasdevpage; 14325b504601Sjiang wu - Sun Microsystems - Beijing China int rval = DDI_SUCCESS, i; 14335b504601Sjiang wu - Sun Microsystems - Beijing China uint8_t *sas_addr = NULL; 14345b504601Sjiang wu - Sun Microsystems - Beijing China uint8_t tmp_sas_wwn[SAS_WWN_BYTE_SIZE]; 14359814ff7fSYong-Feng Du uint16_t *devhdl, *bay_num, *enclosure; 14365b504601Sjiang wu - Sun Microsystems - Beijing China uint64_t *sas_wwn; 14375b504601Sjiang wu - Sun Microsystems - Beijing China uint32_t *dev_info; 14385b504601Sjiang wu - Sun Microsystems - Beijing China uint8_t *physport, *phynum; 1439ed7418aeSAndy Giles uint16_t *pdevhdl, *io_flags; 14405b504601Sjiang wu - Sun Microsystems - Beijing China uint32_t page_address; 14415b504601Sjiang wu - Sun Microsystems - Beijing China 14425b504601Sjiang wu - Sun Microsystems - Beijing China if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) && 14435b504601Sjiang wu - Sun Microsystems - Beijing China (iocstatus != MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)) { 14445b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "mptsas_get_sas_device_page0 " 14455b504601Sjiang wu - Sun Microsystems - Beijing China "header: IOCStatus=0x%x, IOCLogInfo=0x%x", 14465b504601Sjiang wu - Sun Microsystems - Beijing China iocstatus, iocloginfo); 14475b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 14485b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 14495b504601Sjiang wu - Sun Microsystems - Beijing China } 14505b504601Sjiang wu - Sun Microsystems - Beijing China page_address = va_arg(ap, uint32_t); 14515b504601Sjiang wu - Sun Microsystems - Beijing China /* 14525b504601Sjiang wu - Sun Microsystems - Beijing China * The INVALID_PAGE status is normal if using GET_NEXT_HANDLE and there 14535b504601Sjiang wu - Sun Microsystems - Beijing China * are no more pages. If everything is OK up to this point but the 14545b504601Sjiang wu - Sun Microsystems - Beijing China * status is INVALID_PAGE, change rval to FAILURE and quit. Also, 14555b504601Sjiang wu - Sun Microsystems - Beijing China * signal that device traversal is complete. 14565b504601Sjiang wu - Sun Microsystems - Beijing China */ 14575b504601Sjiang wu - Sun Microsystems - Beijing China if (iocstatus == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) { 14585b504601Sjiang wu - Sun Microsystems - Beijing China if ((page_address & MPI2_SAS_DEVICE_PGAD_FORM_MASK) == 14595b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE) { 14605b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_done_traverse_dev = 1; 14615b504601Sjiang wu - Sun Microsystems - Beijing China } 14625b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 14635b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 14645b504601Sjiang wu - Sun Microsystems - Beijing China } 14655b504601Sjiang wu - Sun Microsystems - Beijing China devhdl = va_arg(ap, uint16_t *); 14665b504601Sjiang wu - Sun Microsystems - Beijing China sas_wwn = va_arg(ap, uint64_t *); 14675b504601Sjiang wu - Sun Microsystems - Beijing China dev_info = va_arg(ap, uint32_t *); 14685b504601Sjiang wu - Sun Microsystems - Beijing China physport = va_arg(ap, uint8_t *); 14695b504601Sjiang wu - Sun Microsystems - Beijing China phynum = va_arg(ap, uint8_t *); 1470f2e8686eSxun ni - Sun Microsystems - Beijing China pdevhdl = va_arg(ap, uint16_t *); 14719814ff7fSYong-Feng Du bay_num = va_arg(ap, uint16_t *); 14729814ff7fSYong-Feng Du enclosure = va_arg(ap, uint16_t *); 1473ed7418aeSAndy Giles io_flags = va_arg(ap, uint16_t *); 1474f2e8686eSxun ni - Sun Microsystems - Beijing China 14755b504601Sjiang wu - Sun Microsystems - Beijing China sasdevpage = (pMpi2SasDevicePage0_t)page_memp; 14765b504601Sjiang wu - Sun Microsystems - Beijing China 14775b504601Sjiang wu - Sun Microsystems - Beijing China *dev_info = ddi_get32(accessp, &sasdevpage->DeviceInfo); 14785b504601Sjiang wu - Sun Microsystems - Beijing China *devhdl = ddi_get16(accessp, &sasdevpage->DevHandle); 14795b504601Sjiang wu - Sun Microsystems - Beijing China sas_addr = (uint8_t *)(&sasdevpage->SASAddress); 14805b504601Sjiang wu - Sun Microsystems - Beijing China for (i = 0; i < SAS_WWN_BYTE_SIZE; i++) { 14815b504601Sjiang wu - Sun Microsystems - Beijing China tmp_sas_wwn[i] = ddi_get8(accessp, sas_addr + i); 14825b504601Sjiang wu - Sun Microsystems - Beijing China } 14835b504601Sjiang wu - Sun Microsystems - Beijing China bcopy(tmp_sas_wwn, sas_wwn, SAS_WWN_BYTE_SIZE); 14845b504601Sjiang wu - Sun Microsystems - Beijing China *sas_wwn = LE_64(*sas_wwn); 14855b504601Sjiang wu - Sun Microsystems - Beijing China *physport = ddi_get8(accessp, &sasdevpage->PhysicalPort); 14865b504601Sjiang wu - Sun Microsystems - Beijing China *phynum = ddi_get8(accessp, &sasdevpage->PhyNum); 1487f2e8686eSxun ni - Sun Microsystems - Beijing China *pdevhdl = ddi_get16(accessp, &sasdevpage->ParentDevHandle); 14889814ff7fSYong-Feng Du *bay_num = ddi_get16(accessp, &sasdevpage->Slot); 14899814ff7fSYong-Feng Du *enclosure = ddi_get16(accessp, &sasdevpage->EnclosureHandle); 1490ed7418aeSAndy Giles *io_flags = ddi_get16(accessp, &sasdevpage->Flags); 1491ed7418aeSAndy Giles 1492ed7418aeSAndy Giles if (*io_flags & MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE) { 1493ed7418aeSAndy Giles /* 1494ed7418aeSAndy Giles * Leave a messages about FP cabability in the log. 1495ed7418aeSAndy Giles */ 1496ed7418aeSAndy Giles mptsas_log(mpt, CE_CONT, 1497ed7418aeSAndy Giles "!w%016"PRIx64" FastPath Capable%s", *sas_wwn, 1498ed7418aeSAndy Giles (*io_flags & 1499ed7418aeSAndy Giles MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH)? 1500ed7418aeSAndy Giles " and Enabled":" but Disabled"); 1501ed7418aeSAndy Giles } 1502ed7418aeSAndy Giles 15035b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 15045b504601Sjiang wu - Sun Microsystems - Beijing China } 15055b504601Sjiang wu - Sun Microsystems - Beijing China 15065b504601Sjiang wu - Sun Microsystems - Beijing China /* 15075b504601Sjiang wu - Sun Microsystems - Beijing China * Request MPI configuration page SAS device page 0 to get DevHandle, device 15085b504601Sjiang wu - Sun Microsystems - Beijing China * info and SAS address. 15095b504601Sjiang wu - Sun Microsystems - Beijing China */ 15105b504601Sjiang wu - Sun Microsystems - Beijing China int 15115b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_sas_device_page0(mptsas_t *mpt, uint32_t page_address, 15125b504601Sjiang wu - Sun Microsystems - Beijing China uint16_t *dev_handle, uint64_t *sas_wwn, uint32_t *dev_info, 1513f2e8686eSxun ni - Sun Microsystems - Beijing China uint8_t *physport, uint8_t *phynum, uint16_t *pdev_handle, 1514ed7418aeSAndy Giles uint16_t *bay_num, uint16_t *enclosure, uint16_t *io_flags) 15155b504601Sjiang wu - Sun Microsystems - Beijing China { 15165b504601Sjiang wu - Sun Microsystems - Beijing China int rval = DDI_SUCCESS; 15175b504601Sjiang wu - Sun Microsystems - Beijing China 15185b504601Sjiang wu - Sun Microsystems - Beijing China ASSERT(mutex_owned(&mpt->m_mutex)); 15195b504601Sjiang wu - Sun Microsystems - Beijing China 15205b504601Sjiang wu - Sun Microsystems - Beijing China /* 15215b504601Sjiang wu - Sun Microsystems - Beijing China * Get the header and config page. reply contains the reply frame, 15225b504601Sjiang wu - Sun Microsystems - Beijing China * which holds status info for the request. 15235b504601Sjiang wu - Sun Microsystems - Beijing China */ 15245b504601Sjiang wu - Sun Microsystems - Beijing China rval = mptsas_access_config_page(mpt, 15255b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, 15265b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE, 0, page_address, 15275b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_sasdevpage_0_cb, page_address, dev_handle, sas_wwn, 1528f2e8686eSxun ni - Sun Microsystems - Beijing China dev_info, physport, phynum, pdev_handle, 1529ed7418aeSAndy Giles bay_num, enclosure, io_flags); 15305b504601Sjiang wu - Sun Microsystems - Beijing China 15315b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 15325b504601Sjiang wu - Sun Microsystems - Beijing China } 15335b504601Sjiang wu - Sun Microsystems - Beijing China 15345b504601Sjiang wu - Sun Microsystems - Beijing China static int 15355b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_sasexpdpage_0_cb(mptsas_t *mpt, caddr_t page_memp, 15365b504601Sjiang wu - Sun Microsystems - Beijing China ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo, 15375b504601Sjiang wu - Sun Microsystems - Beijing China va_list ap) 15385b504601Sjiang wu - Sun Microsystems - Beijing China { 15395b504601Sjiang wu - Sun Microsystems - Beijing China #ifndef __lock_lint 15405b504601Sjiang wu - Sun Microsystems - Beijing China _NOTE(ARGUNUSED(ap)) 15415b504601Sjiang wu - Sun Microsystems - Beijing China #endif 15425b504601Sjiang wu - Sun Microsystems - Beijing China pMpi2ExpanderPage0_t expddevpage; 15435b504601Sjiang wu - Sun Microsystems - Beijing China int rval = DDI_SUCCESS, i; 15445b504601Sjiang wu - Sun Microsystems - Beijing China uint8_t *sas_addr = NULL; 15455b504601Sjiang wu - Sun Microsystems - Beijing China uint8_t tmp_sas_wwn[SAS_WWN_BYTE_SIZE]; 15465b504601Sjiang wu - Sun Microsystems - Beijing China uint16_t *devhdl; 15475b504601Sjiang wu - Sun Microsystems - Beijing China uint64_t *sas_wwn; 1548cdc7c7feSAda uint8_t physport; 1549cdc7c7feSAda mptsas_phymask_t *phymask; 1550f2e8686eSxun ni - Sun Microsystems - Beijing China uint16_t *pdevhdl; 15515b504601Sjiang wu - Sun Microsystems - Beijing China uint32_t page_address; 15525b504601Sjiang wu - Sun Microsystems - Beijing China 15535b504601Sjiang wu - Sun Microsystems - Beijing China if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) && 15545b504601Sjiang wu - Sun Microsystems - Beijing China (iocstatus != MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)) { 15555b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "mptsas_get_sas_expander_page0 " 15565b504601Sjiang wu - Sun Microsystems - Beijing China "config: IOCStatus=0x%x, IOCLogInfo=0x%x", 15575b504601Sjiang wu - Sun Microsystems - Beijing China iocstatus, iocloginfo); 15585b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 15595b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 15605b504601Sjiang wu - Sun Microsystems - Beijing China } 15615b504601Sjiang wu - Sun Microsystems - Beijing China page_address = va_arg(ap, uint32_t); 15625b504601Sjiang wu - Sun Microsystems - Beijing China /* 15635b504601Sjiang wu - Sun Microsystems - Beijing China * The INVALID_PAGE status is normal if using GET_NEXT_HANDLE and there 15645b504601Sjiang wu - Sun Microsystems - Beijing China * are no more pages. If everything is OK up to this point but the 15655b504601Sjiang wu - Sun Microsystems - Beijing China * status is INVALID_PAGE, change rval to FAILURE and quit. Also, 15665b504601Sjiang wu - Sun Microsystems - Beijing China * signal that device traversal is complete. 15675b504601Sjiang wu - Sun Microsystems - Beijing China */ 15685b504601Sjiang wu - Sun Microsystems - Beijing China if (iocstatus == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) { 15695b504601Sjiang wu - Sun Microsystems - Beijing China if ((page_address & MPI2_SAS_EXPAND_PGAD_FORM_MASK) == 15705b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL) { 15715b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_done_traverse_smp = 1; 15725b504601Sjiang wu - Sun Microsystems - Beijing China } 15735b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 15745b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 15755b504601Sjiang wu - Sun Microsystems - Beijing China } 15765b504601Sjiang wu - Sun Microsystems - Beijing China devhdl = va_arg(ap, uint16_t *); 15775b504601Sjiang wu - Sun Microsystems - Beijing China sas_wwn = va_arg(ap, uint64_t *); 1578cdc7c7feSAda phymask = va_arg(ap, mptsas_phymask_t *); 1579f2e8686eSxun ni - Sun Microsystems - Beijing China pdevhdl = va_arg(ap, uint16_t *); 15805b504601Sjiang wu - Sun Microsystems - Beijing China 15815b504601Sjiang wu - Sun Microsystems - Beijing China expddevpage = (pMpi2ExpanderPage0_t)page_memp; 15825b504601Sjiang wu - Sun Microsystems - Beijing China 15835b504601Sjiang wu - Sun Microsystems - Beijing China *devhdl = ddi_get16(accessp, &expddevpage->DevHandle); 15845b504601Sjiang wu - Sun Microsystems - Beijing China physport = ddi_get8(accessp, &expddevpage->PhysicalPort); 15855b504601Sjiang wu - Sun Microsystems - Beijing China *phymask = mptsas_physport_to_phymask(mpt, physport); 1586f2e8686eSxun ni - Sun Microsystems - Beijing China *pdevhdl = ddi_get16(accessp, &expddevpage->ParentDevHandle); 15875b504601Sjiang wu - Sun Microsystems - Beijing China sas_addr = (uint8_t *)(&expddevpage->SASAddress); 15885b504601Sjiang wu - Sun Microsystems - Beijing China for (i = 0; i < SAS_WWN_BYTE_SIZE; i++) { 15895b504601Sjiang wu - Sun Microsystems - Beijing China tmp_sas_wwn[i] = ddi_get8(accessp, sas_addr + i); 15905b504601Sjiang wu - Sun Microsystems - Beijing China } 15915b504601Sjiang wu - Sun Microsystems - Beijing China bcopy(tmp_sas_wwn, sas_wwn, SAS_WWN_BYTE_SIZE); 15925b504601Sjiang wu - Sun Microsystems - Beijing China *sas_wwn = LE_64(*sas_wwn); 1593f2e8686eSxun ni - Sun Microsystems - Beijing China 15945b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 15955b504601Sjiang wu - Sun Microsystems - Beijing China } 15965b504601Sjiang wu - Sun Microsystems - Beijing China 15975b504601Sjiang wu - Sun Microsystems - Beijing China /* 15985b504601Sjiang wu - Sun Microsystems - Beijing China * Request MPI configuration page SAS device page 0 to get DevHandle, phymask 15995b504601Sjiang wu - Sun Microsystems - Beijing China * and SAS address. 16005b504601Sjiang wu - Sun Microsystems - Beijing China */ 16015b504601Sjiang wu - Sun Microsystems - Beijing China int 16025b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_sas_expander_page0(mptsas_t *mpt, uint32_t page_address, 16035b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_smp_t *info) 16045b504601Sjiang wu - Sun Microsystems - Beijing China { 16055b504601Sjiang wu - Sun Microsystems - Beijing China int rval = DDI_SUCCESS; 16065b504601Sjiang wu - Sun Microsystems - Beijing China 16075b504601Sjiang wu - Sun Microsystems - Beijing China ASSERT(mutex_owned(&mpt->m_mutex)); 16085b504601Sjiang wu - Sun Microsystems - Beijing China 16095b504601Sjiang wu - Sun Microsystems - Beijing China /* 16105b504601Sjiang wu - Sun Microsystems - Beijing China * Get the header and config page. reply contains the reply frame, 16115b504601Sjiang wu - Sun Microsystems - Beijing China * which holds status info for the request. 16125b504601Sjiang wu - Sun Microsystems - Beijing China */ 16135b504601Sjiang wu - Sun Microsystems - Beijing China rval = mptsas_access_config_page(mpt, 16145b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, 16155b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER, 0, page_address, 16165b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_sasexpdpage_0_cb, page_address, &info->m_devhdl, 1617da5ab83fSKeith M Wesolowski &info->m_addr.mta_wwn, &info->m_addr.mta_phymask, &info->m_pdevhdl); 16185b504601Sjiang wu - Sun Microsystems - Beijing China 16195b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 16205b504601Sjiang wu - Sun Microsystems - Beijing China } 16215b504601Sjiang wu - Sun Microsystems - Beijing China 16225b504601Sjiang wu - Sun Microsystems - Beijing China static int 16235b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_sasportpage_0_cb(mptsas_t *mpt, caddr_t page_memp, 16245b504601Sjiang wu - Sun Microsystems - Beijing China ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo, 16255b504601Sjiang wu - Sun Microsystems - Beijing China va_list ap) 16265b504601Sjiang wu - Sun Microsystems - Beijing China { 16275b504601Sjiang wu - Sun Microsystems - Beijing China #ifndef __lock_lint 16285b504601Sjiang wu - Sun Microsystems - Beijing China _NOTE(ARGUNUSED(ap)) 16295b504601Sjiang wu - Sun Microsystems - Beijing China #endif 16305b504601Sjiang wu - Sun Microsystems - Beijing China int rval = DDI_SUCCESS, i; 16315b504601Sjiang wu - Sun Microsystems - Beijing China uint8_t *sas_addr = NULL; 16325b504601Sjiang wu - Sun Microsystems - Beijing China uint64_t *sas_wwn; 16335b504601Sjiang wu - Sun Microsystems - Beijing China uint8_t tmp_sas_wwn[SAS_WWN_BYTE_SIZE]; 16345b504601Sjiang wu - Sun Microsystems - Beijing China uint8_t *portwidth; 16355b504601Sjiang wu - Sun Microsystems - Beijing China pMpi2SasPortPage0_t sasportpage; 16365b504601Sjiang wu - Sun Microsystems - Beijing China 16375b504601Sjiang wu - Sun Microsystems - Beijing China if (iocstatus != MPI2_IOCSTATUS_SUCCESS) { 16385b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "mptsas_get_sas_port_page0 " 16395b504601Sjiang wu - Sun Microsystems - Beijing China "config: IOCStatus=0x%x, IOCLogInfo=0x%x", 16405b504601Sjiang wu - Sun Microsystems - Beijing China iocstatus, iocloginfo); 16415b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 16425b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 16435b504601Sjiang wu - Sun Microsystems - Beijing China } 16445b504601Sjiang wu - Sun Microsystems - Beijing China sas_wwn = va_arg(ap, uint64_t *); 16455b504601Sjiang wu - Sun Microsystems - Beijing China portwidth = va_arg(ap, uint8_t *); 16465b504601Sjiang wu - Sun Microsystems - Beijing China 16475b504601Sjiang wu - Sun Microsystems - Beijing China sasportpage = (pMpi2SasPortPage0_t)page_memp; 16485b504601Sjiang wu - Sun Microsystems - Beijing China sas_addr = (uint8_t *)(&sasportpage->SASAddress); 16495b504601Sjiang wu - Sun Microsystems - Beijing China for (i = 0; i < SAS_WWN_BYTE_SIZE; i++) { 16505b504601Sjiang wu - Sun Microsystems - Beijing China tmp_sas_wwn[i] = ddi_get8(accessp, sas_addr + i); 16515b504601Sjiang wu - Sun Microsystems - Beijing China } 16525b504601Sjiang wu - Sun Microsystems - Beijing China bcopy(tmp_sas_wwn, sas_wwn, SAS_WWN_BYTE_SIZE); 16535b504601Sjiang wu - Sun Microsystems - Beijing China *sas_wwn = LE_64(*sas_wwn); 16545b504601Sjiang wu - Sun Microsystems - Beijing China *portwidth = ddi_get8(accessp, &sasportpage->PortWidth); 16555b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 16565b504601Sjiang wu - Sun Microsystems - Beijing China } 16575b504601Sjiang wu - Sun Microsystems - Beijing China 16585b504601Sjiang wu - Sun Microsystems - Beijing China /* 16595b504601Sjiang wu - Sun Microsystems - Beijing China * Request MPI configuration page SAS port page 0 to get initiator SAS address 16605b504601Sjiang wu - Sun Microsystems - Beijing China * and port width. 16615b504601Sjiang wu - Sun Microsystems - Beijing China */ 16625b504601Sjiang wu - Sun Microsystems - Beijing China int 16635b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_sas_port_page0(mptsas_t *mpt, uint32_t page_address, 16645b504601Sjiang wu - Sun Microsystems - Beijing China uint64_t *sas_wwn, uint8_t *portwidth) 16655b504601Sjiang wu - Sun Microsystems - Beijing China { 16665b504601Sjiang wu - Sun Microsystems - Beijing China int rval = DDI_SUCCESS; 16675b504601Sjiang wu - Sun Microsystems - Beijing China 16685b504601Sjiang wu - Sun Microsystems - Beijing China ASSERT(mutex_owned(&mpt->m_mutex)); 16695b504601Sjiang wu - Sun Microsystems - Beijing China 16705b504601Sjiang wu - Sun Microsystems - Beijing China /* 16715b504601Sjiang wu - Sun Microsystems - Beijing China * Get the header and config page. reply contains the reply frame, 16725b504601Sjiang wu - Sun Microsystems - Beijing China * which holds status info for the request. 16735b504601Sjiang wu - Sun Microsystems - Beijing China */ 16745b504601Sjiang wu - Sun Microsystems - Beijing China rval = mptsas_access_config_page(mpt, 16755b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, 16765b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_CONFIG_EXTPAGETYPE_SAS_PORT, 0, page_address, 16775b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_sasportpage_0_cb, sas_wwn, portwidth); 16785b504601Sjiang wu - Sun Microsystems - Beijing China 16795b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 16805b504601Sjiang wu - Sun Microsystems - Beijing China } 16815b504601Sjiang wu - Sun Microsystems - Beijing China 16825b504601Sjiang wu - Sun Microsystems - Beijing China static int 16835b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_sasiou_page_0_cb(mptsas_t *mpt, caddr_t page_memp, 16845b504601Sjiang wu - Sun Microsystems - Beijing China ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo, 16855b504601Sjiang wu - Sun Microsystems - Beijing China va_list ap) 16865b504601Sjiang wu - Sun Microsystems - Beijing China { 16875b504601Sjiang wu - Sun Microsystems - Beijing China #ifndef __lock_lint 16885b504601Sjiang wu - Sun Microsystems - Beijing China _NOTE(ARGUNUSED(ap)) 16895b504601Sjiang wu - Sun Microsystems - Beijing China #endif 16905b504601Sjiang wu - Sun Microsystems - Beijing China int rval = DDI_SUCCESS; 16915b504601Sjiang wu - Sun Microsystems - Beijing China pMpi2SasIOUnitPage0_t sasioupage0; 16925b504601Sjiang wu - Sun Microsystems - Beijing China int i, num_phys; 1693cdc7c7feSAda uint32_t cpdi[MPTSAS_MAX_PHYS], *retrypage0, *readpage1; 16945b504601Sjiang wu - Sun Microsystems - Beijing China uint8_t port_flags; 16955b504601Sjiang wu - Sun Microsystems - Beijing China 16965b504601Sjiang wu - Sun Microsystems - Beijing China if (iocstatus != MPI2_IOCSTATUS_SUCCESS) { 16975b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "mptsas_get_sas_io_unit_page0 " 16985b504601Sjiang wu - Sun Microsystems - Beijing China "config: IOCStatus=0x%x, IOCLogInfo=0x%x", 16995b504601Sjiang wu - Sun Microsystems - Beijing China iocstatus, iocloginfo); 17005b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 17015b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 17025b504601Sjiang wu - Sun Microsystems - Beijing China } 17035b504601Sjiang wu - Sun Microsystems - Beijing China readpage1 = va_arg(ap, uint32_t *); 17045b504601Sjiang wu - Sun Microsystems - Beijing China retrypage0 = va_arg(ap, uint32_t *); 17055b504601Sjiang wu - Sun Microsystems - Beijing China 17065b504601Sjiang wu - Sun Microsystems - Beijing China sasioupage0 = (pMpi2SasIOUnitPage0_t)page_memp; 17075b504601Sjiang wu - Sun Microsystems - Beijing China 17085b504601Sjiang wu - Sun Microsystems - Beijing China num_phys = ddi_get8(accessp, &sasioupage0->NumPhys); 1709cdc7c7feSAda /* 1710cdc7c7feSAda * ASSERT that the num_phys value in SAS IO Unit Page 0 is the same as 1711cdc7c7feSAda * was initially set. This should never change throughout the life of 1712e89016e7SRobert Mustacchi * the driver. Note, due to cases where we've seen page zero have more 1713e89016e7SRobert Mustacchi * phys than the reported manufacturing information, we limit the number 1714e89016e7SRobert Mustacchi * of phys here to what we got from the manufacturing information. 1715cdc7c7feSAda */ 1716e89016e7SRobert Mustacchi ASSERT3U(num_phys, >=, mpt->m_num_phys); 1717e89016e7SRobert Mustacchi num_phys = mpt->m_num_phys; 17185b504601Sjiang wu - Sun Microsystems - Beijing China for (i = 0; i < num_phys; i++) { 17195b504601Sjiang wu - Sun Microsystems - Beijing China cpdi[i] = ddi_get32(accessp, 17205b504601Sjiang wu - Sun Microsystems - Beijing China &sasioupage0->PhyData[i]. 17215b504601Sjiang wu - Sun Microsystems - Beijing China ControllerPhyDeviceInfo); 17225b504601Sjiang wu - Sun Microsystems - Beijing China port_flags = ddi_get8(accessp, 17235b504601Sjiang wu - Sun Microsystems - Beijing China &sasioupage0->PhyData[i].PortFlags); 17245b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_phy_info[i].port_num = 17255b504601Sjiang wu - Sun Microsystems - Beijing China ddi_get8(accessp, 17265b504601Sjiang wu - Sun Microsystems - Beijing China &sasioupage0->PhyData[i].Port); 17275b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_phy_info[i].ctrl_devhdl = 17285b504601Sjiang wu - Sun Microsystems - Beijing China ddi_get16(accessp, &sasioupage0-> 17295b504601Sjiang wu - Sun Microsystems - Beijing China PhyData[i].ControllerDevHandle); 17305b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_phy_info[i].attached_devhdl = 17315b504601Sjiang wu - Sun Microsystems - Beijing China ddi_get16(accessp, &sasioupage0-> 17325b504601Sjiang wu - Sun Microsystems - Beijing China PhyData[i].AttachedDevHandle); 17335b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_phy_info[i].phy_device_type = cpdi[i]; 17345b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_phy_info[i].port_flags = port_flags; 17355b504601Sjiang wu - Sun Microsystems - Beijing China 17365b504601Sjiang wu - Sun Microsystems - Beijing China if (port_flags & DISCOVERY_IN_PROGRESS) { 17375b504601Sjiang wu - Sun Microsystems - Beijing China *retrypage0 = *retrypage0 + 1; 17385b504601Sjiang wu - Sun Microsystems - Beijing China break; 17395b504601Sjiang wu - Sun Microsystems - Beijing China } else { 17405b504601Sjiang wu - Sun Microsystems - Beijing China *retrypage0 = 0; 17415b504601Sjiang wu - Sun Microsystems - Beijing China } 17425b504601Sjiang wu - Sun Microsystems - Beijing China if (!(port_flags & AUTO_PORT_CONFIGURATION)) { 17435b504601Sjiang wu - Sun Microsystems - Beijing China /* 17445b504601Sjiang wu - Sun Microsystems - Beijing China * some PHY configuration described in 17455b504601Sjiang wu - Sun Microsystems - Beijing China * SAS IO Unit Page1 17465b504601Sjiang wu - Sun Microsystems - Beijing China */ 17475b504601Sjiang wu - Sun Microsystems - Beijing China *readpage1 = 1; 17485b504601Sjiang wu - Sun Microsystems - Beijing China } 17495b504601Sjiang wu - Sun Microsystems - Beijing China } 17505b504601Sjiang wu - Sun Microsystems - Beijing China 17515b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 17525b504601Sjiang wu - Sun Microsystems - Beijing China } 17535b504601Sjiang wu - Sun Microsystems - Beijing China 17545b504601Sjiang wu - Sun Microsystems - Beijing China static int 17555b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_sasiou_page_1_cb(mptsas_t *mpt, caddr_t page_memp, 17565b504601Sjiang wu - Sun Microsystems - Beijing China ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo, 17575b504601Sjiang wu - Sun Microsystems - Beijing China va_list ap) 17585b504601Sjiang wu - Sun Microsystems - Beijing China { 17595b504601Sjiang wu - Sun Microsystems - Beijing China #ifndef __lock_lint 17605b504601Sjiang wu - Sun Microsystems - Beijing China _NOTE(ARGUNUSED(ap)) 17615b504601Sjiang wu - Sun Microsystems - Beijing China #endif 17625b504601Sjiang wu - Sun Microsystems - Beijing China int rval = DDI_SUCCESS; 17635b504601Sjiang wu - Sun Microsystems - Beijing China pMpi2SasIOUnitPage1_t sasioupage1; 17645b504601Sjiang wu - Sun Microsystems - Beijing China int i, num_phys; 1765cdc7c7feSAda uint32_t cpdi[MPTSAS_MAX_PHYS]; 17665b504601Sjiang wu - Sun Microsystems - Beijing China uint8_t port_flags; 17675b504601Sjiang wu - Sun Microsystems - Beijing China 17685b504601Sjiang wu - Sun Microsystems - Beijing China if (iocstatus != MPI2_IOCSTATUS_SUCCESS) { 17695b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "mptsas_get_sas_io_unit_page1 " 17705b504601Sjiang wu - Sun Microsystems - Beijing China "config: IOCStatus=0x%x, IOCLogInfo=0x%x", 17715b504601Sjiang wu - Sun Microsystems - Beijing China iocstatus, iocloginfo); 17725b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 17735b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 17745b504601Sjiang wu - Sun Microsystems - Beijing China } 17755b504601Sjiang wu - Sun Microsystems - Beijing China 17765b504601Sjiang wu - Sun Microsystems - Beijing China sasioupage1 = (pMpi2SasIOUnitPage1_t)page_memp; 17775b504601Sjiang wu - Sun Microsystems - Beijing China num_phys = ddi_get8(accessp, &sasioupage1->NumPhys); 1778cdc7c7feSAda /* 1779e89016e7SRobert Mustacchi * ASSERT that the num_phys value in SAS IO Unit Page 0 is the same as 1780cdc7c7feSAda * was initially set. This should never change throughout the life of 1781e89016e7SRobert Mustacchi * the driver. Note, due to cases where we've seen page zero have more 1782e89016e7SRobert Mustacchi * phys than the reported manufacturing information, we limit the number 1783e89016e7SRobert Mustacchi * of phys here to what we got from the manufacturing information. 1784cdc7c7feSAda */ 1785e89016e7SRobert Mustacchi ASSERT3U(num_phys, >=, mpt->m_num_phys); 1786e89016e7SRobert Mustacchi num_phys = mpt->m_num_phys; 17875b504601Sjiang wu - Sun Microsystems - Beijing China for (i = 0; i < num_phys; i++) { 17885b504601Sjiang wu - Sun Microsystems - Beijing China cpdi[i] = ddi_get32(accessp, &sasioupage1->PhyData[i]. 17895b504601Sjiang wu - Sun Microsystems - Beijing China ControllerPhyDeviceInfo); 17905b504601Sjiang wu - Sun Microsystems - Beijing China port_flags = ddi_get8(accessp, 17915b504601Sjiang wu - Sun Microsystems - Beijing China &sasioupage1->PhyData[i].PortFlags); 17925b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_phy_info[i].port_num = 17935b504601Sjiang wu - Sun Microsystems - Beijing China ddi_get8(accessp, 17945b504601Sjiang wu - Sun Microsystems - Beijing China &sasioupage1->PhyData[i].Port); 17955b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_phy_info[i].port_flags = port_flags; 17965b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_phy_info[i].phy_device_type = cpdi[i]; 17975b504601Sjiang wu - Sun Microsystems - Beijing China } 17985b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 17995b504601Sjiang wu - Sun Microsystems - Beijing China } 18005b504601Sjiang wu - Sun Microsystems - Beijing China 18015b504601Sjiang wu - Sun Microsystems - Beijing China /* 18025b504601Sjiang wu - Sun Microsystems - Beijing China * Read IO unit page 0 to get information for each PHY. If needed, Read IO Unit 18035b504601Sjiang wu - Sun Microsystems - Beijing China * page1 to update the PHY information. This is the message passing method of 18045b504601Sjiang wu - Sun Microsystems - Beijing China * this function which should be called except during initialization. 18055b504601Sjiang wu - Sun Microsystems - Beijing China */ 18065b504601Sjiang wu - Sun Microsystems - Beijing China int 18075b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_sas_io_unit_page(mptsas_t *mpt) 18085b504601Sjiang wu - Sun Microsystems - Beijing China { 18095b504601Sjiang wu - Sun Microsystems - Beijing China int rval = DDI_SUCCESS, state; 18105b504601Sjiang wu - Sun Microsystems - Beijing China uint32_t readpage1 = 0, retrypage0 = 0; 18115b504601Sjiang wu - Sun Microsystems - Beijing China 18125b504601Sjiang wu - Sun Microsystems - Beijing China ASSERT(mutex_owned(&mpt->m_mutex)); 18135b504601Sjiang wu - Sun Microsystems - Beijing China 18145b504601Sjiang wu - Sun Microsystems - Beijing China /* 18155b504601Sjiang wu - Sun Microsystems - Beijing China * Now we cycle through the state machine. Here's what happens: 18165b504601Sjiang wu - Sun Microsystems - Beijing China * 1. Read IO unit page 0 and set phy information 18175b504601Sjiang wu - Sun Microsystems - Beijing China * 2. See if Read IO unit page1 is needed because of port configuration 18185b504601Sjiang wu - Sun Microsystems - Beijing China * 3. Read IO unit page 1 and update phy information. 18195b504601Sjiang wu - Sun Microsystems - Beijing China */ 18205b504601Sjiang wu - Sun Microsystems - Beijing China state = IOUC_READ_PAGE0; 18215b504601Sjiang wu - Sun Microsystems - Beijing China while (state != IOUC_DONE) { 18225b504601Sjiang wu - Sun Microsystems - Beijing China if (state == IOUC_READ_PAGE0) { 18235b504601Sjiang wu - Sun Microsystems - Beijing China rval = mptsas_access_config_page(mpt, 18245b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, 18255b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 0, 0, 18265b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_sasiou_page_0_cb, &readpage1, 18275b504601Sjiang wu - Sun Microsystems - Beijing China &retrypage0); 18285b504601Sjiang wu - Sun Microsystems - Beijing China } else if (state == IOUC_READ_PAGE1) { 18295b504601Sjiang wu - Sun Microsystems - Beijing China rval = mptsas_access_config_page(mpt, 18305b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, 18315b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 1, 0, 18325b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_sasiou_page_1_cb); 18335b504601Sjiang wu - Sun Microsystems - Beijing China } 18345b504601Sjiang wu - Sun Microsystems - Beijing China 18355b504601Sjiang wu - Sun Microsystems - Beijing China if (rval == DDI_SUCCESS) { 18365b504601Sjiang wu - Sun Microsystems - Beijing China switch (state) { 18375b504601Sjiang wu - Sun Microsystems - Beijing China case IOUC_READ_PAGE0: 18385b504601Sjiang wu - Sun Microsystems - Beijing China /* 18395b504601Sjiang wu - Sun Microsystems - Beijing China * retry 30 times if discovery is in process 18405b504601Sjiang wu - Sun Microsystems - Beijing China */ 18415b504601Sjiang wu - Sun Microsystems - Beijing China if (retrypage0 && (retrypage0 < 30)) { 18425b504601Sjiang wu - Sun Microsystems - Beijing China drv_usecwait(1000 * 100); 18435b504601Sjiang wu - Sun Microsystems - Beijing China state = IOUC_READ_PAGE0; 18445b504601Sjiang wu - Sun Microsystems - Beijing China break; 18455b504601Sjiang wu - Sun Microsystems - Beijing China } else if (retrypage0 == 30) { 18465b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, 18475b504601Sjiang wu - Sun Microsystems - Beijing China "!Discovery in progress, can't " 18485b504601Sjiang wu - Sun Microsystems - Beijing China "verify IO unit config, then " 18495b504601Sjiang wu - Sun Microsystems - Beijing China "after 30 times retry, give " 18505b504601Sjiang wu - Sun Microsystems - Beijing China "up!"); 18515b504601Sjiang wu - Sun Microsystems - Beijing China state = IOUC_DONE; 18525b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 18535b504601Sjiang wu - Sun Microsystems - Beijing China break; 18545b504601Sjiang wu - Sun Microsystems - Beijing China } 18555b504601Sjiang wu - Sun Microsystems - Beijing China 18565b504601Sjiang wu - Sun Microsystems - Beijing China if (readpage1 == 0) { 18575b504601Sjiang wu - Sun Microsystems - Beijing China state = IOUC_DONE; 18585b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_SUCCESS; 18595b504601Sjiang wu - Sun Microsystems - Beijing China break; 18605b504601Sjiang wu - Sun Microsystems - Beijing China } 18615b504601Sjiang wu - Sun Microsystems - Beijing China 18625b504601Sjiang wu - Sun Microsystems - Beijing China state = IOUC_READ_PAGE1; 18635b504601Sjiang wu - Sun Microsystems - Beijing China break; 18645b504601Sjiang wu - Sun Microsystems - Beijing China 18655b504601Sjiang wu - Sun Microsystems - Beijing China case IOUC_READ_PAGE1: 18665b504601Sjiang wu - Sun Microsystems - Beijing China state = IOUC_DONE; 18675b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_SUCCESS; 18685b504601Sjiang wu - Sun Microsystems - Beijing China break; 18695b504601Sjiang wu - Sun Microsystems - Beijing China } 18705b504601Sjiang wu - Sun Microsystems - Beijing China } else { 18715b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 18725b504601Sjiang wu - Sun Microsystems - Beijing China } 18735b504601Sjiang wu - Sun Microsystems - Beijing China } 18745b504601Sjiang wu - Sun Microsystems - Beijing China 18755b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 18765b504601Sjiang wu - Sun Microsystems - Beijing China } 18775b504601Sjiang wu - Sun Microsystems - Beijing China 187808eb0b82SYong-Feng Du static int 187908eb0b82SYong-Feng Du mptsas_biospage_3_cb(mptsas_t *mpt, caddr_t page_memp, 188008eb0b82SYong-Feng Du ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo, 188108eb0b82SYong-Feng Du va_list ap) 188208eb0b82SYong-Feng Du { 188308eb0b82SYong-Feng Du #ifndef __lock_lint 188408eb0b82SYong-Feng Du _NOTE(ARGUNUSED(ap)) 188508eb0b82SYong-Feng Du #endif 188608eb0b82SYong-Feng Du pMpi2BiosPage3_t sasbiospage; 188708eb0b82SYong-Feng Du int rval = DDI_SUCCESS; 188808eb0b82SYong-Feng Du uint32_t *bios_version; 188908eb0b82SYong-Feng Du 189008eb0b82SYong-Feng Du if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) && 189108eb0b82SYong-Feng Du (iocstatus != MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)) { 189208eb0b82SYong-Feng Du mptsas_log(mpt, CE_WARN, "mptsas_get_bios_page3 header: " 189308eb0b82SYong-Feng Du "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus, iocloginfo); 189408eb0b82SYong-Feng Du rval = DDI_FAILURE; 189508eb0b82SYong-Feng Du return (rval); 189608eb0b82SYong-Feng Du } 189708eb0b82SYong-Feng Du bios_version = va_arg(ap, uint32_t *); 189808eb0b82SYong-Feng Du sasbiospage = (pMpi2BiosPage3_t)page_memp; 189908eb0b82SYong-Feng Du *bios_version = ddi_get32(accessp, &sasbiospage->BiosVersion); 190008eb0b82SYong-Feng Du 190108eb0b82SYong-Feng Du return (rval); 190208eb0b82SYong-Feng Du } 190308eb0b82SYong-Feng Du 190408eb0b82SYong-Feng Du /* 190508eb0b82SYong-Feng Du * Request MPI configuration page BIOS page 3 to get BIOS version. Since all 190608eb0b82SYong-Feng Du * other information in this page is not needed, just ignore it. 190708eb0b82SYong-Feng Du */ 190808eb0b82SYong-Feng Du int 190908eb0b82SYong-Feng Du mptsas_get_bios_page3(mptsas_t *mpt, uint32_t *bios_version) 191008eb0b82SYong-Feng Du { 191108eb0b82SYong-Feng Du int rval = DDI_SUCCESS; 191208eb0b82SYong-Feng Du 191308eb0b82SYong-Feng Du ASSERT(mutex_owned(&mpt->m_mutex)); 191408eb0b82SYong-Feng Du 191508eb0b82SYong-Feng Du /* 191608eb0b82SYong-Feng Du * Get the header and config page. reply contains the reply frame, 191708eb0b82SYong-Feng Du * which holds status info for the request. 191808eb0b82SYong-Feng Du */ 191908eb0b82SYong-Feng Du rval = mptsas_access_config_page(mpt, 192008eb0b82SYong-Feng Du MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, MPI2_CONFIG_PAGETYPE_BIOS, 3, 192108eb0b82SYong-Feng Du 0, mptsas_biospage_3_cb, bios_version); 192208eb0b82SYong-Feng Du 192308eb0b82SYong-Feng Du return (rval); 192408eb0b82SYong-Feng Du } 192508eb0b82SYong-Feng Du 19265b504601Sjiang wu - Sun Microsystems - Beijing China /* 19275b504601Sjiang wu - Sun Microsystems - Beijing China * Read IO unit page 0 to get information for each PHY. If needed, Read IO Unit 19285b504601Sjiang wu - Sun Microsystems - Beijing China * page1 to update the PHY information. This is the handshaking version of 19295b504601Sjiang wu - Sun Microsystems - Beijing China * this function, which should be called during initialization only. 19305b504601Sjiang wu - Sun Microsystems - Beijing China */ 19315b504601Sjiang wu - Sun Microsystems - Beijing China int 19325b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_sas_io_unit_page_hndshk(mptsas_t *mpt) 19335b504601Sjiang wu - Sun Microsystems - Beijing China { 19345b504601Sjiang wu - Sun Microsystems - Beijing China ddi_dma_attr_t recv_dma_attrs, page_dma_attrs; 1935a9b51062SAda ddi_dma_cookie_t page_cookie; 19365b504601Sjiang wu - Sun Microsystems - Beijing China ddi_dma_handle_t recv_dma_handle, page_dma_handle; 19375b504601Sjiang wu - Sun Microsystems - Beijing China ddi_acc_handle_t recv_accessp, page_accessp; 19385b504601Sjiang wu - Sun Microsystems - Beijing China pMpi2ConfigReply_t configreply; 19395b504601Sjiang wu - Sun Microsystems - Beijing China pMpi2SasIOUnitPage0_t sasioupage0; 19405b504601Sjiang wu - Sun Microsystems - Beijing China pMpi2SasIOUnitPage1_t sasioupage1; 19415b504601Sjiang wu - Sun Microsystems - Beijing China int recv_numbytes; 19425b504601Sjiang wu - Sun Microsystems - Beijing China caddr_t recv_memp, page_memp; 1943e89016e7SRobert Mustacchi uint_t i, num_phys, start_phy = 0; 19445b504601Sjiang wu - Sun Microsystems - Beijing China int page0_size = 19455b504601Sjiang wu - Sun Microsystems - Beijing China sizeof (MPI2_CONFIG_PAGE_SASIOUNIT_0) + 1946cdc7c7feSAda (sizeof (MPI2_SAS_IO_UNIT0_PHY_DATA) * (MPTSAS_MAX_PHYS - 1)); 19475b504601Sjiang wu - Sun Microsystems - Beijing China int page1_size = 19485b504601Sjiang wu - Sun Microsystems - Beijing China sizeof (MPI2_CONFIG_PAGE_SASIOUNIT_1) + 1949cdc7c7feSAda (sizeof (MPI2_SAS_IO_UNIT1_PHY_DATA) * (MPTSAS_MAX_PHYS - 1)); 19505b504601Sjiang wu - Sun Microsystems - Beijing China uint32_t flags_length; 1951cdc7c7feSAda uint32_t cpdi[MPTSAS_MAX_PHYS]; 1952cdc7c7feSAda uint32_t readpage1 = 0, retrypage0 = 0; 19535b504601Sjiang wu - Sun Microsystems - Beijing China uint16_t iocstatus; 19545b504601Sjiang wu - Sun Microsystems - Beijing China uint8_t port_flags, page_number, action; 19555ee44debSRobert Mustacchi uint32_t reply_size; 19565b504601Sjiang wu - Sun Microsystems - Beijing China uint_t state; 19575b504601Sjiang wu - Sun Microsystems - Beijing China int rval = DDI_FAILURE; 1958f7d0d869SDan McDonald boolean_t free_recv = B_FALSE, free_page = B_FALSE; 19595b504601Sjiang wu - Sun Microsystems - Beijing China 19605ee44debSRobert Mustacchi /* 19615ee44debSRobert Mustacchi * We want to find a reply_size that's large enough for the page0 and 19625ee44debSRobert Mustacchi * page1 sizes and resistant to increase in the number of phys. 19635ee44debSRobert Mustacchi */ 19645ee44debSRobert Mustacchi reply_size = MAX(page0_size, page1_size); 19655ee44debSRobert Mustacchi if (P2ROUNDUP(reply_size, 256) <= reply_size) { 19665ee44debSRobert Mustacchi mptsas_log(mpt, CE_WARN, "mptsas_get_sas_io_unit_page_hndsk: " 19675ee44debSRobert Mustacchi "cannot size reply size"); 19685ee44debSRobert Mustacchi goto cleanup; 19695ee44debSRobert Mustacchi } 19705ee44debSRobert Mustacchi 19715b504601Sjiang wu - Sun Microsystems - Beijing China /* 19725b504601Sjiang wu - Sun Microsystems - Beijing China * Initialize our "state machine". This is a bit convoluted, 19735b504601Sjiang wu - Sun Microsystems - Beijing China * but it keeps us from having to do the ddi allocations numerous 19745b504601Sjiang wu - Sun Microsystems - Beijing China * times. 19755b504601Sjiang wu - Sun Microsystems - Beijing China */ 19765b504601Sjiang wu - Sun Microsystems - Beijing China 19775b504601Sjiang wu - Sun Microsystems - Beijing China NDBG20(("mptsas_get_sas_io_unit_page_hndshk enter")); 19785b504601Sjiang wu - Sun Microsystems - Beijing China ASSERT(mutex_owned(&mpt->m_mutex)); 19795b504601Sjiang wu - Sun Microsystems - Beijing China state = IOUC_READ_PAGE0; 19805b504601Sjiang wu - Sun Microsystems - Beijing China 19815b504601Sjiang wu - Sun Microsystems - Beijing China /* 19825b504601Sjiang wu - Sun Microsystems - Beijing China * dynamically create a customized dma attribute structure 19835b504601Sjiang wu - Sun Microsystems - Beijing China * that describes mpt's config reply page request structure. 19845b504601Sjiang wu - Sun Microsystems - Beijing China */ 19855b504601Sjiang wu - Sun Microsystems - Beijing China recv_dma_attrs = mpt->m_msg_dma_attr; 19865b504601Sjiang wu - Sun Microsystems - Beijing China recv_dma_attrs.dma_attr_sgllen = 1; 19875b504601Sjiang wu - Sun Microsystems - Beijing China recv_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_REPLY)); 19885b504601Sjiang wu - Sun Microsystems - Beijing China 1989a9b51062SAda if (mptsas_dma_addr_create(mpt, recv_dma_attrs, 1990a9b51062SAda &recv_dma_handle, &recv_accessp, &recv_memp, 1991a9b51062SAda (sizeof (MPI2_CONFIG_REPLY)), NULL) == FALSE) { 1992a9b51062SAda mptsas_log(mpt, CE_WARN, 1993a9b51062SAda "mptsas_get_sas_io_unit_page_hndshk: recv dma failed"); 19945b504601Sjiang wu - Sun Microsystems - Beijing China goto cleanup; 19955b504601Sjiang wu - Sun Microsystems - Beijing China } 1996f7d0d869SDan McDonald /* Now safe to call mptsas_dma_addr_destroy(recv_dma_handle). */ 1997f7d0d869SDan McDonald free_recv = B_TRUE; 19985b504601Sjiang wu - Sun Microsystems - Beijing China 19995b504601Sjiang wu - Sun Microsystems - Beijing China page_dma_attrs = mpt->m_msg_dma_attr; 20005b504601Sjiang wu - Sun Microsystems - Beijing China page_dma_attrs.dma_attr_sgllen = 1; 20015b504601Sjiang wu - Sun Microsystems - Beijing China page_dma_attrs.dma_attr_granular = reply_size; 20025b504601Sjiang wu - Sun Microsystems - Beijing China 2003a9b51062SAda if (mptsas_dma_addr_create(mpt, page_dma_attrs, 2004a9b51062SAda &page_dma_handle, &page_accessp, &page_memp, 2005a9b51062SAda reply_size, &page_cookie) == FALSE) { 2006a9b51062SAda mptsas_log(mpt, CE_WARN, 2007a9b51062SAda "mptsas_get_sas_io_unit_page_hndshk: page dma failed"); 20085b504601Sjiang wu - Sun Microsystems - Beijing China goto cleanup; 20095b504601Sjiang wu - Sun Microsystems - Beijing China } 2010f7d0d869SDan McDonald /* Now safe to call mptsas_dma_addr_destroy(page_dma_handle). */ 2011f7d0d869SDan McDonald free_page = B_TRUE; 20125b504601Sjiang wu - Sun Microsystems - Beijing China 20135b504601Sjiang wu - Sun Microsystems - Beijing China /* 20145b504601Sjiang wu - Sun Microsystems - Beijing China * Now we cycle through the state machine. Here's what happens: 20155b504601Sjiang wu - Sun Microsystems - Beijing China * 1. Read IO unit page 0 and set phy information 20165b504601Sjiang wu - Sun Microsystems - Beijing China * 2. See if Read IO unit page1 is needed because of port configuration 20175b504601Sjiang wu - Sun Microsystems - Beijing China * 3. Read IO unit page 1 and update phy information. 20185b504601Sjiang wu - Sun Microsystems - Beijing China */ 20195b504601Sjiang wu - Sun Microsystems - Beijing China 20205b504601Sjiang wu - Sun Microsystems - Beijing China sasioupage0 = (pMpi2SasIOUnitPage0_t)page_memp; 20215b504601Sjiang wu - Sun Microsystems - Beijing China sasioupage1 = (pMpi2SasIOUnitPage1_t)page_memp; 20225b504601Sjiang wu - Sun Microsystems - Beijing China 20235b504601Sjiang wu - Sun Microsystems - Beijing China while (state != IOUC_DONE) { 20245b504601Sjiang wu - Sun Microsystems - Beijing China switch (state) { 20255b504601Sjiang wu - Sun Microsystems - Beijing China case IOUC_READ_PAGE0: 20265b504601Sjiang wu - Sun Microsystems - Beijing China page_number = 0; 20275b504601Sjiang wu - Sun Microsystems - Beijing China action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 20285b504601Sjiang wu - Sun Microsystems - Beijing China flags_length = (uint32_t)page0_size; 20295b504601Sjiang wu - Sun Microsystems - Beijing China flags_length |= ((uint32_t)( 20305b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_LAST_ELEMENT | 20315b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_END_OF_BUFFER | 20325b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 20335b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 2034940efceeSAndy Giles MPI2_SGE_FLAGS_64_BIT_ADDRESSING | 20355b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_IOC_TO_HOST | 20365b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_END_OF_LIST) << 20375b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_SHIFT); 20385b504601Sjiang wu - Sun Microsystems - Beijing China 20395b504601Sjiang wu - Sun Microsystems - Beijing China break; 20405b504601Sjiang wu - Sun Microsystems - Beijing China 20415b504601Sjiang wu - Sun Microsystems - Beijing China case IOUC_READ_PAGE1: 20425b504601Sjiang wu - Sun Microsystems - Beijing China page_number = 1; 20435b504601Sjiang wu - Sun Microsystems - Beijing China action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 20445b504601Sjiang wu - Sun Microsystems - Beijing China flags_length = (uint32_t)page1_size; 20455b504601Sjiang wu - Sun Microsystems - Beijing China flags_length |= ((uint32_t)( 20465b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_LAST_ELEMENT | 20475b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_END_OF_BUFFER | 20485b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 20495b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 2050940efceeSAndy Giles MPI2_SGE_FLAGS_64_BIT_ADDRESSING | 20515b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_IOC_TO_HOST | 20525b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_END_OF_LIST) << 20535b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_SHIFT); 20545b504601Sjiang wu - Sun Microsystems - Beijing China 20555b504601Sjiang wu - Sun Microsystems - Beijing China break; 20565b504601Sjiang wu - Sun Microsystems - Beijing China default: 20575b504601Sjiang wu - Sun Microsystems - Beijing China break; 20585b504601Sjiang wu - Sun Microsystems - Beijing China } 20595b504601Sjiang wu - Sun Microsystems - Beijing China 20605b504601Sjiang wu - Sun Microsystems - Beijing China bzero(recv_memp, sizeof (MPI2_CONFIG_REPLY)); 20615b504601Sjiang wu - Sun Microsystems - Beijing China configreply = (pMpi2ConfigReply_t)recv_memp; 20625b504601Sjiang wu - Sun Microsystems - Beijing China recv_numbytes = sizeof (MPI2_CONFIG_REPLY); 20635b504601Sjiang wu - Sun Microsystems - Beijing China 20645b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_send_extended_config_request_msg(mpt, 20655b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_CONFIG_ACTION_PAGE_HEADER, 20665b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 20675b504601Sjiang wu - Sun Microsystems - Beijing China 0, page_number, 0, 0, 0, 0)) { 20685b504601Sjiang wu - Sun Microsystems - Beijing China goto cleanup; 20695b504601Sjiang wu - Sun Microsystems - Beijing China } 20705b504601Sjiang wu - Sun Microsystems - Beijing China 20715b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes, 20725b504601Sjiang wu - Sun Microsystems - Beijing China recv_accessp)) { 20735b504601Sjiang wu - Sun Microsystems - Beijing China goto cleanup; 20745b504601Sjiang wu - Sun Microsystems - Beijing China } 20755b504601Sjiang wu - Sun Microsystems - Beijing China 20765b504601Sjiang wu - Sun Microsystems - Beijing China iocstatus = ddi_get16(recv_accessp, &configreply->IOCStatus); 20775b504601Sjiang wu - Sun Microsystems - Beijing China iocstatus = MPTSAS_IOCSTATUS(iocstatus); 20785b504601Sjiang wu - Sun Microsystems - Beijing China 20795b504601Sjiang wu - Sun Microsystems - Beijing China if (iocstatus != MPI2_IOCSTATUS_SUCCESS) { 20805b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, 20815b504601Sjiang wu - Sun Microsystems - Beijing China "mptsas_get_sas_io_unit_page_hndshk: read page " 20825b504601Sjiang wu - Sun Microsystems - Beijing China "header iocstatus = 0x%x", iocstatus); 20835b504601Sjiang wu - Sun Microsystems - Beijing China goto cleanup; 20845b504601Sjiang wu - Sun Microsystems - Beijing China } 20855b504601Sjiang wu - Sun Microsystems - Beijing China 20865b504601Sjiang wu - Sun Microsystems - Beijing China if (action != MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) { 20875b504601Sjiang wu - Sun Microsystems - Beijing China bzero(page_memp, reply_size); 20885b504601Sjiang wu - Sun Microsystems - Beijing China } 20895b504601Sjiang wu - Sun Microsystems - Beijing China 20905b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_send_extended_config_request_msg(mpt, action, 20915b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 0, page_number, 20925b504601Sjiang wu - Sun Microsystems - Beijing China ddi_get8(recv_accessp, &configreply->Header.PageVersion), 20935b504601Sjiang wu - Sun Microsystems - Beijing China ddi_get16(recv_accessp, &configreply->ExtPageLength), 2094940efceeSAndy Giles flags_length, page_cookie.dmac_laddress)) { 20955b504601Sjiang wu - Sun Microsystems - Beijing China goto cleanup; 20965b504601Sjiang wu - Sun Microsystems - Beijing China } 20975b504601Sjiang wu - Sun Microsystems - Beijing China 20985b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes, 20995b504601Sjiang wu - Sun Microsystems - Beijing China recv_accessp)) { 21005b504601Sjiang wu - Sun Microsystems - Beijing China goto cleanup; 21015b504601Sjiang wu - Sun Microsystems - Beijing China } 21025b504601Sjiang wu - Sun Microsystems - Beijing China 21035b504601Sjiang wu - Sun Microsystems - Beijing China iocstatus = ddi_get16(recv_accessp, &configreply->IOCStatus); 21045b504601Sjiang wu - Sun Microsystems - Beijing China iocstatus = MPTSAS_IOCSTATUS(iocstatus); 21055b504601Sjiang wu - Sun Microsystems - Beijing China 21065b504601Sjiang wu - Sun Microsystems - Beijing China if (iocstatus != MPI2_IOCSTATUS_SUCCESS) { 21075b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, 21085b504601Sjiang wu - Sun Microsystems - Beijing China "mptsas_get_sas_io_unit_page_hndshk: IO unit " 21095b504601Sjiang wu - Sun Microsystems - Beijing China "config failed for action %d, iocstatus = 0x%x", 21105b504601Sjiang wu - Sun Microsystems - Beijing China action, iocstatus); 21115b504601Sjiang wu - Sun Microsystems - Beijing China goto cleanup; 21125b504601Sjiang wu - Sun Microsystems - Beijing China } 21135b504601Sjiang wu - Sun Microsystems - Beijing China 21145b504601Sjiang wu - Sun Microsystems - Beijing China switch (state) { 21155b504601Sjiang wu - Sun Microsystems - Beijing China case IOUC_READ_PAGE0: 21165b504601Sjiang wu - Sun Microsystems - Beijing China if ((ddi_dma_sync(page_dma_handle, 0, 0, 21175b504601Sjiang wu - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORCPU)) != DDI_SUCCESS) { 21185b504601Sjiang wu - Sun Microsystems - Beijing China goto cleanup; 21195b504601Sjiang wu - Sun Microsystems - Beijing China } 21205b504601Sjiang wu - Sun Microsystems - Beijing China 21215b504601Sjiang wu - Sun Microsystems - Beijing China num_phys = ddi_get8(page_accessp, 21225b504601Sjiang wu - Sun Microsystems - Beijing China &sasioupage0->NumPhys); 2123cdc7c7feSAda if (num_phys > MPTSAS_MAX_PHYS) { 2124cdc7c7feSAda mptsas_log(mpt, CE_WARN, "Number of phys " 2125cdc7c7feSAda "supported by HBA (%d) is more than max " 2126cdc7c7feSAda "supported by driver (%d). Driver will " 2127cdc7c7feSAda "not attach.", num_phys, 2128cdc7c7feSAda MPTSAS_MAX_PHYS); 2129cdc7c7feSAda rval = DDI_FAILURE; 2130cdc7c7feSAda goto cleanup; 2131cdc7c7feSAda } 2132e89016e7SRobert Mustacchi if (num_phys > mpt->m_num_phys) { 2133e89016e7SRobert Mustacchi mptsas_log(mpt, CE_WARN, "Number of phys " 2134e89016e7SRobert Mustacchi "reported by HBA SAS IO Unit Page 0 (%u) " 2135e89016e7SRobert Mustacchi "is greater than that reported by the " 2136e89016e7SRobert Mustacchi "manufacturing information (%u). Driver " 2137e89016e7SRobert Mustacchi "phy count limited to %u. Please contact " 2138e89016e7SRobert Mustacchi "the firmware vendor about this.", num_phys, 2139e89016e7SRobert Mustacchi mpt->m_num_phys, mpt->m_num_phys); 2140e89016e7SRobert Mustacchi num_phys = mpt->m_num_phys; 2141e89016e7SRobert Mustacchi } else if (num_phys < mpt->m_num_phys) { 2142e89016e7SRobert Mustacchi mptsas_log(mpt, CE_WARN, "Number of phys " 2143e89016e7SRobert Mustacchi "reported by HBA SAS IO Unit Page 0 (%u) " 2144e89016e7SRobert Mustacchi "is less than that reported by the " 2145e89016e7SRobert Mustacchi "manufacturing information (%u). Driver " 2146e89016e7SRobert Mustacchi "will not attach. Please contact the " 2147e89016e7SRobert Mustacchi "firmware vendor about this.", num_phys, 2148e89016e7SRobert Mustacchi mpt->m_num_phys); 2149e89016e7SRobert Mustacchi rval = DDI_FAILURE; 2150e89016e7SRobert Mustacchi goto cleanup; 2151e89016e7SRobert Mustacchi } 2152cdc7c7feSAda for (i = start_phy; i < num_phys; i++, start_phy = i) { 21535b504601Sjiang wu - Sun Microsystems - Beijing China cpdi[i] = ddi_get32(page_accessp, 21545b504601Sjiang wu - Sun Microsystems - Beijing China &sasioupage0->PhyData[i]. 21555b504601Sjiang wu - Sun Microsystems - Beijing China ControllerPhyDeviceInfo); 21565b504601Sjiang wu - Sun Microsystems - Beijing China port_flags = ddi_get8(page_accessp, 21575b504601Sjiang wu - Sun Microsystems - Beijing China &sasioupage0->PhyData[i].PortFlags); 21585b504601Sjiang wu - Sun Microsystems - Beijing China 21595b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_phy_info[i].port_num = 21605b504601Sjiang wu - Sun Microsystems - Beijing China ddi_get8(page_accessp, 21615b504601Sjiang wu - Sun Microsystems - Beijing China &sasioupage0->PhyData[i].Port); 21625b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_phy_info[i].ctrl_devhdl = 21635b504601Sjiang wu - Sun Microsystems - Beijing China ddi_get16(page_accessp, &sasioupage0-> 21645b504601Sjiang wu - Sun Microsystems - Beijing China PhyData[i].ControllerDevHandle); 21655b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_phy_info[i].attached_devhdl = 21665b504601Sjiang wu - Sun Microsystems - Beijing China ddi_get16(page_accessp, &sasioupage0-> 21675b504601Sjiang wu - Sun Microsystems - Beijing China PhyData[i].AttachedDevHandle); 21685b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_phy_info[i].phy_device_type = cpdi[i]; 21695b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_phy_info[i].port_flags = port_flags; 21705b504601Sjiang wu - Sun Microsystems - Beijing China 21715b504601Sjiang wu - Sun Microsystems - Beijing China if (port_flags & DISCOVERY_IN_PROGRESS) { 21725b504601Sjiang wu - Sun Microsystems - Beijing China retrypage0++; 21735b504601Sjiang wu - Sun Microsystems - Beijing China NDBG20(("Discovery in progress, can't " 21745b504601Sjiang wu - Sun Microsystems - Beijing China "verify IO unit config, then NO.%d" 21755b504601Sjiang wu - Sun Microsystems - Beijing China " times retry", retrypage0)); 21765b504601Sjiang wu - Sun Microsystems - Beijing China break; 21775b504601Sjiang wu - Sun Microsystems - Beijing China } else { 21785b504601Sjiang wu - Sun Microsystems - Beijing China retrypage0 = 0; 21795b504601Sjiang wu - Sun Microsystems - Beijing China } 21805b504601Sjiang wu - Sun Microsystems - Beijing China if (!(port_flags & AUTO_PORT_CONFIGURATION)) { 21815b504601Sjiang wu - Sun Microsystems - Beijing China /* 21825b504601Sjiang wu - Sun Microsystems - Beijing China * some PHY configuration described in 21835b504601Sjiang wu - Sun Microsystems - Beijing China * SAS IO Unit Page1 21845b504601Sjiang wu - Sun Microsystems - Beijing China */ 21855b504601Sjiang wu - Sun Microsystems - Beijing China readpage1 = 1; 21865b504601Sjiang wu - Sun Microsystems - Beijing China } 21875b504601Sjiang wu - Sun Microsystems - Beijing China } 21885b504601Sjiang wu - Sun Microsystems - Beijing China 21895b504601Sjiang wu - Sun Microsystems - Beijing China /* 21905b504601Sjiang wu - Sun Microsystems - Beijing China * retry 30 times if discovery is in process 21915b504601Sjiang wu - Sun Microsystems - Beijing China */ 21925b504601Sjiang wu - Sun Microsystems - Beijing China if (retrypage0 && (retrypage0 < 30)) { 21935b504601Sjiang wu - Sun Microsystems - Beijing China drv_usecwait(1000 * 100); 21945b504601Sjiang wu - Sun Microsystems - Beijing China state = IOUC_READ_PAGE0; 21955b504601Sjiang wu - Sun Microsystems - Beijing China break; 21965b504601Sjiang wu - Sun Microsystems - Beijing China } else if (retrypage0 == 30) { 21975b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, 21985b504601Sjiang wu - Sun Microsystems - Beijing China "!Discovery in progress, can't " 21995b504601Sjiang wu - Sun Microsystems - Beijing China "verify IO unit config, then after" 22005b504601Sjiang wu - Sun Microsystems - Beijing China " 30 times retry, give up!"); 22015b504601Sjiang wu - Sun Microsystems - Beijing China state = IOUC_DONE; 22025b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 22035b504601Sjiang wu - Sun Microsystems - Beijing China break; 22045b504601Sjiang wu - Sun Microsystems - Beijing China } 22055b504601Sjiang wu - Sun Microsystems - Beijing China 22065b504601Sjiang wu - Sun Microsystems - Beijing China if (readpage1 == 0) { 22075b504601Sjiang wu - Sun Microsystems - Beijing China state = IOUC_DONE; 22085b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_SUCCESS; 22095b504601Sjiang wu - Sun Microsystems - Beijing China break; 22105b504601Sjiang wu - Sun Microsystems - Beijing China } 22115b504601Sjiang wu - Sun Microsystems - Beijing China 22125b504601Sjiang wu - Sun Microsystems - Beijing China state = IOUC_READ_PAGE1; 22135b504601Sjiang wu - Sun Microsystems - Beijing China break; 22145b504601Sjiang wu - Sun Microsystems - Beijing China 22155b504601Sjiang wu - Sun Microsystems - Beijing China case IOUC_READ_PAGE1: 22165b504601Sjiang wu - Sun Microsystems - Beijing China if ((ddi_dma_sync(page_dma_handle, 0, 0, 22175b504601Sjiang wu - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORCPU)) != DDI_SUCCESS) { 22185b504601Sjiang wu - Sun Microsystems - Beijing China goto cleanup; 22195b504601Sjiang wu - Sun Microsystems - Beijing China } 22205b504601Sjiang wu - Sun Microsystems - Beijing China 22215b504601Sjiang wu - Sun Microsystems - Beijing China num_phys = ddi_get8(page_accessp, 22225b504601Sjiang wu - Sun Microsystems - Beijing China &sasioupage1->NumPhys); 2223cdc7c7feSAda if (num_phys > MPTSAS_MAX_PHYS) { 2224cdc7c7feSAda mptsas_log(mpt, CE_WARN, "Number of phys " 2225cdc7c7feSAda "supported by HBA (%d) is more than max " 2226cdc7c7feSAda "supported by driver (%d). Driver will " 2227cdc7c7feSAda "not attach.", num_phys, 2228cdc7c7feSAda MPTSAS_MAX_PHYS); 2229cdc7c7feSAda rval = DDI_FAILURE; 2230cdc7c7feSAda goto cleanup; 2231cdc7c7feSAda } 2232e89016e7SRobert Mustacchi if (num_phys > mpt->m_num_phys) { 2233e89016e7SRobert Mustacchi mptsas_log(mpt, CE_WARN, "Number of phys " 2234e89016e7SRobert Mustacchi "reported by HBA SAS IO Unit Page 1 (%u) " 2235e89016e7SRobert Mustacchi "is greater than that reported by the " 2236e89016e7SRobert Mustacchi "manufacturing information (%u). Limiting " 2237e89016e7SRobert Mustacchi "phy count to %u. Please contact the " 2238e89016e7SRobert Mustacchi "firmware vendor about this.", num_phys, 2239e89016e7SRobert Mustacchi mpt->m_num_phys, mpt->m_num_phys); 2240e89016e7SRobert Mustacchi num_phys = mpt->m_num_phys; 2241e89016e7SRobert Mustacchi } else if (num_phys < mpt->m_num_phys) { 2242e89016e7SRobert Mustacchi mptsas_log(mpt, CE_WARN, "Number of phys " 2243e89016e7SRobert Mustacchi "reported by HBA SAS IO Unit Page 1 (%u) " 2244e89016e7SRobert Mustacchi "is less than that reported by the " 2245e89016e7SRobert Mustacchi "manufacturing information (%u). Driver " 2246e89016e7SRobert Mustacchi "will not attach. Please contact the " 2247e89016e7SRobert Mustacchi "firmware vendor about this.", num_phys, 2248e89016e7SRobert Mustacchi mpt->m_num_phys); 2249e89016e7SRobert Mustacchi rval = DDI_FAILURE; 2250e89016e7SRobert Mustacchi goto cleanup; 2251e89016e7SRobert Mustacchi } 22525b504601Sjiang wu - Sun Microsystems - Beijing China for (i = 0; i < num_phys; i++) { 22535b504601Sjiang wu - Sun Microsystems - Beijing China cpdi[i] = ddi_get32(page_accessp, 22545b504601Sjiang wu - Sun Microsystems - Beijing China &sasioupage1->PhyData[i]. 22555b504601Sjiang wu - Sun Microsystems - Beijing China ControllerPhyDeviceInfo); 22565b504601Sjiang wu - Sun Microsystems - Beijing China port_flags = ddi_get8(page_accessp, 22575b504601Sjiang wu - Sun Microsystems - Beijing China &sasioupage1->PhyData[i].PortFlags); 22585b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_phy_info[i].port_num = 22595b504601Sjiang wu - Sun Microsystems - Beijing China ddi_get8(page_accessp, 22605b504601Sjiang wu - Sun Microsystems - Beijing China &sasioupage1->PhyData[i].Port); 22615b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_phy_info[i].port_flags = port_flags; 22625b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_phy_info[i].phy_device_type = cpdi[i]; 22635b504601Sjiang wu - Sun Microsystems - Beijing China 22645b504601Sjiang wu - Sun Microsystems - Beijing China } 22655b504601Sjiang wu - Sun Microsystems - Beijing China 22665b504601Sjiang wu - Sun Microsystems - Beijing China state = IOUC_DONE; 22675b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_SUCCESS; 22685b504601Sjiang wu - Sun Microsystems - Beijing China break; 22695b504601Sjiang wu - Sun Microsystems - Beijing China } 22705b504601Sjiang wu - Sun Microsystems - Beijing China } 22715b504601Sjiang wu - Sun Microsystems - Beijing China if ((mptsas_check_dma_handle(recv_dma_handle) != DDI_SUCCESS) || 22725b504601Sjiang wu - Sun Microsystems - Beijing China (mptsas_check_dma_handle(page_dma_handle) != DDI_SUCCESS)) { 22735b504601Sjiang wu - Sun Microsystems - Beijing China ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 22745b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 22755b504601Sjiang wu - Sun Microsystems - Beijing China goto cleanup; 22765b504601Sjiang wu - Sun Microsystems - Beijing China } 22775b504601Sjiang wu - Sun Microsystems - Beijing China if ((mptsas_check_acc_handle(recv_accessp) != DDI_SUCCESS) || 22785b504601Sjiang wu - Sun Microsystems - Beijing China (mptsas_check_acc_handle(page_accessp) != DDI_SUCCESS)) { 22795b504601Sjiang wu - Sun Microsystems - Beijing China ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 22805b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 22815b504601Sjiang wu - Sun Microsystems - Beijing China goto cleanup; 22825b504601Sjiang wu - Sun Microsystems - Beijing China } 22835b504601Sjiang wu - Sun Microsystems - Beijing China 22845b504601Sjiang wu - Sun Microsystems - Beijing China cleanup: 2285f7d0d869SDan McDonald if (free_recv) 2286f7d0d869SDan McDonald mptsas_dma_addr_destroy(&recv_dma_handle, &recv_accessp); 2287f7d0d869SDan McDonald if (free_page) 2288f7d0d869SDan McDonald mptsas_dma_addr_destroy(&page_dma_handle, &page_accessp); 22895b504601Sjiang wu - Sun Microsystems - Beijing China if (rval != DDI_SUCCESS) { 22905b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); 22915b504601Sjiang wu - Sun Microsystems - Beijing China ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); 22925b504601Sjiang wu - Sun Microsystems - Beijing China } 22935b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 22945b504601Sjiang wu - Sun Microsystems - Beijing China } 22955b504601Sjiang wu - Sun Microsystems - Beijing China 22965b504601Sjiang wu - Sun Microsystems - Beijing China /* 22975b504601Sjiang wu - Sun Microsystems - Beijing China * mptsas_get_manufacture_page5 22985b504601Sjiang wu - Sun Microsystems - Beijing China * 22995b504601Sjiang wu - Sun Microsystems - Beijing China * This function will retrieve the base WWID from the adapter. Since this 23005b504601Sjiang wu - Sun Microsystems - Beijing China * function is only called during the initialization process, use handshaking. 23015b504601Sjiang wu - Sun Microsystems - Beijing China */ 23025b504601Sjiang wu - Sun Microsystems - Beijing China int 23035b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_get_manufacture_page5(mptsas_t *mpt) 23045b504601Sjiang wu - Sun Microsystems - Beijing China { 23055b504601Sjiang wu - Sun Microsystems - Beijing China ddi_dma_attr_t recv_dma_attrs, page_dma_attrs; 2306a9b51062SAda ddi_dma_cookie_t page_cookie; 23075b504601Sjiang wu - Sun Microsystems - Beijing China ddi_dma_handle_t recv_dma_handle, page_dma_handle; 23085b504601Sjiang wu - Sun Microsystems - Beijing China ddi_acc_handle_t recv_accessp, page_accessp; 23095b504601Sjiang wu - Sun Microsystems - Beijing China pMpi2ConfigReply_t configreply; 23105b504601Sjiang wu - Sun Microsystems - Beijing China caddr_t recv_memp, page_memp; 23115b504601Sjiang wu - Sun Microsystems - Beijing China int recv_numbytes; 23125b504601Sjiang wu - Sun Microsystems - Beijing China pMpi2ManufacturingPage5_t m5; 23135b504601Sjiang wu - Sun Microsystems - Beijing China uint32_t flagslength; 23145b504601Sjiang wu - Sun Microsystems - Beijing China int rval = DDI_SUCCESS; 23155b504601Sjiang wu - Sun Microsystems - Beijing China uint_t iocstatus; 2316f7d0d869SDan McDonald boolean_t free_recv = B_FALSE, free_page = B_FALSE; 23175b504601Sjiang wu - Sun Microsystems - Beijing China 23185b504601Sjiang wu - Sun Microsystems - Beijing China MPTSAS_DISABLE_INTR(mpt); 23195b504601Sjiang wu - Sun Microsystems - Beijing China 23205b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_send_config_request_msg(mpt, MPI2_CONFIG_ACTION_PAGE_HEADER, 23215b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_CONFIG_PAGETYPE_MANUFACTURING, 0, 5, 0, 0, 0, 0)) { 23225b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 23235b504601Sjiang wu - Sun Microsystems - Beijing China goto done; 23245b504601Sjiang wu - Sun Microsystems - Beijing China } 23255b504601Sjiang wu - Sun Microsystems - Beijing China 23265b504601Sjiang wu - Sun Microsystems - Beijing China /* 23275b504601Sjiang wu - Sun Microsystems - Beijing China * dynamically create a customized dma attribute structure 23285b504601Sjiang wu - Sun Microsystems - Beijing China * that describes the MPT's config reply page request structure. 23295b504601Sjiang wu - Sun Microsystems - Beijing China */ 23305b504601Sjiang wu - Sun Microsystems - Beijing China recv_dma_attrs = mpt->m_msg_dma_attr; 23315b504601Sjiang wu - Sun Microsystems - Beijing China recv_dma_attrs.dma_attr_sgllen = 1; 23325b504601Sjiang wu - Sun Microsystems - Beijing China recv_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_REPLY)); 23335b504601Sjiang wu - Sun Microsystems - Beijing China 2334a9b51062SAda if (mptsas_dma_addr_create(mpt, recv_dma_attrs, 2335a9b51062SAda &recv_dma_handle, &recv_accessp, &recv_memp, 2336a9b51062SAda (sizeof (MPI2_CONFIG_REPLY)), NULL) == FALSE) { 2337f7d0d869SDan McDonald rval = DDI_FAILURE; 23385b504601Sjiang wu - Sun Microsystems - Beijing China goto done; 23395b504601Sjiang wu - Sun Microsystems - Beijing China } 2340f7d0d869SDan McDonald /* Now safe to call mptsas_dma_addr_destroy(recv_dma_handle). */ 2341f7d0d869SDan McDonald free_recv = B_TRUE; 23425b504601Sjiang wu - Sun Microsystems - Beijing China 23435b504601Sjiang wu - Sun Microsystems - Beijing China bzero(recv_memp, sizeof (MPI2_CONFIG_REPLY)); 23445b504601Sjiang wu - Sun Microsystems - Beijing China configreply = (pMpi2ConfigReply_t)recv_memp; 23455b504601Sjiang wu - Sun Microsystems - Beijing China recv_numbytes = sizeof (MPI2_CONFIG_REPLY); 23465b504601Sjiang wu - Sun Microsystems - Beijing China 23475b504601Sjiang wu - Sun Microsystems - Beijing China /* 23485b504601Sjiang wu - Sun Microsystems - Beijing China * get config reply message 23495b504601Sjiang wu - Sun Microsystems - Beijing China */ 23505b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes, 23515b504601Sjiang wu - Sun Microsystems - Beijing China recv_accessp)) { 23525b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 23535b504601Sjiang wu - Sun Microsystems - Beijing China goto done; 23545b504601Sjiang wu - Sun Microsystems - Beijing China } 23555b504601Sjiang wu - Sun Microsystems - Beijing China 2356e89016e7SRobert Mustacchi if ((iocstatus = ddi_get16(recv_accessp, &configreply->IOCStatus)) != 2357e89016e7SRobert Mustacchi 0) { 23585b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "mptsas_get_manufacture_page5 update: " 23595b504601Sjiang wu - Sun Microsystems - Beijing China "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus, 23605b504601Sjiang wu - Sun Microsystems - Beijing China ddi_get32(recv_accessp, &configreply->IOCLogInfo)); 23615b504601Sjiang wu - Sun Microsystems - Beijing China goto done; 23625b504601Sjiang wu - Sun Microsystems - Beijing China } 23635b504601Sjiang wu - Sun Microsystems - Beijing China 23645b504601Sjiang wu - Sun Microsystems - Beijing China /* 23655b504601Sjiang wu - Sun Microsystems - Beijing China * dynamically create a customized dma attribute structure 23665b504601Sjiang wu - Sun Microsystems - Beijing China * that describes the MPT's config page structure. 23675b504601Sjiang wu - Sun Microsystems - Beijing China */ 23685b504601Sjiang wu - Sun Microsystems - Beijing China page_dma_attrs = mpt->m_msg_dma_attr; 23695b504601Sjiang wu - Sun Microsystems - Beijing China page_dma_attrs.dma_attr_sgllen = 1; 23705b504601Sjiang wu - Sun Microsystems - Beijing China page_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_PAGE_MAN_5)); 23715b504601Sjiang wu - Sun Microsystems - Beijing China 2372a9b51062SAda if (mptsas_dma_addr_create(mpt, page_dma_attrs, &page_dma_handle, 2373a9b51062SAda &page_accessp, &page_memp, (sizeof (MPI2_CONFIG_PAGE_MAN_5)), 2374a9b51062SAda &page_cookie) == FALSE) { 2375f7d0d869SDan McDonald rval = DDI_FAILURE; 23765b504601Sjiang wu - Sun Microsystems - Beijing China goto done; 23775b504601Sjiang wu - Sun Microsystems - Beijing China } 2378f7d0d869SDan McDonald /* Now safe to call mptsas_dma_addr_destroy(page_dma_handle). */ 2379f7d0d869SDan McDonald free_page = B_TRUE; 2380f7d0d869SDan McDonald 23815b504601Sjiang wu - Sun Microsystems - Beijing China bzero(page_memp, sizeof (MPI2_CONFIG_PAGE_MAN_5)); 23825b504601Sjiang wu - Sun Microsystems - Beijing China m5 = (pMpi2ManufacturingPage5_t)page_memp; 2383940efceeSAndy Giles NDBG20(("mptsas_get_manufacture_page5: paddr 0x%p", 2384940efceeSAndy Giles (void *)(uintptr_t)page_cookie.dmac_laddress)); 23855b504601Sjiang wu - Sun Microsystems - Beijing China 23865b504601Sjiang wu - Sun Microsystems - Beijing China /* 23875b504601Sjiang wu - Sun Microsystems - Beijing China * Give reply address to IOC to store config page in and send 23885b504601Sjiang wu - Sun Microsystems - Beijing China * config request out. 23895b504601Sjiang wu - Sun Microsystems - Beijing China */ 23905b504601Sjiang wu - Sun Microsystems - Beijing China 23915b504601Sjiang wu - Sun Microsystems - Beijing China flagslength = sizeof (MPI2_CONFIG_PAGE_MAN_5); 23925b504601Sjiang wu - Sun Microsystems - Beijing China flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT | 23935b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 2394940efceeSAndy Giles MPI2_SGE_FLAGS_SYSTEM_ADDRESS | MPI2_SGE_FLAGS_64_BIT_ADDRESSING | 23955b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_IOC_TO_HOST | 23965b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); 23975b504601Sjiang wu - Sun Microsystems - Beijing China 23985b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_send_config_request_msg(mpt, 23995b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, 24005b504601Sjiang wu - Sun Microsystems - Beijing China MPI2_CONFIG_PAGETYPE_MANUFACTURING, 0, 5, 24015b504601Sjiang wu - Sun Microsystems - Beijing China ddi_get8(recv_accessp, &configreply->Header.PageVersion), 24025b504601Sjiang wu - Sun Microsystems - Beijing China ddi_get8(recv_accessp, &configreply->Header.PageLength), 2403940efceeSAndy Giles flagslength, page_cookie.dmac_laddress)) { 24045b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 24055b504601Sjiang wu - Sun Microsystems - Beijing China goto done; 24065b504601Sjiang wu - Sun Microsystems - Beijing China } 24075b504601Sjiang wu - Sun Microsystems - Beijing China 24085b504601Sjiang wu - Sun Microsystems - Beijing China /* 24095b504601Sjiang wu - Sun Microsystems - Beijing China * get reply view handshake 24105b504601Sjiang wu - Sun Microsystems - Beijing China */ 24115b504601Sjiang wu - Sun Microsystems - Beijing China if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes, 24125b504601Sjiang wu - Sun Microsystems - Beijing China recv_accessp)) { 24135b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 24145b504601Sjiang wu - Sun Microsystems - Beijing China goto done; 24155b504601Sjiang wu - Sun Microsystems - Beijing China } 24165b504601Sjiang wu - Sun Microsystems - Beijing China 2417e89016e7SRobert Mustacchi if ((iocstatus = ddi_get16(recv_accessp, &configreply->IOCStatus)) != 2418e89016e7SRobert Mustacchi 0) { 24195b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "mptsas_get_manufacture_page5 config: " 24205b504601Sjiang wu - Sun Microsystems - Beijing China "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus, 24215b504601Sjiang wu - Sun Microsystems - Beijing China ddi_get32(recv_accessp, &configreply->IOCLogInfo)); 24225b504601Sjiang wu - Sun Microsystems - Beijing China goto done; 24235b504601Sjiang wu - Sun Microsystems - Beijing China } 24245b504601Sjiang wu - Sun Microsystems - Beijing China 24255b504601Sjiang wu - Sun Microsystems - Beijing China (void) ddi_dma_sync(page_dma_handle, 0, 0, DDI_DMA_SYNC_FORCPU); 24265b504601Sjiang wu - Sun Microsystems - Beijing China 24275b504601Sjiang wu - Sun Microsystems - Beijing China /* 24285b504601Sjiang wu - Sun Microsystems - Beijing China * Fusion-MPT stores fields in little-endian format. This is 24295b504601Sjiang wu - Sun Microsystems - Beijing China * why the low-order 32 bits are stored first. 24305b504601Sjiang wu - Sun Microsystems - Beijing China */ 24315b504601Sjiang wu - Sun Microsystems - Beijing China mpt->un.sasaddr.m_base_wwid_lo = 24325b504601Sjiang wu - Sun Microsystems - Beijing China ddi_get32(page_accessp, (uint32_t *)(void *)&m5->Phy[0].WWID); 24335b504601Sjiang wu - Sun Microsystems - Beijing China mpt->un.sasaddr.m_base_wwid_hi = 24345b504601Sjiang wu - Sun Microsystems - Beijing China ddi_get32(page_accessp, (uint32_t *)(void *)&m5->Phy[0].WWID + 1); 24355b504601Sjiang wu - Sun Microsystems - Beijing China 24365b504601Sjiang wu - Sun Microsystems - Beijing China if (ddi_prop_update_int64(DDI_DEV_T_NONE, mpt->m_dip, 24375b504601Sjiang wu - Sun Microsystems - Beijing China "base-wwid", mpt->un.m_base_wwid) != DDI_PROP_SUCCESS) { 24385b504601Sjiang wu - Sun Microsystems - Beijing China NDBG2(("%s%d: failed to create base-wwid property", 24395b504601Sjiang wu - Sun Microsystems - Beijing China ddi_driver_name(mpt->m_dip), ddi_get_instance(mpt->m_dip))); 24405b504601Sjiang wu - Sun Microsystems - Beijing China } 24415b504601Sjiang wu - Sun Microsystems - Beijing China 24425b504601Sjiang wu - Sun Microsystems - Beijing China /* 24435b504601Sjiang wu - Sun Microsystems - Beijing China * Set the number of PHYs present. 24445b504601Sjiang wu - Sun Microsystems - Beijing China */ 24455b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_num_phys = ddi_get8(page_accessp, (uint8_t *)&m5->NumPhys); 24465b504601Sjiang wu - Sun Microsystems - Beijing China 24475b504601Sjiang wu - Sun Microsystems - Beijing China if (ddi_prop_update_int(DDI_DEV_T_NONE, mpt->m_dip, 24485b504601Sjiang wu - Sun Microsystems - Beijing China "num-phys", mpt->m_num_phys) != DDI_PROP_SUCCESS) { 24495b504601Sjiang wu - Sun Microsystems - Beijing China NDBG2(("%s%d: failed to create num-phys property", 24505b504601Sjiang wu - Sun Microsystems - Beijing China ddi_driver_name(mpt->m_dip), ddi_get_instance(mpt->m_dip))); 24515b504601Sjiang wu - Sun Microsystems - Beijing China } 24525b504601Sjiang wu - Sun Microsystems - Beijing China 24535b504601Sjiang wu - Sun Microsystems - Beijing China mptsas_log(mpt, CE_NOTE, "!mpt%d: Initiator WWNs: 0x%016llx-0x%016llx", 24545b504601Sjiang wu - Sun Microsystems - Beijing China mpt->m_instance, (unsigned long long)mpt->un.m_base_wwid, 24555b504601Sjiang wu - Sun Microsystems - Beijing China (unsigned long long)mpt->un.m_base_wwid + mpt->m_num_phys - 1); 24565b504601Sjiang wu - Sun Microsystems - Beijing China 24575b504601Sjiang wu - Sun Microsystems - Beijing China if ((mptsas_check_dma_handle(recv_dma_handle) != DDI_SUCCESS) || 2458f2e8686eSxun ni - Sun Microsystems - Beijing China (mptsas_check_dma_handle(page_dma_handle) != DDI_SUCCESS)) { 2459f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 2460f2e8686eSxun ni - Sun Microsystems - Beijing China rval = DDI_FAILURE; 2461f2e8686eSxun ni - Sun Microsystems - Beijing China goto done; 2462f2e8686eSxun ni - Sun Microsystems - Beijing China } 2463f2e8686eSxun ni - Sun Microsystems - Beijing China if ((mptsas_check_acc_handle(recv_accessp) != DDI_SUCCESS) || 2464f2e8686eSxun ni - Sun Microsystems - Beijing China (mptsas_check_acc_handle(page_accessp) != DDI_SUCCESS)) { 2465f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 2466f2e8686eSxun ni - Sun Microsystems - Beijing China rval = DDI_FAILURE; 2467f2e8686eSxun ni - Sun Microsystems - Beijing China } 2468f2e8686eSxun ni - Sun Microsystems - Beijing China done: 2469f2e8686eSxun ni - Sun Microsystems - Beijing China /* 2470f2e8686eSxun ni - Sun Microsystems - Beijing China * free up memory 2471f2e8686eSxun ni - Sun Microsystems - Beijing China */ 2472f7d0d869SDan McDonald if (free_recv) 2473f7d0d869SDan McDonald mptsas_dma_addr_destroy(&recv_dma_handle, &recv_accessp); 2474f7d0d869SDan McDonald if (free_page) 2475f7d0d869SDan McDonald mptsas_dma_addr_destroy(&page_dma_handle, &page_accessp); 2476f2e8686eSxun ni - Sun Microsystems - Beijing China MPTSAS_ENABLE_INTR(mpt); 2477f2e8686eSxun ni - Sun Microsystems - Beijing China 2478f2e8686eSxun ni - Sun Microsystems - Beijing China return (rval); 2479f2e8686eSxun ni - Sun Microsystems - Beijing China } 2480f2e8686eSxun ni - Sun Microsystems - Beijing China 2481f2e8686eSxun ni - Sun Microsystems - Beijing China static int 2482f2e8686eSxun ni - Sun Microsystems - Beijing China mptsas_sasphypage_0_cb(mptsas_t *mpt, caddr_t page_memp, 2483f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo, 2484f2e8686eSxun ni - Sun Microsystems - Beijing China va_list ap) 2485f2e8686eSxun ni - Sun Microsystems - Beijing China { 2486f2e8686eSxun ni - Sun Microsystems - Beijing China #ifndef __lock_lint 2487f2e8686eSxun ni - Sun Microsystems - Beijing China _NOTE(ARGUNUSED(ap)) 2488f2e8686eSxun ni - Sun Microsystems - Beijing China #endif 2489f2e8686eSxun ni - Sun Microsystems - Beijing China pMpi2SasPhyPage0_t sasphypage; 2490f2e8686eSxun ni - Sun Microsystems - Beijing China int rval = DDI_SUCCESS; 2491f2e8686eSxun ni - Sun Microsystems - Beijing China uint16_t *owner_devhdl, *attached_devhdl; 2492f2e8686eSxun ni - Sun Microsystems - Beijing China uint8_t *attached_phy_identify; 2493f2e8686eSxun ni - Sun Microsystems - Beijing China uint32_t *attached_phy_info; 2494f2e8686eSxun ni - Sun Microsystems - Beijing China uint8_t *programmed_link_rate; 2495f2e8686eSxun ni - Sun Microsystems - Beijing China uint8_t *hw_link_rate; 2496f2e8686eSxun ni - Sun Microsystems - Beijing China uint8_t *change_count; 2497f2e8686eSxun ni - Sun Microsystems - Beijing China uint32_t *phy_info; 2498f2e8686eSxun ni - Sun Microsystems - Beijing China uint8_t *negotiated_link_rate; 2499f2e8686eSxun ni - Sun Microsystems - Beijing China uint32_t page_address; 2500f2e8686eSxun ni - Sun Microsystems - Beijing China 2501f2e8686eSxun ni - Sun Microsystems - Beijing China if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) && 2502f2e8686eSxun ni - Sun Microsystems - Beijing China (iocstatus != MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)) { 2503f2e8686eSxun ni - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "mptsas_get_sas_expander_page0 " 2504f2e8686eSxun ni - Sun Microsystems - Beijing China "config: IOCStatus=0x%x, IOCLogInfo=0x%x", 2505f2e8686eSxun ni - Sun Microsystems - Beijing China iocstatus, iocloginfo); 2506f2e8686eSxun ni - Sun Microsystems - Beijing China rval = DDI_FAILURE; 2507f2e8686eSxun ni - Sun Microsystems - Beijing China return (rval); 2508f2e8686eSxun ni - Sun Microsystems - Beijing China } 2509f2e8686eSxun ni - Sun Microsystems - Beijing China page_address = va_arg(ap, uint32_t); 2510f2e8686eSxun ni - Sun Microsystems - Beijing China /* 2511f2e8686eSxun ni - Sun Microsystems - Beijing China * The INVALID_PAGE status is normal if using GET_NEXT_HANDLE and there 2512f2e8686eSxun ni - Sun Microsystems - Beijing China * are no more pages. If everything is OK up to this point but the 2513f2e8686eSxun ni - Sun Microsystems - Beijing China * status is INVALID_PAGE, change rval to FAILURE and quit. Also, 2514f2e8686eSxun ni - Sun Microsystems - Beijing China * signal that device traversal is complete. 2515f2e8686eSxun ni - Sun Microsystems - Beijing China */ 2516f2e8686eSxun ni - Sun Microsystems - Beijing China if (iocstatus == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) { 2517f2e8686eSxun ni - Sun Microsystems - Beijing China if ((page_address & MPI2_SAS_EXPAND_PGAD_FORM_MASK) == 2518f2e8686eSxun ni - Sun Microsystems - Beijing China MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL) { 2519f2e8686eSxun ni - Sun Microsystems - Beijing China mpt->m_done_traverse_smp = 1; 2520f2e8686eSxun ni - Sun Microsystems - Beijing China } 2521f2e8686eSxun ni - Sun Microsystems - Beijing China rval = DDI_FAILURE; 2522f2e8686eSxun ni - Sun Microsystems - Beijing China return (rval); 2523f2e8686eSxun ni - Sun Microsystems - Beijing China } 2524f2e8686eSxun ni - Sun Microsystems - Beijing China owner_devhdl = va_arg(ap, uint16_t *); 2525f2e8686eSxun ni - Sun Microsystems - Beijing China attached_devhdl = va_arg(ap, uint16_t *); 2526f2e8686eSxun ni - Sun Microsystems - Beijing China attached_phy_identify = va_arg(ap, uint8_t *); 2527f2e8686eSxun ni - Sun Microsystems - Beijing China attached_phy_info = va_arg(ap, uint32_t *); 2528f2e8686eSxun ni - Sun Microsystems - Beijing China programmed_link_rate = va_arg(ap, uint8_t *); 2529f2e8686eSxun ni - Sun Microsystems - Beijing China hw_link_rate = va_arg(ap, uint8_t *); 2530f2e8686eSxun ni - Sun Microsystems - Beijing China change_count = va_arg(ap, uint8_t *); 2531f2e8686eSxun ni - Sun Microsystems - Beijing China phy_info = va_arg(ap, uint32_t *); 2532f2e8686eSxun ni - Sun Microsystems - Beijing China negotiated_link_rate = va_arg(ap, uint8_t *); 2533f2e8686eSxun ni - Sun Microsystems - Beijing China 2534f2e8686eSxun ni - Sun Microsystems - Beijing China sasphypage = (pMpi2SasPhyPage0_t)page_memp; 2535f2e8686eSxun ni - Sun Microsystems - Beijing China 2536f2e8686eSxun ni - Sun Microsystems - Beijing China *owner_devhdl = 2537f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get16(accessp, &sasphypage->OwnerDevHandle); 2538f2e8686eSxun ni - Sun Microsystems - Beijing China *attached_devhdl = 2539f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get16(accessp, &sasphypage->AttachedDevHandle); 2540f2e8686eSxun ni - Sun Microsystems - Beijing China *attached_phy_identify = 2541f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get8(accessp, &sasphypage->AttachedPhyIdentifier); 2542f2e8686eSxun ni - Sun Microsystems - Beijing China *attached_phy_info = 2543f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get32(accessp, &sasphypage->AttachedPhyInfo); 2544f2e8686eSxun ni - Sun Microsystems - Beijing China *programmed_link_rate = 2545f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get8(accessp, &sasphypage->ProgrammedLinkRate); 2546f2e8686eSxun ni - Sun Microsystems - Beijing China *hw_link_rate = 2547f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get8(accessp, &sasphypage->HwLinkRate); 2548f2e8686eSxun ni - Sun Microsystems - Beijing China *change_count = 2549f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get8(accessp, &sasphypage->ChangeCount); 2550f2e8686eSxun ni - Sun Microsystems - Beijing China *phy_info = 2551f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get32(accessp, &sasphypage->PhyInfo); 2552f2e8686eSxun ni - Sun Microsystems - Beijing China *negotiated_link_rate = 2553f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get8(accessp, &sasphypage->NegotiatedLinkRate); 2554f2e8686eSxun ni - Sun Microsystems - Beijing China 2555f2e8686eSxun ni - Sun Microsystems - Beijing China return (rval); 2556f2e8686eSxun ni - Sun Microsystems - Beijing China } 2557f2e8686eSxun ni - Sun Microsystems - Beijing China 2558f2e8686eSxun ni - Sun Microsystems - Beijing China /* 2559f2e8686eSxun ni - Sun Microsystems - Beijing China * Request MPI configuration page SAS phy page 0 to get DevHandle, phymask 2560f2e8686eSxun ni - Sun Microsystems - Beijing China * and SAS address. 2561f2e8686eSxun ni - Sun Microsystems - Beijing China */ 2562f2e8686eSxun ni - Sun Microsystems - Beijing China int 2563f2e8686eSxun ni - Sun Microsystems - Beijing China mptsas_get_sas_phy_page0(mptsas_t *mpt, uint32_t page_address, 2564f2e8686eSxun ni - Sun Microsystems - Beijing China smhba_info_t *info) 2565f2e8686eSxun ni - Sun Microsystems - Beijing China { 2566f2e8686eSxun ni - Sun Microsystems - Beijing China int rval = DDI_SUCCESS; 2567f2e8686eSxun ni - Sun Microsystems - Beijing China 2568f2e8686eSxun ni - Sun Microsystems - Beijing China ASSERT(mutex_owned(&mpt->m_mutex)); 2569f2e8686eSxun ni - Sun Microsystems - Beijing China 2570f2e8686eSxun ni - Sun Microsystems - Beijing China /* 2571f2e8686eSxun ni - Sun Microsystems - Beijing China * Get the header and config page. reply contains the reply frame, 2572f2e8686eSxun ni - Sun Microsystems - Beijing China * which holds status info for the request. 2573f2e8686eSxun ni - Sun Microsystems - Beijing China */ 2574f2e8686eSxun ni - Sun Microsystems - Beijing China rval = mptsas_access_config_page(mpt, 2575f2e8686eSxun ni - Sun Microsystems - Beijing China MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, 2576f2e8686eSxun ni - Sun Microsystems - Beijing China MPI2_CONFIG_EXTPAGETYPE_SAS_PHY, 0, page_address, 2577f2e8686eSxun ni - Sun Microsystems - Beijing China mptsas_sasphypage_0_cb, page_address, &info->owner_devhdl, 2578f2e8686eSxun ni - Sun Microsystems - Beijing China &info->attached_devhdl, &info->attached_phy_identify, 2579f2e8686eSxun ni - Sun Microsystems - Beijing China &info->attached_phy_info, &info->programmed_link_rate, 2580f2e8686eSxun ni - Sun Microsystems - Beijing China &info->hw_link_rate, &info->change_count, 2581f2e8686eSxun ni - Sun Microsystems - Beijing China &info->phy_info, &info->negotiated_link_rate); 2582f2e8686eSxun ni - Sun Microsystems - Beijing China 2583f2e8686eSxun ni - Sun Microsystems - Beijing China return (rval); 2584f2e8686eSxun ni - Sun Microsystems - Beijing China } 2585f2e8686eSxun ni - Sun Microsystems - Beijing China 2586f2e8686eSxun ni - Sun Microsystems - Beijing China static int 2587f2e8686eSxun ni - Sun Microsystems - Beijing China mptsas_sasphypage_1_cb(mptsas_t *mpt, caddr_t page_memp, 2588f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo, 2589f2e8686eSxun ni - Sun Microsystems - Beijing China va_list ap) 2590f2e8686eSxun ni - Sun Microsystems - Beijing China { 2591f2e8686eSxun ni - Sun Microsystems - Beijing China #ifndef __lock_lint 2592f2e8686eSxun ni - Sun Microsystems - Beijing China _NOTE(ARGUNUSED(ap)) 2593f2e8686eSxun ni - Sun Microsystems - Beijing China #endif 2594f2e8686eSxun ni - Sun Microsystems - Beijing China pMpi2SasPhyPage1_t sasphypage; 2595f2e8686eSxun ni - Sun Microsystems - Beijing China int rval = DDI_SUCCESS; 2596f2e8686eSxun ni - Sun Microsystems - Beijing China 2597f2e8686eSxun ni - Sun Microsystems - Beijing China uint32_t *invalid_dword_count; 2598f2e8686eSxun ni - Sun Microsystems - Beijing China uint32_t *running_disparity_error_count; 2599f2e8686eSxun ni - Sun Microsystems - Beijing China uint32_t *loss_of_dword_sync_count; 2600f2e8686eSxun ni - Sun Microsystems - Beijing China uint32_t *phy_reset_problem_count; 2601f2e8686eSxun ni - Sun Microsystems - Beijing China uint32_t page_address; 2602f2e8686eSxun ni - Sun Microsystems - Beijing China 2603f2e8686eSxun ni - Sun Microsystems - Beijing China if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) && 2604f2e8686eSxun ni - Sun Microsystems - Beijing China (iocstatus != MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)) { 2605f2e8686eSxun ni - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "mptsas_get_sas_expander_page1 " 2606f2e8686eSxun ni - Sun Microsystems - Beijing China "config: IOCStatus=0x%x, IOCLogInfo=0x%x", 2607f2e8686eSxun ni - Sun Microsystems - Beijing China iocstatus, iocloginfo); 2608f2e8686eSxun ni - Sun Microsystems - Beijing China rval = DDI_FAILURE; 2609f2e8686eSxun ni - Sun Microsystems - Beijing China return (rval); 2610f2e8686eSxun ni - Sun Microsystems - Beijing China } 2611f2e8686eSxun ni - Sun Microsystems - Beijing China page_address = va_arg(ap, uint32_t); 2612f2e8686eSxun ni - Sun Microsystems - Beijing China /* 2613f2e8686eSxun ni - Sun Microsystems - Beijing China * The INVALID_PAGE status is normal if using GET_NEXT_HANDLE and there 2614f2e8686eSxun ni - Sun Microsystems - Beijing China * are no more pages. If everything is OK up to this point but the 2615f2e8686eSxun ni - Sun Microsystems - Beijing China * status is INVALID_PAGE, change rval to FAILURE and quit. Also, 2616f2e8686eSxun ni - Sun Microsystems - Beijing China * signal that device traversal is complete. 2617f2e8686eSxun ni - Sun Microsystems - Beijing China */ 2618f2e8686eSxun ni - Sun Microsystems - Beijing China if (iocstatus == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) { 2619f2e8686eSxun ni - Sun Microsystems - Beijing China if ((page_address & MPI2_SAS_EXPAND_PGAD_FORM_MASK) == 2620f2e8686eSxun ni - Sun Microsystems - Beijing China MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL) { 2621f2e8686eSxun ni - Sun Microsystems - Beijing China mpt->m_done_traverse_smp = 1; 2622f2e8686eSxun ni - Sun Microsystems - Beijing China } 2623f2e8686eSxun ni - Sun Microsystems - Beijing China rval = DDI_FAILURE; 2624f2e8686eSxun ni - Sun Microsystems - Beijing China return (rval); 2625f2e8686eSxun ni - Sun Microsystems - Beijing China } 2626f2e8686eSxun ni - Sun Microsystems - Beijing China 2627f2e8686eSxun ni - Sun Microsystems - Beijing China invalid_dword_count = va_arg(ap, uint32_t *); 2628f2e8686eSxun ni - Sun Microsystems - Beijing China running_disparity_error_count = va_arg(ap, uint32_t *); 2629f2e8686eSxun ni - Sun Microsystems - Beijing China loss_of_dword_sync_count = va_arg(ap, uint32_t *); 2630f2e8686eSxun ni - Sun Microsystems - Beijing China phy_reset_problem_count = va_arg(ap, uint32_t *); 2631f2e8686eSxun ni - Sun Microsystems - Beijing China 2632f2e8686eSxun ni - Sun Microsystems - Beijing China sasphypage = (pMpi2SasPhyPage1_t)page_memp; 2633f2e8686eSxun ni - Sun Microsystems - Beijing China 2634f2e8686eSxun ni - Sun Microsystems - Beijing China *invalid_dword_count = 2635f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get32(accessp, &sasphypage->InvalidDwordCount); 2636f2e8686eSxun ni - Sun Microsystems - Beijing China *running_disparity_error_count = 2637f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get32(accessp, &sasphypage->RunningDisparityErrorCount); 2638f2e8686eSxun ni - Sun Microsystems - Beijing China *loss_of_dword_sync_count = 2639f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get32(accessp, &sasphypage->LossDwordSynchCount); 2640f2e8686eSxun ni - Sun Microsystems - Beijing China *phy_reset_problem_count = 2641f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get32(accessp, &sasphypage->PhyResetProblemCount); 2642f2e8686eSxun ni - Sun Microsystems - Beijing China 2643f2e8686eSxun ni - Sun Microsystems - Beijing China return (rval); 2644f2e8686eSxun ni - Sun Microsystems - Beijing China } 2645f2e8686eSxun ni - Sun Microsystems - Beijing China 2646f2e8686eSxun ni - Sun Microsystems - Beijing China /* 2647f2e8686eSxun ni - Sun Microsystems - Beijing China * Request MPI configuration page SAS phy page 0 to get DevHandle, phymask 2648f2e8686eSxun ni - Sun Microsystems - Beijing China * and SAS address. 2649f2e8686eSxun ni - Sun Microsystems - Beijing China */ 2650f2e8686eSxun ni - Sun Microsystems - Beijing China int 2651f2e8686eSxun ni - Sun Microsystems - Beijing China mptsas_get_sas_phy_page1(mptsas_t *mpt, uint32_t page_address, 2652f2e8686eSxun ni - Sun Microsystems - Beijing China smhba_info_t *info) 2653f2e8686eSxun ni - Sun Microsystems - Beijing China { 2654f2e8686eSxun ni - Sun Microsystems - Beijing China int rval = DDI_SUCCESS; 2655f2e8686eSxun ni - Sun Microsystems - Beijing China 2656f2e8686eSxun ni - Sun Microsystems - Beijing China ASSERT(mutex_owned(&mpt->m_mutex)); 2657f2e8686eSxun ni - Sun Microsystems - Beijing China 2658f2e8686eSxun ni - Sun Microsystems - Beijing China /* 2659f2e8686eSxun ni - Sun Microsystems - Beijing China * Get the header and config page. reply contains the reply frame, 2660f2e8686eSxun ni - Sun Microsystems - Beijing China * which holds status info for the request. 2661f2e8686eSxun ni - Sun Microsystems - Beijing China */ 2662f2e8686eSxun ni - Sun Microsystems - Beijing China rval = mptsas_access_config_page(mpt, 2663f2e8686eSxun ni - Sun Microsystems - Beijing China MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, 2664f2e8686eSxun ni - Sun Microsystems - Beijing China MPI2_CONFIG_EXTPAGETYPE_SAS_PHY, 1, page_address, 2665f2e8686eSxun ni - Sun Microsystems - Beijing China mptsas_sasphypage_1_cb, page_address, 2666f2e8686eSxun ni - Sun Microsystems - Beijing China &info->invalid_dword_count, 2667f2e8686eSxun ni - Sun Microsystems - Beijing China &info->running_disparity_error_count, 2668f2e8686eSxun ni - Sun Microsystems - Beijing China &info->loss_of_dword_sync_count, 2669f2e8686eSxun ni - Sun Microsystems - Beijing China &info->phy_reset_problem_count); 2670f2e8686eSxun ni - Sun Microsystems - Beijing China 2671f2e8686eSxun ni - Sun Microsystems - Beijing China return (rval); 2672f2e8686eSxun ni - Sun Microsystems - Beijing China } 2673f2e8686eSxun ni - Sun Microsystems - Beijing China /* 2674f2e8686eSxun ni - Sun Microsystems - Beijing China * mptsas_get_manufacture_page0 2675f2e8686eSxun ni - Sun Microsystems - Beijing China * 2676f2e8686eSxun ni - Sun Microsystems - Beijing China * This function will retrieve the base 2677f2e8686eSxun ni - Sun Microsystems - Beijing China * Chip name, Board Name,Board Trace number from the adapter. 2678f2e8686eSxun ni - Sun Microsystems - Beijing China * Since this function is only called during the 2679f2e8686eSxun ni - Sun Microsystems - Beijing China * initialization process, use handshaking. 2680f2e8686eSxun ni - Sun Microsystems - Beijing China */ 2681f2e8686eSxun ni - Sun Microsystems - Beijing China int 2682f2e8686eSxun ni - Sun Microsystems - Beijing China mptsas_get_manufacture_page0(mptsas_t *mpt) 2683f2e8686eSxun ni - Sun Microsystems - Beijing China { 2684f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_dma_attr_t recv_dma_attrs, page_dma_attrs; 2685a9b51062SAda ddi_dma_cookie_t page_cookie; 2686f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_dma_handle_t recv_dma_handle, page_dma_handle; 2687f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_acc_handle_t recv_accessp, page_accessp; 2688f2e8686eSxun ni - Sun Microsystems - Beijing China pMpi2ConfigReply_t configreply; 2689f2e8686eSxun ni - Sun Microsystems - Beijing China caddr_t recv_memp, page_memp; 2690f2e8686eSxun ni - Sun Microsystems - Beijing China int recv_numbytes; 2691f2e8686eSxun ni - Sun Microsystems - Beijing China pMpi2ManufacturingPage0_t m0; 2692f2e8686eSxun ni - Sun Microsystems - Beijing China uint32_t flagslength; 2693f2e8686eSxun ni - Sun Microsystems - Beijing China int rval = DDI_SUCCESS; 2694f2e8686eSxun ni - Sun Microsystems - Beijing China uint_t iocstatus; 2695f2e8686eSxun ni - Sun Microsystems - Beijing China uint8_t i = 0; 2696f7d0d869SDan McDonald boolean_t free_recv = B_FALSE, free_page = B_FALSE; 2697f2e8686eSxun ni - Sun Microsystems - Beijing China 2698f2e8686eSxun ni - Sun Microsystems - Beijing China MPTSAS_DISABLE_INTR(mpt); 2699f2e8686eSxun ni - Sun Microsystems - Beijing China 2700f2e8686eSxun ni - Sun Microsystems - Beijing China if (mptsas_send_config_request_msg(mpt, MPI2_CONFIG_ACTION_PAGE_HEADER, 2701f2e8686eSxun ni - Sun Microsystems - Beijing China MPI2_CONFIG_PAGETYPE_MANUFACTURING, 0, 0, 0, 0, 0, 0)) { 2702f2e8686eSxun ni - Sun Microsystems - Beijing China rval = DDI_FAILURE; 2703f2e8686eSxun ni - Sun Microsystems - Beijing China goto done; 2704f2e8686eSxun ni - Sun Microsystems - Beijing China } 2705f2e8686eSxun ni - Sun Microsystems - Beijing China 2706f2e8686eSxun ni - Sun Microsystems - Beijing China /* 2707f2e8686eSxun ni - Sun Microsystems - Beijing China * dynamically create a customized dma attribute structure 2708f2e8686eSxun ni - Sun Microsystems - Beijing China * that describes the MPT's config reply page request structure. 2709f2e8686eSxun ni - Sun Microsystems - Beijing China */ 2710f2e8686eSxun ni - Sun Microsystems - Beijing China recv_dma_attrs = mpt->m_msg_dma_attr; 2711f2e8686eSxun ni - Sun Microsystems - Beijing China recv_dma_attrs.dma_attr_sgllen = 1; 2712f2e8686eSxun ni - Sun Microsystems - Beijing China recv_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_REPLY)); 2713f2e8686eSxun ni - Sun Microsystems - Beijing China 2714a9b51062SAda if (mptsas_dma_addr_create(mpt, recv_dma_attrs, &recv_dma_handle, 2715a9b51062SAda &recv_accessp, &recv_memp, (sizeof (MPI2_CONFIG_REPLY)), 2716a9b51062SAda NULL) == FALSE) { 2717f7d0d869SDan McDonald rval = DDI_FAILURE; 2718f2e8686eSxun ni - Sun Microsystems - Beijing China goto done; 2719f2e8686eSxun ni - Sun Microsystems - Beijing China } 2720f7d0d869SDan McDonald /* Now safe to call mptsas_dma_addr_destroy(recv_dma_handle). */ 2721f7d0d869SDan McDonald free_recv = B_TRUE; 2722f7d0d869SDan McDonald 2723f2e8686eSxun ni - Sun Microsystems - Beijing China bzero(recv_memp, sizeof (MPI2_CONFIG_REPLY)); 2724f2e8686eSxun ni - Sun Microsystems - Beijing China configreply = (pMpi2ConfigReply_t)recv_memp; 2725f2e8686eSxun ni - Sun Microsystems - Beijing China recv_numbytes = sizeof (MPI2_CONFIG_REPLY); 2726f2e8686eSxun ni - Sun Microsystems - Beijing China 2727f2e8686eSxun ni - Sun Microsystems - Beijing China /* 2728f2e8686eSxun ni - Sun Microsystems - Beijing China * get config reply message 2729f2e8686eSxun ni - Sun Microsystems - Beijing China */ 2730f2e8686eSxun ni - Sun Microsystems - Beijing China if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes, 2731f2e8686eSxun ni - Sun Microsystems - Beijing China recv_accessp)) { 2732f2e8686eSxun ni - Sun Microsystems - Beijing China rval = DDI_FAILURE; 2733f2e8686eSxun ni - Sun Microsystems - Beijing China goto done; 2734f2e8686eSxun ni - Sun Microsystems - Beijing China } 2735f2e8686eSxun ni - Sun Microsystems - Beijing China 2736e89016e7SRobert Mustacchi if ((iocstatus = ddi_get16(recv_accessp, &configreply->IOCStatus)) != 2737e89016e7SRobert Mustacchi 0) { 2738f2e8686eSxun ni - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "mptsas_get_manufacture_page5 update: " 2739f2e8686eSxun ni - Sun Microsystems - Beijing China "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus, 2740f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get32(recv_accessp, &configreply->IOCLogInfo)); 2741f2e8686eSxun ni - Sun Microsystems - Beijing China goto done; 2742f2e8686eSxun ni - Sun Microsystems - Beijing China } 2743f2e8686eSxun ni - Sun Microsystems - Beijing China 2744f2e8686eSxun ni - Sun Microsystems - Beijing China /* 2745f2e8686eSxun ni - Sun Microsystems - Beijing China * dynamically create a customized dma attribute structure 2746f2e8686eSxun ni - Sun Microsystems - Beijing China * that describes the MPT's config page structure. 2747f2e8686eSxun ni - Sun Microsystems - Beijing China */ 2748f2e8686eSxun ni - Sun Microsystems - Beijing China page_dma_attrs = mpt->m_msg_dma_attr; 2749f2e8686eSxun ni - Sun Microsystems - Beijing China page_dma_attrs.dma_attr_sgllen = 1; 2750f2e8686eSxun ni - Sun Microsystems - Beijing China page_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_PAGE_MAN_0)); 2751f2e8686eSxun ni - Sun Microsystems - Beijing China 2752a9b51062SAda if (mptsas_dma_addr_create(mpt, page_dma_attrs, &page_dma_handle, 2753a9b51062SAda &page_accessp, &page_memp, (sizeof (MPI2_CONFIG_PAGE_MAN_0)), 2754a9b51062SAda &page_cookie) == FALSE) { 2755f7d0d869SDan McDonald rval = DDI_FAILURE; 2756f2e8686eSxun ni - Sun Microsystems - Beijing China goto done; 2757f2e8686eSxun ni - Sun Microsystems - Beijing China } 2758f7d0d869SDan McDonald /* Now safe to call mptsas_dma_addr_destroy(page_dma_handle). */ 2759f7d0d869SDan McDonald free_page = B_TRUE; 2760f7d0d869SDan McDonald 2761f2e8686eSxun ni - Sun Microsystems - Beijing China bzero(page_memp, sizeof (MPI2_CONFIG_PAGE_MAN_0)); 2762f2e8686eSxun ni - Sun Microsystems - Beijing China m0 = (pMpi2ManufacturingPage0_t)page_memp; 2763f2e8686eSxun ni - Sun Microsystems - Beijing China 2764f2e8686eSxun ni - Sun Microsystems - Beijing China /* 2765f2e8686eSxun ni - Sun Microsystems - Beijing China * Give reply address to IOC to store config page in and send 2766f2e8686eSxun ni - Sun Microsystems - Beijing China * config request out. 2767f2e8686eSxun ni - Sun Microsystems - Beijing China */ 2768f2e8686eSxun ni - Sun Microsystems - Beijing China 2769f2e8686eSxun ni - Sun Microsystems - Beijing China flagslength = sizeof (MPI2_CONFIG_PAGE_MAN_0); 2770f2e8686eSxun ni - Sun Microsystems - Beijing China flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT | 2771f2e8686eSxun ni - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 2772940efceeSAndy Giles MPI2_SGE_FLAGS_SYSTEM_ADDRESS | MPI2_SGE_FLAGS_64_BIT_ADDRESSING | 2773f2e8686eSxun ni - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_IOC_TO_HOST | 2774f2e8686eSxun ni - Sun Microsystems - Beijing China MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); 2775f2e8686eSxun ni - Sun Microsystems - Beijing China 2776f2e8686eSxun ni - Sun Microsystems - Beijing China if (mptsas_send_config_request_msg(mpt, 2777f2e8686eSxun ni - Sun Microsystems - Beijing China MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, 2778f2e8686eSxun ni - Sun Microsystems - Beijing China MPI2_CONFIG_PAGETYPE_MANUFACTURING, 0, 0, 2779f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get8(recv_accessp, &configreply->Header.PageVersion), 2780f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get8(recv_accessp, &configreply->Header.PageLength), 2781940efceeSAndy Giles flagslength, page_cookie.dmac_laddress)) { 2782f2e8686eSxun ni - Sun Microsystems - Beijing China rval = DDI_FAILURE; 2783f2e8686eSxun ni - Sun Microsystems - Beijing China goto done; 2784f2e8686eSxun ni - Sun Microsystems - Beijing China } 2785f2e8686eSxun ni - Sun Microsystems - Beijing China 2786f2e8686eSxun ni - Sun Microsystems - Beijing China /* 2787f2e8686eSxun ni - Sun Microsystems - Beijing China * get reply view handshake 2788f2e8686eSxun ni - Sun Microsystems - Beijing China */ 2789f2e8686eSxun ni - Sun Microsystems - Beijing China if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes, 2790f2e8686eSxun ni - Sun Microsystems - Beijing China recv_accessp)) { 2791f2e8686eSxun ni - Sun Microsystems - Beijing China rval = DDI_FAILURE; 2792f2e8686eSxun ni - Sun Microsystems - Beijing China goto done; 2793f2e8686eSxun ni - Sun Microsystems - Beijing China } 2794f2e8686eSxun ni - Sun Microsystems - Beijing China 2795e89016e7SRobert Mustacchi if ((iocstatus = ddi_get16(recv_accessp, &configreply->IOCStatus)) != 2796e89016e7SRobert Mustacchi 0) { 2797f2e8686eSxun ni - Sun Microsystems - Beijing China mptsas_log(mpt, CE_WARN, "mptsas_get_manufacture_page0 config: " 2798f2e8686eSxun ni - Sun Microsystems - Beijing China "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus, 2799f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get32(recv_accessp, &configreply->IOCLogInfo)); 2800f2e8686eSxun ni - Sun Microsystems - Beijing China goto done; 2801f2e8686eSxun ni - Sun Microsystems - Beijing China } 2802f2e8686eSxun ni - Sun Microsystems - Beijing China 2803f2e8686eSxun ni - Sun Microsystems - Beijing China (void) ddi_dma_sync(page_dma_handle, 0, 0, DDI_DMA_SYNC_FORCPU); 2804f2e8686eSxun ni - Sun Microsystems - Beijing China 2805f2e8686eSxun ni - Sun Microsystems - Beijing China /* 2806f2e8686eSxun ni - Sun Microsystems - Beijing China * Fusion-MPT stores fields in little-endian format. This is 2807f2e8686eSxun ni - Sun Microsystems - Beijing China * why the low-order 32 bits are stored first. 2808f2e8686eSxun ni - Sun Microsystems - Beijing China */ 2809f2e8686eSxun ni - Sun Microsystems - Beijing China 2810f2e8686eSxun ni - Sun Microsystems - Beijing China for (i = 0; i < 16; i++) { 2811f2e8686eSxun ni - Sun Microsystems - Beijing China mpt->m_MANU_page0.ChipName[i] = 2812f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get8(page_accessp, 2813f2e8686eSxun ni - Sun Microsystems - Beijing China (uint8_t *)(void *)&m0->ChipName[i]); 2814f2e8686eSxun ni - Sun Microsystems - Beijing China } 2815f2e8686eSxun ni - Sun Microsystems - Beijing China 2816f2e8686eSxun ni - Sun Microsystems - Beijing China for (i = 0; i < 8; i++) { 2817f2e8686eSxun ni - Sun Microsystems - Beijing China mpt->m_MANU_page0.ChipRevision[i] = 2818f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get8(page_accessp, 2819f2e8686eSxun ni - Sun Microsystems - Beijing China (uint8_t *)(void *)&m0->ChipRevision[i]); 2820f2e8686eSxun ni - Sun Microsystems - Beijing China } 2821f2e8686eSxun ni - Sun Microsystems - Beijing China 2822f2e8686eSxun ni - Sun Microsystems - Beijing China for (i = 0; i < 16; i++) { 2823f2e8686eSxun ni - Sun Microsystems - Beijing China mpt->m_MANU_page0.BoardName[i] = 2824f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get8(page_accessp, 2825f2e8686eSxun ni - Sun Microsystems - Beijing China (uint8_t *)(void *)&m0->BoardName[i]); 2826f2e8686eSxun ni - Sun Microsystems - Beijing China } 2827f2e8686eSxun ni - Sun Microsystems - Beijing China 2828f2e8686eSxun ni - Sun Microsystems - Beijing China for (i = 0; i < 16; i++) { 2829f2e8686eSxun ni - Sun Microsystems - Beijing China mpt->m_MANU_page0.BoardAssembly[i] = 2830f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get8(page_accessp, 2831f2e8686eSxun ni - Sun Microsystems - Beijing China (uint8_t *)(void *)&m0->BoardAssembly[i]); 2832f2e8686eSxun ni - Sun Microsystems - Beijing China } 2833f2e8686eSxun ni - Sun Microsystems - Beijing China 2834f2e8686eSxun ni - Sun Microsystems - Beijing China for (i = 0; i < 16; i++) { 2835f2e8686eSxun ni - Sun Microsystems - Beijing China mpt->m_MANU_page0.BoardTracerNumber[i] = 2836f2e8686eSxun ni - Sun Microsystems - Beijing China ddi_get8(page_accessp, 2837f2e8686eSxun ni - Sun Microsystems - Beijing China (uint8_t *)(void *)&m0->BoardTracerNumber[i]); 2838f2e8686eSxun ni - Sun Microsystems - Beijing China } 2839f2e8686eSxun ni - Sun Microsystems - Beijing China 2840f2e8686eSxun ni - Sun Microsystems - Beijing China if ((mptsas_check_dma_handle(recv_dma_handle) != DDI_SUCCESS) || 28415b504601Sjiang wu - Sun Microsystems - Beijing China (mptsas_check_dma_handle(page_dma_handle) != DDI_SUCCESS)) { 28425b504601Sjiang wu - Sun Microsystems - Beijing China ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 28435b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 28445b504601Sjiang wu - Sun Microsystems - Beijing China goto done; 28455b504601Sjiang wu - Sun Microsystems - Beijing China } 28465b504601Sjiang wu - Sun Microsystems - Beijing China if ((mptsas_check_acc_handle(recv_accessp) != DDI_SUCCESS) || 28475b504601Sjiang wu - Sun Microsystems - Beijing China (mptsas_check_acc_handle(page_accessp) != DDI_SUCCESS)) { 28485b504601Sjiang wu - Sun Microsystems - Beijing China ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 28495b504601Sjiang wu - Sun Microsystems - Beijing China rval = DDI_FAILURE; 28505b504601Sjiang wu - Sun Microsystems - Beijing China } 28515b504601Sjiang wu - Sun Microsystems - Beijing China done: 28525b504601Sjiang wu - Sun Microsystems - Beijing China /* 28535b504601Sjiang wu - Sun Microsystems - Beijing China * free up memory 28545b504601Sjiang wu - Sun Microsystems - Beijing China */ 2855f7d0d869SDan McDonald if (free_recv) 2856f7d0d869SDan McDonald mptsas_dma_addr_destroy(&recv_dma_handle, &recv_accessp); 2857f7d0d869SDan McDonald if (free_page) 2858f7d0d869SDan McDonald mptsas_dma_addr_destroy(&page_dma_handle, &page_accessp); 28595b504601Sjiang wu - Sun Microsystems - Beijing China MPTSAS_ENABLE_INTR(mpt); 28605b504601Sjiang wu - Sun Microsystems - Beijing China 28615b504601Sjiang wu - Sun Microsystems - Beijing China return (rval); 28625b504601Sjiang wu - Sun Microsystems - Beijing China } 286315ada8fcSRobert Mustacchi 286415ada8fcSRobert Mustacchi static int 286515ada8fcSRobert Mustacchi mptsas_enclosurepage_0_cb(mptsas_t *mpt, caddr_t page_memp, 286615ada8fcSRobert Mustacchi ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo, 286715ada8fcSRobert Mustacchi va_list ap) 286815ada8fcSRobert Mustacchi { 2869a0ac5a9eSToomas Soome uint32_t page_address; 287015ada8fcSRobert Mustacchi pMpi2SasEnclosurePage0_t encpage, encout; 287115ada8fcSRobert Mustacchi 287215ada8fcSRobert Mustacchi if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) && 287315ada8fcSRobert Mustacchi (iocstatus != MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)) { 287415ada8fcSRobert Mustacchi mptsas_log(mpt, CE_WARN, "mptsas_get_enclsourepage0 " 287515ada8fcSRobert Mustacchi "header: IOCStatus=0x%x, IOCLogInfo=0x%x", 287615ada8fcSRobert Mustacchi iocstatus, iocloginfo); 287715ada8fcSRobert Mustacchi return (DDI_FAILURE); 287815ada8fcSRobert Mustacchi } 287915ada8fcSRobert Mustacchi 288015ada8fcSRobert Mustacchi page_address = va_arg(ap, uint32_t); 288115ada8fcSRobert Mustacchi encout = va_arg(ap, pMpi2SasEnclosurePage0_t); 288215ada8fcSRobert Mustacchi encpage = (pMpi2SasEnclosurePage0_t)page_memp; 288315ada8fcSRobert Mustacchi 288415ada8fcSRobert Mustacchi /* 288515ada8fcSRobert Mustacchi * The INVALID_PAGE status is normal if using GET_NEXT_HANDLE and there 288615ada8fcSRobert Mustacchi * are no more pages. If everything is OK up to this point but the 288715ada8fcSRobert Mustacchi * status is INVALID_PAGE, change rval to FAILURE and quit. Also, 288815ada8fcSRobert Mustacchi * signal that enclosure traversal is complete. 288915ada8fcSRobert Mustacchi */ 289015ada8fcSRobert Mustacchi if (iocstatus == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) { 289115ada8fcSRobert Mustacchi if ((page_address & MPI2_SAS_DEVICE_PGAD_FORM_MASK) == 289215ada8fcSRobert Mustacchi MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE) { 289315ada8fcSRobert Mustacchi mpt->m_done_traverse_enc = 1; 289415ada8fcSRobert Mustacchi } 289515ada8fcSRobert Mustacchi return (DDI_FAILURE); 289615ada8fcSRobert Mustacchi } 289715ada8fcSRobert Mustacchi 289815ada8fcSRobert Mustacchi encout->Header.PageVersion = ddi_get8(accessp, 289915ada8fcSRobert Mustacchi &encpage->Header.PageVersion); 290015ada8fcSRobert Mustacchi encout->Header.PageNumber = ddi_get8(accessp, 290115ada8fcSRobert Mustacchi &encpage->Header.PageNumber); 290215ada8fcSRobert Mustacchi encout->Header.PageType = ddi_get8(accessp, &encpage->Header.PageType); 290315ada8fcSRobert Mustacchi encout->Header.ExtPageLength = ddi_get16(accessp, 290415ada8fcSRobert Mustacchi &encpage->Header.ExtPageLength); 290515ada8fcSRobert Mustacchi encout->Header.ExtPageType = ddi_get8(accessp, 290615ada8fcSRobert Mustacchi &encpage->Header.ExtPageType); 290715ada8fcSRobert Mustacchi 290815ada8fcSRobert Mustacchi encout->EnclosureLogicalID.Low = ddi_get32(accessp, 290915ada8fcSRobert Mustacchi &encpage->EnclosureLogicalID.Low); 291015ada8fcSRobert Mustacchi encout->EnclosureLogicalID.High = ddi_get32(accessp, 291115ada8fcSRobert Mustacchi &encpage->EnclosureLogicalID.High); 291215ada8fcSRobert Mustacchi encout->Flags = ddi_get16(accessp, &encpage->Flags); 291315ada8fcSRobert Mustacchi encout->EnclosureHandle = ddi_get16(accessp, &encpage->EnclosureHandle); 291415ada8fcSRobert Mustacchi encout->NumSlots = ddi_get16(accessp, &encpage->NumSlots); 291515ada8fcSRobert Mustacchi encout->StartSlot = ddi_get16(accessp, &encpage->StartSlot); 291615ada8fcSRobert Mustacchi encout->EnclosureLevel = ddi_get8(accessp, &encpage->EnclosureLevel); 291715ada8fcSRobert Mustacchi encout->SEPDevHandle = ddi_get16(accessp, &encpage->SEPDevHandle); 291815ada8fcSRobert Mustacchi 291915ada8fcSRobert Mustacchi return (DDI_SUCCESS); 292015ada8fcSRobert Mustacchi } 292115ada8fcSRobert Mustacchi 292215ada8fcSRobert Mustacchi /* 292315ada8fcSRobert Mustacchi * Request information about the SES enclosures. 292415ada8fcSRobert Mustacchi */ 292515ada8fcSRobert Mustacchi int 292615ada8fcSRobert Mustacchi mptsas_get_enclosure_page0(mptsas_t *mpt, uint32_t page_address, 292715ada8fcSRobert Mustacchi mptsas_enclosure_t *mep) 292815ada8fcSRobert Mustacchi { 292915ada8fcSRobert Mustacchi int rval = DDI_SUCCESS; 293015ada8fcSRobert Mustacchi Mpi2SasEnclosurePage0_t encpage; 293115ada8fcSRobert Mustacchi 293215ada8fcSRobert Mustacchi ASSERT(MUTEX_HELD(&mpt->m_mutex)); 293315ada8fcSRobert Mustacchi 293415ada8fcSRobert Mustacchi bzero(&encpage, sizeof (encpage)); 293515ada8fcSRobert Mustacchi rval = mptsas_access_config_page(mpt, 293615ada8fcSRobert Mustacchi MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, 293715ada8fcSRobert Mustacchi MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE, 0, page_address, 293815ada8fcSRobert Mustacchi mptsas_enclosurepage_0_cb, page_address, &encpage); 293915ada8fcSRobert Mustacchi 294015ada8fcSRobert Mustacchi if (rval == DDI_SUCCESS) { 294115ada8fcSRobert Mustacchi mep->me_enchdl = encpage.EnclosureHandle; 294215ada8fcSRobert Mustacchi mep->me_flags = encpage.Flags; 2943bf62a5c5SRobert Mustacchi mep->me_nslots = encpage.NumSlots; 2944bf62a5c5SRobert Mustacchi mep->me_fslot = encpage.StartSlot; 2945bf62a5c5SRobert Mustacchi mep->me_slotleds = NULL; 294615ada8fcSRobert Mustacchi } 294715ada8fcSRobert Mustacchi 294815ada8fcSRobert Mustacchi return (rval); 294915ada8fcSRobert Mustacchi } 2950