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->shost_recovery) || (ioc->config_cmds.status & 398 MPT3_CMD_RESET) || ioc->pci_error_recovery) 399 goto retry_config; 400 issue_host_reset = 1; 401 goto free_mem; 402 } 403 404 if (ioc->config_cmds.status & MPT3_CMD_REPLY_VALID) { 405 memcpy(mpi_reply, ioc->config_cmds.reply, 406 sizeof(Mpi2ConfigReply_t)); 407 408 /* Reply Frame Sanity Checks to workaround FW issues */ 409 if ((mpi_request->Header.PageType & 0xF) != 410 (mpi_reply->Header.PageType & 0xF)) { 411 if (!(ioc->logging_level & MPT_DEBUG_CONFIG)) 412 _config_display_some_debug(ioc, 413 smid, "config_request", NULL); 414 _debug_dump_mf(mpi_request, ioc->request_sz/4); 415 _debug_dump_reply(mpi_reply, ioc->reply_sz/4); 416 panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n", 417 ioc->name, __func__, 418 mpi_request->Header.PageType & 0xF, 419 mpi_reply->Header.PageType & 0xF); 420 } 421 422 if (((mpi_request->Header.PageType & 0xF) == 423 MPI2_CONFIG_PAGETYPE_EXTENDED) && 424 mpi_request->ExtPageType != mpi_reply->ExtPageType) { 425 if (!(ioc->logging_level & MPT_DEBUG_CONFIG)) 426 _config_display_some_debug(ioc, 427 smid, "config_request", NULL); 428 _debug_dump_mf(mpi_request, ioc->request_sz/4); 429 _debug_dump_reply(mpi_reply, ioc->reply_sz/4); 430 panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n", 431 ioc->name, __func__, 432 mpi_request->ExtPageType, 433 mpi_reply->ExtPageType); 434 } 435 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) 436 & MPI2_IOCSTATUS_MASK; 437 } 438 439 if (retry_count) 440 ioc_info(ioc, "%s: retry (%d) completed!!\n", 441 __func__, retry_count); 442 443 if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) && 444 config_page && mpi_request->Action == 445 MPI2_CONFIG_ACTION_PAGE_READ_CURRENT) { 446 u8 *p = (u8 *)mem.page; 447 448 /* Config Page Sanity Checks to workaround FW issues */ 449 if (p) { 450 if ((mpi_request->Header.PageType & 0xF) != 451 (p[3] & 0xF)) { 452 if (!(ioc->logging_level & MPT_DEBUG_CONFIG)) 453 _config_display_some_debug(ioc, 454 smid, "config_request", NULL); 455 _debug_dump_mf(mpi_request, ioc->request_sz/4); 456 _debug_dump_reply(mpi_reply, ioc->reply_sz/4); 457 _debug_dump_config(p, min_t(u16, mem.sz, 458 config_page_sz)/4); 459 panic("%s: %s: Firmware BUG: config page mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n", 460 ioc->name, __func__, 461 mpi_request->Header.PageType & 0xF, 462 p[3] & 0xF); 463 } 464 465 if (((mpi_request->Header.PageType & 0xF) == 466 MPI2_CONFIG_PAGETYPE_EXTENDED) && 467 (mpi_request->ExtPageType != p[6])) { 468 if (!(ioc->logging_level & MPT_DEBUG_CONFIG)) 469 _config_display_some_debug(ioc, 470 smid, "config_request", NULL); 471 _debug_dump_mf(mpi_request, ioc->request_sz/4); 472 _debug_dump_reply(mpi_reply, ioc->reply_sz/4); 473 _debug_dump_config(p, min_t(u16, mem.sz, 474 config_page_sz)/4); 475 panic("%s: %s: Firmware BUG: config page mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n", 476 ioc->name, __func__, 477 mpi_request->ExtPageType, p[6]); 478 } 479 } 480 memcpy(config_page, mem.page, min_t(u16, mem.sz, 481 config_page_sz)); 482 } 483 484 free_mem: 485 if (config_page) 486 _config_free_config_dma_memory(ioc, &mem); 487 out: 488 ioc->config_cmds.status = MPT3_CMD_NOT_USED; 489 mutex_unlock(&ioc->config_cmds.mutex); 490 491 if (issue_host_reset) { 492 if (ioc->drv_internal_flags & MPT_DRV_INTERNAL_FIRST_PE_ISSUED) { 493 mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER); 494 r = -EFAULT; 495 } else { 496 if (mpt3sas_base_check_for_fault_and_issue_reset(ioc)) 497 return -EFAULT; 498 r = -EAGAIN; 499 } 500 } 501 return r; 502 } 503 504 /** 505 * mpt3sas_config_get_manufacturing_pg0 - obtain manufacturing page 0 506 * @ioc: per adapter object 507 * @mpi_reply: reply mf payload returned from firmware 508 * @config_page: contents of the config page 509 * Context: sleep. 510 * 511 * Return: 0 for success, non-zero for failure. 512 */ 513 int 514 mpt3sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER *ioc, 515 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page) 516 { 517 Mpi2ConfigRequest_t mpi_request; 518 int r; 519 520 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 521 mpi_request.Function = MPI2_FUNCTION_CONFIG; 522 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 523 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; 524 mpi_request.Header.PageNumber = 0; 525 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; 526 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 527 r = _config_request(ioc, &mpi_request, mpi_reply, 528 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 529 if (r) 530 goto out; 531 532 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 533 r = _config_request(ioc, &mpi_request, mpi_reply, 534 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 535 sizeof(*config_page)); 536 out: 537 return r; 538 } 539 540 /** 541 * mpt3sas_config_get_manufacturing_pg7 - obtain manufacturing page 7 542 * @ioc: per adapter object 543 * @mpi_reply: reply mf payload returned from firmware 544 * @config_page: contents of the config page 545 * @sz: size of buffer passed in config_page 546 * Context: sleep. 547 * 548 * Return: 0 for success, non-zero for failure. 549 */ 550 int 551 mpt3sas_config_get_manufacturing_pg7(struct MPT3SAS_ADAPTER *ioc, 552 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage7_t *config_page, 553 u16 sz) 554 { 555 Mpi2ConfigRequest_t mpi_request; 556 int r; 557 558 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 559 mpi_request.Function = MPI2_FUNCTION_CONFIG; 560 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 561 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; 562 mpi_request.Header.PageNumber = 7; 563 mpi_request.Header.PageVersion = MPI2_MANUFACTURING7_PAGEVERSION; 564 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 565 r = _config_request(ioc, &mpi_request, mpi_reply, 566 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 567 if (r) 568 goto out; 569 570 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 571 r = _config_request(ioc, &mpi_request, mpi_reply, 572 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 573 sz); 574 out: 575 return r; 576 } 577 578 /** 579 * mpt3sas_config_get_manufacturing_pg10 - obtain manufacturing page 10 580 * @ioc: per adapter object 581 * @mpi_reply: reply mf payload returned from firmware 582 * @config_page: contents of the config page 583 * Context: sleep. 584 * 585 * Return: 0 for success, non-zero for failure. 586 */ 587 int 588 mpt3sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER *ioc, 589 Mpi2ConfigReply_t *mpi_reply, 590 struct Mpi2ManufacturingPage10_t *config_page) 591 { 592 Mpi2ConfigRequest_t mpi_request; 593 int r; 594 595 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 596 mpi_request.Function = MPI2_FUNCTION_CONFIG; 597 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 598 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; 599 mpi_request.Header.PageNumber = 10; 600 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; 601 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 602 r = _config_request(ioc, &mpi_request, mpi_reply, 603 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 604 if (r) 605 goto out; 606 607 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 608 r = _config_request(ioc, &mpi_request, mpi_reply, 609 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 610 sizeof(*config_page)); 611 out: 612 return r; 613 } 614 615 /** 616 * mpt3sas_config_get_manufacturing_pg11 - obtain manufacturing page 11 617 * @ioc: per adapter object 618 * @mpi_reply: reply mf payload returned from firmware 619 * @config_page: contents of the config page 620 * Context: sleep. 621 * 622 * Return: 0 for success, non-zero for failure. 623 */ 624 int 625 mpt3sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc, 626 Mpi2ConfigReply_t *mpi_reply, 627 struct Mpi2ManufacturingPage11_t *config_page) 628 { 629 Mpi2ConfigRequest_t mpi_request; 630 int r; 631 632 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 633 mpi_request.Function = MPI2_FUNCTION_CONFIG; 634 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 635 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; 636 mpi_request.Header.PageNumber = 11; 637 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; 638 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 639 r = _config_request(ioc, &mpi_request, mpi_reply, 640 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 641 if (r) 642 goto out; 643 644 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 645 r = _config_request(ioc, &mpi_request, mpi_reply, 646 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 647 sizeof(*config_page)); 648 out: 649 return r; 650 } 651 652 /** 653 * mpt3sas_config_set_manufacturing_pg11 - set manufacturing page 11 654 * @ioc: per adapter object 655 * @mpi_reply: reply mf payload returned from firmware 656 * @config_page: contents of the config page 657 * Context: sleep. 658 * 659 * Return: 0 for success, non-zero for failure. 660 */ 661 int 662 mpt3sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc, 663 Mpi2ConfigReply_t *mpi_reply, 664 struct Mpi2ManufacturingPage11_t *config_page) 665 { 666 Mpi2ConfigRequest_t mpi_request; 667 int r; 668 669 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 670 mpi_request.Function = MPI2_FUNCTION_CONFIG; 671 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 672 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; 673 mpi_request.Header.PageNumber = 11; 674 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; 675 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 676 r = _config_request(ioc, &mpi_request, mpi_reply, 677 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 678 if (r) 679 goto out; 680 681 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 682 r = _config_request(ioc, &mpi_request, mpi_reply, 683 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 684 sizeof(*config_page)); 685 out: 686 return r; 687 } 688 689 /** 690 * mpt3sas_config_get_bios_pg2 - obtain bios page 2 691 * @ioc: per adapter object 692 * @mpi_reply: reply mf payload returned from firmware 693 * @config_page: contents of the config page 694 * Context: sleep. 695 * 696 * Return: 0 for success, non-zero for failure. 697 */ 698 int 699 mpt3sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER *ioc, 700 Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page) 701 { 702 Mpi2ConfigRequest_t mpi_request; 703 int r; 704 705 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 706 mpi_request.Function = MPI2_FUNCTION_CONFIG; 707 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 708 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS; 709 mpi_request.Header.PageNumber = 2; 710 mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION; 711 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 712 r = _config_request(ioc, &mpi_request, mpi_reply, 713 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 714 if (r) 715 goto out; 716 717 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 718 r = _config_request(ioc, &mpi_request, mpi_reply, 719 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 720 sizeof(*config_page)); 721 out: 722 return r; 723 } 724 725 /** 726 * mpt3sas_config_get_bios_pg3 - obtain bios page 3 727 * @ioc: per adapter object 728 * @mpi_reply: reply mf payload returned from firmware 729 * @config_page: contents of the config page 730 * Context: sleep. 731 * 732 * Return: 0 for success, non-zero for failure. 733 */ 734 int 735 mpt3sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 736 *mpi_reply, Mpi2BiosPage3_t *config_page) 737 { 738 Mpi2ConfigRequest_t mpi_request; 739 int r; 740 741 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 742 mpi_request.Function = MPI2_FUNCTION_CONFIG; 743 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 744 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS; 745 mpi_request.Header.PageNumber = 3; 746 mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION; 747 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 748 r = _config_request(ioc, &mpi_request, mpi_reply, 749 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 750 if (r) 751 goto out; 752 753 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 754 r = _config_request(ioc, &mpi_request, mpi_reply, 755 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 756 sizeof(*config_page)); 757 out: 758 return r; 759 } 760 761 /** 762 * mpt3sas_config_get_iounit_pg0 - obtain iounit page 0 763 * @ioc: per adapter object 764 * @mpi_reply: reply mf payload returned from firmware 765 * @config_page: contents of the config page 766 * Context: sleep. 767 * 768 * Return: 0 for success, non-zero for failure. 769 */ 770 int 771 mpt3sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER *ioc, 772 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page) 773 { 774 Mpi2ConfigRequest_t mpi_request; 775 int r; 776 777 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 778 mpi_request.Function = MPI2_FUNCTION_CONFIG; 779 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 780 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; 781 mpi_request.Header.PageNumber = 0; 782 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION; 783 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 784 r = _config_request(ioc, &mpi_request, mpi_reply, 785 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 786 if (r) 787 goto out; 788 789 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 790 r = _config_request(ioc, &mpi_request, mpi_reply, 791 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 792 sizeof(*config_page)); 793 out: 794 return r; 795 } 796 797 /** 798 * mpt3sas_config_get_iounit_pg1 - obtain iounit page 1 799 * @ioc: per adapter object 800 * @mpi_reply: reply mf payload returned from firmware 801 * @config_page: contents of the config page 802 * Context: sleep. 803 * 804 * Return: 0 for success, non-zero for failure. 805 */ 806 int 807 mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, 808 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page) 809 { 810 Mpi2ConfigRequest_t mpi_request; 811 int r; 812 813 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 814 mpi_request.Function = MPI2_FUNCTION_CONFIG; 815 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 816 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; 817 mpi_request.Header.PageNumber = 1; 818 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION; 819 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 820 r = _config_request(ioc, &mpi_request, mpi_reply, 821 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 822 if (r) 823 goto out; 824 825 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 826 r = _config_request(ioc, &mpi_request, mpi_reply, 827 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 828 sizeof(*config_page)); 829 out: 830 return r; 831 } 832 833 /** 834 * mpt3sas_config_set_iounit_pg1 - set iounit page 1 835 * @ioc: per adapter object 836 * @mpi_reply: reply mf payload returned from firmware 837 * @config_page: contents of the config page 838 * Context: sleep. 839 * 840 * Return: 0 for success, non-zero for failure. 841 */ 842 int 843 mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, 844 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page) 845 { 846 Mpi2ConfigRequest_t mpi_request; 847 int r; 848 849 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 850 mpi_request.Function = MPI2_FUNCTION_CONFIG; 851 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 852 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; 853 mpi_request.Header.PageNumber = 1; 854 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION; 855 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 856 r = _config_request(ioc, &mpi_request, mpi_reply, 857 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 858 if (r) 859 goto out; 860 861 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 862 r = _config_request(ioc, &mpi_request, mpi_reply, 863 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 864 sizeof(*config_page)); 865 out: 866 return r; 867 } 868 869 /** 870 * mpt3sas_config_get_iounit_pg3 - obtain iounit page 3 871 * @ioc: per adapter object 872 * @mpi_reply: reply mf payload returned from firmware 873 * @config_page: contents of the config page 874 * @sz: size of buffer passed in config_page 875 * Context: sleep. 876 * 877 * Return: 0 for success, non-zero for failure. 878 */ 879 int 880 mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc, 881 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz) 882 { 883 Mpi2ConfigRequest_t mpi_request; 884 int r; 885 886 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 887 mpi_request.Function = MPI2_FUNCTION_CONFIG; 888 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 889 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; 890 mpi_request.Header.PageNumber = 3; 891 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION; 892 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 893 r = _config_request(ioc, &mpi_request, mpi_reply, 894 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 895 if (r) 896 goto out; 897 898 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 899 r = _config_request(ioc, &mpi_request, mpi_reply, 900 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 901 out: 902 return r; 903 } 904 905 /** 906 * mpt3sas_config_get_iounit_pg8 - obtain iounit page 8 907 * @ioc: per adapter object 908 * @mpi_reply: reply mf payload returned from firmware 909 * @config_page: contents of the config page 910 * Context: sleep. 911 * 912 * Return: 0 for success, non-zero for failure. 913 */ 914 int 915 mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc, 916 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page) 917 { 918 Mpi2ConfigRequest_t mpi_request; 919 int r; 920 921 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 922 mpi_request.Function = MPI2_FUNCTION_CONFIG; 923 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 924 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; 925 mpi_request.Header.PageNumber = 8; 926 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION; 927 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 928 r = _config_request(ioc, &mpi_request, mpi_reply, 929 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 930 if (r) 931 goto out; 932 933 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 934 r = _config_request(ioc, &mpi_request, mpi_reply, 935 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 936 sizeof(*config_page)); 937 out: 938 return r; 939 } 940 941 /** 942 * mpt3sas_config_get_ioc_pg8 - obtain ioc page 8 943 * @ioc: per adapter object 944 * @mpi_reply: reply mf payload returned from firmware 945 * @config_page: contents of the config page 946 * Context: sleep. 947 * 948 * Return: 0 for success, non-zero for failure. 949 */ 950 int 951 mpt3sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER *ioc, 952 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page) 953 { 954 Mpi2ConfigRequest_t mpi_request; 955 int r; 956 957 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 958 mpi_request.Function = MPI2_FUNCTION_CONFIG; 959 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 960 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC; 961 mpi_request.Header.PageNumber = 8; 962 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION; 963 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 964 r = _config_request(ioc, &mpi_request, mpi_reply, 965 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 966 if (r) 967 goto out; 968 969 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 970 r = _config_request(ioc, &mpi_request, mpi_reply, 971 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 972 sizeof(*config_page)); 973 out: 974 return r; 975 } 976 /** 977 * mpt3sas_config_get_ioc_pg1 - obtain ioc page 1 978 * @ioc: per adapter object 979 * @mpi_reply: reply mf payload returned from firmware 980 * @config_page: contents of the config page 981 * Context: sleep. 982 * 983 * Return: 0 for success, non-zero for failure. 984 */ 985 int 986 mpt3sas_config_get_ioc_pg1(struct MPT3SAS_ADAPTER *ioc, 987 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page) 988 { 989 Mpi2ConfigRequest_t mpi_request; 990 int r; 991 992 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 993 mpi_request.Function = MPI2_FUNCTION_CONFIG; 994 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 995 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC; 996 mpi_request.Header.PageNumber = 1; 997 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION; 998 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 999 r = _config_request(ioc, &mpi_request, mpi_reply, 1000 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1001 if (r) 1002 goto out; 1003 1004 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1005 r = _config_request(ioc, &mpi_request, mpi_reply, 1006 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1007 sizeof(*config_page)); 1008 out: 1009 return r; 1010 } 1011 1012 /** 1013 * mpt3sas_config_set_ioc_pg1 - modify ioc page 1 1014 * @ioc: per adapter object 1015 * @mpi_reply: reply mf payload returned from firmware 1016 * @config_page: contents of the config page 1017 * Context: sleep. 1018 * 1019 * Return: 0 for success, non-zero for failure. 1020 */ 1021 int 1022 mpt3sas_config_set_ioc_pg1(struct MPT3SAS_ADAPTER *ioc, 1023 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page) 1024 { 1025 Mpi2ConfigRequest_t mpi_request; 1026 int r; 1027 1028 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1029 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1030 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1031 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC; 1032 mpi_request.Header.PageNumber = 1; 1033 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION; 1034 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1035 r = _config_request(ioc, &mpi_request, mpi_reply, 1036 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1037 if (r) 1038 goto out; 1039 1040 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 1041 r = _config_request(ioc, &mpi_request, mpi_reply, 1042 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1043 sizeof(*config_page)); 1044 out: 1045 return r; 1046 } 1047 1048 /** 1049 * mpt3sas_config_get_sas_device_pg0 - obtain sas device page 0 1050 * @ioc: per adapter object 1051 * @mpi_reply: reply mf payload returned from firmware 1052 * @config_page: contents of the config page 1053 * @form: GET_NEXT_HANDLE or HANDLE 1054 * @handle: device handle 1055 * Context: sleep. 1056 * 1057 * Return: 0 for success, non-zero for failure. 1058 */ 1059 int 1060 mpt3sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc, 1061 Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage0_t *config_page, 1062 u32 form, u32 handle) 1063 { 1064 Mpi2ConfigRequest_t mpi_request; 1065 int r; 1066 1067 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1068 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1069 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1070 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1071 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE; 1072 mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION; 1073 mpi_request.Header.PageNumber = 0; 1074 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1075 r = _config_request(ioc, &mpi_request, mpi_reply, 1076 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1077 if (r) 1078 goto out; 1079 1080 mpi_request.PageAddress = cpu_to_le32(form | handle); 1081 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1082 r = _config_request(ioc, &mpi_request, mpi_reply, 1083 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1084 sizeof(*config_page)); 1085 out: 1086 return r; 1087 } 1088 1089 /** 1090 * mpt3sas_config_get_sas_device_pg1 - obtain sas device page 1 1091 * @ioc: per adapter object 1092 * @mpi_reply: reply mf payload returned from firmware 1093 * @config_page: contents of the config page 1094 * @form: GET_NEXT_HANDLE or HANDLE 1095 * @handle: device handle 1096 * Context: sleep. 1097 * 1098 * Return: 0 for success, non-zero for failure. 1099 */ 1100 int 1101 mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc, 1102 Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page, 1103 u32 form, u32 handle) 1104 { 1105 Mpi2ConfigRequest_t mpi_request; 1106 int r; 1107 1108 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1109 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1110 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1111 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1112 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE; 1113 mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION; 1114 mpi_request.Header.PageNumber = 1; 1115 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1116 r = _config_request(ioc, &mpi_request, mpi_reply, 1117 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1118 if (r) 1119 goto out; 1120 1121 mpi_request.PageAddress = cpu_to_le32(form | handle); 1122 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1123 r = _config_request(ioc, &mpi_request, mpi_reply, 1124 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1125 sizeof(*config_page)); 1126 out: 1127 return r; 1128 } 1129 1130 /** 1131 * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 0 1132 * @ioc: per adapter object 1133 * @mpi_reply: reply mf payload returned from firmware 1134 * @config_page: contents of the config page 1135 * @form: GET_NEXT_HANDLE or HANDLE 1136 * @handle: device handle 1137 * Context: sleep. 1138 * 1139 * Return: 0 for success, non-zero for failure. 1140 */ 1141 int 1142 mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc, 1143 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page, 1144 u32 form, u32 handle) 1145 { 1146 Mpi2ConfigRequest_t mpi_request; 1147 int r; 1148 1149 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1150 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1151 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1152 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1153 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE; 1154 mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION; 1155 mpi_request.Header.PageNumber = 0; 1156 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1157 r = _config_request(ioc, &mpi_request, mpi_reply, 1158 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1159 if (r) 1160 goto out; 1161 1162 mpi_request.PageAddress = cpu_to_le32(form | handle); 1163 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1164 r = _config_request(ioc, &mpi_request, mpi_reply, 1165 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1166 sizeof(*config_page)); 1167 out: 1168 return r; 1169 } 1170 1171 /** 1172 * mpt3sas_config_get_pcie_device_pg2 - obtain pcie device page 2 1173 * @ioc: per adapter object 1174 * @mpi_reply: reply mf payload returned from firmware 1175 * @config_page: contents of the config page 1176 * @form: GET_NEXT_HANDLE or HANDLE 1177 * @handle: device handle 1178 * Context: sleep. 1179 * 1180 * Return: 0 for success, non-zero for failure. 1181 */ 1182 int 1183 mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc, 1184 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page, 1185 u32 form, u32 handle) 1186 { 1187 Mpi2ConfigRequest_t mpi_request; 1188 int r; 1189 1190 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1191 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1192 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1193 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1194 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE; 1195 mpi_request.Header.PageVersion = MPI26_PCIEDEVICE2_PAGEVERSION; 1196 mpi_request.Header.PageNumber = 2; 1197 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1198 r = _config_request(ioc, &mpi_request, mpi_reply, 1199 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1200 if (r) 1201 goto out; 1202 1203 mpi_request.PageAddress = cpu_to_le32(form | handle); 1204 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1205 r = _config_request(ioc, &mpi_request, mpi_reply, 1206 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1207 sizeof(*config_page)); 1208 out: 1209 return r; 1210 } 1211 1212 /** 1213 * mpt3sas_config_get_number_hba_phys - obtain number of phys on the host 1214 * @ioc: per adapter object 1215 * @num_phys: pointer returned with the number of phys 1216 * Context: sleep. 1217 * 1218 * Return: 0 for success, non-zero for failure. 1219 */ 1220 int 1221 mpt3sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER *ioc, u8 *num_phys) 1222 { 1223 Mpi2ConfigRequest_t mpi_request; 1224 int r; 1225 u16 ioc_status; 1226 Mpi2ConfigReply_t mpi_reply; 1227 Mpi2SasIOUnitPage0_t config_page; 1228 1229 *num_phys = 0; 1230 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1231 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1232 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1233 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1234 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; 1235 mpi_request.Header.PageNumber = 0; 1236 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION; 1237 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1238 r = _config_request(ioc, &mpi_request, &mpi_reply, 1239 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1240 if (r) 1241 goto out; 1242 1243 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1244 r = _config_request(ioc, &mpi_request, &mpi_reply, 1245 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page, 1246 sizeof(Mpi2SasIOUnitPage0_t)); 1247 if (!r) { 1248 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1249 MPI2_IOCSTATUS_MASK; 1250 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) 1251 *num_phys = config_page.NumPhys; 1252 } 1253 out: 1254 return r; 1255 } 1256 1257 /** 1258 * mpt3sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0 1259 * @ioc: per adapter object 1260 * @mpi_reply: reply mf payload returned from firmware 1261 * @config_page: contents of the config page 1262 * @sz: size of buffer passed in config_page 1263 * Context: sleep. 1264 * 1265 * Calling function should call config_get_number_hba_phys prior to 1266 * this function, so enough memory is allocated for config_page. 1267 * 1268 * Return: 0 for success, non-zero for failure. 1269 */ 1270 int 1271 mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc, 1272 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page, 1273 u16 sz) 1274 { 1275 Mpi2ConfigRequest_t mpi_request; 1276 int r; 1277 1278 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1279 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1280 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1281 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1282 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; 1283 mpi_request.Header.PageNumber = 0; 1284 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION; 1285 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1286 r = _config_request(ioc, &mpi_request, mpi_reply, 1287 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1288 if (r) 1289 goto out; 1290 1291 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1292 r = _config_request(ioc, &mpi_request, mpi_reply, 1293 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 1294 out: 1295 return r; 1296 } 1297 1298 /** 1299 * mpt3sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1 1300 * @ioc: per adapter object 1301 * @mpi_reply: reply mf payload returned from firmware 1302 * @config_page: contents of the config page 1303 * @sz: size of buffer passed in config_page 1304 * Context: sleep. 1305 * 1306 * Calling function should call config_get_number_hba_phys prior to 1307 * this function, so enough memory is allocated for config_page. 1308 * 1309 * Return: 0 for success, non-zero for failure. 1310 */ 1311 int 1312 mpt3sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, 1313 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, 1314 u16 sz) 1315 { 1316 Mpi2ConfigRequest_t mpi_request; 1317 int r; 1318 1319 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1320 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1321 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1322 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1323 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; 1324 mpi_request.Header.PageNumber = 1; 1325 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION; 1326 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1327 r = _config_request(ioc, &mpi_request, mpi_reply, 1328 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1329 if (r) 1330 goto out; 1331 1332 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1333 r = _config_request(ioc, &mpi_request, mpi_reply, 1334 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 1335 out: 1336 return r; 1337 } 1338 1339 /** 1340 * mpt3sas_config_set_sas_iounit_pg1 - send sas iounit page 1 1341 * @ioc: per adapter object 1342 * @mpi_reply: reply mf payload returned from firmware 1343 * @config_page: contents of the config page 1344 * @sz: size of buffer passed in config_page 1345 * Context: sleep. 1346 * 1347 * Calling function should call config_get_number_hba_phys prior to 1348 * this function, so enough memory is allocated for config_page. 1349 * 1350 * Return: 0 for success, non-zero for failure. 1351 */ 1352 int 1353 mpt3sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, 1354 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, 1355 u16 sz) 1356 { 1357 Mpi2ConfigRequest_t mpi_request; 1358 int r; 1359 1360 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1361 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1362 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1363 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1364 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; 1365 mpi_request.Header.PageNumber = 1; 1366 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION; 1367 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1368 r = _config_request(ioc, &mpi_request, mpi_reply, 1369 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1370 if (r) 1371 goto out; 1372 1373 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 1374 _config_request(ioc, &mpi_request, mpi_reply, 1375 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 1376 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 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_expander_pg0 - obtain expander page 0 1385 * @ioc: per adapter object 1386 * @mpi_reply: reply mf payload returned from firmware 1387 * @config_page: contents of the config page 1388 * @form: GET_NEXT_HANDLE or HANDLE 1389 * @handle: expander handle 1390 * Context: sleep. 1391 * 1392 * Return: 0 for success, non-zero for failure. 1393 */ 1394 int 1395 mpt3sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1396 *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle) 1397 { 1398 Mpi2ConfigRequest_t mpi_request; 1399 int r; 1400 1401 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1402 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1403 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1404 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1405 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER; 1406 mpi_request.Header.PageNumber = 0; 1407 mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION; 1408 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1409 r = _config_request(ioc, &mpi_request, mpi_reply, 1410 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1411 if (r) 1412 goto out; 1413 1414 mpi_request.PageAddress = cpu_to_le32(form | handle); 1415 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1416 r = _config_request(ioc, &mpi_request, mpi_reply, 1417 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1418 sizeof(*config_page)); 1419 out: 1420 return r; 1421 } 1422 1423 /** 1424 * mpt3sas_config_get_expander_pg1 - obtain expander page 1 1425 * @ioc: per adapter object 1426 * @mpi_reply: reply mf payload returned from firmware 1427 * @config_page: contents of the config page 1428 * @phy_number: phy number 1429 * @handle: expander handle 1430 * Context: sleep. 1431 * 1432 * Return: 0 for success, non-zero for failure. 1433 */ 1434 int 1435 mpt3sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1436 *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number, 1437 u16 handle) 1438 { 1439 Mpi2ConfigRequest_t mpi_request; 1440 int r; 1441 1442 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1443 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1444 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1445 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1446 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER; 1447 mpi_request.Header.PageNumber = 1; 1448 mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION; 1449 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1450 r = _config_request(ioc, &mpi_request, mpi_reply, 1451 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1452 if (r) 1453 goto out; 1454 1455 mpi_request.PageAddress = 1456 cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM | 1457 (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle); 1458 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1459 r = _config_request(ioc, &mpi_request, mpi_reply, 1460 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1461 sizeof(*config_page)); 1462 out: 1463 return r; 1464 } 1465 1466 /** 1467 * mpt3sas_config_get_enclosure_pg0 - obtain enclosure page 0 1468 * @ioc: per adapter object 1469 * @mpi_reply: reply mf payload returned from firmware 1470 * @config_page: contents of the config page 1471 * @form: GET_NEXT_HANDLE or HANDLE 1472 * @handle: expander handle 1473 * Context: sleep. 1474 * 1475 * Return: 0 for success, non-zero for failure. 1476 */ 1477 int 1478 mpt3sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1479 *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle) 1480 { 1481 Mpi2ConfigRequest_t mpi_request; 1482 int r; 1483 1484 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1485 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1486 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1487 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1488 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE; 1489 mpi_request.Header.PageNumber = 0; 1490 mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION; 1491 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1492 r = _config_request(ioc, &mpi_request, mpi_reply, 1493 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1494 if (r) 1495 goto out; 1496 1497 mpi_request.PageAddress = cpu_to_le32(form | handle); 1498 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1499 r = _config_request(ioc, &mpi_request, mpi_reply, 1500 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1501 sizeof(*config_page)); 1502 out: 1503 return r; 1504 } 1505 1506 /** 1507 * mpt3sas_config_get_phy_pg0 - obtain phy page 0 1508 * @ioc: per adapter object 1509 * @mpi_reply: reply mf payload returned from firmware 1510 * @config_page: contents of the config page 1511 * @phy_number: phy number 1512 * Context: sleep. 1513 * 1514 * Return: 0 for success, non-zero for failure. 1515 */ 1516 int 1517 mpt3sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1518 *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number) 1519 { 1520 Mpi2ConfigRequest_t mpi_request; 1521 int r; 1522 1523 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1524 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1525 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1526 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1527 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY; 1528 mpi_request.Header.PageNumber = 0; 1529 mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION; 1530 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1531 r = _config_request(ioc, &mpi_request, mpi_reply, 1532 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1533 if (r) 1534 goto out; 1535 1536 mpi_request.PageAddress = 1537 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number); 1538 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1539 r = _config_request(ioc, &mpi_request, mpi_reply, 1540 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1541 sizeof(*config_page)); 1542 out: 1543 return r; 1544 } 1545 1546 /** 1547 * mpt3sas_config_get_phy_pg1 - obtain phy page 1 1548 * @ioc: per adapter object 1549 * @mpi_reply: reply mf payload returned from firmware 1550 * @config_page: contents of the config page 1551 * @phy_number: phy number 1552 * Context: sleep. 1553 * 1554 * Return: 0 for success, non-zero for failure. 1555 */ 1556 int 1557 mpt3sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1558 *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number) 1559 { 1560 Mpi2ConfigRequest_t mpi_request; 1561 int r; 1562 1563 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1564 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1565 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1566 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1567 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY; 1568 mpi_request.Header.PageNumber = 1; 1569 mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION; 1570 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1571 r = _config_request(ioc, &mpi_request, mpi_reply, 1572 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1573 if (r) 1574 goto out; 1575 1576 mpi_request.PageAddress = 1577 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number); 1578 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1579 r = _config_request(ioc, &mpi_request, mpi_reply, 1580 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1581 sizeof(*config_page)); 1582 out: 1583 return r; 1584 } 1585 1586 /** 1587 * mpt3sas_config_get_raid_volume_pg1 - obtain raid volume page 1 1588 * @ioc: per adapter object 1589 * @mpi_reply: reply mf payload returned from firmware 1590 * @config_page: contents of the config page 1591 * @form: GET_NEXT_HANDLE or HANDLE 1592 * @handle: volume handle 1593 * Context: sleep. 1594 * 1595 * Return: 0 for success, non-zero for failure. 1596 */ 1597 int 1598 mpt3sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER *ioc, 1599 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form, 1600 u32 handle) 1601 { 1602 Mpi2ConfigRequest_t mpi_request; 1603 int r; 1604 1605 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1606 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1607 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1608 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; 1609 mpi_request.Header.PageNumber = 1; 1610 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION; 1611 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1612 r = _config_request(ioc, &mpi_request, mpi_reply, 1613 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1614 if (r) 1615 goto out; 1616 1617 mpi_request.PageAddress = cpu_to_le32(form | handle); 1618 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1619 r = _config_request(ioc, &mpi_request, mpi_reply, 1620 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1621 sizeof(*config_page)); 1622 out: 1623 return r; 1624 } 1625 1626 /** 1627 * mpt3sas_config_get_number_pds - obtain number of phys disk assigned to volume 1628 * @ioc: per adapter object 1629 * @handle: volume handle 1630 * @num_pds: returns pds count 1631 * Context: sleep. 1632 * 1633 * Return: 0 for success, non-zero for failure. 1634 */ 1635 int 1636 mpt3sas_config_get_number_pds(struct MPT3SAS_ADAPTER *ioc, u16 handle, 1637 u8 *num_pds) 1638 { 1639 Mpi2ConfigRequest_t mpi_request; 1640 Mpi2RaidVolPage0_t config_page; 1641 Mpi2ConfigReply_t mpi_reply; 1642 int r; 1643 u16 ioc_status; 1644 1645 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1646 *num_pds = 0; 1647 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1648 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1649 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; 1650 mpi_request.Header.PageNumber = 0; 1651 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION; 1652 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1653 r = _config_request(ioc, &mpi_request, &mpi_reply, 1654 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1655 if (r) 1656 goto out; 1657 1658 mpi_request.PageAddress = 1659 cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle); 1660 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1661 r = _config_request(ioc, &mpi_request, &mpi_reply, 1662 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page, 1663 sizeof(Mpi2RaidVolPage0_t)); 1664 if (!r) { 1665 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1666 MPI2_IOCSTATUS_MASK; 1667 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) 1668 *num_pds = config_page.NumPhysDisks; 1669 } 1670 1671 out: 1672 return r; 1673 } 1674 1675 /** 1676 * mpt3sas_config_get_raid_volume_pg0 - obtain raid volume page 0 1677 * @ioc: per adapter object 1678 * @mpi_reply: reply mf payload returned from firmware 1679 * @config_page: contents of the config page 1680 * @form: GET_NEXT_HANDLE or HANDLE 1681 * @handle: volume handle 1682 * @sz: size of buffer passed in config_page 1683 * Context: sleep. 1684 * 1685 * Return: 0 for success, non-zero for failure. 1686 */ 1687 int 1688 mpt3sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER *ioc, 1689 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form, 1690 u32 handle, u16 sz) 1691 { 1692 Mpi2ConfigRequest_t mpi_request; 1693 int r; 1694 1695 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1696 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1697 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1698 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; 1699 mpi_request.Header.PageNumber = 0; 1700 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION; 1701 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1702 r = _config_request(ioc, &mpi_request, mpi_reply, 1703 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1704 if (r) 1705 goto out; 1706 1707 mpi_request.PageAddress = cpu_to_le32(form | handle); 1708 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1709 r = _config_request(ioc, &mpi_request, mpi_reply, 1710 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 1711 out: 1712 return r; 1713 } 1714 1715 /** 1716 * mpt3sas_config_get_phys_disk_pg0 - obtain phys disk page 0 1717 * @ioc: per adapter object 1718 * @mpi_reply: reply mf payload returned from firmware 1719 * @config_page: contents of the config page 1720 * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE 1721 * @form_specific: specific to the form 1722 * Context: sleep. 1723 * 1724 * Return: 0 for success, non-zero for failure. 1725 */ 1726 int 1727 mpt3sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1728 *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form, 1729 u32 form_specific) 1730 { 1731 Mpi2ConfigRequest_t mpi_request; 1732 int r; 1733 1734 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1735 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1736 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1737 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK; 1738 mpi_request.Header.PageNumber = 0; 1739 mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION; 1740 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1741 r = _config_request(ioc, &mpi_request, mpi_reply, 1742 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1743 if (r) 1744 goto out; 1745 1746 mpi_request.PageAddress = cpu_to_le32(form | form_specific); 1747 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1748 r = _config_request(ioc, &mpi_request, mpi_reply, 1749 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1750 sizeof(*config_page)); 1751 out: 1752 return r; 1753 } 1754 1755 /** 1756 * mpt3sas_config_get_driver_trigger_pg0 - obtain driver trigger page 0 1757 * @ioc: per adapter object 1758 * @mpi_reply: reply mf payload returned from firmware 1759 * @config_page: contents of the config page 1760 * Context: sleep. 1761 * 1762 * Returns 0 for success, non-zero for failure. 1763 */ 1764 int 1765 mpt3sas_config_get_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc, 1766 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page) 1767 { 1768 Mpi2ConfigRequest_t mpi_request; 1769 int r; 1770 1771 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1772 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1773 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1774 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1775 mpi_request.ExtPageType = 1776 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 1777 mpi_request.Header.PageNumber = 0; 1778 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION; 1779 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1780 r = _config_request(ioc, &mpi_request, mpi_reply, 1781 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1782 if (r) 1783 goto out; 1784 1785 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1786 r = _config_request(ioc, &mpi_request, mpi_reply, 1787 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1788 sizeof(*config_page)); 1789 out: 1790 return r; 1791 } 1792 1793 /** 1794 * _config_set_driver_trigger_pg0 - write driver trigger page 0 1795 * @ioc: per adapter object 1796 * @mpi_reply: reply mf payload returned from firmware 1797 * @config_page: contents of the config page 1798 * Context: sleep. 1799 * 1800 * Returns 0 for success, non-zero for failure. 1801 */ 1802 static int 1803 _config_set_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc, 1804 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page) 1805 { 1806 Mpi2ConfigRequest_t mpi_request; 1807 int r; 1808 1809 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1810 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1811 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1812 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1813 mpi_request.ExtPageType = 1814 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 1815 mpi_request.Header.PageNumber = 0; 1816 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION; 1817 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1818 r = _config_request(ioc, &mpi_request, mpi_reply, 1819 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1820 if (r) 1821 goto out; 1822 1823 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 1824 _config_request(ioc, &mpi_request, mpi_reply, 1825 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1826 sizeof(*config_page)); 1827 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 1828 r = _config_request(ioc, &mpi_request, mpi_reply, 1829 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1830 sizeof(*config_page)); 1831 out: 1832 return r; 1833 } 1834 1835 /** 1836 * mpt3sas_config_update_driver_trigger_pg0 - update driver trigger page 0 1837 * @ioc: per adapter object 1838 * @trigger_flag: trigger type bit map 1839 * @set: set ot clear trigger values 1840 * Context: sleep. 1841 * 1842 * Returns 0 for success, non-zero for failure. 1843 */ 1844 static int 1845 mpt3sas_config_update_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc, 1846 u16 trigger_flag, bool set) 1847 { 1848 Mpi26DriverTriggerPage0_t tg_pg0; 1849 Mpi2ConfigReply_t mpi_reply; 1850 int rc; 1851 u16 flags, ioc_status; 1852 1853 rc = mpt3sas_config_get_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0); 1854 if (rc) 1855 return rc; 1856 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1857 MPI2_IOCSTATUS_MASK; 1858 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 1859 dcprintk(ioc, 1860 ioc_err(ioc, 1861 "%s: Failed to get trigger pg0, ioc_status(0x%04x)\n", 1862 __func__, ioc_status)); 1863 return -EFAULT; 1864 } 1865 1866 if (set) 1867 flags = le16_to_cpu(tg_pg0.TriggerFlags) | trigger_flag; 1868 else 1869 flags = le16_to_cpu(tg_pg0.TriggerFlags) & ~trigger_flag; 1870 1871 tg_pg0.TriggerFlags = cpu_to_le16(flags); 1872 1873 rc = _config_set_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0); 1874 if (rc) 1875 return rc; 1876 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1877 MPI2_IOCSTATUS_MASK; 1878 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 1879 dcprintk(ioc, 1880 ioc_err(ioc, 1881 "%s: Failed to update trigger pg0, ioc_status(0x%04x)\n", 1882 __func__, ioc_status)); 1883 return -EFAULT; 1884 } 1885 1886 return 0; 1887 } 1888 1889 /** 1890 * mpt3sas_config_get_driver_trigger_pg1 - obtain driver trigger page 1 1891 * @ioc: per adapter object 1892 * @mpi_reply: reply mf payload returned from firmware 1893 * @config_page: contents of the config page 1894 * Context: sleep. 1895 * 1896 * Returns 0 for success, non-zero for failure. 1897 */ 1898 int 1899 mpt3sas_config_get_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc, 1900 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page) 1901 { 1902 Mpi2ConfigRequest_t mpi_request; 1903 int r; 1904 1905 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1906 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1907 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1908 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1909 mpi_request.ExtPageType = 1910 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 1911 mpi_request.Header.PageNumber = 1; 1912 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION; 1913 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1914 r = _config_request(ioc, &mpi_request, mpi_reply, 1915 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1916 if (r) 1917 goto out; 1918 1919 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1920 r = _config_request(ioc, &mpi_request, mpi_reply, 1921 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1922 sizeof(*config_page)); 1923 out: 1924 return r; 1925 } 1926 1927 /** 1928 * _config_set_driver_trigger_pg1 - write driver trigger page 1 1929 * @ioc: per adapter object 1930 * @mpi_reply: reply mf payload returned from firmware 1931 * @config_page: contents of the config page 1932 * Context: sleep. 1933 * 1934 * Returns 0 for success, non-zero for failure. 1935 */ 1936 static int 1937 _config_set_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc, 1938 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page) 1939 { 1940 Mpi2ConfigRequest_t mpi_request; 1941 int r; 1942 1943 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1944 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1945 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1946 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1947 mpi_request.ExtPageType = 1948 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 1949 mpi_request.Header.PageNumber = 1; 1950 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION; 1951 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1952 r = _config_request(ioc, &mpi_request, mpi_reply, 1953 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1954 if (r) 1955 goto out; 1956 1957 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 1958 _config_request(ioc, &mpi_request, mpi_reply, 1959 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1960 sizeof(*config_page)); 1961 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 1962 r = _config_request(ioc, &mpi_request, mpi_reply, 1963 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1964 sizeof(*config_page)); 1965 out: 1966 return r; 1967 } 1968 1969 /** 1970 * mpt3sas_config_update_driver_trigger_pg1 - update driver trigger page 1 1971 * @ioc: per adapter object 1972 * @master_tg: Master trigger bit map 1973 * @set: set ot clear trigger values 1974 * Context: sleep. 1975 * 1976 * Returns 0 for success, non-zero for failure. 1977 */ 1978 int 1979 mpt3sas_config_update_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc, 1980 struct SL_WH_MASTER_TRIGGER_T *master_tg, bool set) 1981 { 1982 Mpi26DriverTriggerPage1_t tg_pg1; 1983 Mpi2ConfigReply_t mpi_reply; 1984 int rc; 1985 u16 ioc_status; 1986 1987 rc = mpt3sas_config_update_driver_trigger_pg0(ioc, 1988 MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, set); 1989 if (rc) 1990 return rc; 1991 1992 rc = mpt3sas_config_get_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1); 1993 if (rc) 1994 goto out; 1995 1996 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1997 MPI2_IOCSTATUS_MASK; 1998 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 1999 dcprintk(ioc, 2000 ioc_err(ioc, 2001 "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n", 2002 __func__, ioc_status)); 2003 rc = -EFAULT; 2004 goto out; 2005 } 2006 2007 if (set) { 2008 tg_pg1.NumMasterTrigger = cpu_to_le16(1); 2009 tg_pg1.MasterTriggers[0].MasterTriggerFlags = cpu_to_le32( 2010 master_tg->MasterData); 2011 } else { 2012 tg_pg1.NumMasterTrigger = 0; 2013 tg_pg1.MasterTriggers[0].MasterTriggerFlags = 0; 2014 } 2015 2016 rc = _config_set_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1); 2017 if (rc) 2018 goto out; 2019 2020 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2021 MPI2_IOCSTATUS_MASK; 2022 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2023 dcprintk(ioc, 2024 ioc_err(ioc, 2025 "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n", 2026 __func__, ioc_status)); 2027 rc = -EFAULT; 2028 goto out; 2029 } 2030 2031 return 0; 2032 2033 out: 2034 mpt3sas_config_update_driver_trigger_pg0(ioc, 2035 MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, !set); 2036 2037 return rc; 2038 } 2039 2040 /** 2041 * mpt3sas_config_get_driver_trigger_pg2 - obtain driver trigger page 2 2042 * @ioc: per adapter object 2043 * @mpi_reply: reply mf payload returned from firmware 2044 * @config_page: contents of the config page 2045 * Context: sleep. 2046 * 2047 * Returns 0 for success, non-zero for failure. 2048 */ 2049 int 2050 mpt3sas_config_get_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc, 2051 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page) 2052 { 2053 Mpi2ConfigRequest_t mpi_request; 2054 int r; 2055 2056 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2057 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2058 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2059 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2060 mpi_request.ExtPageType = 2061 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 2062 mpi_request.Header.PageNumber = 2; 2063 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION; 2064 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2065 r = _config_request(ioc, &mpi_request, mpi_reply, 2066 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2067 if (r) 2068 goto out; 2069 2070 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 2071 r = _config_request(ioc, &mpi_request, mpi_reply, 2072 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2073 sizeof(*config_page)); 2074 out: 2075 return r; 2076 } 2077 2078 /** 2079 * _config_set_driver_trigger_pg2 - write driver trigger page 2 2080 * @ioc: per adapter object 2081 * @mpi_reply: reply mf payload returned from firmware 2082 * @config_page: contents of the config page 2083 * Context: sleep. 2084 * 2085 * Returns 0 for success, non-zero for failure. 2086 */ 2087 static int 2088 _config_set_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc, 2089 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page) 2090 { 2091 Mpi2ConfigRequest_t mpi_request; 2092 int r; 2093 2094 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2095 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2096 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2097 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2098 mpi_request.ExtPageType = 2099 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 2100 mpi_request.Header.PageNumber = 2; 2101 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION; 2102 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2103 r = _config_request(ioc, &mpi_request, mpi_reply, 2104 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2105 if (r) 2106 goto out; 2107 2108 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 2109 _config_request(ioc, &mpi_request, mpi_reply, 2110 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2111 sizeof(*config_page)); 2112 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 2113 r = _config_request(ioc, &mpi_request, mpi_reply, 2114 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2115 sizeof(*config_page)); 2116 out: 2117 return r; 2118 } 2119 2120 /** 2121 * mpt3sas_config_update_driver_trigger_pg2 - update driver trigger page 2 2122 * @ioc: per adapter object 2123 * @event_tg: list of Event Triggers 2124 * @set: set ot clear trigger values 2125 * Context: sleep. 2126 * 2127 * Returns 0 for success, non-zero for failure. 2128 */ 2129 int 2130 mpt3sas_config_update_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc, 2131 struct SL_WH_EVENT_TRIGGERS_T *event_tg, bool set) 2132 { 2133 Mpi26DriverTriggerPage2_t tg_pg2; 2134 Mpi2ConfigReply_t mpi_reply; 2135 int rc, i, count; 2136 u16 ioc_status; 2137 2138 rc = mpt3sas_config_update_driver_trigger_pg0(ioc, 2139 MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, set); 2140 if (rc) 2141 return rc; 2142 2143 rc = mpt3sas_config_get_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2); 2144 if (rc) 2145 goto out; 2146 2147 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2148 MPI2_IOCSTATUS_MASK; 2149 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2150 dcprintk(ioc, 2151 ioc_err(ioc, 2152 "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n", 2153 __func__, ioc_status)); 2154 rc = -EFAULT; 2155 goto out; 2156 } 2157 2158 if (set) { 2159 count = event_tg->ValidEntries; 2160 tg_pg2.NumMPIEventTrigger = cpu_to_le16(count); 2161 for (i = 0; i < count; i++) { 2162 tg_pg2.MPIEventTriggers[i].MPIEventCode = 2163 cpu_to_le16( 2164 event_tg->EventTriggerEntry[i].EventValue); 2165 tg_pg2.MPIEventTriggers[i].MPIEventCodeSpecific = 2166 cpu_to_le16( 2167 event_tg->EventTriggerEntry[i].LogEntryQualifier); 2168 } 2169 } else { 2170 tg_pg2.NumMPIEventTrigger = 0; 2171 memset(&tg_pg2.MPIEventTriggers[0], 0, 2172 NUM_VALID_ENTRIES * sizeof( 2173 MPI26_DRIVER_MPI_EVENT_TIGGER_ENTRY)); 2174 } 2175 2176 rc = _config_set_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2); 2177 if (rc) 2178 goto out; 2179 2180 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2181 MPI2_IOCSTATUS_MASK; 2182 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2183 dcprintk(ioc, 2184 ioc_err(ioc, 2185 "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n", 2186 __func__, ioc_status)); 2187 rc = -EFAULT; 2188 goto out; 2189 } 2190 2191 return 0; 2192 2193 out: 2194 mpt3sas_config_update_driver_trigger_pg0(ioc, 2195 MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, !set); 2196 2197 return rc; 2198 } 2199 2200 /** 2201 * mpt3sas_config_get_driver_trigger_pg3 - obtain driver trigger page 3 2202 * @ioc: per adapter object 2203 * @mpi_reply: reply mf payload returned from firmware 2204 * @config_page: contents of the config page 2205 * Context: sleep. 2206 * 2207 * Returns 0 for success, non-zero for failure. 2208 */ 2209 int 2210 mpt3sas_config_get_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc, 2211 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page) 2212 { 2213 Mpi2ConfigRequest_t mpi_request; 2214 int r; 2215 2216 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2217 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2218 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2219 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2220 mpi_request.ExtPageType = 2221 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 2222 mpi_request.Header.PageNumber = 3; 2223 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION; 2224 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2225 r = _config_request(ioc, &mpi_request, mpi_reply, 2226 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2227 if (r) 2228 goto out; 2229 2230 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 2231 r = _config_request(ioc, &mpi_request, mpi_reply, 2232 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2233 sizeof(*config_page)); 2234 out: 2235 return r; 2236 } 2237 2238 /** 2239 * _config_set_driver_trigger_pg3 - write driver trigger page 3 2240 * @ioc: per adapter object 2241 * @mpi_reply: reply mf payload returned from firmware 2242 * @config_page: contents of the config page 2243 * Context: sleep. 2244 * 2245 * Returns 0 for success, non-zero for failure. 2246 */ 2247 static int 2248 _config_set_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc, 2249 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page) 2250 { 2251 Mpi2ConfigRequest_t mpi_request; 2252 int r; 2253 2254 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2255 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2256 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2257 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2258 mpi_request.ExtPageType = 2259 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 2260 mpi_request.Header.PageNumber = 3; 2261 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION; 2262 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2263 r = _config_request(ioc, &mpi_request, mpi_reply, 2264 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2265 if (r) 2266 goto out; 2267 2268 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 2269 _config_request(ioc, &mpi_request, mpi_reply, 2270 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2271 sizeof(*config_page)); 2272 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 2273 r = _config_request(ioc, &mpi_request, mpi_reply, 2274 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2275 sizeof(*config_page)); 2276 out: 2277 return r; 2278 } 2279 2280 /** 2281 * mpt3sas_config_update_driver_trigger_pg3 - update driver trigger page 3 2282 * @ioc: per adapter object 2283 * @scsi_tg: scsi trigger list 2284 * @set: set ot clear trigger values 2285 * Context: sleep. 2286 * 2287 * Returns 0 for success, non-zero for failure. 2288 */ 2289 int 2290 mpt3sas_config_update_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc, 2291 struct SL_WH_SCSI_TRIGGERS_T *scsi_tg, bool set) 2292 { 2293 Mpi26DriverTriggerPage3_t tg_pg3; 2294 Mpi2ConfigReply_t mpi_reply; 2295 int rc, i, count; 2296 u16 ioc_status; 2297 2298 rc = mpt3sas_config_update_driver_trigger_pg0(ioc, 2299 MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, set); 2300 if (rc) 2301 return rc; 2302 2303 rc = mpt3sas_config_get_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3); 2304 if (rc) 2305 goto out; 2306 2307 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2308 MPI2_IOCSTATUS_MASK; 2309 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2310 dcprintk(ioc, 2311 ioc_err(ioc, 2312 "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n", 2313 __func__, ioc_status)); 2314 return -EFAULT; 2315 } 2316 2317 if (set) { 2318 count = scsi_tg->ValidEntries; 2319 tg_pg3.NumSCSISenseTrigger = cpu_to_le16(count); 2320 for (i = 0; i < count; i++) { 2321 tg_pg3.SCSISenseTriggers[i].ASCQ = 2322 scsi_tg->SCSITriggerEntry[i].ASCQ; 2323 tg_pg3.SCSISenseTriggers[i].ASC = 2324 scsi_tg->SCSITriggerEntry[i].ASC; 2325 tg_pg3.SCSISenseTriggers[i].SenseKey = 2326 scsi_tg->SCSITriggerEntry[i].SenseKey; 2327 } 2328 } else { 2329 tg_pg3.NumSCSISenseTrigger = 0; 2330 memset(&tg_pg3.SCSISenseTriggers[0], 0, 2331 NUM_VALID_ENTRIES * sizeof( 2332 MPI26_DRIVER_SCSI_SENSE_TIGGER_ENTRY)); 2333 } 2334 2335 rc = _config_set_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3); 2336 if (rc) 2337 goto out; 2338 2339 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2340 MPI2_IOCSTATUS_MASK; 2341 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2342 dcprintk(ioc, 2343 ioc_err(ioc, 2344 "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n", 2345 __func__, ioc_status)); 2346 return -EFAULT; 2347 } 2348 2349 return 0; 2350 out: 2351 mpt3sas_config_update_driver_trigger_pg0(ioc, 2352 MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, !set); 2353 2354 return rc; 2355 } 2356 2357 /** 2358 * mpt3sas_config_get_driver_trigger_pg4 - obtain driver trigger page 4 2359 * @ioc: per adapter object 2360 * @mpi_reply: reply mf payload returned from firmware 2361 * @config_page: contents of the config page 2362 * Context: sleep. 2363 * 2364 * Returns 0 for success, non-zero for failure. 2365 */ 2366 int 2367 mpt3sas_config_get_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc, 2368 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page) 2369 { 2370 Mpi2ConfigRequest_t mpi_request; 2371 int r; 2372 2373 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2374 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2375 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2376 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2377 mpi_request.ExtPageType = 2378 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 2379 mpi_request.Header.PageNumber = 4; 2380 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION; 2381 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2382 r = _config_request(ioc, &mpi_request, mpi_reply, 2383 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2384 if (r) 2385 goto out; 2386 2387 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 2388 r = _config_request(ioc, &mpi_request, mpi_reply, 2389 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2390 sizeof(*config_page)); 2391 out: 2392 return r; 2393 } 2394 2395 /** 2396 * _config_set_driver_trigger_pg4 - write driver trigger page 4 2397 * @ioc: per adapter object 2398 * @mpi_reply: reply mf payload returned from firmware 2399 * @config_page: contents of the config page 2400 * Context: sleep. 2401 * 2402 * Returns 0 for success, non-zero for failure. 2403 */ 2404 static int 2405 _config_set_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc, 2406 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page) 2407 { 2408 Mpi2ConfigRequest_t mpi_request; 2409 int r; 2410 2411 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2412 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2413 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2414 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2415 mpi_request.ExtPageType = 2416 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 2417 mpi_request.Header.PageNumber = 4; 2418 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION; 2419 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2420 r = _config_request(ioc, &mpi_request, mpi_reply, 2421 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2422 if (r) 2423 goto out; 2424 2425 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 2426 _config_request(ioc, &mpi_request, mpi_reply, 2427 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2428 sizeof(*config_page)); 2429 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 2430 r = _config_request(ioc, &mpi_request, mpi_reply, 2431 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2432 sizeof(*config_page)); 2433 out: 2434 return r; 2435 } 2436 2437 /** 2438 * mpt3sas_config_update_driver_trigger_pg4 - update driver trigger page 4 2439 * @ioc: per adapter object 2440 * @mpi_tg: mpi trigger list 2441 * @set: set ot clear trigger values 2442 * Context: sleep. 2443 * 2444 * Returns 0 for success, non-zero for failure. 2445 */ 2446 int 2447 mpt3sas_config_update_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc, 2448 struct SL_WH_MPI_TRIGGERS_T *mpi_tg, bool set) 2449 { 2450 Mpi26DriverTriggerPage4_t tg_pg4; 2451 Mpi2ConfigReply_t mpi_reply; 2452 int rc, i, count; 2453 u16 ioc_status; 2454 2455 rc = mpt3sas_config_update_driver_trigger_pg0(ioc, 2456 MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, set); 2457 if (rc) 2458 return rc; 2459 2460 rc = mpt3sas_config_get_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4); 2461 if (rc) 2462 goto out; 2463 2464 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2465 MPI2_IOCSTATUS_MASK; 2466 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2467 dcprintk(ioc, 2468 ioc_err(ioc, 2469 "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n", 2470 __func__, ioc_status)); 2471 rc = -EFAULT; 2472 goto out; 2473 } 2474 2475 if (set) { 2476 count = mpi_tg->ValidEntries; 2477 tg_pg4.NumIOCStatusLogInfoTrigger = cpu_to_le16(count); 2478 for (i = 0; i < count; i++) { 2479 tg_pg4.IOCStatusLoginfoTriggers[i].IOCStatus = 2480 cpu_to_le16(mpi_tg->MPITriggerEntry[i].IOCStatus); 2481 tg_pg4.IOCStatusLoginfoTriggers[i].LogInfo = 2482 cpu_to_le32(mpi_tg->MPITriggerEntry[i].IocLogInfo); 2483 } 2484 } else { 2485 tg_pg4.NumIOCStatusLogInfoTrigger = 0; 2486 memset(&tg_pg4.IOCStatusLoginfoTriggers[0], 0, 2487 NUM_VALID_ENTRIES * sizeof( 2488 MPI26_DRIVER_IOCSTATUS_LOGINFO_TIGGER_ENTRY)); 2489 } 2490 2491 rc = _config_set_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4); 2492 if (rc) 2493 goto out; 2494 2495 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2496 MPI2_IOCSTATUS_MASK; 2497 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2498 dcprintk(ioc, 2499 ioc_err(ioc, 2500 "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n", 2501 __func__, ioc_status)); 2502 rc = -EFAULT; 2503 goto out; 2504 } 2505 2506 return 0; 2507 2508 out: 2509 mpt3sas_config_update_driver_trigger_pg0(ioc, 2510 MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, !set); 2511 2512 return rc; 2513 } 2514 2515 /** 2516 * mpt3sas_config_get_volume_handle - returns volume handle for give hidden 2517 * raid components 2518 * @ioc: per adapter object 2519 * @pd_handle: phys disk handle 2520 * @volume_handle: volume handle 2521 * Context: sleep. 2522 * 2523 * Return: 0 for success, non-zero for failure. 2524 */ 2525 int 2526 mpt3sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle, 2527 u16 *volume_handle) 2528 { 2529 Mpi2RaidConfigurationPage0_t *config_page = NULL; 2530 Mpi2ConfigRequest_t mpi_request; 2531 Mpi2ConfigReply_t mpi_reply; 2532 int r, i, config_page_sz; 2533 u16 ioc_status; 2534 int config_num; 2535 u16 element_type; 2536 u16 phys_disk_dev_handle; 2537 2538 *volume_handle = 0; 2539 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2540 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2541 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2542 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2543 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG; 2544 mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION; 2545 mpi_request.Header.PageNumber = 0; 2546 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2547 r = _config_request(ioc, &mpi_request, &mpi_reply, 2548 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2549 if (r) 2550 goto out; 2551 2552 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 2553 config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4); 2554 config_page = kmalloc(config_page_sz, GFP_KERNEL); 2555 if (!config_page) { 2556 r = -1; 2557 goto out; 2558 } 2559 2560 config_num = 0xff; 2561 while (1) { 2562 mpi_request.PageAddress = cpu_to_le32(config_num + 2563 MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM); 2564 r = _config_request(ioc, &mpi_request, &mpi_reply, 2565 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2566 config_page_sz); 2567 if (r) 2568 goto out; 2569 r = -1; 2570 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2571 MPI2_IOCSTATUS_MASK; 2572 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) 2573 goto out; 2574 for (i = 0; i < config_page->NumElements; i++) { 2575 element_type = le16_to_cpu(config_page-> 2576 ConfigElement[i].ElementFlags) & 2577 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE; 2578 if (element_type == 2579 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT || 2580 element_type == 2581 MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) { 2582 phys_disk_dev_handle = 2583 le16_to_cpu(config_page->ConfigElement[i]. 2584 PhysDiskDevHandle); 2585 if (phys_disk_dev_handle == pd_handle) { 2586 *volume_handle = 2587 le16_to_cpu(config_page-> 2588 ConfigElement[i].VolDevHandle); 2589 r = 0; 2590 goto out; 2591 } 2592 } else if (element_type == 2593 MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) { 2594 *volume_handle = 0; 2595 r = 0; 2596 goto out; 2597 } 2598 } 2599 config_num = config_page->ConfigNum; 2600 } 2601 out: 2602 kfree(config_page); 2603 return r; 2604 } 2605 2606 /** 2607 * mpt3sas_config_get_volume_wwid - returns wwid given the volume handle 2608 * @ioc: per adapter object 2609 * @volume_handle: volume handle 2610 * @wwid: volume wwid 2611 * Context: sleep. 2612 * 2613 * Return: 0 for success, non-zero for failure. 2614 */ 2615 int 2616 mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc, u16 volume_handle, 2617 u64 *wwid) 2618 { 2619 Mpi2ConfigReply_t mpi_reply; 2620 Mpi2RaidVolPage1_t raid_vol_pg1; 2621 2622 *wwid = 0; 2623 if (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply, 2624 &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, 2625 volume_handle))) { 2626 *wwid = le64_to_cpu(raid_vol_pg1.WWID); 2627 return 0; 2628 } else 2629 return -1; 2630 } 2631