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