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_iounit_pg1 - obtain pcie iounit page 1 1173 * @ioc: per adapter object 1174 * @mpi_reply: reply mf payload returned from firmware 1175 * @config_page: contents of the config page 1176 * @sz: size of buffer passed in config_page 1177 * Context: sleep. 1178 * 1179 * Returns 0 for success, non-zero for failure. 1180 */ 1181 int 1182 mpt3sas_config_get_pcie_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, 1183 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeIOUnitPage1_t *config_page, 1184 u16 sz) 1185 { 1186 Mpi2ConfigRequest_t mpi_request; 1187 int r; 1188 1189 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1190 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1191 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1192 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1193 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT; 1194 mpi_request.Header.PageVersion = MPI26_PCIEIOUNITPAGE1_PAGEVERSION; 1195 mpi_request.Header.PageNumber = 1; 1196 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1197 r = _config_request(ioc, &mpi_request, mpi_reply, 1198 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1199 if (r) 1200 goto out; 1201 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1202 r = _config_request(ioc, &mpi_request, mpi_reply, 1203 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 1204 out: 1205 return r; 1206 } 1207 1208 /** 1209 * mpt3sas_config_get_pcie_device_pg2 - obtain pcie device page 2 1210 * @ioc: per adapter object 1211 * @mpi_reply: reply mf payload returned from firmware 1212 * @config_page: contents of the config page 1213 * @form: GET_NEXT_HANDLE or HANDLE 1214 * @handle: device handle 1215 * Context: sleep. 1216 * 1217 * Return: 0 for success, non-zero for failure. 1218 */ 1219 int 1220 mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc, 1221 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page, 1222 u32 form, u32 handle) 1223 { 1224 Mpi2ConfigRequest_t mpi_request; 1225 int r; 1226 1227 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1228 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1229 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1230 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1231 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE; 1232 mpi_request.Header.PageVersion = MPI26_PCIEDEVICE2_PAGEVERSION; 1233 mpi_request.Header.PageNumber = 2; 1234 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1235 r = _config_request(ioc, &mpi_request, mpi_reply, 1236 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1237 if (r) 1238 goto out; 1239 1240 mpi_request.PageAddress = cpu_to_le32(form | handle); 1241 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1242 r = _config_request(ioc, &mpi_request, mpi_reply, 1243 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1244 sizeof(*config_page)); 1245 out: 1246 return r; 1247 } 1248 1249 /** 1250 * mpt3sas_config_get_number_hba_phys - obtain number of phys on the host 1251 * @ioc: per adapter object 1252 * @num_phys: pointer returned with the number of phys 1253 * Context: sleep. 1254 * 1255 * Return: 0 for success, non-zero for failure. 1256 */ 1257 int 1258 mpt3sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER *ioc, u8 *num_phys) 1259 { 1260 Mpi2ConfigRequest_t mpi_request; 1261 int r; 1262 u16 ioc_status; 1263 Mpi2ConfigReply_t mpi_reply; 1264 Mpi2SasIOUnitPage0_t config_page; 1265 1266 *num_phys = 0; 1267 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1268 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1269 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1270 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1271 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; 1272 mpi_request.Header.PageNumber = 0; 1273 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION; 1274 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1275 r = _config_request(ioc, &mpi_request, &mpi_reply, 1276 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1277 if (r) 1278 goto out; 1279 1280 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1281 r = _config_request(ioc, &mpi_request, &mpi_reply, 1282 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page, 1283 sizeof(Mpi2SasIOUnitPage0_t)); 1284 if (!r) { 1285 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1286 MPI2_IOCSTATUS_MASK; 1287 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) 1288 *num_phys = config_page.NumPhys; 1289 } 1290 out: 1291 return r; 1292 } 1293 1294 /** 1295 * mpt3sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0 1296 * @ioc: per adapter object 1297 * @mpi_reply: reply mf payload returned from firmware 1298 * @config_page: contents of the config page 1299 * @sz: size of buffer passed in config_page 1300 * Context: sleep. 1301 * 1302 * Calling function should call config_get_number_hba_phys prior to 1303 * this function, so enough memory is allocated for config_page. 1304 * 1305 * Return: 0 for success, non-zero for failure. 1306 */ 1307 int 1308 mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc, 1309 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page, 1310 u16 sz) 1311 { 1312 Mpi2ConfigRequest_t mpi_request; 1313 int r; 1314 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, sz); 1331 out: 1332 return r; 1333 } 1334 1335 /** 1336 * mpt3sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1 1337 * @ioc: per adapter object 1338 * @mpi_reply: reply mf payload returned from firmware 1339 * @config_page: contents of the config page 1340 * @sz: size of buffer passed in config_page 1341 * Context: sleep. 1342 * 1343 * Calling function should call config_get_number_hba_phys prior to 1344 * this function, so enough memory is allocated for config_page. 1345 * 1346 * Return: 0 for success, non-zero for failure. 1347 */ 1348 int 1349 mpt3sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, 1350 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, 1351 u16 sz) 1352 { 1353 Mpi2ConfigRequest_t mpi_request; 1354 int r; 1355 1356 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1357 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1358 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1359 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1360 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; 1361 mpi_request.Header.PageNumber = 1; 1362 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION; 1363 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1364 r = _config_request(ioc, &mpi_request, mpi_reply, 1365 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1366 if (r) 1367 goto out; 1368 1369 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1370 r = _config_request(ioc, &mpi_request, mpi_reply, 1371 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 1372 out: 1373 return r; 1374 } 1375 1376 /** 1377 * mpt3sas_config_set_sas_iounit_pg1 - send sas iounit page 1 1378 * @ioc: per adapter object 1379 * @mpi_reply: reply mf payload returned from firmware 1380 * @config_page: contents of the config page 1381 * @sz: size of buffer passed in config_page 1382 * Context: sleep. 1383 * 1384 * Calling function should call config_get_number_hba_phys prior to 1385 * this function, so enough memory is allocated for config_page. 1386 * 1387 * Return: 0 for success, non-zero for failure. 1388 */ 1389 int 1390 mpt3sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, 1391 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, 1392 u16 sz) 1393 { 1394 Mpi2ConfigRequest_t mpi_request; 1395 int r; 1396 1397 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1398 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1399 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1400 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1401 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; 1402 mpi_request.Header.PageNumber = 1; 1403 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION; 1404 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1405 r = _config_request(ioc, &mpi_request, mpi_reply, 1406 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1407 if (r) 1408 goto out; 1409 1410 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 1411 _config_request(ioc, &mpi_request, mpi_reply, 1412 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 1413 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 1414 r = _config_request(ioc, &mpi_request, mpi_reply, 1415 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); 1416 out: 1417 return r; 1418 } 1419 1420 /** 1421 * mpt3sas_config_get_expander_pg0 - obtain expander page 0 1422 * @ioc: per adapter object 1423 * @mpi_reply: reply mf payload returned from firmware 1424 * @config_page: contents of the config page 1425 * @form: GET_NEXT_HANDLE or HANDLE 1426 * @handle: expander handle 1427 * Context: sleep. 1428 * 1429 * Return: 0 for success, non-zero for failure. 1430 */ 1431 int 1432 mpt3sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1433 *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle) 1434 { 1435 Mpi2ConfigRequest_t mpi_request; 1436 int r; 1437 1438 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1439 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1440 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1441 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1442 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER; 1443 mpi_request.Header.PageNumber = 0; 1444 mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION; 1445 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1446 r = _config_request(ioc, &mpi_request, mpi_reply, 1447 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1448 if (r) 1449 goto out; 1450 1451 mpi_request.PageAddress = cpu_to_le32(form | handle); 1452 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1453 r = _config_request(ioc, &mpi_request, mpi_reply, 1454 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1455 sizeof(*config_page)); 1456 out: 1457 return r; 1458 } 1459 1460 /** 1461 * mpt3sas_config_get_expander_pg1 - obtain expander page 1 1462 * @ioc: per adapter object 1463 * @mpi_reply: reply mf payload returned from firmware 1464 * @config_page: contents of the config page 1465 * @phy_number: phy number 1466 * @handle: expander handle 1467 * Context: sleep. 1468 * 1469 * Return: 0 for success, non-zero for failure. 1470 */ 1471 int 1472 mpt3sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1473 *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number, 1474 u16 handle) 1475 { 1476 Mpi2ConfigRequest_t mpi_request; 1477 int r; 1478 1479 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1480 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1481 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1482 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1483 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER; 1484 mpi_request.Header.PageNumber = 1; 1485 mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION; 1486 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1487 r = _config_request(ioc, &mpi_request, mpi_reply, 1488 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1489 if (r) 1490 goto out; 1491 1492 mpi_request.PageAddress = 1493 cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM | 1494 (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle); 1495 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1496 r = _config_request(ioc, &mpi_request, mpi_reply, 1497 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1498 sizeof(*config_page)); 1499 out: 1500 return r; 1501 } 1502 1503 /** 1504 * mpt3sas_config_get_enclosure_pg0 - obtain enclosure page 0 1505 * @ioc: per adapter object 1506 * @mpi_reply: reply mf payload returned from firmware 1507 * @config_page: contents of the config page 1508 * @form: GET_NEXT_HANDLE or HANDLE 1509 * @handle: expander handle 1510 * Context: sleep. 1511 * 1512 * Return: 0 for success, non-zero for failure. 1513 */ 1514 int 1515 mpt3sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1516 *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle) 1517 { 1518 Mpi2ConfigRequest_t mpi_request; 1519 int r; 1520 1521 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1522 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1523 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1524 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1525 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE; 1526 mpi_request.Header.PageNumber = 0; 1527 mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION; 1528 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1529 r = _config_request(ioc, &mpi_request, mpi_reply, 1530 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1531 if (r) 1532 goto out; 1533 1534 mpi_request.PageAddress = cpu_to_le32(form | handle); 1535 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1536 r = _config_request(ioc, &mpi_request, mpi_reply, 1537 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1538 sizeof(*config_page)); 1539 out: 1540 return r; 1541 } 1542 1543 /** 1544 * mpt3sas_config_get_phy_pg0 - obtain phy page 0 1545 * @ioc: per adapter object 1546 * @mpi_reply: reply mf payload returned from firmware 1547 * @config_page: contents of the config page 1548 * @phy_number: phy number 1549 * Context: sleep. 1550 * 1551 * Return: 0 for success, non-zero for failure. 1552 */ 1553 int 1554 mpt3sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1555 *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number) 1556 { 1557 Mpi2ConfigRequest_t mpi_request; 1558 int r; 1559 1560 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1561 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1562 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1563 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1564 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY; 1565 mpi_request.Header.PageNumber = 0; 1566 mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION; 1567 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1568 r = _config_request(ioc, &mpi_request, mpi_reply, 1569 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1570 if (r) 1571 goto out; 1572 1573 mpi_request.PageAddress = 1574 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number); 1575 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1576 r = _config_request(ioc, &mpi_request, mpi_reply, 1577 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1578 sizeof(*config_page)); 1579 out: 1580 return r; 1581 } 1582 1583 /** 1584 * mpt3sas_config_get_phy_pg1 - obtain phy page 1 1585 * @ioc: per adapter object 1586 * @mpi_reply: reply mf payload returned from firmware 1587 * @config_page: contents of the config page 1588 * @phy_number: phy number 1589 * Context: sleep. 1590 * 1591 * Return: 0 for success, non-zero for failure. 1592 */ 1593 int 1594 mpt3sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1595 *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number) 1596 { 1597 Mpi2ConfigRequest_t mpi_request; 1598 int r; 1599 1600 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1601 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1602 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1603 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1604 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY; 1605 mpi_request.Header.PageNumber = 1; 1606 mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION; 1607 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1608 r = _config_request(ioc, &mpi_request, mpi_reply, 1609 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1610 if (r) 1611 goto out; 1612 1613 mpi_request.PageAddress = 1614 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number); 1615 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1616 r = _config_request(ioc, &mpi_request, mpi_reply, 1617 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1618 sizeof(*config_page)); 1619 out: 1620 return r; 1621 } 1622 1623 /** 1624 * mpt3sas_config_get_raid_volume_pg1 - obtain raid volume page 1 1625 * @ioc: per adapter object 1626 * @mpi_reply: reply mf payload returned from firmware 1627 * @config_page: contents of the config page 1628 * @form: GET_NEXT_HANDLE or HANDLE 1629 * @handle: volume handle 1630 * Context: sleep. 1631 * 1632 * Return: 0 for success, non-zero for failure. 1633 */ 1634 int 1635 mpt3sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER *ioc, 1636 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form, 1637 u32 handle) 1638 { 1639 Mpi2ConfigRequest_t mpi_request; 1640 int r; 1641 1642 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1643 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1644 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1645 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; 1646 mpi_request.Header.PageNumber = 1; 1647 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION; 1648 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1649 r = _config_request(ioc, &mpi_request, mpi_reply, 1650 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1651 if (r) 1652 goto out; 1653 1654 mpi_request.PageAddress = cpu_to_le32(form | handle); 1655 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1656 r = _config_request(ioc, &mpi_request, mpi_reply, 1657 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1658 sizeof(*config_page)); 1659 out: 1660 return r; 1661 } 1662 1663 /** 1664 * mpt3sas_config_get_number_pds - obtain number of phys disk assigned to volume 1665 * @ioc: per adapter object 1666 * @handle: volume handle 1667 * @num_pds: returns pds count 1668 * Context: sleep. 1669 * 1670 * Return: 0 for success, non-zero for failure. 1671 */ 1672 int 1673 mpt3sas_config_get_number_pds(struct MPT3SAS_ADAPTER *ioc, u16 handle, 1674 u8 *num_pds) 1675 { 1676 Mpi2ConfigRequest_t mpi_request; 1677 Mpi2RaidVolPage0_t config_page; 1678 Mpi2ConfigReply_t mpi_reply; 1679 int r; 1680 u16 ioc_status; 1681 1682 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1683 *num_pds = 0; 1684 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1685 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1686 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; 1687 mpi_request.Header.PageNumber = 0; 1688 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION; 1689 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1690 r = _config_request(ioc, &mpi_request, &mpi_reply, 1691 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1692 if (r) 1693 goto out; 1694 1695 mpi_request.PageAddress = 1696 cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle); 1697 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1698 r = _config_request(ioc, &mpi_request, &mpi_reply, 1699 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page, 1700 sizeof(Mpi2RaidVolPage0_t)); 1701 if (!r) { 1702 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1703 MPI2_IOCSTATUS_MASK; 1704 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) 1705 *num_pds = config_page.NumPhysDisks; 1706 } 1707 1708 out: 1709 return r; 1710 } 1711 1712 /** 1713 * mpt3sas_config_get_raid_volume_pg0 - obtain raid volume page 0 1714 * @ioc: per adapter object 1715 * @mpi_reply: reply mf payload returned from firmware 1716 * @config_page: contents of the config page 1717 * @form: GET_NEXT_HANDLE or HANDLE 1718 * @handle: volume handle 1719 * @sz: size of buffer passed in config_page 1720 * Context: sleep. 1721 * 1722 * Return: 0 for success, non-zero for failure. 1723 */ 1724 int 1725 mpt3sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER *ioc, 1726 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form, 1727 u32 handle, u16 sz) 1728 { 1729 Mpi2ConfigRequest_t mpi_request; 1730 int r; 1731 1732 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1733 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1734 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1735 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; 1736 mpi_request.Header.PageNumber = 0; 1737 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION; 1738 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1739 r = _config_request(ioc, &mpi_request, mpi_reply, 1740 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1741 if (r) 1742 goto out; 1743 1744 mpi_request.PageAddress = cpu_to_le32(form | 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, sz); 1748 out: 1749 return r; 1750 } 1751 1752 /** 1753 * mpt3sas_config_get_phys_disk_pg0 - obtain phys disk page 0 1754 * @ioc: per adapter object 1755 * @mpi_reply: reply mf payload returned from firmware 1756 * @config_page: contents of the config page 1757 * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE 1758 * @form_specific: specific to the form 1759 * Context: sleep. 1760 * 1761 * Return: 0 for success, non-zero for failure. 1762 */ 1763 int 1764 mpt3sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1765 *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form, 1766 u32 form_specific) 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_RAID_PHYSDISK; 1775 mpi_request.Header.PageNumber = 0; 1776 mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION; 1777 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1778 r = _config_request(ioc, &mpi_request, mpi_reply, 1779 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1780 if (r) 1781 goto out; 1782 1783 mpi_request.PageAddress = cpu_to_le32(form | form_specific); 1784 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1785 r = _config_request(ioc, &mpi_request, mpi_reply, 1786 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1787 sizeof(*config_page)); 1788 out: 1789 return r; 1790 } 1791 1792 /** 1793 * mpt3sas_config_get_driver_trigger_pg0 - obtain driver trigger page 0 1794 * @ioc: per adapter object 1795 * @mpi_reply: reply mf payload returned from firmware 1796 * @config_page: contents of the config page 1797 * Context: sleep. 1798 * 1799 * Returns 0 for success, non-zero for failure. 1800 */ 1801 int 1802 mpt3sas_config_get_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc, 1803 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page) 1804 { 1805 Mpi2ConfigRequest_t mpi_request; 1806 int r; 1807 1808 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1809 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1810 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1811 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1812 mpi_request.ExtPageType = 1813 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 1814 mpi_request.Header.PageNumber = 0; 1815 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION; 1816 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1817 r = _config_request(ioc, &mpi_request, mpi_reply, 1818 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1819 if (r) 1820 goto out; 1821 1822 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1823 r = _config_request(ioc, &mpi_request, mpi_reply, 1824 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1825 sizeof(*config_page)); 1826 out: 1827 return r; 1828 } 1829 1830 /** 1831 * _config_set_driver_trigger_pg0 - write driver trigger page 0 1832 * @ioc: per adapter object 1833 * @mpi_reply: reply mf payload returned from firmware 1834 * @config_page: contents of the config page 1835 * Context: sleep. 1836 * 1837 * Returns 0 for success, non-zero for failure. 1838 */ 1839 static int 1840 _config_set_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc, 1841 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page) 1842 { 1843 Mpi2ConfigRequest_t mpi_request; 1844 int r; 1845 1846 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1847 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1848 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1849 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1850 mpi_request.ExtPageType = 1851 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 1852 mpi_request.Header.PageNumber = 0; 1853 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION; 1854 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1855 r = _config_request(ioc, &mpi_request, mpi_reply, 1856 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1857 if (r) 1858 goto out; 1859 1860 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 1861 _config_request(ioc, &mpi_request, mpi_reply, 1862 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1863 sizeof(*config_page)); 1864 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 1865 r = _config_request(ioc, &mpi_request, mpi_reply, 1866 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1867 sizeof(*config_page)); 1868 out: 1869 return r; 1870 } 1871 1872 /** 1873 * mpt3sas_config_update_driver_trigger_pg0 - update driver trigger page 0 1874 * @ioc: per adapter object 1875 * @trigger_flag: trigger type bit map 1876 * @set: set ot clear trigger values 1877 * Context: sleep. 1878 * 1879 * Returns 0 for success, non-zero for failure. 1880 */ 1881 static int 1882 mpt3sas_config_update_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc, 1883 u16 trigger_flag, bool set) 1884 { 1885 Mpi26DriverTriggerPage0_t tg_pg0; 1886 Mpi2ConfigReply_t mpi_reply; 1887 int rc; 1888 u16 flags, ioc_status; 1889 1890 rc = mpt3sas_config_get_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0); 1891 if (rc) 1892 return rc; 1893 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1894 MPI2_IOCSTATUS_MASK; 1895 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 1896 dcprintk(ioc, 1897 ioc_err(ioc, 1898 "%s: Failed to get trigger pg0, ioc_status(0x%04x)\n", 1899 __func__, ioc_status)); 1900 return -EFAULT; 1901 } 1902 1903 if (set) 1904 flags = le16_to_cpu(tg_pg0.TriggerFlags) | trigger_flag; 1905 else 1906 flags = le16_to_cpu(tg_pg0.TriggerFlags) & ~trigger_flag; 1907 1908 tg_pg0.TriggerFlags = cpu_to_le16(flags); 1909 1910 rc = _config_set_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0); 1911 if (rc) 1912 return rc; 1913 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1914 MPI2_IOCSTATUS_MASK; 1915 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 1916 dcprintk(ioc, 1917 ioc_err(ioc, 1918 "%s: Failed to update trigger pg0, ioc_status(0x%04x)\n", 1919 __func__, ioc_status)); 1920 return -EFAULT; 1921 } 1922 1923 return 0; 1924 } 1925 1926 /** 1927 * mpt3sas_config_get_driver_trigger_pg1 - obtain driver trigger page 1 1928 * @ioc: per adapter object 1929 * @mpi_reply: reply mf payload returned from firmware 1930 * @config_page: contents of the config page 1931 * Context: sleep. 1932 * 1933 * Returns 0 for success, non-zero for failure. 1934 */ 1935 int 1936 mpt3sas_config_get_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc, 1937 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page) 1938 { 1939 Mpi2ConfigRequest_t mpi_request; 1940 int r; 1941 1942 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1943 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1944 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1945 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1946 mpi_request.ExtPageType = 1947 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 1948 mpi_request.Header.PageNumber = 1; 1949 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION; 1950 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1951 r = _config_request(ioc, &mpi_request, mpi_reply, 1952 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1953 if (r) 1954 goto out; 1955 1956 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1957 r = _config_request(ioc, &mpi_request, mpi_reply, 1958 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1959 sizeof(*config_page)); 1960 out: 1961 return r; 1962 } 1963 1964 /** 1965 * _config_set_driver_trigger_pg1 - write driver trigger page 1 1966 * @ioc: per adapter object 1967 * @mpi_reply: reply mf payload returned from firmware 1968 * @config_page: contents of the config page 1969 * Context: sleep. 1970 * 1971 * Returns 0 for success, non-zero for failure. 1972 */ 1973 static int 1974 _config_set_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc, 1975 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page) 1976 { 1977 Mpi2ConfigRequest_t mpi_request; 1978 int r; 1979 1980 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1981 mpi_request.Function = MPI2_FUNCTION_CONFIG; 1982 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1983 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1984 mpi_request.ExtPageType = 1985 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 1986 mpi_request.Header.PageNumber = 1; 1987 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION; 1988 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 1989 r = _config_request(ioc, &mpi_request, mpi_reply, 1990 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 1991 if (r) 1992 goto out; 1993 1994 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 1995 _config_request(ioc, &mpi_request, mpi_reply, 1996 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 1997 sizeof(*config_page)); 1998 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 1999 r = _config_request(ioc, &mpi_request, mpi_reply, 2000 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2001 sizeof(*config_page)); 2002 out: 2003 return r; 2004 } 2005 2006 /** 2007 * mpt3sas_config_update_driver_trigger_pg1 - update driver trigger page 1 2008 * @ioc: per adapter object 2009 * @master_tg: Master trigger bit map 2010 * @set: set ot clear trigger values 2011 * Context: sleep. 2012 * 2013 * Returns 0 for success, non-zero for failure. 2014 */ 2015 int 2016 mpt3sas_config_update_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc, 2017 struct SL_WH_MASTER_TRIGGER_T *master_tg, bool set) 2018 { 2019 Mpi26DriverTriggerPage1_t tg_pg1; 2020 Mpi2ConfigReply_t mpi_reply; 2021 int rc; 2022 u16 ioc_status; 2023 2024 rc = mpt3sas_config_update_driver_trigger_pg0(ioc, 2025 MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, set); 2026 if (rc) 2027 return rc; 2028 2029 rc = mpt3sas_config_get_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1); 2030 if (rc) 2031 goto out; 2032 2033 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2034 MPI2_IOCSTATUS_MASK; 2035 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2036 dcprintk(ioc, 2037 ioc_err(ioc, 2038 "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n", 2039 __func__, ioc_status)); 2040 rc = -EFAULT; 2041 goto out; 2042 } 2043 2044 if (set) { 2045 tg_pg1.NumMasterTrigger = cpu_to_le16(1); 2046 tg_pg1.MasterTriggers[0].MasterTriggerFlags = cpu_to_le32( 2047 master_tg->MasterData); 2048 } else { 2049 tg_pg1.NumMasterTrigger = 0; 2050 tg_pg1.MasterTriggers[0].MasterTriggerFlags = 0; 2051 } 2052 2053 rc = _config_set_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1); 2054 if (rc) 2055 goto out; 2056 2057 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2058 MPI2_IOCSTATUS_MASK; 2059 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2060 dcprintk(ioc, 2061 ioc_err(ioc, 2062 "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n", 2063 __func__, ioc_status)); 2064 rc = -EFAULT; 2065 goto out; 2066 } 2067 2068 return 0; 2069 2070 out: 2071 mpt3sas_config_update_driver_trigger_pg0(ioc, 2072 MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, !set); 2073 2074 return rc; 2075 } 2076 2077 /** 2078 * mpt3sas_config_get_driver_trigger_pg2 - obtain driver trigger page 2 2079 * @ioc: per adapter object 2080 * @mpi_reply: reply mf payload returned from firmware 2081 * @config_page: contents of the config page 2082 * Context: sleep. 2083 * 2084 * Returns 0 for success, non-zero for failure. 2085 */ 2086 int 2087 mpt3sas_config_get_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc, 2088 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page) 2089 { 2090 Mpi2ConfigRequest_t mpi_request; 2091 int r; 2092 2093 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2094 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2095 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2096 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2097 mpi_request.ExtPageType = 2098 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 2099 mpi_request.Header.PageNumber = 2; 2100 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION; 2101 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2102 r = _config_request(ioc, &mpi_request, mpi_reply, 2103 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2104 if (r) 2105 goto out; 2106 2107 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 2108 r = _config_request(ioc, &mpi_request, mpi_reply, 2109 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2110 sizeof(*config_page)); 2111 out: 2112 return r; 2113 } 2114 2115 /** 2116 * _config_set_driver_trigger_pg2 - write driver trigger page 2 2117 * @ioc: per adapter object 2118 * @mpi_reply: reply mf payload returned from firmware 2119 * @config_page: contents of the config page 2120 * Context: sleep. 2121 * 2122 * Returns 0 for success, non-zero for failure. 2123 */ 2124 static int 2125 _config_set_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc, 2126 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page) 2127 { 2128 Mpi2ConfigRequest_t mpi_request; 2129 int r; 2130 2131 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2132 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2133 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2134 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2135 mpi_request.ExtPageType = 2136 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 2137 mpi_request.Header.PageNumber = 2; 2138 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION; 2139 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2140 r = _config_request(ioc, &mpi_request, mpi_reply, 2141 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2142 if (r) 2143 goto out; 2144 2145 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 2146 _config_request(ioc, &mpi_request, mpi_reply, 2147 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2148 sizeof(*config_page)); 2149 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 2150 r = _config_request(ioc, &mpi_request, mpi_reply, 2151 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2152 sizeof(*config_page)); 2153 out: 2154 return r; 2155 } 2156 2157 /** 2158 * mpt3sas_config_update_driver_trigger_pg2 - update driver trigger page 2 2159 * @ioc: per adapter object 2160 * @event_tg: list of Event Triggers 2161 * @set: set ot clear trigger values 2162 * Context: sleep. 2163 * 2164 * Returns 0 for success, non-zero for failure. 2165 */ 2166 int 2167 mpt3sas_config_update_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc, 2168 struct SL_WH_EVENT_TRIGGERS_T *event_tg, bool set) 2169 { 2170 Mpi26DriverTriggerPage2_t tg_pg2; 2171 Mpi2ConfigReply_t mpi_reply; 2172 int rc, i, count; 2173 u16 ioc_status; 2174 2175 rc = mpt3sas_config_update_driver_trigger_pg0(ioc, 2176 MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, set); 2177 if (rc) 2178 return rc; 2179 2180 rc = mpt3sas_config_get_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2); 2181 if (rc) 2182 goto out; 2183 2184 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2185 MPI2_IOCSTATUS_MASK; 2186 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2187 dcprintk(ioc, 2188 ioc_err(ioc, 2189 "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n", 2190 __func__, ioc_status)); 2191 rc = -EFAULT; 2192 goto out; 2193 } 2194 2195 if (set) { 2196 count = event_tg->ValidEntries; 2197 tg_pg2.NumMPIEventTrigger = cpu_to_le16(count); 2198 for (i = 0; i < count; i++) { 2199 tg_pg2.MPIEventTriggers[i].MPIEventCode = 2200 cpu_to_le16( 2201 event_tg->EventTriggerEntry[i].EventValue); 2202 tg_pg2.MPIEventTriggers[i].MPIEventCodeSpecific = 2203 cpu_to_le16( 2204 event_tg->EventTriggerEntry[i].LogEntryQualifier); 2205 } 2206 } else { 2207 tg_pg2.NumMPIEventTrigger = 0; 2208 memset(&tg_pg2.MPIEventTriggers[0], 0, 2209 NUM_VALID_ENTRIES * sizeof( 2210 MPI26_DRIVER_MPI_EVENT_TIGGER_ENTRY)); 2211 } 2212 2213 rc = _config_set_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2); 2214 if (rc) 2215 goto out; 2216 2217 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2218 MPI2_IOCSTATUS_MASK; 2219 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2220 dcprintk(ioc, 2221 ioc_err(ioc, 2222 "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n", 2223 __func__, ioc_status)); 2224 rc = -EFAULT; 2225 goto out; 2226 } 2227 2228 return 0; 2229 2230 out: 2231 mpt3sas_config_update_driver_trigger_pg0(ioc, 2232 MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, !set); 2233 2234 return rc; 2235 } 2236 2237 /** 2238 * mpt3sas_config_get_driver_trigger_pg3 - obtain driver trigger page 3 2239 * @ioc: per adapter object 2240 * @mpi_reply: reply mf payload returned from firmware 2241 * @config_page: contents of the config page 2242 * Context: sleep. 2243 * 2244 * Returns 0 for success, non-zero for failure. 2245 */ 2246 int 2247 mpt3sas_config_get_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc, 2248 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page) 2249 { 2250 Mpi2ConfigRequest_t mpi_request; 2251 int r; 2252 2253 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2254 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2255 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2256 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2257 mpi_request.ExtPageType = 2258 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 2259 mpi_request.Header.PageNumber = 3; 2260 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION; 2261 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2262 r = _config_request(ioc, &mpi_request, mpi_reply, 2263 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2264 if (r) 2265 goto out; 2266 2267 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 2268 r = _config_request(ioc, &mpi_request, mpi_reply, 2269 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2270 sizeof(*config_page)); 2271 out: 2272 return r; 2273 } 2274 2275 /** 2276 * _config_set_driver_trigger_pg3 - write driver trigger page 3 2277 * @ioc: per adapter object 2278 * @mpi_reply: reply mf payload returned from firmware 2279 * @config_page: contents of the config page 2280 * Context: sleep. 2281 * 2282 * Returns 0 for success, non-zero for failure. 2283 */ 2284 static int 2285 _config_set_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc, 2286 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page) 2287 { 2288 Mpi2ConfigRequest_t mpi_request; 2289 int r; 2290 2291 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2292 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2293 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2294 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2295 mpi_request.ExtPageType = 2296 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 2297 mpi_request.Header.PageNumber = 3; 2298 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION; 2299 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2300 r = _config_request(ioc, &mpi_request, mpi_reply, 2301 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2302 if (r) 2303 goto out; 2304 2305 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 2306 _config_request(ioc, &mpi_request, mpi_reply, 2307 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2308 sizeof(*config_page)); 2309 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 2310 r = _config_request(ioc, &mpi_request, mpi_reply, 2311 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2312 sizeof(*config_page)); 2313 out: 2314 return r; 2315 } 2316 2317 /** 2318 * mpt3sas_config_update_driver_trigger_pg3 - update driver trigger page 3 2319 * @ioc: per adapter object 2320 * @scsi_tg: scsi trigger list 2321 * @set: set ot clear trigger values 2322 * Context: sleep. 2323 * 2324 * Returns 0 for success, non-zero for failure. 2325 */ 2326 int 2327 mpt3sas_config_update_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc, 2328 struct SL_WH_SCSI_TRIGGERS_T *scsi_tg, bool set) 2329 { 2330 Mpi26DriverTriggerPage3_t tg_pg3; 2331 Mpi2ConfigReply_t mpi_reply; 2332 int rc, i, count; 2333 u16 ioc_status; 2334 2335 rc = mpt3sas_config_update_driver_trigger_pg0(ioc, 2336 MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, set); 2337 if (rc) 2338 return rc; 2339 2340 rc = mpt3sas_config_get_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3); 2341 if (rc) 2342 goto out; 2343 2344 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2345 MPI2_IOCSTATUS_MASK; 2346 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2347 dcprintk(ioc, 2348 ioc_err(ioc, 2349 "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n", 2350 __func__, ioc_status)); 2351 return -EFAULT; 2352 } 2353 2354 if (set) { 2355 count = scsi_tg->ValidEntries; 2356 tg_pg3.NumSCSISenseTrigger = cpu_to_le16(count); 2357 for (i = 0; i < count; i++) { 2358 tg_pg3.SCSISenseTriggers[i].ASCQ = 2359 scsi_tg->SCSITriggerEntry[i].ASCQ; 2360 tg_pg3.SCSISenseTriggers[i].ASC = 2361 scsi_tg->SCSITriggerEntry[i].ASC; 2362 tg_pg3.SCSISenseTriggers[i].SenseKey = 2363 scsi_tg->SCSITriggerEntry[i].SenseKey; 2364 } 2365 } else { 2366 tg_pg3.NumSCSISenseTrigger = 0; 2367 memset(&tg_pg3.SCSISenseTriggers[0], 0, 2368 NUM_VALID_ENTRIES * sizeof( 2369 MPI26_DRIVER_SCSI_SENSE_TIGGER_ENTRY)); 2370 } 2371 2372 rc = _config_set_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3); 2373 if (rc) 2374 goto out; 2375 2376 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2377 MPI2_IOCSTATUS_MASK; 2378 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2379 dcprintk(ioc, 2380 ioc_err(ioc, 2381 "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n", 2382 __func__, ioc_status)); 2383 return -EFAULT; 2384 } 2385 2386 return 0; 2387 out: 2388 mpt3sas_config_update_driver_trigger_pg0(ioc, 2389 MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, !set); 2390 2391 return rc; 2392 } 2393 2394 /** 2395 * mpt3sas_config_get_driver_trigger_pg4 - obtain driver trigger page 4 2396 * @ioc: per adapter object 2397 * @mpi_reply: reply mf payload returned from firmware 2398 * @config_page: contents of the config page 2399 * Context: sleep. 2400 * 2401 * Returns 0 for success, non-zero for failure. 2402 */ 2403 int 2404 mpt3sas_config_get_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc, 2405 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page) 2406 { 2407 Mpi2ConfigRequest_t mpi_request; 2408 int r; 2409 2410 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2411 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2412 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2413 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2414 mpi_request.ExtPageType = 2415 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 2416 mpi_request.Header.PageNumber = 4; 2417 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION; 2418 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2419 r = _config_request(ioc, &mpi_request, mpi_reply, 2420 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2421 if (r) 2422 goto out; 2423 2424 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 2425 r = _config_request(ioc, &mpi_request, mpi_reply, 2426 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2427 sizeof(*config_page)); 2428 out: 2429 return r; 2430 } 2431 2432 /** 2433 * _config_set_driver_trigger_pg4 - write driver trigger page 4 2434 * @ioc: per adapter object 2435 * @mpi_reply: reply mf payload returned from firmware 2436 * @config_page: contents of the config page 2437 * Context: sleep. 2438 * 2439 * Returns 0 for success, non-zero for failure. 2440 */ 2441 static int 2442 _config_set_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc, 2443 Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page) 2444 { 2445 Mpi2ConfigRequest_t mpi_request; 2446 int r; 2447 2448 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2449 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2450 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2451 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2452 mpi_request.ExtPageType = 2453 MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER; 2454 mpi_request.Header.PageNumber = 4; 2455 mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION; 2456 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2457 r = _config_request(ioc, &mpi_request, mpi_reply, 2458 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2459 if (r) 2460 goto out; 2461 2462 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 2463 _config_request(ioc, &mpi_request, mpi_reply, 2464 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2465 sizeof(*config_page)); 2466 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 2467 r = _config_request(ioc, &mpi_request, mpi_reply, 2468 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2469 sizeof(*config_page)); 2470 out: 2471 return r; 2472 } 2473 2474 /** 2475 * mpt3sas_config_update_driver_trigger_pg4 - update driver trigger page 4 2476 * @ioc: per adapter object 2477 * @mpi_tg: mpi trigger list 2478 * @set: set ot clear trigger values 2479 * Context: sleep. 2480 * 2481 * Returns 0 for success, non-zero for failure. 2482 */ 2483 int 2484 mpt3sas_config_update_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc, 2485 struct SL_WH_MPI_TRIGGERS_T *mpi_tg, bool set) 2486 { 2487 Mpi26DriverTriggerPage4_t tg_pg4; 2488 Mpi2ConfigReply_t mpi_reply; 2489 int rc, i, count; 2490 u16 ioc_status; 2491 2492 rc = mpt3sas_config_update_driver_trigger_pg0(ioc, 2493 MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, set); 2494 if (rc) 2495 return rc; 2496 2497 rc = mpt3sas_config_get_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4); 2498 if (rc) 2499 goto out; 2500 2501 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2502 MPI2_IOCSTATUS_MASK; 2503 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2504 dcprintk(ioc, 2505 ioc_err(ioc, 2506 "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n", 2507 __func__, ioc_status)); 2508 rc = -EFAULT; 2509 goto out; 2510 } 2511 2512 if (set) { 2513 count = mpi_tg->ValidEntries; 2514 tg_pg4.NumIOCStatusLogInfoTrigger = cpu_to_le16(count); 2515 for (i = 0; i < count; i++) { 2516 tg_pg4.IOCStatusLoginfoTriggers[i].IOCStatus = 2517 cpu_to_le16(mpi_tg->MPITriggerEntry[i].IOCStatus); 2518 tg_pg4.IOCStatusLoginfoTriggers[i].LogInfo = 2519 cpu_to_le32(mpi_tg->MPITriggerEntry[i].IocLogInfo); 2520 } 2521 } else { 2522 tg_pg4.NumIOCStatusLogInfoTrigger = 0; 2523 memset(&tg_pg4.IOCStatusLoginfoTriggers[0], 0, 2524 NUM_VALID_ENTRIES * sizeof( 2525 MPI26_DRIVER_IOCSTATUS_LOGINFO_TIGGER_ENTRY)); 2526 } 2527 2528 rc = _config_set_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4); 2529 if (rc) 2530 goto out; 2531 2532 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2533 MPI2_IOCSTATUS_MASK; 2534 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 2535 dcprintk(ioc, 2536 ioc_err(ioc, 2537 "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n", 2538 __func__, ioc_status)); 2539 rc = -EFAULT; 2540 goto out; 2541 } 2542 2543 return 0; 2544 2545 out: 2546 mpt3sas_config_update_driver_trigger_pg0(ioc, 2547 MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, !set); 2548 2549 return rc; 2550 } 2551 2552 /** 2553 * mpt3sas_config_get_volume_handle - returns volume handle for give hidden 2554 * raid components 2555 * @ioc: per adapter object 2556 * @pd_handle: phys disk handle 2557 * @volume_handle: volume handle 2558 * Context: sleep. 2559 * 2560 * Return: 0 for success, non-zero for failure. 2561 */ 2562 int 2563 mpt3sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle, 2564 u16 *volume_handle) 2565 { 2566 Mpi2RaidConfigurationPage0_t *config_page = NULL; 2567 Mpi2ConfigRequest_t mpi_request; 2568 Mpi2ConfigReply_t mpi_reply; 2569 int r, i, config_page_sz; 2570 u16 ioc_status; 2571 int config_num; 2572 u16 element_type; 2573 u16 phys_disk_dev_handle; 2574 2575 *volume_handle = 0; 2576 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 2577 mpi_request.Function = MPI2_FUNCTION_CONFIG; 2578 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 2579 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 2580 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG; 2581 mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION; 2582 mpi_request.Header.PageNumber = 0; 2583 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 2584 r = _config_request(ioc, &mpi_request, &mpi_reply, 2585 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 2586 if (r) 2587 goto out; 2588 2589 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 2590 config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4); 2591 config_page = kmalloc(config_page_sz, GFP_KERNEL); 2592 if (!config_page) { 2593 r = -1; 2594 goto out; 2595 } 2596 2597 config_num = 0xff; 2598 while (1) { 2599 mpi_request.PageAddress = cpu_to_le32(config_num + 2600 MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM); 2601 r = _config_request(ioc, &mpi_request, &mpi_reply, 2602 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 2603 config_page_sz); 2604 if (r) 2605 goto out; 2606 r = -1; 2607 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 2608 MPI2_IOCSTATUS_MASK; 2609 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) 2610 goto out; 2611 for (i = 0; i < config_page->NumElements; i++) { 2612 element_type = le16_to_cpu(config_page-> 2613 ConfigElement[i].ElementFlags) & 2614 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE; 2615 if (element_type == 2616 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT || 2617 element_type == 2618 MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) { 2619 phys_disk_dev_handle = 2620 le16_to_cpu(config_page->ConfigElement[i]. 2621 PhysDiskDevHandle); 2622 if (phys_disk_dev_handle == pd_handle) { 2623 *volume_handle = 2624 le16_to_cpu(config_page-> 2625 ConfigElement[i].VolDevHandle); 2626 r = 0; 2627 goto out; 2628 } 2629 } else if (element_type == 2630 MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) { 2631 *volume_handle = 0; 2632 r = 0; 2633 goto out; 2634 } 2635 } 2636 config_num = config_page->ConfigNum; 2637 } 2638 out: 2639 kfree(config_page); 2640 return r; 2641 } 2642 2643 /** 2644 * mpt3sas_config_get_volume_wwid - returns wwid given the volume handle 2645 * @ioc: per adapter object 2646 * @volume_handle: volume handle 2647 * @wwid: volume wwid 2648 * Context: sleep. 2649 * 2650 * Return: 0 for success, non-zero for failure. 2651 */ 2652 int 2653 mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc, u16 volume_handle, 2654 u64 *wwid) 2655 { 2656 Mpi2ConfigReply_t mpi_reply; 2657 Mpi2RaidVolPage1_t raid_vol_pg1; 2658 2659 *wwid = 0; 2660 if (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply, 2661 &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, 2662 volume_handle))) { 2663 *wwid = le64_to_cpu(raid_vol_pg1.WWID); 2664 return 0; 2665 } else 2666 return -1; 2667 } 2668