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