1 /*- 2 * Copyright (c) 2011-2015 LSI Corp. 3 * Copyright (c) 2013-2015 Avago Technologies 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 /* TODO Move headers to mpsvar */ 34 #include <sys/types.h> 35 #include <sys/param.h> 36 #include <sys/lock.h> 37 #include <sys/mutex.h> 38 #include <sys/systm.h> 39 #include <sys/kernel.h> 40 #include <sys/malloc.h> 41 #include <sys/kthread.h> 42 #include <sys/taskqueue.h> 43 #include <sys/bus.h> 44 #include <sys/endian.h> 45 #include <sys/sysctl.h> 46 #include <sys/sbuf.h> 47 #include <sys/eventhandler.h> 48 #include <sys/uio.h> 49 #include <machine/bus.h> 50 #include <machine/resource.h> 51 #include <dev/mps/mpi/mpi2_type.h> 52 #include <dev/mps/mpi/mpi2.h> 53 #include <dev/mps/mpi/mpi2_ioc.h> 54 #include <dev/mps/mpi/mpi2_sas.h> 55 #include <dev/mps/mpi/mpi2_cnfg.h> 56 #include <dev/mps/mpi/mpi2_init.h> 57 #include <dev/mps/mpi/mpi2_tool.h> 58 #include <dev/mps/mps_ioctl.h> 59 #include <dev/mps/mpsvar.h> 60 #include <dev/mps/mps_mapping.h> 61 62 /** 63 * _mapping_clear_entry - Clear a particular mapping entry. 64 * @map_entry: map table entry 65 * 66 * Returns nothing. 67 */ 68 static inline void 69 _mapping_clear_map_entry(struct dev_mapping_table *map_entry) 70 { 71 map_entry->physical_id = 0; 72 map_entry->device_info = 0; 73 map_entry->phy_bits = 0; 74 map_entry->dpm_entry_num = MPS_DPM_BAD_IDX; 75 map_entry->dev_handle = 0; 76 map_entry->channel = -1; 77 map_entry->id = -1; 78 map_entry->missing_count = 0; 79 map_entry->init_complete = 0; 80 map_entry->TLR_bits = (u8)MPI2_SCSIIO_CONTROL_NO_TLR; 81 } 82 83 /** 84 * _mapping_clear_enc_entry - Clear a particular enclosure table entry. 85 * @enc_entry: enclosure table entry 86 * 87 * Returns nothing. 88 */ 89 static inline void 90 _mapping_clear_enc_entry(struct enc_mapping_table *enc_entry) 91 { 92 enc_entry->enclosure_id = 0; 93 enc_entry->start_index = MPS_MAPTABLE_BAD_IDX; 94 enc_entry->phy_bits = 0; 95 enc_entry->dpm_entry_num = MPS_DPM_BAD_IDX; 96 enc_entry->enc_handle = 0; 97 enc_entry->num_slots = 0; 98 enc_entry->start_slot = 0; 99 enc_entry->missing_count = 0; 100 enc_entry->removal_flag = 0; 101 enc_entry->skip_search = 0; 102 enc_entry->init_complete = 0; 103 } 104 105 /** 106 * _mapping_commit_enc_entry - write a particular enc entry in DPM page0. 107 * @sc: per adapter object 108 * @enc_entry: enclosure table entry 109 * 110 * Returns 0 for success, non-zero for failure. 111 */ 112 static int 113 _mapping_commit_enc_entry(struct mps_softc *sc, 114 struct enc_mapping_table *et_entry) 115 { 116 Mpi2DriverMap0Entry_t *dpm_entry; 117 struct dev_mapping_table *mt_entry; 118 Mpi2ConfigReply_t mpi_reply; 119 Mpi2DriverMappingPage0_t config_page; 120 121 if (!sc->is_dpm_enable) 122 return 0; 123 124 memset(&config_page, 0, sizeof(Mpi2DriverMappingPage0_t)); 125 memcpy(&config_page.Header, (u8 *) sc->dpm_pg0, 126 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 127 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *)sc->dpm_pg0 + 128 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 129 dpm_entry += et_entry->dpm_entry_num; 130 dpm_entry->PhysicalIdentifier.Low = 131 ( 0xFFFFFFFF & et_entry->enclosure_id); 132 dpm_entry->PhysicalIdentifier.High = 133 ( et_entry->enclosure_id >> 32); 134 mt_entry = &sc->mapping_table[et_entry->start_index]; 135 dpm_entry->DeviceIndex = htole16(mt_entry->id); 136 dpm_entry->MappingInformation = et_entry->num_slots; 137 dpm_entry->MappingInformation <<= MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT; 138 dpm_entry->MappingInformation |= et_entry->missing_count; 139 dpm_entry->MappingInformation = htole16(dpm_entry->MappingInformation); 140 dpm_entry->PhysicalBitsMapping = htole32(et_entry->phy_bits); 141 dpm_entry->Reserved1 = 0; 142 143 memcpy(&config_page.Entry, (u8 *)dpm_entry, 144 sizeof(Mpi2DriverMap0Entry_t)); 145 if (mps_config_set_dpm_pg0(sc, &mpi_reply, &config_page, 146 et_entry->dpm_entry_num)) { 147 printf("%s: write of dpm entry %d for enclosure failed\n", 148 __func__, et_entry->dpm_entry_num); 149 dpm_entry->MappingInformation = le16toh(dpm_entry-> 150 MappingInformation); 151 dpm_entry->DeviceIndex = le16toh(dpm_entry->DeviceIndex); 152 dpm_entry->PhysicalBitsMapping = 153 le32toh(dpm_entry->PhysicalBitsMapping); 154 return -1; 155 } 156 dpm_entry->MappingInformation = le16toh(dpm_entry-> 157 MappingInformation); 158 dpm_entry->DeviceIndex = le16toh(dpm_entry->DeviceIndex); 159 dpm_entry->PhysicalBitsMapping = 160 le32toh(dpm_entry->PhysicalBitsMapping); 161 return 0; 162 } 163 164 /** 165 * _mapping_commit_map_entry - write a particular map table entry in DPM page0. 166 * @sc: per adapter object 167 * @enc_entry: enclosure table entry 168 * 169 * Returns 0 for success, non-zero for failure. 170 */ 171 172 static int 173 _mapping_commit_map_entry(struct mps_softc *sc, 174 struct dev_mapping_table *mt_entry) 175 { 176 Mpi2DriverMap0Entry_t *dpm_entry; 177 Mpi2ConfigReply_t mpi_reply; 178 Mpi2DriverMappingPage0_t config_page; 179 180 if (!sc->is_dpm_enable) 181 return 0; 182 183 memset(&config_page, 0, sizeof(Mpi2DriverMappingPage0_t)); 184 memcpy(&config_page.Header, (u8 *)sc->dpm_pg0, 185 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 186 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *) sc->dpm_pg0 + 187 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 188 dpm_entry = dpm_entry + mt_entry->dpm_entry_num; 189 dpm_entry->PhysicalIdentifier.Low = (0xFFFFFFFF & 190 mt_entry->physical_id); 191 dpm_entry->PhysicalIdentifier.High = (mt_entry->physical_id >> 32); 192 dpm_entry->DeviceIndex = htole16(mt_entry->id); 193 dpm_entry->MappingInformation = htole16(mt_entry->missing_count); 194 dpm_entry->PhysicalBitsMapping = 0; 195 dpm_entry->Reserved1 = 0; 196 dpm_entry->MappingInformation = htole16(dpm_entry->MappingInformation); 197 memcpy(&config_page.Entry, (u8 *)dpm_entry, 198 sizeof(Mpi2DriverMap0Entry_t)); 199 if (mps_config_set_dpm_pg0(sc, &mpi_reply, &config_page, 200 mt_entry->dpm_entry_num)) { 201 printf("%s: write of dpm entry %d for device failed\n", 202 __func__, mt_entry->dpm_entry_num); 203 dpm_entry->MappingInformation = le16toh(dpm_entry-> 204 MappingInformation); 205 dpm_entry->DeviceIndex = le16toh(dpm_entry->DeviceIndex); 206 return -1; 207 } 208 209 dpm_entry->MappingInformation = le16toh(dpm_entry->MappingInformation); 210 dpm_entry->DeviceIndex = le16toh(dpm_entry->DeviceIndex); 211 return 0; 212 } 213 214 /** 215 * _mapping_get_ir_maprange - get start and end index for IR map range. 216 * @sc: per adapter object 217 * @start_idx: place holder for start index 218 * @end_idx: place holder for end index 219 * 220 * The IR volumes can be mapped either at start or end of the mapping table 221 * this function gets the detail of where IR volume mapping starts and ends 222 * in the device mapping table 223 * 224 * Returns nothing. 225 */ 226 static void 227 _mapping_get_ir_maprange(struct mps_softc *sc, u32 *start_idx, u32 *end_idx) 228 { 229 u16 volume_mapping_flags; 230 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 231 232 volume_mapping_flags = le16toh(sc->ioc_pg8.IRVolumeMappingFlags) & 233 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE; 234 if (volume_mapping_flags == MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING) { 235 *start_idx = 0; 236 if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0) 237 *start_idx = 1; 238 } else 239 *start_idx = sc->max_devices - sc->max_volumes; 240 *end_idx = *start_idx + sc->max_volumes - 1; 241 } 242 243 /** 244 * _mapping_get_enc_idx_from_id - get enclosure index from enclosure ID 245 * @sc: per adapter object 246 * @enc_id: enclosure logical identifier 247 * 248 * Returns the index of enclosure entry on success or bad index. 249 */ 250 static u8 251 _mapping_get_enc_idx_from_id(struct mps_softc *sc, u64 enc_id, 252 u64 phy_bits) 253 { 254 struct enc_mapping_table *et_entry; 255 u8 enc_idx = 0; 256 257 for (enc_idx = 0; enc_idx < sc->num_enc_table_entries; enc_idx++) { 258 et_entry = &sc->enclosure_table[enc_idx]; 259 if ((et_entry->enclosure_id == le64toh(enc_id)) && 260 (!et_entry->phy_bits || (et_entry->phy_bits & 261 le32toh(phy_bits)))) 262 return enc_idx; 263 } 264 return MPS_ENCTABLE_BAD_IDX; 265 } 266 267 /** 268 * _mapping_get_enc_idx_from_handle - get enclosure index from handle 269 * @sc: per adapter object 270 * @enc_id: enclosure handle 271 * 272 * Returns the index of enclosure entry on success or bad index. 273 */ 274 static u8 275 _mapping_get_enc_idx_from_handle(struct mps_softc *sc, u16 handle) 276 { 277 struct enc_mapping_table *et_entry; 278 u8 enc_idx = 0; 279 280 for (enc_idx = 0; enc_idx < sc->num_enc_table_entries; enc_idx++) { 281 et_entry = &sc->enclosure_table[enc_idx]; 282 if (et_entry->missing_count) 283 continue; 284 if (et_entry->enc_handle == handle) 285 return enc_idx; 286 } 287 return MPS_ENCTABLE_BAD_IDX; 288 } 289 290 /** 291 * _mapping_get_high_missing_et_idx - get missing enclosure index 292 * @sc: per adapter object 293 * 294 * Search through the enclosure table and identifies the enclosure entry 295 * with high missing count and returns it's index 296 * 297 * Returns the index of enclosure entry on success or bad index. 298 */ 299 static u8 300 _mapping_get_high_missing_et_idx(struct mps_softc *sc) 301 { 302 struct enc_mapping_table *et_entry; 303 u8 high_missing_count = 0; 304 u8 enc_idx, high_idx = MPS_ENCTABLE_BAD_IDX; 305 306 for (enc_idx = 0; enc_idx < sc->num_enc_table_entries; enc_idx++) { 307 et_entry = &sc->enclosure_table[enc_idx]; 308 if ((et_entry->missing_count > high_missing_count) && 309 !et_entry->skip_search) { 310 high_missing_count = et_entry->missing_count; 311 high_idx = enc_idx; 312 } 313 } 314 return high_idx; 315 } 316 317 /** 318 * _mapping_get_high_missing_mt_idx - get missing map table index 319 * @sc: per adapter object 320 * 321 * Search through the map table and identifies the device entry 322 * with high missing count and returns it's index 323 * 324 * Returns the index of map table entry on success or bad index. 325 */ 326 static u32 327 _mapping_get_high_missing_mt_idx(struct mps_softc *sc) 328 { 329 u32 map_idx, high_idx = MPS_ENCTABLE_BAD_IDX; 330 u8 high_missing_count = 0; 331 u32 start_idx, end_idx, start_idx_ir, end_idx_ir; 332 struct dev_mapping_table *mt_entry; 333 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 334 335 start_idx = 0; 336 start_idx_ir = 0; 337 end_idx_ir = 0; 338 end_idx = sc->max_devices; 339 if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0) 340 start_idx = 1; 341 if (sc->ir_firmware) { 342 _mapping_get_ir_maprange(sc, &start_idx_ir, &end_idx_ir); 343 if (start_idx == start_idx_ir) 344 start_idx = end_idx_ir + 1; 345 else 346 end_idx = start_idx_ir; 347 } 348 mt_entry = &sc->mapping_table[start_idx]; 349 for (map_idx = start_idx; map_idx < end_idx; map_idx++, mt_entry++) { 350 if (mt_entry->missing_count > high_missing_count) { 351 high_missing_count = mt_entry->missing_count; 352 high_idx = map_idx; 353 } 354 } 355 return high_idx; 356 } 357 358 /** 359 * _mapping_get_ir_mt_idx_from_wwid - get map table index from volume WWID 360 * @sc: per adapter object 361 * @wwid: world wide unique ID of the volume 362 * 363 * Returns the index of map table entry on success or bad index. 364 */ 365 static u32 366 _mapping_get_ir_mt_idx_from_wwid(struct mps_softc *sc, u64 wwid) 367 { 368 u32 start_idx, end_idx, map_idx; 369 struct dev_mapping_table *mt_entry; 370 371 _mapping_get_ir_maprange(sc, &start_idx, &end_idx); 372 mt_entry = &sc->mapping_table[start_idx]; 373 for (map_idx = start_idx; map_idx <= end_idx; map_idx++, mt_entry++) 374 if (mt_entry->physical_id == wwid) 375 return map_idx; 376 377 return MPS_MAPTABLE_BAD_IDX; 378 } 379 380 /** 381 * _mapping_get_mt_idx_from_id - get map table index from a device ID 382 * @sc: per adapter object 383 * @dev_id: device identifer (SAS Address) 384 * 385 * Returns the index of map table entry on success or bad index. 386 */ 387 static u32 388 _mapping_get_mt_idx_from_id(struct mps_softc *sc, u64 dev_id) 389 { 390 u32 map_idx; 391 struct dev_mapping_table *mt_entry; 392 393 for (map_idx = 0; map_idx < sc->max_devices; map_idx++) { 394 mt_entry = &sc->mapping_table[map_idx]; 395 if (mt_entry->physical_id == dev_id) 396 return map_idx; 397 } 398 return MPS_MAPTABLE_BAD_IDX; 399 } 400 401 /** 402 * _mapping_get_ir_mt_idx_from_handle - get map table index from volume handle 403 * @sc: per adapter object 404 * @wwid: volume device handle 405 * 406 * Returns the index of map table entry on success or bad index. 407 */ 408 static u32 409 _mapping_get_ir_mt_idx_from_handle(struct mps_softc *sc, u16 volHandle) 410 { 411 u32 start_idx, end_idx, map_idx; 412 struct dev_mapping_table *mt_entry; 413 414 _mapping_get_ir_maprange(sc, &start_idx, &end_idx); 415 mt_entry = &sc->mapping_table[start_idx]; 416 for (map_idx = start_idx; map_idx <= end_idx; map_idx++, mt_entry++) 417 if (mt_entry->dev_handle == volHandle) 418 return map_idx; 419 420 return MPS_MAPTABLE_BAD_IDX; 421 } 422 423 /** 424 * _mapping_get_mt_idx_from_handle - get map table index from handle 425 * @sc: per adapter object 426 * @dev_id: device handle 427 * 428 * Returns the index of map table entry on success or bad index. 429 */ 430 static u32 431 _mapping_get_mt_idx_from_handle(struct mps_softc *sc, u16 handle) 432 { 433 u32 map_idx; 434 struct dev_mapping_table *mt_entry; 435 436 for (map_idx = 0; map_idx < sc->max_devices; map_idx++) { 437 mt_entry = &sc->mapping_table[map_idx]; 438 if (mt_entry->dev_handle == handle) 439 return map_idx; 440 } 441 return MPS_MAPTABLE_BAD_IDX; 442 } 443 444 /** 445 * _mapping_get_free_ir_mt_idx - get first free index for a volume 446 * @sc: per adapter object 447 * 448 * Search through mapping table for free index for a volume and if no free 449 * index then looks for a volume with high mapping index 450 * 451 * Returns the index of map table entry on success or bad index. 452 */ 453 static u32 454 _mapping_get_free_ir_mt_idx(struct mps_softc *sc) 455 { 456 u8 high_missing_count = 0; 457 u32 start_idx, end_idx, map_idx; 458 u32 high_idx = MPS_MAPTABLE_BAD_IDX; 459 struct dev_mapping_table *mt_entry; 460 461 _mapping_get_ir_maprange(sc, &start_idx, &end_idx); 462 463 mt_entry = &sc->mapping_table[start_idx]; 464 for (map_idx = start_idx; map_idx <= end_idx; map_idx++, mt_entry++) 465 if (!(mt_entry->device_info & MPS_MAP_IN_USE)) 466 return map_idx; 467 468 mt_entry = &sc->mapping_table[start_idx]; 469 for (map_idx = start_idx; map_idx <= end_idx; map_idx++, mt_entry++) { 470 if (mt_entry->missing_count > high_missing_count) { 471 high_missing_count = mt_entry->missing_count; 472 high_idx = map_idx; 473 } 474 } 475 return high_idx; 476 } 477 478 /** 479 * _mapping_get_free_mt_idx - get first free index for a device 480 * @sc: per adapter object 481 * @start_idx: offset in the table to start search 482 * 483 * Returns the index of map table entry on success or bad index. 484 */ 485 static u32 486 _mapping_get_free_mt_idx(struct mps_softc *sc, u32 start_idx) 487 { 488 u32 map_idx, max_idx = sc->max_devices; 489 struct dev_mapping_table *mt_entry = &sc->mapping_table[start_idx]; 490 u16 volume_mapping_flags; 491 492 volume_mapping_flags = le16toh(sc->ioc_pg8.IRVolumeMappingFlags) & 493 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE; 494 if (sc->ir_firmware && (volume_mapping_flags == 495 MPI2_IOCPAGE8_IRFLAGS_HIGH_VOLUME_MAPPING)) 496 max_idx -= sc->max_volumes; 497 for (map_idx = start_idx; map_idx < max_idx; map_idx++, mt_entry++) 498 if (!(mt_entry->device_info & (MPS_MAP_IN_USE | 499 MPS_DEV_RESERVED))) 500 return map_idx; 501 502 return MPS_MAPTABLE_BAD_IDX; 503 } 504 505 /** 506 * _mapping_get_dpm_idx_from_id - get DPM index from ID 507 * @sc: per adapter object 508 * @id: volume WWID or enclosure ID or device ID 509 * 510 * Returns the index of DPM entry on success or bad index. 511 */ 512 static u16 513 _mapping_get_dpm_idx_from_id(struct mps_softc *sc, u64 id, u32 phy_bits) 514 { 515 u16 entry_num; 516 uint64_t PhysicalIdentifier; 517 Mpi2DriverMap0Entry_t *dpm_entry; 518 519 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *)sc->dpm_pg0 + 520 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 521 PhysicalIdentifier = dpm_entry->PhysicalIdentifier.High; 522 PhysicalIdentifier = (PhysicalIdentifier << 32) | 523 dpm_entry->PhysicalIdentifier.Low; 524 for (entry_num = 0; entry_num < sc->max_dpm_entries; entry_num++, 525 dpm_entry++) 526 if ((id == PhysicalIdentifier) && 527 (!phy_bits || !dpm_entry->PhysicalBitsMapping || 528 (phy_bits & dpm_entry->PhysicalBitsMapping))) 529 return entry_num; 530 531 return MPS_DPM_BAD_IDX; 532 } 533 534 535 /** 536 * _mapping_get_free_dpm_idx - get first available DPM index 537 * @sc: per adapter object 538 * 539 * Returns the index of DPM entry on success or bad index. 540 */ 541 static u32 542 _mapping_get_free_dpm_idx(struct mps_softc *sc) 543 { 544 u16 entry_num; 545 546 for (entry_num = 0; entry_num < sc->max_dpm_entries; entry_num++) { 547 if (!sc->dpm_entry_used[entry_num]) 548 return entry_num; 549 } 550 return MPS_DPM_BAD_IDX; 551 } 552 553 /** 554 * _mapping_update_ir_missing_cnt - Updates missing count for a volume 555 * @sc: per adapter object 556 * @map_idx: map table index of the volume 557 * @element: IR configuration change element 558 * @wwid: IR volume ID. 559 * 560 * Updates the missing count in the map table and in the DPM entry for a volume 561 * 562 * Returns nothing. 563 */ 564 static void 565 _mapping_update_ir_missing_cnt(struct mps_softc *sc, u32 map_idx, 566 Mpi2EventIrConfigElement_t *element, u64 wwid) 567 { 568 struct dev_mapping_table *mt_entry; 569 u8 missing_cnt, reason = element->ReasonCode; 570 u16 dpm_idx; 571 Mpi2DriverMap0Entry_t *dpm_entry; 572 573 if (!sc->is_dpm_enable) 574 return; 575 mt_entry = &sc->mapping_table[map_idx]; 576 if (reason == MPI2_EVENT_IR_CHANGE_RC_ADDED) { 577 mt_entry->missing_count = 0; 578 } else if (reason == MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED) { 579 mt_entry->missing_count = 0; 580 mt_entry->init_complete = 0; 581 } else if ((reason == MPI2_EVENT_IR_CHANGE_RC_REMOVED) || 582 (reason == MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED)) { 583 if (!mt_entry->init_complete) { 584 if (mt_entry->missing_count < MPS_MAX_MISSING_COUNT) 585 mt_entry->missing_count++; 586 else 587 mt_entry->init_complete = 1; 588 } 589 if (!mt_entry->missing_count) 590 mt_entry->missing_count++; 591 mt_entry->dev_handle = 0; 592 } 593 594 dpm_idx = mt_entry->dpm_entry_num; 595 if (dpm_idx == MPS_DPM_BAD_IDX) { 596 if ((reason == MPI2_EVENT_IR_CHANGE_RC_ADDED) || 597 (reason == MPI2_EVENT_IR_CHANGE_RC_REMOVED)) 598 dpm_idx = _mapping_get_dpm_idx_from_id(sc, 599 mt_entry->physical_id, 0); 600 else if (reason == MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED) 601 return; 602 } 603 if (dpm_idx != MPS_DPM_BAD_IDX) { 604 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *)sc->dpm_pg0 + 605 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 606 dpm_entry += dpm_idx; 607 missing_cnt = dpm_entry->MappingInformation & 608 MPI2_DRVMAP0_MAPINFO_MISSING_MASK; 609 if ((mt_entry->physical_id == 610 le64toh((u64)dpm_entry->PhysicalIdentifier.High | 611 dpm_entry->PhysicalIdentifier.Low)) && (missing_cnt == 612 mt_entry->missing_count)) 613 mt_entry->init_complete = 1; 614 } else { 615 dpm_idx = _mapping_get_free_dpm_idx(sc); 616 mt_entry->init_complete = 0; 617 } 618 619 if ((dpm_idx != MPS_DPM_BAD_IDX) && !mt_entry->init_complete) { 620 mt_entry->init_complete = 1; 621 mt_entry->dpm_entry_num = dpm_idx; 622 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *)sc->dpm_pg0 + 623 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 624 dpm_entry += dpm_idx; 625 dpm_entry->PhysicalIdentifier.Low = 626 (0xFFFFFFFF & mt_entry->physical_id); 627 dpm_entry->PhysicalIdentifier.High = 628 (mt_entry->physical_id >> 32); 629 dpm_entry->DeviceIndex = map_idx; 630 dpm_entry->MappingInformation = mt_entry->missing_count; 631 dpm_entry->PhysicalBitsMapping = 0; 632 dpm_entry->Reserved1 = 0; 633 sc->dpm_flush_entry[dpm_idx] = 1; 634 sc->dpm_entry_used[dpm_idx] = 1; 635 } else if (dpm_idx == MPS_DPM_BAD_IDX) { 636 printf("%s: no space to add entry in DPM table\n", __func__); 637 mt_entry->init_complete = 1; 638 } 639 } 640 641 /** 642 * _mapping_add_to_removal_table - mark an entry for removal 643 * @sc: per adapter object 644 * @handle: Handle of enclosures/device/volume 645 * 646 * Adds the handle or DPM entry number in removal table. 647 * 648 * Returns nothing. 649 */ 650 static void 651 _mapping_add_to_removal_table(struct mps_softc *sc, u16 handle, 652 u16 dpm_idx) 653 { 654 struct map_removal_table *remove_entry; 655 u32 i; 656 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 657 658 remove_entry = sc->removal_table; 659 660 for (i = 0; i < sc->max_devices; i++, remove_entry++) { 661 if (remove_entry->dev_handle || remove_entry->dpm_entry_num != 662 MPS_DPM_BAD_IDX) 663 continue; 664 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 665 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 666 if (dpm_idx) 667 remove_entry->dpm_entry_num = dpm_idx; 668 if (remove_entry->dpm_entry_num == MPS_DPM_BAD_IDX) 669 remove_entry->dev_handle = handle; 670 } else if ((ioc_pg8_flags & 671 MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 672 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) 673 remove_entry->dev_handle = handle; 674 break; 675 } 676 677 } 678 679 /** 680 * _mapping_update_missing_count - Update missing count for a device 681 * @sc: per adapter object 682 * @topo_change: Topology change event entry 683 * 684 * Search through the topology change list and if any device is found not 685 * responding it's associated map table entry and DPM entry is updated 686 * 687 * Returns nothing. 688 */ 689 static void 690 _mapping_update_missing_count(struct mps_softc *sc, 691 struct _map_topology_change *topo_change) 692 { 693 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 694 u8 entry; 695 struct _map_phy_change *phy_change; 696 u32 map_idx; 697 struct dev_mapping_table *mt_entry; 698 Mpi2DriverMap0Entry_t *dpm_entry; 699 700 for (entry = 0; entry < topo_change->num_entries; entry++) { 701 phy_change = &topo_change->phy_details[entry]; 702 if (!phy_change->dev_handle || (phy_change->reason != 703 MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)) 704 continue; 705 map_idx = _mapping_get_mt_idx_from_handle(sc, phy_change-> 706 dev_handle); 707 phy_change->is_processed = 1; 708 if (map_idx == MPS_MAPTABLE_BAD_IDX) { 709 printf("%s: device is already removed from mapping " 710 "table\n", __func__); 711 continue; 712 } 713 mt_entry = &sc->mapping_table[map_idx]; 714 if (!mt_entry->init_complete) { 715 if (mt_entry->missing_count < MPS_MAX_MISSING_COUNT) 716 mt_entry->missing_count++; 717 else 718 mt_entry->init_complete = 1; 719 } 720 if (!mt_entry->missing_count) 721 mt_entry->missing_count++; 722 _mapping_add_to_removal_table(sc, mt_entry->dev_handle, 0); 723 mt_entry->dev_handle = 0; 724 725 if (((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 726 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) && 727 sc->is_dpm_enable && !mt_entry->init_complete && 728 mt_entry->dpm_entry_num != MPS_DPM_BAD_IDX) { 729 dpm_entry = 730 (Mpi2DriverMap0Entry_t *) ((u8 *)sc->dpm_pg0 + 731 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 732 dpm_entry += mt_entry->dpm_entry_num; 733 dpm_entry->MappingInformation = mt_entry->missing_count; 734 sc->dpm_flush_entry[mt_entry->dpm_entry_num] = 1; 735 } 736 mt_entry->init_complete = 1; 737 } 738 } 739 740 /** 741 * _mapping_find_enc_map_space -find map table entries for enclosure 742 * @sc: per adapter object 743 * @et_entry: enclosure entry 744 * 745 * Search through the mapping table defragment it and provide contiguous 746 * space in map table for a particular enclosure entry 747 * 748 * Returns start index in map table or bad index. 749 */ 750 static u32 751 _mapping_find_enc_map_space(struct mps_softc *sc, 752 struct enc_mapping_table *et_entry) 753 { 754 u16 vol_mapping_flags; 755 u32 skip_count, end_of_table, map_idx, enc_idx; 756 u16 num_found; 757 u32 start_idx = MPS_MAPTABLE_BAD_IDX; 758 struct dev_mapping_table *mt_entry; 759 struct enc_mapping_table *enc_entry; 760 unsigned char done_flag = 0, found_space; 761 u16 max_num_phy_ids = le16toh(sc->ioc_pg8.MaxNumPhysicalMappedIDs); 762 763 skip_count = sc->num_rsvd_entries; 764 num_found = 0; 765 766 vol_mapping_flags = le16toh(sc->ioc_pg8.IRVolumeMappingFlags) & 767 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE; 768 769 if (!sc->ir_firmware) 770 end_of_table = sc->max_devices; 771 else if (vol_mapping_flags == MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING) 772 end_of_table = sc->max_devices; 773 else 774 end_of_table = sc->max_devices - sc->max_volumes; 775 776 for (map_idx = (max_num_phy_ids + skip_count); 777 map_idx < end_of_table; map_idx++) { 778 mt_entry = &sc->mapping_table[map_idx]; 779 if ((et_entry->enclosure_id == mt_entry->physical_id) && 780 (!mt_entry->phy_bits || (mt_entry->phy_bits & 781 et_entry->phy_bits))) { 782 num_found += 1; 783 if (num_found == et_entry->num_slots) { 784 start_idx = (map_idx - num_found) + 1; 785 return start_idx; 786 } 787 } else 788 num_found = 0; 789 } 790 for (map_idx = (max_num_phy_ids + skip_count); 791 map_idx < end_of_table; map_idx++) { 792 mt_entry = &sc->mapping_table[map_idx]; 793 if (!(mt_entry->device_info & MPS_DEV_RESERVED)) { 794 num_found += 1; 795 if (num_found == et_entry->num_slots) { 796 start_idx = (map_idx - num_found) + 1; 797 return start_idx; 798 } 799 } else 800 num_found = 0; 801 } 802 803 while (!done_flag) { 804 enc_idx = _mapping_get_high_missing_et_idx(sc); 805 if (enc_idx == MPS_ENCTABLE_BAD_IDX) 806 return MPS_MAPTABLE_BAD_IDX; 807 enc_entry = &sc->enclosure_table[enc_idx]; 808 /*VSP FIXME*/ 809 enc_entry->skip_search = 1; 810 mt_entry = &sc->mapping_table[enc_entry->start_index]; 811 for (map_idx = enc_entry->start_index; map_idx < 812 (enc_entry->start_index + enc_entry->num_slots); map_idx++, 813 mt_entry++) 814 mt_entry->device_info &= ~MPS_DEV_RESERVED; 815 found_space = 0; 816 for (map_idx = (max_num_phy_ids + 817 skip_count); map_idx < end_of_table; map_idx++) { 818 mt_entry = &sc->mapping_table[map_idx]; 819 if (!(mt_entry->device_info & MPS_DEV_RESERVED)) { 820 num_found += 1; 821 if (num_found == et_entry->num_slots) { 822 start_idx = (map_idx - num_found) + 1; 823 found_space = 1; 824 } 825 } else 826 num_found = 0; 827 } 828 829 if (!found_space) 830 continue; 831 for (map_idx = start_idx; map_idx < (start_idx + num_found); 832 map_idx++) { 833 enc_entry = sc->enclosure_table; 834 for (enc_idx = 0; enc_idx < sc->num_enc_table_entries; 835 enc_idx++, enc_entry++) { 836 if (map_idx < enc_entry->start_index || 837 map_idx > (enc_entry->start_index + 838 enc_entry->num_slots)) 839 continue; 840 if (!enc_entry->removal_flag) { 841 enc_entry->removal_flag = 1; 842 _mapping_add_to_removal_table(sc, 0, 843 enc_entry->dpm_entry_num); 844 } 845 mt_entry = &sc->mapping_table[map_idx]; 846 if (mt_entry->device_info & 847 MPS_MAP_IN_USE) { 848 _mapping_add_to_removal_table(sc, 849 mt_entry->dev_handle, 0); 850 _mapping_clear_map_entry(mt_entry); 851 } 852 if (map_idx == (enc_entry->start_index + 853 enc_entry->num_slots - 1)) 854 _mapping_clear_enc_entry(et_entry); 855 } 856 } 857 enc_entry = sc->enclosure_table; 858 for (enc_idx = 0; enc_idx < sc->num_enc_table_entries; 859 enc_idx++, enc_entry++) { 860 if (!enc_entry->removal_flag) { 861 mt_entry = &sc->mapping_table[enc_entry-> 862 start_index]; 863 for (map_idx = enc_entry->start_index; map_idx < 864 (enc_entry->start_index + 865 enc_entry->num_slots); map_idx++, 866 mt_entry++) 867 mt_entry->device_info |= 868 MPS_DEV_RESERVED; 869 et_entry->skip_search = 0; 870 } 871 } 872 done_flag = 1; 873 } 874 return start_idx; 875 } 876 877 /** 878 * _mapping_get_dev_info -get information about newly added devices 879 * @sc: per adapter object 880 * @topo_change: Topology change event entry 881 * 882 * Search through the topology change event list and issues sas device pg0 883 * requests for the newly added device and reserved entries in tables 884 * 885 * Returns nothing 886 */ 887 static void 888 _mapping_get_dev_info(struct mps_softc *sc, 889 struct _map_topology_change *topo_change) 890 { 891 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 892 Mpi2ConfigReply_t mpi_reply; 893 Mpi2SasDevicePage0_t sas_device_pg0; 894 u8 entry, enc_idx, phy_idx; 895 u32 map_idx, index, device_info; 896 struct _map_phy_change *phy_change, *tmp_phy_change; 897 uint64_t sas_address; 898 struct enc_mapping_table *et_entry; 899 struct dev_mapping_table *mt_entry; 900 u8 add_code = MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED; 901 int rc = 1; 902 903 for (entry = 0; entry < topo_change->num_entries; entry++) { 904 phy_change = &topo_change->phy_details[entry]; 905 if (phy_change->is_processed || !phy_change->dev_handle || 906 phy_change->reason != MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED) 907 continue; 908 if (mps_config_get_sas_device_pg0(sc, &mpi_reply, 909 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, 910 phy_change->dev_handle)) { 911 phy_change->is_processed = 1; 912 continue; 913 } 914 915 /* 916 * Always get SATA Identify information because this is used 917 * to determine if Start/Stop Unit should be sent to the drive 918 * when the system is shutdown. 919 */ 920 device_info = le32toh(sas_device_pg0.DeviceInfo); 921 sas_address = sas_device_pg0.SASAddress.High; 922 sas_address = (sas_address << 32) | 923 sas_device_pg0.SASAddress.Low; 924 if ((device_info & MPI2_SAS_DEVICE_INFO_END_DEVICE) && 925 (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)) { 926 rc = mpssas_get_sas_address_for_sata_disk(sc, 927 &sas_address, phy_change->dev_handle, device_info, 928 &phy_change->is_SATA_SSD); 929 if (rc) { 930 mps_dprint(sc, MPS_ERROR, "%s: failed to get " 931 "disk type (SSD or HDD) and SAS Address " 932 "for SATA device with handle 0x%04x\n", 933 __func__, phy_change->dev_handle); 934 } else { 935 mps_dprint(sc, MPS_INFO, "SAS Address for SATA " 936 "device = %jx\n", sas_address); 937 } 938 } 939 940 phy_change->physical_id = sas_address; 941 phy_change->slot = le16toh(sas_device_pg0.Slot); 942 phy_change->device_info = le32toh(sas_device_pg0.DeviceInfo); 943 944 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 945 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 946 enc_idx = _mapping_get_enc_idx_from_handle(sc, 947 topo_change->enc_handle); 948 if (enc_idx == MPS_ENCTABLE_BAD_IDX) { 949 phy_change->is_processed = 1; 950 mps_dprint(sc, MPS_MAPPING, "%s: failed to add " 951 "the device with handle 0x%04x because the " 952 "enclosure is not in the mapping table\n", 953 __func__, phy_change->dev_handle); 954 continue; 955 } 956 if (!((phy_change->device_info & 957 MPI2_SAS_DEVICE_INFO_END_DEVICE) && 958 (phy_change->device_info & 959 (MPI2_SAS_DEVICE_INFO_SSP_TARGET | 960 MPI2_SAS_DEVICE_INFO_STP_TARGET | 961 MPI2_SAS_DEVICE_INFO_SATA_DEVICE)))) { 962 phy_change->is_processed = 1; 963 continue; 964 } 965 et_entry = &sc->enclosure_table[enc_idx]; 966 if (et_entry->start_index != MPS_MAPTABLE_BAD_IDX) 967 continue; 968 if (!topo_change->exp_handle) { 969 map_idx = sc->num_rsvd_entries; 970 et_entry->start_index = map_idx; 971 } else { 972 map_idx = _mapping_find_enc_map_space(sc, 973 et_entry); 974 et_entry->start_index = map_idx; 975 if (et_entry->start_index == 976 MPS_MAPTABLE_BAD_IDX) { 977 phy_change->is_processed = 1; 978 for (phy_idx = 0; phy_idx < 979 topo_change->num_entries; 980 phy_idx++) { 981 tmp_phy_change = 982 &topo_change->phy_details 983 [phy_idx]; 984 if (tmp_phy_change->reason == 985 add_code) 986 tmp_phy_change-> 987 is_processed = 1; 988 } 989 break; 990 } 991 } 992 mt_entry = &sc->mapping_table[map_idx]; 993 for (index = map_idx; index < (et_entry->num_slots 994 + map_idx); index++, mt_entry++) { 995 mt_entry->device_info = MPS_DEV_RESERVED; 996 mt_entry->physical_id = et_entry->enclosure_id; 997 mt_entry->phy_bits = et_entry->phy_bits; 998 } 999 } 1000 } 1001 } 1002 1003 /** 1004 * _mapping_set_mid_to_eid -set map table data from enclosure table 1005 * @sc: per adapter object 1006 * @et_entry: enclosure entry 1007 * 1008 * Returns nothing 1009 */ 1010 static inline void 1011 _mapping_set_mid_to_eid(struct mps_softc *sc, 1012 struct enc_mapping_table *et_entry) 1013 { 1014 struct dev_mapping_table *mt_entry; 1015 u16 slots = et_entry->num_slots, map_idx; 1016 u32 start_idx = et_entry->start_index; 1017 if (start_idx != MPS_MAPTABLE_BAD_IDX) { 1018 mt_entry = &sc->mapping_table[start_idx]; 1019 for (map_idx = 0; map_idx < slots; map_idx++, mt_entry++) 1020 mt_entry->physical_id = et_entry->enclosure_id; 1021 } 1022 } 1023 1024 /** 1025 * _mapping_clear_removed_entries - mark the entries to be cleared 1026 * @sc: per adapter object 1027 * 1028 * Search through the removal table and mark the entries which needs to be 1029 * flushed to DPM and also updates the map table and enclosure table by 1030 * clearing the corresponding entries. 1031 * 1032 * Returns nothing 1033 */ 1034 static void 1035 _mapping_clear_removed_entries(struct mps_softc *sc) 1036 { 1037 u32 remove_idx; 1038 struct map_removal_table *remove_entry; 1039 Mpi2DriverMap0Entry_t *dpm_entry; 1040 u8 done_flag = 0, num_entries, m, i; 1041 struct enc_mapping_table *et_entry, *from, *to; 1042 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 1043 1044 if (sc->is_dpm_enable) { 1045 remove_entry = sc->removal_table; 1046 for (remove_idx = 0; remove_idx < sc->max_devices; 1047 remove_idx++, remove_entry++) { 1048 if (remove_entry->dpm_entry_num != MPS_DPM_BAD_IDX) { 1049 dpm_entry = (Mpi2DriverMap0Entry_t *) 1050 ((u8 *) sc->dpm_pg0 + 1051 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 1052 dpm_entry += remove_entry->dpm_entry_num; 1053 dpm_entry->PhysicalIdentifier.Low = 0; 1054 dpm_entry->PhysicalIdentifier.High = 0; 1055 dpm_entry->DeviceIndex = 0; 1056 dpm_entry->MappingInformation = 0; 1057 dpm_entry->PhysicalBitsMapping = 0; 1058 sc->dpm_flush_entry[remove_entry-> 1059 dpm_entry_num] = 1; 1060 sc->dpm_entry_used[remove_entry->dpm_entry_num] 1061 = 0; 1062 remove_entry->dpm_entry_num = MPS_DPM_BAD_IDX; 1063 } 1064 } 1065 } 1066 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1067 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 1068 num_entries = sc->num_enc_table_entries; 1069 while (!done_flag) { 1070 done_flag = 1; 1071 et_entry = sc->enclosure_table; 1072 for (i = 0; i < num_entries; i++, et_entry++) { 1073 if (!et_entry->enc_handle && et_entry-> 1074 init_complete) { 1075 done_flag = 0; 1076 if (i != (num_entries - 1)) { 1077 from = &sc->enclosure_table 1078 [i+1]; 1079 to = &sc->enclosure_table[i]; 1080 for (m = i; m < (num_entries - 1081 1); m++, from++, to++) { 1082 _mapping_set_mid_to_eid 1083 (sc, to); 1084 *to = *from; 1085 } 1086 _mapping_clear_enc_entry(to); 1087 sc->num_enc_table_entries--; 1088 num_entries = 1089 sc->num_enc_table_entries; 1090 } else { 1091 _mapping_clear_enc_entry 1092 (et_entry); 1093 sc->num_enc_table_entries--; 1094 num_entries = 1095 sc->num_enc_table_entries; 1096 } 1097 } 1098 } 1099 } 1100 } 1101 } 1102 1103 /** 1104 * _mapping_add_new_device -Add the new device into mapping table 1105 * @sc: per adapter object 1106 * @topo_change: Topology change event entry 1107 * 1108 * Search through the topology change event list and updates map table, 1109 * enclosure table and DPM pages for for the newly added devices. 1110 * 1111 * Returns nothing 1112 */ 1113 static void 1114 _mapping_add_new_device(struct mps_softc *sc, 1115 struct _map_topology_change *topo_change) 1116 { 1117 u8 enc_idx, missing_cnt, is_removed = 0; 1118 u16 dpm_idx; 1119 u32 search_idx, map_idx; 1120 u32 entry; 1121 struct dev_mapping_table *mt_entry; 1122 struct enc_mapping_table *et_entry; 1123 struct _map_phy_change *phy_change; 1124 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 1125 Mpi2DriverMap0Entry_t *dpm_entry; 1126 uint64_t temp64_var; 1127 u8 map_shift = MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT; 1128 u8 hdr_sz = sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER); 1129 u16 max_num_phy_ids = le16toh(sc->ioc_pg8.MaxNumPhysicalMappedIDs); 1130 1131 for (entry = 0; entry < topo_change->num_entries; entry++) { 1132 phy_change = &topo_change->phy_details[entry]; 1133 if (phy_change->is_processed) 1134 continue; 1135 if (phy_change->reason != MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED || 1136 !phy_change->dev_handle) { 1137 phy_change->is_processed = 1; 1138 continue; 1139 } 1140 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1141 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 1142 enc_idx = _mapping_get_enc_idx_from_handle 1143 (sc, topo_change->enc_handle); 1144 if (enc_idx == MPS_ENCTABLE_BAD_IDX) { 1145 phy_change->is_processed = 1; 1146 printf("%s: failed to add the device with " 1147 "handle 0x%04x because the enclosure is " 1148 "not in the mapping table\n", __func__, 1149 phy_change->dev_handle); 1150 continue; 1151 } 1152 et_entry = &sc->enclosure_table[enc_idx]; 1153 if (et_entry->start_index == MPS_MAPTABLE_BAD_IDX) { 1154 phy_change->is_processed = 1; 1155 if (!sc->mt_full_retry) { 1156 sc->mt_add_device_failed = 1; 1157 continue; 1158 } 1159 printf("%s: failed to add the device with " 1160 "handle 0x%04x because there is no free " 1161 "space available in the mapping table\n", 1162 __func__, phy_change->dev_handle); 1163 continue; 1164 } 1165 map_idx = et_entry->start_index + phy_change->slot - 1166 et_entry->start_slot; 1167 mt_entry = &sc->mapping_table[map_idx]; 1168 mt_entry->physical_id = phy_change->physical_id; 1169 mt_entry->channel = 0; 1170 mt_entry->id = map_idx; 1171 mt_entry->dev_handle = phy_change->dev_handle; 1172 mt_entry->missing_count = 0; 1173 mt_entry->dpm_entry_num = et_entry->dpm_entry_num; 1174 mt_entry->device_info = phy_change->device_info | 1175 (MPS_DEV_RESERVED | MPS_MAP_IN_USE); 1176 if (sc->is_dpm_enable) { 1177 dpm_idx = et_entry->dpm_entry_num; 1178 if (dpm_idx == MPS_DPM_BAD_IDX) 1179 dpm_idx = _mapping_get_dpm_idx_from_id 1180 (sc, et_entry->enclosure_id, 1181 et_entry->phy_bits); 1182 if (dpm_idx == MPS_DPM_BAD_IDX) { 1183 dpm_idx = _mapping_get_free_dpm_idx(sc); 1184 if (dpm_idx != MPS_DPM_BAD_IDX) { 1185 dpm_entry = 1186 (Mpi2DriverMap0Entry_t *) 1187 ((u8 *) sc->dpm_pg0 + 1188 hdr_sz); 1189 dpm_entry += dpm_idx; 1190 dpm_entry-> 1191 PhysicalIdentifier.Low = 1192 (0xFFFFFFFF & 1193 et_entry->enclosure_id); 1194 dpm_entry-> 1195 PhysicalIdentifier.High = 1196 ( et_entry->enclosure_id 1197 >> 32); 1198 dpm_entry->DeviceIndex = 1199 (U16)et_entry->start_index; 1200 dpm_entry->MappingInformation = 1201 et_entry->num_slots; 1202 dpm_entry->MappingInformation 1203 <<= map_shift; 1204 dpm_entry->PhysicalBitsMapping 1205 = et_entry->phy_bits; 1206 et_entry->dpm_entry_num = 1207 dpm_idx; 1208 /* FIXME Do I need to set the dpm_idxin mt_entry too */ 1209 sc->dpm_entry_used[dpm_idx] = 1; 1210 sc->dpm_flush_entry[dpm_idx] = 1211 1; 1212 phy_change->is_processed = 1; 1213 } else { 1214 phy_change->is_processed = 1; 1215 mps_dprint(sc, MPS_INFO, "%s: " 1216 "failed to add the device " 1217 "with handle 0x%04x to " 1218 "persistent table because " 1219 "there is no free space " 1220 "available\n", __func__, 1221 phy_change->dev_handle); 1222 } 1223 } else { 1224 et_entry->dpm_entry_num = dpm_idx; 1225 mt_entry->dpm_entry_num = dpm_idx; 1226 } 1227 } 1228 /* FIXME Why not mt_entry too? */ 1229 et_entry->init_complete = 1; 1230 } else if ((ioc_pg8_flags & 1231 MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1232 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) { 1233 map_idx = _mapping_get_mt_idx_from_id 1234 (sc, phy_change->physical_id); 1235 if (map_idx == MPS_MAPTABLE_BAD_IDX) { 1236 search_idx = sc->num_rsvd_entries; 1237 if (topo_change->exp_handle) 1238 search_idx += max_num_phy_ids; 1239 map_idx = _mapping_get_free_mt_idx(sc, 1240 search_idx); 1241 } 1242 if (map_idx == MPS_MAPTABLE_BAD_IDX) { 1243 map_idx = _mapping_get_high_missing_mt_idx(sc); 1244 if (map_idx != MPS_MAPTABLE_BAD_IDX) { 1245 mt_entry = &sc->mapping_table[map_idx]; 1246 if (mt_entry->dev_handle) { 1247 _mapping_add_to_removal_table 1248 (sc, mt_entry->dev_handle, 1249 0); 1250 is_removed = 1; 1251 } 1252 mt_entry->init_complete = 0; 1253 } 1254 } 1255 if (map_idx != MPS_MAPTABLE_BAD_IDX) { 1256 mt_entry = &sc->mapping_table[map_idx]; 1257 mt_entry->physical_id = phy_change->physical_id; 1258 mt_entry->channel = 0; 1259 mt_entry->id = map_idx; 1260 mt_entry->dev_handle = phy_change->dev_handle; 1261 mt_entry->missing_count = 0; 1262 mt_entry->device_info = phy_change->device_info 1263 | (MPS_DEV_RESERVED | MPS_MAP_IN_USE); 1264 } else { 1265 phy_change->is_processed = 1; 1266 if (!sc->mt_full_retry) { 1267 sc->mt_add_device_failed = 1; 1268 continue; 1269 } 1270 printf("%s: failed to add the device with " 1271 "handle 0x%04x because there is no free " 1272 "space available in the mapping table\n", 1273 __func__, phy_change->dev_handle); 1274 continue; 1275 } 1276 if (sc->is_dpm_enable) { 1277 if (mt_entry->dpm_entry_num != 1278 MPS_DPM_BAD_IDX) { 1279 dpm_idx = mt_entry->dpm_entry_num; 1280 dpm_entry = (Mpi2DriverMap0Entry_t *) 1281 ((u8 *)sc->dpm_pg0 + hdr_sz); 1282 dpm_entry += dpm_idx; 1283 missing_cnt = dpm_entry-> 1284 MappingInformation & 1285 MPI2_DRVMAP0_MAPINFO_MISSING_MASK; 1286 temp64_var = dpm_entry-> 1287 PhysicalIdentifier.High; 1288 temp64_var = (temp64_var << 32) | 1289 dpm_entry->PhysicalIdentifier.Low; 1290 if ((mt_entry->physical_id == 1291 temp64_var) && !missing_cnt) 1292 mt_entry->init_complete = 1; 1293 } else { 1294 dpm_idx = _mapping_get_free_dpm_idx(sc); 1295 mt_entry->init_complete = 0; 1296 } 1297 if (dpm_idx != MPS_DPM_BAD_IDX && 1298 !mt_entry->init_complete) { 1299 mt_entry->init_complete = 1; 1300 mt_entry->dpm_entry_num = dpm_idx; 1301 dpm_entry = (Mpi2DriverMap0Entry_t *) 1302 ((u8 *)sc->dpm_pg0 + hdr_sz); 1303 dpm_entry += dpm_idx; 1304 dpm_entry->PhysicalIdentifier.Low = 1305 (0xFFFFFFFF & 1306 mt_entry->physical_id); 1307 dpm_entry->PhysicalIdentifier.High = 1308 (mt_entry->physical_id >> 32); 1309 dpm_entry->DeviceIndex = (U16) map_idx; 1310 dpm_entry->MappingInformation = 0; 1311 dpm_entry->PhysicalBitsMapping = 0; 1312 sc->dpm_entry_used[dpm_idx] = 1; 1313 sc->dpm_flush_entry[dpm_idx] = 1; 1314 phy_change->is_processed = 1; 1315 } else if (dpm_idx == MPS_DPM_BAD_IDX) { 1316 phy_change->is_processed = 1; 1317 mps_dprint(sc, MPS_INFO, "%s: " 1318 "failed to add the device " 1319 "with handle 0x%04x to " 1320 "persistent table because " 1321 "there is no free space " 1322 "available\n", __func__, 1323 phy_change->dev_handle); 1324 } 1325 } 1326 mt_entry->init_complete = 1; 1327 } 1328 1329 phy_change->is_processed = 1; 1330 } 1331 if (is_removed) 1332 _mapping_clear_removed_entries(sc); 1333 } 1334 1335 /** 1336 * _mapping_flush_dpm_pages -Flush the DPM pages to NVRAM 1337 * @sc: per adapter object 1338 * 1339 * Returns nothing 1340 */ 1341 static void 1342 _mapping_flush_dpm_pages(struct mps_softc *sc) 1343 { 1344 Mpi2DriverMap0Entry_t *dpm_entry; 1345 Mpi2ConfigReply_t mpi_reply; 1346 Mpi2DriverMappingPage0_t config_page; 1347 u16 entry_num; 1348 1349 for (entry_num = 0; entry_num < sc->max_dpm_entries; entry_num++) { 1350 if (!sc->dpm_flush_entry[entry_num]) 1351 continue; 1352 memset(&config_page, 0, sizeof(Mpi2DriverMappingPage0_t)); 1353 memcpy(&config_page.Header, (u8 *)sc->dpm_pg0, 1354 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 1355 dpm_entry = (Mpi2DriverMap0Entry_t *) ((u8 *)sc->dpm_pg0 + 1356 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 1357 dpm_entry += entry_num; 1358 dpm_entry->MappingInformation = htole16(dpm_entry-> 1359 MappingInformation); 1360 dpm_entry->DeviceIndex = htole16(dpm_entry->DeviceIndex); 1361 dpm_entry->PhysicalBitsMapping = htole32(dpm_entry-> 1362 PhysicalBitsMapping); 1363 memcpy(&config_page.Entry, (u8 *)dpm_entry, 1364 sizeof(Mpi2DriverMap0Entry_t)); 1365 /* TODO-How to handle failed writes? */ 1366 if (mps_config_set_dpm_pg0(sc, &mpi_reply, &config_page, 1367 entry_num)) { 1368 printf("%s: write of dpm entry %d for device failed\n", 1369 __func__, entry_num); 1370 } else 1371 sc->dpm_flush_entry[entry_num] = 0; 1372 dpm_entry->MappingInformation = le16toh(dpm_entry-> 1373 MappingInformation); 1374 dpm_entry->DeviceIndex = le16toh(dpm_entry->DeviceIndex); 1375 dpm_entry->PhysicalBitsMapping = le32toh(dpm_entry-> 1376 PhysicalBitsMapping); 1377 } 1378 } 1379 1380 /** 1381 * _mapping_allocate_memory- allocates the memory required for mapping tables 1382 * @sc: per adapter object 1383 * 1384 * Allocates the memory for all the tables required for host mapping 1385 * 1386 * Return 0 on success or non-zero on failure. 1387 */ 1388 int 1389 mps_mapping_allocate_memory(struct mps_softc *sc) 1390 { 1391 uint32_t dpm_pg0_sz; 1392 1393 sc->mapping_table = malloc((sizeof(struct dev_mapping_table) * 1394 sc->max_devices), M_MPT2, M_ZERO|M_NOWAIT); 1395 if (!sc->mapping_table) 1396 goto free_resources; 1397 1398 sc->removal_table = malloc((sizeof(struct map_removal_table) * 1399 sc->max_devices), M_MPT2, M_ZERO|M_NOWAIT); 1400 if (!sc->removal_table) 1401 goto free_resources; 1402 1403 sc->enclosure_table = malloc((sizeof(struct enc_mapping_table) * 1404 sc->max_enclosures), M_MPT2, M_ZERO|M_NOWAIT); 1405 if (!sc->enclosure_table) 1406 goto free_resources; 1407 1408 sc->dpm_entry_used = malloc((sizeof(u8) * sc->max_dpm_entries), 1409 M_MPT2, M_ZERO|M_NOWAIT); 1410 if (!sc->dpm_entry_used) 1411 goto free_resources; 1412 1413 sc->dpm_flush_entry = malloc((sizeof(u8) * sc->max_dpm_entries), 1414 M_MPT2, M_ZERO|M_NOWAIT); 1415 if (!sc->dpm_flush_entry) 1416 goto free_resources; 1417 1418 dpm_pg0_sz = sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER) + 1419 (sc->max_dpm_entries * sizeof(MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY)); 1420 1421 sc->dpm_pg0 = malloc(dpm_pg0_sz, M_MPT2, M_ZERO|M_NOWAIT); 1422 if (!sc->dpm_pg0) { 1423 printf("%s: memory alloc failed for dpm page; disabling dpm\n", 1424 __func__); 1425 sc->is_dpm_enable = 0; 1426 } 1427 1428 return 0; 1429 1430 free_resources: 1431 free(sc->mapping_table, M_MPT2); 1432 free(sc->removal_table, M_MPT2); 1433 free(sc->enclosure_table, M_MPT2); 1434 free(sc->dpm_entry_used, M_MPT2); 1435 free(sc->dpm_flush_entry, M_MPT2); 1436 free(sc->dpm_pg0, M_MPT2); 1437 printf("%s: device initialization failed due to failure in mapping " 1438 "table memory allocation\n", __func__); 1439 return -1; 1440 } 1441 1442 /** 1443 * mps_mapping_free_memory- frees the memory allocated for mapping tables 1444 * @sc: per adapter object 1445 * 1446 * Returns nothing. 1447 */ 1448 void 1449 mps_mapping_free_memory(struct mps_softc *sc) 1450 { 1451 free(sc->mapping_table, M_MPT2); 1452 free(sc->removal_table, M_MPT2); 1453 free(sc->enclosure_table, M_MPT2); 1454 free(sc->dpm_entry_used, M_MPT2); 1455 free(sc->dpm_flush_entry, M_MPT2); 1456 free(sc->dpm_pg0, M_MPT2); 1457 } 1458 1459 1460 static void 1461 _mapping_process_dpm_pg0(struct mps_softc *sc) 1462 { 1463 u8 missing_cnt, enc_idx; 1464 u16 slot_id, entry_num, num_slots; 1465 u32 map_idx, dev_idx, start_idx, end_idx; 1466 struct dev_mapping_table *mt_entry; 1467 Mpi2DriverMap0Entry_t *dpm_entry; 1468 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 1469 u16 max_num_phy_ids = le16toh(sc->ioc_pg8.MaxNumPhysicalMappedIDs); 1470 struct enc_mapping_table *et_entry; 1471 u64 physical_id; 1472 u32 phy_bits = 0; 1473 1474 if (sc->ir_firmware) 1475 _mapping_get_ir_maprange(sc, &start_idx, &end_idx); 1476 1477 dpm_entry = (Mpi2DriverMap0Entry_t *) ((uint8_t *) sc->dpm_pg0 + 1478 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 1479 for (entry_num = 0; entry_num < sc->max_dpm_entries; entry_num++, 1480 dpm_entry++) { 1481 physical_id = dpm_entry->PhysicalIdentifier.High; 1482 physical_id = (physical_id << 32) | 1483 dpm_entry->PhysicalIdentifier.Low; 1484 if (!physical_id) { 1485 sc->dpm_entry_used[entry_num] = 0; 1486 continue; 1487 } 1488 sc->dpm_entry_used[entry_num] = 1; 1489 dpm_entry->MappingInformation = le16toh(dpm_entry-> 1490 MappingInformation); 1491 missing_cnt = dpm_entry->MappingInformation & 1492 MPI2_DRVMAP0_MAPINFO_MISSING_MASK; 1493 dev_idx = le16toh(dpm_entry->DeviceIndex); 1494 phy_bits = le32toh(dpm_entry->PhysicalBitsMapping); 1495 if (sc->ir_firmware && (dev_idx >= start_idx) && 1496 (dev_idx <= end_idx)) { 1497 mt_entry = &sc->mapping_table[dev_idx]; 1498 mt_entry->physical_id = dpm_entry->PhysicalIdentifier.High; 1499 mt_entry->physical_id = (mt_entry->physical_id << 32) | 1500 dpm_entry->PhysicalIdentifier.Low; 1501 mt_entry->channel = MPS_RAID_CHANNEL; 1502 mt_entry->id = dev_idx; 1503 mt_entry->missing_count = missing_cnt; 1504 mt_entry->dpm_entry_num = entry_num; 1505 mt_entry->device_info = MPS_DEV_RESERVED; 1506 continue; 1507 } 1508 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1509 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 1510 if (dev_idx < (sc->num_rsvd_entries + 1511 max_num_phy_ids)) { 1512 slot_id = 0; 1513 if (ioc_pg8_flags & 1514 MPI2_IOCPAGE8_FLAGS_DA_START_SLOT_1) 1515 slot_id = 1; 1516 num_slots = max_num_phy_ids; 1517 } else { 1518 slot_id = 0; 1519 num_slots = dpm_entry->MappingInformation & 1520 MPI2_DRVMAP0_MAPINFO_SLOT_MASK; 1521 num_slots >>= MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT; 1522 } 1523 enc_idx = sc->num_enc_table_entries; 1524 if (enc_idx >= sc->max_enclosures) { 1525 printf("%s: enclosure entries exceed max " 1526 "enclosures of %d\n", __func__, 1527 sc->max_enclosures); 1528 break; 1529 } 1530 sc->num_enc_table_entries++; 1531 et_entry = &sc->enclosure_table[enc_idx]; 1532 physical_id = dpm_entry->PhysicalIdentifier.High; 1533 et_entry->enclosure_id = (physical_id << 32) | 1534 dpm_entry->PhysicalIdentifier.Low; 1535 et_entry->start_index = dev_idx; 1536 et_entry->dpm_entry_num = entry_num; 1537 et_entry->num_slots = num_slots; 1538 et_entry->start_slot = slot_id; 1539 et_entry->missing_count = missing_cnt; 1540 et_entry->phy_bits = phy_bits; 1541 1542 mt_entry = &sc->mapping_table[dev_idx]; 1543 for (map_idx = dev_idx; map_idx < (dev_idx + num_slots); 1544 map_idx++, mt_entry++) { 1545 if (mt_entry->dpm_entry_num != 1546 MPS_DPM_BAD_IDX) { 1547 printf("%s: conflict in mapping table " 1548 "for enclosure %d\n", __func__, 1549 enc_idx); 1550 break; 1551 } 1552 physical_id = dpm_entry->PhysicalIdentifier.High; 1553 mt_entry->physical_id = (physical_id << 32) | 1554 dpm_entry->PhysicalIdentifier.Low; 1555 mt_entry->phy_bits = phy_bits; 1556 mt_entry->channel = 0; 1557 mt_entry->id = dev_idx; 1558 mt_entry->dpm_entry_num = entry_num; 1559 mt_entry->missing_count = missing_cnt; 1560 mt_entry->device_info = MPS_DEV_RESERVED; 1561 } 1562 } else if ((ioc_pg8_flags & 1563 MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1564 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) { 1565 map_idx = dev_idx; 1566 mt_entry = &sc->mapping_table[map_idx]; 1567 if (mt_entry->dpm_entry_num != MPS_DPM_BAD_IDX) { 1568 printf("%s: conflict in mapping table for " 1569 "device %d\n", __func__, map_idx); 1570 break; 1571 } 1572 physical_id = dpm_entry->PhysicalIdentifier.High; 1573 mt_entry->physical_id = (physical_id << 32) | 1574 dpm_entry->PhysicalIdentifier.Low; 1575 mt_entry->phy_bits = phy_bits; 1576 mt_entry->channel = 0; 1577 mt_entry->id = dev_idx; 1578 mt_entry->missing_count = missing_cnt; 1579 mt_entry->dpm_entry_num = entry_num; 1580 mt_entry->device_info = MPS_DEV_RESERVED; 1581 } 1582 } /*close the loop for DPM table */ 1583 } 1584 1585 /* 1586 * mps_mapping_check_devices - start of the day check for device availabilty 1587 * @sc: per adapter object 1588 * @sleep_flag: Flag indicating whether this function can sleep or not 1589 * 1590 * Returns nothing. 1591 */ 1592 void 1593 mps_mapping_check_devices(struct mps_softc *sc, int sleep_flag) 1594 { 1595 u32 i; 1596 /* u32 cntdn, i; 1597 u32 timeout = 60;*/ 1598 struct dev_mapping_table *mt_entry; 1599 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 1600 struct enc_mapping_table *et_entry; 1601 u32 start_idx, end_idx; 1602 1603 /* We need to ucomment this when this function is called 1604 * from the port enable complete */ 1605 #if 0 1606 sc->track_mapping_events = 0; 1607 cntdn = (sleep_flag == CAN_SLEEP) ? 1000*timeout : 2000*timeout; 1608 do { 1609 if (!sc->pending_map_events) 1610 break; 1611 if (sleep_flag == CAN_SLEEP) 1612 pause("mps_pause", (hz/1000));/* 1msec sleep */ 1613 else 1614 DELAY(500); /* 500 useconds delay */ 1615 } while (--cntdn); 1616 1617 1618 if (!cntdn) 1619 printf("%s: there are %d" 1620 " pending events after %d seconds of delay\n", 1621 __func__, sc->pending_map_events, timeout); 1622 #endif 1623 sc->pending_map_events = 0; 1624 1625 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1626 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 1627 et_entry = sc->enclosure_table; 1628 for (i = 0; i < sc->num_enc_table_entries; i++, et_entry++) { 1629 if (!et_entry->init_complete) { 1630 if (et_entry->missing_count < 1631 MPS_MAX_MISSING_COUNT) { 1632 et_entry->missing_count++; 1633 if (et_entry->dpm_entry_num != 1634 MPS_DPM_BAD_IDX) 1635 _mapping_commit_enc_entry(sc, 1636 et_entry); 1637 } 1638 et_entry->init_complete = 1; 1639 } 1640 } 1641 if (!sc->ir_firmware) 1642 return; 1643 _mapping_get_ir_maprange(sc, &start_idx, &end_idx); 1644 mt_entry = &sc->mapping_table[start_idx]; 1645 for (i = start_idx; i < (end_idx + 1); i++, mt_entry++) { 1646 if (mt_entry->device_info & MPS_DEV_RESERVED 1647 && !mt_entry->physical_id) 1648 mt_entry->init_complete = 1; 1649 else if (mt_entry->device_info & MPS_DEV_RESERVED) { 1650 if (!mt_entry->init_complete) { 1651 if (mt_entry->missing_count < 1652 MPS_MAX_MISSING_COUNT) { 1653 mt_entry->missing_count++; 1654 if (mt_entry->dpm_entry_num != 1655 MPS_DPM_BAD_IDX) 1656 _mapping_commit_map_entry(sc, 1657 mt_entry); 1658 } 1659 mt_entry->init_complete = 1; 1660 } 1661 } 1662 } 1663 } else if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1664 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) { 1665 mt_entry = sc->mapping_table; 1666 for (i = 0; i < sc->max_devices; i++, mt_entry++) { 1667 if (mt_entry->device_info & MPS_DEV_RESERVED 1668 && !mt_entry->physical_id) 1669 mt_entry->init_complete = 1; 1670 else if (mt_entry->device_info & MPS_DEV_RESERVED) { 1671 if (!mt_entry->init_complete) { 1672 if (mt_entry->missing_count < 1673 MPS_MAX_MISSING_COUNT) { 1674 mt_entry->missing_count++; 1675 if (mt_entry->dpm_entry_num != 1676 MPS_DPM_BAD_IDX) 1677 _mapping_commit_map_entry(sc, 1678 mt_entry); 1679 } 1680 mt_entry->init_complete = 1; 1681 } 1682 } 1683 } 1684 } 1685 } 1686 1687 1688 /** 1689 * mps_mapping_is_reinit_required - check whether event replay required 1690 * @sc: per adapter object 1691 * 1692 * Checks the per ioc flags and decide whether reinit of events required 1693 * 1694 * Returns 1 for reinit of ioc 0 for not. 1695 */ 1696 int mps_mapping_is_reinit_required(struct mps_softc *sc) 1697 { 1698 if (!sc->mt_full_retry && sc->mt_add_device_failed) { 1699 sc->mt_full_retry = 1; 1700 sc->mt_add_device_failed = 0; 1701 _mapping_flush_dpm_pages(sc); 1702 return 1; 1703 } 1704 sc->mt_full_retry = 1; 1705 return 0; 1706 } 1707 1708 /** 1709 * mps_mapping_initialize - initialize mapping tables 1710 * @sc: per adapter object 1711 * 1712 * Read controller persitant mapping tables into internal data area. 1713 * 1714 * Return 0 for success or non-zero for failure. 1715 */ 1716 int 1717 mps_mapping_initialize(struct mps_softc *sc) 1718 { 1719 uint16_t volume_mapping_flags, dpm_pg0_sz; 1720 uint32_t i; 1721 Mpi2ConfigReply_t mpi_reply; 1722 int error; 1723 uint8_t retry_count; 1724 uint16_t ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 1725 1726 /* The additional 1 accounts for the virtual enclosure 1727 * created for the controller 1728 */ 1729 sc->max_enclosures = sc->facts->MaxEnclosures + 1; 1730 sc->max_expanders = sc->facts->MaxSasExpanders; 1731 sc->max_volumes = sc->facts->MaxVolumes; 1732 sc->max_devices = sc->facts->MaxTargets + sc->max_volumes; 1733 sc->pending_map_events = 0; 1734 sc->num_enc_table_entries = 0; 1735 sc->num_rsvd_entries = 0; 1736 sc->num_channels = 1; 1737 sc->max_dpm_entries = sc->ioc_pg8.MaxPersistentEntries; 1738 sc->is_dpm_enable = (sc->max_dpm_entries) ? 1 : 0; 1739 sc->track_mapping_events = 0; 1740 1741 if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_DISABLE_PERSISTENT_MAPPING) 1742 sc->is_dpm_enable = 0; 1743 1744 if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0) 1745 sc->num_rsvd_entries = 1; 1746 1747 volume_mapping_flags = sc->ioc_pg8.IRVolumeMappingFlags & 1748 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE; 1749 if (sc->ir_firmware && (volume_mapping_flags == 1750 MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING)) 1751 sc->num_rsvd_entries += sc->max_volumes; 1752 1753 error = mps_mapping_allocate_memory(sc); 1754 if (error) 1755 return (error); 1756 1757 for (i = 0; i < sc->max_devices; i++) 1758 _mapping_clear_map_entry(sc->mapping_table + i); 1759 1760 for (i = 0; i < sc->max_enclosures; i++) 1761 _mapping_clear_enc_entry(sc->enclosure_table + i); 1762 1763 for (i = 0; i < sc->max_devices; i++) { 1764 sc->removal_table[i].dev_handle = 0; 1765 sc->removal_table[i].dpm_entry_num = MPS_DPM_BAD_IDX; 1766 } 1767 1768 memset(sc->dpm_entry_used, 0, sc->max_dpm_entries); 1769 memset(sc->dpm_flush_entry, 0, sc->max_dpm_entries); 1770 1771 if (sc->is_dpm_enable) { 1772 dpm_pg0_sz = sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER) + 1773 (sc->max_dpm_entries * 1774 sizeof(MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY)); 1775 retry_count = 0; 1776 1777 retry_read_dpm: 1778 if (mps_config_get_dpm_pg0(sc, &mpi_reply, sc->dpm_pg0, 1779 dpm_pg0_sz)) { 1780 printf("%s: dpm page read failed; disabling dpm\n", 1781 __func__); 1782 if (retry_count < 3) { 1783 retry_count++; 1784 goto retry_read_dpm; 1785 } 1786 sc->is_dpm_enable = 0; 1787 } 1788 } 1789 1790 if (sc->is_dpm_enable) 1791 _mapping_process_dpm_pg0(sc); 1792 1793 sc->track_mapping_events = 1; 1794 return 0; 1795 } 1796 1797 /** 1798 * mps_mapping_exit - clear mapping table and associated memory 1799 * @sc: per adapter object 1800 * 1801 * Returns nothing. 1802 */ 1803 void 1804 mps_mapping_exit(struct mps_softc *sc) 1805 { 1806 _mapping_flush_dpm_pages(sc); 1807 mps_mapping_free_memory(sc); 1808 } 1809 1810 /** 1811 * mps_mapping_get_sas_id - assign a target id for sas device 1812 * @sc: per adapter object 1813 * @sas_address: sas address of the device 1814 * @handle: device handle 1815 * 1816 * Returns valid ID on success or BAD_ID. 1817 */ 1818 unsigned int 1819 mps_mapping_get_sas_id(struct mps_softc *sc, uint64_t sas_address, u16 handle) 1820 { 1821 u32 map_idx; 1822 struct dev_mapping_table *mt_entry; 1823 1824 for (map_idx = 0; map_idx < sc->max_devices; map_idx++) { 1825 mt_entry = &sc->mapping_table[map_idx]; 1826 if (mt_entry->dev_handle == handle && mt_entry->physical_id == 1827 sas_address) 1828 return mt_entry->id; 1829 } 1830 1831 return MPS_MAP_BAD_ID; 1832 } 1833 1834 /** 1835 * mps_mapping_get_sas_id_from_handle - find a target id in mapping table using 1836 * only the dev handle. This is just a wrapper function for the local function 1837 * _mapping_get_mt_idx_from_handle. 1838 * @sc: per adapter object 1839 * @handle: device handle 1840 * 1841 * Returns valid ID on success or BAD_ID. 1842 */ 1843 unsigned int 1844 mps_mapping_get_sas_id_from_handle(struct mps_softc *sc, u16 handle) 1845 { 1846 return (_mapping_get_mt_idx_from_handle(sc, handle)); 1847 } 1848 1849 /** 1850 * mps_mapping_get_raid_id - assign a target id for raid device 1851 * @sc: per adapter object 1852 * @wwid: world wide identifier for raid volume 1853 * @handle: device handle 1854 * 1855 * Returns valid ID on success or BAD_ID. 1856 */ 1857 unsigned int 1858 mps_mapping_get_raid_id(struct mps_softc *sc, u64 wwid, u16 handle) 1859 { 1860 u32 map_idx; 1861 struct dev_mapping_table *mt_entry; 1862 1863 for (map_idx = 0; map_idx < sc->max_devices; map_idx++) { 1864 mt_entry = &sc->mapping_table[map_idx]; 1865 if (mt_entry->dev_handle == handle && mt_entry->physical_id == 1866 wwid) 1867 return mt_entry->id; 1868 } 1869 1870 return MPS_MAP_BAD_ID; 1871 } 1872 1873 /** 1874 * mps_mapping_get_raid_id_from_handle - find raid device in mapping table 1875 * using only the volume dev handle. This is just a wrapper function for the 1876 * local function _mapping_get_ir_mt_idx_from_handle. 1877 * @sc: per adapter object 1878 * @volHandle: volume device handle 1879 * 1880 * Returns valid ID on success or BAD_ID. 1881 */ 1882 unsigned int 1883 mps_mapping_get_raid_id_from_handle(struct mps_softc *sc, u16 volHandle) 1884 { 1885 return (_mapping_get_ir_mt_idx_from_handle(sc, volHandle)); 1886 } 1887 1888 /** 1889 * mps_mapping_enclosure_dev_status_change_event - handle enclosure events 1890 * @sc: per adapter object 1891 * @event_data: event data payload 1892 * 1893 * Return nothing. 1894 */ 1895 void 1896 mps_mapping_enclosure_dev_status_change_event(struct mps_softc *sc, 1897 Mpi2EventDataSasEnclDevStatusChange_t *event_data) 1898 { 1899 u8 enc_idx, missing_count; 1900 struct enc_mapping_table *et_entry; 1901 Mpi2DriverMap0Entry_t *dpm_entry; 1902 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 1903 u8 map_shift = MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT; 1904 u8 update_phy_bits = 0; 1905 u32 saved_phy_bits; 1906 uint64_t temp64_var; 1907 1908 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) != 1909 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) 1910 goto out; 1911 1912 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *)sc->dpm_pg0 + 1913 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 1914 1915 if (event_data->ReasonCode == MPI2_EVENT_SAS_ENCL_RC_ADDED) { 1916 if (!event_data->NumSlots) { 1917 printf("%s: enclosure with handle = 0x%x reported 0 " 1918 "slots\n", __func__, 1919 le16toh(event_data->EnclosureHandle)); 1920 goto out; 1921 } 1922 temp64_var = event_data->EnclosureLogicalID.High; 1923 temp64_var = (temp64_var << 32) | 1924 event_data->EnclosureLogicalID.Low; 1925 enc_idx = _mapping_get_enc_idx_from_id(sc, temp64_var, 1926 event_data->PhyBits); 1927 if (enc_idx != MPS_ENCTABLE_BAD_IDX) { 1928 et_entry = &sc->enclosure_table[enc_idx]; 1929 if (et_entry->init_complete && 1930 !et_entry->missing_count) { 1931 printf("%s: enclosure %d is already present " 1932 "with handle = 0x%x\n",__func__, enc_idx, 1933 et_entry->enc_handle); 1934 goto out; 1935 } 1936 et_entry->enc_handle = le16toh(event_data-> 1937 EnclosureHandle); 1938 et_entry->start_slot = le16toh(event_data->StartSlot); 1939 saved_phy_bits = et_entry->phy_bits; 1940 et_entry->phy_bits |= le32toh(event_data->PhyBits); 1941 if (saved_phy_bits != et_entry->phy_bits) 1942 update_phy_bits = 1; 1943 if (et_entry->missing_count || update_phy_bits) { 1944 et_entry->missing_count = 0; 1945 if (sc->is_dpm_enable && 1946 et_entry->dpm_entry_num != 1947 MPS_DPM_BAD_IDX) { 1948 dpm_entry += et_entry->dpm_entry_num; 1949 missing_count = 1950 (u8)(dpm_entry->MappingInformation & 1951 MPI2_DRVMAP0_MAPINFO_MISSING_MASK); 1952 if (!et_entry->init_complete && ( 1953 missing_count || update_phy_bits)) { 1954 dpm_entry->MappingInformation 1955 = et_entry->num_slots; 1956 dpm_entry->MappingInformation 1957 <<= map_shift; 1958 dpm_entry->PhysicalBitsMapping 1959 = et_entry->phy_bits; 1960 sc->dpm_flush_entry[et_entry-> 1961 dpm_entry_num] = 1; 1962 } 1963 } 1964 } 1965 } else { 1966 enc_idx = sc->num_enc_table_entries; 1967 if (enc_idx >= sc->max_enclosures) { 1968 printf("%s: enclosure can not be added; " 1969 "mapping table is full\n", __func__); 1970 goto out; 1971 } 1972 sc->num_enc_table_entries++; 1973 et_entry = &sc->enclosure_table[enc_idx]; 1974 et_entry->enc_handle = le16toh(event_data-> 1975 EnclosureHandle); 1976 et_entry->enclosure_id = event_data-> 1977 EnclosureLogicalID.High; 1978 et_entry->enclosure_id = ( et_entry->enclosure_id << 1979 32) | event_data->EnclosureLogicalID.Low; 1980 et_entry->start_index = MPS_MAPTABLE_BAD_IDX; 1981 et_entry->dpm_entry_num = MPS_DPM_BAD_IDX; 1982 et_entry->num_slots = le16toh(event_data->NumSlots); 1983 et_entry->start_slot = le16toh(event_data->StartSlot); 1984 et_entry->phy_bits = le32toh(event_data->PhyBits); 1985 } 1986 et_entry->init_complete = 1; 1987 } else if (event_data->ReasonCode == 1988 MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING) { 1989 enc_idx = _mapping_get_enc_idx_from_handle(sc, 1990 le16toh(event_data->EnclosureHandle)); 1991 if (enc_idx == MPS_ENCTABLE_BAD_IDX) { 1992 printf("%s: cannot unmap enclosure %d because it has " 1993 "already been deleted", __func__, enc_idx); 1994 goto out; 1995 } 1996 et_entry = &sc->enclosure_table[enc_idx]; 1997 if (!et_entry->init_complete) { 1998 if (et_entry->missing_count < MPS_MAX_MISSING_COUNT) 1999 et_entry->missing_count++; 2000 else 2001 et_entry->init_complete = 1; 2002 } 2003 if (!et_entry->missing_count) 2004 et_entry->missing_count++; 2005 if (sc->is_dpm_enable && !et_entry->init_complete && 2006 et_entry->dpm_entry_num != MPS_DPM_BAD_IDX) { 2007 dpm_entry += et_entry->dpm_entry_num; 2008 dpm_entry->MappingInformation = et_entry->num_slots; 2009 dpm_entry->MappingInformation <<= map_shift; 2010 dpm_entry->MappingInformation |= 2011 et_entry->missing_count; 2012 sc->dpm_flush_entry[et_entry->dpm_entry_num] = 1; 2013 } 2014 et_entry->init_complete = 1; 2015 } 2016 2017 out: 2018 _mapping_flush_dpm_pages(sc); 2019 if (sc->pending_map_events) 2020 sc->pending_map_events--; 2021 } 2022 2023 /** 2024 * mps_mapping_topology_change_event - handle topology change events 2025 * @sc: per adapter object 2026 * @event_data: event data payload 2027 * 2028 * Returns nothing. 2029 */ 2030 void 2031 mps_mapping_topology_change_event(struct mps_softc *sc, 2032 Mpi2EventDataSasTopologyChangeList_t *event_data) 2033 { 2034 struct _map_topology_change topo_change; 2035 struct _map_phy_change *phy_change; 2036 Mpi2EventSasTopoPhyEntry_t *event_phy_change; 2037 u8 i, num_entries; 2038 2039 topo_change.enc_handle = le16toh(event_data->EnclosureHandle); 2040 topo_change.exp_handle = le16toh(event_data->ExpanderDevHandle); 2041 num_entries = event_data->NumEntries; 2042 topo_change.num_entries = num_entries; 2043 topo_change.start_phy_num = event_data->StartPhyNum; 2044 topo_change.num_phys = event_data->NumPhys; 2045 topo_change.exp_status = event_data->ExpStatus; 2046 event_phy_change = event_data->PHY; 2047 topo_change.phy_details = NULL; 2048 2049 if (!num_entries) 2050 goto out; 2051 phy_change = malloc(sizeof(struct _map_phy_change) * num_entries, 2052 M_MPT2, M_NOWAIT|M_ZERO); 2053 topo_change.phy_details = phy_change; 2054 if (!phy_change) 2055 goto out; 2056 for (i = 0; i < num_entries; i++, event_phy_change++, phy_change++) { 2057 phy_change->dev_handle = le16toh(event_phy_change-> 2058 AttachedDevHandle); 2059 phy_change->reason = event_phy_change->PhyStatus & 2060 MPI2_EVENT_SAS_TOPO_RC_MASK; 2061 } 2062 _mapping_update_missing_count(sc, &topo_change); 2063 _mapping_get_dev_info(sc, &topo_change); 2064 _mapping_clear_removed_entries(sc); 2065 _mapping_add_new_device(sc, &topo_change); 2066 2067 out: 2068 free(topo_change.phy_details, M_MPT2); 2069 _mapping_flush_dpm_pages(sc); 2070 if (sc->pending_map_events) 2071 sc->pending_map_events--; 2072 } 2073 2074 /** 2075 * _mapping_check_update_ir_mt_idx - Check and update IR map table index 2076 * @sc: per adapter object 2077 * @event_data: event data payload 2078 * @evt_idx: current event index 2079 * @map_idx: current index and the place holder for new map table index 2080 * @wwid_table: world wide name for volumes in the element table 2081 * 2082 * pass through IR events and find whether any events matches and if so 2083 * tries to find new index if not returns failure 2084 * 2085 * Returns 0 on success and 1 on failure 2086 */ 2087 static int 2088 _mapping_check_update_ir_mt_idx(struct mps_softc *sc, 2089 Mpi2EventDataIrConfigChangeList_t *event_data, int evt_idx, u32 *map_idx, 2090 u64 *wwid_table) 2091 { 2092 struct dev_mapping_table *mt_entry; 2093 u32 st_idx, end_idx, mt_idx = *map_idx; 2094 u8 match = 0; 2095 Mpi2EventIrConfigElement_t *element; 2096 u16 element_flags; 2097 int i; 2098 2099 mt_entry = &sc->mapping_table[mt_idx]; 2100 _mapping_get_ir_maprange(sc, &st_idx, &end_idx); 2101 search_again: 2102 match = 0; 2103 for (i = evt_idx + 1; i < event_data->NumElements; i++) { 2104 element = (Mpi2EventIrConfigElement_t *) 2105 &event_data->ConfigElement[i]; 2106 element_flags = le16toh(element->ElementFlags); 2107 if ((element_flags & 2108 MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK) != 2109 MPI2_EVENT_IR_CHANGE_EFLAGS_VOLUME_ELEMENT) 2110 continue; 2111 if (element->ReasonCode == MPI2_EVENT_IR_CHANGE_RC_ADDED || 2112 element->ReasonCode == 2113 MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED) { 2114 if (mt_entry->physical_id == wwid_table[i]) { 2115 match = 1; 2116 break; 2117 } 2118 } 2119 } 2120 2121 if (match) { 2122 do { 2123 mt_idx++; 2124 if (mt_idx > end_idx) 2125 return 1; 2126 mt_entry = &sc->mapping_table[mt_idx]; 2127 } while (mt_entry->device_info & MPS_MAP_IN_USE); 2128 goto search_again; 2129 } 2130 *map_idx = mt_idx; 2131 return 0; 2132 } 2133 2134 /** 2135 * mps_mapping_ir_config_change_event - handle IR config change list events 2136 * @sc: per adapter object 2137 * @event_data: event data payload 2138 * 2139 * Returns nothing. 2140 */ 2141 void 2142 mps_mapping_ir_config_change_event(struct mps_softc *sc, 2143 Mpi2EventDataIrConfigChangeList_t *event_data) 2144 { 2145 Mpi2EventIrConfigElement_t *element; 2146 int i; 2147 u64 *wwid_table; 2148 u32 map_idx, flags; 2149 struct dev_mapping_table *mt_entry; 2150 u16 element_flags; 2151 u8 log_full_error = 0; 2152 2153 wwid_table = malloc(sizeof(u64) * event_data->NumElements, M_MPT2, 2154 M_NOWAIT | M_ZERO); 2155 if (!wwid_table) 2156 goto out; 2157 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; 2158 flags = le32toh(event_data->Flags); 2159 for (i = 0; i < event_data->NumElements; i++, element++) { 2160 element_flags = le16toh(element->ElementFlags); 2161 if ((element->ReasonCode != MPI2_EVENT_IR_CHANGE_RC_ADDED) && 2162 (element->ReasonCode != MPI2_EVENT_IR_CHANGE_RC_REMOVED) && 2163 (element->ReasonCode != MPI2_EVENT_IR_CHANGE_RC_NO_CHANGE) 2164 && (element->ReasonCode != 2165 MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED)) 2166 continue; 2167 if ((element_flags & 2168 MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK) == 2169 MPI2_EVENT_IR_CHANGE_EFLAGS_VOLUME_ELEMENT) { 2170 mps_config_get_volume_wwid(sc, 2171 le16toh(element->VolDevHandle), &wwid_table[i]); 2172 map_idx = _mapping_get_ir_mt_idx_from_wwid(sc, 2173 wwid_table[i]); 2174 if (map_idx != MPS_MAPTABLE_BAD_IDX) { 2175 mt_entry = &sc->mapping_table[map_idx]; 2176 mt_entry->device_info |= MPS_MAP_IN_USE; 2177 } 2178 } 2179 } 2180 if (flags == MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) 2181 goto out; 2182 else { 2183 element = (Mpi2EventIrConfigElement_t *)&event_data-> 2184 ConfigElement[0]; 2185 for (i = 0; i < event_data->NumElements; i++, element++) { 2186 if (element->ReasonCode == 2187 MPI2_EVENT_IR_CHANGE_RC_ADDED || 2188 element->ReasonCode == 2189 MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED) { 2190 map_idx = _mapping_get_ir_mt_idx_from_wwid 2191 (sc, wwid_table[i]); 2192 if (map_idx != MPS_MAPTABLE_BAD_IDX) { 2193 mt_entry = &sc->mapping_table[map_idx]; 2194 mt_entry->channel = MPS_RAID_CHANNEL; 2195 mt_entry->id = map_idx; 2196 mt_entry->dev_handle = le16toh 2197 (element->VolDevHandle); 2198 mt_entry->device_info = 2199 MPS_DEV_RESERVED | MPS_MAP_IN_USE; 2200 _mapping_update_ir_missing_cnt(sc, 2201 map_idx, element, wwid_table[i]); 2202 continue; 2203 } 2204 map_idx = _mapping_get_free_ir_mt_idx(sc); 2205 if (map_idx == MPS_MAPTABLE_BAD_IDX) 2206 log_full_error = 1; 2207 else if (i < (event_data->NumElements - 1)) { 2208 log_full_error = 2209 _mapping_check_update_ir_mt_idx 2210 (sc, event_data, i, &map_idx, 2211 wwid_table); 2212 } 2213 if (log_full_error) { 2214 printf("%s: no space to add the RAID " 2215 "volume with handle 0x%04x in " 2216 "mapping table\n", __func__, le16toh 2217 (element->VolDevHandle)); 2218 continue; 2219 } 2220 mt_entry = &sc->mapping_table[map_idx]; 2221 mt_entry->physical_id = wwid_table[i]; 2222 mt_entry->channel = MPS_RAID_CHANNEL; 2223 mt_entry->id = map_idx; 2224 mt_entry->dev_handle = le16toh(element-> 2225 VolDevHandle); 2226 mt_entry->device_info = MPS_DEV_RESERVED | 2227 MPS_MAP_IN_USE; 2228 mt_entry->init_complete = 0; 2229 _mapping_update_ir_missing_cnt(sc, map_idx, 2230 element, wwid_table[i]); 2231 } else if (element->ReasonCode == 2232 MPI2_EVENT_IR_CHANGE_RC_REMOVED) { 2233 map_idx = _mapping_get_ir_mt_idx_from_wwid(sc, 2234 wwid_table[i]); 2235 if (map_idx == MPS_MAPTABLE_BAD_IDX) { 2236 printf("%s: failed to remove a volume " 2237 "because it has already been " 2238 "removed\n", __func__); 2239 continue; 2240 } 2241 _mapping_update_ir_missing_cnt(sc, map_idx, 2242 element, wwid_table[i]); 2243 } else if (element->ReasonCode == 2244 MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED) { 2245 map_idx = _mapping_get_mt_idx_from_handle(sc, 2246 le16toh(element->VolDevHandle)); 2247 if (map_idx == MPS_MAPTABLE_BAD_IDX) { 2248 printf("%s: failed to remove volume " 2249 "with handle 0x%04x because it has " 2250 "already been removed\n", __func__, 2251 le16toh(element->VolDevHandle)); 2252 continue; 2253 } 2254 mt_entry = &sc->mapping_table[map_idx]; 2255 _mapping_update_ir_missing_cnt(sc, map_idx, 2256 element, mt_entry->physical_id); 2257 } 2258 } 2259 } 2260 2261 out: 2262 _mapping_flush_dpm_pages(sc); 2263 free(wwid_table, M_MPT2); 2264 if (sc->pending_map_events) 2265 sc->pending_map_events--; 2266 } 2267 2268 int 2269 mps_mapping_dump(SYSCTL_HANDLER_ARGS) 2270 { 2271 struct mps_softc *sc; 2272 struct dev_mapping_table *mt_entry; 2273 struct sbuf sbuf; 2274 int i, error; 2275 2276 sc = (struct mps_softc *)arg1; 2277 2278 error = sysctl_wire_old_buffer(req, 0); 2279 if (error != 0) 2280 return (error); 2281 sbuf_new_for_sysctl(&sbuf, NULL, 128, req); 2282 2283 sbuf_printf(&sbuf, "\nindex physical_id handle id\n"); 2284 for (i = 0; i < sc->max_devices; i++) { 2285 mt_entry = &sc->mapping_table[i]; 2286 if (mt_entry->physical_id == 0) 2287 continue; 2288 sbuf_printf(&sbuf, "%4d %jx %04x %hd\n", 2289 i, mt_entry->physical_id, mt_entry->dev_handle, 2290 mt_entry->id); 2291 } 2292 error = sbuf_finish(&sbuf); 2293 sbuf_delete(&sbuf); 2294 return (error); 2295 } 2296 2297 int 2298 mps_mapping_encl_dump(SYSCTL_HANDLER_ARGS) 2299 { 2300 struct mps_softc *sc; 2301 struct enc_mapping_table *enc_entry; 2302 struct sbuf sbuf; 2303 int i, error; 2304 2305 sc = (struct mps_softc *)arg1; 2306 2307 error = sysctl_wire_old_buffer(req, 0); 2308 if (error != 0) 2309 return (error); 2310 sbuf_new_for_sysctl(&sbuf, NULL, 128, req); 2311 2312 sbuf_printf(&sbuf, "\nindex enclosure_id handle map_index\n"); 2313 for (i = 0; i < sc->max_enclosures; i++) { 2314 enc_entry = &sc->enclosure_table[i]; 2315 if (enc_entry->enclosure_id == 0) 2316 continue; 2317 sbuf_printf(&sbuf, "%4d %jx %04x %d\n", 2318 i, enc_entry->enclosure_id, enc_entry->enc_handle, 2319 enc_entry->start_index); 2320 } 2321 error = sbuf_finish(&sbuf); 2322 sbuf_delete(&sbuf); 2323 return (error); 2324 } 2325