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