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