2795 lines · c
1/*2 * This module provides common API for accessing firmware configuration pages3 *4 * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c5 * Copyright (C) 2012-2014 LSI Corporation6 * Copyright (C) 2013-2014 Avago Technologies7 * (mailto: MPT-FusionLinux.pdl@avagotech.com)8 *9 * This program is free software; you can redistribute it and/or10 * modify it under the terms of the GNU General Public License11 * as published by the Free Software Foundation; either version 212 * of the License, or (at your option) any later version.13 *14 * This program is distributed in the hope that it will be useful,15 * but WITHOUT ANY WARRANTY; without even the implied warranty of16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the17 * GNU General Public License for more details.18 *19 * NO WARRANTY20 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR21 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT22 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,23 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is24 * solely responsible for determining the appropriateness of using and25 * distributing the Program and assumes all risks associated with its26 * exercise of rights under this Agreement, including but not limited to27 * the risks and costs of program errors, damage to or loss of data,28 * programs or equipment, and unavailability or interruption of operations.29 30 * DISCLAIMER OF LIABILITY31 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY32 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL33 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND34 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR35 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE36 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED37 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES38 39 * You should have received a copy of the GNU General Public License40 * along with this program; if not, write to the Free Software41 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,42 * USA.43 */44 45#include <linux/module.h>46#include <linux/kernel.h>47#include <linux/init.h>48#include <linux/errno.h>49#include <linux/blkdev.h>50#include <linux/sched.h>51#include <linux/workqueue.h>52#include <linux/delay.h>53#include <linux/pci.h>54 55#include "mpt3sas_base.h"56 57/* local definitions */58 59/* Timeout for config page request (in seconds) */60#define MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT 1561 62/* Common sgl flags for READING a config page. */63#define MPT3_CONFIG_COMMON_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \64 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \65 | MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT)66 67/* Common sgl flags for WRITING a config page. */68#define MPT3_CONFIG_COMMON_WRITE_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \69 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \70 | MPI2_SGE_FLAGS_END_OF_LIST | MPI2_SGE_FLAGS_HOST_TO_IOC) \71 << MPI2_SGE_FLAGS_SHIFT)72 73/**74 * struct config_request - obtain dma memory via routine75 * @sz: size76 * @page: virt pointer77 * @page_dma: phys pointer78 *79 */80struct config_request {81 u16 sz;82 void *page;83 dma_addr_t page_dma;84};85 86/**87 * _config_display_some_debug - debug routine88 * @ioc: per adapter object89 * @smid: system request message index90 * @calling_function_name: string pass from calling function91 * @mpi_reply: reply message frame92 * Context: none.93 *94 * Function for displaying debug info helpful when debugging issues95 * in this module.96 */97static void98_config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid,99 char *calling_function_name, MPI2DefaultReply_t *mpi_reply)100{101 Mpi2ConfigRequest_t *mpi_request;102 char *desc = NULL;103 104 mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);105 switch (mpi_request->Header.PageType & MPI2_CONFIG_PAGETYPE_MASK) {106 case MPI2_CONFIG_PAGETYPE_IO_UNIT:107 desc = "io_unit";108 break;109 case MPI2_CONFIG_PAGETYPE_IOC:110 desc = "ioc";111 break;112 case MPI2_CONFIG_PAGETYPE_BIOS:113 desc = "bios";114 break;115 case MPI2_CONFIG_PAGETYPE_RAID_VOLUME:116 desc = "raid_volume";117 break;118 case MPI2_CONFIG_PAGETYPE_MANUFACTURING:119 desc = "manufacturing";120 break;121 case MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK:122 desc = "physdisk";123 break;124 case MPI2_CONFIG_PAGETYPE_EXTENDED:125 switch (mpi_request->ExtPageType) {126 case MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT:127 desc = "sas_io_unit";128 break;129 case MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER:130 desc = "sas_expander";131 break;132 case MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE:133 desc = "sas_device";134 break;135 case MPI2_CONFIG_EXTPAGETYPE_SAS_PHY:136 desc = "sas_phy";137 break;138 case MPI2_CONFIG_EXTPAGETYPE_LOG:139 desc = "log";140 break;141 case MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE:142 desc = "enclosure";143 break;144 case MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG:145 desc = "raid_config";146 break;147 case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING:148 desc = "driver_mapping";149 break;150 case MPI2_CONFIG_EXTPAGETYPE_SAS_PORT:151 desc = "sas_port";152 break;153 case MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING:154 desc = "ext_manufacturing";155 break;156 case MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT:157 desc = "pcie_io_unit";158 break;159 case MPI2_CONFIG_EXTPAGETYPE_PCIE_SWITCH:160 desc = "pcie_switch";161 break;162 case MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE:163 desc = "pcie_device";164 break;165 case MPI2_CONFIG_EXTPAGETYPE_PCIE_LINK:166 desc = "pcie_link";167 break;168 }169 break;170 }171 172 if (!desc)173 return;174 175 ioc_info(ioc, "%s: %s(%d), action(%d), form(0x%08x), smid(%d)\n",176 calling_function_name, desc,177 mpi_request->Header.PageNumber, mpi_request->Action,178 le32_to_cpu(mpi_request->PageAddress), smid);179 180 if (!mpi_reply)181 return;182 183 if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo)184 ioc_info(ioc, "\tiocstatus(0x%04x), loginfo(0x%08x)\n",185 le16_to_cpu(mpi_reply->IOCStatus),186 le32_to_cpu(mpi_reply->IOCLogInfo));187}188 189/**190 * _config_alloc_config_dma_memory - obtain physical memory191 * @ioc: per adapter object192 * @mem: struct config_request193 *194 * A wrapper for obtaining dma-able memory for config page request.195 *196 * Return: 0 for success, non-zero for failure.197 */198static int199_config_alloc_config_dma_memory(struct MPT3SAS_ADAPTER *ioc,200 struct config_request *mem)201{202 int r = 0;203 204 if (mem->sz > ioc->config_page_sz) {205 mem->page = dma_alloc_coherent(&ioc->pdev->dev, mem->sz,206 &mem->page_dma, GFP_KERNEL);207 if (!mem->page) {208 ioc_err(ioc, "%s: dma_alloc_coherent failed asking for (%d) bytes!!\n",209 __func__, mem->sz);210 r = -ENOMEM;211 }212 } else { /* use tmp buffer if less than 512 bytes */213 mem->page = ioc->config_page;214 mem->page_dma = ioc->config_page_dma;215 }216 ioc->config_vaddr = mem->page;217 return r;218}219 220/**221 * _config_free_config_dma_memory - wrapper to free the memory222 * @ioc: per adapter object223 * @mem: struct config_request224 *225 * A wrapper to free dma-able memory when using _config_alloc_config_dma_memory.226 *227 * Return: 0 for success, non-zero for failure.228 */229static void230_config_free_config_dma_memory(struct MPT3SAS_ADAPTER *ioc,231 struct config_request *mem)232{233 if (mem->sz > ioc->config_page_sz)234 dma_free_coherent(&ioc->pdev->dev, mem->sz, mem->page,235 mem->page_dma);236}237 238/**239 * mpt3sas_config_done - config page completion routine240 * @ioc: per adapter object241 * @smid: system request message index242 * @msix_index: MSIX table index supplied by the OS243 * @reply: reply message frame(lower 32bit addr)244 * Context: none.245 *246 * The callback handler when using _config_request.247 *248 * Return: 1 meaning mf should be freed from _base_interrupt249 * 0 means the mf is freed from this function.250 */251u8252mpt3sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,253 u32 reply)254{255 MPI2DefaultReply_t *mpi_reply;256 257 if (ioc->config_cmds.status == MPT3_CMD_NOT_USED)258 return 1;259 if (ioc->config_cmds.smid != smid)260 return 1;261 ioc->config_cmds.status |= MPT3_CMD_COMPLETE;262 mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);263 if (mpi_reply) {264 ioc->config_cmds.status |= MPT3_CMD_REPLY_VALID;265 memcpy(ioc->config_cmds.reply, mpi_reply,266 mpi_reply->MsgLength*4);267 }268 ioc->config_cmds.status &= ~MPT3_CMD_PENDING;269 if (ioc->logging_level & MPT_DEBUG_CONFIG)270 _config_display_some_debug(ioc, smid, "config_done", mpi_reply);271 ioc->config_cmds.smid = USHRT_MAX;272 complete(&ioc->config_cmds.done);273 return 1;274}275 276/**277 * _config_request - main routine for sending config page requests278 * @ioc: per adapter object279 * @mpi_request: request message frame280 * @mpi_reply: reply mf payload returned from firmware281 * @timeout: timeout in seconds282 * @config_page: contents of the config page283 * @config_page_sz: size of config page284 * Context: sleep285 *286 * A generic API for config page requests to firmware.287 *288 * The ioc->config_cmds.status flag should be MPT3_CMD_NOT_USED before calling289 * this API.290 *291 * The callback index is set inside `ioc->config_cb_idx.292 *293 * Return: 0 for success, non-zero for failure.294 */295static int296_config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t297 *mpi_request, Mpi2ConfigReply_t *mpi_reply, int timeout,298 void *config_page, u16 config_page_sz)299{300 u16 smid;301 Mpi2ConfigRequest_t *config_request;302 int r;303 u8 retry_count, issue_host_reset = 0;304 struct config_request mem;305 u32 ioc_status = UINT_MAX;306 307 mutex_lock(&ioc->config_cmds.mutex);308 if (ioc->config_cmds.status != MPT3_CMD_NOT_USED) {309 ioc_err(ioc, "%s: config_cmd in use\n", __func__);310 mutex_unlock(&ioc->config_cmds.mutex);311 return -EAGAIN;312 }313 314 retry_count = 0;315 memset(&mem, 0, sizeof(struct config_request));316 317 mpi_request->VF_ID = 0; /* TODO */318 mpi_request->VP_ID = 0;319 320 if (config_page) {321 mpi_request->Header.PageVersion = mpi_reply->Header.PageVersion;322 mpi_request->Header.PageNumber = mpi_reply->Header.PageNumber;323 mpi_request->Header.PageType = mpi_reply->Header.PageType;324 mpi_request->Header.PageLength = mpi_reply->Header.PageLength;325 mpi_request->ExtPageLength = mpi_reply->ExtPageLength;326 mpi_request->ExtPageType = mpi_reply->ExtPageType;327 if (mpi_request->Header.PageLength)328 mem.sz = mpi_request->Header.PageLength * 4;329 else330 mem.sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;331 r = _config_alloc_config_dma_memory(ioc, &mem);332 if (r != 0)333 goto out;334 if (mpi_request->Action ==335 MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT ||336 mpi_request->Action ==337 MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {338 ioc->base_add_sg_single(&mpi_request->PageBufferSGE,339 MPT3_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz,340 mem.page_dma);341 memcpy(mem.page, config_page, min_t(u16, mem.sz,342 config_page_sz));343 } else {344 memset(config_page, 0, config_page_sz);345 ioc->base_add_sg_single(&mpi_request->PageBufferSGE,346 MPT3_CONFIG_COMMON_SGLFLAGS | mem.sz, mem.page_dma);347 memset(mem.page, 0, min_t(u16, mem.sz, config_page_sz));348 }349 }350 351 retry_config:352 if (retry_count) {353 if (retry_count > 2) { /* attempt only 2 retries */354 r = -EFAULT;355 goto free_mem;356 }357 ioc_info(ioc, "%s: attempting retry (%d)\n",358 __func__, retry_count);359 }360 361 r = mpt3sas_wait_for_ioc(ioc, MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT);362 if (r) {363 if (r == -ETIME)364 issue_host_reset = 1;365 goto free_mem;366 }367 368 smid = mpt3sas_base_get_smid(ioc, ioc->config_cb_idx);369 if (!smid) {370 ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);371 ioc->config_cmds.status = MPT3_CMD_NOT_USED;372 r = -EAGAIN;373 goto free_mem;374 }375 376 r = 0;377 memset(ioc->config_cmds.reply, 0, sizeof(Mpi2ConfigReply_t));378 ioc->config_cmds.status = MPT3_CMD_PENDING;379 config_request = mpt3sas_base_get_msg_frame(ioc, smid);380 ioc->config_cmds.smid = smid;381 memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t));382 if (ioc->logging_level & MPT_DEBUG_CONFIG)383 _config_display_some_debug(ioc, smid, "config_request", NULL);384 init_completion(&ioc->config_cmds.done);385 ioc->put_smid_default(ioc, smid);386 wait_for_completion_timeout(&ioc->config_cmds.done, timeout*HZ);387 if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) {388 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))389 _config_display_some_debug(ioc,390 smid, "config_request", NULL);391 ioc_err(ioc, "%s: command timeout\n", __func__);392 mpt3sas_base_check_cmd_timeout(ioc, ioc->config_cmds.status,393 mpi_request, sizeof(Mpi2ConfigRequest_t) / 4);394 retry_count++;395 if (ioc->config_cmds.smid == smid)396 mpt3sas_base_free_smid(ioc, smid);397 if (ioc->config_cmds.status & MPT3_CMD_RESET)398 goto retry_config;399 if (ioc->shost_recovery || ioc->pci_error_recovery) {400 issue_host_reset = 0;401 r = -EFAULT;402 } else403 issue_host_reset = 1;404 goto free_mem;405 }406 407 if (ioc->config_cmds.status & MPT3_CMD_REPLY_VALID) {408 memcpy(mpi_reply, ioc->config_cmds.reply,409 sizeof(Mpi2ConfigReply_t));410 411 /* Reply Frame Sanity Checks to workaround FW issues */412 if ((mpi_request->Header.PageType & 0xF) !=413 (mpi_reply->Header.PageType & 0xF)) {414 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))415 _config_display_some_debug(ioc,416 smid, "config_request", NULL);417 _debug_dump_mf(mpi_request, ioc->request_sz/4);418 _debug_dump_reply(mpi_reply, ioc->reply_sz/4);419 panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n",420 ioc->name, __func__,421 mpi_request->Header.PageType & 0xF,422 mpi_reply->Header.PageType & 0xF);423 }424 425 if (((mpi_request->Header.PageType & 0xF) ==426 MPI2_CONFIG_PAGETYPE_EXTENDED) &&427 mpi_request->ExtPageType != mpi_reply->ExtPageType) {428 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))429 _config_display_some_debug(ioc,430 smid, "config_request", NULL);431 _debug_dump_mf(mpi_request, ioc->request_sz/4);432 _debug_dump_reply(mpi_reply, ioc->reply_sz/4);433 panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n",434 ioc->name, __func__,435 mpi_request->ExtPageType,436 mpi_reply->ExtPageType);437 }438 ioc_status = le16_to_cpu(mpi_reply->IOCStatus)439 & MPI2_IOCSTATUS_MASK;440 }441 442 if (retry_count)443 ioc_info(ioc, "%s: retry (%d) completed!!\n",444 __func__, retry_count);445 446 if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) &&447 config_page && mpi_request->Action ==448 MPI2_CONFIG_ACTION_PAGE_READ_CURRENT) {449 u8 *p = (u8 *)mem.page;450 451 /* Config Page Sanity Checks to workaround FW issues */452 if (p) {453 if ((mpi_request->Header.PageType & 0xF) !=454 (p[3] & 0xF)) {455 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))456 _config_display_some_debug(ioc,457 smid, "config_request", NULL);458 _debug_dump_mf(mpi_request, ioc->request_sz/4);459 _debug_dump_reply(mpi_reply, ioc->reply_sz/4);460 _debug_dump_config(p, min_t(u16, mem.sz,461 config_page_sz)/4);462 panic("%s: %s: Firmware BUG: config page mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n",463 ioc->name, __func__,464 mpi_request->Header.PageType & 0xF,465 p[3] & 0xF);466 }467 468 if (((mpi_request->Header.PageType & 0xF) ==469 MPI2_CONFIG_PAGETYPE_EXTENDED) &&470 (mpi_request->ExtPageType != p[6])) {471 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))472 _config_display_some_debug(ioc,473 smid, "config_request", NULL);474 _debug_dump_mf(mpi_request, ioc->request_sz/4);475 _debug_dump_reply(mpi_reply, ioc->reply_sz/4);476 _debug_dump_config(p, min_t(u16, mem.sz,477 config_page_sz)/4);478 panic("%s: %s: Firmware BUG: config page mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n",479 ioc->name, __func__,480 mpi_request->ExtPageType, p[6]);481 }482 }483 memcpy(config_page, mem.page, min_t(u16, mem.sz,484 config_page_sz));485 }486 487 free_mem:488 if (config_page)489 _config_free_config_dma_memory(ioc, &mem);490 out:491 ioc->config_cmds.status = MPT3_CMD_NOT_USED;492 mutex_unlock(&ioc->config_cmds.mutex);493 494 if (issue_host_reset) {495 if (ioc->drv_internal_flags & MPT_DRV_INTERNAL_FIRST_PE_ISSUED) {496 mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);497 r = -EFAULT;498 } else {499 if (mpt3sas_base_check_for_fault_and_issue_reset(ioc))500 return -EFAULT;501 r = -EAGAIN;502 }503 }504 return r;505}506 507/**508 * mpt3sas_config_get_manufacturing_pg0 - obtain manufacturing page 0509 * @ioc: per adapter object510 * @mpi_reply: reply mf payload returned from firmware511 * @config_page: contents of the config page512 * Context: sleep.513 *514 * Return: 0 for success, non-zero for failure.515 */516int517mpt3sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER *ioc,518 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page)519{520 Mpi2ConfigRequest_t mpi_request;521 int r;522 523 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));524 mpi_request.Function = MPI2_FUNCTION_CONFIG;525 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;526 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;527 mpi_request.Header.PageNumber = 0;528 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;529 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);530 r = _config_request(ioc, &mpi_request, mpi_reply,531 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);532 if (r)533 goto out;534 535 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;536 r = _config_request(ioc, &mpi_request, mpi_reply,537 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,538 sizeof(*config_page));539 out:540 return r;541}542 543/**544 * mpt3sas_config_get_manufacturing_pg1 - obtain manufacturing page 1545 * @ioc: per adapter object546 * @mpi_reply: reply mf payload returned from firmware547 * @config_page: contents of the config page548 * Context: sleep.549 *550 * Return: 0 for success, non-zero for failure.551 */552int553mpt3sas_config_get_manufacturing_pg1(struct MPT3SAS_ADAPTER *ioc,554 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage1_t *config_page)555{556 Mpi2ConfigRequest_t mpi_request;557 int r;558 559 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));560 mpi_request.Function = MPI2_FUNCTION_CONFIG;561 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;562 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;563 mpi_request.Header.PageNumber = 1;564 mpi_request.Header.PageVersion = MPI2_MANUFACTURING1_PAGEVERSION;565 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);566 r = _config_request(ioc, &mpi_request, mpi_reply,567 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);568 if (r)569 goto out;570 571 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;572 r = _config_request(ioc, &mpi_request, mpi_reply,573 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,574 sizeof(*config_page));575 out:576 return r;577}578 579/**580 * mpt3sas_config_get_manufacturing_pg7 - obtain manufacturing page 7581 * @ioc: per adapter object582 * @mpi_reply: reply mf payload returned from firmware583 * @config_page: contents of the config page584 * @sz: size of buffer passed in config_page585 * Context: sleep.586 *587 * Return: 0 for success, non-zero for failure.588 */589int590mpt3sas_config_get_manufacturing_pg7(struct MPT3SAS_ADAPTER *ioc,591 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage7_t *config_page,592 u16 sz)593{594 Mpi2ConfigRequest_t mpi_request;595 int r;596 597 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));598 mpi_request.Function = MPI2_FUNCTION_CONFIG;599 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;600 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;601 mpi_request.Header.PageNumber = 7;602 mpi_request.Header.PageVersion = MPI2_MANUFACTURING7_PAGEVERSION;603 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);604 r = _config_request(ioc, &mpi_request, mpi_reply,605 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);606 if (r)607 goto out;608 609 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;610 r = _config_request(ioc, &mpi_request, mpi_reply,611 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,612 sz);613 out:614 return r;615}616 617/**618 * mpt3sas_config_get_manufacturing_pg10 - obtain manufacturing page 10619 * @ioc: per adapter object620 * @mpi_reply: reply mf payload returned from firmware621 * @config_page: contents of the config page622 * Context: sleep.623 *624 * Return: 0 for success, non-zero for failure.625 */626int627mpt3sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER *ioc,628 Mpi2ConfigReply_t *mpi_reply,629 struct Mpi2ManufacturingPage10_t *config_page)630{631 Mpi2ConfigRequest_t mpi_request;632 int r;633 634 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));635 mpi_request.Function = MPI2_FUNCTION_CONFIG;636 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;637 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;638 mpi_request.Header.PageNumber = 10;639 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;640 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);641 r = _config_request(ioc, &mpi_request, mpi_reply,642 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);643 if (r)644 goto out;645 646 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;647 r = _config_request(ioc, &mpi_request, mpi_reply,648 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,649 sizeof(*config_page));650 out:651 return r;652}653 654/**655 * mpt3sas_config_get_manufacturing_pg11 - obtain manufacturing page 11656 * @ioc: per adapter object657 * @mpi_reply: reply mf payload returned from firmware658 * @config_page: contents of the config page659 * Context: sleep.660 *661 * Return: 0 for success, non-zero for failure.662 */663int664mpt3sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,665 Mpi2ConfigReply_t *mpi_reply,666 struct Mpi2ManufacturingPage11_t *config_page)667{668 Mpi2ConfigRequest_t mpi_request;669 int r;670 671 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));672 mpi_request.Function = MPI2_FUNCTION_CONFIG;673 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;674 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;675 mpi_request.Header.PageNumber = 11;676 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;677 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);678 r = _config_request(ioc, &mpi_request, mpi_reply,679 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);680 if (r)681 goto out;682 683 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;684 r = _config_request(ioc, &mpi_request, mpi_reply,685 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,686 sizeof(*config_page));687 out:688 return r;689}690 691/**692 * mpt3sas_config_set_manufacturing_pg11 - set manufacturing page 11693 * @ioc: per adapter object694 * @mpi_reply: reply mf payload returned from firmware695 * @config_page: contents of the config page696 * Context: sleep.697 *698 * Return: 0 for success, non-zero for failure.699 */700int701mpt3sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,702 Mpi2ConfigReply_t *mpi_reply,703 struct Mpi2ManufacturingPage11_t *config_page)704{705 Mpi2ConfigRequest_t mpi_request;706 int r;707 708 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));709 mpi_request.Function = MPI2_FUNCTION_CONFIG;710 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;711 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;712 mpi_request.Header.PageNumber = 11;713 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;714 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);715 r = _config_request(ioc, &mpi_request, mpi_reply,716 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);717 if (r)718 goto out;719 720 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;721 r = _config_request(ioc, &mpi_request, mpi_reply,722 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,723 sizeof(*config_page));724 out:725 return r;726}727 728/**729 * mpt3sas_config_get_bios_pg2 - obtain bios page 2730 * @ioc: per adapter object731 * @mpi_reply: reply mf payload returned from firmware732 * @config_page: contents of the config page733 * Context: sleep.734 *735 * Return: 0 for success, non-zero for failure.736 */737int738mpt3sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER *ioc,739 Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page)740{741 Mpi2ConfigRequest_t mpi_request;742 int r;743 744 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));745 mpi_request.Function = MPI2_FUNCTION_CONFIG;746 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;747 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;748 mpi_request.Header.PageNumber = 2;749 mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION;750 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);751 r = _config_request(ioc, &mpi_request, mpi_reply,752 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);753 if (r)754 goto out;755 756 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;757 r = _config_request(ioc, &mpi_request, mpi_reply,758 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,759 sizeof(*config_page));760 out:761 return r;762}763 764/**765 * mpt3sas_config_get_bios_pg3 - obtain bios page 3766 * @ioc: per adapter object767 * @mpi_reply: reply mf payload returned from firmware768 * @config_page: contents of the config page769 * Context: sleep.770 *771 * Return: 0 for success, non-zero for failure.772 */773int774mpt3sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t775 *mpi_reply, Mpi2BiosPage3_t *config_page)776{777 Mpi2ConfigRequest_t mpi_request;778 int r;779 780 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));781 mpi_request.Function = MPI2_FUNCTION_CONFIG;782 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;783 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;784 mpi_request.Header.PageNumber = 3;785 mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;786 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);787 r = _config_request(ioc, &mpi_request, mpi_reply,788 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);789 if (r)790 goto out;791 792 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;793 r = _config_request(ioc, &mpi_request, mpi_reply,794 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,795 sizeof(*config_page));796 797 out:798 return r;799}800 801/**802 * mpt3sas_config_set_bios_pg4 - write out bios page 4803 * @ioc: per adapter object804 * @mpi_reply: reply mf payload returned from firmware805 * @config_page: contents of the config page806 * @sz_config_pg: sizeof the config page807 * Context: sleep.808 *809 * Return: 0 for success, non-zero for failure.810 */811int812mpt3sas_config_set_bios_pg4(struct MPT3SAS_ADAPTER *ioc,813 Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage4_t *config_page,814 int sz_config_pg)815{816 Mpi2ConfigRequest_t mpi_request;817 int r;818 819 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));820 821 mpi_request.Function = MPI2_FUNCTION_CONFIG;822 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;823 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;824 mpi_request.Header.PageNumber = 4;825 mpi_request.Header.PageVersion = MPI2_BIOSPAGE4_PAGEVERSION;826 827 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);828 829 r = _config_request(ioc, &mpi_request, mpi_reply,830 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);831 if (r)832 goto out;833 834 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;835 r = _config_request(ioc, &mpi_request, mpi_reply,836 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,837 sz_config_pg);838 out:839 return r;840}841 842/**843 * mpt3sas_config_get_bios_pg4 - read bios page 4844 * @ioc: per adapter object845 * @mpi_reply: reply mf payload returned from firmware846 * @config_page: contents of the config page847 * @sz_config_pg: sizeof the config page848 * Context: sleep.849 *850 * Return: 0 for success, non-zero for failure.851 */852int853mpt3sas_config_get_bios_pg4(struct MPT3SAS_ADAPTER *ioc,854 Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage4_t *config_page,855 int sz_config_pg)856{857 Mpi2ConfigRequest_t mpi_request;858 int r;859 860 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));861 mpi_request.Function = MPI2_FUNCTION_CONFIG;862 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;863 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;864 mpi_request.Header.PageNumber = 4;865 mpi_request.Header.PageVersion = MPI2_BIOSPAGE4_PAGEVERSION;866 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);867 r = _config_request(ioc, &mpi_request, mpi_reply,868 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);869 if (r)870 goto out;871 872 /*873 * The sizeof the page is variable. Allow for just the874 * size to be returned875 */876 if (config_page && sz_config_pg) {877 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;878 879 r = _config_request(ioc, &mpi_request, mpi_reply,880 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,881 sz_config_pg);882 }883 884out:885 return r;886}887 888/**889 * mpt3sas_config_get_iounit_pg0 - obtain iounit page 0890 * @ioc: per adapter object891 * @mpi_reply: reply mf payload returned from firmware892 * @config_page: contents of the config page893 * Context: sleep.894 *895 * Return: 0 for success, non-zero for failure.896 */897int898mpt3sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,899 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page)900{901 Mpi2ConfigRequest_t mpi_request;902 int r;903 904 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));905 mpi_request.Function = MPI2_FUNCTION_CONFIG;906 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;907 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;908 mpi_request.Header.PageNumber = 0;909 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION;910 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);911 r = _config_request(ioc, &mpi_request, mpi_reply,912 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);913 if (r)914 goto out;915 916 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;917 r = _config_request(ioc, &mpi_request, mpi_reply,918 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,919 sizeof(*config_page));920 out:921 return r;922}923 924/**925 * mpt3sas_config_get_iounit_pg1 - obtain iounit page 1926 * @ioc: per adapter object927 * @mpi_reply: reply mf payload returned from firmware928 * @config_page: contents of the config page929 * Context: sleep.930 *931 * Return: 0 for success, non-zero for failure.932 */933int934mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,935 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)936{937 Mpi2ConfigRequest_t mpi_request;938 int r;939 940 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));941 mpi_request.Function = MPI2_FUNCTION_CONFIG;942 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;943 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;944 mpi_request.Header.PageNumber = 1;945 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;946 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);947 r = _config_request(ioc, &mpi_request, mpi_reply,948 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);949 if (r)950 goto out;951 952 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;953 r = _config_request(ioc, &mpi_request, mpi_reply,954 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,955 sizeof(*config_page));956 out:957 return r;958}959 960/**961 * mpt3sas_config_set_iounit_pg1 - set iounit page 1962 * @ioc: per adapter object963 * @mpi_reply: reply mf payload returned from firmware964 * @config_page: contents of the config page965 * Context: sleep.966 *967 * Return: 0 for success, non-zero for failure.968 */969int970mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,971 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)972{973 Mpi2ConfigRequest_t mpi_request;974 int r;975 976 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));977 mpi_request.Function = MPI2_FUNCTION_CONFIG;978 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;979 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;980 mpi_request.Header.PageNumber = 1;981 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;982 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);983 r = _config_request(ioc, &mpi_request, mpi_reply,984 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);985 if (r)986 goto out;987 988 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;989 r = _config_request(ioc, &mpi_request, mpi_reply,990 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,991 sizeof(*config_page));992 out:993 return r;994}995 996/**997 * mpt3sas_config_get_iounit_pg3 - obtain iounit page 3998 * @ioc: per adapter object999 * @mpi_reply: reply mf payload returned from firmware1000 * @config_page: contents of the config page1001 * @sz: size of buffer passed in config_page1002 * Context: sleep.1003 *1004 * Return: 0 for success, non-zero for failure.1005 */1006int1007mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,1008 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz)1009{1010 Mpi2ConfigRequest_t mpi_request;1011 int r;1012 1013 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1014 mpi_request.Function = MPI2_FUNCTION_CONFIG;1015 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1016 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;1017 mpi_request.Header.PageNumber = 3;1018 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION;1019 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1020 r = _config_request(ioc, &mpi_request, mpi_reply,1021 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1022 if (r)1023 goto out;1024 1025 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1026 r = _config_request(ioc, &mpi_request, mpi_reply,1027 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);1028 out:1029 return r;1030}1031 1032/**1033 * mpt3sas_config_get_iounit_pg8 - obtain iounit page 81034 * @ioc: per adapter object1035 * @mpi_reply: reply mf payload returned from firmware1036 * @config_page: contents of the config page1037 * Context: sleep.1038 *1039 * Return: 0 for success, non-zero for failure.1040 */1041int1042mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc,1043 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page)1044{1045 Mpi2ConfigRequest_t mpi_request;1046 int r;1047 1048 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1049 mpi_request.Function = MPI2_FUNCTION_CONFIG;1050 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1051 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;1052 mpi_request.Header.PageNumber = 8;1053 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION;1054 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1055 r = _config_request(ioc, &mpi_request, mpi_reply,1056 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1057 if (r)1058 goto out;1059 1060 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1061 r = _config_request(ioc, &mpi_request, mpi_reply,1062 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1063 sizeof(*config_page));1064 out:1065 return r;1066}1067 1068/**1069 * mpt3sas_config_get_ioc_pg8 - obtain ioc page 81070 * @ioc: per adapter object1071 * @mpi_reply: reply mf payload returned from firmware1072 * @config_page: contents of the config page1073 * Context: sleep.1074 *1075 * Return: 0 for success, non-zero for failure.1076 */1077int1078mpt3sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER *ioc,1079 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page)1080{1081 Mpi2ConfigRequest_t mpi_request;1082 int r;1083 1084 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1085 mpi_request.Function = MPI2_FUNCTION_CONFIG;1086 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1087 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;1088 mpi_request.Header.PageNumber = 8;1089 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;1090 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1091 r = _config_request(ioc, &mpi_request, mpi_reply,1092 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1093 if (r)1094 goto out;1095 1096 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1097 r = _config_request(ioc, &mpi_request, mpi_reply,1098 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1099 sizeof(*config_page));1100 out:1101 return r;1102}1103/**1104 * mpt3sas_config_get_ioc_pg1 - obtain ioc page 11105 * @ioc: per adapter object1106 * @mpi_reply: reply mf payload returned from firmware1107 * @config_page: contents of the config page1108 * Context: sleep.1109 *1110 * Return: 0 for success, non-zero for failure.1111 */1112int1113mpt3sas_config_get_ioc_pg1(struct MPT3SAS_ADAPTER *ioc,1114 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page)1115{1116 Mpi2ConfigRequest_t mpi_request;1117 int r;1118 1119 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1120 mpi_request.Function = MPI2_FUNCTION_CONFIG;1121 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1122 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;1123 mpi_request.Header.PageNumber = 1;1124 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;1125 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1126 r = _config_request(ioc, &mpi_request, mpi_reply,1127 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1128 if (r)1129 goto out;1130 1131 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1132 r = _config_request(ioc, &mpi_request, mpi_reply,1133 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1134 sizeof(*config_page));1135 out:1136 return r;1137}1138 1139/**1140 * mpt3sas_config_set_ioc_pg1 - modify ioc page 11141 * @ioc: per adapter object1142 * @mpi_reply: reply mf payload returned from firmware1143 * @config_page: contents of the config page1144 * Context: sleep.1145 *1146 * Return: 0 for success, non-zero for failure.1147 */1148int1149mpt3sas_config_set_ioc_pg1(struct MPT3SAS_ADAPTER *ioc,1150 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page)1151{1152 Mpi2ConfigRequest_t mpi_request;1153 int r;1154 1155 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1156 mpi_request.Function = MPI2_FUNCTION_CONFIG;1157 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1158 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;1159 mpi_request.Header.PageNumber = 1;1160 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;1161 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1162 r = _config_request(ioc, &mpi_request, mpi_reply,1163 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1164 if (r)1165 goto out;1166 1167 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;1168 r = _config_request(ioc, &mpi_request, mpi_reply,1169 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1170 sizeof(*config_page));1171 out:1172 return r;1173}1174 1175/**1176 * mpt3sas_config_get_sas_device_pg0 - obtain sas device page 01177 * @ioc: per adapter object1178 * @mpi_reply: reply mf payload returned from firmware1179 * @config_page: contents of the config page1180 * @form: GET_NEXT_HANDLE or HANDLE1181 * @handle: device handle1182 * Context: sleep.1183 *1184 * Return: 0 for success, non-zero for failure.1185 */1186int1187mpt3sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc,1188 Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage0_t *config_page,1189 u32 form, u32 handle)1190{1191 Mpi2ConfigRequest_t mpi_request;1192 int r;1193 1194 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1195 mpi_request.Function = MPI2_FUNCTION_CONFIG;1196 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1197 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1198 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;1199 mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;1200 mpi_request.Header.PageNumber = 0;1201 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1202 r = _config_request(ioc, &mpi_request, mpi_reply,1203 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1204 if (r)1205 goto out;1206 1207 mpi_request.PageAddress = cpu_to_le32(form | handle);1208 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1209 r = _config_request(ioc, &mpi_request, mpi_reply,1210 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1211 sizeof(*config_page));1212 out:1213 return r;1214}1215 1216/**1217 * mpt3sas_config_get_sas_device_pg1 - obtain sas device page 11218 * @ioc: per adapter object1219 * @mpi_reply: reply mf payload returned from firmware1220 * @config_page: contents of the config page1221 * @form: GET_NEXT_HANDLE or HANDLE1222 * @handle: device handle1223 * Context: sleep.1224 *1225 * Return: 0 for success, non-zero for failure.1226 */1227int1228mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc,1229 Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page,1230 u32 form, u32 handle)1231{1232 Mpi2ConfigRequest_t mpi_request;1233 int r;1234 1235 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1236 mpi_request.Function = MPI2_FUNCTION_CONFIG;1237 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1238 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1239 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;1240 mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION;1241 mpi_request.Header.PageNumber = 1;1242 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1243 r = _config_request(ioc, &mpi_request, mpi_reply,1244 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1245 if (r)1246 goto out;1247 1248 mpi_request.PageAddress = cpu_to_le32(form | handle);1249 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1250 r = _config_request(ioc, &mpi_request, mpi_reply,1251 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1252 sizeof(*config_page));1253 out:1254 return r;1255}1256 1257/**1258 * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 01259 * @ioc: per adapter object1260 * @mpi_reply: reply mf payload returned from firmware1261 * @config_page: contents of the config page1262 * @form: GET_NEXT_HANDLE or HANDLE1263 * @handle: device handle1264 * Context: sleep.1265 *1266 * Return: 0 for success, non-zero for failure.1267 */1268int1269mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,1270 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,1271 u32 form, u32 handle)1272{1273 Mpi2ConfigRequest_t mpi_request;1274 int r;1275 1276 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1277 mpi_request.Function = MPI2_FUNCTION_CONFIG;1278 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1279 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1280 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;1281 mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION;1282 mpi_request.Header.PageNumber = 0;1283 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1284 r = _config_request(ioc, &mpi_request, mpi_reply,1285 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1286 if (r)1287 goto out;1288 1289 mpi_request.PageAddress = cpu_to_le32(form | handle);1290 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1291 r = _config_request(ioc, &mpi_request, mpi_reply,1292 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1293 sizeof(*config_page));1294out:1295 return r;1296}1297 1298/**1299 * mpt3sas_config_get_pcie_iounit_pg1 - obtain pcie iounit page 11300 * @ioc: per adapter object1301 * @mpi_reply: reply mf payload returned from firmware1302 * @config_page: contents of the config page1303 * @sz: size of buffer passed in config_page1304 * Context: sleep.1305 *1306 * Returns 0 for success, non-zero for failure.1307 */1308int1309mpt3sas_config_get_pcie_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,1310 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeIOUnitPage1_t *config_page,1311 u16 sz)1312{1313 Mpi2ConfigRequest_t mpi_request;1314 int r;1315 1316 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1317 mpi_request.Function = MPI2_FUNCTION_CONFIG;1318 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1319 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1320 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT;1321 mpi_request.Header.PageVersion = MPI26_PCIEIOUNITPAGE1_PAGEVERSION;1322 mpi_request.Header.PageNumber = 1;1323 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1324 r = _config_request(ioc, &mpi_request, mpi_reply,1325 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1326 if (r)1327 goto out;1328 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1329 r = _config_request(ioc, &mpi_request, mpi_reply,1330 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);1331out:1332 return r;1333}1334 1335/**1336 * mpt3sas_config_get_pcie_device_pg2 - obtain pcie device page 21337 * @ioc: per adapter object1338 * @mpi_reply: reply mf payload returned from firmware1339 * @config_page: contents of the config page1340 * @form: GET_NEXT_HANDLE or HANDLE1341 * @handle: device handle1342 * Context: sleep.1343 *1344 * Return: 0 for success, non-zero for failure.1345 */1346int1347mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc,1348 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page,1349 u32 form, u32 handle)1350{1351 Mpi2ConfigRequest_t mpi_request;1352 int r;1353 1354 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1355 mpi_request.Function = MPI2_FUNCTION_CONFIG;1356 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1357 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1358 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;1359 mpi_request.Header.PageVersion = MPI26_PCIEDEVICE2_PAGEVERSION;1360 mpi_request.Header.PageNumber = 2;1361 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1362 r = _config_request(ioc, &mpi_request, mpi_reply,1363 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1364 if (r)1365 goto out;1366 1367 mpi_request.PageAddress = cpu_to_le32(form | handle);1368 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1369 r = _config_request(ioc, &mpi_request, mpi_reply,1370 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1371 sizeof(*config_page));1372out:1373 return r;1374}1375 1376/**1377 * mpt3sas_config_get_number_hba_phys - obtain number of phys on the host1378 * @ioc: per adapter object1379 * @num_phys: pointer returned with the number of phys1380 * Context: sleep.1381 *1382 * Return: 0 for success, non-zero for failure.1383 */1384int1385mpt3sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER *ioc, u8 *num_phys)1386{1387 Mpi2ConfigRequest_t mpi_request;1388 int r;1389 u16 ioc_status;1390 Mpi2ConfigReply_t mpi_reply;1391 Mpi2SasIOUnitPage0_t config_page;1392 1393 *num_phys = 0;1394 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1395 mpi_request.Function = MPI2_FUNCTION_CONFIG;1396 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1397 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1398 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;1399 mpi_request.Header.PageNumber = 0;1400 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;1401 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1402 r = _config_request(ioc, &mpi_request, &mpi_reply,1403 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1404 if (r)1405 goto out;1406 1407 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1408 r = _config_request(ioc, &mpi_request, &mpi_reply,1409 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,1410 sizeof(Mpi2SasIOUnitPage0_t));1411 if (!r) {1412 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &1413 MPI2_IOCSTATUS_MASK;1414 if (ioc_status == MPI2_IOCSTATUS_SUCCESS)1415 *num_phys = config_page.NumPhys;1416 }1417 out:1418 return r;1419}1420 1421/**1422 * mpt3sas_config_get_sas_iounit_pg0 - obtain sas iounit page 01423 * @ioc: per adapter object1424 * @mpi_reply: reply mf payload returned from firmware1425 * @config_page: contents of the config page1426 * @sz: size of buffer passed in config_page1427 * Context: sleep.1428 *1429 * Calling function should call config_get_number_hba_phys prior to1430 * this function, so enough memory is allocated for config_page.1431 *1432 * Return: 0 for success, non-zero for failure.1433 */1434int1435mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,1436 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page,1437 u16 sz)1438{1439 Mpi2ConfigRequest_t mpi_request;1440 int r;1441 1442 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1443 mpi_request.Function = MPI2_FUNCTION_CONFIG;1444 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1445 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1446 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;1447 mpi_request.Header.PageNumber = 0;1448 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;1449 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1450 r = _config_request(ioc, &mpi_request, mpi_reply,1451 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1452 if (r)1453 goto out;1454 1455 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1456 r = _config_request(ioc, &mpi_request, mpi_reply,1457 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);1458 out:1459 return r;1460}1461 1462/**1463 * mpt3sas_config_get_sas_iounit_pg1 - obtain sas iounit page 11464 * @ioc: per adapter object1465 * @mpi_reply: reply mf payload returned from firmware1466 * @config_page: contents of the config page1467 * @sz: size of buffer passed in config_page1468 * Context: sleep.1469 *1470 * Calling function should call config_get_number_hba_phys prior to1471 * this function, so enough memory is allocated for config_page.1472 *1473 * Return: 0 for success, non-zero for failure.1474 */1475int1476mpt3sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,1477 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,1478 u16 sz)1479{1480 Mpi2ConfigRequest_t mpi_request;1481 int r;1482 1483 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1484 mpi_request.Function = MPI2_FUNCTION_CONFIG;1485 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1486 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1487 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;1488 mpi_request.Header.PageNumber = 1;1489 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;1490 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1491 r = _config_request(ioc, &mpi_request, mpi_reply,1492 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1493 if (r)1494 goto out;1495 1496 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1497 r = _config_request(ioc, &mpi_request, mpi_reply,1498 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);1499 out:1500 return r;1501}1502 1503/**1504 * mpt3sas_config_set_sas_iounit_pg1 - send sas iounit page 11505 * @ioc: per adapter object1506 * @mpi_reply: reply mf payload returned from firmware1507 * @config_page: contents of the config page1508 * @sz: size of buffer passed in config_page1509 * Context: sleep.1510 *1511 * Calling function should call config_get_number_hba_phys prior to1512 * this function, so enough memory is allocated for config_page.1513 *1514 * Return: 0 for success, non-zero for failure.1515 */1516int1517mpt3sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,1518 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,1519 u16 sz)1520{1521 Mpi2ConfigRequest_t mpi_request;1522 int r;1523 1524 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1525 mpi_request.Function = MPI2_FUNCTION_CONFIG;1526 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1527 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1528 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;1529 mpi_request.Header.PageNumber = 1;1530 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;1531 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1532 r = _config_request(ioc, &mpi_request, mpi_reply,1533 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1534 if (r)1535 goto out;1536 1537 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;1538 _config_request(ioc, &mpi_request, mpi_reply,1539 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);1540 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;1541 r = _config_request(ioc, &mpi_request, mpi_reply,1542 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);1543 out:1544 return r;1545}1546 1547/**1548 * mpt3sas_config_get_expander_pg0 - obtain expander page 01549 * @ioc: per adapter object1550 * @mpi_reply: reply mf payload returned from firmware1551 * @config_page: contents of the config page1552 * @form: GET_NEXT_HANDLE or HANDLE1553 * @handle: expander handle1554 * Context: sleep.1555 *1556 * Return: 0 for success, non-zero for failure.1557 */1558int1559mpt3sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t1560 *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle)1561{1562 Mpi2ConfigRequest_t mpi_request;1563 int r;1564 1565 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1566 mpi_request.Function = MPI2_FUNCTION_CONFIG;1567 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1568 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1569 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;1570 mpi_request.Header.PageNumber = 0;1571 mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION;1572 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1573 r = _config_request(ioc, &mpi_request, mpi_reply,1574 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1575 if (r)1576 goto out;1577 1578 mpi_request.PageAddress = cpu_to_le32(form | handle);1579 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1580 r = _config_request(ioc, &mpi_request, mpi_reply,1581 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1582 sizeof(*config_page));1583 out:1584 return r;1585}1586 1587/**1588 * mpt3sas_config_get_expander_pg1 - obtain expander page 11589 * @ioc: per adapter object1590 * @mpi_reply: reply mf payload returned from firmware1591 * @config_page: contents of the config page1592 * @phy_number: phy number1593 * @handle: expander handle1594 * Context: sleep.1595 *1596 * Return: 0 for success, non-zero for failure.1597 */1598int1599mpt3sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t1600 *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number,1601 u16 handle)1602{1603 Mpi2ConfigRequest_t mpi_request;1604 int r;1605 1606 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1607 mpi_request.Function = MPI2_FUNCTION_CONFIG;1608 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1609 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1610 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;1611 mpi_request.Header.PageNumber = 1;1612 mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION;1613 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1614 r = _config_request(ioc, &mpi_request, mpi_reply,1615 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1616 if (r)1617 goto out;1618 1619 mpi_request.PageAddress =1620 cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |1621 (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle);1622 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1623 r = _config_request(ioc, &mpi_request, mpi_reply,1624 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1625 sizeof(*config_page));1626 out:1627 return r;1628}1629 1630/**1631 * mpt3sas_config_get_enclosure_pg0 - obtain enclosure page 01632 * @ioc: per adapter object1633 * @mpi_reply: reply mf payload returned from firmware1634 * @config_page: contents of the config page1635 * @form: GET_NEXT_HANDLE or HANDLE1636 * @handle: expander handle1637 * Context: sleep.1638 *1639 * Return: 0 for success, non-zero for failure.1640 */1641int1642mpt3sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t1643 *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle)1644{1645 Mpi2ConfigRequest_t mpi_request;1646 int r;1647 1648 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1649 mpi_request.Function = MPI2_FUNCTION_CONFIG;1650 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1651 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1652 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE;1653 mpi_request.Header.PageNumber = 0;1654 mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION;1655 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1656 r = _config_request(ioc, &mpi_request, mpi_reply,1657 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1658 if (r)1659 goto out;1660 1661 mpi_request.PageAddress = cpu_to_le32(form | handle);1662 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1663 r = _config_request(ioc, &mpi_request, mpi_reply,1664 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1665 sizeof(*config_page));1666 out:1667 return r;1668}1669 1670/**1671 * mpt3sas_config_get_phy_pg0 - obtain phy page 01672 * @ioc: per adapter object1673 * @mpi_reply: reply mf payload returned from firmware1674 * @config_page: contents of the config page1675 * @phy_number: phy number1676 * Context: sleep.1677 *1678 * Return: 0 for success, non-zero for failure.1679 */1680int1681mpt3sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t1682 *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number)1683{1684 Mpi2ConfigRequest_t mpi_request;1685 int r;1686 1687 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1688 mpi_request.Function = MPI2_FUNCTION_CONFIG;1689 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1690 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1691 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;1692 mpi_request.Header.PageNumber = 0;1693 mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION;1694 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1695 r = _config_request(ioc, &mpi_request, mpi_reply,1696 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1697 if (r)1698 goto out;1699 1700 mpi_request.PageAddress =1701 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);1702 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1703 r = _config_request(ioc, &mpi_request, mpi_reply,1704 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1705 sizeof(*config_page));1706 out:1707 return r;1708}1709 1710/**1711 * mpt3sas_config_get_phy_pg1 - obtain phy page 11712 * @ioc: per adapter object1713 * @mpi_reply: reply mf payload returned from firmware1714 * @config_page: contents of the config page1715 * @phy_number: phy number1716 * Context: sleep.1717 *1718 * Return: 0 for success, non-zero for failure.1719 */1720int1721mpt3sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t1722 *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number)1723{1724 Mpi2ConfigRequest_t mpi_request;1725 int r;1726 1727 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1728 mpi_request.Function = MPI2_FUNCTION_CONFIG;1729 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1730 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1731 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;1732 mpi_request.Header.PageNumber = 1;1733 mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION;1734 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1735 r = _config_request(ioc, &mpi_request, mpi_reply,1736 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1737 if (r)1738 goto out;1739 1740 mpi_request.PageAddress =1741 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);1742 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1743 r = _config_request(ioc, &mpi_request, mpi_reply,1744 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1745 sizeof(*config_page));1746 out:1747 return r;1748}1749 1750/**1751 * mpt3sas_config_get_raid_volume_pg1 - obtain raid volume page 11752 * @ioc: per adapter object1753 * @mpi_reply: reply mf payload returned from firmware1754 * @config_page: contents of the config page1755 * @form: GET_NEXT_HANDLE or HANDLE1756 * @handle: volume handle1757 * Context: sleep.1758 *1759 * Return: 0 for success, non-zero for failure.1760 */1761int1762mpt3sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER *ioc,1763 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form,1764 u32 handle)1765{1766 Mpi2ConfigRequest_t mpi_request;1767 int r;1768 1769 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1770 mpi_request.Function = MPI2_FUNCTION_CONFIG;1771 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1772 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;1773 mpi_request.Header.PageNumber = 1;1774 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;1775 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1776 r = _config_request(ioc, &mpi_request, mpi_reply,1777 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1778 if (r)1779 goto out;1780 1781 mpi_request.PageAddress = cpu_to_le32(form | handle);1782 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1783 r = _config_request(ioc, &mpi_request, mpi_reply,1784 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1785 sizeof(*config_page));1786 out:1787 return r;1788}1789 1790/**1791 * mpt3sas_config_get_number_pds - obtain number of phys disk assigned to volume1792 * @ioc: per adapter object1793 * @handle: volume handle1794 * @num_pds: returns pds count1795 * Context: sleep.1796 *1797 * Return: 0 for success, non-zero for failure.1798 */1799int1800mpt3sas_config_get_number_pds(struct MPT3SAS_ADAPTER *ioc, u16 handle,1801 u8 *num_pds)1802{1803 Mpi2ConfigRequest_t mpi_request;1804 Mpi2RaidVolPage0_t config_page;1805 Mpi2ConfigReply_t mpi_reply;1806 int r;1807 u16 ioc_status;1808 1809 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1810 *num_pds = 0;1811 mpi_request.Function = MPI2_FUNCTION_CONFIG;1812 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1813 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;1814 mpi_request.Header.PageNumber = 0;1815 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;1816 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1817 r = _config_request(ioc, &mpi_request, &mpi_reply,1818 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1819 if (r)1820 goto out;1821 1822 mpi_request.PageAddress =1823 cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle);1824 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1825 r = _config_request(ioc, &mpi_request, &mpi_reply,1826 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,1827 sizeof(Mpi2RaidVolPage0_t));1828 if (!r) {1829 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &1830 MPI2_IOCSTATUS_MASK;1831 if (ioc_status == MPI2_IOCSTATUS_SUCCESS)1832 *num_pds = config_page.NumPhysDisks;1833 }1834 1835 out:1836 return r;1837}1838 1839/**1840 * mpt3sas_config_get_raid_volume_pg0 - obtain raid volume page 01841 * @ioc: per adapter object1842 * @mpi_reply: reply mf payload returned from firmware1843 * @config_page: contents of the config page1844 * @form: GET_NEXT_HANDLE or HANDLE1845 * @handle: volume handle1846 * @sz: size of buffer passed in config_page1847 * Context: sleep.1848 *1849 * Return: 0 for success, non-zero for failure.1850 */1851int1852mpt3sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER *ioc,1853 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form,1854 u32 handle, u16 sz)1855{1856 Mpi2ConfigRequest_t mpi_request;1857 int r;1858 1859 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1860 mpi_request.Function = MPI2_FUNCTION_CONFIG;1861 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1862 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;1863 mpi_request.Header.PageNumber = 0;1864 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;1865 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1866 r = _config_request(ioc, &mpi_request, mpi_reply,1867 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1868 if (r)1869 goto out;1870 1871 mpi_request.PageAddress = cpu_to_le32(form | handle);1872 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1873 r = _config_request(ioc, &mpi_request, mpi_reply,1874 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);1875 out:1876 return r;1877}1878 1879/**1880 * mpt3sas_config_get_phys_disk_pg0 - obtain phys disk page 01881 * @ioc: per adapter object1882 * @mpi_reply: reply mf payload returned from firmware1883 * @config_page: contents of the config page1884 * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE1885 * @form_specific: specific to the form1886 * Context: sleep.1887 *1888 * Return: 0 for success, non-zero for failure.1889 */1890int1891mpt3sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t1892 *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form,1893 u32 form_specific)1894{1895 Mpi2ConfigRequest_t mpi_request;1896 int r;1897 1898 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1899 mpi_request.Function = MPI2_FUNCTION_CONFIG;1900 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1901 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;1902 mpi_request.Header.PageNumber = 0;1903 mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION;1904 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1905 r = _config_request(ioc, &mpi_request, mpi_reply,1906 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1907 if (r)1908 goto out;1909 1910 mpi_request.PageAddress = cpu_to_le32(form | form_specific);1911 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1912 r = _config_request(ioc, &mpi_request, mpi_reply,1913 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1914 sizeof(*config_page));1915 out:1916 return r;1917}1918 1919/**1920 * mpt3sas_config_get_driver_trigger_pg0 - obtain driver trigger page 01921 * @ioc: per adapter object1922 * @mpi_reply: reply mf payload returned from firmware1923 * @config_page: contents of the config page1924 * Context: sleep.1925 *1926 * Returns 0 for success, non-zero for failure.1927 */1928int1929mpt3sas_config_get_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,1930 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)1931{1932 Mpi2ConfigRequest_t mpi_request;1933 int r;1934 1935 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1936 mpi_request.Function = MPI2_FUNCTION_CONFIG;1937 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1938 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1939 mpi_request.ExtPageType =1940 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;1941 mpi_request.Header.PageNumber = 0;1942 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;1943 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1944 r = _config_request(ioc, &mpi_request, mpi_reply,1945 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1946 if (r)1947 goto out;1948 1949 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1950 r = _config_request(ioc, &mpi_request, mpi_reply,1951 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1952 sizeof(*config_page));1953 out:1954 return r;1955}1956 1957/**1958 * _config_set_driver_trigger_pg0 - write driver trigger page 01959 * @ioc: per adapter object1960 * @mpi_reply: reply mf payload returned from firmware1961 * @config_page: contents of the config page1962 * Context: sleep.1963 *1964 * Returns 0 for success, non-zero for failure.1965 */1966static int1967_config_set_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,1968 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)1969{1970 Mpi2ConfigRequest_t mpi_request;1971 int r;1972 1973 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1974 mpi_request.Function = MPI2_FUNCTION_CONFIG;1975 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1976 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1977 mpi_request.ExtPageType =1978 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;1979 mpi_request.Header.PageNumber = 0;1980 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;1981 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1982 r = _config_request(ioc, &mpi_request, mpi_reply,1983 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1984 if (r)1985 goto out;1986 1987 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;1988 _config_request(ioc, &mpi_request, mpi_reply,1989 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1990 sizeof(*config_page));1991 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;1992 r = _config_request(ioc, &mpi_request, mpi_reply,1993 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1994 sizeof(*config_page));1995 out:1996 return r;1997}1998 1999/**2000 * mpt3sas_config_update_driver_trigger_pg0 - update driver trigger page 02001 * @ioc: per adapter object2002 * @trigger_flag: trigger type bit map2003 * @set: set ot clear trigger values2004 * Context: sleep.2005 *2006 * Returns 0 for success, non-zero for failure.2007 */2008static int2009mpt3sas_config_update_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,2010 u16 trigger_flag, bool set)2011{2012 Mpi26DriverTriggerPage0_t tg_pg0;2013 Mpi2ConfigReply_t mpi_reply;2014 int rc;2015 u16 flags, ioc_status;2016 2017 rc = mpt3sas_config_get_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);2018 if (rc)2019 return rc;2020 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2021 MPI2_IOCSTATUS_MASK;2022 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {2023 dcprintk(ioc,2024 ioc_err(ioc,2025 "%s: Failed to get trigger pg0, ioc_status(0x%04x)\n",2026 __func__, ioc_status));2027 return -EFAULT;2028 }2029 2030 if (set)2031 flags = le16_to_cpu(tg_pg0.TriggerFlags) | trigger_flag;2032 else2033 flags = le16_to_cpu(tg_pg0.TriggerFlags) & ~trigger_flag;2034 2035 tg_pg0.TriggerFlags = cpu_to_le16(flags);2036 2037 rc = _config_set_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);2038 if (rc)2039 return rc;2040 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2041 MPI2_IOCSTATUS_MASK;2042 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {2043 dcprintk(ioc,2044 ioc_err(ioc,2045 "%s: Failed to update trigger pg0, ioc_status(0x%04x)\n",2046 __func__, ioc_status));2047 return -EFAULT;2048 }2049 2050 return 0;2051}2052 2053/**2054 * mpt3sas_config_get_driver_trigger_pg1 - obtain driver trigger page 12055 * @ioc: per adapter object2056 * @mpi_reply: reply mf payload returned from firmware2057 * @config_page: contents of the config page2058 * Context: sleep.2059 *2060 * Returns 0 for success, non-zero for failure.2061 */2062int2063mpt3sas_config_get_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,2064 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page)2065{2066 Mpi2ConfigRequest_t mpi_request;2067 int r;2068 2069 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));2070 mpi_request.Function = MPI2_FUNCTION_CONFIG;2071 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;2072 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;2073 mpi_request.ExtPageType =2074 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;2075 mpi_request.Header.PageNumber = 1;2076 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION;2077 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);2078 r = _config_request(ioc, &mpi_request, mpi_reply,2079 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);2080 if (r)2081 goto out;2082 2083 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;2084 r = _config_request(ioc, &mpi_request, mpi_reply,2085 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2086 sizeof(*config_page));2087 out:2088 return r;2089}2090 2091/**2092 * _config_set_driver_trigger_pg1 - write driver trigger page 12093 * @ioc: per adapter object2094 * @mpi_reply: reply mf payload returned from firmware2095 * @config_page: contents of the config page2096 * Context: sleep.2097 *2098 * Returns 0 for success, non-zero for failure.2099 */2100static int2101_config_set_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,2102 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page)2103{2104 Mpi2ConfigRequest_t mpi_request;2105 int r;2106 2107 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));2108 mpi_request.Function = MPI2_FUNCTION_CONFIG;2109 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;2110 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;2111 mpi_request.ExtPageType =2112 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;2113 mpi_request.Header.PageNumber = 1;2114 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION;2115 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);2116 r = _config_request(ioc, &mpi_request, mpi_reply,2117 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);2118 if (r)2119 goto out;2120 2121 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;2122 _config_request(ioc, &mpi_request, mpi_reply,2123 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2124 sizeof(*config_page));2125 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;2126 r = _config_request(ioc, &mpi_request, mpi_reply,2127 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2128 sizeof(*config_page));2129 out:2130 return r;2131}2132 2133/**2134 * mpt3sas_config_update_driver_trigger_pg1 - update driver trigger page 12135 * @ioc: per adapter object2136 * @master_tg: Master trigger bit map2137 * @set: set ot clear trigger values2138 * Context: sleep.2139 *2140 * Returns 0 for success, non-zero for failure.2141 */2142int2143mpt3sas_config_update_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,2144 struct SL_WH_MASTER_TRIGGER_T *master_tg, bool set)2145{2146 Mpi26DriverTriggerPage1_t tg_pg1;2147 Mpi2ConfigReply_t mpi_reply;2148 int rc;2149 u16 ioc_status;2150 2151 rc = mpt3sas_config_update_driver_trigger_pg0(ioc,2152 MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, set);2153 if (rc)2154 return rc;2155 2156 rc = mpt3sas_config_get_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1);2157 if (rc)2158 goto out;2159 2160 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2161 MPI2_IOCSTATUS_MASK;2162 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {2163 dcprintk(ioc,2164 ioc_err(ioc,2165 "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n",2166 __func__, ioc_status));2167 rc = -EFAULT;2168 goto out;2169 }2170 2171 if (set) {2172 tg_pg1.NumMasterTrigger = cpu_to_le16(1);2173 tg_pg1.MasterTriggers[0].MasterTriggerFlags = cpu_to_le32(2174 master_tg->MasterData);2175 } else {2176 tg_pg1.NumMasterTrigger = 0;2177 tg_pg1.MasterTriggers[0].MasterTriggerFlags = 0;2178 }2179 2180 rc = _config_set_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1);2181 if (rc)2182 goto out;2183 2184 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2185 MPI2_IOCSTATUS_MASK;2186 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {2187 dcprintk(ioc,2188 ioc_err(ioc,2189 "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n",2190 __func__, ioc_status));2191 rc = -EFAULT;2192 goto out;2193 }2194 2195 return 0;2196 2197out:2198 mpt3sas_config_update_driver_trigger_pg0(ioc,2199 MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, !set);2200 2201 return rc;2202}2203 2204/**2205 * mpt3sas_config_get_driver_trigger_pg2 - obtain driver trigger page 22206 * @ioc: per adapter object2207 * @mpi_reply: reply mf payload returned from firmware2208 * @config_page: contents of the config page2209 * Context: sleep.2210 *2211 * Returns 0 for success, non-zero for failure.2212 */2213int2214mpt3sas_config_get_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,2215 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page)2216{2217 Mpi2ConfigRequest_t mpi_request;2218 int r;2219 2220 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));2221 mpi_request.Function = MPI2_FUNCTION_CONFIG;2222 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;2223 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;2224 mpi_request.ExtPageType =2225 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;2226 mpi_request.Header.PageNumber = 2;2227 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION;2228 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);2229 r = _config_request(ioc, &mpi_request, mpi_reply,2230 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);2231 if (r)2232 goto out;2233 2234 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;2235 r = _config_request(ioc, &mpi_request, mpi_reply,2236 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2237 sizeof(*config_page));2238 out:2239 return r;2240}2241 2242/**2243 * _config_set_driver_trigger_pg2 - write driver trigger page 22244 * @ioc: per adapter object2245 * @mpi_reply: reply mf payload returned from firmware2246 * @config_page: contents of the config page2247 * Context: sleep.2248 *2249 * Returns 0 for success, non-zero for failure.2250 */2251static int2252_config_set_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,2253 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page)2254{2255 Mpi2ConfigRequest_t mpi_request;2256 int r;2257 2258 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));2259 mpi_request.Function = MPI2_FUNCTION_CONFIG;2260 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;2261 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;2262 mpi_request.ExtPageType =2263 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;2264 mpi_request.Header.PageNumber = 2;2265 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION;2266 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);2267 r = _config_request(ioc, &mpi_request, mpi_reply,2268 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);2269 if (r)2270 goto out;2271 2272 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;2273 _config_request(ioc, &mpi_request, mpi_reply,2274 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2275 sizeof(*config_page));2276 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;2277 r = _config_request(ioc, &mpi_request, mpi_reply,2278 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2279 sizeof(*config_page));2280 out:2281 return r;2282}2283 2284/**2285 * mpt3sas_config_update_driver_trigger_pg2 - update driver trigger page 22286 * @ioc: per adapter object2287 * @event_tg: list of Event Triggers2288 * @set: set ot clear trigger values2289 * Context: sleep.2290 *2291 * Returns 0 for success, non-zero for failure.2292 */2293int2294mpt3sas_config_update_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,2295 struct SL_WH_EVENT_TRIGGERS_T *event_tg, bool set)2296{2297 Mpi26DriverTriggerPage2_t tg_pg2;2298 Mpi2ConfigReply_t mpi_reply;2299 int rc, i, count;2300 u16 ioc_status;2301 2302 rc = mpt3sas_config_update_driver_trigger_pg0(ioc,2303 MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, set);2304 if (rc)2305 return rc;2306 2307 rc = mpt3sas_config_get_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2);2308 if (rc)2309 goto out;2310 2311 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2312 MPI2_IOCSTATUS_MASK;2313 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {2314 dcprintk(ioc,2315 ioc_err(ioc,2316 "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n",2317 __func__, ioc_status));2318 rc = -EFAULT;2319 goto out;2320 }2321 2322 if (set) {2323 count = event_tg->ValidEntries;2324 tg_pg2.NumMPIEventTrigger = cpu_to_le16(count);2325 for (i = 0; i < count; i++) {2326 tg_pg2.MPIEventTriggers[i].MPIEventCode =2327 cpu_to_le16(2328 event_tg->EventTriggerEntry[i].EventValue);2329 tg_pg2.MPIEventTriggers[i].MPIEventCodeSpecific =2330 cpu_to_le16(2331 event_tg->EventTriggerEntry[i].LogEntryQualifier);2332 }2333 } else {2334 tg_pg2.NumMPIEventTrigger = 0;2335 memset(&tg_pg2.MPIEventTriggers[0], 0,2336 NUM_VALID_ENTRIES * sizeof(2337 MPI26_DRIVER_MPI_EVENT_TRIGGER_ENTRY));2338 }2339 2340 rc = _config_set_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2);2341 if (rc)2342 goto out;2343 2344 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2345 MPI2_IOCSTATUS_MASK;2346 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {2347 dcprintk(ioc,2348 ioc_err(ioc,2349 "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n",2350 __func__, ioc_status));2351 rc = -EFAULT;2352 goto out;2353 }2354 2355 return 0;2356 2357out:2358 mpt3sas_config_update_driver_trigger_pg0(ioc,2359 MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, !set);2360 2361 return rc;2362}2363 2364/**2365 * mpt3sas_config_get_driver_trigger_pg3 - obtain driver trigger page 32366 * @ioc: per adapter object2367 * @mpi_reply: reply mf payload returned from firmware2368 * @config_page: contents of the config page2369 * Context: sleep.2370 *2371 * Returns 0 for success, non-zero for failure.2372 */2373int2374mpt3sas_config_get_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,2375 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page)2376{2377 Mpi2ConfigRequest_t mpi_request;2378 int r;2379 2380 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));2381 mpi_request.Function = MPI2_FUNCTION_CONFIG;2382 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;2383 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;2384 mpi_request.ExtPageType =2385 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;2386 mpi_request.Header.PageNumber = 3;2387 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION;2388 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);2389 r = _config_request(ioc, &mpi_request, mpi_reply,2390 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);2391 if (r)2392 goto out;2393 2394 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;2395 r = _config_request(ioc, &mpi_request, mpi_reply,2396 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2397 sizeof(*config_page));2398 out:2399 return r;2400}2401 2402/**2403 * _config_set_driver_trigger_pg3 - write driver trigger page 32404 * @ioc: per adapter object2405 * @mpi_reply: reply mf payload returned from firmware2406 * @config_page: contents of the config page2407 * Context: sleep.2408 *2409 * Returns 0 for success, non-zero for failure.2410 */2411static int2412_config_set_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,2413 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page)2414{2415 Mpi2ConfigRequest_t mpi_request;2416 int r;2417 2418 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));2419 mpi_request.Function = MPI2_FUNCTION_CONFIG;2420 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;2421 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;2422 mpi_request.ExtPageType =2423 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;2424 mpi_request.Header.PageNumber = 3;2425 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION;2426 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);2427 r = _config_request(ioc, &mpi_request, mpi_reply,2428 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);2429 if (r)2430 goto out;2431 2432 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;2433 _config_request(ioc, &mpi_request, mpi_reply,2434 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2435 sizeof(*config_page));2436 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;2437 r = _config_request(ioc, &mpi_request, mpi_reply,2438 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2439 sizeof(*config_page));2440 out:2441 return r;2442}2443 2444/**2445 * mpt3sas_config_update_driver_trigger_pg3 - update driver trigger page 32446 * @ioc: per adapter object2447 * @scsi_tg: scsi trigger list2448 * @set: set ot clear trigger values2449 * Context: sleep.2450 *2451 * Returns 0 for success, non-zero for failure.2452 */2453int2454mpt3sas_config_update_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,2455 struct SL_WH_SCSI_TRIGGERS_T *scsi_tg, bool set)2456{2457 Mpi26DriverTriggerPage3_t tg_pg3;2458 Mpi2ConfigReply_t mpi_reply;2459 int rc, i, count;2460 u16 ioc_status;2461 2462 rc = mpt3sas_config_update_driver_trigger_pg0(ioc,2463 MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, set);2464 if (rc)2465 return rc;2466 2467 rc = mpt3sas_config_get_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3);2468 if (rc)2469 goto out;2470 2471 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2472 MPI2_IOCSTATUS_MASK;2473 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {2474 dcprintk(ioc,2475 ioc_err(ioc,2476 "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n",2477 __func__, ioc_status));2478 return -EFAULT;2479 }2480 2481 if (set) {2482 count = scsi_tg->ValidEntries;2483 tg_pg3.NumSCSISenseTrigger = cpu_to_le16(count);2484 for (i = 0; i < count; i++) {2485 tg_pg3.SCSISenseTriggers[i].ASCQ =2486 scsi_tg->SCSITriggerEntry[i].ASCQ;2487 tg_pg3.SCSISenseTriggers[i].ASC =2488 scsi_tg->SCSITriggerEntry[i].ASC;2489 tg_pg3.SCSISenseTriggers[i].SenseKey =2490 scsi_tg->SCSITriggerEntry[i].SenseKey;2491 }2492 } else {2493 tg_pg3.NumSCSISenseTrigger = 0;2494 memset(&tg_pg3.SCSISenseTriggers[0], 0,2495 NUM_VALID_ENTRIES * sizeof(2496 MPI26_DRIVER_SCSI_SENSE_TRIGGER_ENTRY));2497 }2498 2499 rc = _config_set_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3);2500 if (rc)2501 goto out;2502 2503 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2504 MPI2_IOCSTATUS_MASK;2505 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {2506 dcprintk(ioc,2507 ioc_err(ioc,2508 "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n",2509 __func__, ioc_status));2510 return -EFAULT;2511 }2512 2513 return 0;2514out:2515 mpt3sas_config_update_driver_trigger_pg0(ioc,2516 MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, !set);2517 2518 return rc;2519}2520 2521/**2522 * mpt3sas_config_get_driver_trigger_pg4 - obtain driver trigger page 42523 * @ioc: per adapter object2524 * @mpi_reply: reply mf payload returned from firmware2525 * @config_page: contents of the config page2526 * Context: sleep.2527 *2528 * Returns 0 for success, non-zero for failure.2529 */2530int2531mpt3sas_config_get_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,2532 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page)2533{2534 Mpi2ConfigRequest_t mpi_request;2535 int r;2536 2537 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));2538 mpi_request.Function = MPI2_FUNCTION_CONFIG;2539 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;2540 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;2541 mpi_request.ExtPageType =2542 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;2543 mpi_request.Header.PageNumber = 4;2544 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION;2545 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);2546 r = _config_request(ioc, &mpi_request, mpi_reply,2547 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);2548 if (r)2549 goto out;2550 2551 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;2552 r = _config_request(ioc, &mpi_request, mpi_reply,2553 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2554 sizeof(*config_page));2555 out:2556 return r;2557}2558 2559/**2560 * _config_set_driver_trigger_pg4 - write driver trigger page 42561 * @ioc: per adapter object2562 * @mpi_reply: reply mf payload returned from firmware2563 * @config_page: contents of the config page2564 * Context: sleep.2565 *2566 * Returns 0 for success, non-zero for failure.2567 */2568static int2569_config_set_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,2570 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page)2571{2572 Mpi2ConfigRequest_t mpi_request;2573 int r;2574 2575 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));2576 mpi_request.Function = MPI2_FUNCTION_CONFIG;2577 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;2578 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;2579 mpi_request.ExtPageType =2580 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;2581 mpi_request.Header.PageNumber = 4;2582 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION;2583 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);2584 r = _config_request(ioc, &mpi_request, mpi_reply,2585 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);2586 if (r)2587 goto out;2588 2589 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;2590 _config_request(ioc, &mpi_request, mpi_reply,2591 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2592 sizeof(*config_page));2593 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;2594 r = _config_request(ioc, &mpi_request, mpi_reply,2595 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2596 sizeof(*config_page));2597 out:2598 return r;2599}2600 2601/**2602 * mpt3sas_config_update_driver_trigger_pg4 - update driver trigger page 42603 * @ioc: per adapter object2604 * @mpi_tg: mpi trigger list2605 * @set: set ot clear trigger values2606 * Context: sleep.2607 *2608 * Returns 0 for success, non-zero for failure.2609 */2610int2611mpt3sas_config_update_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,2612 struct SL_WH_MPI_TRIGGERS_T *mpi_tg, bool set)2613{2614 Mpi26DriverTriggerPage4_t tg_pg4;2615 Mpi2ConfigReply_t mpi_reply;2616 int rc, i, count;2617 u16 ioc_status;2618 2619 rc = mpt3sas_config_update_driver_trigger_pg0(ioc,2620 MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, set);2621 if (rc)2622 return rc;2623 2624 rc = mpt3sas_config_get_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4);2625 if (rc)2626 goto out;2627 2628 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2629 MPI2_IOCSTATUS_MASK;2630 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {2631 dcprintk(ioc,2632 ioc_err(ioc,2633 "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n",2634 __func__, ioc_status));2635 rc = -EFAULT;2636 goto out;2637 }2638 2639 if (set) {2640 count = mpi_tg->ValidEntries;2641 tg_pg4.NumIOCStatusLogInfoTrigger = cpu_to_le16(count);2642 for (i = 0; i < count; i++) {2643 tg_pg4.IOCStatusLoginfoTriggers[i].IOCStatus =2644 cpu_to_le16(mpi_tg->MPITriggerEntry[i].IOCStatus);2645 tg_pg4.IOCStatusLoginfoTriggers[i].LogInfo =2646 cpu_to_le32(mpi_tg->MPITriggerEntry[i].IocLogInfo);2647 }2648 } else {2649 tg_pg4.NumIOCStatusLogInfoTrigger = 0;2650 memset(&tg_pg4.IOCStatusLoginfoTriggers[0], 0,2651 NUM_VALID_ENTRIES * sizeof(2652 MPI26_DRIVER_IOCSTATUS_LOGINFO_TRIGGER_ENTRY));2653 }2654 2655 rc = _config_set_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4);2656 if (rc)2657 goto out;2658 2659 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2660 MPI2_IOCSTATUS_MASK;2661 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {2662 dcprintk(ioc,2663 ioc_err(ioc,2664 "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n",2665 __func__, ioc_status));2666 rc = -EFAULT;2667 goto out;2668 }2669 2670 return 0;2671 2672out:2673 mpt3sas_config_update_driver_trigger_pg0(ioc,2674 MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, !set);2675 2676 return rc;2677}2678 2679/**2680 * mpt3sas_config_get_volume_handle - returns volume handle for give hidden2681 * raid components2682 * @ioc: per adapter object2683 * @pd_handle: phys disk handle2684 * @volume_handle: volume handle2685 * Context: sleep.2686 *2687 * Return: 0 for success, non-zero for failure.2688 */2689int2690mpt3sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle,2691 u16 *volume_handle)2692{2693 Mpi2RaidConfigurationPage0_t *config_page = NULL;2694 Mpi2ConfigRequest_t mpi_request;2695 Mpi2ConfigReply_t mpi_reply;2696 int r, i, config_page_sz;2697 u16 ioc_status;2698 int config_num;2699 u16 element_type;2700 u16 phys_disk_dev_handle;2701 2702 *volume_handle = 0;2703 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));2704 mpi_request.Function = MPI2_FUNCTION_CONFIG;2705 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;2706 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;2707 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG;2708 mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION;2709 mpi_request.Header.PageNumber = 0;2710 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);2711 r = _config_request(ioc, &mpi_request, &mpi_reply,2712 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);2713 if (r)2714 goto out;2715 2716 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;2717 config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4);2718 config_page = kmalloc(config_page_sz, GFP_KERNEL);2719 if (!config_page) {2720 r = -1;2721 goto out;2722 }2723 2724 config_num = 0xff;2725 while (1) {2726 mpi_request.PageAddress = cpu_to_le32(config_num +2727 MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM);2728 r = _config_request(ioc, &mpi_request, &mpi_reply,2729 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2730 config_page_sz);2731 if (r)2732 goto out;2733 r = -1;2734 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2735 MPI2_IOCSTATUS_MASK;2736 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)2737 goto out;2738 for (i = 0; i < config_page->NumElements; i++) {2739 element_type = le16_to_cpu(config_page->2740 ConfigElement[i].ElementFlags) &2741 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE;2742 if (element_type ==2743 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT ||2744 element_type ==2745 MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) {2746 phys_disk_dev_handle =2747 le16_to_cpu(config_page->ConfigElement[i].2748 PhysDiskDevHandle);2749 if (phys_disk_dev_handle == pd_handle) {2750 *volume_handle =2751 le16_to_cpu(config_page->2752 ConfigElement[i].VolDevHandle);2753 r = 0;2754 goto out;2755 }2756 } else if (element_type ==2757 MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) {2758 *volume_handle = 0;2759 r = 0;2760 goto out;2761 }2762 }2763 config_num = config_page->ConfigNum;2764 }2765 out:2766 kfree(config_page);2767 return r;2768}2769 2770/**2771 * mpt3sas_config_get_volume_wwid - returns wwid given the volume handle2772 * @ioc: per adapter object2773 * @volume_handle: volume handle2774 * @wwid: volume wwid2775 * Context: sleep.2776 *2777 * Return: 0 for success, non-zero for failure.2778 */2779int2780mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc, u16 volume_handle,2781 u64 *wwid)2782{2783 Mpi2ConfigReply_t mpi_reply;2784 Mpi2RaidVolPage1_t raid_vol_pg1;2785 2786 *wwid = 0;2787 if (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply,2788 &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE,2789 volume_handle))) {2790 *wwid = le64_to_cpu(raid_vol_pg1.WWID);2791 return 0;2792 } else2793 return -1;2794}2795