1f92363d1SSreekanth Reddy /* 2f92363d1SSreekanth Reddy * This module provides common API for accessing firmware configuration pages 3f92363d1SSreekanth Reddy * 4f92363d1SSreekanth Reddy * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c 5a4ffce0dSSreekanth Reddy * Copyright (C) 2012-2014 LSI Corporation 6a03bd153SSreekanth Reddy * Copyright (C) 2013-2014 Avago Technologies 7a03bd153SSreekanth Reddy * (mailto: MPT-FusionLinux.pdl@avagotech.com) 8f92363d1SSreekanth Reddy * 9f92363d1SSreekanth Reddy * This program is free software; you can redistribute it and/or 10f92363d1SSreekanth Reddy * modify it under the terms of the GNU General Public License 11f92363d1SSreekanth Reddy * as published by the Free Software Foundation; either version 2 12f92363d1SSreekanth Reddy * of the License, or (at your option) any later version. 13f92363d1SSreekanth Reddy * 14f92363d1SSreekanth Reddy * This program is distributed in the hope that it will be useful, 15f92363d1SSreekanth Reddy * but WITHOUT ANY WARRANTY; without even the implied warranty of 16f92363d1SSreekanth Reddy * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17f92363d1SSreekanth Reddy * GNU General Public License for more details. 18f92363d1SSreekanth Reddy * 19f92363d1SSreekanth Reddy * NO WARRANTY 20f92363d1SSreekanth Reddy * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR 21f92363d1SSreekanth Reddy * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT 22f92363d1SSreekanth Reddy * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 23f92363d1SSreekanth Reddy * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is 24f92363d1SSreekanth Reddy * solely responsible for determining the appropriateness of using and 25f92363d1SSreekanth Reddy * distributing the Program and assumes all risks associated with its 26f92363d1SSreekanth Reddy * exercise of rights under this Agreement, including but not limited to 27f92363d1SSreekanth Reddy * the risks and costs of program errors, damage to or loss of data, 28f92363d1SSreekanth Reddy * programs or equipment, and unavailability or interruption of operations. 29f92363d1SSreekanth Reddy 30f92363d1SSreekanth Reddy * DISCLAIMER OF LIABILITY 31f92363d1SSreekanth Reddy * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY 32f92363d1SSreekanth Reddy * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33f92363d1SSreekanth Reddy * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND 34f92363d1SSreekanth Reddy * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 35f92363d1SSreekanth Reddy * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 36f92363d1SSreekanth Reddy * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED 37f92363d1SSreekanth Reddy * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES 38f92363d1SSreekanth Reddy 39f92363d1SSreekanth Reddy * You should have received a copy of the GNU General Public License 40f92363d1SSreekanth Reddy * along with this program; if not, write to the Free Software 41f92363d1SSreekanth Reddy * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 42f92363d1SSreekanth Reddy * USA. 43f92363d1SSreekanth Reddy */ 44f92363d1SSreekanth Reddy 45f92363d1SSreekanth Reddy #include <linux/module.h> 46f92363d1SSreekanth Reddy #include <linux/kernel.h> 47f92363d1SSreekanth Reddy #include <linux/init.h> 48f92363d1SSreekanth Reddy #include <linux/errno.h> 49f92363d1SSreekanth Reddy #include <linux/blkdev.h> 50f92363d1SSreekanth Reddy #include <linux/sched.h> 51f92363d1SSreekanth Reddy #include <linux/workqueue.h> 52f92363d1SSreekanth Reddy #include <linux/delay.h> 53f92363d1SSreekanth Reddy #include <linux/pci.h> 54f92363d1SSreekanth Reddy 55f92363d1SSreekanth Reddy #include "mpt3sas_base.h" 56f92363d1SSreekanth Reddy 57f92363d1SSreekanth Reddy /* local definitions */ 58f92363d1SSreekanth Reddy 59f92363d1SSreekanth Reddy /* Timeout for config page request (in seconds) */ 60f92363d1SSreekanth Reddy #define MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT 15 61f92363d1SSreekanth Reddy 62f92363d1SSreekanth Reddy /* Common sgl flags for READING a config page. */ 63f92363d1SSreekanth Reddy #define MPT3_CONFIG_COMMON_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \ 64f92363d1SSreekanth Reddy MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \ 65f92363d1SSreekanth Reddy | MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT) 66f92363d1SSreekanth Reddy 67f92363d1SSreekanth Reddy /* Common sgl flags for WRITING a config page. */ 68f92363d1SSreekanth Reddy #define MPT3_CONFIG_COMMON_WRITE_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \ 69f92363d1SSreekanth Reddy MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \ 70f92363d1SSreekanth Reddy | MPI2_SGE_FLAGS_END_OF_LIST | MPI2_SGE_FLAGS_HOST_TO_IOC) \ 71f92363d1SSreekanth Reddy << MPI2_SGE_FLAGS_SHIFT) 72f92363d1SSreekanth Reddy 73f92363d1SSreekanth Reddy /** 74f92363d1SSreekanth Reddy * struct config_request - obtain dma memory via routine 75f92363d1SSreekanth Reddy * @sz: size 76f92363d1SSreekanth Reddy * @page: virt pointer 77f92363d1SSreekanth Reddy * @page_dma: phys pointer 78f92363d1SSreekanth Reddy * 79f92363d1SSreekanth Reddy */ 80f92363d1SSreekanth Reddy struct config_request { 81f92363d1SSreekanth Reddy u16 sz; 82f92363d1SSreekanth Reddy void *page; 83f92363d1SSreekanth Reddy dma_addr_t page_dma; 84f92363d1SSreekanth Reddy }; 85f92363d1SSreekanth Reddy 86f92363d1SSreekanth Reddy /** 87f92363d1SSreekanth Reddy * _config_display_some_debug - debug routine 88f92363d1SSreekanth Reddy * @ioc: per adapter object 89f92363d1SSreekanth Reddy * @smid: system request message index 90f92363d1SSreekanth Reddy * @calling_function_name: string pass from calling function 91f92363d1SSreekanth Reddy * @mpi_reply: reply message frame 92f92363d1SSreekanth Reddy * Context: none. 93f92363d1SSreekanth Reddy * 94f92363d1SSreekanth Reddy * Function for displaying debug info helpful when debugging issues 95f92363d1SSreekanth Reddy * in this module. 96f92363d1SSreekanth Reddy */ 97f92363d1SSreekanth Reddy static void 98f92363d1SSreekanth Reddy _config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid, 99f92363d1SSreekanth Reddy char *calling_function_name, MPI2DefaultReply_t *mpi_reply) 100f92363d1SSreekanth Reddy { 101f92363d1SSreekanth Reddy Mpi2ConfigRequest_t *mpi_request; 102f92363d1SSreekanth Reddy char *desc = NULL; 103f92363d1SSreekanth Reddy 104f92363d1SSreekanth Reddy mpi_request = mpt3sas_base_get_msg_frame(ioc, smid); 105f92363d1SSreekanth Reddy switch (mpi_request->Header.PageType & MPI2_CONFIG_PAGETYPE_MASK) { 106f92363d1SSreekanth Reddy case MPI2_CONFIG_PAGETYPE_IO_UNIT: 107f92363d1SSreekanth Reddy desc = "io_unit"; 108f92363d1SSreekanth Reddy break; 109f92363d1SSreekanth Reddy case MPI2_CONFIG_PAGETYPE_IOC: 110f92363d1SSreekanth Reddy desc = "ioc"; 111f92363d1SSreekanth Reddy break; 112f92363d1SSreekanth Reddy case MPI2_CONFIG_PAGETYPE_BIOS: 113f92363d1SSreekanth Reddy desc = "bios"; 114f92363d1SSreekanth Reddy break; 115f92363d1SSreekanth Reddy case MPI2_CONFIG_PAGETYPE_RAID_VOLUME: 116f92363d1SSreekanth Reddy desc = "raid_volume"; 117f92363d1SSreekanth Reddy break; 118f92363d1SSreekanth Reddy case MPI2_CONFIG_PAGETYPE_MANUFACTURING: 1198700bc76SColin Ian King desc = "manufacturing"; 120f92363d1SSreekanth Reddy break; 121f92363d1SSreekanth Reddy case MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK: 122f92363d1SSreekanth Reddy desc = "physdisk"; 123f92363d1SSreekanth Reddy break; 124f92363d1SSreekanth Reddy case MPI2_CONFIG_PAGETYPE_EXTENDED: 125f92363d1SSreekanth Reddy switch (mpi_request->ExtPageType) { 126f92363d1SSreekanth Reddy case MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT: 127f92363d1SSreekanth Reddy desc = "sas_io_unit"; 128f92363d1SSreekanth Reddy break; 129f92363d1SSreekanth Reddy case MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER: 130f92363d1SSreekanth Reddy desc = "sas_expander"; 131f92363d1SSreekanth Reddy break; 132f92363d1SSreekanth Reddy case MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE: 133f92363d1SSreekanth Reddy desc = "sas_device"; 134f92363d1SSreekanth Reddy break; 135f92363d1SSreekanth Reddy case MPI2_CONFIG_EXTPAGETYPE_SAS_PHY: 136f92363d1SSreekanth Reddy desc = "sas_phy"; 137f92363d1SSreekanth Reddy break; 138f92363d1SSreekanth Reddy case MPI2_CONFIG_EXTPAGETYPE_LOG: 139f92363d1SSreekanth Reddy desc = "log"; 140f92363d1SSreekanth Reddy break; 141f92363d1SSreekanth Reddy case MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE: 142f92363d1SSreekanth Reddy desc = "enclosure"; 143f92363d1SSreekanth Reddy break; 144f92363d1SSreekanth Reddy case MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG: 145f92363d1SSreekanth Reddy desc = "raid_config"; 146f92363d1SSreekanth Reddy break; 147f92363d1SSreekanth Reddy case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING: 14807f42258SMasanari Iida desc = "driver_mapping"; 149f92363d1SSreekanth Reddy break; 150c102e00cSSuganath Prabu Subramani case MPI2_CONFIG_EXTPAGETYPE_SAS_PORT: 151c102e00cSSuganath Prabu Subramani desc = "sas_port"; 152c102e00cSSuganath Prabu Subramani break; 153c102e00cSSuganath Prabu Subramani case MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING: 154c102e00cSSuganath Prabu Subramani desc = "ext_manufacturing"; 155c102e00cSSuganath Prabu Subramani break; 156c102e00cSSuganath Prabu Subramani case MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT: 157c102e00cSSuganath Prabu Subramani desc = "pcie_io_unit"; 158c102e00cSSuganath Prabu Subramani break; 159c102e00cSSuganath Prabu Subramani case MPI2_CONFIG_EXTPAGETYPE_PCIE_SWITCH: 160c102e00cSSuganath Prabu Subramani desc = "pcie_switch"; 161c102e00cSSuganath Prabu Subramani break; 162c102e00cSSuganath Prabu Subramani case MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE: 163c102e00cSSuganath Prabu Subramani desc = "pcie_device"; 164c102e00cSSuganath Prabu Subramani break; 165c102e00cSSuganath Prabu Subramani case MPI2_CONFIG_EXTPAGETYPE_PCIE_LINK: 166c102e00cSSuganath Prabu Subramani desc = "pcie_link"; 167c102e00cSSuganath Prabu Subramani break; 168f92363d1SSreekanth Reddy } 169f92363d1SSreekanth Reddy break; 170f92363d1SSreekanth Reddy } 171f92363d1SSreekanth Reddy 172f92363d1SSreekanth Reddy if (!desc) 173f92363d1SSreekanth Reddy return; 174f92363d1SSreekanth Reddy 175919d8a3fSJoe Perches ioc_info(ioc, "%s: %s(%d), action(%d), form(0x%08x), smid(%d)\n", 176919d8a3fSJoe Perches calling_function_name, desc, 177f92363d1SSreekanth Reddy mpi_request->Header.PageNumber, mpi_request->Action, 178f92363d1SSreekanth Reddy le32_to_cpu(mpi_request->PageAddress), smid); 179f92363d1SSreekanth Reddy 180f92363d1SSreekanth Reddy if (!mpi_reply) 181f92363d1SSreekanth Reddy return; 182f92363d1SSreekanth Reddy 183f92363d1SSreekanth Reddy if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo) 184919d8a3fSJoe Perches ioc_info(ioc, "\tiocstatus(0x%04x), loginfo(0x%08x)\n", 185919d8a3fSJoe Perches le16_to_cpu(mpi_reply->IOCStatus), 186f92363d1SSreekanth Reddy le32_to_cpu(mpi_reply->IOCLogInfo)); 187f92363d1SSreekanth Reddy } 188f92363d1SSreekanth Reddy 189f92363d1SSreekanth Reddy /** 190f92363d1SSreekanth Reddy * _config_alloc_config_dma_memory - obtain physical memory 191f92363d1SSreekanth Reddy * @ioc: per adapter object 192f92363d1SSreekanth Reddy * @mem: struct config_request 193f92363d1SSreekanth Reddy * 194f92363d1SSreekanth Reddy * A wrapper for obtaining dma-able memory for config page request. 195f92363d1SSreekanth Reddy * 1964beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 197f92363d1SSreekanth Reddy */ 198f92363d1SSreekanth Reddy static int 199f92363d1SSreekanth Reddy _config_alloc_config_dma_memory(struct MPT3SAS_ADAPTER *ioc, 200f92363d1SSreekanth Reddy struct config_request *mem) 201f92363d1SSreekanth Reddy { 202f92363d1SSreekanth Reddy int r = 0; 203f92363d1SSreekanth Reddy 204f92363d1SSreekanth Reddy if (mem->sz > ioc->config_page_sz) { 205f92363d1SSreekanth Reddy mem->page = dma_alloc_coherent(&ioc->pdev->dev, mem->sz, 206f92363d1SSreekanth Reddy &mem->page_dma, GFP_KERNEL); 207f92363d1SSreekanth Reddy if (!mem->page) { 208919d8a3fSJoe Perches ioc_err(ioc, "%s: dma_alloc_coherent failed asking for (%d) bytes!!\n", 209919d8a3fSJoe Perches __func__, mem->sz); 210f92363d1SSreekanth Reddy r = -ENOMEM; 211f92363d1SSreekanth Reddy } 212f92363d1SSreekanth Reddy } else { /* use tmp buffer if less than 512 bytes */ 213f92363d1SSreekanth Reddy mem->page = ioc->config_page; 214f92363d1SSreekanth Reddy mem->page_dma = ioc->config_page_dma; 215f92363d1SSreekanth Reddy } 216182ac784SSuganath Prabu Subramani ioc->config_vaddr = mem->page; 217f92363d1SSreekanth Reddy return r; 218f92363d1SSreekanth Reddy } 219f92363d1SSreekanth Reddy 220f92363d1SSreekanth Reddy /** 221f92363d1SSreekanth Reddy * _config_free_config_dma_memory - wrapper to free the memory 222f92363d1SSreekanth Reddy * @ioc: per adapter object 223f92363d1SSreekanth Reddy * @mem: struct config_request 224f92363d1SSreekanth Reddy * 225f92363d1SSreekanth Reddy * A wrapper to free dma-able memory when using _config_alloc_config_dma_memory. 226f92363d1SSreekanth Reddy * 2274beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 228f92363d1SSreekanth Reddy */ 229f92363d1SSreekanth Reddy static void 230f92363d1SSreekanth Reddy _config_free_config_dma_memory(struct MPT3SAS_ADAPTER *ioc, 231f92363d1SSreekanth Reddy struct config_request *mem) 232f92363d1SSreekanth Reddy { 233f92363d1SSreekanth Reddy if (mem->sz > ioc->config_page_sz) 234f92363d1SSreekanth Reddy dma_free_coherent(&ioc->pdev->dev, mem->sz, mem->page, 235f92363d1SSreekanth Reddy mem->page_dma); 236f92363d1SSreekanth Reddy } 237f92363d1SSreekanth Reddy 238f92363d1SSreekanth Reddy /** 239f92363d1SSreekanth Reddy * mpt3sas_config_done - config page completion routine 240f92363d1SSreekanth Reddy * @ioc: per adapter object 241f92363d1SSreekanth Reddy * @smid: system request message index 242f92363d1SSreekanth Reddy * @msix_index: MSIX table index supplied by the OS 243f92363d1SSreekanth Reddy * @reply: reply message frame(lower 32bit addr) 244f92363d1SSreekanth Reddy * Context: none. 245f92363d1SSreekanth Reddy * 246f92363d1SSreekanth Reddy * The callback handler when using _config_request. 247f92363d1SSreekanth Reddy * 2484beb4867SBart Van Assche * Return: 1 meaning mf should be freed from _base_interrupt 249f92363d1SSreekanth Reddy * 0 means the mf is freed from this function. 250f92363d1SSreekanth Reddy */ 251f92363d1SSreekanth Reddy u8 252f92363d1SSreekanth Reddy mpt3sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, 253f92363d1SSreekanth Reddy u32 reply) 254f92363d1SSreekanth Reddy { 255f92363d1SSreekanth Reddy MPI2DefaultReply_t *mpi_reply; 256f92363d1SSreekanth Reddy 257f92363d1SSreekanth Reddy if (ioc->config_cmds.status == MPT3_CMD_NOT_USED) 258f92363d1SSreekanth Reddy return 1; 259f92363d1SSreekanth Reddy if (ioc->config_cmds.smid != smid) 260f92363d1SSreekanth Reddy return 1; 261f92363d1SSreekanth Reddy ioc->config_cmds.status |= MPT3_CMD_COMPLETE; 262f92363d1SSreekanth Reddy mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply); 263f92363d1SSreekanth Reddy if (mpi_reply) { 264f92363d1SSreekanth Reddy ioc->config_cmds.status |= MPT3_CMD_REPLY_VALID; 265f92363d1SSreekanth Reddy memcpy(ioc->config_cmds.reply, mpi_reply, 266f92363d1SSreekanth Reddy mpi_reply->MsgLength*4); 267f92363d1SSreekanth Reddy } 268f92363d1SSreekanth Reddy ioc->config_cmds.status &= ~MPT3_CMD_PENDING; 2695b061980SSreekanth Reddy if (ioc->logging_level & MPT_DEBUG_CONFIG) 270f92363d1SSreekanth Reddy _config_display_some_debug(ioc, smid, "config_done", mpi_reply); 271f92363d1SSreekanth Reddy ioc->config_cmds.smid = USHRT_MAX; 272f92363d1SSreekanth Reddy complete(&ioc->config_cmds.done); 273f92363d1SSreekanth Reddy return 1; 274f92363d1SSreekanth Reddy } 275f92363d1SSreekanth Reddy 276f92363d1SSreekanth Reddy /** 277f92363d1SSreekanth Reddy * _config_request - main routine for sending config page requests 278f92363d1SSreekanth Reddy * @ioc: per adapter object 279f92363d1SSreekanth Reddy * @mpi_request: request message frame 280f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 281f92363d1SSreekanth Reddy * @timeout: timeout in seconds 282f92363d1SSreekanth Reddy * @config_page: contents of the config page 283f92363d1SSreekanth Reddy * @config_page_sz: size of config page 284f92363d1SSreekanth Reddy * Context: sleep 285f92363d1SSreekanth Reddy * 286f92363d1SSreekanth Reddy * A generic API for config page requests to firmware. 287f92363d1SSreekanth Reddy * 288f92363d1SSreekanth Reddy * The ioc->config_cmds.status flag should be MPT3_CMD_NOT_USED before calling 289f92363d1SSreekanth Reddy * this API. 290f92363d1SSreekanth Reddy * 291f92363d1SSreekanth Reddy * The callback index is set inside `ioc->config_cb_idx. 292f92363d1SSreekanth Reddy * 2934beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 294f92363d1SSreekanth Reddy */ 295f92363d1SSreekanth Reddy static int 296f92363d1SSreekanth Reddy _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t 297f92363d1SSreekanth Reddy *mpi_request, Mpi2ConfigReply_t *mpi_reply, int timeout, 298f92363d1SSreekanth Reddy void *config_page, u16 config_page_sz) 299f92363d1SSreekanth Reddy { 300f92363d1SSreekanth Reddy u16 smid; 301f92363d1SSreekanth Reddy Mpi2ConfigRequest_t *config_request; 302f92363d1SSreekanth Reddy int r; 303f92363d1SSreekanth Reddy u8 retry_count, issue_host_reset = 0; 304f92363d1SSreekanth Reddy struct config_request mem; 305f92363d1SSreekanth Reddy u32 ioc_status = UINT_MAX; 306f92363d1SSreekanth Reddy 307f92363d1SSreekanth Reddy mutex_lock(&ioc->config_cmds.mutex); 308f92363d1SSreekanth Reddy if (ioc->config_cmds.status != MPT3_CMD_NOT_USED) { 309919d8a3fSJoe Perches ioc_err(ioc, "%s: config_cmd in use\n", __func__); 310f92363d1SSreekanth Reddy mutex_unlock(&ioc->config_cmds.mutex); 311f92363d1SSreekanth Reddy return -EAGAIN; 312f92363d1SSreekanth Reddy } 313f92363d1SSreekanth Reddy 314f92363d1SSreekanth Reddy retry_count = 0; 315f92363d1SSreekanth Reddy memset(&mem, 0, sizeof(struct config_request)); 316f92363d1SSreekanth Reddy 317f92363d1SSreekanth Reddy mpi_request->VF_ID = 0; /* TODO */ 318f92363d1SSreekanth Reddy mpi_request->VP_ID = 0; 319f92363d1SSreekanth Reddy 320f92363d1SSreekanth Reddy if (config_page) { 321f92363d1SSreekanth Reddy mpi_request->Header.PageVersion = mpi_reply->Header.PageVersion; 322f92363d1SSreekanth Reddy mpi_request->Header.PageNumber = mpi_reply->Header.PageNumber; 323f92363d1SSreekanth Reddy mpi_request->Header.PageType = mpi_reply->Header.PageType; 324f92363d1SSreekanth Reddy mpi_request->Header.PageLength = mpi_reply->Header.PageLength; 325f92363d1SSreekanth Reddy mpi_request->ExtPageLength = mpi_reply->ExtPageLength; 326f92363d1SSreekanth Reddy mpi_request->ExtPageType = mpi_reply->ExtPageType; 327f92363d1SSreekanth Reddy if (mpi_request->Header.PageLength) 328f92363d1SSreekanth Reddy mem.sz = mpi_request->Header.PageLength * 4; 329f92363d1SSreekanth Reddy else 330f92363d1SSreekanth Reddy mem.sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4; 331f92363d1SSreekanth Reddy r = _config_alloc_config_dma_memory(ioc, &mem); 332f92363d1SSreekanth Reddy if (r != 0) 333f92363d1SSreekanth Reddy goto out; 334f92363d1SSreekanth Reddy if (mpi_request->Action == 335f92363d1SSreekanth Reddy MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT || 336f92363d1SSreekanth Reddy mpi_request->Action == 337f92363d1SSreekanth Reddy MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) { 338f92363d1SSreekanth Reddy ioc->base_add_sg_single(&mpi_request->PageBufferSGE, 339f92363d1SSreekanth Reddy MPT3_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz, 340f92363d1SSreekanth Reddy mem.page_dma); 341f92363d1SSreekanth Reddy memcpy(mem.page, config_page, min_t(u16, mem.sz, 342f92363d1SSreekanth Reddy config_page_sz)); 343f92363d1SSreekanth Reddy } else { 344f92363d1SSreekanth Reddy memset(config_page, 0, config_page_sz); 345f92363d1SSreekanth Reddy ioc->base_add_sg_single(&mpi_request->PageBufferSGE, 346f92363d1SSreekanth Reddy MPT3_CONFIG_COMMON_SGLFLAGS | mem.sz, mem.page_dma); 347f92363d1SSreekanth Reddy memset(mem.page, 0, min_t(u16, mem.sz, config_page_sz)); 348f92363d1SSreekanth Reddy } 349f92363d1SSreekanth Reddy } 350f92363d1SSreekanth Reddy 351f92363d1SSreekanth Reddy retry_config: 352f92363d1SSreekanth Reddy if (retry_count) { 353f92363d1SSreekanth Reddy if (retry_count > 2) { /* attempt only 2 retries */ 354f92363d1SSreekanth Reddy r = -EFAULT; 355f92363d1SSreekanth Reddy goto free_mem; 356f92363d1SSreekanth Reddy } 357919d8a3fSJoe Perches ioc_info(ioc, "%s: attempting retry (%d)\n", 358919d8a3fSJoe Perches __func__, retry_count); 359f92363d1SSreekanth Reddy } 360f4305749SSuganath Prabu 361f4305749SSuganath Prabu r = mpt3sas_wait_for_ioc(ioc, MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT); 36219a622c3SSuganath Prabu S if (r) { 36319a622c3SSuganath Prabu S if (r == -ETIME) 36419a622c3SSuganath Prabu S issue_host_reset = 1; 365f92363d1SSreekanth Reddy goto free_mem; 36619a622c3SSuganath Prabu S } 367f92363d1SSreekanth Reddy 368f92363d1SSreekanth Reddy smid = mpt3sas_base_get_smid(ioc, ioc->config_cb_idx); 369f92363d1SSreekanth Reddy if (!smid) { 370919d8a3fSJoe Perches ioc_err(ioc, "%s: failed obtaining a smid\n", __func__); 371f92363d1SSreekanth Reddy ioc->config_cmds.status = MPT3_CMD_NOT_USED; 372f92363d1SSreekanth Reddy r = -EAGAIN; 373f92363d1SSreekanth Reddy goto free_mem; 374f92363d1SSreekanth Reddy } 375f92363d1SSreekanth Reddy 376f92363d1SSreekanth Reddy r = 0; 377f09219e4SSuganath Prabu S memset(ioc->config_cmds.reply, 0, sizeof(Mpi2ConfigReply_t)); 378f92363d1SSreekanth Reddy ioc->config_cmds.status = MPT3_CMD_PENDING; 379f92363d1SSreekanth Reddy config_request = mpt3sas_base_get_msg_frame(ioc, smid); 380f92363d1SSreekanth Reddy ioc->config_cmds.smid = smid; 381f92363d1SSreekanth Reddy memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t)); 3825b061980SSreekanth Reddy if (ioc->logging_level & MPT_DEBUG_CONFIG) 383f92363d1SSreekanth Reddy _config_display_some_debug(ioc, smid, "config_request", NULL); 384f92363d1SSreekanth Reddy init_completion(&ioc->config_cmds.done); 385078a4cc1SSuganath Prabu S ioc->put_smid_default(ioc, smid); 3868bbb1cf6SCalvin Owens wait_for_completion_timeout(&ioc->config_cmds.done, timeout*HZ); 387f92363d1SSreekanth Reddy if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) { 3885b061980SSreekanth Reddy if (!(ioc->logging_level & MPT_DEBUG_CONFIG)) 3895b061980SSreekanth Reddy _config_display_some_debug(ioc, 3905b061980SSreekanth Reddy smid, "config_request", NULL); 3912eab3eb0SDamien Le Moal ioc_err(ioc, "%s: command timeout\n", __func__); 3922eab3eb0SDamien Le Moal mpt3sas_base_check_cmd_timeout(ioc, ioc->config_cmds.status, 3932eab3eb0SDamien Le Moal mpi_request, sizeof(Mpi2ConfigRequest_t) / 4); 394f92363d1SSreekanth Reddy retry_count++; 395f92363d1SSreekanth Reddy if (ioc->config_cmds.smid == smid) 396f92363d1SSreekanth Reddy mpt3sas_base_free_smid(ioc, smid); 397*f61eb121SSreekanth Reddy if (ioc->config_cmds.status & MPT3_CMD_RESET) 398f92363d1SSreekanth Reddy goto retry_config; 399*f61eb121SSreekanth Reddy if (ioc->shost_recovery || ioc->pci_error_recovery) { 400*f61eb121SSreekanth Reddy issue_host_reset = 0; 401*f61eb121SSreekanth Reddy r = -EFAULT; 402*f61eb121SSreekanth Reddy } else 403f92363d1SSreekanth Reddy issue_host_reset = 1; 404f92363d1SSreekanth Reddy goto free_mem; 405f92363d1SSreekanth Reddy } 406f92363d1SSreekanth Reddy 407f92363d1SSreekanth Reddy if (ioc->config_cmds.status & MPT3_CMD_REPLY_VALID) { 408f92363d1SSreekanth Reddy memcpy(mpi_reply, ioc->config_cmds.reply, 409f92363d1SSreekanth Reddy sizeof(Mpi2ConfigReply_t)); 410f92363d1SSreekanth Reddy 411f92363d1SSreekanth Reddy /* Reply Frame Sanity Checks to workaround FW issues */ 412f92363d1SSreekanth Reddy if ((mpi_request->Header.PageType & 0xF) != 413f92363d1SSreekanth Reddy (mpi_reply->Header.PageType & 0xF)) { 4145b061980SSreekanth Reddy if (!(ioc->logging_level & MPT_DEBUG_CONFIG)) 4155b061980SSreekanth Reddy _config_display_some_debug(ioc, 4165b061980SSreekanth Reddy smid, "config_request", NULL); 417f92363d1SSreekanth Reddy _debug_dump_mf(mpi_request, ioc->request_sz/4); 4185b061980SSreekanth Reddy _debug_dump_reply(mpi_reply, ioc->reply_sz/4); 419506f7f6bSJoe Perches panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n", 420f92363d1SSreekanth Reddy ioc->name, __func__, 421506f7f6bSJoe Perches mpi_request->Header.PageType & 0xF, 422506f7f6bSJoe Perches mpi_reply->Header.PageType & 0xF); 423f92363d1SSreekanth Reddy } 424f92363d1SSreekanth Reddy 425f92363d1SSreekanth Reddy if (((mpi_request->Header.PageType & 0xF) == 426f92363d1SSreekanth Reddy MPI2_CONFIG_PAGETYPE_EXTENDED) && 427f92363d1SSreekanth Reddy mpi_request->ExtPageType != mpi_reply->ExtPageType) { 4285b061980SSreekanth Reddy if (!(ioc->logging_level & MPT_DEBUG_CONFIG)) 4295b061980SSreekanth Reddy _config_display_some_debug(ioc, 4305b061980SSreekanth Reddy smid, "config_request", NULL); 431f92363d1SSreekanth Reddy _debug_dump_mf(mpi_request, ioc->request_sz/4); 4325b061980SSreekanth Reddy _debug_dump_reply(mpi_reply, ioc->reply_sz/4); 433506f7f6bSJoe Perches panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n", 434506f7f6bSJoe Perches ioc->name, __func__, 435506f7f6bSJoe Perches mpi_request->ExtPageType, 436f92363d1SSreekanth Reddy mpi_reply->ExtPageType); 437f92363d1SSreekanth Reddy } 438f92363d1SSreekanth Reddy ioc_status = le16_to_cpu(mpi_reply->IOCStatus) 439f92363d1SSreekanth Reddy & MPI2_IOCSTATUS_MASK; 440f92363d1SSreekanth Reddy } 441f92363d1SSreekanth Reddy 442f92363d1SSreekanth Reddy if (retry_count) 443919d8a3fSJoe Perches ioc_info(ioc, "%s: retry (%d) completed!!\n", 444919d8a3fSJoe Perches __func__, retry_count); 445f92363d1SSreekanth Reddy 446f92363d1SSreekanth Reddy if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) && 447f92363d1SSreekanth Reddy config_page && mpi_request->Action == 448f92363d1SSreekanth Reddy MPI2_CONFIG_ACTION_PAGE_READ_CURRENT) { 449f92363d1SSreekanth Reddy u8 *p = (u8 *)mem.page; 450f92363d1SSreekanth Reddy 451f92363d1SSreekanth Reddy /* Config Page Sanity Checks to workaround FW issues */ 452f92363d1SSreekanth Reddy if (p) { 453f92363d1SSreekanth Reddy if ((mpi_request->Header.PageType & 0xF) != 454f92363d1SSreekanth Reddy (p[3] & 0xF)) { 4555b061980SSreekanth Reddy if (!(ioc->logging_level & MPT_DEBUG_CONFIG)) 4565b061980SSreekanth Reddy _config_display_some_debug(ioc, 4575b061980SSreekanth Reddy smid, "config_request", NULL); 458f92363d1SSreekanth Reddy _debug_dump_mf(mpi_request, ioc->request_sz/4); 4595b061980SSreekanth Reddy _debug_dump_reply(mpi_reply, ioc->reply_sz/4); 460f92363d1SSreekanth Reddy _debug_dump_config(p, min_t(u16, mem.sz, 461f92363d1SSreekanth Reddy config_page_sz)/4); 462506f7f6bSJoe Perches panic("%s: %s: Firmware BUG: config page mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n", 463f92363d1SSreekanth Reddy ioc->name, __func__, 464506f7f6bSJoe Perches mpi_request->Header.PageType & 0xF, 465506f7f6bSJoe Perches p[3] & 0xF); 466f92363d1SSreekanth Reddy } 467f92363d1SSreekanth Reddy 468f92363d1SSreekanth Reddy if (((mpi_request->Header.PageType & 0xF) == 469f92363d1SSreekanth Reddy MPI2_CONFIG_PAGETYPE_EXTENDED) && 470f92363d1SSreekanth Reddy (mpi_request->ExtPageType != p[6])) { 4715b061980SSreekanth Reddy if (!(ioc->logging_level & MPT_DEBUG_CONFIG)) 4725b061980SSreekanth Reddy _config_display_some_debug(ioc, 4735b061980SSreekanth Reddy smid, "config_request", NULL); 474f92363d1SSreekanth Reddy _debug_dump_mf(mpi_request, ioc->request_sz/4); 4755b061980SSreekanth Reddy _debug_dump_reply(mpi_reply, ioc->reply_sz/4); 476f92363d1SSreekanth Reddy _debug_dump_config(p, min_t(u16, mem.sz, 477f92363d1SSreekanth Reddy config_page_sz)/4); 478506f7f6bSJoe Perches panic("%s: %s: Firmware BUG: config page mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n", 479f92363d1SSreekanth Reddy ioc->name, __func__, 480f92363d1SSreekanth Reddy mpi_request->ExtPageType, p[6]); 481f92363d1SSreekanth Reddy } 482f92363d1SSreekanth Reddy } 483f92363d1SSreekanth Reddy memcpy(config_page, mem.page, min_t(u16, mem.sz, 484f92363d1SSreekanth Reddy config_page_sz)); 485f92363d1SSreekanth Reddy } 486f92363d1SSreekanth Reddy 487f92363d1SSreekanth Reddy free_mem: 488f92363d1SSreekanth Reddy if (config_page) 489f92363d1SSreekanth Reddy _config_free_config_dma_memory(ioc, &mem); 490f92363d1SSreekanth Reddy out: 491f92363d1SSreekanth Reddy ioc->config_cmds.status = MPT3_CMD_NOT_USED; 492f92363d1SSreekanth Reddy mutex_unlock(&ioc->config_cmds.mutex); 493f92363d1SSreekanth Reddy 49419a622c3SSuganath Prabu S if (issue_host_reset) { 49519a622c3SSuganath Prabu S if (ioc->drv_internal_flags & MPT_DRV_INTERNAL_FIRST_PE_ISSUED) { 49698c56ad3SCalvin Owens mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER); 49719a622c3SSuganath Prabu S r = -EFAULT; 49819a622c3SSuganath Prabu S } else { 49919a622c3SSuganath Prabu S if (mpt3sas_base_check_for_fault_and_issue_reset(ioc)) 50019a622c3SSuganath Prabu S return -EFAULT; 50119a622c3SSuganath Prabu S r = -EAGAIN; 50219a622c3SSuganath Prabu S } 50319a622c3SSuganath Prabu S } 504f92363d1SSreekanth Reddy return r; 505f92363d1SSreekanth Reddy } 506f92363d1SSreekanth Reddy 507f92363d1SSreekanth Reddy /** 508f92363d1SSreekanth Reddy * mpt3sas_config_get_manufacturing_pg0 - obtain manufacturing page 0 509f92363d1SSreekanth Reddy * @ioc: per adapter object 510f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 511f92363d1SSreekanth Reddy * @config_page: contents of the config page 512f92363d1SSreekanth Reddy * Context: sleep. 513f92363d1SSreekanth Reddy * 5144beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 515f92363d1SSreekanth Reddy */ 516f92363d1SSreekanth Reddy int 517f92363d1SSreekanth Reddy mpt3sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER *ioc, 518f92363d1SSreekanth Reddy Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page) 519f92363d1SSreekanth Reddy { 520f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 521f92363d1SSreekanth Reddy int r; 522f92363d1SSreekanth Reddy 523f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 524f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 525f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 526f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; 527f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 0; 528f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; 529f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 530f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 531f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 532f92363d1SSreekanth Reddy if (r) 533f92363d1SSreekanth Reddy goto out; 534f92363d1SSreekanth Reddy 535f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 536f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 537f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 538f92363d1SSreekanth Reddy sizeof(*config_page)); 539f92363d1SSreekanth Reddy out: 540f92363d1SSreekanth Reddy return r; 541f92363d1SSreekanth Reddy } 542f92363d1SSreekanth Reddy 543f92363d1SSreekanth Reddy /** 544f92363d1SSreekanth Reddy * mpt3sas_config_get_manufacturing_pg7 - obtain manufacturing page 7 545f92363d1SSreekanth Reddy * @ioc: per adapter object 546f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 547f92363d1SSreekanth Reddy * @config_page: contents of the config page 548f92363d1SSreekanth Reddy * @sz: size of buffer passed in config_page 549f92363d1SSreekanth Reddy * Context: sleep. 550f92363d1SSreekanth Reddy * 5514beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 552f92363d1SSreekanth Reddy */ 553f92363d1SSreekanth Reddy int 554f92363d1SSreekanth Reddy mpt3sas_config_get_manufacturing_pg7(struct MPT3SAS_ADAPTER *ioc, 555f92363d1SSreekanth Reddy Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage7_t *config_page, 556f92363d1SSreekanth Reddy u16 sz) 557f92363d1SSreekanth Reddy { 558f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 559f92363d1SSreekanth Reddy int r; 560f92363d1SSreekanth Reddy 561f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 562f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 563f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 564f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; 565f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 7; 566f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_MANUFACTURING7_PAGEVERSION; 567f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 568f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 569f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 570f92363d1SSreekanth Reddy if (r) 571f92363d1SSreekanth Reddy goto out; 572f92363d1SSreekanth Reddy 573f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 574f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 575f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 576f92363d1SSreekanth Reddy sz); 577f92363d1SSreekanth Reddy out: 578f92363d1SSreekanth Reddy return r; 579f92363d1SSreekanth Reddy } 580f92363d1SSreekanth Reddy 581f92363d1SSreekanth Reddy /** 582f92363d1SSreekanth Reddy * mpt3sas_config_get_manufacturing_pg10 - obtain manufacturing page 10 583f92363d1SSreekanth Reddy * @ioc: per adapter object 584f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 585f92363d1SSreekanth Reddy * @config_page: contents of the config page 586f92363d1SSreekanth Reddy * Context: sleep. 587f92363d1SSreekanth Reddy * 5884beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 589f92363d1SSreekanth Reddy */ 590f92363d1SSreekanth Reddy int 591f92363d1SSreekanth Reddy mpt3sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER *ioc, 592f92363d1SSreekanth Reddy Mpi2ConfigReply_t *mpi_reply, 593f92363d1SSreekanth Reddy struct Mpi2ManufacturingPage10_t *config_page) 594f92363d1SSreekanth Reddy { 595f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 596f92363d1SSreekanth Reddy int r; 597f92363d1SSreekanth Reddy 598f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 599f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 600f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 601f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; 602f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 10; 603f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; 604f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 605f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 606f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 607f92363d1SSreekanth Reddy if (r) 608f92363d1SSreekanth Reddy goto out; 609f92363d1SSreekanth Reddy 610f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 611f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 612f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 613f92363d1SSreekanth Reddy sizeof(*config_page)); 614f92363d1SSreekanth Reddy out: 615f92363d1SSreekanth Reddy return r; 616f92363d1SSreekanth Reddy } 617f92363d1SSreekanth Reddy 618f92363d1SSreekanth Reddy /** 619f92363d1SSreekanth Reddy * mpt3sas_config_get_manufacturing_pg11 - obtain manufacturing page 11 620f92363d1SSreekanth Reddy * @ioc: per adapter object 621f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 622f92363d1SSreekanth Reddy * @config_page: contents of the config page 623f92363d1SSreekanth Reddy * Context: sleep. 624f92363d1SSreekanth Reddy * 6254beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 626f92363d1SSreekanth Reddy */ 627f92363d1SSreekanth Reddy int 628f92363d1SSreekanth Reddy mpt3sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc, 629f92363d1SSreekanth Reddy Mpi2ConfigReply_t *mpi_reply, 630f92363d1SSreekanth Reddy struct Mpi2ManufacturingPage11_t *config_page) 631f92363d1SSreekanth Reddy { 632f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 633f92363d1SSreekanth Reddy int r; 634f92363d1SSreekanth Reddy 635f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 636f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 637f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 638f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; 639f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 11; 640f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; 641f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 642f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 643f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 644f92363d1SSreekanth Reddy if (r) 645f92363d1SSreekanth Reddy goto out; 646f92363d1SSreekanth Reddy 647f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 648f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 649f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 650f92363d1SSreekanth Reddy sizeof(*config_page)); 651f92363d1SSreekanth Reddy out: 652f92363d1SSreekanth Reddy return r; 653f92363d1SSreekanth Reddy } 654f92363d1SSreekanth Reddy 655f92363d1SSreekanth Reddy /** 656f92363d1SSreekanth Reddy * mpt3sas_config_set_manufacturing_pg11 - set manufacturing page 11 657f92363d1SSreekanth Reddy * @ioc: per adapter object 658f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 659f92363d1SSreekanth Reddy * @config_page: contents of the config page 660f92363d1SSreekanth Reddy * Context: sleep. 661f92363d1SSreekanth Reddy * 6624beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 663f92363d1SSreekanth Reddy */ 664f92363d1SSreekanth Reddy int 665f92363d1SSreekanth Reddy mpt3sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc, 666f92363d1SSreekanth Reddy Mpi2ConfigReply_t *mpi_reply, 667f92363d1SSreekanth Reddy struct Mpi2ManufacturingPage11_t *config_page) 668f92363d1SSreekanth Reddy { 669f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 670f92363d1SSreekanth Reddy int r; 671f92363d1SSreekanth Reddy 672f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 673f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 674f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 675f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; 676f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 11; 677f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; 678f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 679f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 680f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 681f92363d1SSreekanth Reddy if (r) 682f92363d1SSreekanth Reddy goto out; 683f92363d1SSreekanth Reddy 684f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 685f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 686f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 687f92363d1SSreekanth Reddy sizeof(*config_page)); 688f92363d1SSreekanth Reddy out: 689f92363d1SSreekanth Reddy return r; 690f92363d1SSreekanth Reddy } 691f92363d1SSreekanth Reddy 692f92363d1SSreekanth Reddy /** 693f92363d1SSreekanth Reddy * mpt3sas_config_get_bios_pg2 - obtain bios page 2 694f92363d1SSreekanth Reddy * @ioc: per adapter object 695f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 696f92363d1SSreekanth Reddy * @config_page: contents of the config page 697f92363d1SSreekanth Reddy * Context: sleep. 698f92363d1SSreekanth Reddy * 6994beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 700f92363d1SSreekanth Reddy */ 701f92363d1SSreekanth Reddy int 702f92363d1SSreekanth Reddy mpt3sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER *ioc, 703f92363d1SSreekanth Reddy Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page) 704f92363d1SSreekanth Reddy { 705f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 706f92363d1SSreekanth Reddy int r; 707f92363d1SSreekanth Reddy 708f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 709f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 710f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 711f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS; 712f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 2; 713f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION; 714f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 715f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 716f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 717f92363d1SSreekanth Reddy if (r) 718f92363d1SSreekanth Reddy goto out; 719f92363d1SSreekanth Reddy 720f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 721f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 722f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 723f92363d1SSreekanth Reddy sizeof(*config_page)); 724f92363d1SSreekanth Reddy out: 725f92363d1SSreekanth Reddy return r; 726f92363d1SSreekanth Reddy } 727f92363d1SSreekanth Reddy 728f92363d1SSreekanth Reddy /** 729f92363d1SSreekanth Reddy * mpt3sas_config_get_bios_pg3 - obtain bios page 3 730f92363d1SSreekanth Reddy * @ioc: per adapter object 731f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 732f92363d1SSreekanth Reddy * @config_page: contents of the config page 733f92363d1SSreekanth Reddy * Context: sleep. 734f92363d1SSreekanth Reddy * 7354beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 736f92363d1SSreekanth Reddy */ 737f92363d1SSreekanth Reddy int 738f92363d1SSreekanth Reddy mpt3sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 739f92363d1SSreekanth Reddy *mpi_reply, Mpi2BiosPage3_t *config_page) 740f92363d1SSreekanth Reddy { 741f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 742f92363d1SSreekanth Reddy int r; 743f92363d1SSreekanth Reddy 744f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 745f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 746f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 747f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS; 748f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 3; 749f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION; 750f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 751f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 752f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 753f92363d1SSreekanth Reddy if (r) 754f92363d1SSreekanth Reddy goto out; 755f92363d1SSreekanth Reddy 756f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 757f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 758f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 759f92363d1SSreekanth Reddy sizeof(*config_page)); 760f92363d1SSreekanth Reddy out: 761f92363d1SSreekanth Reddy return r; 762f92363d1SSreekanth Reddy } 763f92363d1SSreekanth Reddy 764f92363d1SSreekanth Reddy /** 765f92363d1SSreekanth Reddy * mpt3sas_config_get_iounit_pg0 - obtain iounit page 0 766f92363d1SSreekanth Reddy * @ioc: per adapter object 767f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 768f92363d1SSreekanth Reddy * @config_page: contents of the config page 769f92363d1SSreekanth Reddy * Context: sleep. 770f92363d1SSreekanth Reddy * 7714beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 772f92363d1SSreekanth Reddy */ 773f92363d1SSreekanth Reddy int 774f92363d1SSreekanth Reddy mpt3sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER *ioc, 775f92363d1SSreekanth Reddy Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page) 776f92363d1SSreekanth Reddy { 777f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 778f92363d1SSreekanth Reddy int r; 779f92363d1SSreekanth Reddy 780f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 781f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 782f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 783f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; 784f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 0; 785f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION; 786f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 787f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 788f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 789f92363d1SSreekanth Reddy if (r) 790f92363d1SSreekanth Reddy goto out; 791f92363d1SSreekanth Reddy 792f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 793f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 794f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 795f92363d1SSreekanth Reddy sizeof(*config_page)); 796f92363d1SSreekanth Reddy out: 797f92363d1SSreekanth Reddy return r; 798f92363d1SSreekanth Reddy } 799f92363d1SSreekanth Reddy 800f92363d1SSreekanth Reddy /** 801f92363d1SSreekanth Reddy * mpt3sas_config_get_iounit_pg1 - obtain iounit page 1 802f92363d1SSreekanth Reddy * @ioc: per adapter object 803f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 804f92363d1SSreekanth Reddy * @config_page: contents of the config page 805f92363d1SSreekanth Reddy * Context: sleep. 806f92363d1SSreekanth Reddy * 8074beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 808f92363d1SSreekanth Reddy */ 809f92363d1SSreekanth Reddy int 810f92363d1SSreekanth Reddy mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, 811f92363d1SSreekanth Reddy Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page) 812f92363d1SSreekanth Reddy { 813f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 814f92363d1SSreekanth Reddy int r; 815f92363d1SSreekanth Reddy 816f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 817f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 818f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 819f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; 820f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 1; 821f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION; 822f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 823f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 824f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 825f92363d1SSreekanth Reddy if (r) 826f92363d1SSreekanth Reddy goto out; 827f92363d1SSreekanth Reddy 828f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 829f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 830f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 831f92363d1SSreekanth Reddy sizeof(*config_page)); 832f92363d1SSreekanth Reddy out: 833f92363d1SSreekanth Reddy return r; 834f92363d1SSreekanth Reddy } 835f92363d1SSreekanth Reddy 836f92363d1SSreekanth Reddy /** 837f92363d1SSreekanth Reddy * mpt3sas_config_set_iounit_pg1 - set iounit page 1 838f92363d1SSreekanth Reddy * @ioc: per adapter object 839f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 840f92363d1SSreekanth Reddy * @config_page: contents of the config page 841f92363d1SSreekanth Reddy * Context: sleep. 842f92363d1SSreekanth Reddy * 8434beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 844f92363d1SSreekanth Reddy */ 845f92363d1SSreekanth Reddy int 846f92363d1SSreekanth Reddy mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, 847f92363d1SSreekanth Reddy Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page) 848f92363d1SSreekanth Reddy { 849f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 850f92363d1SSreekanth Reddy int r; 851f92363d1SSreekanth Reddy 852f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 853f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 854f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 855f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; 856f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 1; 857f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION; 858f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 859f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 860f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 861f92363d1SSreekanth Reddy if (r) 862f92363d1SSreekanth Reddy goto out; 863f92363d1SSreekanth Reddy 864f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 865f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 866f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 867f92363d1SSreekanth Reddy sizeof(*config_page)); 868f92363d1SSreekanth Reddy out: 869f92363d1SSreekanth Reddy return r; 870f92363d1SSreekanth Reddy } 871f92363d1SSreekanth Reddy 87242263095SSreekanth Reddy /** 87342263095SSreekanth Reddy * mpt3sas_config_get_iounit_pg3 - obtain iounit page 3 87442263095SSreekanth Reddy * @ioc: per adapter object 87542263095SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 87642263095SSreekanth Reddy * @config_page: contents of the config page 87742263095SSreekanth Reddy * @sz: size of buffer passed in config_page 87842263095SSreekanth Reddy * Context: sleep. 87942263095SSreekanth Reddy * 8804beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 88142263095SSreekanth Reddy */ 88242263095SSreekanth Reddy int 88342263095SSreekanth Reddy mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc, 88442263095SSreekanth Reddy Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz) 88542263095SSreekanth Reddy { 88642263095SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 88742263095SSreekanth Reddy int r; 88842263095SSreekanth Reddy 88942263095SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 89042263095SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 89142263095SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 89242263095SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; 89342263095SSreekanth Reddy mpi_request.Header.PageNumber = 3; 89442263095SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION; 89542263095SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 89642263095SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 89742263095SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 89842263095SSreekanth Reddy if (r) 89942263095SSreekanth Reddy goto out; 90042263095SSreekanth Reddy 90142263095SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 90242263095SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 90342263095SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 90442263095SSreekanth Reddy out: 90542263095SSreekanth Reddy return r; 90642263095SSreekanth Reddy } 90742263095SSreekanth Reddy 908f92363d1SSreekanth Reddy /** 9092d8ce8c9SSreekanth Reddy * mpt3sas_config_get_iounit_pg8 - obtain iounit page 8 9102d8ce8c9SSreekanth Reddy * @ioc: per adapter object 9112d8ce8c9SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 9122d8ce8c9SSreekanth Reddy * @config_page: contents of the config page 9132d8ce8c9SSreekanth Reddy * Context: sleep. 9142d8ce8c9SSreekanth Reddy * 9154beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 9162d8ce8c9SSreekanth Reddy */ 9172d8ce8c9SSreekanth Reddy int 9182d8ce8c9SSreekanth Reddy mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc, 9192d8ce8c9SSreekanth Reddy Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page) 9202d8ce8c9SSreekanth Reddy { 9212d8ce8c9SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 9222d8ce8c9SSreekanth Reddy int r; 9232d8ce8c9SSreekanth Reddy 9242d8ce8c9SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 9252d8ce8c9SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 9262d8ce8c9SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 9272d8ce8c9SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; 9282d8ce8c9SSreekanth Reddy mpi_request.Header.PageNumber = 8; 9292d8ce8c9SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION; 9302d8ce8c9SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 9312d8ce8c9SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 9322d8ce8c9SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 9332d8ce8c9SSreekanth Reddy if (r) 9342d8ce8c9SSreekanth Reddy goto out; 9352d8ce8c9SSreekanth Reddy 9362d8ce8c9SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 9372d8ce8c9SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 9382d8ce8c9SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 9392d8ce8c9SSreekanth Reddy sizeof(*config_page)); 9402d8ce8c9SSreekanth Reddy out: 9412d8ce8c9SSreekanth Reddy return r; 9422d8ce8c9SSreekanth Reddy } 9432d8ce8c9SSreekanth Reddy 9442d8ce8c9SSreekanth Reddy /** 945f92363d1SSreekanth Reddy * mpt3sas_config_get_ioc_pg8 - obtain ioc page 8 946f92363d1SSreekanth Reddy * @ioc: per adapter object 947f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 948f92363d1SSreekanth Reddy * @config_page: contents of the config page 949f92363d1SSreekanth Reddy * Context: sleep. 950f92363d1SSreekanth Reddy * 9514beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 952f92363d1SSreekanth Reddy */ 953f92363d1SSreekanth Reddy int 954f92363d1SSreekanth Reddy mpt3sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER *ioc, 955f92363d1SSreekanth Reddy Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page) 956f92363d1SSreekanth Reddy { 957f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 958f92363d1SSreekanth Reddy int r; 959f92363d1SSreekanth Reddy 960f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 961f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 962f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 963f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC; 964f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 8; 965f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION; 966f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 967f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 968f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 969f92363d1SSreekanth Reddy if (r) 970f92363d1SSreekanth Reddy goto out; 971f92363d1SSreekanth Reddy 972f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 973f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 974f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 975f92363d1SSreekanth Reddy sizeof(*config_page)); 976f92363d1SSreekanth Reddy out: 977f92363d1SSreekanth Reddy return r; 978f92363d1SSreekanth Reddy } 9792426f209SSuganath Prabu S /** 9802426f209SSuganath Prabu S * mpt3sas_config_get_ioc_pg1 - obtain ioc page 1 9812426f209SSuganath Prabu S * @ioc: per adapter object 9822426f209SSuganath Prabu S * @mpi_reply: reply mf payload returned from firmware 9832426f209SSuganath Prabu S * @config_page: contents of the config page 9842426f209SSuganath Prabu S * Context: sleep. 9852426f209SSuganath Prabu S * 9862426f209SSuganath Prabu S * Return: 0 for success, non-zero for failure. 9872426f209SSuganath Prabu S */ 9882426f209SSuganath Prabu S int 9892426f209SSuganath Prabu S mpt3sas_config_get_ioc_pg1(struct MPT3SAS_ADAPTER *ioc, 9902426f209SSuganath Prabu S Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page) 9912426f209SSuganath Prabu S { 9922426f209SSuganath Prabu S Mpi2ConfigRequest_t mpi_request; 9932426f209SSuganath Prabu S int r; 9942426f209SSuganath Prabu S 9952426f209SSuganath Prabu S memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 9962426f209SSuganath Prabu S mpi_request.Function = MPI2_FUNCTION_CONFIG; 9972426f209SSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 9982426f209SSuganath Prabu S mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC; 9992426f209SSuganath Prabu S mpi_request.Header.PageNumber = 1; 10002426f209SSuganath Prabu S mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION; 10012426f209SSuganath Prabu S ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 10022426f209SSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 10032426f209SSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 10042426f209SSuganath Prabu S if (r) 10052426f209SSuganath Prabu S goto out; 10062426f209SSuganath Prabu S 10072426f209SSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 10082426f209SSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 10092426f209SSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 10102426f209SSuganath Prabu S sizeof(*config_page)); 10112426f209SSuganath Prabu S out: 10122426f209SSuganath Prabu S return r; 10132426f209SSuganath Prabu S } 10142426f209SSuganath Prabu S 10152426f209SSuganath Prabu S /** 10162426f209SSuganath Prabu S * mpt3sas_config_set_ioc_pg1 - modify ioc page 1 10172426f209SSuganath Prabu S * @ioc: per adapter object 10182426f209SSuganath Prabu S * @mpi_reply: reply mf payload returned from firmware 10192426f209SSuganath Prabu S * @config_page: contents of the config page 10202426f209SSuganath Prabu S * Context: sleep. 10212426f209SSuganath Prabu S * 10222426f209SSuganath Prabu S * Return: 0 for success, non-zero for failure. 10232426f209SSuganath Prabu S */ 10242426f209SSuganath Prabu S int 10252426f209SSuganath Prabu S mpt3sas_config_set_ioc_pg1(struct MPT3SAS_ADAPTER *ioc, 10262426f209SSuganath Prabu S Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page) 10272426f209SSuganath Prabu S { 10282426f209SSuganath Prabu S Mpi2ConfigRequest_t mpi_request; 10292426f209SSuganath Prabu S int r; 10302426f209SSuganath Prabu S 10312426f209SSuganath Prabu S memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 10322426f209SSuganath Prabu S mpi_request.Function = MPI2_FUNCTION_CONFIG; 10332426f209SSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 10342426f209SSuganath Prabu S mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC; 10352426f209SSuganath Prabu S mpi_request.Header.PageNumber = 1; 10362426f209SSuganath Prabu S mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION; 10372426f209SSuganath Prabu S ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 10382426f209SSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 10392426f209SSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 10402426f209SSuganath Prabu S if (r) 10412426f209SSuganath Prabu S goto out; 10422426f209SSuganath Prabu S 10432426f209SSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 10442426f209SSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 10452426f209SSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 10462426f209SSuganath Prabu S sizeof(*config_page)); 10472426f209SSuganath Prabu S out: 10482426f209SSuganath Prabu S return r; 10492426f209SSuganath Prabu S } 1050f92363d1SSreekanth Reddy 1051f92363d1SSreekanth Reddy /** 1052f92363d1SSreekanth Reddy * mpt3sas_config_get_sas_device_pg0 - obtain sas device page 0 1053f92363d1SSreekanth Reddy * @ioc: per adapter object 1054f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 1055f92363d1SSreekanth Reddy * @config_page: contents of the config page 1056f92363d1SSreekanth Reddy * @form: GET_NEXT_HANDLE or HANDLE 1057f92363d1SSreekanth Reddy * @handle: device handle 1058f92363d1SSreekanth Reddy * Context: sleep. 1059f92363d1SSreekanth Reddy * 10604beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 1061f92363d1SSreekanth Reddy */ 1062f92363d1SSreekanth Reddy int 1063f92363d1SSreekanth Reddy mpt3sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc, 1064f92363d1SSreekanth Reddy Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage0_t *config_page, 1065f92363d1SSreekanth Reddy u32 form, u32 handle) 1066f92363d1SSreekanth Reddy { 1067f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 1068f92363d1SSreekanth Reddy int r; 1069f92363d1SSreekanth Reddy 1070f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1071f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 1072f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1073f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1074f92363d1SSreekanth Reddy mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE; 1075f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION; 1076f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 0; 1077f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1078f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1079f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1080f92363d1SSreekanth Reddy if (r) 1081f92363d1SSreekanth Reddy goto out; 1082f92363d1SSreekanth Reddy 1083f92363d1SSreekanth Reddy mpi_request.PageAddress = cpu_to_le32(form | handle); 1084f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1085f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1086f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1087f92363d1SSreekanth Reddy sizeof(*config_page)); 1088f92363d1SSreekanth Reddy out: 1089f92363d1SSreekanth Reddy return r; 1090f92363d1SSreekanth Reddy } 1091f92363d1SSreekanth Reddy 1092f92363d1SSreekanth Reddy /** 1093f92363d1SSreekanth Reddy * mpt3sas_config_get_sas_device_pg1 - obtain sas device page 1 1094f92363d1SSreekanth Reddy * @ioc: per adapter object 1095f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 1096f92363d1SSreekanth Reddy * @config_page: contents of the config page 1097f92363d1SSreekanth Reddy * @form: GET_NEXT_HANDLE or HANDLE 1098f92363d1SSreekanth Reddy * @handle: device handle 1099f92363d1SSreekanth Reddy * Context: sleep. 1100f92363d1SSreekanth Reddy * 11014beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 1102f92363d1SSreekanth Reddy */ 1103f92363d1SSreekanth Reddy int 1104f92363d1SSreekanth Reddy mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc, 1105f92363d1SSreekanth Reddy Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page, 1106f92363d1SSreekanth Reddy u32 form, u32 handle) 1107f92363d1SSreekanth Reddy { 1108f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 1109f92363d1SSreekanth Reddy int r; 1110f92363d1SSreekanth Reddy 1111f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1112f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 1113f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1114f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1115f92363d1SSreekanth Reddy mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE; 1116f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION; 1117f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 1; 1118f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1119f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1120f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1121f92363d1SSreekanth Reddy if (r) 1122f92363d1SSreekanth Reddy goto out; 1123f92363d1SSreekanth Reddy 1124f92363d1SSreekanth Reddy mpi_request.PageAddress = cpu_to_le32(form | handle); 1125f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1126f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1127f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1128f92363d1SSreekanth Reddy sizeof(*config_page)); 1129f92363d1SSreekanth Reddy out: 1130f92363d1SSreekanth Reddy return r; 1131f92363d1SSreekanth Reddy } 1132f92363d1SSreekanth Reddy 1133f92363d1SSreekanth Reddy /** 1134c102e00cSSuganath Prabu Subramani * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 0 1135c102e00cSSuganath Prabu Subramani * @ioc: per adapter object 1136c102e00cSSuganath Prabu Subramani * @mpi_reply: reply mf payload returned from firmware 1137c102e00cSSuganath Prabu Subramani * @config_page: contents of the config page 1138c102e00cSSuganath Prabu Subramani * @form: GET_NEXT_HANDLE or HANDLE 1139c102e00cSSuganath Prabu Subramani * @handle: device handle 1140c102e00cSSuganath Prabu Subramani * Context: sleep. 1141c102e00cSSuganath Prabu Subramani * 11424beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 1143c102e00cSSuganath Prabu Subramani */ 1144c102e00cSSuganath Prabu Subramani int 1145c102e00cSSuganath Prabu Subramani mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc, 1146c102e00cSSuganath Prabu Subramani Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page, 1147c102e00cSSuganath Prabu Subramani u32 form, u32 handle) 1148c102e00cSSuganath Prabu Subramani { 1149c102e00cSSuganath Prabu Subramani Mpi2ConfigRequest_t mpi_request; 1150c102e00cSSuganath Prabu Subramani int r; 1151c102e00cSSuganath Prabu Subramani 1152c102e00cSSuganath Prabu Subramani memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1153c102e00cSSuganath Prabu Subramani mpi_request.Function = MPI2_FUNCTION_CONFIG; 1154c102e00cSSuganath Prabu Subramani mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1155c102e00cSSuganath Prabu Subramani mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1156c102e00cSSuganath Prabu Subramani mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE; 1157c102e00cSSuganath Prabu Subramani mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION; 1158c102e00cSSuganath Prabu Subramani mpi_request.Header.PageNumber = 0; 1159c102e00cSSuganath Prabu Subramani ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1160c102e00cSSuganath Prabu Subramani r = _config_request(ioc, &mpi_request, mpi_reply, 1161c102e00cSSuganath Prabu Subramani MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1162c102e00cSSuganath Prabu Subramani if (r) 1163c102e00cSSuganath Prabu Subramani goto out; 1164c102e00cSSuganath Prabu Subramani 1165c102e00cSSuganath Prabu Subramani mpi_request.PageAddress = cpu_to_le32(form | handle); 1166c102e00cSSuganath Prabu Subramani mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1167c102e00cSSuganath Prabu Subramani r = _config_request(ioc, &mpi_request, mpi_reply, 1168c102e00cSSuganath Prabu Subramani MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1169c102e00cSSuganath Prabu Subramani sizeof(*config_page)); 1170c102e00cSSuganath Prabu Subramani out: 1171c102e00cSSuganath Prabu Subramani return r; 1172c102e00cSSuganath Prabu Subramani } 1173c102e00cSSuganath Prabu Subramani 1174c102e00cSSuganath Prabu Subramani /** 1175787f2448SSuganath Prabu S * mpt3sas_config_get_pcie_iounit_pg1 - obtain pcie iounit page 1 1176787f2448SSuganath Prabu S * @ioc: per adapter object 1177787f2448SSuganath Prabu S * @mpi_reply: reply mf payload returned from firmware 1178787f2448SSuganath Prabu S * @config_page: contents of the config page 1179787f2448SSuganath Prabu S * @sz: size of buffer passed in config_page 1180787f2448SSuganath Prabu S * Context: sleep. 1181787f2448SSuganath Prabu S * 1182787f2448SSuganath Prabu S * Returns 0 for success, non-zero for failure. 1183787f2448SSuganath Prabu S */ 1184787f2448SSuganath Prabu S int 1185787f2448SSuganath Prabu S mpt3sas_config_get_pcie_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, 1186787f2448SSuganath Prabu S Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeIOUnitPage1_t *config_page, 1187787f2448SSuganath Prabu S u16 sz) 1188787f2448SSuganath Prabu S { 1189787f2448SSuganath Prabu S Mpi2ConfigRequest_t mpi_request; 1190787f2448SSuganath Prabu S int r; 1191787f2448SSuganath Prabu S 1192787f2448SSuganath Prabu S memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1193787f2448SSuganath Prabu S mpi_request.Function = MPI2_FUNCTION_CONFIG; 1194787f2448SSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1195787f2448SSuganath Prabu S mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1196787f2448SSuganath Prabu S mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT; 1197787f2448SSuganath Prabu S mpi_request.Header.PageVersion = MPI26_PCIEIOUNITPAGE1_PAGEVERSION; 1198787f2448SSuganath Prabu S mpi_request.Header.PageNumber = 1; 1199787f2448SSuganath Prabu S ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1200787f2448SSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 1201787f2448SSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1202787f2448SSuganath Prabu S if (r) 1203787f2448SSuganath Prabu S goto out; 1204787f2448SSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1205787f2448SSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 1206787f2448SSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 1207787f2448SSuganath Prabu S out: 1208787f2448SSuganath Prabu S return r; 1209787f2448SSuganath Prabu S } 1210787f2448SSuganath Prabu S 1211787f2448SSuganath Prabu S /** 1212c102e00cSSuganath Prabu Subramani * mpt3sas_config_get_pcie_device_pg2 - obtain pcie device page 2 1213c102e00cSSuganath Prabu Subramani * @ioc: per adapter object 1214c102e00cSSuganath Prabu Subramani * @mpi_reply: reply mf payload returned from firmware 1215c102e00cSSuganath Prabu Subramani * @config_page: contents of the config page 1216c102e00cSSuganath Prabu Subramani * @form: GET_NEXT_HANDLE or HANDLE 1217c102e00cSSuganath Prabu Subramani * @handle: device handle 1218c102e00cSSuganath Prabu Subramani * Context: sleep. 1219c102e00cSSuganath Prabu Subramani * 12204beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 1221c102e00cSSuganath Prabu Subramani */ 1222c102e00cSSuganath Prabu Subramani int 1223c102e00cSSuganath Prabu Subramani mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc, 1224c102e00cSSuganath Prabu Subramani Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page, 1225c102e00cSSuganath Prabu Subramani u32 form, u32 handle) 1226c102e00cSSuganath Prabu Subramani { 1227c102e00cSSuganath Prabu Subramani Mpi2ConfigRequest_t mpi_request; 1228c102e00cSSuganath Prabu Subramani int r; 1229c102e00cSSuganath Prabu Subramani 1230c102e00cSSuganath Prabu Subramani memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1231c102e00cSSuganath Prabu Subramani mpi_request.Function = MPI2_FUNCTION_CONFIG; 1232c102e00cSSuganath Prabu Subramani mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1233c102e00cSSuganath Prabu Subramani mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1234c102e00cSSuganath Prabu Subramani mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE; 1235c102e00cSSuganath Prabu Subramani mpi_request.Header.PageVersion = MPI26_PCIEDEVICE2_PAGEVERSION; 1236c102e00cSSuganath Prabu Subramani mpi_request.Header.PageNumber = 2; 1237c102e00cSSuganath Prabu Subramani ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1238c102e00cSSuganath Prabu Subramani r = _config_request(ioc, &mpi_request, mpi_reply, 1239c102e00cSSuganath Prabu Subramani MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1240c102e00cSSuganath Prabu Subramani if (r) 1241c102e00cSSuganath Prabu Subramani goto out; 1242c102e00cSSuganath Prabu Subramani 1243c102e00cSSuganath Prabu Subramani mpi_request.PageAddress = cpu_to_le32(form | handle); 1244c102e00cSSuganath Prabu Subramani mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1245c102e00cSSuganath Prabu Subramani r = _config_request(ioc, &mpi_request, mpi_reply, 1246c102e00cSSuganath Prabu Subramani MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1247c102e00cSSuganath Prabu Subramani sizeof(*config_page)); 1248c102e00cSSuganath Prabu Subramani out: 1249c102e00cSSuganath Prabu Subramani return r; 1250c102e00cSSuganath Prabu Subramani } 1251c102e00cSSuganath Prabu Subramani 1252c102e00cSSuganath Prabu Subramani /** 1253f92363d1SSreekanth Reddy * mpt3sas_config_get_number_hba_phys - obtain number of phys on the host 1254f92363d1SSreekanth Reddy * @ioc: per adapter object 1255f92363d1SSreekanth Reddy * @num_phys: pointer returned with the number of phys 1256f92363d1SSreekanth Reddy * Context: sleep. 1257f92363d1SSreekanth Reddy * 12584beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 1259f92363d1SSreekanth Reddy */ 1260f92363d1SSreekanth Reddy int 1261f92363d1SSreekanth Reddy mpt3sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER *ioc, u8 *num_phys) 1262f92363d1SSreekanth Reddy { 1263f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 1264f92363d1SSreekanth Reddy int r; 1265f92363d1SSreekanth Reddy u16 ioc_status; 1266f92363d1SSreekanth Reddy Mpi2ConfigReply_t mpi_reply; 1267f92363d1SSreekanth Reddy Mpi2SasIOUnitPage0_t config_page; 1268f92363d1SSreekanth Reddy 1269f92363d1SSreekanth Reddy *num_phys = 0; 1270f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1271f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 1272f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1273f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1274f92363d1SSreekanth Reddy mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; 1275f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 0; 1276f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION; 1277f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1278f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, &mpi_reply, 1279f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1280f92363d1SSreekanth Reddy if (r) 1281f92363d1SSreekanth Reddy goto out; 1282f92363d1SSreekanth Reddy 1283f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1284f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, &mpi_reply, 1285f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page, 1286f92363d1SSreekanth Reddy sizeof(Mpi2SasIOUnitPage0_t)); 1287f92363d1SSreekanth Reddy if (!r) { 1288f92363d1SSreekanth Reddy ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1289f92363d1SSreekanth Reddy MPI2_IOCSTATUS_MASK; 1290f92363d1SSreekanth Reddy if (ioc_status == MPI2_IOCSTATUS_SUCCESS) 1291f92363d1SSreekanth Reddy *num_phys = config_page.NumPhys; 1292f92363d1SSreekanth Reddy } 1293f92363d1SSreekanth Reddy out: 1294f92363d1SSreekanth Reddy return r; 1295f92363d1SSreekanth Reddy } 1296f92363d1SSreekanth Reddy 1297f92363d1SSreekanth Reddy /** 1298f92363d1SSreekanth Reddy * mpt3sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0 1299f92363d1SSreekanth Reddy * @ioc: per adapter object 1300f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 1301f92363d1SSreekanth Reddy * @config_page: contents of the config page 1302f92363d1SSreekanth Reddy * @sz: size of buffer passed in config_page 1303f92363d1SSreekanth Reddy * Context: sleep. 1304f92363d1SSreekanth Reddy * 1305f92363d1SSreekanth Reddy * Calling function should call config_get_number_hba_phys prior to 1306f92363d1SSreekanth Reddy * this function, so enough memory is allocated for config_page. 1307f92363d1SSreekanth Reddy * 13084beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 1309f92363d1SSreekanth Reddy */ 1310f92363d1SSreekanth Reddy int 1311f92363d1SSreekanth Reddy mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc, 1312f92363d1SSreekanth Reddy Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page, 1313f92363d1SSreekanth Reddy u16 sz) 1314f92363d1SSreekanth Reddy { 1315f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 1316f92363d1SSreekanth Reddy int r; 1317f92363d1SSreekanth Reddy 1318f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1319f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 1320f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1321f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1322f92363d1SSreekanth Reddy mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; 1323f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 0; 1324f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION; 1325f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1326f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1327f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1328f92363d1SSreekanth Reddy if (r) 1329f92363d1SSreekanth Reddy goto out; 1330f92363d1SSreekanth Reddy 1331f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1332f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1333f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 1334f92363d1SSreekanth Reddy out: 1335f92363d1SSreekanth Reddy return r; 1336f92363d1SSreekanth Reddy } 1337f92363d1SSreekanth Reddy 1338f92363d1SSreekanth Reddy /** 1339f92363d1SSreekanth Reddy * mpt3sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1 1340f92363d1SSreekanth Reddy * @ioc: per adapter object 1341f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 1342f92363d1SSreekanth Reddy * @config_page: contents of the config page 1343f92363d1SSreekanth Reddy * @sz: size of buffer passed in config_page 1344f92363d1SSreekanth Reddy * Context: sleep. 1345f92363d1SSreekanth Reddy * 1346f92363d1SSreekanth Reddy * Calling function should call config_get_number_hba_phys prior to 1347f92363d1SSreekanth Reddy * this function, so enough memory is allocated for config_page. 1348f92363d1SSreekanth Reddy * 13494beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 1350f92363d1SSreekanth Reddy */ 1351f92363d1SSreekanth Reddy int 1352f92363d1SSreekanth Reddy mpt3sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, 1353f92363d1SSreekanth Reddy Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, 1354f92363d1SSreekanth Reddy u16 sz) 1355f92363d1SSreekanth Reddy { 1356f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 1357f92363d1SSreekanth Reddy int r; 1358f92363d1SSreekanth Reddy 1359f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1360f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 1361f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1362f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1363f92363d1SSreekanth Reddy mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; 1364f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 1; 1365f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION; 1366f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1367f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1368f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1369f92363d1SSreekanth Reddy if (r) 1370f92363d1SSreekanth Reddy goto out; 1371f92363d1SSreekanth Reddy 1372f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1373f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1374f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 1375f92363d1SSreekanth Reddy out: 1376f92363d1SSreekanth Reddy return r; 1377f92363d1SSreekanth Reddy } 1378f92363d1SSreekanth Reddy 1379f92363d1SSreekanth Reddy /** 1380f92363d1SSreekanth Reddy * mpt3sas_config_set_sas_iounit_pg1 - send sas iounit page 1 1381f92363d1SSreekanth Reddy * @ioc: per adapter object 1382f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 1383f92363d1SSreekanth Reddy * @config_page: contents of the config page 1384f92363d1SSreekanth Reddy * @sz: size of buffer passed in config_page 1385f92363d1SSreekanth Reddy * Context: sleep. 1386f92363d1SSreekanth Reddy * 1387f92363d1SSreekanth Reddy * Calling function should call config_get_number_hba_phys prior to 1388f92363d1SSreekanth Reddy * this function, so enough memory is allocated for config_page. 1389f92363d1SSreekanth Reddy * 13904beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 1391f92363d1SSreekanth Reddy */ 1392f92363d1SSreekanth Reddy int 1393f92363d1SSreekanth Reddy mpt3sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, 1394f92363d1SSreekanth Reddy Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, 1395f92363d1SSreekanth Reddy u16 sz) 1396f92363d1SSreekanth Reddy { 1397f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 1398f92363d1SSreekanth Reddy int r; 1399f92363d1SSreekanth Reddy 1400f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1401f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 1402f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1403f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1404f92363d1SSreekanth Reddy mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; 1405f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 1; 1406f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION; 1407f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1408f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1409f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1410f92363d1SSreekanth Reddy if (r) 1411f92363d1SSreekanth Reddy goto out; 1412f92363d1SSreekanth Reddy 1413f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 1414f92363d1SSreekanth Reddy _config_request(ioc, &mpi_request, mpi_reply, 1415f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 1416f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 1417f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1418f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 1419f92363d1SSreekanth Reddy out: 1420f92363d1SSreekanth Reddy return r; 1421f92363d1SSreekanth Reddy } 1422f92363d1SSreekanth Reddy 1423f92363d1SSreekanth Reddy /** 1424f92363d1SSreekanth Reddy * mpt3sas_config_get_expander_pg0 - obtain expander page 0 1425f92363d1SSreekanth Reddy * @ioc: per adapter object 1426f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 1427f92363d1SSreekanth Reddy * @config_page: contents of the config page 1428f92363d1SSreekanth Reddy * @form: GET_NEXT_HANDLE or HANDLE 1429f92363d1SSreekanth Reddy * @handle: expander handle 1430f92363d1SSreekanth Reddy * Context: sleep. 1431f92363d1SSreekanth Reddy * 14324beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 1433f92363d1SSreekanth Reddy */ 1434f92363d1SSreekanth Reddy int 1435f92363d1SSreekanth Reddy mpt3sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1436f92363d1SSreekanth Reddy *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle) 1437f92363d1SSreekanth Reddy { 1438f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 1439f92363d1SSreekanth Reddy int r; 1440f92363d1SSreekanth Reddy 1441f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1442f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 1443f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1444f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1445f92363d1SSreekanth Reddy mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER; 1446f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 0; 1447f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION; 1448f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1449f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1450f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1451f92363d1SSreekanth Reddy if (r) 1452f92363d1SSreekanth Reddy goto out; 1453f92363d1SSreekanth Reddy 1454f92363d1SSreekanth Reddy mpi_request.PageAddress = cpu_to_le32(form | handle); 1455f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1456f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1457f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1458f92363d1SSreekanth Reddy sizeof(*config_page)); 1459f92363d1SSreekanth Reddy out: 1460f92363d1SSreekanth Reddy return r; 1461f92363d1SSreekanth Reddy } 1462f92363d1SSreekanth Reddy 1463f92363d1SSreekanth Reddy /** 1464f92363d1SSreekanth Reddy * mpt3sas_config_get_expander_pg1 - obtain expander page 1 1465f92363d1SSreekanth Reddy * @ioc: per adapter object 1466f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 1467f92363d1SSreekanth Reddy * @config_page: contents of the config page 1468f92363d1SSreekanth Reddy * @phy_number: phy number 1469f92363d1SSreekanth Reddy * @handle: expander handle 1470f92363d1SSreekanth Reddy * Context: sleep. 1471f92363d1SSreekanth Reddy * 14724beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 1473f92363d1SSreekanth Reddy */ 1474f92363d1SSreekanth Reddy int 1475f92363d1SSreekanth Reddy mpt3sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1476f92363d1SSreekanth Reddy *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number, 1477f92363d1SSreekanth Reddy u16 handle) 1478f92363d1SSreekanth Reddy { 1479f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 1480f92363d1SSreekanth Reddy int r; 1481f92363d1SSreekanth Reddy 1482f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1483f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 1484f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1485f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1486f92363d1SSreekanth Reddy mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER; 1487f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 1; 1488f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION; 1489f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1490f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1491f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1492f92363d1SSreekanth Reddy if (r) 1493f92363d1SSreekanth Reddy goto out; 1494f92363d1SSreekanth Reddy 1495f92363d1SSreekanth Reddy mpi_request.PageAddress = 1496f92363d1SSreekanth Reddy cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM | 1497f92363d1SSreekanth Reddy (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle); 1498f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1499f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1500f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1501f92363d1SSreekanth Reddy sizeof(*config_page)); 1502f92363d1SSreekanth Reddy out: 1503f92363d1SSreekanth Reddy return r; 1504f92363d1SSreekanth Reddy } 1505f92363d1SSreekanth Reddy 1506f92363d1SSreekanth Reddy /** 1507f92363d1SSreekanth Reddy * mpt3sas_config_get_enclosure_pg0 - obtain enclosure page 0 1508f92363d1SSreekanth Reddy * @ioc: per adapter object 1509f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 1510f92363d1SSreekanth Reddy * @config_page: contents of the config page 1511f92363d1SSreekanth Reddy * @form: GET_NEXT_HANDLE or HANDLE 1512f92363d1SSreekanth Reddy * @handle: expander handle 1513f92363d1SSreekanth Reddy * Context: sleep. 1514f92363d1SSreekanth Reddy * 15154beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 1516f92363d1SSreekanth Reddy */ 1517f92363d1SSreekanth Reddy int 1518f92363d1SSreekanth Reddy mpt3sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1519f92363d1SSreekanth Reddy *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle) 1520f92363d1SSreekanth Reddy { 1521f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 1522f92363d1SSreekanth Reddy int r; 1523f92363d1SSreekanth Reddy 1524f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1525f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 1526f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1527f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1528f92363d1SSreekanth Reddy mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE; 1529f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 0; 1530f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION; 1531f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1532f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1533f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1534f92363d1SSreekanth Reddy if (r) 1535f92363d1SSreekanth Reddy goto out; 1536f92363d1SSreekanth Reddy 1537f92363d1SSreekanth Reddy mpi_request.PageAddress = cpu_to_le32(form | handle); 1538f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1539f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1540f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1541f92363d1SSreekanth Reddy sizeof(*config_page)); 1542f92363d1SSreekanth Reddy out: 1543f92363d1SSreekanth Reddy return r; 1544f92363d1SSreekanth Reddy } 1545f92363d1SSreekanth Reddy 1546f92363d1SSreekanth Reddy /** 1547f92363d1SSreekanth Reddy * mpt3sas_config_get_phy_pg0 - obtain phy page 0 1548f92363d1SSreekanth Reddy * @ioc: per adapter object 1549f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 1550f92363d1SSreekanth Reddy * @config_page: contents of the config page 1551f92363d1SSreekanth Reddy * @phy_number: phy number 1552f92363d1SSreekanth Reddy * Context: sleep. 1553f92363d1SSreekanth Reddy * 15544beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 1555f92363d1SSreekanth Reddy */ 1556f92363d1SSreekanth Reddy int 1557f92363d1SSreekanth Reddy mpt3sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1558f92363d1SSreekanth Reddy *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number) 1559f92363d1SSreekanth Reddy { 1560f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 1561f92363d1SSreekanth Reddy int r; 1562f92363d1SSreekanth Reddy 1563f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1564f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 1565f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1566f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1567f92363d1SSreekanth Reddy mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY; 1568f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 0; 1569f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION; 1570f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1571f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1572f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1573f92363d1SSreekanth Reddy if (r) 1574f92363d1SSreekanth Reddy goto out; 1575f92363d1SSreekanth Reddy 1576f92363d1SSreekanth Reddy mpi_request.PageAddress = 1577f92363d1SSreekanth Reddy cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number); 1578f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1579f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1580f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1581f92363d1SSreekanth Reddy sizeof(*config_page)); 1582f92363d1SSreekanth Reddy out: 1583f92363d1SSreekanth Reddy return r; 1584f92363d1SSreekanth Reddy } 1585f92363d1SSreekanth Reddy 1586f92363d1SSreekanth Reddy /** 1587f92363d1SSreekanth Reddy * mpt3sas_config_get_phy_pg1 - obtain phy page 1 1588f92363d1SSreekanth Reddy * @ioc: per adapter object 1589f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 1590f92363d1SSreekanth Reddy * @config_page: contents of the config page 1591f92363d1SSreekanth Reddy * @phy_number: phy number 1592f92363d1SSreekanth Reddy * Context: sleep. 1593f92363d1SSreekanth Reddy * 15944beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 1595f92363d1SSreekanth Reddy */ 1596f92363d1SSreekanth Reddy int 1597f92363d1SSreekanth Reddy mpt3sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1598f92363d1SSreekanth Reddy *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number) 1599f92363d1SSreekanth Reddy { 1600f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 1601f92363d1SSreekanth Reddy int r; 1602f92363d1SSreekanth Reddy 1603f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1604f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 1605f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1606f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1607f92363d1SSreekanth Reddy mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY; 1608f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 1; 1609f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION; 1610f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1611f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1612f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1613f92363d1SSreekanth Reddy if (r) 1614f92363d1SSreekanth Reddy goto out; 1615f92363d1SSreekanth Reddy 1616f92363d1SSreekanth Reddy mpi_request.PageAddress = 1617f92363d1SSreekanth Reddy cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number); 1618f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1619f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1620f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1621f92363d1SSreekanth Reddy sizeof(*config_page)); 1622f92363d1SSreekanth Reddy out: 1623f92363d1SSreekanth Reddy return r; 1624f92363d1SSreekanth Reddy } 1625f92363d1SSreekanth Reddy 1626f92363d1SSreekanth Reddy /** 1627f92363d1SSreekanth Reddy * mpt3sas_config_get_raid_volume_pg1 - obtain raid volume page 1 1628f92363d1SSreekanth Reddy * @ioc: per adapter object 1629f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 1630f92363d1SSreekanth Reddy * @config_page: contents of the config page 1631f92363d1SSreekanth Reddy * @form: GET_NEXT_HANDLE or HANDLE 1632f92363d1SSreekanth Reddy * @handle: volume handle 1633f92363d1SSreekanth Reddy * Context: sleep. 1634f92363d1SSreekanth Reddy * 16354beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 1636f92363d1SSreekanth Reddy */ 1637f92363d1SSreekanth Reddy int 1638f92363d1SSreekanth Reddy mpt3sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER *ioc, 1639f92363d1SSreekanth Reddy Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form, 1640f92363d1SSreekanth Reddy u32 handle) 1641f92363d1SSreekanth Reddy { 1642f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 1643f92363d1SSreekanth Reddy int r; 1644f92363d1SSreekanth Reddy 1645f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1646f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 1647f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1648f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; 1649f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 1; 1650f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION; 1651f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1652f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1653f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1654f92363d1SSreekanth Reddy if (r) 1655f92363d1SSreekanth Reddy goto out; 1656f92363d1SSreekanth Reddy 1657f92363d1SSreekanth Reddy mpi_request.PageAddress = cpu_to_le32(form | handle); 1658f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1659f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1660f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1661f92363d1SSreekanth Reddy sizeof(*config_page)); 1662f92363d1SSreekanth Reddy out: 1663f92363d1SSreekanth Reddy return r; 1664f92363d1SSreekanth Reddy } 1665f92363d1SSreekanth Reddy 1666f92363d1SSreekanth Reddy /** 1667f92363d1SSreekanth Reddy * mpt3sas_config_get_number_pds - obtain number of phys disk assigned to volume 1668f92363d1SSreekanth Reddy * @ioc: per adapter object 1669f92363d1SSreekanth Reddy * @handle: volume handle 1670f92363d1SSreekanth Reddy * @num_pds: returns pds count 1671f92363d1SSreekanth Reddy * Context: sleep. 1672f92363d1SSreekanth Reddy * 16734beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 1674f92363d1SSreekanth Reddy */ 1675f92363d1SSreekanth Reddy int 1676f92363d1SSreekanth Reddy mpt3sas_config_get_number_pds(struct MPT3SAS_ADAPTER *ioc, u16 handle, 1677f92363d1SSreekanth Reddy u8 *num_pds) 1678f92363d1SSreekanth Reddy { 1679f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 1680f92363d1SSreekanth Reddy Mpi2RaidVolPage0_t config_page; 1681f92363d1SSreekanth Reddy Mpi2ConfigReply_t mpi_reply; 1682f92363d1SSreekanth Reddy int r; 1683f92363d1SSreekanth Reddy u16 ioc_status; 1684f92363d1SSreekanth Reddy 1685f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1686f92363d1SSreekanth Reddy *num_pds = 0; 1687f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 1688f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1689f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; 1690f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 0; 1691f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION; 1692f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1693f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, &mpi_reply, 1694f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1695f92363d1SSreekanth Reddy if (r) 1696f92363d1SSreekanth Reddy goto out; 1697f92363d1SSreekanth Reddy 1698f92363d1SSreekanth Reddy mpi_request.PageAddress = 1699f92363d1SSreekanth Reddy cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle); 1700f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1701f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, &mpi_reply, 1702f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page, 1703f92363d1SSreekanth Reddy sizeof(Mpi2RaidVolPage0_t)); 1704f92363d1SSreekanth Reddy if (!r) { 1705f92363d1SSreekanth Reddy ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1706f92363d1SSreekanth Reddy MPI2_IOCSTATUS_MASK; 1707f92363d1SSreekanth Reddy if (ioc_status == MPI2_IOCSTATUS_SUCCESS) 1708f92363d1SSreekanth Reddy *num_pds = config_page.NumPhysDisks; 1709f92363d1SSreekanth Reddy } 1710f92363d1SSreekanth Reddy 1711f92363d1SSreekanth Reddy out: 1712f92363d1SSreekanth Reddy return r; 1713f92363d1SSreekanth Reddy } 1714f92363d1SSreekanth Reddy 1715f92363d1SSreekanth Reddy /** 1716f92363d1SSreekanth Reddy * mpt3sas_config_get_raid_volume_pg0 - obtain raid volume page 0 1717f92363d1SSreekanth Reddy * @ioc: per adapter object 1718f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 1719f92363d1SSreekanth Reddy * @config_page: contents of the config page 1720f92363d1SSreekanth Reddy * @form: GET_NEXT_HANDLE or HANDLE 1721f92363d1SSreekanth Reddy * @handle: volume handle 1722f92363d1SSreekanth Reddy * @sz: size of buffer passed in config_page 1723f92363d1SSreekanth Reddy * Context: sleep. 1724f92363d1SSreekanth Reddy * 17254beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 1726f92363d1SSreekanth Reddy */ 1727f92363d1SSreekanth Reddy int 1728f92363d1SSreekanth Reddy mpt3sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER *ioc, 1729f92363d1SSreekanth Reddy Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form, 1730f92363d1SSreekanth Reddy u32 handle, u16 sz) 1731f92363d1SSreekanth Reddy { 1732f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 1733f92363d1SSreekanth Reddy int r; 1734f92363d1SSreekanth Reddy 1735f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1736f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 1737f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1738f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; 1739f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 0; 1740f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION; 1741f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1742f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1743f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1744f92363d1SSreekanth Reddy if (r) 1745f92363d1SSreekanth Reddy goto out; 1746f92363d1SSreekanth Reddy 1747f92363d1SSreekanth Reddy mpi_request.PageAddress = cpu_to_le32(form | handle); 1748f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1749f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1750f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 1751f92363d1SSreekanth Reddy out: 1752f92363d1SSreekanth Reddy return r; 1753f92363d1SSreekanth Reddy } 1754f92363d1SSreekanth Reddy 1755f92363d1SSreekanth Reddy /** 1756f92363d1SSreekanth Reddy * mpt3sas_config_get_phys_disk_pg0 - obtain phys disk page 0 1757f92363d1SSreekanth Reddy * @ioc: per adapter object 1758f92363d1SSreekanth Reddy * @mpi_reply: reply mf payload returned from firmware 1759f92363d1SSreekanth Reddy * @config_page: contents of the config page 1760f92363d1SSreekanth Reddy * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE 1761f92363d1SSreekanth Reddy * @form_specific: specific to the form 1762f92363d1SSreekanth Reddy * Context: sleep. 1763f92363d1SSreekanth Reddy * 17644beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 1765f92363d1SSreekanth Reddy */ 1766f92363d1SSreekanth Reddy int 1767f92363d1SSreekanth Reddy mpt3sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1768f92363d1SSreekanth Reddy *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form, 1769f92363d1SSreekanth Reddy u32 form_specific) 1770f92363d1SSreekanth Reddy { 1771f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 1772f92363d1SSreekanth Reddy int r; 1773f92363d1SSreekanth Reddy 1774f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1775f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 1776f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1777f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK; 1778f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 0; 1779f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION; 1780f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1781f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1782f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1783f92363d1SSreekanth Reddy if (r) 1784f92363d1SSreekanth Reddy goto out; 1785f92363d1SSreekanth Reddy 1786f92363d1SSreekanth Reddy mpi_request.PageAddress = cpu_to_le32(form | form_specific); 1787f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1788f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, mpi_reply, 1789f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1790f92363d1SSreekanth Reddy sizeof(*config_page)); 1791f92363d1SSreekanth Reddy out: 1792f92363d1SSreekanth Reddy return r; 1793f92363d1SSreekanth Reddy } 1794f92363d1SSreekanth Reddy 1795f92363d1SSreekanth Reddy /** 1796aec93e8eSSuganath Prabu S * mpt3sas_config_get_driver_trigger_pg0 - obtain driver trigger page 0 1797aec93e8eSSuganath Prabu S * @ioc: per adapter object 1798aec93e8eSSuganath Prabu S * @mpi_reply: reply mf payload returned from firmware 1799aec93e8eSSuganath Prabu S * @config_page: contents of the config page 1800aec93e8eSSuganath Prabu S * Context: sleep. 1801aec93e8eSSuganath Prabu S * 1802aec93e8eSSuganath Prabu S * Returns 0 for success, non-zero for failure. 1803aec93e8eSSuganath Prabu S */ 1804aec93e8eSSuganath Prabu S int 1805aec93e8eSSuganath Prabu S mpt3sas_config_get_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc, 1806aec93e8eSSuganath Prabu S Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page) 1807aec93e8eSSuganath Prabu S { 1808aec93e8eSSuganath Prabu S Mpi2ConfigRequest_t mpi_request; 1809aec93e8eSSuganath Prabu S int r; 1810aec93e8eSSuganath Prabu S 1811aec93e8eSSuganath Prabu S memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1812aec93e8eSSuganath Prabu S mpi_request.Function = MPI2_FUNCTION_CONFIG; 1813aec93e8eSSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1814aec93e8eSSuganath Prabu S mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1815aec93e8eSSuganath Prabu S mpi_request.ExtPageType = 1816aec93e8eSSuganath Prabu S MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 1817aec93e8eSSuganath Prabu S mpi_request.Header.PageNumber = 0; 1818aec93e8eSSuganath Prabu S mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION; 1819aec93e8eSSuganath Prabu S ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1820aec93e8eSSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 1821aec93e8eSSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1822aec93e8eSSuganath Prabu S if (r) 1823aec93e8eSSuganath Prabu S goto out; 1824aec93e8eSSuganath Prabu S 1825aec93e8eSSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1826aec93e8eSSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 1827aec93e8eSSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1828aec93e8eSSuganath Prabu S sizeof(*config_page)); 1829aec93e8eSSuganath Prabu S out: 1830aec93e8eSSuganath Prabu S return r; 1831aec93e8eSSuganath Prabu S } 1832aec93e8eSSuganath Prabu S 1833aec93e8eSSuganath Prabu S /** 1834cf9e575eSLee Jones * _config_set_driver_trigger_pg0 - write driver trigger page 0 1835aec93e8eSSuganath Prabu S * @ioc: per adapter object 1836aec93e8eSSuganath Prabu S * @mpi_reply: reply mf payload returned from firmware 1837aec93e8eSSuganath Prabu S * @config_page: contents of the config page 1838aec93e8eSSuganath Prabu S * Context: sleep. 1839aec93e8eSSuganath Prabu S * 1840aec93e8eSSuganath Prabu S * Returns 0 for success, non-zero for failure. 1841aec93e8eSSuganath Prabu S */ 1842aec93e8eSSuganath Prabu S static int 1843aec93e8eSSuganath Prabu S _config_set_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc, 1844aec93e8eSSuganath Prabu S Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page) 1845aec93e8eSSuganath Prabu S { 1846aec93e8eSSuganath Prabu S Mpi2ConfigRequest_t mpi_request; 1847aec93e8eSSuganath Prabu S int r; 1848aec93e8eSSuganath Prabu S 1849aec93e8eSSuganath Prabu S memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1850aec93e8eSSuganath Prabu S mpi_request.Function = MPI2_FUNCTION_CONFIG; 1851aec93e8eSSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1852aec93e8eSSuganath Prabu S mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1853aec93e8eSSuganath Prabu S mpi_request.ExtPageType = 1854aec93e8eSSuganath Prabu S MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 1855aec93e8eSSuganath Prabu S mpi_request.Header.PageNumber = 0; 1856aec93e8eSSuganath Prabu S mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION; 1857aec93e8eSSuganath Prabu S ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1858aec93e8eSSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 1859aec93e8eSSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1860aec93e8eSSuganath Prabu S if (r) 1861aec93e8eSSuganath Prabu S goto out; 1862aec93e8eSSuganath Prabu S 1863aec93e8eSSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 1864aec93e8eSSuganath Prabu S _config_request(ioc, &mpi_request, mpi_reply, 1865aec93e8eSSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1866aec93e8eSSuganath Prabu S sizeof(*config_page)); 1867aec93e8eSSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 1868aec93e8eSSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 1869aec93e8eSSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1870aec93e8eSSuganath Prabu S sizeof(*config_page)); 1871aec93e8eSSuganath Prabu S out: 1872aec93e8eSSuganath Prabu S return r; 1873aec93e8eSSuganath Prabu S } 1874aec93e8eSSuganath Prabu S 1875aec93e8eSSuganath Prabu S /** 1876aec93e8eSSuganath Prabu S * mpt3sas_config_update_driver_trigger_pg0 - update driver trigger page 0 1877aec93e8eSSuganath Prabu S * @ioc: per adapter object 1878aec93e8eSSuganath Prabu S * @trigger_flag: trigger type bit map 1879aec93e8eSSuganath Prabu S * @set: set ot clear trigger values 1880aec93e8eSSuganath Prabu S * Context: sleep. 1881aec93e8eSSuganath Prabu S * 1882aec93e8eSSuganath Prabu S * Returns 0 for success, non-zero for failure. 1883aec93e8eSSuganath Prabu S */ 1884aec93e8eSSuganath Prabu S static int 1885aec93e8eSSuganath Prabu S mpt3sas_config_update_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc, 1886aec93e8eSSuganath Prabu S u16 trigger_flag, bool set) 1887aec93e8eSSuganath Prabu S { 1888aec93e8eSSuganath Prabu S Mpi26DriverTriggerPage0_t tg_pg0; 1889aec93e8eSSuganath Prabu S Mpi2ConfigReply_t mpi_reply; 1890aec93e8eSSuganath Prabu S int rc; 1891aec93e8eSSuganath Prabu S u16 flags, ioc_status; 1892aec93e8eSSuganath Prabu S 1893aec93e8eSSuganath Prabu S rc = mpt3sas_config_get_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0); 1894aec93e8eSSuganath Prabu S if (rc) 1895aec93e8eSSuganath Prabu S return rc; 1896aec93e8eSSuganath Prabu S ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1897aec93e8eSSuganath Prabu S MPI2_IOCSTATUS_MASK; 1898aec93e8eSSuganath Prabu S if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 1899aec93e8eSSuganath Prabu S dcprintk(ioc, 1900aec93e8eSSuganath Prabu S ioc_err(ioc, 1901aec93e8eSSuganath Prabu S "%s: Failed to get trigger pg0, ioc_status(0x%04x)\n", 1902aec93e8eSSuganath Prabu S __func__, ioc_status)); 1903aec93e8eSSuganath Prabu S return -EFAULT; 1904aec93e8eSSuganath Prabu S } 1905aec93e8eSSuganath Prabu S 1906aec93e8eSSuganath Prabu S if (set) 1907aec93e8eSSuganath Prabu S flags = le16_to_cpu(tg_pg0.TriggerFlags) | trigger_flag; 1908aec93e8eSSuganath Prabu S else 1909aec93e8eSSuganath Prabu S flags = le16_to_cpu(tg_pg0.TriggerFlags) & ~trigger_flag; 1910aec93e8eSSuganath Prabu S 1911aec93e8eSSuganath Prabu S tg_pg0.TriggerFlags = cpu_to_le16(flags); 1912aec93e8eSSuganath Prabu S 1913aec93e8eSSuganath Prabu S rc = _config_set_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0); 1914aec93e8eSSuganath Prabu S if (rc) 1915aec93e8eSSuganath Prabu S return rc; 1916aec93e8eSSuganath Prabu S ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1917aec93e8eSSuganath Prabu S MPI2_IOCSTATUS_MASK; 1918aec93e8eSSuganath Prabu S if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 1919aec93e8eSSuganath Prabu S dcprintk(ioc, 1920aec93e8eSSuganath Prabu S ioc_err(ioc, 1921aec93e8eSSuganath Prabu S "%s: Failed to update trigger pg0, ioc_status(0x%04x)\n", 1922aec93e8eSSuganath Prabu S __func__, ioc_status)); 1923aec93e8eSSuganath Prabu S return -EFAULT; 1924aec93e8eSSuganath Prabu S } 1925aec93e8eSSuganath Prabu S 1926aec93e8eSSuganath Prabu S return 0; 1927aec93e8eSSuganath Prabu S } 1928aec93e8eSSuganath Prabu S 1929aec93e8eSSuganath Prabu S /** 1930bb855f2aSSuganath Prabu S * mpt3sas_config_get_driver_trigger_pg1 - obtain driver trigger page 1 1931bb855f2aSSuganath Prabu S * @ioc: per adapter object 1932bb855f2aSSuganath Prabu S * @mpi_reply: reply mf payload returned from firmware 1933bb855f2aSSuganath Prabu S * @config_page: contents of the config page 1934bb855f2aSSuganath Prabu S * Context: sleep. 1935bb855f2aSSuganath Prabu S * 1936bb855f2aSSuganath Prabu S * Returns 0 for success, non-zero for failure. 1937bb855f2aSSuganath Prabu S */ 1938bb855f2aSSuganath Prabu S int 1939bb855f2aSSuganath Prabu S mpt3sas_config_get_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc, 1940bb855f2aSSuganath Prabu S Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page) 1941bb855f2aSSuganath Prabu S { 1942bb855f2aSSuganath Prabu S Mpi2ConfigRequest_t mpi_request; 1943bb855f2aSSuganath Prabu S int r; 1944bb855f2aSSuganath Prabu S 1945bb855f2aSSuganath Prabu S memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1946bb855f2aSSuganath Prabu S mpi_request.Function = MPI2_FUNCTION_CONFIG; 1947bb855f2aSSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1948bb855f2aSSuganath Prabu S mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1949bb855f2aSSuganath Prabu S mpi_request.ExtPageType = 1950bb855f2aSSuganath Prabu S MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 1951bb855f2aSSuganath Prabu S mpi_request.Header.PageNumber = 1; 1952bb855f2aSSuganath Prabu S mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION; 1953bb855f2aSSuganath Prabu S ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1954bb855f2aSSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 1955bb855f2aSSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1956bb855f2aSSuganath Prabu S if (r) 1957bb855f2aSSuganath Prabu S goto out; 1958bb855f2aSSuganath Prabu S 1959bb855f2aSSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1960bb855f2aSSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 1961bb855f2aSSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1962bb855f2aSSuganath Prabu S sizeof(*config_page)); 1963bb855f2aSSuganath Prabu S out: 1964bb855f2aSSuganath Prabu S return r; 1965bb855f2aSSuganath Prabu S } 1966bb855f2aSSuganath Prabu S 1967bb855f2aSSuganath Prabu S /** 1968cf9e575eSLee Jones * _config_set_driver_trigger_pg1 - write driver trigger page 1 1969bb855f2aSSuganath Prabu S * @ioc: per adapter object 1970bb855f2aSSuganath Prabu S * @mpi_reply: reply mf payload returned from firmware 1971bb855f2aSSuganath Prabu S * @config_page: contents of the config page 1972bb855f2aSSuganath Prabu S * Context: sleep. 1973bb855f2aSSuganath Prabu S * 1974bb855f2aSSuganath Prabu S * Returns 0 for success, non-zero for failure. 1975bb855f2aSSuganath Prabu S */ 1976bb855f2aSSuganath Prabu S static int 1977bb855f2aSSuganath Prabu S _config_set_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc, 1978bb855f2aSSuganath Prabu S Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page) 1979bb855f2aSSuganath Prabu S { 1980bb855f2aSSuganath Prabu S Mpi2ConfigRequest_t mpi_request; 1981bb855f2aSSuganath Prabu S int r; 1982bb855f2aSSuganath Prabu S 1983bb855f2aSSuganath Prabu S memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1984bb855f2aSSuganath Prabu S mpi_request.Function = MPI2_FUNCTION_CONFIG; 1985bb855f2aSSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1986bb855f2aSSuganath Prabu S mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1987bb855f2aSSuganath Prabu S mpi_request.ExtPageType = 1988bb855f2aSSuganath Prabu S MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 1989bb855f2aSSuganath Prabu S mpi_request.Header.PageNumber = 1; 1990bb855f2aSSuganath Prabu S mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION; 1991bb855f2aSSuganath Prabu S ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1992bb855f2aSSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 1993bb855f2aSSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1994bb855f2aSSuganath Prabu S if (r) 1995bb855f2aSSuganath Prabu S goto out; 1996bb855f2aSSuganath Prabu S 1997bb855f2aSSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 1998bb855f2aSSuganath Prabu S _config_request(ioc, &mpi_request, mpi_reply, 1999bb855f2aSSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2000bb855f2aSSuganath Prabu S sizeof(*config_page)); 2001bb855f2aSSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 2002bb855f2aSSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 2003bb855f2aSSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2004bb855f2aSSuganath Prabu S sizeof(*config_page)); 2005bb855f2aSSuganath Prabu S out: 2006bb855f2aSSuganath Prabu S return r; 2007bb855f2aSSuganath Prabu S } 2008bb855f2aSSuganath Prabu S 2009bb855f2aSSuganath Prabu S /** 2010bb855f2aSSuganath Prabu S * mpt3sas_config_update_driver_trigger_pg1 - update driver trigger page 1 2011bb855f2aSSuganath Prabu S * @ioc: per adapter object 2012bb855f2aSSuganath Prabu S * @master_tg: Master trigger bit map 2013bb855f2aSSuganath Prabu S * @set: set ot clear trigger values 2014bb855f2aSSuganath Prabu S * Context: sleep. 2015bb855f2aSSuganath Prabu S * 2016bb855f2aSSuganath Prabu S * Returns 0 for success, non-zero for failure. 2017bb855f2aSSuganath Prabu S */ 2018bb855f2aSSuganath Prabu S int 2019bb855f2aSSuganath Prabu S mpt3sas_config_update_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc, 2020bb855f2aSSuganath Prabu S struct SL_WH_MASTER_TRIGGER_T *master_tg, bool set) 2021bb855f2aSSuganath Prabu S { 2022bb855f2aSSuganath Prabu S Mpi26DriverTriggerPage1_t tg_pg1; 2023bb855f2aSSuganath Prabu S Mpi2ConfigReply_t mpi_reply; 2024bb855f2aSSuganath Prabu S int rc; 2025bb855f2aSSuganath Prabu S u16 ioc_status; 2026bb855f2aSSuganath Prabu S 2027bb855f2aSSuganath Prabu S rc = mpt3sas_config_update_driver_trigger_pg0(ioc, 2028bb855f2aSSuganath Prabu S MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, set); 2029bb855f2aSSuganath Prabu S if (rc) 2030bb855f2aSSuganath Prabu S return rc; 2031bb855f2aSSuganath Prabu S 2032bb855f2aSSuganath Prabu S rc = mpt3sas_config_get_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1); 2033bb855f2aSSuganath Prabu S if (rc) 2034bb855f2aSSuganath Prabu S goto out; 2035bb855f2aSSuganath Prabu S 2036bb855f2aSSuganath Prabu S ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2037bb855f2aSSuganath Prabu S MPI2_IOCSTATUS_MASK; 2038bb855f2aSSuganath Prabu S if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2039bb855f2aSSuganath Prabu S dcprintk(ioc, 2040bb855f2aSSuganath Prabu S ioc_err(ioc, 2041bb855f2aSSuganath Prabu S "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n", 2042bb855f2aSSuganath Prabu S __func__, ioc_status)); 2043bb855f2aSSuganath Prabu S rc = -EFAULT; 2044bb855f2aSSuganath Prabu S goto out; 2045bb855f2aSSuganath Prabu S } 2046bb855f2aSSuganath Prabu S 2047bb855f2aSSuganath Prabu S if (set) { 2048bb855f2aSSuganath Prabu S tg_pg1.NumMasterTrigger = cpu_to_le16(1); 2049bb855f2aSSuganath Prabu S tg_pg1.MasterTriggers[0].MasterTriggerFlags = cpu_to_le32( 2050bb855f2aSSuganath Prabu S master_tg->MasterData); 2051bb855f2aSSuganath Prabu S } else { 2052bb855f2aSSuganath Prabu S tg_pg1.NumMasterTrigger = 0; 2053bb855f2aSSuganath Prabu S tg_pg1.MasterTriggers[0].MasterTriggerFlags = 0; 2054bb855f2aSSuganath Prabu S } 2055bb855f2aSSuganath Prabu S 2056bb855f2aSSuganath Prabu S rc = _config_set_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1); 2057bb855f2aSSuganath Prabu S if (rc) 2058bb855f2aSSuganath Prabu S goto out; 2059bb855f2aSSuganath Prabu S 2060bb855f2aSSuganath Prabu S ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2061bb855f2aSSuganath Prabu S MPI2_IOCSTATUS_MASK; 2062bb855f2aSSuganath Prabu S if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2063bb855f2aSSuganath Prabu S dcprintk(ioc, 2064bb855f2aSSuganath Prabu S ioc_err(ioc, 2065bb855f2aSSuganath Prabu S "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n", 2066bb855f2aSSuganath Prabu S __func__, ioc_status)); 2067bb855f2aSSuganath Prabu S rc = -EFAULT; 2068bb855f2aSSuganath Prabu S goto out; 2069bb855f2aSSuganath Prabu S } 2070bb855f2aSSuganath Prabu S 2071bb855f2aSSuganath Prabu S return 0; 2072bb855f2aSSuganath Prabu S 2073bb855f2aSSuganath Prabu S out: 2074bb855f2aSSuganath Prabu S mpt3sas_config_update_driver_trigger_pg0(ioc, 2075bb855f2aSSuganath Prabu S MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, !set); 2076bb855f2aSSuganath Prabu S 2077bb855f2aSSuganath Prabu S return rc; 2078bb855f2aSSuganath Prabu S } 2079bb855f2aSSuganath Prabu S 2080bb855f2aSSuganath Prabu S /** 208171b3fb8fSSuganath Prabu S * mpt3sas_config_get_driver_trigger_pg2 - obtain driver trigger page 2 208271b3fb8fSSuganath Prabu S * @ioc: per adapter object 208371b3fb8fSSuganath Prabu S * @mpi_reply: reply mf payload returned from firmware 208471b3fb8fSSuganath Prabu S * @config_page: contents of the config page 208571b3fb8fSSuganath Prabu S * Context: sleep. 208671b3fb8fSSuganath Prabu S * 208771b3fb8fSSuganath Prabu S * Returns 0 for success, non-zero for failure. 208871b3fb8fSSuganath Prabu S */ 208971b3fb8fSSuganath Prabu S int 209071b3fb8fSSuganath Prabu S mpt3sas_config_get_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc, 209171b3fb8fSSuganath Prabu S Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page) 209271b3fb8fSSuganath Prabu S { 209371b3fb8fSSuganath Prabu S Mpi2ConfigRequest_t mpi_request; 209471b3fb8fSSuganath Prabu S int r; 209571b3fb8fSSuganath Prabu S 209671b3fb8fSSuganath Prabu S memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 209771b3fb8fSSuganath Prabu S mpi_request.Function = MPI2_FUNCTION_CONFIG; 209871b3fb8fSSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 209971b3fb8fSSuganath Prabu S mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 210071b3fb8fSSuganath Prabu S mpi_request.ExtPageType = 210171b3fb8fSSuganath Prabu S MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 210271b3fb8fSSuganath Prabu S mpi_request.Header.PageNumber = 2; 210371b3fb8fSSuganath Prabu S mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION; 210471b3fb8fSSuganath Prabu S ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 210571b3fb8fSSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 210671b3fb8fSSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 210771b3fb8fSSuganath Prabu S if (r) 210871b3fb8fSSuganath Prabu S goto out; 210971b3fb8fSSuganath Prabu S 211071b3fb8fSSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 211171b3fb8fSSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 211271b3fb8fSSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 211371b3fb8fSSuganath Prabu S sizeof(*config_page)); 211471b3fb8fSSuganath Prabu S out: 211571b3fb8fSSuganath Prabu S return r; 211671b3fb8fSSuganath Prabu S } 211771b3fb8fSSuganath Prabu S 211871b3fb8fSSuganath Prabu S /** 2119cf9e575eSLee Jones * _config_set_driver_trigger_pg2 - write driver trigger page 2 212071b3fb8fSSuganath Prabu S * @ioc: per adapter object 212171b3fb8fSSuganath Prabu S * @mpi_reply: reply mf payload returned from firmware 212271b3fb8fSSuganath Prabu S * @config_page: contents of the config page 212371b3fb8fSSuganath Prabu S * Context: sleep. 212471b3fb8fSSuganath Prabu S * 212571b3fb8fSSuganath Prabu S * Returns 0 for success, non-zero for failure. 212671b3fb8fSSuganath Prabu S */ 212771b3fb8fSSuganath Prabu S static int 212871b3fb8fSSuganath Prabu S _config_set_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc, 212971b3fb8fSSuganath Prabu S Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page) 213071b3fb8fSSuganath Prabu S { 213171b3fb8fSSuganath Prabu S Mpi2ConfigRequest_t mpi_request; 213271b3fb8fSSuganath Prabu S int r; 213371b3fb8fSSuganath Prabu S 213471b3fb8fSSuganath Prabu S memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 213571b3fb8fSSuganath Prabu S mpi_request.Function = MPI2_FUNCTION_CONFIG; 213671b3fb8fSSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 213771b3fb8fSSuganath Prabu S mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 213871b3fb8fSSuganath Prabu S mpi_request.ExtPageType = 213971b3fb8fSSuganath Prabu S MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 214071b3fb8fSSuganath Prabu S mpi_request.Header.PageNumber = 2; 214171b3fb8fSSuganath Prabu S mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION; 214271b3fb8fSSuganath Prabu S ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 214371b3fb8fSSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 214471b3fb8fSSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 214571b3fb8fSSuganath Prabu S if (r) 214671b3fb8fSSuganath Prabu S goto out; 214771b3fb8fSSuganath Prabu S 214871b3fb8fSSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 214971b3fb8fSSuganath Prabu S _config_request(ioc, &mpi_request, mpi_reply, 215071b3fb8fSSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 215171b3fb8fSSuganath Prabu S sizeof(*config_page)); 215271b3fb8fSSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 215371b3fb8fSSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 215471b3fb8fSSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 215571b3fb8fSSuganath Prabu S sizeof(*config_page)); 215671b3fb8fSSuganath Prabu S out: 215771b3fb8fSSuganath Prabu S return r; 215871b3fb8fSSuganath Prabu S } 215971b3fb8fSSuganath Prabu S 216071b3fb8fSSuganath Prabu S /** 216171b3fb8fSSuganath Prabu S * mpt3sas_config_update_driver_trigger_pg2 - update driver trigger page 2 216271b3fb8fSSuganath Prabu S * @ioc: per adapter object 216371b3fb8fSSuganath Prabu S * @event_tg: list of Event Triggers 216471b3fb8fSSuganath Prabu S * @set: set ot clear trigger values 216571b3fb8fSSuganath Prabu S * Context: sleep. 216671b3fb8fSSuganath Prabu S * 216771b3fb8fSSuganath Prabu S * Returns 0 for success, non-zero for failure. 216871b3fb8fSSuganath Prabu S */ 216971b3fb8fSSuganath Prabu S int 217071b3fb8fSSuganath Prabu S mpt3sas_config_update_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc, 217171b3fb8fSSuganath Prabu S struct SL_WH_EVENT_TRIGGERS_T *event_tg, bool set) 217271b3fb8fSSuganath Prabu S { 217371b3fb8fSSuganath Prabu S Mpi26DriverTriggerPage2_t tg_pg2; 217471b3fb8fSSuganath Prabu S Mpi2ConfigReply_t mpi_reply; 217571b3fb8fSSuganath Prabu S int rc, i, count; 217671b3fb8fSSuganath Prabu S u16 ioc_status; 217771b3fb8fSSuganath Prabu S 217871b3fb8fSSuganath Prabu S rc = mpt3sas_config_update_driver_trigger_pg0(ioc, 217971b3fb8fSSuganath Prabu S MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, set); 218071b3fb8fSSuganath Prabu S if (rc) 218171b3fb8fSSuganath Prabu S return rc; 218271b3fb8fSSuganath Prabu S 218371b3fb8fSSuganath Prabu S rc = mpt3sas_config_get_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2); 218471b3fb8fSSuganath Prabu S if (rc) 218571b3fb8fSSuganath Prabu S goto out; 218671b3fb8fSSuganath Prabu S 218771b3fb8fSSuganath Prabu S ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 218871b3fb8fSSuganath Prabu S MPI2_IOCSTATUS_MASK; 218971b3fb8fSSuganath Prabu S if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 219071b3fb8fSSuganath Prabu S dcprintk(ioc, 219171b3fb8fSSuganath Prabu S ioc_err(ioc, 219271b3fb8fSSuganath Prabu S "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n", 219371b3fb8fSSuganath Prabu S __func__, ioc_status)); 219471b3fb8fSSuganath Prabu S rc = -EFAULT; 219571b3fb8fSSuganath Prabu S goto out; 219671b3fb8fSSuganath Prabu S } 219771b3fb8fSSuganath Prabu S 219871b3fb8fSSuganath Prabu S if (set) { 219971b3fb8fSSuganath Prabu S count = event_tg->ValidEntries; 220071b3fb8fSSuganath Prabu S tg_pg2.NumMPIEventTrigger = cpu_to_le16(count); 220171b3fb8fSSuganath Prabu S for (i = 0; i < count; i++) { 220271b3fb8fSSuganath Prabu S tg_pg2.MPIEventTriggers[i].MPIEventCode = 220371b3fb8fSSuganath Prabu S cpu_to_le16( 220471b3fb8fSSuganath Prabu S event_tg->EventTriggerEntry[i].EventValue); 220571b3fb8fSSuganath Prabu S tg_pg2.MPIEventTriggers[i].MPIEventCodeSpecific = 220671b3fb8fSSuganath Prabu S cpu_to_le16( 220771b3fb8fSSuganath Prabu S event_tg->EventTriggerEntry[i].LogEntryQualifier); 220871b3fb8fSSuganath Prabu S } 220971b3fb8fSSuganath Prabu S } else { 221071b3fb8fSSuganath Prabu S tg_pg2.NumMPIEventTrigger = 0; 221171b3fb8fSSuganath Prabu S memset(&tg_pg2.MPIEventTriggers[0], 0, 221271b3fb8fSSuganath Prabu S NUM_VALID_ENTRIES * sizeof( 221371b3fb8fSSuganath Prabu S MPI26_DRIVER_MPI_EVENT_TIGGER_ENTRY)); 221471b3fb8fSSuganath Prabu S } 221571b3fb8fSSuganath Prabu S 221671b3fb8fSSuganath Prabu S rc = _config_set_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2); 221771b3fb8fSSuganath Prabu S if (rc) 221871b3fb8fSSuganath Prabu S goto out; 221971b3fb8fSSuganath Prabu S 222071b3fb8fSSuganath Prabu S ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 222171b3fb8fSSuganath Prabu S MPI2_IOCSTATUS_MASK; 222271b3fb8fSSuganath Prabu S if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 222371b3fb8fSSuganath Prabu S dcprintk(ioc, 222471b3fb8fSSuganath Prabu S ioc_err(ioc, 222571b3fb8fSSuganath Prabu S "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n", 222671b3fb8fSSuganath Prabu S __func__, ioc_status)); 222771b3fb8fSSuganath Prabu S rc = -EFAULT; 222871b3fb8fSSuganath Prabu S goto out; 222971b3fb8fSSuganath Prabu S } 223071b3fb8fSSuganath Prabu S 223171b3fb8fSSuganath Prabu S return 0; 223271b3fb8fSSuganath Prabu S 223371b3fb8fSSuganath Prabu S out: 223471b3fb8fSSuganath Prabu S mpt3sas_config_update_driver_trigger_pg0(ioc, 223571b3fb8fSSuganath Prabu S MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, !set); 223671b3fb8fSSuganath Prabu S 223771b3fb8fSSuganath Prabu S return rc; 223871b3fb8fSSuganath Prabu S } 223971b3fb8fSSuganath Prabu S 224071b3fb8fSSuganath Prabu S /** 22412a5c3a35SSuganath Prabu S * mpt3sas_config_get_driver_trigger_pg3 - obtain driver trigger page 3 22422a5c3a35SSuganath Prabu S * @ioc: per adapter object 22432a5c3a35SSuganath Prabu S * @mpi_reply: reply mf payload returned from firmware 22442a5c3a35SSuganath Prabu S * @config_page: contents of the config page 22452a5c3a35SSuganath Prabu S * Context: sleep. 22462a5c3a35SSuganath Prabu S * 22472a5c3a35SSuganath Prabu S * Returns 0 for success, non-zero for failure. 22482a5c3a35SSuganath Prabu S */ 22492a5c3a35SSuganath Prabu S int 22502a5c3a35SSuganath Prabu S mpt3sas_config_get_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc, 22512a5c3a35SSuganath Prabu S Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page) 22522a5c3a35SSuganath Prabu S { 22532a5c3a35SSuganath Prabu S Mpi2ConfigRequest_t mpi_request; 22542a5c3a35SSuganath Prabu S int r; 22552a5c3a35SSuganath Prabu S 22562a5c3a35SSuganath Prabu S memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 22572a5c3a35SSuganath Prabu S mpi_request.Function = MPI2_FUNCTION_CONFIG; 22582a5c3a35SSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 22592a5c3a35SSuganath Prabu S mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 22602a5c3a35SSuganath Prabu S mpi_request.ExtPageType = 22612a5c3a35SSuganath Prabu S MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 22622a5c3a35SSuganath Prabu S mpi_request.Header.PageNumber = 3; 22632a5c3a35SSuganath Prabu S mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION; 22642a5c3a35SSuganath Prabu S ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 22652a5c3a35SSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 22662a5c3a35SSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 22672a5c3a35SSuganath Prabu S if (r) 22682a5c3a35SSuganath Prabu S goto out; 22692a5c3a35SSuganath Prabu S 22702a5c3a35SSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 22712a5c3a35SSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 22722a5c3a35SSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 22732a5c3a35SSuganath Prabu S sizeof(*config_page)); 22742a5c3a35SSuganath Prabu S out: 22752a5c3a35SSuganath Prabu S return r; 22762a5c3a35SSuganath Prabu S } 22772a5c3a35SSuganath Prabu S 22782a5c3a35SSuganath Prabu S /** 2279cf9e575eSLee Jones * _config_set_driver_trigger_pg3 - write driver trigger page 3 22802a5c3a35SSuganath Prabu S * @ioc: per adapter object 22812a5c3a35SSuganath Prabu S * @mpi_reply: reply mf payload returned from firmware 22822a5c3a35SSuganath Prabu S * @config_page: contents of the config page 22832a5c3a35SSuganath Prabu S * Context: sleep. 22842a5c3a35SSuganath Prabu S * 22852a5c3a35SSuganath Prabu S * Returns 0 for success, non-zero for failure. 22862a5c3a35SSuganath Prabu S */ 22872a5c3a35SSuganath Prabu S static int 22882a5c3a35SSuganath Prabu S _config_set_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc, 22892a5c3a35SSuganath Prabu S Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page) 22902a5c3a35SSuganath Prabu S { 22912a5c3a35SSuganath Prabu S Mpi2ConfigRequest_t mpi_request; 22922a5c3a35SSuganath Prabu S int r; 22932a5c3a35SSuganath Prabu S 22942a5c3a35SSuganath Prabu S memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 22952a5c3a35SSuganath Prabu S mpi_request.Function = MPI2_FUNCTION_CONFIG; 22962a5c3a35SSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 22972a5c3a35SSuganath Prabu S mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 22982a5c3a35SSuganath Prabu S mpi_request.ExtPageType = 22992a5c3a35SSuganath Prabu S MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 23002a5c3a35SSuganath Prabu S mpi_request.Header.PageNumber = 3; 23012a5c3a35SSuganath Prabu S mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION; 23022a5c3a35SSuganath Prabu S ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 23032a5c3a35SSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 23042a5c3a35SSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 23052a5c3a35SSuganath Prabu S if (r) 23062a5c3a35SSuganath Prabu S goto out; 23072a5c3a35SSuganath Prabu S 23082a5c3a35SSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 23092a5c3a35SSuganath Prabu S _config_request(ioc, &mpi_request, mpi_reply, 23102a5c3a35SSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 23112a5c3a35SSuganath Prabu S sizeof(*config_page)); 23122a5c3a35SSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 23132a5c3a35SSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 23142a5c3a35SSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 23152a5c3a35SSuganath Prabu S sizeof(*config_page)); 23162a5c3a35SSuganath Prabu S out: 23172a5c3a35SSuganath Prabu S return r; 23182a5c3a35SSuganath Prabu S } 23192a5c3a35SSuganath Prabu S 23202a5c3a35SSuganath Prabu S /** 23212a5c3a35SSuganath Prabu S * mpt3sas_config_update_driver_trigger_pg3 - update driver trigger page 3 23222a5c3a35SSuganath Prabu S * @ioc: per adapter object 23232a5c3a35SSuganath Prabu S * @scsi_tg: scsi trigger list 23242a5c3a35SSuganath Prabu S * @set: set ot clear trigger values 23252a5c3a35SSuganath Prabu S * Context: sleep. 23262a5c3a35SSuganath Prabu S * 23272a5c3a35SSuganath Prabu S * Returns 0 for success, non-zero for failure. 23282a5c3a35SSuganath Prabu S */ 23292a5c3a35SSuganath Prabu S int 23302a5c3a35SSuganath Prabu S mpt3sas_config_update_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc, 23312a5c3a35SSuganath Prabu S struct SL_WH_SCSI_TRIGGERS_T *scsi_tg, bool set) 23322a5c3a35SSuganath Prabu S { 23332a5c3a35SSuganath Prabu S Mpi26DriverTriggerPage3_t tg_pg3; 23342a5c3a35SSuganath Prabu S Mpi2ConfigReply_t mpi_reply; 23352a5c3a35SSuganath Prabu S int rc, i, count; 23362a5c3a35SSuganath Prabu S u16 ioc_status; 23372a5c3a35SSuganath Prabu S 23382a5c3a35SSuganath Prabu S rc = mpt3sas_config_update_driver_trigger_pg0(ioc, 23392a5c3a35SSuganath Prabu S MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, set); 23402a5c3a35SSuganath Prabu S if (rc) 23412a5c3a35SSuganath Prabu S return rc; 23422a5c3a35SSuganath Prabu S 23432a5c3a35SSuganath Prabu S rc = mpt3sas_config_get_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3); 23442a5c3a35SSuganath Prabu S if (rc) 23452a5c3a35SSuganath Prabu S goto out; 23462a5c3a35SSuganath Prabu S 23472a5c3a35SSuganath Prabu S ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 23482a5c3a35SSuganath Prabu S MPI2_IOCSTATUS_MASK; 23492a5c3a35SSuganath Prabu S if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 23502a5c3a35SSuganath Prabu S dcprintk(ioc, 23512a5c3a35SSuganath Prabu S ioc_err(ioc, 23522a5c3a35SSuganath Prabu S "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n", 23532a5c3a35SSuganath Prabu S __func__, ioc_status)); 23542a5c3a35SSuganath Prabu S return -EFAULT; 23552a5c3a35SSuganath Prabu S } 23562a5c3a35SSuganath Prabu S 23572a5c3a35SSuganath Prabu S if (set) { 23582a5c3a35SSuganath Prabu S count = scsi_tg->ValidEntries; 23592a5c3a35SSuganath Prabu S tg_pg3.NumSCSISenseTrigger = cpu_to_le16(count); 23602a5c3a35SSuganath Prabu S for (i = 0; i < count; i++) { 23612a5c3a35SSuganath Prabu S tg_pg3.SCSISenseTriggers[i].ASCQ = 23622a5c3a35SSuganath Prabu S scsi_tg->SCSITriggerEntry[i].ASCQ; 23632a5c3a35SSuganath Prabu S tg_pg3.SCSISenseTriggers[i].ASC = 23642a5c3a35SSuganath Prabu S scsi_tg->SCSITriggerEntry[i].ASC; 23652a5c3a35SSuganath Prabu S tg_pg3.SCSISenseTriggers[i].SenseKey = 23662a5c3a35SSuganath Prabu S scsi_tg->SCSITriggerEntry[i].SenseKey; 23672a5c3a35SSuganath Prabu S } 23682a5c3a35SSuganath Prabu S } else { 23692a5c3a35SSuganath Prabu S tg_pg3.NumSCSISenseTrigger = 0; 23702a5c3a35SSuganath Prabu S memset(&tg_pg3.SCSISenseTriggers[0], 0, 23712a5c3a35SSuganath Prabu S NUM_VALID_ENTRIES * sizeof( 23722a5c3a35SSuganath Prabu S MPI26_DRIVER_SCSI_SENSE_TIGGER_ENTRY)); 23732a5c3a35SSuganath Prabu S } 23742a5c3a35SSuganath Prabu S 23752a5c3a35SSuganath Prabu S rc = _config_set_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3); 23762a5c3a35SSuganath Prabu S if (rc) 23772a5c3a35SSuganath Prabu S goto out; 23782a5c3a35SSuganath Prabu S 23792a5c3a35SSuganath Prabu S ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 23802a5c3a35SSuganath Prabu S MPI2_IOCSTATUS_MASK; 23812a5c3a35SSuganath Prabu S if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 23822a5c3a35SSuganath Prabu S dcprintk(ioc, 23832a5c3a35SSuganath Prabu S ioc_err(ioc, 23842a5c3a35SSuganath Prabu S "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n", 23852a5c3a35SSuganath Prabu S __func__, ioc_status)); 23862a5c3a35SSuganath Prabu S return -EFAULT; 23872a5c3a35SSuganath Prabu S } 23882a5c3a35SSuganath Prabu S 23892a5c3a35SSuganath Prabu S return 0; 23902a5c3a35SSuganath Prabu S out: 23912a5c3a35SSuganath Prabu S mpt3sas_config_update_driver_trigger_pg0(ioc, 23922a5c3a35SSuganath Prabu S MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, !set); 23932a5c3a35SSuganath Prabu S 23942a5c3a35SSuganath Prabu S return rc; 23952a5c3a35SSuganath Prabu S } 23962a5c3a35SSuganath Prabu S 23972a5c3a35SSuganath Prabu S /** 23980e17a87cSSuganath Prabu S * mpt3sas_config_get_driver_trigger_pg4 - obtain driver trigger page 4 23990e17a87cSSuganath Prabu S * @ioc: per adapter object 24000e17a87cSSuganath Prabu S * @mpi_reply: reply mf payload returned from firmware 24010e17a87cSSuganath Prabu S * @config_page: contents of the config page 24020e17a87cSSuganath Prabu S * Context: sleep. 24030e17a87cSSuganath Prabu S * 24040e17a87cSSuganath Prabu S * Returns 0 for success, non-zero for failure. 24050e17a87cSSuganath Prabu S */ 24060e17a87cSSuganath Prabu S int 24070e17a87cSSuganath Prabu S mpt3sas_config_get_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc, 24080e17a87cSSuganath Prabu S Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page) 24090e17a87cSSuganath Prabu S { 24100e17a87cSSuganath Prabu S Mpi2ConfigRequest_t mpi_request; 24110e17a87cSSuganath Prabu S int r; 24120e17a87cSSuganath Prabu S 24130e17a87cSSuganath Prabu S memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 24140e17a87cSSuganath Prabu S mpi_request.Function = MPI2_FUNCTION_CONFIG; 24150e17a87cSSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 24160e17a87cSSuganath Prabu S mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 24170e17a87cSSuganath Prabu S mpi_request.ExtPageType = 24180e17a87cSSuganath Prabu S MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 24190e17a87cSSuganath Prabu S mpi_request.Header.PageNumber = 4; 24200e17a87cSSuganath Prabu S mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION; 24210e17a87cSSuganath Prabu S ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 24220e17a87cSSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 24230e17a87cSSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 24240e17a87cSSuganath Prabu S if (r) 24250e17a87cSSuganath Prabu S goto out; 24260e17a87cSSuganath Prabu S 24270e17a87cSSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 24280e17a87cSSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 24290e17a87cSSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 24300e17a87cSSuganath Prabu S sizeof(*config_page)); 24310e17a87cSSuganath Prabu S out: 24320e17a87cSSuganath Prabu S return r; 24330e17a87cSSuganath Prabu S } 24340e17a87cSSuganath Prabu S 24350e17a87cSSuganath Prabu S /** 2436cf9e575eSLee Jones * _config_set_driver_trigger_pg4 - write driver trigger page 4 24370e17a87cSSuganath Prabu S * @ioc: per adapter object 24380e17a87cSSuganath Prabu S * @mpi_reply: reply mf payload returned from firmware 24390e17a87cSSuganath Prabu S * @config_page: contents of the config page 24400e17a87cSSuganath Prabu S * Context: sleep. 24410e17a87cSSuganath Prabu S * 24420e17a87cSSuganath Prabu S * Returns 0 for success, non-zero for failure. 24430e17a87cSSuganath Prabu S */ 24440e17a87cSSuganath Prabu S static int 24450e17a87cSSuganath Prabu S _config_set_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc, 24460e17a87cSSuganath Prabu S Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page) 24470e17a87cSSuganath Prabu S { 24480e17a87cSSuganath Prabu S Mpi2ConfigRequest_t mpi_request; 24490e17a87cSSuganath Prabu S int r; 24500e17a87cSSuganath Prabu S 24510e17a87cSSuganath Prabu S memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 24520e17a87cSSuganath Prabu S mpi_request.Function = MPI2_FUNCTION_CONFIG; 24530e17a87cSSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 24540e17a87cSSuganath Prabu S mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 24550e17a87cSSuganath Prabu S mpi_request.ExtPageType = 24560e17a87cSSuganath Prabu S MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 24570e17a87cSSuganath Prabu S mpi_request.Header.PageNumber = 4; 24580e17a87cSSuganath Prabu S mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION; 24590e17a87cSSuganath Prabu S ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 24600e17a87cSSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 24610e17a87cSSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 24620e17a87cSSuganath Prabu S if (r) 24630e17a87cSSuganath Prabu S goto out; 24640e17a87cSSuganath Prabu S 24650e17a87cSSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 24660e17a87cSSuganath Prabu S _config_request(ioc, &mpi_request, mpi_reply, 24670e17a87cSSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 24680e17a87cSSuganath Prabu S sizeof(*config_page)); 24690e17a87cSSuganath Prabu S mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 24700e17a87cSSuganath Prabu S r = _config_request(ioc, &mpi_request, mpi_reply, 24710e17a87cSSuganath Prabu S MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 24720e17a87cSSuganath Prabu S sizeof(*config_page)); 24730e17a87cSSuganath Prabu S out: 24740e17a87cSSuganath Prabu S return r; 24750e17a87cSSuganath Prabu S } 24760e17a87cSSuganath Prabu S 24770e17a87cSSuganath Prabu S /** 24780e17a87cSSuganath Prabu S * mpt3sas_config_update_driver_trigger_pg4 - update driver trigger page 4 24790e17a87cSSuganath Prabu S * @ioc: per adapter object 24800e17a87cSSuganath Prabu S * @mpi_tg: mpi trigger list 24810e17a87cSSuganath Prabu S * @set: set ot clear trigger values 24820e17a87cSSuganath Prabu S * Context: sleep. 24830e17a87cSSuganath Prabu S * 24840e17a87cSSuganath Prabu S * Returns 0 for success, non-zero for failure. 24850e17a87cSSuganath Prabu S */ 24860e17a87cSSuganath Prabu S int 24870e17a87cSSuganath Prabu S mpt3sas_config_update_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc, 24880e17a87cSSuganath Prabu S struct SL_WH_MPI_TRIGGERS_T *mpi_tg, bool set) 24890e17a87cSSuganath Prabu S { 24900e17a87cSSuganath Prabu S Mpi26DriverTriggerPage4_t tg_pg4; 24910e17a87cSSuganath Prabu S Mpi2ConfigReply_t mpi_reply; 24920e17a87cSSuganath Prabu S int rc, i, count; 24930e17a87cSSuganath Prabu S u16 ioc_status; 24940e17a87cSSuganath Prabu S 24950e17a87cSSuganath Prabu S rc = mpt3sas_config_update_driver_trigger_pg0(ioc, 24960e17a87cSSuganath Prabu S MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, set); 24970e17a87cSSuganath Prabu S if (rc) 24980e17a87cSSuganath Prabu S return rc; 24990e17a87cSSuganath Prabu S 25000e17a87cSSuganath Prabu S rc = mpt3sas_config_get_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4); 25010e17a87cSSuganath Prabu S if (rc) 25020e17a87cSSuganath Prabu S goto out; 25030e17a87cSSuganath Prabu S 25040e17a87cSSuganath Prabu S ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 25050e17a87cSSuganath Prabu S MPI2_IOCSTATUS_MASK; 25060e17a87cSSuganath Prabu S if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 25070e17a87cSSuganath Prabu S dcprintk(ioc, 25080e17a87cSSuganath Prabu S ioc_err(ioc, 25090e17a87cSSuganath Prabu S "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n", 25100e17a87cSSuganath Prabu S __func__, ioc_status)); 25110e17a87cSSuganath Prabu S rc = -EFAULT; 25120e17a87cSSuganath Prabu S goto out; 25130e17a87cSSuganath Prabu S } 25140e17a87cSSuganath Prabu S 25150e17a87cSSuganath Prabu S if (set) { 25160e17a87cSSuganath Prabu S count = mpi_tg->ValidEntries; 25170e17a87cSSuganath Prabu S tg_pg4.NumIOCStatusLogInfoTrigger = cpu_to_le16(count); 25180e17a87cSSuganath Prabu S for (i = 0; i < count; i++) { 25190e17a87cSSuganath Prabu S tg_pg4.IOCStatusLoginfoTriggers[i].IOCStatus = 25200e17a87cSSuganath Prabu S cpu_to_le16(mpi_tg->MPITriggerEntry[i].IOCStatus); 25210e17a87cSSuganath Prabu S tg_pg4.IOCStatusLoginfoTriggers[i].LogInfo = 25220e17a87cSSuganath Prabu S cpu_to_le32(mpi_tg->MPITriggerEntry[i].IocLogInfo); 25230e17a87cSSuganath Prabu S } 25240e17a87cSSuganath Prabu S } else { 25250e17a87cSSuganath Prabu S tg_pg4.NumIOCStatusLogInfoTrigger = 0; 25260e17a87cSSuganath Prabu S memset(&tg_pg4.IOCStatusLoginfoTriggers[0], 0, 25270e17a87cSSuganath Prabu S NUM_VALID_ENTRIES * sizeof( 25280e17a87cSSuganath Prabu S MPI26_DRIVER_IOCSTATUS_LOGINFO_TIGGER_ENTRY)); 25290e17a87cSSuganath Prabu S } 25300e17a87cSSuganath Prabu S 25310e17a87cSSuganath Prabu S rc = _config_set_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4); 25320e17a87cSSuganath Prabu S if (rc) 25330e17a87cSSuganath Prabu S goto out; 25340e17a87cSSuganath Prabu S 25350e17a87cSSuganath Prabu S ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 25360e17a87cSSuganath Prabu S MPI2_IOCSTATUS_MASK; 25370e17a87cSSuganath Prabu S if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 25380e17a87cSSuganath Prabu S dcprintk(ioc, 25390e17a87cSSuganath Prabu S ioc_err(ioc, 25400e17a87cSSuganath Prabu S "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n", 25410e17a87cSSuganath Prabu S __func__, ioc_status)); 25420e17a87cSSuganath Prabu S rc = -EFAULT; 25430e17a87cSSuganath Prabu S goto out; 25440e17a87cSSuganath Prabu S } 25450e17a87cSSuganath Prabu S 25460e17a87cSSuganath Prabu S return 0; 25470e17a87cSSuganath Prabu S 25480e17a87cSSuganath Prabu S out: 25490e17a87cSSuganath Prabu S mpt3sas_config_update_driver_trigger_pg0(ioc, 25500e17a87cSSuganath Prabu S MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, !set); 25510e17a87cSSuganath Prabu S 25520e17a87cSSuganath Prabu S return rc; 25530e17a87cSSuganath Prabu S } 25540e17a87cSSuganath Prabu S 25550e17a87cSSuganath Prabu S /** 2556f92363d1SSreekanth Reddy * mpt3sas_config_get_volume_handle - returns volume handle for give hidden 2557f92363d1SSreekanth Reddy * raid components 2558f92363d1SSreekanth Reddy * @ioc: per adapter object 2559f92363d1SSreekanth Reddy * @pd_handle: phys disk handle 2560f92363d1SSreekanth Reddy * @volume_handle: volume handle 2561f92363d1SSreekanth Reddy * Context: sleep. 2562f92363d1SSreekanth Reddy * 25634beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 2564f92363d1SSreekanth Reddy */ 2565f92363d1SSreekanth Reddy int 2566f92363d1SSreekanth Reddy mpt3sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle, 2567f92363d1SSreekanth Reddy u16 *volume_handle) 2568f92363d1SSreekanth Reddy { 2569f92363d1SSreekanth Reddy Mpi2RaidConfigurationPage0_t *config_page = NULL; 2570f92363d1SSreekanth Reddy Mpi2ConfigRequest_t mpi_request; 2571f92363d1SSreekanth Reddy Mpi2ConfigReply_t mpi_reply; 2572f92363d1SSreekanth Reddy int r, i, config_page_sz; 2573f92363d1SSreekanth Reddy u16 ioc_status; 2574f92363d1SSreekanth Reddy int config_num; 2575f92363d1SSreekanth Reddy u16 element_type; 2576f92363d1SSreekanth Reddy u16 phys_disk_dev_handle; 2577f92363d1SSreekanth Reddy 2578f92363d1SSreekanth Reddy *volume_handle = 0; 2579f92363d1SSreekanth Reddy memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2580f92363d1SSreekanth Reddy mpi_request.Function = MPI2_FUNCTION_CONFIG; 2581f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2582f92363d1SSreekanth Reddy mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2583f92363d1SSreekanth Reddy mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG; 2584f92363d1SSreekanth Reddy mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION; 2585f92363d1SSreekanth Reddy mpi_request.Header.PageNumber = 0; 2586f92363d1SSreekanth Reddy ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2587f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, &mpi_reply, 2588f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2589f92363d1SSreekanth Reddy if (r) 2590f92363d1SSreekanth Reddy goto out; 2591f92363d1SSreekanth Reddy 2592f92363d1SSreekanth Reddy mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 2593f92363d1SSreekanth Reddy config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4); 2594f92363d1SSreekanth Reddy config_page = kmalloc(config_page_sz, GFP_KERNEL); 2595f92363d1SSreekanth Reddy if (!config_page) { 2596f92363d1SSreekanth Reddy r = -1; 2597f92363d1SSreekanth Reddy goto out; 2598f92363d1SSreekanth Reddy } 2599f92363d1SSreekanth Reddy 2600f92363d1SSreekanth Reddy config_num = 0xff; 2601f92363d1SSreekanth Reddy while (1) { 2602f92363d1SSreekanth Reddy mpi_request.PageAddress = cpu_to_le32(config_num + 2603f92363d1SSreekanth Reddy MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM); 2604f92363d1SSreekanth Reddy r = _config_request(ioc, &mpi_request, &mpi_reply, 2605f92363d1SSreekanth Reddy MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2606f92363d1SSreekanth Reddy config_page_sz); 2607f92363d1SSreekanth Reddy if (r) 2608f92363d1SSreekanth Reddy goto out; 2609f92363d1SSreekanth Reddy r = -1; 2610f92363d1SSreekanth Reddy ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2611f92363d1SSreekanth Reddy MPI2_IOCSTATUS_MASK; 2612f92363d1SSreekanth Reddy if (ioc_status != MPI2_IOCSTATUS_SUCCESS) 2613f92363d1SSreekanth Reddy goto out; 2614f92363d1SSreekanth Reddy for (i = 0; i < config_page->NumElements; i++) { 2615f92363d1SSreekanth Reddy element_type = le16_to_cpu(config_page-> 2616f92363d1SSreekanth Reddy ConfigElement[i].ElementFlags) & 2617f92363d1SSreekanth Reddy MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE; 2618f92363d1SSreekanth Reddy if (element_type == 2619f92363d1SSreekanth Reddy MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT || 2620f92363d1SSreekanth Reddy element_type == 2621f92363d1SSreekanth Reddy MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) { 2622f92363d1SSreekanth Reddy phys_disk_dev_handle = 2623f92363d1SSreekanth Reddy le16_to_cpu(config_page->ConfigElement[i]. 2624f92363d1SSreekanth Reddy PhysDiskDevHandle); 2625f92363d1SSreekanth Reddy if (phys_disk_dev_handle == pd_handle) { 2626f92363d1SSreekanth Reddy *volume_handle = 2627f92363d1SSreekanth Reddy le16_to_cpu(config_page-> 2628f92363d1SSreekanth Reddy ConfigElement[i].VolDevHandle); 2629f92363d1SSreekanth Reddy r = 0; 2630f92363d1SSreekanth Reddy goto out; 2631f92363d1SSreekanth Reddy } 2632f92363d1SSreekanth Reddy } else if (element_type == 2633f92363d1SSreekanth Reddy MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) { 2634f92363d1SSreekanth Reddy *volume_handle = 0; 2635f92363d1SSreekanth Reddy r = 0; 2636f92363d1SSreekanth Reddy goto out; 2637f92363d1SSreekanth Reddy } 2638f92363d1SSreekanth Reddy } 2639f92363d1SSreekanth Reddy config_num = config_page->ConfigNum; 2640f92363d1SSreekanth Reddy } 2641f92363d1SSreekanth Reddy out: 2642f92363d1SSreekanth Reddy kfree(config_page); 2643f92363d1SSreekanth Reddy return r; 2644f92363d1SSreekanth Reddy } 2645f92363d1SSreekanth Reddy 2646f92363d1SSreekanth Reddy /** 2647f92363d1SSreekanth Reddy * mpt3sas_config_get_volume_wwid - returns wwid given the volume handle 2648f92363d1SSreekanth Reddy * @ioc: per adapter object 2649f92363d1SSreekanth Reddy * @volume_handle: volume handle 2650f92363d1SSreekanth Reddy * @wwid: volume wwid 2651f92363d1SSreekanth Reddy * Context: sleep. 2652f92363d1SSreekanth Reddy * 26534beb4867SBart Van Assche * Return: 0 for success, non-zero for failure. 2654f92363d1SSreekanth Reddy */ 2655f92363d1SSreekanth Reddy int 2656f92363d1SSreekanth Reddy mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc, u16 volume_handle, 2657f92363d1SSreekanth Reddy u64 *wwid) 2658f92363d1SSreekanth Reddy { 2659f92363d1SSreekanth Reddy Mpi2ConfigReply_t mpi_reply; 2660f92363d1SSreekanth Reddy Mpi2RaidVolPage1_t raid_vol_pg1; 2661f92363d1SSreekanth Reddy 2662f92363d1SSreekanth Reddy *wwid = 0; 2663f92363d1SSreekanth Reddy if (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply, 2664f92363d1SSreekanth Reddy &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, 2665f92363d1SSreekanth Reddy volume_handle))) { 2666f92363d1SSreekanth Reddy *wwid = le64_to_cpu(raid_vol_pg1.WWID); 2667f92363d1SSreekanth Reddy return 0; 2668f92363d1SSreekanth Reddy } else 2669f92363d1SSreekanth Reddy return -1; 2670f92363d1SSreekanth Reddy } 2671