1 /*- 2 * Copyright (c) 2011 LSI Corp. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * LSI MPT-Fusion Host Adapter FreeBSD 27 * 28 * $FreeBSD: src/sys/dev/mps/mps_config.c,v 1.1 2012/01/26 18:17:21 ken Exp $ 29 */ 30 31 /* TODO Move headers to mpsvar */ 32 #include <sys/types.h> 33 #include <sys/param.h> 34 #include <sys/lock.h> 35 #include <sys/systm.h> 36 #include <sys/kernel.h> 37 #include <sys/malloc.h> 38 #include <sys/kthread.h> 39 #include <sys/taskqueue.h> 40 #include <sys/bus.h> 41 #include <sys/endian.h> 42 #include <sys/sysctl.h> 43 #include <sys/eventhandler.h> 44 #include <sys/uio.h> 45 #include <dev/raid/mps/mpi/mpi2_type.h> 46 #include <dev/raid/mps/mpi/mpi2.h> 47 #include <dev/raid/mps/mpi/mpi2_ioc.h> 48 #include <dev/raid/mps/mpi/mpi2_sas.h> 49 #include <dev/raid/mps/mpi/mpi2_cnfg.h> 50 #include <dev/raid/mps/mpi/mpi2_init.h> 51 #include <dev/raid/mps/mpi/mpi2_tool.h> 52 #include <dev/raid/mps/mps_ioctl.h> 53 #include <dev/raid/mps/mpsvar.h> 54 55 /** 56 * mps_config_get_ioc_pg8 - obtain ioc page 8 57 * @sc: per adapter object 58 * @mpi_reply: reply mf payload returned from firmware 59 * @config_page: contents of the config page 60 * Context: sleep. 61 * 62 * Returns 0 for success, non-zero for failure. 63 */ 64 int 65 mps_config_get_ioc_pg8(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, 66 Mpi2IOCPage8_t *config_page) 67 { 68 MPI2_CONFIG_REQUEST *request; 69 MPI2_CONFIG_REPLY *reply; 70 struct mps_command *cm; 71 MPI2_CONFIG_PAGE_IOC_8 *page = NULL; 72 int error = 0; 73 u16 ioc_status; 74 75 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 76 77 if ((cm = mps_alloc_command(sc)) == NULL) { 78 kprintf("%s: command alloc failed @ line %d\n", __func__, 79 __LINE__); 80 error = EBUSY; 81 goto out; 82 } 83 request = (MPI2_CONFIG_REQUEST *)cm->cm_req; 84 bzero(request, sizeof(MPI2_CONFIG_REQUEST)); 85 request->Function = MPI2_FUNCTION_CONFIG; 86 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 87 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IOC; 88 request->Header.PageNumber = 8; 89 request->Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION; 90 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 91 cm->cm_data = NULL; 92 error = mps_request_polled(sc, cm); 93 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; 94 if (error || (reply == NULL)) { 95 /* FIXME */ 96 /* If the poll returns error then we need to do diag reset */ 97 kprintf("%s: poll for header completed with error %d", 98 __func__, error); 99 error = ENXIO; 100 goto out; 101 } 102 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK; 103 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); 104 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 105 /* FIXME */ 106 /* If the poll returns error then we need to do diag reset */ 107 kprintf("%s: header read with error; iocstatus = 0x%x\n", 108 __func__, ioc_status); 109 error = ENXIO; 110 goto out; 111 } 112 /* We have to do free and alloc for the reply-free and reply-post 113 * counters to match - Need to review the reply FIFO handling. 114 */ 115 mps_free_command(sc, cm); 116 117 if ((cm = mps_alloc_command(sc)) == NULL) { 118 kprintf("%s: command alloc failed @ line %d\n", __func__, 119 __LINE__); 120 error = EBUSY; 121 goto out; 122 } 123 request = (MPI2_CONFIG_REQUEST *)cm->cm_req; 124 bzero(request, sizeof(MPI2_CONFIG_REQUEST)); 125 request->Function = MPI2_FUNCTION_CONFIG; 126 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 127 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IOC; 128 request->Header.PageNumber = 8; 129 request->Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION; 130 request->Header.PageLength = mpi_reply->Header.PageLength; 131 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4; 132 cm->cm_sge = &request->PageBufferSGE; 133 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION); 134 cm->cm_flags = MPS_CM_FLAGS_SGE_SIMPLE | MPS_CM_FLAGS_DATAIN; 135 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 136 page = kmalloc((cm->cm_length), M_MPT2, M_ZERO | M_INTWAIT); 137 if (!page) { 138 kprintf("%s: page alloc failed\n", __func__); 139 error = ENOMEM; 140 goto out; 141 } 142 cm->cm_data = page; 143 error = mps_request_polled(sc, cm); 144 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; 145 if (error || (reply == NULL)) { 146 /* FIXME */ 147 /* If the poll returns error then we need to do diag reset */ 148 kprintf("%s: poll for page completed with error %d", 149 __func__, error); 150 error = ENXIO; 151 goto out; 152 } 153 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK; 154 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); 155 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 156 /* FIXME */ 157 /* If the poll returns error then we need to do diag reset */ 158 kprintf("%s: page read with error; iocstatus = 0x%x\n", 159 __func__, ioc_status); 160 error = ENXIO; 161 goto out; 162 } 163 bcopy(page, config_page, MIN(cm->cm_length, (sizeof(Mpi2IOCPage8_t)))); 164 165 out: 166 kfree(page, M_MPT2); 167 if (cm) 168 mps_free_command(sc, cm); 169 return (error); 170 } 171 172 /** 173 * mps_config_get_man_pg10 - obtain Manufacturing Page 10 data and set flags 174 * accordingly. Currently, this page does not need to return to caller. 175 * @sc: per adapter object 176 * @mpi_reply: reply mf payload returned from firmware 177 * Context: sleep. 178 * 179 * Returns 0 for success, non-zero for failure. 180 */ 181 int 182 mps_config_get_man_pg10(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply) 183 { 184 MPI2_CONFIG_REQUEST *request; 185 MPI2_CONFIG_REPLY *reply; 186 struct mps_command *cm; 187 pMpi2ManufacturingPagePS_t page = NULL; 188 uint32_t *pPS_info; 189 uint8_t OEM_Value = 0; 190 int error = 0; 191 u16 ioc_status; 192 193 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 194 195 if ((cm = mps_alloc_command(sc)) == NULL) { 196 kprintf("%s: command alloc failed @ line %d\n", __func__, 197 __LINE__); 198 error = EBUSY; 199 goto out; 200 } 201 request = (MPI2_CONFIG_REQUEST *)cm->cm_req; 202 bzero(request, sizeof(MPI2_CONFIG_REQUEST)); 203 request->Function = MPI2_FUNCTION_CONFIG; 204 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 205 request->Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; 206 request->Header.PageNumber = 10; 207 request->Header.PageVersion = MPI2_MANUFACTURING10_PAGEVERSION; 208 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 209 cm->cm_data = NULL; 210 error = mps_request_polled(sc, cm); 211 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; 212 if (error || (reply == NULL)) { 213 /* FIXME */ 214 /* If the poll returns error then we need to do diag reset */ 215 kprintf("%s: poll for header completed with error %d", 216 __func__, error); 217 error = ENXIO; 218 goto out; 219 } 220 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK; 221 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); 222 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 223 /* FIXME */ 224 /* If the poll returns error then we need to do diag reset */ 225 kprintf("%s: header read with error; iocstatus = 0x%x\n", 226 __func__, ioc_status); 227 error = ENXIO; 228 goto out; 229 } 230 /* We have to do free and alloc for the reply-free and reply-post 231 * counters to match - Need to review the reply FIFO handling. 232 */ 233 mps_free_command(sc, cm); 234 235 if ((cm = mps_alloc_command(sc)) == NULL) { 236 kprintf("%s: command alloc failed @ line %d\n", __func__, 237 __LINE__); 238 error = EBUSY; 239 goto out; 240 } 241 request = (MPI2_CONFIG_REQUEST *)cm->cm_req; 242 bzero(request, sizeof(MPI2_CONFIG_REQUEST)); 243 request->Function = MPI2_FUNCTION_CONFIG; 244 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 245 request->Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; 246 request->Header.PageNumber = 10; 247 request->Header.PageVersion = MPI2_MANUFACTURING10_PAGEVERSION; 248 request->Header.PageLength = mpi_reply->Header.PageLength; 249 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4; 250 cm->cm_sge = &request->PageBufferSGE; 251 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION); 252 cm->cm_flags = MPS_CM_FLAGS_SGE_SIMPLE | MPS_CM_FLAGS_DATAIN; 253 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 254 page = kmalloc(MPS_MAN_PAGE10_SIZE, M_MPT2, M_ZERO | M_INTWAIT); 255 if (!page) { 256 kprintf("%s: page alloc failed\n", __func__); 257 error = ENOMEM; 258 goto out; 259 } 260 cm->cm_data = page; 261 error = mps_request_polled(sc, cm); 262 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; 263 if (error || (reply == NULL)) { 264 /* FIXME */ 265 /* If the poll returns error then we need to do diag reset */ 266 kprintf("%s: poll for page completed with error %d", 267 __func__, error); 268 error = ENXIO; 269 goto out; 270 } 271 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK; 272 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); 273 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 274 /* FIXME */ 275 /* If the poll returns error then we need to do diag reset */ 276 kprintf("%s: page read with error; iocstatus = 0x%x\n", 277 __func__, ioc_status); 278 error = ENXIO; 279 goto out; 280 } 281 282 /* 283 * If OEM ID is unknown, fail the request. 284 */ 285 sc->WD_hide_expose = MPS_WD_HIDE_ALWAYS; 286 OEM_Value = (uint8_t)(page->ProductSpecificInfo & 0x000000FF); 287 if (OEM_Value != MPS_WD_LSI_OEM) { 288 mps_dprint(sc, MPS_FAULT, "Unknown OEM value for WarpDrive " 289 "(0x%x)\n", OEM_Value); 290 error = ENXIO; 291 goto out; 292 } 293 294 /* 295 * Set the phys disks hide/expose value. 296 */ 297 pPS_info = &page->ProductSpecificInfo; 298 sc->WD_hide_expose = (uint8_t)(pPS_info[5]); 299 sc->WD_hide_expose &= MPS_WD_HIDE_EXPOSE_MASK; 300 if ((sc->WD_hide_expose != MPS_WD_HIDE_ALWAYS) && 301 (sc->WD_hide_expose != MPS_WD_EXPOSE_ALWAYS) && 302 (sc->WD_hide_expose != MPS_WD_HIDE_IF_VOLUME)) { 303 mps_dprint(sc, MPS_FAULT, "Unknown value for WarpDrive " 304 "hide/expose: 0x%x\n", sc->WD_hide_expose); 305 error = ENXIO; 306 goto out; 307 } 308 309 out: 310 kfree(page, M_MPT2); 311 if (cm) 312 mps_free_command(sc, cm); 313 return (error); 314 } 315 316 /** 317 * mps_base_static_config_pages - static start of day config pages. 318 * @sc: per adapter object 319 * 320 * Return nothing. 321 */ 322 void 323 mps_base_static_config_pages(struct mps_softc *sc) 324 { 325 Mpi2ConfigReply_t mpi_reply; 326 int retry; 327 328 retry = 0; 329 while (mps_config_get_ioc_pg8(sc, &mpi_reply, &sc->ioc_pg8)) { 330 retry++; 331 if (retry > 5) { 332 /* We need to Handle this situation */ 333 /*FIXME*/ 334 break; 335 } 336 } 337 } 338 339 /** 340 * mps_wd_config_pages - get info required to support WarpDrive. This needs to 341 * be called after discovery is complete to guarentee that IR info is there. 342 * @sc: per adapter object 343 * 344 * Return nothing. 345 */ 346 void 347 mps_wd_config_pages(struct mps_softc *sc) 348 { 349 Mpi2ConfigReply_t mpi_reply; 350 pMpi2RaidVolPage0_t raid_vol_pg0 = NULL; 351 Mpi2RaidPhysDiskPage0_t phys_disk_pg0; 352 pMpi2RaidVol0PhysDisk_t pRVPD; 353 uint32_t stripe_size, phys_disk_page_address; 354 uint16_t block_size; 355 uint8_t index, stripe_exp = 0, block_exp = 0; 356 357 /* 358 * Get the WD settings from manufacturing page 10 if using a WD HBA. 359 * This will be used to determine if phys disks should always be 360 * hidden, hidden only if part of a WD volume, or never hidden. Also, 361 * get the WD RAID Volume info and fail if volume does not exist or if 362 * volume does not meet the requirements for a WD volume. No retry 363 * here. Just default to HIDE ALWAYS if man Page10 fails, or clear WD 364 * Valid flag if Volume info fails. 365 */ 366 sc->WD_valid_config = FALSE; 367 if (sc->mps_flags & MPS_FLAGS_WD_AVAILABLE) { 368 if (mps_config_get_man_pg10(sc, &mpi_reply)) { 369 mps_dprint(sc, MPS_FAULT, 370 "mps_config_get_man_pg10 failed! Using 0 (Hide " 371 "Always) for WarpDrive hide/expose value.\n"); 372 sc->WD_hide_expose = MPS_WD_HIDE_ALWAYS; 373 } 374 375 /* 376 * Get first RAID Volume Page0 using GET_NEXT_HANDLE. 377 */ 378 raid_vol_pg0 = kmalloc(sizeof(Mpi2RaidVolPage0_t) + 379 (sizeof(Mpi2RaidVol0PhysDisk_t) * MPS_MAX_DISKS_IN_VOL), 380 M_MPT2, M_ZERO | M_INTWAIT); 381 if (!raid_vol_pg0) { 382 kprintf("%s: page alloc failed\n", __func__); 383 goto out; 384 } 385 386 if (mps_config_get_raid_volume_pg0(sc, &mpi_reply, raid_vol_pg0, 387 0x0000FFFF)) { 388 mps_dprint(sc, MPS_INFO, 389 "mps_config_get_raid_volume_pg0 failed! Assuming " 390 "WarpDrive IT mode.\n"); 391 goto out; 392 } 393 394 /* 395 * Check for valid WD configuration: 396 * volume type is RAID0 397 * number of phys disks in the volume is no more than 8 398 */ 399 if ((raid_vol_pg0->VolumeType != MPI2_RAID_VOL_TYPE_RAID0) || 400 (raid_vol_pg0->NumPhysDisks > 8)) { 401 mps_dprint(sc, MPS_FAULT, 402 "Invalid WarpDrive configuration. Direct Drive I/O " 403 "will not be used.\n"); 404 goto out; 405 } 406 407 /* 408 * Save the WD RAID data to be used during WD I/O. 409 */ 410 sc->DD_max_lba = le64toh((uint64_t)raid_vol_pg0->MaxLBA.High << 411 32 | (uint64_t)raid_vol_pg0->MaxLBA.Low); 412 sc->DD_num_phys_disks = raid_vol_pg0->NumPhysDisks; 413 sc->DD_dev_handle = raid_vol_pg0->DevHandle; 414 sc->DD_stripe_size = raid_vol_pg0->StripeSize; 415 sc->DD_block_size = raid_vol_pg0->BlockSize; 416 417 /* 418 * Find power of 2 of stripe size and set this as the exponent. 419 * Fail if stripe size is 0. 420 */ 421 stripe_size = raid_vol_pg0->StripeSize; 422 for (index = 0; index < 32; index++) { 423 if (stripe_size & 1) 424 break; 425 stripe_exp++; 426 stripe_size >>= 1; 427 } 428 if (index == 32) { 429 mps_dprint(sc, MPS_FAULT, 430 "RAID Volume's stripe size is 0. Direct Drive I/O " 431 "will not be used.\n"); 432 goto out; 433 } 434 sc->DD_stripe_exponent = stripe_exp; 435 436 /* 437 * Find power of 2 of block size and set this as the exponent. 438 * Fail if block size is 0. 439 */ 440 block_size = raid_vol_pg0->BlockSize; 441 for (index = 0; index < 16; index++) { 442 if (block_size & 1) 443 break; 444 block_exp++; 445 block_size >>= 1; 446 } 447 if (index == 16) { 448 mps_dprint(sc, MPS_FAULT, 449 "RAID Volume's block size is 0. Direct Drive I/O " 450 "will not be used.\n"); 451 goto out; 452 } 453 sc->DD_block_exponent = block_exp; 454 455 /* 456 * Loop through all of the volume's Phys Disks to map the phys 457 * disk number into the columm map. This is used during Direct 458 * Drive I/O to send the request to the correct SSD. 459 */ 460 pRVPD = (pMpi2RaidVol0PhysDisk_t)&raid_vol_pg0->PhysDisk; 461 for (index = 0; index < raid_vol_pg0->NumPhysDisks; index++) { 462 sc->DD_column_map[pRVPD->PhysDiskMap].phys_disk_num = 463 pRVPD->PhysDiskNum; 464 pRVPD++; 465 } 466 467 /* 468 * Get second RAID Volume Page0 using previous handle. This 469 * page should not exist. If it does, must not proceed with WD 470 * handling. 471 */ 472 if (mps_config_get_raid_volume_pg0(sc, &mpi_reply, 473 raid_vol_pg0, (u32)raid_vol_pg0->DevHandle)) { 474 if (mpi_reply.IOCStatus != 475 MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) { 476 mps_dprint(sc, MPS_FAULT, 477 "Multiple RAID Volume Page0! Direct Drive " 478 "I/O will not be used.\n"); 479 goto out; 480 } 481 } else { 482 mps_dprint(sc, MPS_FAULT, 483 "Multiple volumes! Direct Drive I/O will not be " 484 "used.\n"); 485 goto out; 486 } 487 488 /* 489 * Get RAID Volume Phys Disk Page 0 for all SSDs in the volume. 490 */ 491 for (index = 0; index < raid_vol_pg0->NumPhysDisks; index++) { 492 phys_disk_page_address = 493 MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM + 494 sc->DD_column_map[index].phys_disk_num; 495 if (mps_config_get_raid_pd_pg0(sc, &mpi_reply, 496 &phys_disk_pg0, phys_disk_page_address)) { 497 mps_dprint(sc, MPS_FAULT, 498 "mps_config_get_raid_pd_pg0 failed! Direct " 499 "Drive I/O will not be used.\n"); 500 goto out; 501 } 502 if (phys_disk_pg0.DevHandle == 0xFFFF) { 503 mps_dprint(sc, MPS_FAULT, 504 "Invalid Phys Disk DevHandle! Direct Drive " 505 "I/O will not be used.\n"); 506 goto out; 507 } 508 sc->DD_column_map[index].dev_handle = 509 phys_disk_pg0.DevHandle; 510 } 511 sc->WD_valid_config = TRUE; 512 out: 513 if (raid_vol_pg0) 514 kfree(raid_vol_pg0, M_MPT2); 515 } 516 } 517 518 /** 519 * mps_config_get_dpm_pg0 - obtain driver persistent mapping page0 520 * @sc: per adapter object 521 * @mpi_reply: reply mf payload returned from firmware 522 * @config_page: contents of the config page 523 * @sz: size of buffer passed in config_page 524 * Context: sleep. 525 * 526 * Returns 0 for success, non-zero for failure. 527 */ 528 int 529 mps_config_get_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, 530 Mpi2DriverMappingPage0_t *config_page, u16 sz) 531 { 532 MPI2_CONFIG_REQUEST *request; 533 MPI2_CONFIG_REPLY *reply; 534 struct mps_command *cm; 535 Mpi2DriverMappingPage0_t *page = NULL; 536 int error = 0; 537 u16 ioc_status; 538 539 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 540 541 memset(config_page, 0, sz); 542 if ((cm = mps_alloc_command(sc)) == NULL) { 543 kprintf("%s: command alloc failed @ line %d\n", __func__, 544 __LINE__); 545 error = EBUSY; 546 goto out; 547 } 548 request = (MPI2_CONFIG_REQUEST *)cm->cm_req; 549 bzero(request, sizeof(MPI2_CONFIG_REQUEST)); 550 request->Function = MPI2_FUNCTION_CONFIG; 551 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 552 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 553 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING; 554 request->Header.PageNumber = 0; 555 request->Header.PageVersion = MPI2_DRIVERMAPPING0_PAGEVERSION; 556 request->PageAddress = sc->max_dpm_entries << 557 MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT; 558 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 559 cm->cm_data = NULL; 560 error = mps_request_polled(sc, cm); 561 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; 562 if (error || (reply == NULL)) { 563 /* FIXME */ 564 /* If the poll returns error then we need to do diag reset */ 565 kprintf("%s: poll for header completed with error %d", 566 __func__, error); 567 error = ENXIO; 568 goto out; 569 } 570 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK; 571 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); 572 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 573 /* FIXME */ 574 /* If the poll returns error then we need to do diag reset */ 575 kprintf("%s: header read with error; iocstatus = 0x%x\n", 576 __func__, ioc_status); 577 error = ENXIO; 578 goto out; 579 } 580 /* We have to do free and alloc for the reply-free and reply-post 581 * counters to match - Need to review the reply FIFO handling. 582 */ 583 mps_free_command(sc, cm); 584 585 if ((cm = mps_alloc_command(sc)) == NULL) { 586 kprintf("%s: command alloc failed @ line %d\n", __func__, 587 __LINE__); 588 error = EBUSY; 589 goto out; 590 } 591 request = (MPI2_CONFIG_REQUEST *)cm->cm_req; 592 bzero(request, sizeof(MPI2_CONFIG_REQUEST)); 593 request->Function = MPI2_FUNCTION_CONFIG; 594 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_NVRAM; 595 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 596 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING; 597 request->Header.PageNumber = 0; 598 request->Header.PageVersion = MPI2_DRIVERMAPPING0_PAGEVERSION; 599 request->PageAddress = sc->max_dpm_entries << 600 MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT; 601 request->ExtPageLength = mpi_reply->ExtPageLength; 602 cm->cm_length = le16toh(request->ExtPageLength) * 4; 603 cm->cm_sge = &request->PageBufferSGE; 604 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION); 605 cm->cm_flags = MPS_CM_FLAGS_SGE_SIMPLE | MPS_CM_FLAGS_DATAIN; 606 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 607 page = kmalloc(cm->cm_length, M_MPT2, M_ZERO|M_INTWAIT); 608 if (!page) { 609 kprintf("%s: page alloc failed\n", __func__); 610 error = ENOMEM; 611 goto out; 612 } 613 cm->cm_data = page; 614 error = mps_request_polled(sc, cm); 615 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; 616 if (error || (reply == NULL)) { 617 /* FIXME */ 618 /* If the poll returns error then we need to do diag reset */ 619 kprintf("%s: poll for page completed with error %d", 620 __func__, error); 621 error = ENXIO; 622 goto out; 623 } 624 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK; 625 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); 626 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 627 /* FIXME */ 628 /* If the poll returns error then we need to do diag reset */ 629 kprintf("%s: page read with error; iocstatus = 0x%x\n", 630 __func__, ioc_status); 631 error = ENXIO; 632 goto out; 633 } 634 bcopy(page, config_page, MIN(cm->cm_length, sz)); 635 out: 636 kfree(page, M_MPT2); 637 if (cm) 638 mps_free_command(sc, cm); 639 return (error); 640 } 641 642 /** 643 * mps_config_set_dpm_pg0 - write an entry in driver persistent mapping page0 644 * @sc: per adapter object 645 * @mpi_reply: reply mf payload returned from firmware 646 * @config_page: contents of the config page 647 * @entry_idx: entry index in DPM Page0 to be modified 648 * Context: sleep. 649 * 650 * Returns 0 for success, non-zero for failure. 651 */ 652 653 int mps_config_set_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, 654 Mpi2DriverMappingPage0_t *config_page, u16 entry_idx) 655 { 656 MPI2_CONFIG_REQUEST *request; 657 MPI2_CONFIG_REPLY *reply; 658 struct mps_command *cm; 659 MPI2_CONFIG_PAGE_DRIVER_MAPPING_0 *page = NULL; 660 int error = 0; 661 u16 ioc_status; 662 663 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 664 665 if ((cm = mps_alloc_command(sc)) == NULL) { 666 kprintf("%s: command alloc failed @ line %d\n", __func__, 667 __LINE__); 668 error = EBUSY; 669 goto out; 670 } 671 request = (MPI2_CONFIG_REQUEST *)cm->cm_req; 672 bzero(request, sizeof(MPI2_CONFIG_REQUEST)); 673 request->Function = MPI2_FUNCTION_CONFIG; 674 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 675 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 676 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING; 677 request->Header.PageNumber = 0; 678 request->Header.PageVersion = MPI2_DRIVERMAPPING0_PAGEVERSION; 679 request->PageAddress = 1 << MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT; 680 request->PageAddress |= htole16(entry_idx); 681 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 682 cm->cm_data = NULL; 683 error = mps_request_polled(sc, cm); 684 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; 685 if (error || (reply == NULL)) { 686 /* FIXME */ 687 /* If the poll returns error then we need to do diag reset */ 688 kprintf("%s: poll for header completed with error %d", 689 __func__, error); 690 error = ENXIO; 691 goto out; 692 } 693 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK; 694 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); 695 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 696 /* FIXME */ 697 /* If the poll returns error then we need to do diag reset */ 698 kprintf("%s: header read with error; iocstatus = 0x%x\n", 699 __func__, ioc_status); 700 error = ENXIO; 701 goto out; 702 } 703 /* We have to do free and alloc for the reply-free and reply-post 704 * counters to match - Need to review the reply FIFO handling. 705 */ 706 mps_free_command(sc, cm); 707 708 if ((cm = mps_alloc_command(sc)) == NULL) { 709 kprintf("%s: command alloc failed @ line %d\n", __func__, 710 __LINE__); 711 error = EBUSY; 712 goto out; 713 } 714 request = (MPI2_CONFIG_REQUEST *)cm->cm_req; 715 bzero(request, sizeof(MPI2_CONFIG_REQUEST)); 716 request->Function = MPI2_FUNCTION_CONFIG; 717 request->Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; 718 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 719 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING; 720 request->Header.PageNumber = 0; 721 request->Header.PageVersion = MPI2_DRIVERMAPPING0_PAGEVERSION; 722 request->ExtPageLength = mpi_reply->ExtPageLength; 723 request->PageAddress = 1 << MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT; 724 request->PageAddress |= htole16(entry_idx); 725 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4; 726 cm->cm_sge = &request->PageBufferSGE; 727 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION); 728 cm->cm_flags = MPS_CM_FLAGS_SGE_SIMPLE | MPS_CM_FLAGS_DATAOUT; 729 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 730 page = kmalloc(cm->cm_length, M_MPT2, M_ZERO | M_INTWAIT); 731 if (!page) { 732 kprintf("%s: page alloc failed\n", __func__); 733 error = ENOMEM; 734 goto out; 735 } 736 bcopy(config_page, page, MIN(cm->cm_length, 737 (sizeof(Mpi2DriverMappingPage0_t)))); 738 cm->cm_data = page; 739 error = mps_request_polled(sc, cm); 740 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; 741 if (error || (reply == NULL)) { 742 /* FIXME */ 743 /* If the poll returns error then we need to do diag reset */ 744 kprintf("%s: poll for page completed with error %d", 745 __func__, error); 746 error = ENXIO; 747 goto out; 748 } 749 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK; 750 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); 751 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 752 /* FIXME */ 753 /* If the poll returns error then we need to do diag reset */ 754 kprintf("%s: page written with error; iocstatus = 0x%x\n", 755 __func__, ioc_status); 756 error = ENXIO; 757 goto out; 758 } 759 out: 760 kfree(page, M_MPT2); 761 if (cm) 762 mps_free_command(sc, cm); 763 return (error); 764 } 765 766 /** 767 * mps_config_get_sas_device_pg0 - obtain sas device page 0 768 * @sc: per adapter object 769 * @mpi_reply: reply mf payload returned from firmware 770 * @config_page: contents of the config page 771 * @form: GET_NEXT_HANDLE or HANDLE 772 * @handle: device handle 773 * Context: sleep. 774 * 775 * Returns 0 for success, non-zero for failure. 776 */ 777 int 778 mps_config_get_sas_device_pg0(struct mps_softc *sc, Mpi2ConfigReply_t 779 *mpi_reply, Mpi2SasDevicePage0_t *config_page, u32 form, u16 handle) 780 { 781 MPI2_CONFIG_REQUEST *request; 782 MPI2_CONFIG_REPLY *reply; 783 struct mps_command *cm; 784 Mpi2SasDevicePage0_t *page = NULL; 785 int error = 0; 786 u16 ioc_status; 787 788 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 789 790 if ((cm = mps_alloc_command(sc)) == NULL) { 791 kprintf("%s: command alloc failed @ line %d\n", __func__, 792 __LINE__); 793 error = EBUSY; 794 goto out; 795 } 796 request = (MPI2_CONFIG_REQUEST *)cm->cm_req; 797 bzero(request, sizeof(MPI2_CONFIG_REQUEST)); 798 request->Function = MPI2_FUNCTION_CONFIG; 799 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 800 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 801 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE; 802 request->Header.PageNumber = 0; 803 request->Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION; 804 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 805 cm->cm_data = NULL; 806 error = mps_request_polled(sc, cm); 807 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; 808 if (error || (reply == NULL)) { 809 /* FIXME */ 810 /* If the poll returns error then we need to do diag reset */ 811 kprintf("%s: poll for header completed with error %d", 812 __func__, error); 813 error = ENXIO; 814 goto out; 815 } 816 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK; 817 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); 818 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 819 /* FIXME */ 820 /* If the poll returns error then we need to do diag reset */ 821 kprintf("%s: header read with error; iocstatus = 0x%x\n", 822 __func__, ioc_status); 823 error = ENXIO; 824 goto out; 825 } 826 /* We have to do free and alloc for the reply-free and reply-post 827 * counters to match - Need to review the reply FIFO handling. 828 */ 829 mps_free_command(sc, cm); 830 831 if ((cm = mps_alloc_command(sc)) == NULL) { 832 kprintf("%s: command alloc failed @ line %d\n", __func__, 833 __LINE__); 834 error = EBUSY; 835 goto out; 836 } 837 request = (MPI2_CONFIG_REQUEST *)cm->cm_req; 838 bzero(request, sizeof(MPI2_CONFIG_REQUEST)); 839 request->Function = MPI2_FUNCTION_CONFIG; 840 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 841 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 842 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE; 843 request->Header.PageNumber = 0; 844 request->Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION; 845 request->ExtPageLength = mpi_reply->ExtPageLength; 846 request->PageAddress = htole32(form | handle); 847 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4; 848 cm->cm_sge = &request->PageBufferSGE; 849 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION); 850 cm->cm_flags = MPS_CM_FLAGS_SGE_SIMPLE | MPS_CM_FLAGS_DATAIN; 851 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 852 page = kmalloc(cm->cm_length, M_MPT2, M_ZERO | M_INTWAIT); 853 if (!page) { 854 kprintf("%s: page alloc failed\n", __func__); 855 error = ENOMEM; 856 goto out; 857 } 858 cm->cm_data = page; 859 860 error = mps_request_polled(sc, cm); 861 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; 862 if (error || (reply == NULL)) { 863 /* FIXME */ 864 /* If the poll returns error then we need to do diag reset */ 865 kprintf("%s: poll for page completed with error %d", 866 __func__, error); 867 error = ENXIO; 868 goto out; 869 } 870 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK; 871 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); 872 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 873 /* FIXME */ 874 /* If the poll returns error then we need to do diag reset */ 875 kprintf("%s: page read with error; iocstatus = 0x%x\n", 876 __func__, ioc_status); 877 error = ENXIO; 878 goto out; 879 } 880 bcopy(page, config_page, MIN(cm->cm_length, 881 sizeof(Mpi2SasDevicePage0_t))); 882 out: 883 kfree(page, M_MPT2); 884 if (cm) 885 mps_free_command(sc, cm); 886 return (error); 887 } 888 889 /** 890 * mps_config_get_bios_pg3 - obtain BIOS page 3 891 * @sc: per adapter object 892 * @mpi_reply: reply mf payload returned from firmware 893 * @config_page: contents of the config page 894 * Context: sleep. 895 * 896 * Returns 0 for success, non-zero for failure. 897 */ 898 int 899 mps_config_get_bios_pg3(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, 900 Mpi2BiosPage3_t *config_page) 901 { 902 MPI2_CONFIG_REQUEST *request; 903 MPI2_CONFIG_REPLY *reply; 904 struct mps_command *cm; 905 Mpi2BiosPage3_t *page = NULL; 906 int error = 0; 907 u16 ioc_status; 908 909 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 910 911 if ((cm = mps_alloc_command(sc)) == NULL) { 912 kprintf("%s: command alloc failed @ line %d\n", __func__, 913 __LINE__); 914 error = EBUSY; 915 goto out; 916 } 917 request = (MPI2_CONFIG_REQUEST *)cm->cm_req; 918 bzero(request, sizeof(MPI2_CONFIG_REQUEST)); 919 request->Function = MPI2_FUNCTION_CONFIG; 920 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 921 request->Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS; 922 request->Header.PageNumber = 3; 923 request->Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION; 924 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 925 cm->cm_data = NULL; 926 error = mps_request_polled(sc, cm); 927 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; 928 if (error || (reply == NULL)) { 929 /* FIXME */ 930 /* If the poll returns error then we need to do diag reset */ 931 kprintf("%s: poll for header completed with error %d", 932 __func__, error); 933 error = ENXIO; 934 goto out; 935 } 936 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK; 937 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); 938 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 939 /* FIXME */ 940 /* If the poll returns error then we need to do diag reset */ 941 kprintf("%s: header read with error; iocstatus = 0x%x\n", 942 __func__, ioc_status); 943 error = ENXIO; 944 goto out; 945 } 946 /* We have to do free and alloc for the reply-free and reply-post 947 * counters to match - Need to review the reply FIFO handling. 948 */ 949 mps_free_command(sc, cm); 950 951 if ((cm = mps_alloc_command(sc)) == NULL) { 952 kprintf("%s: command alloc failed @ line %d\n", __func__, 953 __LINE__); 954 error = EBUSY; 955 goto out; 956 } 957 request = (MPI2_CONFIG_REQUEST *)cm->cm_req; 958 bzero(request, sizeof(MPI2_CONFIG_REQUEST)); 959 request->Function = MPI2_FUNCTION_CONFIG; 960 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 961 request->Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS; 962 request->Header.PageNumber = 3; 963 request->Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION; 964 request->Header.PageLength = mpi_reply->Header.PageLength; 965 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4; 966 cm->cm_sge = &request->PageBufferSGE; 967 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION); 968 cm->cm_flags = MPS_CM_FLAGS_SGE_SIMPLE | MPS_CM_FLAGS_DATAIN; 969 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 970 page = kmalloc(cm->cm_length, M_MPT2, M_ZERO | M_INTWAIT); 971 if (!page) { 972 kprintf("%s: page alloc failed\n", __func__); 973 error = ENOMEM; 974 goto out; 975 } 976 cm->cm_data = page; 977 978 error = mps_request_polled(sc, cm); 979 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; 980 if (error || (reply == NULL)) { 981 /* FIXME */ 982 /* If the poll returns error then we need to do diag reset */ 983 kprintf("%s: poll for page completed with error %d", 984 __func__, error); 985 error = ENXIO; 986 goto out; 987 } 988 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK; 989 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); 990 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 991 /* FIXME */ 992 /* If the poll returns error then we need to do diag reset */ 993 kprintf("%s: page read with error; iocstatus = 0x%x\n", 994 __func__, ioc_status); 995 error = ENXIO; 996 goto out; 997 } 998 bcopy(page, config_page, MIN(cm->cm_length, sizeof(Mpi2BiosPage3_t))); 999 out: 1000 kfree(page, M_MPT2); 1001 if (cm) 1002 mps_free_command(sc, cm); 1003 return (error); 1004 } 1005 1006 /** 1007 * mps_config_get_raid_volume_pg0 - obtain raid volume page 0 1008 * @sc: per adapter object 1009 * @mpi_reply: reply mf payload returned from firmware 1010 * @config_page: contents of the config page 1011 * @page_address: form and handle value used to get page 1012 * Context: sleep. 1013 * 1014 * Returns 0 for success, non-zero for failure. 1015 */ 1016 int 1017 mps_config_get_raid_volume_pg0(struct mps_softc *sc, Mpi2ConfigReply_t 1018 *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 page_address) 1019 { 1020 MPI2_CONFIG_REQUEST *request; 1021 MPI2_CONFIG_REPLY *reply; 1022 struct mps_command *cm; 1023 Mpi2RaidVolPage0_t *page = NULL; 1024 int error = 0; 1025 u16 ioc_status; 1026 1027 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 1028 1029 if ((cm = mps_alloc_command(sc)) == NULL) { 1030 kprintf("%s: command alloc failed @ line %d\n", __func__, 1031 __LINE__); 1032 error = EBUSY; 1033 goto out; 1034 } 1035 request = (MPI2_CONFIG_REQUEST *)cm->cm_req; 1036 bzero(request, sizeof(MPI2_CONFIG_REQUEST)); 1037 request->Function = MPI2_FUNCTION_CONFIG; 1038 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1039 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; 1040 request->Header.PageNumber = 0; 1041 request->Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION; 1042 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 1043 cm->cm_data = NULL; 1044 error = mps_request_polled(sc, cm); 1045 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; 1046 if (error || (reply == NULL)) { 1047 /* FIXME */ 1048 /* If the poll returns error then we need to do diag reset */ 1049 kprintf("%s: poll for header completed with error %d", 1050 __func__, error); 1051 error = ENXIO; 1052 goto out; 1053 } 1054 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK; 1055 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); 1056 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 1057 /* FIXME */ 1058 /* If the poll returns error then we need to do diag reset */ 1059 kprintf("%s: header read with error; iocstatus = 0x%x\n", 1060 __func__, ioc_status); 1061 error = ENXIO; 1062 goto out; 1063 } 1064 /* We have to do free and alloc for the reply-free and reply-post 1065 * counters to match - Need to review the reply FIFO handling. 1066 */ 1067 mps_free_command(sc, cm); 1068 1069 if ((cm = mps_alloc_command(sc)) == NULL) { 1070 kprintf("%s: command alloc failed @ line %d\n", __func__, 1071 __LINE__); 1072 error = EBUSY; 1073 goto out; 1074 } 1075 request = (MPI2_CONFIG_REQUEST *)cm->cm_req; 1076 bzero(request, sizeof(MPI2_CONFIG_REQUEST)); 1077 request->Function = MPI2_FUNCTION_CONFIG; 1078 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1079 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; 1080 request->Header.PageNumber = 0; 1081 request->Header.PageLength = mpi_reply->Header.PageLength; 1082 request->Header.PageVersion = mpi_reply->Header.PageVersion; 1083 request->PageAddress = page_address; 1084 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4; 1085 cm->cm_sge = &request->PageBufferSGE; 1086 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION); 1087 cm->cm_flags = MPS_CM_FLAGS_SGE_SIMPLE | MPS_CM_FLAGS_DATAIN; 1088 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 1089 page = kmalloc(cm->cm_length, M_MPT2, M_ZERO | M_INTWAIT); 1090 if (!page) { 1091 kprintf("%s: page alloc failed\n", __func__); 1092 error = ENOMEM; 1093 goto out; 1094 } 1095 cm->cm_data = page; 1096 1097 error = mps_request_polled(sc, cm); 1098 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; 1099 if (error || (reply == NULL)) { 1100 /* FIXME */ 1101 /* If the poll returns error then we need to do diag reset */ 1102 kprintf("%s: poll for page completed with error %d", 1103 __func__, error); 1104 error = ENXIO; 1105 goto out; 1106 } 1107 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK; 1108 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); 1109 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 1110 /* FIXME */ 1111 /* If the poll returns error then we need to do diag reset */ 1112 kprintf("%s: page read with error; iocstatus = 0x%x\n", 1113 __func__, ioc_status); 1114 error = ENXIO; 1115 goto out; 1116 } 1117 bcopy(page, config_page, cm->cm_length); 1118 out: 1119 kfree(page, M_MPT2); 1120 if (cm) 1121 mps_free_command(sc, cm); 1122 return (error); 1123 } 1124 1125 /** 1126 * mps_config_get_raid_volume_pg1 - obtain raid volume page 1 1127 * @sc: per adapter object 1128 * @mpi_reply: reply mf payload returned from firmware 1129 * @config_page: contents of the config page 1130 * @form: GET_NEXT_HANDLE or HANDLE 1131 * @handle: volume handle 1132 * Context: sleep. 1133 * 1134 * Returns 0 for success, non-zero for failure. 1135 */ 1136 int 1137 mps_config_get_raid_volume_pg1(struct mps_softc *sc, Mpi2ConfigReply_t 1138 *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form, u16 handle) 1139 { 1140 MPI2_CONFIG_REQUEST *request; 1141 MPI2_CONFIG_REPLY *reply; 1142 struct mps_command *cm; 1143 Mpi2RaidVolPage1_t *page = NULL; 1144 int error = 0; 1145 u16 ioc_status; 1146 1147 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 1148 1149 if ((cm = mps_alloc_command(sc)) == NULL) { 1150 kprintf("%s: command alloc failed @ line %d\n", __func__, 1151 __LINE__); 1152 error = EBUSY; 1153 goto out; 1154 } 1155 request = (MPI2_CONFIG_REQUEST *)cm->cm_req; 1156 bzero(request, sizeof(MPI2_CONFIG_REQUEST)); 1157 request->Function = MPI2_FUNCTION_CONFIG; 1158 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1159 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; 1160 request->Header.PageNumber = 1; 1161 request->Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION; 1162 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 1163 cm->cm_data = NULL; 1164 error = mps_request_polled(sc, cm); 1165 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; 1166 if (error || (reply == NULL)) { 1167 /* FIXME */ 1168 /* If the poll returns error then we need to do diag reset */ 1169 kprintf("%s: poll for header completed with error %d", 1170 __func__, error); 1171 error = ENXIO; 1172 goto out; 1173 } 1174 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK; 1175 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); 1176 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 1177 /* FIXME */ 1178 /* If the poll returns error then we need to do diag reset */ 1179 kprintf("%s: header read with error; iocstatus = 0x%x\n", 1180 __func__, ioc_status); 1181 error = ENXIO; 1182 goto out; 1183 } 1184 /* We have to do free and alloc for the reply-free and reply-post 1185 * counters to match - Need to review the reply FIFO handling. 1186 */ 1187 mps_free_command(sc, cm); 1188 1189 if ((cm = mps_alloc_command(sc)) == NULL) { 1190 kprintf("%s: command alloc failed @ line %d\n", __func__, 1191 __LINE__); 1192 error = EBUSY; 1193 goto out; 1194 } 1195 request = (MPI2_CONFIG_REQUEST *)cm->cm_req; 1196 bzero(request, sizeof(MPI2_CONFIG_REQUEST)); 1197 request->Function = MPI2_FUNCTION_CONFIG; 1198 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1199 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; 1200 request->Header.PageNumber = 1; 1201 request->Header.PageLength = mpi_reply->Header.PageLength; 1202 request->Header.PageVersion = mpi_reply->Header.PageVersion; 1203 request->PageAddress = htole32(form | handle); 1204 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4; 1205 cm->cm_sge = &request->PageBufferSGE; 1206 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION); 1207 cm->cm_flags = MPS_CM_FLAGS_SGE_SIMPLE | MPS_CM_FLAGS_DATAIN; 1208 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 1209 page = kmalloc(cm->cm_length, M_MPT2, M_ZERO | M_INTWAIT); 1210 if (!page) { 1211 kprintf("%s: page alloc failed\n", __func__); 1212 error = ENOMEM; 1213 goto out; 1214 } 1215 cm->cm_data = page; 1216 1217 error = mps_request_polled(sc, cm); 1218 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; 1219 if (error || (reply == NULL)) { 1220 /* FIXME */ 1221 /* If the poll returns error then we need to do diag reset */ 1222 kprintf("%s: poll for page completed with error %d", 1223 __func__, error); 1224 error = ENXIO; 1225 goto out; 1226 } 1227 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK; 1228 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); 1229 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 1230 /* FIXME */ 1231 /* If the poll returns error then we need to do diag reset */ 1232 kprintf("%s: page read with error; iocstatus = 0x%x\n", 1233 __func__, ioc_status); 1234 error = ENXIO; 1235 goto out; 1236 } 1237 bcopy(page, config_page, MIN(cm->cm_length, 1238 sizeof(Mpi2RaidVolPage1_t))); 1239 out: 1240 kfree(page, M_MPT2); 1241 if (cm) 1242 mps_free_command(sc, cm); 1243 return (error); 1244 } 1245 1246 /** 1247 * mps_config_get_volume_wwid - returns wwid given the volume handle 1248 * @sc: per adapter object 1249 * @volume_handle: volume handle 1250 * @wwid: volume wwid 1251 * Context: sleep. 1252 * 1253 * Returns 0 for success, non-zero for failure. 1254 */ 1255 int 1256 mps_config_get_volume_wwid(struct mps_softc *sc, u16 volume_handle, u64 *wwid) 1257 { 1258 Mpi2ConfigReply_t mpi_reply; 1259 Mpi2RaidVolPage1_t raid_vol_pg1; 1260 1261 *wwid = 0; 1262 if (!(mps_config_get_raid_volume_pg1(sc, &mpi_reply, &raid_vol_pg1, 1263 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, volume_handle))) { 1264 *wwid = le64toh((u64)raid_vol_pg1.WWID.High << 32 | 1265 raid_vol_pg1.WWID.Low); 1266 return 0; 1267 } else 1268 return -1; 1269 } 1270 1271 /** 1272 * mps_config_get_pd_pg0 - obtain raid phys disk page 0 1273 * @sc: per adapter object 1274 * @mpi_reply: reply mf payload returned from firmware 1275 * @config_page: contents of the config page 1276 * @page_address: form and handle value used to get page 1277 * Context: sleep. 1278 * 1279 * Returns 0 for success, non-zero for failure. 1280 */ 1281 int 1282 mps_config_get_raid_pd_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, 1283 Mpi2RaidPhysDiskPage0_t *config_page, u32 page_address) 1284 { 1285 MPI2_CONFIG_REQUEST *request; 1286 MPI2_CONFIG_REPLY *reply; 1287 struct mps_command *cm; 1288 Mpi2RaidPhysDiskPage0_t *page = NULL; 1289 int error = 0; 1290 u16 ioc_status; 1291 1292 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 1293 1294 if ((cm = mps_alloc_command(sc)) == NULL) { 1295 kprintf("%s: command alloc failed @ line %d\n", __func__, 1296 __LINE__); 1297 error = EBUSY; 1298 goto out; 1299 } 1300 request = (MPI2_CONFIG_REQUEST *)cm->cm_req; 1301 bzero(request, sizeof(MPI2_CONFIG_REQUEST)); 1302 request->Function = MPI2_FUNCTION_CONFIG; 1303 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 1304 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK; 1305 request->Header.PageNumber = 0; 1306 request->Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION; 1307 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 1308 cm->cm_data = NULL; 1309 error = mps_request_polled(sc, cm); 1310 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; 1311 if (error || (reply == NULL)) { 1312 /* FIXME */ 1313 /* If the poll returns error then we need to do diag reset */ 1314 kprintf("%s: poll for header completed with error %d", 1315 __func__, error); 1316 error = ENXIO; 1317 goto out; 1318 } 1319 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK; 1320 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); 1321 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 1322 /* FIXME */ 1323 /* If the poll returns error then we need to do diag reset */ 1324 kprintf("%s: header read with error; iocstatus = 0x%x\n", 1325 __func__, ioc_status); 1326 error = ENXIO; 1327 goto out; 1328 } 1329 /* We have to do free and alloc for the reply-free and reply-post 1330 * counters to match - Need to review the reply FIFO handling. 1331 */ 1332 mps_free_command(sc, cm); 1333 1334 if ((cm = mps_alloc_command(sc)) == NULL) { 1335 kprintf("%s: command alloc failed @ line %d\n", __func__, 1336 __LINE__); 1337 error = EBUSY; 1338 goto out; 1339 } 1340 request = (MPI2_CONFIG_REQUEST *)cm->cm_req; 1341 bzero(request, sizeof(MPI2_CONFIG_REQUEST)); 1342 request->Function = MPI2_FUNCTION_CONFIG; 1343 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1344 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK; 1345 request->Header.PageNumber = 0; 1346 request->Header.PageLength = mpi_reply->Header.PageLength; 1347 request->Header.PageVersion = mpi_reply->Header.PageVersion; 1348 request->PageAddress = page_address; 1349 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4; 1350 cm->cm_sge = &request->PageBufferSGE; 1351 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION); 1352 cm->cm_flags = MPS_CM_FLAGS_SGE_SIMPLE | MPS_CM_FLAGS_DATAIN; 1353 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 1354 page = kmalloc(cm->cm_length, M_MPT2, M_ZERO | M_INTWAIT); 1355 if (!page) { 1356 kprintf("%s: page alloc failed\n", __func__); 1357 error = ENOMEM; 1358 goto out; 1359 } 1360 cm->cm_data = page; 1361 1362 error = mps_request_polled(sc, cm); 1363 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; 1364 if (error || (reply == NULL)) { 1365 /* FIXME */ 1366 /* If the poll returns error then we need to do diag reset */ 1367 kprintf("%s: poll for page completed with error %d", 1368 __func__, error); 1369 error = ENXIO; 1370 goto out; 1371 } 1372 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK; 1373 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); 1374 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 1375 /* FIXME */ 1376 /* If the poll returns error then we need to do diag reset */ 1377 kprintf("%s: page read with error; iocstatus = 0x%x\n", 1378 __func__, ioc_status); 1379 error = ENXIO; 1380 goto out; 1381 } 1382 bcopy(page, config_page, MIN(cm->cm_length, 1383 sizeof(Mpi2RaidPhysDiskPage0_t))); 1384 out: 1385 kfree(page, M_MPT2); 1386 if (cm) 1387 mps_free_command(sc, cm); 1388 return (error); 1389 } 1390