1 /* 2 * This module provides common API for accessing firmware configuration pages 3 * 4 * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c 5 * Copyright (C) 2012-2014 LSI Corporation 6 * Copyright (C) 2013-2014 Avago Technologies 7 * (mailto: MPT-FusionLinux.pdl@avagotech.com) 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License 11 * as published by the Free Software Foundation; either version 2 12 * 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 of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * NO WARRANTY 20 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR 21 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT 22 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 23 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is 24 * solely responsible for determining the appropriateness of using and 25 * distributing the Program and assumes all risks associated with its 26 * exercise of rights under this Agreement, including but not limited to 27 * 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 LIABILITY 31 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY 32 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND 34 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 35 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 36 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED 37 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES 38 39 * You should have received a copy of the GNU General Public License 40 * along with this program; if not, write to the Free Software 41 * 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 15 61 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 routine 75 * @sz: size 76 * @page: virt pointer 77 * @page_dma: phys pointer 78 * 79 */ 80 struct config_request { 81 u16 sz; 82 void *page; 83 dma_addr_t page_dma; 84 }; 85 86 /** 87 * _config_display_some_debug - debug routine 88 * @ioc: per adapter object 89 * @smid: system request message index 90 * @calling_function_name: string pass from calling function 91 * @mpi_reply: reply message frame 92 * Context: none. 93 * 94 * Function for displaying debug info helpful when debugging issues 95 * in this module. 96 */ 97 static void 98 _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 memory 191 * @ioc: per adapter object 192 * @mem: struct config_request 193 * 194 * A wrapper for obtaining dma-able memory for config page request. 195 * 196 * Return: 0 for success, non-zero for failure. 197 */ 198 static int 199 _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 memory 222 * @ioc: per adapter object 223 * @mem: struct config_request 224 * 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 */ 229 static void 230 _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 routine 240 * @ioc: per adapter object 241 * @smid: system request message index 242 * @msix_index: MSIX table index supplied by the OS 243 * @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_interrupt 249 * 0 means the mf is freed from this function. 250 */ 251 u8 252 mpt3sas_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 requests 278 * @ioc: per adapter object 279 * @mpi_request: request message frame 280 * @mpi_reply: reply mf payload returned from firmware 281 * @timeout: timeout in seconds 282 * @config_page: contents of the config page 283 * @config_page_sz: size of config page 284 * Context: sleep 285 * 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 calling 289 * 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 */ 295 static int 296 _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t 297 *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 else 330 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 } else 403 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 0 509 * @ioc: per adapter object 510 * @mpi_reply: reply mf payload returned from firmware 511 * @config_page: contents of the config page 512 * Context: sleep. 513 * 514 * Return: 0 for success, non-zero for failure. 515 */ 516 int 517 mpt3sas_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 1 545 * @ioc: per adapter object 546 * @mpi_reply: reply mf payload returned from firmware 547 * @config_page: contents of the config page 548 * Context: sleep. 549 * 550 * Return: 0 for success, non-zero for failure. 551 */ 552 int 553 mpt3sas_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_pg10 - obtain manufacturing page 10 581 * @ioc: per adapter object 582 * @mpi_reply: reply mf payload returned from firmware 583 * @config_page: contents of the config page 584 * Context: sleep. 585 * 586 * Return: 0 for success, non-zero for failure. 587 */ 588 int 589 mpt3sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER *ioc, 590 Mpi2ConfigReply_t *mpi_reply, 591 struct Mpi2ManufacturingPage10_t *config_page) 592 { 593 Mpi2ConfigRequest_t mpi_request; 594 int r; 595 596 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 597 mpi_request.Function = MPI2_FUNCTION_CONFIG; 598 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 599 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; 600 mpi_request.Header.PageNumber = 10; 601 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; 602 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 603 r = _config_request(ioc, &mpi_request, mpi_reply, 604 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 605 if (r) 606 goto out; 607 608 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 609 r = _config_request(ioc, &mpi_request, mpi_reply, 610 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 611 sizeof(*config_page)); 612 out: 613 return r; 614 } 615 616 /** 617 * mpt3sas_config_get_manufacturing_pg11 - obtain manufacturing page 11 618 * @ioc: per adapter object 619 * @mpi_reply: reply mf payload returned from firmware 620 * @config_page: contents of the config page 621 * Context: sleep. 622 * 623 * Return: 0 for success, non-zero for failure. 624 */ 625 int 626 mpt3sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc, 627 Mpi2ConfigReply_t *mpi_reply, 628 struct Mpi2ManufacturingPage11_t *config_page) 629 { 630 Mpi2ConfigRequest_t mpi_request; 631 int r; 632 633 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 634 mpi_request.Function = MPI2_FUNCTION_CONFIG; 635 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 636 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; 637 mpi_request.Header.PageNumber = 11; 638 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; 639 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 640 r = _config_request(ioc, &mpi_request, mpi_reply, 641 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 642 if (r) 643 goto out; 644 645 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 646 r = _config_request(ioc, &mpi_request, mpi_reply, 647 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 648 sizeof(*config_page)); 649 out: 650 return r; 651 } 652 653 /** 654 * mpt3sas_config_set_manufacturing_pg11 - set manufacturing page 11 655 * @ioc: per adapter object 656 * @mpi_reply: reply mf payload returned from firmware 657 * @config_page: contents of the config page 658 * Context: sleep. 659 * 660 * Return: 0 for success, non-zero for failure. 661 */ 662 int 663 mpt3sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc, 664 Mpi2ConfigReply_t *mpi_reply, 665 struct Mpi2ManufacturingPage11_t *config_page) 666 { 667 Mpi2ConfigRequest_t mpi_request; 668 int r; 669 670 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 671 mpi_request.Function = MPI2_FUNCTION_CONFIG; 672 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 673 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; 674 mpi_request.Header.PageNumber = 11; 675 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; 676 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 677 r = _config_request(ioc, &mpi_request, mpi_reply, 678 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 679 if (r) 680 goto out; 681 682 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 683 r = _config_request(ioc, &mpi_request, mpi_reply, 684 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 685 sizeof(*config_page)); 686 out: 687 return r; 688 } 689 690 /** 691 * mpt3sas_config_get_bios_pg2 - obtain bios page 2 692 * @ioc: per adapter object 693 * @mpi_reply: reply mf payload returned from firmware 694 * @config_page: contents of the config page 695 * Context: sleep. 696 * 697 * Return: 0 for success, non-zero for failure. 698 */ 699 int 700 mpt3sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER *ioc, 701 Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page) 702 { 703 Mpi2ConfigRequest_t mpi_request; 704 int r; 705 706 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 707 mpi_request.Function = MPI2_FUNCTION_CONFIG; 708 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 709 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS; 710 mpi_request.Header.PageNumber = 2; 711 mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION; 712 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 713 r = _config_request(ioc, &mpi_request, mpi_reply, 714 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 715 if (r) 716 goto out; 717 718 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 719 r = _config_request(ioc, &mpi_request, mpi_reply, 720 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 721 sizeof(*config_page)); 722 out: 723 return r; 724 } 725 726 /** 727 * mpt3sas_config_get_bios_pg3 - obtain bios page 3 728 * @ioc: per adapter object 729 * @mpi_reply: reply mf payload returned from firmware 730 * @config_page: contents of the config page 731 * Context: sleep. 732 * 733 * Return: 0 for success, non-zero for failure. 734 */ 735 int 736 mpt3sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 737 *mpi_reply, Mpi2BiosPage3_t *config_page) 738 { 739 Mpi2ConfigRequest_t mpi_request; 740 int r; 741 742 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 743 mpi_request.Function = MPI2_FUNCTION_CONFIG; 744 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 745 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS; 746 mpi_request.Header.PageNumber = 3; 747 mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION; 748 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 749 r = _config_request(ioc, &mpi_request, mpi_reply, 750 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 751 if (r) 752 goto out; 753 754 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 755 r = _config_request(ioc, &mpi_request, mpi_reply, 756 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 757 sizeof(*config_page)); 758 759 out: 760 return r; 761 } 762 763 /** 764 * mpt3sas_config_set_bios_pg4 - write out bios page 4 765 * @ioc: per adapter object 766 * @mpi_reply: reply mf payload returned from firmware 767 * @config_page: contents of the config page 768 * @sz_config_pg: sizeof the config page 769 * Context: sleep. 770 * 771 * Return: 0 for success, non-zero for failure. 772 */ 773 int 774 mpt3sas_config_set_bios_pg4(struct MPT3SAS_ADAPTER *ioc, 775 Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage4_t *config_page, 776 int sz_config_pg) 777 { 778 Mpi2ConfigRequest_t mpi_request; 779 int r; 780 781 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 782 783 mpi_request.Function = MPI2_FUNCTION_CONFIG; 784 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 785 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS; 786 mpi_request.Header.PageNumber = 4; 787 mpi_request.Header.PageVersion = MPI2_BIOSPAGE4_PAGEVERSION; 788 789 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 790 791 r = _config_request(ioc, &mpi_request, mpi_reply, 792 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 793 if (r) 794 goto out; 795 796 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 797 r = _config_request(ioc, &mpi_request, mpi_reply, 798 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 799 sz_config_pg); 800 out: 801 return r; 802 } 803 804 /** 805 * mpt3sas_config_get_bios_pg4 - read bios page 4 806 * @ioc: per adapter object 807 * @mpi_reply: reply mf payload returned from firmware 808 * @config_page: contents of the config page 809 * @sz_config_pg: sizeof the config page 810 * Context: sleep. 811 * 812 * Return: 0 for success, non-zero for failure. 813 */ 814 int 815 mpt3sas_config_get_bios_pg4(struct MPT3SAS_ADAPTER *ioc, 816 Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage4_t *config_page, 817 int sz_config_pg) 818 { 819 Mpi2ConfigRequest_t mpi_request; 820 int r; 821 822 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 823 mpi_request.Function = MPI2_FUNCTION_CONFIG; 824 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 825 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS; 826 mpi_request.Header.PageNumber = 4; 827 mpi_request.Header.PageVersion = MPI2_BIOSPAGE4_PAGEVERSION; 828 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 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 /* 835 * The sizeof the page is variable. Allow for just the 836 * size to be returned 837 */ 838 if (config_page && sz_config_pg) { 839 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 840 841 r = _config_request(ioc, &mpi_request, mpi_reply, 842 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 843 sz_config_pg); 844 } 845 846 out: 847 return r; 848 } 849 850 /** 851 * mpt3sas_config_get_iounit_pg0 - obtain iounit page 0 852 * @ioc: per adapter object 853 * @mpi_reply: reply mf payload returned from firmware 854 * @config_page: contents of the config page 855 * Context: sleep. 856 * 857 * Return: 0 for success, non-zero for failure. 858 */ 859 int 860 mpt3sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER *ioc, 861 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page) 862 { 863 Mpi2ConfigRequest_t mpi_request; 864 int r; 865 866 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 867 mpi_request.Function = MPI2_FUNCTION_CONFIG; 868 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 869 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; 870 mpi_request.Header.PageNumber = 0; 871 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION; 872 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 873 r = _config_request(ioc, &mpi_request, mpi_reply, 874 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 875 if (r) 876 goto out; 877 878 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 879 r = _config_request(ioc, &mpi_request, mpi_reply, 880 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 881 sizeof(*config_page)); 882 out: 883 return r; 884 } 885 886 /** 887 * mpt3sas_config_get_iounit_pg1 - obtain iounit page 1 888 * @ioc: per adapter object 889 * @mpi_reply: reply mf payload returned from firmware 890 * @config_page: contents of the config page 891 * Context: sleep. 892 * 893 * Return: 0 for success, non-zero for failure. 894 */ 895 int 896 mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, 897 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page) 898 { 899 Mpi2ConfigRequest_t mpi_request; 900 int r; 901 902 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 903 mpi_request.Function = MPI2_FUNCTION_CONFIG; 904 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 905 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; 906 mpi_request.Header.PageNumber = 1; 907 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION; 908 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 909 r = _config_request(ioc, &mpi_request, mpi_reply, 910 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 911 if (r) 912 goto out; 913 914 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 915 r = _config_request(ioc, &mpi_request, mpi_reply, 916 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 917 sizeof(*config_page)); 918 out: 919 return r; 920 } 921 922 /** 923 * mpt3sas_config_set_iounit_pg1 - set iounit page 1 924 * @ioc: per adapter object 925 * @mpi_reply: reply mf payload returned from firmware 926 * @config_page: contents of the config page 927 * Context: sleep. 928 * 929 * Return: 0 for success, non-zero for failure. 930 */ 931 int 932 mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, 933 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page) 934 { 935 Mpi2ConfigRequest_t mpi_request; 936 int r; 937 938 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 939 mpi_request.Function = MPI2_FUNCTION_CONFIG; 940 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 941 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; 942 mpi_request.Header.PageNumber = 1; 943 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION; 944 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 945 r = _config_request(ioc, &mpi_request, mpi_reply, 946 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 947 if (r) 948 goto out; 949 950 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 951 r = _config_request(ioc, &mpi_request, mpi_reply, 952 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 953 sizeof(*config_page)); 954 out: 955 return r; 956 } 957 958 /** 959 * mpt3sas_config_get_iounit_pg3 - obtain iounit page 3 960 * @ioc: per adapter object 961 * @mpi_reply: reply mf payload returned from firmware 962 * @config_page: contents of the config page 963 * @sz: size of buffer passed in config_page 964 * Context: sleep. 965 * 966 * Return: 0 for success, non-zero for failure. 967 */ 968 int 969 mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc, 970 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz) 971 { 972 Mpi2ConfigRequest_t mpi_request; 973 int r; 974 975 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 976 mpi_request.Function = MPI2_FUNCTION_CONFIG; 977 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 978 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; 979 mpi_request.Header.PageNumber = 3; 980 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION; 981 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 982 r = _config_request(ioc, &mpi_request, mpi_reply, 983 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 984 if (r) 985 goto out; 986 987 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 988 r = _config_request(ioc, &mpi_request, mpi_reply, 989 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 990 out: 991 return r; 992 } 993 994 /** 995 * mpt3sas_config_get_iounit_pg8 - obtain iounit page 8 996 * @ioc: per adapter object 997 * @mpi_reply: reply mf payload returned from firmware 998 * @config_page: contents of the config page 999 * Context: sleep. 1000 * 1001 * Return: 0 for success, non-zero for failure. 1002 */ 1003 int 1004 mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc, 1005 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page) 1006 { 1007 Mpi2ConfigRequest_t mpi_request; 1008 int r; 1009 1010 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1011 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1012 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1013 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; 1014 mpi_request.Header.PageNumber = 8; 1015 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION; 1016 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1017 r = _config_request(ioc, &mpi_request, mpi_reply, 1018 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1019 if (r) 1020 goto out; 1021 1022 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1023 r = _config_request(ioc, &mpi_request, mpi_reply, 1024 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1025 sizeof(*config_page)); 1026 out: 1027 return r; 1028 } 1029 1030 /** 1031 * mpt3sas_config_get_ioc_pg8 - obtain ioc page 8 1032 * @ioc: per adapter object 1033 * @mpi_reply: reply mf payload returned from firmware 1034 * @config_page: contents of the config page 1035 * Context: sleep. 1036 * 1037 * Return: 0 for success, non-zero for failure. 1038 */ 1039 int 1040 mpt3sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER *ioc, 1041 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page) 1042 { 1043 Mpi2ConfigRequest_t mpi_request; 1044 int r; 1045 1046 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1047 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1048 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1049 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC; 1050 mpi_request.Header.PageNumber = 8; 1051 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION; 1052 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1053 r = _config_request(ioc, &mpi_request, mpi_reply, 1054 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1055 if (r) 1056 goto out; 1057 1058 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1059 r = _config_request(ioc, &mpi_request, mpi_reply, 1060 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1061 sizeof(*config_page)); 1062 out: 1063 return r; 1064 } 1065 /** 1066 * mpt3sas_config_get_ioc_pg1 - obtain ioc page 1 1067 * @ioc: per adapter object 1068 * @mpi_reply: reply mf payload returned from firmware 1069 * @config_page: contents of the config page 1070 * Context: sleep. 1071 * 1072 * Return: 0 for success, non-zero for failure. 1073 */ 1074 int 1075 mpt3sas_config_get_ioc_pg1(struct MPT3SAS_ADAPTER *ioc, 1076 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page) 1077 { 1078 Mpi2ConfigRequest_t mpi_request; 1079 int r; 1080 1081 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1082 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1083 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1084 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC; 1085 mpi_request.Header.PageNumber = 1; 1086 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION; 1087 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1088 r = _config_request(ioc, &mpi_request, mpi_reply, 1089 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1090 if (r) 1091 goto out; 1092 1093 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1094 r = _config_request(ioc, &mpi_request, mpi_reply, 1095 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1096 sizeof(*config_page)); 1097 out: 1098 return r; 1099 } 1100 1101 /** 1102 * mpt3sas_config_set_ioc_pg1 - modify ioc page 1 1103 * @ioc: per adapter object 1104 * @mpi_reply: reply mf payload returned from firmware 1105 * @config_page: contents of the config page 1106 * Context: sleep. 1107 * 1108 * Return: 0 for success, non-zero for failure. 1109 */ 1110 int 1111 mpt3sas_config_set_ioc_pg1(struct MPT3SAS_ADAPTER *ioc, 1112 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page) 1113 { 1114 Mpi2ConfigRequest_t mpi_request; 1115 int r; 1116 1117 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1118 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1119 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1120 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC; 1121 mpi_request.Header.PageNumber = 1; 1122 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION; 1123 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1124 r = _config_request(ioc, &mpi_request, mpi_reply, 1125 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1126 if (r) 1127 goto out; 1128 1129 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 1130 r = _config_request(ioc, &mpi_request, mpi_reply, 1131 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1132 sizeof(*config_page)); 1133 out: 1134 return r; 1135 } 1136 1137 /** 1138 * mpt3sas_config_get_sas_device_pg0 - obtain sas device page 0 1139 * @ioc: per adapter object 1140 * @mpi_reply: reply mf payload returned from firmware 1141 * @config_page: contents of the config page 1142 * @form: GET_NEXT_HANDLE or HANDLE 1143 * @handle: device handle 1144 * Context: sleep. 1145 * 1146 * Return: 0 for success, non-zero for failure. 1147 */ 1148 int 1149 mpt3sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc, 1150 Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage0_t *config_page, 1151 u32 form, u32 handle) 1152 { 1153 Mpi2ConfigRequest_t mpi_request; 1154 int r; 1155 1156 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1157 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1158 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1159 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1160 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE; 1161 mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION; 1162 mpi_request.Header.PageNumber = 0; 1163 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1164 r = _config_request(ioc, &mpi_request, mpi_reply, 1165 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1166 if (r) 1167 goto out; 1168 1169 mpi_request.PageAddress = cpu_to_le32(form | handle); 1170 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1171 r = _config_request(ioc, &mpi_request, mpi_reply, 1172 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1173 sizeof(*config_page)); 1174 out: 1175 return r; 1176 } 1177 1178 /** 1179 * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 0 1180 * @ioc: per adapter object 1181 * @mpi_reply: reply mf payload returned from firmware 1182 * @config_page: contents of the config page 1183 * @form: GET_NEXT_HANDLE or HANDLE 1184 * @handle: device handle 1185 * Context: sleep. 1186 * 1187 * Return: 0 for success, non-zero for failure. 1188 */ 1189 int 1190 mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc, 1191 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page, 1192 u32 form, u32 handle) 1193 { 1194 Mpi2ConfigRequest_t mpi_request; 1195 int r; 1196 1197 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1198 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1199 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1200 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1201 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE; 1202 mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION; 1203 mpi_request.Header.PageNumber = 0; 1204 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1205 r = _config_request(ioc, &mpi_request, mpi_reply, 1206 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1207 if (r) 1208 goto out; 1209 1210 mpi_request.PageAddress = cpu_to_le32(form | handle); 1211 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1212 r = _config_request(ioc, &mpi_request, mpi_reply, 1213 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1214 sizeof(*config_page)); 1215 out: 1216 return r; 1217 } 1218 1219 /** 1220 * mpt3sas_config_get_pcie_iounit_pg1 - obtain pcie iounit page 1 1221 * @ioc: per adapter object 1222 * @mpi_reply: reply mf payload returned from firmware 1223 * @config_page: contents of the config page 1224 * @sz: size of buffer passed in config_page 1225 * Context: sleep. 1226 * 1227 * Returns 0 for success, non-zero for failure. 1228 */ 1229 int 1230 mpt3sas_config_get_pcie_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, 1231 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeIOUnitPage1_t *config_page, 1232 u16 sz) 1233 { 1234 Mpi2ConfigRequest_t mpi_request; 1235 int r; 1236 1237 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1238 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1239 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1240 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1241 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT; 1242 mpi_request.Header.PageVersion = MPI26_PCIEIOUNITPAGE1_PAGEVERSION; 1243 mpi_request.Header.PageNumber = 1; 1244 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1245 r = _config_request(ioc, &mpi_request, mpi_reply, 1246 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1247 if (r) 1248 goto out; 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, sz); 1252 out: 1253 return r; 1254 } 1255 1256 /** 1257 * mpt3sas_config_get_pcie_device_pg2 - obtain pcie device page 2 1258 * @ioc: per adapter object 1259 * @mpi_reply: reply mf payload returned from firmware 1260 * @config_page: contents of the config page 1261 * @form: GET_NEXT_HANDLE or HANDLE 1262 * @handle: device handle 1263 * Context: sleep. 1264 * 1265 * Return: 0 for success, non-zero for failure. 1266 */ 1267 int 1268 mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc, 1269 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page, 1270 u32 form, u32 handle) 1271 { 1272 Mpi2ConfigRequest_t mpi_request; 1273 int r; 1274 1275 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1276 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1277 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1278 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1279 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE; 1280 mpi_request.Header.PageVersion = MPI26_PCIEDEVICE2_PAGEVERSION; 1281 mpi_request.Header.PageNumber = 2; 1282 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1283 r = _config_request(ioc, &mpi_request, mpi_reply, 1284 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1285 if (r) 1286 goto out; 1287 1288 mpi_request.PageAddress = cpu_to_le32(form | handle); 1289 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1290 r = _config_request(ioc, &mpi_request, mpi_reply, 1291 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1292 sizeof(*config_page)); 1293 out: 1294 return r; 1295 } 1296 1297 /** 1298 * mpt3sas_config_get_number_hba_phys - obtain number of phys on the host 1299 * @ioc: per adapter object 1300 * @num_phys: pointer returned with the number of phys 1301 * Context: sleep. 1302 * 1303 * Return: 0 for success, non-zero for failure. 1304 */ 1305 int 1306 mpt3sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER *ioc, u8 *num_phys) 1307 { 1308 Mpi2ConfigRequest_t mpi_request; 1309 int r; 1310 u16 ioc_status; 1311 Mpi2ConfigReply_t mpi_reply; 1312 Mpi2SasIOUnitPage0_t config_page; 1313 1314 *num_phys = 0; 1315 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1316 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1317 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1318 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1319 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; 1320 mpi_request.Header.PageNumber = 0; 1321 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION; 1322 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1323 r = _config_request(ioc, &mpi_request, &mpi_reply, 1324 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1325 if (r) 1326 goto out; 1327 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, 1331 sizeof(Mpi2SasIOUnitPage0_t)); 1332 if (!r) { 1333 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1334 MPI2_IOCSTATUS_MASK; 1335 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) 1336 *num_phys = config_page.NumPhys; 1337 } 1338 out: 1339 return r; 1340 } 1341 1342 /** 1343 * mpt3sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0 1344 * @ioc: per adapter object 1345 * @mpi_reply: reply mf payload returned from firmware 1346 * @config_page: contents of the config page 1347 * @sz: size of buffer passed in config_page 1348 * Context: sleep. 1349 * 1350 * Calling function should call config_get_number_hba_phys prior to 1351 * this function, so enough memory is allocated for config_page. 1352 * 1353 * Return: 0 for success, non-zero for failure. 1354 */ 1355 int 1356 mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc, 1357 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page, 1358 u16 sz) 1359 { 1360 Mpi2ConfigRequest_t mpi_request; 1361 int r; 1362 1363 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1364 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1365 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1366 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1367 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; 1368 mpi_request.Header.PageNumber = 0; 1369 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION; 1370 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1371 r = _config_request(ioc, &mpi_request, mpi_reply, 1372 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1373 if (r) 1374 goto out; 1375 1376 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1377 r = _config_request(ioc, &mpi_request, mpi_reply, 1378 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 1379 out: 1380 return r; 1381 } 1382 1383 /** 1384 * mpt3sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1 1385 * @ioc: per adapter object 1386 * @mpi_reply: reply mf payload returned from firmware 1387 * @config_page: contents of the config page 1388 * @sz: size of buffer passed in config_page 1389 * Context: sleep. 1390 * 1391 * Calling function should call config_get_number_hba_phys prior to 1392 * this function, so enough memory is allocated for config_page. 1393 * 1394 * Return: 0 for success, non-zero for failure. 1395 */ 1396 int 1397 mpt3sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, 1398 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, 1399 u16 sz) 1400 { 1401 Mpi2ConfigRequest_t mpi_request; 1402 int r; 1403 1404 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1405 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1406 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1407 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1408 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; 1409 mpi_request.Header.PageNumber = 1; 1410 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION; 1411 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1412 r = _config_request(ioc, &mpi_request, mpi_reply, 1413 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1414 if (r) 1415 goto out; 1416 1417 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1418 r = _config_request(ioc, &mpi_request, mpi_reply, 1419 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 1420 out: 1421 return r; 1422 } 1423 1424 /** 1425 * mpt3sas_config_set_sas_iounit_pg1 - send sas iounit page 1 1426 * @ioc: per adapter object 1427 * @mpi_reply: reply mf payload returned from firmware 1428 * @config_page: contents of the config page 1429 * @sz: size of buffer passed in config_page 1430 * Context: sleep. 1431 * 1432 * Calling function should call config_get_number_hba_phys prior to 1433 * this function, so enough memory is allocated for config_page. 1434 * 1435 * Return: 0 for success, non-zero for failure. 1436 */ 1437 int 1438 mpt3sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, 1439 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, 1440 u16 sz) 1441 { 1442 Mpi2ConfigRequest_t mpi_request; 1443 int r; 1444 1445 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1446 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1447 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1448 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1449 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; 1450 mpi_request.Header.PageNumber = 1; 1451 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION; 1452 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1453 r = _config_request(ioc, &mpi_request, mpi_reply, 1454 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1455 if (r) 1456 goto out; 1457 1458 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 1459 _config_request(ioc, &mpi_request, mpi_reply, 1460 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 1461 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 1462 r = _config_request(ioc, &mpi_request, mpi_reply, 1463 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 1464 out: 1465 return r; 1466 } 1467 1468 /** 1469 * mpt3sas_config_get_expander_pg0 - obtain expander page 0 1470 * @ioc: per adapter object 1471 * @mpi_reply: reply mf payload returned from firmware 1472 * @config_page: contents of the config page 1473 * @form: GET_NEXT_HANDLE or HANDLE 1474 * @handle: expander handle 1475 * Context: sleep. 1476 * 1477 * Return: 0 for success, non-zero for failure. 1478 */ 1479 int 1480 mpt3sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1481 *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle) 1482 { 1483 Mpi2ConfigRequest_t mpi_request; 1484 int r; 1485 1486 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1487 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1488 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1489 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1490 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER; 1491 mpi_request.Header.PageNumber = 0; 1492 mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION; 1493 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1494 r = _config_request(ioc, &mpi_request, mpi_reply, 1495 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1496 if (r) 1497 goto out; 1498 1499 mpi_request.PageAddress = cpu_to_le32(form | handle); 1500 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1501 r = _config_request(ioc, &mpi_request, mpi_reply, 1502 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1503 sizeof(*config_page)); 1504 out: 1505 return r; 1506 } 1507 1508 /** 1509 * mpt3sas_config_get_expander_pg1 - obtain expander page 1 1510 * @ioc: per adapter object 1511 * @mpi_reply: reply mf payload returned from firmware 1512 * @config_page: contents of the config page 1513 * @phy_number: phy number 1514 * @handle: expander handle 1515 * Context: sleep. 1516 * 1517 * Return: 0 for success, non-zero for failure. 1518 */ 1519 int 1520 mpt3sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1521 *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number, 1522 u16 handle) 1523 { 1524 Mpi2ConfigRequest_t mpi_request; 1525 int r; 1526 1527 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1528 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1529 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1530 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1531 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER; 1532 mpi_request.Header.PageNumber = 1; 1533 mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION; 1534 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1535 r = _config_request(ioc, &mpi_request, mpi_reply, 1536 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1537 if (r) 1538 goto out; 1539 1540 mpi_request.PageAddress = 1541 cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM | 1542 (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle); 1543 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1544 r = _config_request(ioc, &mpi_request, mpi_reply, 1545 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1546 sizeof(*config_page)); 1547 out: 1548 return r; 1549 } 1550 1551 /** 1552 * mpt3sas_config_get_enclosure_pg0 - obtain enclosure page 0 1553 * @ioc: per adapter object 1554 * @mpi_reply: reply mf payload returned from firmware 1555 * @config_page: contents of the config page 1556 * @form: GET_NEXT_HANDLE or HANDLE 1557 * @handle: expander handle 1558 * Context: sleep. 1559 * 1560 * Return: 0 for success, non-zero for failure. 1561 */ 1562 int 1563 mpt3sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1564 *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle) 1565 { 1566 Mpi2ConfigRequest_t mpi_request; 1567 int r; 1568 1569 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1570 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1571 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1572 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1573 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE; 1574 mpi_request.Header.PageNumber = 0; 1575 mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION; 1576 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1577 r = _config_request(ioc, &mpi_request, mpi_reply, 1578 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1579 if (r) 1580 goto out; 1581 1582 mpi_request.PageAddress = cpu_to_le32(form | handle); 1583 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1584 r = _config_request(ioc, &mpi_request, mpi_reply, 1585 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1586 sizeof(*config_page)); 1587 out: 1588 return r; 1589 } 1590 1591 /** 1592 * mpt3sas_config_get_phy_pg0 - obtain phy page 0 1593 * @ioc: per adapter object 1594 * @mpi_reply: reply mf payload returned from firmware 1595 * @config_page: contents of the config page 1596 * @phy_number: phy number 1597 * Context: sleep. 1598 * 1599 * Return: 0 for success, non-zero for failure. 1600 */ 1601 int 1602 mpt3sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1603 *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number) 1604 { 1605 Mpi2ConfigRequest_t mpi_request; 1606 int r; 1607 1608 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1609 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1610 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1611 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1612 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY; 1613 mpi_request.Header.PageNumber = 0; 1614 mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION; 1615 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1616 r = _config_request(ioc, &mpi_request, mpi_reply, 1617 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1618 if (r) 1619 goto out; 1620 1621 mpi_request.PageAddress = 1622 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number); 1623 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1624 r = _config_request(ioc, &mpi_request, mpi_reply, 1625 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1626 sizeof(*config_page)); 1627 out: 1628 return r; 1629 } 1630 1631 /** 1632 * mpt3sas_config_get_phy_pg1 - obtain phy page 1 1633 * @ioc: per adapter object 1634 * @mpi_reply: reply mf payload returned from firmware 1635 * @config_page: contents of the config page 1636 * @phy_number: phy number 1637 * Context: sleep. 1638 * 1639 * Return: 0 for success, non-zero for failure. 1640 */ 1641 int 1642 mpt3sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1643 *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number) 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_SAS_PHY; 1653 mpi_request.Header.PageNumber = 1; 1654 mpi_request.Header.PageVersion = MPI2_SASPHY1_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 = 1662 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number); 1663 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1664 r = _config_request(ioc, &mpi_request, mpi_reply, 1665 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1666 sizeof(*config_page)); 1667 out: 1668 return r; 1669 } 1670 1671 /** 1672 * mpt3sas_config_get_raid_volume_pg1 - obtain raid volume page 1 1673 * @ioc: per adapter object 1674 * @mpi_reply: reply mf payload returned from firmware 1675 * @config_page: contents of the config page 1676 * @form: GET_NEXT_HANDLE or HANDLE 1677 * @handle: volume handle 1678 * Context: sleep. 1679 * 1680 * Return: 0 for success, non-zero for failure. 1681 */ 1682 int 1683 mpt3sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER *ioc, 1684 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form, 1685 u32 handle) 1686 { 1687 Mpi2ConfigRequest_t mpi_request; 1688 int r; 1689 1690 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1691 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1692 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1693 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; 1694 mpi_request.Header.PageNumber = 1; 1695 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION; 1696 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1697 r = _config_request(ioc, &mpi_request, mpi_reply, 1698 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1699 if (r) 1700 goto out; 1701 1702 mpi_request.PageAddress = cpu_to_le32(form | handle); 1703 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1704 r = _config_request(ioc, &mpi_request, mpi_reply, 1705 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1706 sizeof(*config_page)); 1707 out: 1708 return r; 1709 } 1710 1711 /** 1712 * mpt3sas_config_get_number_pds - obtain number of phys disk assigned to volume 1713 * @ioc: per adapter object 1714 * @handle: volume handle 1715 * @num_pds: returns pds count 1716 * Context: sleep. 1717 * 1718 * Return: 0 for success, non-zero for failure. 1719 */ 1720 int 1721 mpt3sas_config_get_number_pds(struct MPT3SAS_ADAPTER *ioc, u16 handle, 1722 u8 *num_pds) 1723 { 1724 Mpi2ConfigRequest_t mpi_request; 1725 Mpi2RaidVolPage0_t config_page; 1726 Mpi2ConfigReply_t mpi_reply; 1727 int r; 1728 u16 ioc_status; 1729 1730 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1731 *num_pds = 0; 1732 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1733 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1734 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; 1735 mpi_request.Header.PageNumber = 0; 1736 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION; 1737 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1738 r = _config_request(ioc, &mpi_request, &mpi_reply, 1739 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1740 if (r) 1741 goto out; 1742 1743 mpi_request.PageAddress = 1744 cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle); 1745 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1746 r = _config_request(ioc, &mpi_request, &mpi_reply, 1747 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page, 1748 sizeof(Mpi2RaidVolPage0_t)); 1749 if (!r) { 1750 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1751 MPI2_IOCSTATUS_MASK; 1752 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) 1753 *num_pds = config_page.NumPhysDisks; 1754 } 1755 1756 out: 1757 return r; 1758 } 1759 1760 /** 1761 * mpt3sas_config_get_raid_volume_pg0 - obtain raid volume page 0 1762 * @ioc: per adapter object 1763 * @mpi_reply: reply mf payload returned from firmware 1764 * @config_page: contents of the config page 1765 * @form: GET_NEXT_HANDLE or HANDLE 1766 * @handle: volume handle 1767 * @sz: size of buffer passed in config_page 1768 * Context: sleep. 1769 * 1770 * Return: 0 for success, non-zero for failure. 1771 */ 1772 int 1773 mpt3sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER *ioc, 1774 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form, 1775 u32 handle, u16 sz) 1776 { 1777 Mpi2ConfigRequest_t mpi_request; 1778 int r; 1779 1780 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1781 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1782 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1783 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; 1784 mpi_request.Header.PageNumber = 0; 1785 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION; 1786 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1787 r = _config_request(ioc, &mpi_request, mpi_reply, 1788 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1789 if (r) 1790 goto out; 1791 1792 mpi_request.PageAddress = cpu_to_le32(form | handle); 1793 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1794 r = _config_request(ioc, &mpi_request, mpi_reply, 1795 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 1796 out: 1797 return r; 1798 } 1799 1800 /** 1801 * mpt3sas_config_get_phys_disk_pg0 - obtain phys disk page 0 1802 * @ioc: per adapter object 1803 * @mpi_reply: reply mf payload returned from firmware 1804 * @config_page: contents of the config page 1805 * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE 1806 * @form_specific: specific to the form 1807 * Context: sleep. 1808 * 1809 * Return: 0 for success, non-zero for failure. 1810 */ 1811 int 1812 mpt3sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1813 *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form, 1814 u32 form_specific) 1815 { 1816 Mpi2ConfigRequest_t mpi_request; 1817 int r; 1818 1819 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1820 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1821 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1822 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK; 1823 mpi_request.Header.PageNumber = 0; 1824 mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION; 1825 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1826 r = _config_request(ioc, &mpi_request, mpi_reply, 1827 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1828 if (r) 1829 goto out; 1830 1831 mpi_request.PageAddress = cpu_to_le32(form | form_specific); 1832 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1833 r = _config_request(ioc, &mpi_request, mpi_reply, 1834 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1835 sizeof(*config_page)); 1836 out: 1837 return r; 1838 } 1839 1840 /** 1841 * mpt3sas_config_get_driver_trigger_pg0 - obtain driver trigger page 0 1842 * @ioc: per adapter object 1843 * @mpi_reply: reply mf payload returned from firmware 1844 * @config_page: contents of the config page 1845 * Context: sleep. 1846 * 1847 * Returns 0 for success, non-zero for failure. 1848 */ 1849 int 1850 mpt3sas_config_get_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc, 1851 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page) 1852 { 1853 Mpi2ConfigRequest_t mpi_request; 1854 int r; 1855 1856 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1857 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1858 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1859 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1860 mpi_request.ExtPageType = 1861 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 1862 mpi_request.Header.PageNumber = 0; 1863 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION; 1864 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1865 r = _config_request(ioc, &mpi_request, mpi_reply, 1866 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1867 if (r) 1868 goto out; 1869 1870 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1871 r = _config_request(ioc, &mpi_request, mpi_reply, 1872 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1873 sizeof(*config_page)); 1874 out: 1875 return r; 1876 } 1877 1878 /** 1879 * _config_set_driver_trigger_pg0 - write driver trigger page 0 1880 * @ioc: per adapter object 1881 * @mpi_reply: reply mf payload returned from firmware 1882 * @config_page: contents of the config page 1883 * Context: sleep. 1884 * 1885 * Returns 0 for success, non-zero for failure. 1886 */ 1887 static int 1888 _config_set_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc, 1889 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page) 1890 { 1891 Mpi2ConfigRequest_t mpi_request; 1892 int r; 1893 1894 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1895 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1896 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1897 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1898 mpi_request.ExtPageType = 1899 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 1900 mpi_request.Header.PageNumber = 0; 1901 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION; 1902 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1903 r = _config_request(ioc, &mpi_request, mpi_reply, 1904 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1905 if (r) 1906 goto out; 1907 1908 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 1909 _config_request(ioc, &mpi_request, mpi_reply, 1910 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1911 sizeof(*config_page)); 1912 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 1913 r = _config_request(ioc, &mpi_request, mpi_reply, 1914 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1915 sizeof(*config_page)); 1916 out: 1917 return r; 1918 } 1919 1920 /** 1921 * mpt3sas_config_update_driver_trigger_pg0 - update driver trigger page 0 1922 * @ioc: per adapter object 1923 * @trigger_flag: trigger type bit map 1924 * @set: set ot clear trigger values 1925 * Context: sleep. 1926 * 1927 * Returns 0 for success, non-zero for failure. 1928 */ 1929 static int 1930 mpt3sas_config_update_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc, 1931 u16 trigger_flag, bool set) 1932 { 1933 Mpi26DriverTriggerPage0_t tg_pg0; 1934 Mpi2ConfigReply_t mpi_reply; 1935 int rc; 1936 u16 flags, ioc_status; 1937 1938 rc = mpt3sas_config_get_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0); 1939 if (rc) 1940 return rc; 1941 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1942 MPI2_IOCSTATUS_MASK; 1943 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 1944 dcprintk(ioc, 1945 ioc_err(ioc, 1946 "%s: Failed to get trigger pg0, ioc_status(0x%04x)\n", 1947 __func__, ioc_status)); 1948 return -EFAULT; 1949 } 1950 1951 if (set) 1952 flags = le16_to_cpu(tg_pg0.TriggerFlags) | trigger_flag; 1953 else 1954 flags = le16_to_cpu(tg_pg0.TriggerFlags) & ~trigger_flag; 1955 1956 tg_pg0.TriggerFlags = cpu_to_le16(flags); 1957 1958 rc = _config_set_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0); 1959 if (rc) 1960 return rc; 1961 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1962 MPI2_IOCSTATUS_MASK; 1963 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 1964 dcprintk(ioc, 1965 ioc_err(ioc, 1966 "%s: Failed to update trigger pg0, ioc_status(0x%04x)\n", 1967 __func__, ioc_status)); 1968 return -EFAULT; 1969 } 1970 1971 return 0; 1972 } 1973 1974 /** 1975 * mpt3sas_config_get_driver_trigger_pg1 - obtain driver trigger page 1 1976 * @ioc: per adapter object 1977 * @mpi_reply: reply mf payload returned from firmware 1978 * @config_page: contents of the config page 1979 * Context: sleep. 1980 * 1981 * Returns 0 for success, non-zero for failure. 1982 */ 1983 int 1984 mpt3sas_config_get_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc, 1985 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page) 1986 { 1987 Mpi2ConfigRequest_t mpi_request; 1988 int r; 1989 1990 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1991 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1992 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1993 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1994 mpi_request.ExtPageType = 1995 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 1996 mpi_request.Header.PageNumber = 1; 1997 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION; 1998 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1999 r = _config_request(ioc, &mpi_request, mpi_reply, 2000 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2001 if (r) 2002 goto out; 2003 2004 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 2005 r = _config_request(ioc, &mpi_request, mpi_reply, 2006 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2007 sizeof(*config_page)); 2008 out: 2009 return r; 2010 } 2011 2012 /** 2013 * _config_set_driver_trigger_pg1 - write driver trigger page 1 2014 * @ioc: per adapter object 2015 * @mpi_reply: reply mf payload returned from firmware 2016 * @config_page: contents of the config page 2017 * Context: sleep. 2018 * 2019 * Returns 0 for success, non-zero for failure. 2020 */ 2021 static int 2022 _config_set_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc, 2023 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page) 2024 { 2025 Mpi2ConfigRequest_t mpi_request; 2026 int r; 2027 2028 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2029 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2030 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2031 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2032 mpi_request.ExtPageType = 2033 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 2034 mpi_request.Header.PageNumber = 1; 2035 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION; 2036 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2037 r = _config_request(ioc, &mpi_request, mpi_reply, 2038 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2039 if (r) 2040 goto out; 2041 2042 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 2043 _config_request(ioc, &mpi_request, mpi_reply, 2044 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2045 sizeof(*config_page)); 2046 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 2047 r = _config_request(ioc, &mpi_request, mpi_reply, 2048 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2049 sizeof(*config_page)); 2050 out: 2051 return r; 2052 } 2053 2054 /** 2055 * mpt3sas_config_update_driver_trigger_pg1 - update driver trigger page 1 2056 * @ioc: per adapter object 2057 * @master_tg: Master trigger bit map 2058 * @set: set ot clear trigger values 2059 * Context: sleep. 2060 * 2061 * Returns 0 for success, non-zero for failure. 2062 */ 2063 int 2064 mpt3sas_config_update_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc, 2065 struct SL_WH_MASTER_TRIGGER_T *master_tg, bool set) 2066 { 2067 Mpi26DriverTriggerPage1_t tg_pg1; 2068 Mpi2ConfigReply_t mpi_reply; 2069 int rc; 2070 u16 ioc_status; 2071 2072 rc = mpt3sas_config_update_driver_trigger_pg0(ioc, 2073 MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, set); 2074 if (rc) 2075 return rc; 2076 2077 rc = mpt3sas_config_get_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1); 2078 if (rc) 2079 goto out; 2080 2081 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2082 MPI2_IOCSTATUS_MASK; 2083 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2084 dcprintk(ioc, 2085 ioc_err(ioc, 2086 "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n", 2087 __func__, ioc_status)); 2088 rc = -EFAULT; 2089 goto out; 2090 } 2091 2092 if (set) { 2093 tg_pg1.NumMasterTrigger = cpu_to_le16(1); 2094 tg_pg1.MasterTriggers[0].MasterTriggerFlags = cpu_to_le32( 2095 master_tg->MasterData); 2096 } else { 2097 tg_pg1.NumMasterTrigger = 0; 2098 tg_pg1.MasterTriggers[0].MasterTriggerFlags = 0; 2099 } 2100 2101 rc = _config_set_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1); 2102 if (rc) 2103 goto out; 2104 2105 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2106 MPI2_IOCSTATUS_MASK; 2107 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2108 dcprintk(ioc, 2109 ioc_err(ioc, 2110 "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n", 2111 __func__, ioc_status)); 2112 rc = -EFAULT; 2113 goto out; 2114 } 2115 2116 return 0; 2117 2118 out: 2119 mpt3sas_config_update_driver_trigger_pg0(ioc, 2120 MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, !set); 2121 2122 return rc; 2123 } 2124 2125 /** 2126 * mpt3sas_config_get_driver_trigger_pg2 - obtain driver trigger page 2 2127 * @ioc: per adapter object 2128 * @mpi_reply: reply mf payload returned from firmware 2129 * @config_page: contents of the config page 2130 * Context: sleep. 2131 * 2132 * Returns 0 for success, non-zero for failure. 2133 */ 2134 int 2135 mpt3sas_config_get_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc, 2136 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page) 2137 { 2138 Mpi2ConfigRequest_t mpi_request; 2139 int r; 2140 2141 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2142 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2143 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2144 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2145 mpi_request.ExtPageType = 2146 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 2147 mpi_request.Header.PageNumber = 2; 2148 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION; 2149 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2150 r = _config_request(ioc, &mpi_request, mpi_reply, 2151 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2152 if (r) 2153 goto out; 2154 2155 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 2156 r = _config_request(ioc, &mpi_request, mpi_reply, 2157 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2158 sizeof(*config_page)); 2159 out: 2160 return r; 2161 } 2162 2163 /** 2164 * _config_set_driver_trigger_pg2 - write driver trigger page 2 2165 * @ioc: per adapter object 2166 * @mpi_reply: reply mf payload returned from firmware 2167 * @config_page: contents of the config page 2168 * Context: sleep. 2169 * 2170 * Returns 0 for success, non-zero for failure. 2171 */ 2172 static int 2173 _config_set_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc, 2174 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page) 2175 { 2176 Mpi2ConfigRequest_t mpi_request; 2177 int r; 2178 2179 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2180 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2181 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2182 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2183 mpi_request.ExtPageType = 2184 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 2185 mpi_request.Header.PageNumber = 2; 2186 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION; 2187 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2188 r = _config_request(ioc, &mpi_request, mpi_reply, 2189 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2190 if (r) 2191 goto out; 2192 2193 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 2194 _config_request(ioc, &mpi_request, mpi_reply, 2195 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2196 sizeof(*config_page)); 2197 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 2198 r = _config_request(ioc, &mpi_request, mpi_reply, 2199 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2200 sizeof(*config_page)); 2201 out: 2202 return r; 2203 } 2204 2205 /** 2206 * mpt3sas_config_update_driver_trigger_pg2 - update driver trigger page 2 2207 * @ioc: per adapter object 2208 * @event_tg: list of Event Triggers 2209 * @set: set ot clear trigger values 2210 * Context: sleep. 2211 * 2212 * Returns 0 for success, non-zero for failure. 2213 */ 2214 int 2215 mpt3sas_config_update_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc, 2216 struct SL_WH_EVENT_TRIGGERS_T *event_tg, bool set) 2217 { 2218 Mpi26DriverTriggerPage2_t tg_pg2; 2219 Mpi2ConfigReply_t mpi_reply; 2220 int rc, i, count; 2221 u16 ioc_status; 2222 2223 rc = mpt3sas_config_update_driver_trigger_pg0(ioc, 2224 MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, set); 2225 if (rc) 2226 return rc; 2227 2228 rc = mpt3sas_config_get_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2); 2229 if (rc) 2230 goto out; 2231 2232 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2233 MPI2_IOCSTATUS_MASK; 2234 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2235 dcprintk(ioc, 2236 ioc_err(ioc, 2237 "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n", 2238 __func__, ioc_status)); 2239 rc = -EFAULT; 2240 goto out; 2241 } 2242 2243 if (set) { 2244 count = event_tg->ValidEntries; 2245 tg_pg2.NumMPIEventTrigger = cpu_to_le16(count); 2246 for (i = 0; i < count; i++) { 2247 tg_pg2.MPIEventTriggers[i].MPIEventCode = 2248 cpu_to_le16( 2249 event_tg->EventTriggerEntry[i].EventValue); 2250 tg_pg2.MPIEventTriggers[i].MPIEventCodeSpecific = 2251 cpu_to_le16( 2252 event_tg->EventTriggerEntry[i].LogEntryQualifier); 2253 } 2254 } else { 2255 tg_pg2.NumMPIEventTrigger = 0; 2256 memset(&tg_pg2.MPIEventTriggers[0], 0, 2257 NUM_VALID_ENTRIES * sizeof( 2258 MPI26_DRIVER_MPI_EVENT_TRIGGER_ENTRY)); 2259 } 2260 2261 rc = _config_set_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2); 2262 if (rc) 2263 goto out; 2264 2265 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2266 MPI2_IOCSTATUS_MASK; 2267 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2268 dcprintk(ioc, 2269 ioc_err(ioc, 2270 "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n", 2271 __func__, ioc_status)); 2272 rc = -EFAULT; 2273 goto out; 2274 } 2275 2276 return 0; 2277 2278 out: 2279 mpt3sas_config_update_driver_trigger_pg0(ioc, 2280 MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, !set); 2281 2282 return rc; 2283 } 2284 2285 /** 2286 * mpt3sas_config_get_driver_trigger_pg3 - obtain driver trigger page 3 2287 * @ioc: per adapter object 2288 * @mpi_reply: reply mf payload returned from firmware 2289 * @config_page: contents of the config page 2290 * Context: sleep. 2291 * 2292 * Returns 0 for success, non-zero for failure. 2293 */ 2294 int 2295 mpt3sas_config_get_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc, 2296 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page) 2297 { 2298 Mpi2ConfigRequest_t mpi_request; 2299 int r; 2300 2301 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2302 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2303 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2304 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2305 mpi_request.ExtPageType = 2306 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 2307 mpi_request.Header.PageNumber = 3; 2308 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION; 2309 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2310 r = _config_request(ioc, &mpi_request, mpi_reply, 2311 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2312 if (r) 2313 goto out; 2314 2315 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 2316 r = _config_request(ioc, &mpi_request, mpi_reply, 2317 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2318 sizeof(*config_page)); 2319 out: 2320 return r; 2321 } 2322 2323 /** 2324 * _config_set_driver_trigger_pg3 - write driver trigger page 3 2325 * @ioc: per adapter object 2326 * @mpi_reply: reply mf payload returned from firmware 2327 * @config_page: contents of the config page 2328 * Context: sleep. 2329 * 2330 * Returns 0 for success, non-zero for failure. 2331 */ 2332 static int 2333 _config_set_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc, 2334 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page) 2335 { 2336 Mpi2ConfigRequest_t mpi_request; 2337 int r; 2338 2339 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2340 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2341 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2342 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2343 mpi_request.ExtPageType = 2344 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 2345 mpi_request.Header.PageNumber = 3; 2346 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION; 2347 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2348 r = _config_request(ioc, &mpi_request, mpi_reply, 2349 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2350 if (r) 2351 goto out; 2352 2353 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 2354 _config_request(ioc, &mpi_request, mpi_reply, 2355 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2356 sizeof(*config_page)); 2357 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 2358 r = _config_request(ioc, &mpi_request, mpi_reply, 2359 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2360 sizeof(*config_page)); 2361 out: 2362 return r; 2363 } 2364 2365 /** 2366 * mpt3sas_config_update_driver_trigger_pg3 - update driver trigger page 3 2367 * @ioc: per adapter object 2368 * @scsi_tg: scsi trigger list 2369 * @set: set ot clear trigger values 2370 * Context: sleep. 2371 * 2372 * Returns 0 for success, non-zero for failure. 2373 */ 2374 int 2375 mpt3sas_config_update_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc, 2376 struct SL_WH_SCSI_TRIGGERS_T *scsi_tg, bool set) 2377 { 2378 Mpi26DriverTriggerPage3_t tg_pg3; 2379 Mpi2ConfigReply_t mpi_reply; 2380 int rc, i, count; 2381 u16 ioc_status; 2382 2383 rc = mpt3sas_config_update_driver_trigger_pg0(ioc, 2384 MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, set); 2385 if (rc) 2386 return rc; 2387 2388 rc = mpt3sas_config_get_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3); 2389 if (rc) 2390 goto out; 2391 2392 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2393 MPI2_IOCSTATUS_MASK; 2394 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2395 dcprintk(ioc, 2396 ioc_err(ioc, 2397 "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n", 2398 __func__, ioc_status)); 2399 return -EFAULT; 2400 } 2401 2402 if (set) { 2403 count = scsi_tg->ValidEntries; 2404 tg_pg3.NumSCSISenseTrigger = cpu_to_le16(count); 2405 for (i = 0; i < count; i++) { 2406 tg_pg3.SCSISenseTriggers[i].ASCQ = 2407 scsi_tg->SCSITriggerEntry[i].ASCQ; 2408 tg_pg3.SCSISenseTriggers[i].ASC = 2409 scsi_tg->SCSITriggerEntry[i].ASC; 2410 tg_pg3.SCSISenseTriggers[i].SenseKey = 2411 scsi_tg->SCSITriggerEntry[i].SenseKey; 2412 } 2413 } else { 2414 tg_pg3.NumSCSISenseTrigger = 0; 2415 memset(&tg_pg3.SCSISenseTriggers[0], 0, 2416 NUM_VALID_ENTRIES * sizeof( 2417 MPI26_DRIVER_SCSI_SENSE_TRIGGER_ENTRY)); 2418 } 2419 2420 rc = _config_set_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3); 2421 if (rc) 2422 goto out; 2423 2424 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2425 MPI2_IOCSTATUS_MASK; 2426 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2427 dcprintk(ioc, 2428 ioc_err(ioc, 2429 "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n", 2430 __func__, ioc_status)); 2431 return -EFAULT; 2432 } 2433 2434 return 0; 2435 out: 2436 mpt3sas_config_update_driver_trigger_pg0(ioc, 2437 MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, !set); 2438 2439 return rc; 2440 } 2441 2442 /** 2443 * mpt3sas_config_get_driver_trigger_pg4 - obtain driver trigger page 4 2444 * @ioc: per adapter object 2445 * @mpi_reply: reply mf payload returned from firmware 2446 * @config_page: contents of the config page 2447 * Context: sleep. 2448 * 2449 * Returns 0 for success, non-zero for failure. 2450 */ 2451 int 2452 mpt3sas_config_get_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc, 2453 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page) 2454 { 2455 Mpi2ConfigRequest_t mpi_request; 2456 int r; 2457 2458 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2459 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2460 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2461 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2462 mpi_request.ExtPageType = 2463 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 2464 mpi_request.Header.PageNumber = 4; 2465 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION; 2466 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2467 r = _config_request(ioc, &mpi_request, mpi_reply, 2468 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2469 if (r) 2470 goto out; 2471 2472 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 2473 r = _config_request(ioc, &mpi_request, mpi_reply, 2474 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2475 sizeof(*config_page)); 2476 out: 2477 return r; 2478 } 2479 2480 /** 2481 * _config_set_driver_trigger_pg4 - write driver trigger page 4 2482 * @ioc: per adapter object 2483 * @mpi_reply: reply mf payload returned from firmware 2484 * @config_page: contents of the config page 2485 * Context: sleep. 2486 * 2487 * Returns 0 for success, non-zero for failure. 2488 */ 2489 static int 2490 _config_set_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc, 2491 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page) 2492 { 2493 Mpi2ConfigRequest_t mpi_request; 2494 int r; 2495 2496 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2497 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2498 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2499 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2500 mpi_request.ExtPageType = 2501 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 2502 mpi_request.Header.PageNumber = 4; 2503 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION; 2504 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2505 r = _config_request(ioc, &mpi_request, mpi_reply, 2506 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2507 if (r) 2508 goto out; 2509 2510 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 2511 _config_request(ioc, &mpi_request, mpi_reply, 2512 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2513 sizeof(*config_page)); 2514 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 2515 r = _config_request(ioc, &mpi_request, mpi_reply, 2516 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2517 sizeof(*config_page)); 2518 out: 2519 return r; 2520 } 2521 2522 /** 2523 * mpt3sas_config_update_driver_trigger_pg4 - update driver trigger page 4 2524 * @ioc: per adapter object 2525 * @mpi_tg: mpi trigger list 2526 * @set: set ot clear trigger values 2527 * Context: sleep. 2528 * 2529 * Returns 0 for success, non-zero for failure. 2530 */ 2531 int 2532 mpt3sas_config_update_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc, 2533 struct SL_WH_MPI_TRIGGERS_T *mpi_tg, bool set) 2534 { 2535 Mpi26DriverTriggerPage4_t tg_pg4; 2536 Mpi2ConfigReply_t mpi_reply; 2537 int rc, i, count; 2538 u16 ioc_status; 2539 2540 rc = mpt3sas_config_update_driver_trigger_pg0(ioc, 2541 MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, set); 2542 if (rc) 2543 return rc; 2544 2545 rc = mpt3sas_config_get_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4); 2546 if (rc) 2547 goto out; 2548 2549 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2550 MPI2_IOCSTATUS_MASK; 2551 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2552 dcprintk(ioc, 2553 ioc_err(ioc, 2554 "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n", 2555 __func__, ioc_status)); 2556 rc = -EFAULT; 2557 goto out; 2558 } 2559 2560 if (set) { 2561 count = mpi_tg->ValidEntries; 2562 tg_pg4.NumIOCStatusLogInfoTrigger = cpu_to_le16(count); 2563 for (i = 0; i < count; i++) { 2564 tg_pg4.IOCStatusLoginfoTriggers[i].IOCStatus = 2565 cpu_to_le16(mpi_tg->MPITriggerEntry[i].IOCStatus); 2566 tg_pg4.IOCStatusLoginfoTriggers[i].LogInfo = 2567 cpu_to_le32(mpi_tg->MPITriggerEntry[i].IocLogInfo); 2568 } 2569 } else { 2570 tg_pg4.NumIOCStatusLogInfoTrigger = 0; 2571 memset(&tg_pg4.IOCStatusLoginfoTriggers[0], 0, 2572 NUM_VALID_ENTRIES * sizeof( 2573 MPI26_DRIVER_IOCSTATUS_LOGINFO_TRIGGER_ENTRY)); 2574 } 2575 2576 rc = _config_set_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4); 2577 if (rc) 2578 goto out; 2579 2580 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2581 MPI2_IOCSTATUS_MASK; 2582 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2583 dcprintk(ioc, 2584 ioc_err(ioc, 2585 "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n", 2586 __func__, ioc_status)); 2587 rc = -EFAULT; 2588 goto out; 2589 } 2590 2591 return 0; 2592 2593 out: 2594 mpt3sas_config_update_driver_trigger_pg0(ioc, 2595 MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, !set); 2596 2597 return rc; 2598 } 2599 2600 /** 2601 * mpt3sas_config_get_volume_handle - returns volume handle for give hidden 2602 * raid components 2603 * @ioc: per adapter object 2604 * @pd_handle: phys disk handle 2605 * @volume_handle: volume handle 2606 * Context: sleep. 2607 * 2608 * Return: 0 for success, non-zero for failure. 2609 */ 2610 int 2611 mpt3sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle, 2612 u16 *volume_handle) 2613 { 2614 Mpi2RaidConfigurationPage0_t *config_page = NULL; 2615 Mpi2ConfigRequest_t mpi_request; 2616 Mpi2ConfigReply_t mpi_reply; 2617 int r, i, config_page_sz; 2618 u16 ioc_status; 2619 int config_num; 2620 u16 element_type; 2621 u16 phys_disk_dev_handle; 2622 2623 *volume_handle = 0; 2624 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2625 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2626 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2627 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2628 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG; 2629 mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION; 2630 mpi_request.Header.PageNumber = 0; 2631 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2632 r = _config_request(ioc, &mpi_request, &mpi_reply, 2633 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2634 if (r) 2635 goto out; 2636 2637 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 2638 config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4); 2639 config_page = kmalloc(config_page_sz, GFP_KERNEL); 2640 if (!config_page) { 2641 r = -1; 2642 goto out; 2643 } 2644 2645 config_num = 0xff; 2646 while (1) { 2647 mpi_request.PageAddress = cpu_to_le32(config_num + 2648 MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM); 2649 r = _config_request(ioc, &mpi_request, &mpi_reply, 2650 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2651 config_page_sz); 2652 if (r) 2653 goto out; 2654 r = -1; 2655 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2656 MPI2_IOCSTATUS_MASK; 2657 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) 2658 goto out; 2659 for (i = 0; i < config_page->NumElements; i++) { 2660 element_type = le16_to_cpu(config_page-> 2661 ConfigElement[i].ElementFlags) & 2662 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE; 2663 if (element_type == 2664 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT || 2665 element_type == 2666 MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) { 2667 phys_disk_dev_handle = 2668 le16_to_cpu(config_page->ConfigElement[i]. 2669 PhysDiskDevHandle); 2670 if (phys_disk_dev_handle == pd_handle) { 2671 *volume_handle = 2672 le16_to_cpu(config_page-> 2673 ConfigElement[i].VolDevHandle); 2674 r = 0; 2675 goto out; 2676 } 2677 } else if (element_type == 2678 MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) { 2679 *volume_handle = 0; 2680 r = 0; 2681 goto out; 2682 } 2683 } 2684 config_num = config_page->ConfigNum; 2685 } 2686 out: 2687 kfree(config_page); 2688 return r; 2689 } 2690 2691 /** 2692 * mpt3sas_config_get_volume_wwid - returns wwid given the volume handle 2693 * @ioc: per adapter object 2694 * @volume_handle: volume handle 2695 * @wwid: volume wwid 2696 * Context: sleep. 2697 * 2698 * Return: 0 for success, non-zero for failure. 2699 */ 2700 int 2701 mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc, u16 volume_handle, 2702 u64 *wwid) 2703 { 2704 Mpi2ConfigReply_t mpi_reply; 2705 Mpi2RaidVolPage1_t raid_vol_pg1; 2706 2707 *wwid = 0; 2708 if (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply, 2709 &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, 2710 volume_handle))) { 2711 *wwid = le64_to_cpu(raid_vol_pg1.WWID); 2712 return 0; 2713 } else 2714 return -1; 2715 } 2716