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