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_INFO, "SAS Address for SATA " 931 "device = %jx\n", sas_address); 932 } else { 933 sas_address = 934 sas_device_pg0.SASAddress.High; 935 sas_address = (sas_address << 32) | 936 sas_device_pg0.SASAddress.Low; 937 } 938 } else { 939 sas_address = sas_device_pg0.SASAddress.High; 940 sas_address = (sas_address << 32) | 941 sas_device_pg0.SASAddress.Low; 942 } 943 phy_change->physical_id = sas_address; 944 phy_change->slot = le16toh(sas_device_pg0.Slot); 945 phy_change->device_info = 946 le32toh(sas_device_pg0.DeviceInfo); 947 948 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 949 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 950 enc_idx = _mapping_get_enc_idx_from_handle(sc, 951 topo_change->enc_handle); 952 if (enc_idx == MPS_ENCTABLE_BAD_IDX) { 953 phy_change->is_processed = 1; 954 printf("%s: failed to add the device with " 955 "handle 0x%04x because the enclosure is " 956 "not in the mapping table\n", __func__, 957 phy_change->dev_handle); 958 continue; 959 } 960 if (!((phy_change->device_info & 961 MPI2_SAS_DEVICE_INFO_END_DEVICE) && 962 (phy_change->device_info & 963 (MPI2_SAS_DEVICE_INFO_SSP_TARGET | 964 MPI2_SAS_DEVICE_INFO_STP_TARGET | 965 MPI2_SAS_DEVICE_INFO_SATA_DEVICE)))) { 966 phy_change->is_processed = 1; 967 continue; 968 } 969 et_entry = &sc->enclosure_table[enc_idx]; 970 if (et_entry->start_index != MPS_MAPTABLE_BAD_IDX) 971 continue; 972 if (!topo_change->exp_handle) { 973 map_idx = sc->num_rsvd_entries; 974 et_entry->start_index = map_idx; 975 } else { 976 map_idx = _mapping_find_enc_map_space(sc, 977 et_entry); 978 et_entry->start_index = map_idx; 979 if (et_entry->start_index == 980 MPS_MAPTABLE_BAD_IDX) { 981 phy_change->is_processed = 1; 982 for (phy_idx = 0; phy_idx < 983 topo_change->num_entries; 984 phy_idx++) { 985 tmp_phy_change = 986 &topo_change->phy_details 987 [phy_idx]; 988 if (tmp_phy_change->reason == 989 add_code) 990 tmp_phy_change-> 991 is_processed = 1; 992 } 993 break; 994 } 995 } 996 mt_entry = &sc->mapping_table[map_idx]; 997 for (index = map_idx; index < (et_entry->num_slots 998 + map_idx); index++, mt_entry++) { 999 mt_entry->device_info = MPS_DEV_RESERVED; 1000 mt_entry->physical_id = et_entry->enclosure_id; 1001 mt_entry->phy_bits = et_entry->phy_bits; 1002 } 1003 } 1004 } 1005 } 1006 1007 /** 1008 * _mapping_set_mid_to_eid -set map table data from enclosure table 1009 * @sc: per adapter object 1010 * @et_entry: enclosure entry 1011 * 1012 * Returns nothing 1013 */ 1014 static inline void 1015 _mapping_set_mid_to_eid(struct mps_softc *sc, 1016 struct enc_mapping_table *et_entry) 1017 { 1018 struct dev_mapping_table *mt_entry; 1019 u16 slots = et_entry->num_slots, map_idx; 1020 u32 start_idx = et_entry->start_index; 1021 if (start_idx != MPS_MAPTABLE_BAD_IDX) { 1022 mt_entry = &sc->mapping_table[start_idx]; 1023 for (map_idx = 0; map_idx < slots; map_idx++, mt_entry++) 1024 mt_entry->physical_id = et_entry->enclosure_id; 1025 } 1026 } 1027 1028 /** 1029 * _mapping_clear_removed_entries - mark the entries to be cleared 1030 * @sc: per adapter object 1031 * 1032 * Search through the removal table and mark the entries which needs to be 1033 * flushed to DPM and also updates the map table and enclosure table by 1034 * clearing the corresponding entries. 1035 * 1036 * Returns nothing 1037 */ 1038 static void 1039 _mapping_clear_removed_entries(struct mps_softc *sc) 1040 { 1041 u32 remove_idx; 1042 struct map_removal_table *remove_entry; 1043 Mpi2DriverMap0Entry_t *dpm_entry; 1044 u8 done_flag = 0, num_entries, m, i; 1045 struct enc_mapping_table *et_entry, *from, *to; 1046 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 1047 1048 if (sc->is_dpm_enable) { 1049 remove_entry = sc->removal_table; 1050 for (remove_idx = 0; remove_idx < sc->max_devices; 1051 remove_idx++, remove_entry++) { 1052 if (remove_entry->dpm_entry_num != MPS_DPM_BAD_IDX) { 1053 dpm_entry = (Mpi2DriverMap0Entry_t *) 1054 ((u8 *) sc->dpm_pg0 + 1055 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 1056 dpm_entry += remove_entry->dpm_entry_num; 1057 dpm_entry->PhysicalIdentifier.Low = 0; 1058 dpm_entry->PhysicalIdentifier.High = 0; 1059 dpm_entry->DeviceIndex = 0; 1060 dpm_entry->MappingInformation = 0; 1061 dpm_entry->PhysicalBitsMapping = 0; 1062 sc->dpm_flush_entry[remove_entry-> 1063 dpm_entry_num] = 1; 1064 sc->dpm_entry_used[remove_entry->dpm_entry_num] 1065 = 0; 1066 remove_entry->dpm_entry_num = MPS_DPM_BAD_IDX; 1067 } 1068 } 1069 } 1070 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1071 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 1072 num_entries = sc->num_enc_table_entries; 1073 while (!done_flag) { 1074 done_flag = 1; 1075 et_entry = sc->enclosure_table; 1076 for (i = 0; i < num_entries; i++, et_entry++) { 1077 if (!et_entry->enc_handle && et_entry-> 1078 init_complete) { 1079 done_flag = 0; 1080 if (i != (num_entries - 1)) { 1081 from = &sc->enclosure_table 1082 [i+1]; 1083 to = &sc->enclosure_table[i]; 1084 for (m = i; m < (num_entries - 1085 1); m++, from++, to++) { 1086 _mapping_set_mid_to_eid 1087 (sc, to); 1088 *to = *from; 1089 } 1090 _mapping_clear_enc_entry(to); 1091 sc->num_enc_table_entries--; 1092 num_entries = 1093 sc->num_enc_table_entries; 1094 } else { 1095 _mapping_clear_enc_entry 1096 (et_entry); 1097 sc->num_enc_table_entries--; 1098 num_entries = 1099 sc->num_enc_table_entries; 1100 } 1101 } 1102 } 1103 } 1104 } 1105 } 1106 1107 /** 1108 * _mapping_add_new_device -Add the new device into mapping table 1109 * @sc: per adapter object 1110 * @topo_change: Topology change event entry 1111 * 1112 * Search through the topology change event list and updates map table, 1113 * enclosure table and DPM pages for for the newly added devices. 1114 * 1115 * Returns nothing 1116 */ 1117 static void 1118 _mapping_add_new_device(struct mps_softc *sc, 1119 struct _map_topology_change *topo_change) 1120 { 1121 u8 enc_idx, missing_cnt, is_removed = 0; 1122 u16 dpm_idx; 1123 u32 search_idx, map_idx; 1124 u32 entry; 1125 struct dev_mapping_table *mt_entry; 1126 struct enc_mapping_table *et_entry; 1127 struct _map_phy_change *phy_change; 1128 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 1129 Mpi2DriverMap0Entry_t *dpm_entry; 1130 uint64_t temp64_var; 1131 u8 map_shift = MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT; 1132 u8 hdr_sz = sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER); 1133 u16 max_num_phy_ids = le16toh(sc->ioc_pg8.MaxNumPhysicalMappedIDs); 1134 1135 for (entry = 0; entry < topo_change->num_entries; entry++) { 1136 phy_change = &topo_change->phy_details[entry]; 1137 if (phy_change->is_processed) 1138 continue; 1139 if (phy_change->reason != MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED || 1140 !phy_change->dev_handle) { 1141 phy_change->is_processed = 1; 1142 continue; 1143 } 1144 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1145 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 1146 enc_idx = _mapping_get_enc_idx_from_handle 1147 (sc, topo_change->enc_handle); 1148 if (enc_idx == MPS_ENCTABLE_BAD_IDX) { 1149 phy_change->is_processed = 1; 1150 printf("%s: failed to add the device with " 1151 "handle 0x%04x because the enclosure is " 1152 "not in the mapping table\n", __func__, 1153 phy_change->dev_handle); 1154 continue; 1155 } 1156 et_entry = &sc->enclosure_table[enc_idx]; 1157 if (et_entry->start_index == MPS_MAPTABLE_BAD_IDX) { 1158 phy_change->is_processed = 1; 1159 if (!sc->mt_full_retry) { 1160 sc->mt_add_device_failed = 1; 1161 continue; 1162 } 1163 printf("%s: failed to add the device with " 1164 "handle 0x%04x because there is no free " 1165 "space available in the mapping table\n", 1166 __func__, phy_change->dev_handle); 1167 continue; 1168 } 1169 map_idx = et_entry->start_index + phy_change->slot - 1170 et_entry->start_slot; 1171 mt_entry = &sc->mapping_table[map_idx]; 1172 mt_entry->physical_id = phy_change->physical_id; 1173 mt_entry->channel = 0; 1174 mt_entry->id = map_idx; 1175 mt_entry->dev_handle = phy_change->dev_handle; 1176 mt_entry->missing_count = 0; 1177 mt_entry->dpm_entry_num = et_entry->dpm_entry_num; 1178 mt_entry->device_info = phy_change->device_info | 1179 (MPS_DEV_RESERVED | MPS_MAP_IN_USE); 1180 if (sc->is_dpm_enable) { 1181 dpm_idx = et_entry->dpm_entry_num; 1182 if (dpm_idx == MPS_DPM_BAD_IDX) 1183 dpm_idx = _mapping_get_dpm_idx_from_id 1184 (sc, et_entry->enclosure_id, 1185 et_entry->phy_bits); 1186 if (dpm_idx == MPS_DPM_BAD_IDX) { 1187 dpm_idx = _mapping_get_free_dpm_idx(sc); 1188 if (dpm_idx != MPS_DPM_BAD_IDX) { 1189 dpm_entry = 1190 (Mpi2DriverMap0Entry_t *) 1191 ((u8 *) sc->dpm_pg0 + 1192 hdr_sz); 1193 dpm_entry += dpm_idx; 1194 dpm_entry-> 1195 PhysicalIdentifier.Low = 1196 (0xFFFFFFFF & 1197 et_entry->enclosure_id); 1198 dpm_entry-> 1199 PhysicalIdentifier.High = 1200 ( et_entry->enclosure_id 1201 >> 32); 1202 dpm_entry->DeviceIndex = 1203 (U16)et_entry->start_index; 1204 dpm_entry->MappingInformation = 1205 et_entry->num_slots; 1206 dpm_entry->MappingInformation 1207 <<= map_shift; 1208 dpm_entry->PhysicalBitsMapping 1209 = et_entry->phy_bits; 1210 et_entry->dpm_entry_num = 1211 dpm_idx; 1212 /* FIXME Do I need to set the dpm_idxin mt_entry too */ 1213 sc->dpm_entry_used[dpm_idx] = 1; 1214 sc->dpm_flush_entry[dpm_idx] = 1215 1; 1216 phy_change->is_processed = 1; 1217 } else { 1218 phy_change->is_processed = 1; 1219 printf("%s: failed to add the " 1220 "device with handle 0x%04x " 1221 "to persistent table " 1222 "because there is no free " 1223 "space available\n", 1224 __func__, 1225 phy_change->dev_handle); 1226 } 1227 } else { 1228 et_entry->dpm_entry_num = dpm_idx; 1229 mt_entry->dpm_entry_num = dpm_idx; 1230 } 1231 } 1232 /* FIXME Why not mt_entry too? */ 1233 et_entry->init_complete = 1; 1234 } else if ((ioc_pg8_flags & 1235 MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1236 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) { 1237 map_idx = _mapping_get_mt_idx_from_id 1238 (sc, phy_change->physical_id); 1239 if (map_idx == MPS_MAPTABLE_BAD_IDX) { 1240 search_idx = sc->num_rsvd_entries; 1241 if (topo_change->exp_handle) 1242 search_idx += max_num_phy_ids; 1243 map_idx = _mapping_get_free_mt_idx(sc, 1244 search_idx); 1245 } 1246 if (map_idx == MPS_MAPTABLE_BAD_IDX) { 1247 map_idx = _mapping_get_high_missing_mt_idx(sc); 1248 if (map_idx != MPS_MAPTABLE_BAD_IDX) { 1249 mt_entry = &sc->mapping_table[map_idx]; 1250 if (mt_entry->dev_handle) { 1251 _mapping_add_to_removal_table 1252 (sc, mt_entry->dev_handle, 1253 0); 1254 is_removed = 1; 1255 } 1256 mt_entry->init_complete = 0; 1257 } 1258 } 1259 if (map_idx != MPS_MAPTABLE_BAD_IDX) { 1260 mt_entry = &sc->mapping_table[map_idx]; 1261 mt_entry->physical_id = phy_change->physical_id; 1262 mt_entry->channel = 0; 1263 mt_entry->id = map_idx; 1264 mt_entry->dev_handle = phy_change->dev_handle; 1265 mt_entry->missing_count = 0; 1266 mt_entry->device_info = phy_change->device_info 1267 | (MPS_DEV_RESERVED | MPS_MAP_IN_USE); 1268 } else { 1269 phy_change->is_processed = 1; 1270 if (!sc->mt_full_retry) { 1271 sc->mt_add_device_failed = 1; 1272 continue; 1273 } 1274 printf("%s: failed to add the device with " 1275 "handle 0x%04x because there is no free " 1276 "space available in the mapping table\n", 1277 __func__, phy_change->dev_handle); 1278 continue; 1279 } 1280 if (sc->is_dpm_enable) { 1281 if (mt_entry->dpm_entry_num != 1282 MPS_DPM_BAD_IDX) { 1283 dpm_idx = mt_entry->dpm_entry_num; 1284 dpm_entry = (Mpi2DriverMap0Entry_t *) 1285 ((u8 *)sc->dpm_pg0 + hdr_sz); 1286 dpm_entry += dpm_idx; 1287 missing_cnt = dpm_entry-> 1288 MappingInformation & 1289 MPI2_DRVMAP0_MAPINFO_MISSING_MASK; 1290 temp64_var = dpm_entry-> 1291 PhysicalIdentifier.High; 1292 temp64_var = (temp64_var << 32) | 1293 dpm_entry->PhysicalIdentifier.Low; 1294 if ((mt_entry->physical_id == 1295 temp64_var) && !missing_cnt) 1296 mt_entry->init_complete = 1; 1297 } else { 1298 dpm_idx = _mapping_get_free_dpm_idx(sc); 1299 mt_entry->init_complete = 0; 1300 } 1301 if (dpm_idx != MPS_DPM_BAD_IDX && 1302 !mt_entry->init_complete) { 1303 mt_entry->init_complete = 1; 1304 mt_entry->dpm_entry_num = dpm_idx; 1305 dpm_entry = (Mpi2DriverMap0Entry_t *) 1306 ((u8 *)sc->dpm_pg0 + hdr_sz); 1307 dpm_entry += dpm_idx; 1308 dpm_entry->PhysicalIdentifier.Low = 1309 (0xFFFFFFFF & 1310 mt_entry->physical_id); 1311 dpm_entry->PhysicalIdentifier.High = 1312 (mt_entry->physical_id >> 32); 1313 dpm_entry->DeviceIndex = (U16) map_idx; 1314 dpm_entry->MappingInformation = 0; 1315 dpm_entry->PhysicalBitsMapping = 0; 1316 sc->dpm_entry_used[dpm_idx] = 1; 1317 sc->dpm_flush_entry[dpm_idx] = 1; 1318 phy_change->is_processed = 1; 1319 } else if (dpm_idx == MPS_DPM_BAD_IDX) { 1320 phy_change->is_processed = 1; 1321 printf("%s: failed to add the " 1322 "device with handle 0x%04x " 1323 "to persistent table " 1324 "because there is no free " 1325 "space available\n", 1326 __func__, 1327 phy_change->dev_handle); 1328 } 1329 } 1330 mt_entry->init_complete = 1; 1331 } 1332 1333 phy_change->is_processed = 1; 1334 } 1335 if (is_removed) 1336 _mapping_clear_removed_entries(sc); 1337 } 1338 1339 /** 1340 * _mapping_flush_dpm_pages -Flush the DPM pages to NVRAM 1341 * @sc: per adapter object 1342 * 1343 * Returns nothing 1344 */ 1345 static void 1346 _mapping_flush_dpm_pages(struct mps_softc *sc) 1347 { 1348 Mpi2DriverMap0Entry_t *dpm_entry; 1349 Mpi2ConfigReply_t mpi_reply; 1350 Mpi2DriverMappingPage0_t config_page; 1351 u16 entry_num; 1352 1353 for (entry_num = 0; entry_num < sc->max_dpm_entries; entry_num++) { 1354 if (!sc->dpm_flush_entry[entry_num]) 1355 continue; 1356 memset(&config_page, 0, sizeof(Mpi2DriverMappingPage0_t)); 1357 memcpy(&config_page.Header, (u8 *)sc->dpm_pg0, 1358 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 1359 dpm_entry = (Mpi2DriverMap0Entry_t *) ((u8 *)sc->dpm_pg0 + 1360 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 1361 dpm_entry += entry_num; 1362 dpm_entry->MappingInformation = htole16(dpm_entry-> 1363 MappingInformation); 1364 dpm_entry->DeviceIndex = htole16(dpm_entry->DeviceIndex); 1365 dpm_entry->PhysicalBitsMapping = htole32(dpm_entry-> 1366 PhysicalBitsMapping); 1367 memcpy(&config_page.Entry, (u8 *)dpm_entry, 1368 sizeof(Mpi2DriverMap0Entry_t)); 1369 /* TODO-How to handle failed writes? */ 1370 if (mps_config_set_dpm_pg0(sc, &mpi_reply, &config_page, 1371 entry_num)) { 1372 printf("%s: write of dpm entry %d for device failed\n", 1373 __func__, entry_num); 1374 } else 1375 sc->dpm_flush_entry[entry_num] = 0; 1376 dpm_entry->MappingInformation = le16toh(dpm_entry-> 1377 MappingInformation); 1378 dpm_entry->DeviceIndex = le16toh(dpm_entry->DeviceIndex); 1379 dpm_entry->PhysicalBitsMapping = le32toh(dpm_entry-> 1380 PhysicalBitsMapping); 1381 } 1382 } 1383 1384 /** 1385 * _mapping_allocate_memory- allocates the memory required for mapping tables 1386 * @sc: per adapter object 1387 * 1388 * Allocates the memory for all the tables required for host mapping 1389 * 1390 * Return 0 on success or non-zero on failure. 1391 */ 1392 int 1393 mps_mapping_allocate_memory(struct mps_softc *sc) 1394 { 1395 uint32_t dpm_pg0_sz; 1396 1397 sc->mapping_table = malloc((sizeof(struct dev_mapping_table) * 1398 sc->max_devices), M_MPT2, M_ZERO|M_NOWAIT); 1399 if (!sc->mapping_table) 1400 goto free_resources; 1401 1402 sc->removal_table = malloc((sizeof(struct map_removal_table) * 1403 sc->max_devices), M_MPT2, M_ZERO|M_NOWAIT); 1404 if (!sc->removal_table) 1405 goto free_resources; 1406 1407 sc->enclosure_table = malloc((sizeof(struct enc_mapping_table) * 1408 sc->max_enclosures), M_MPT2, M_ZERO|M_NOWAIT); 1409 if (!sc->enclosure_table) 1410 goto free_resources; 1411 1412 sc->dpm_entry_used = malloc((sizeof(u8) * sc->max_dpm_entries), 1413 M_MPT2, M_ZERO|M_NOWAIT); 1414 if (!sc->dpm_entry_used) 1415 goto free_resources; 1416 1417 sc->dpm_flush_entry = malloc((sizeof(u8) * sc->max_dpm_entries), 1418 M_MPT2, M_ZERO|M_NOWAIT); 1419 if (!sc->dpm_flush_entry) 1420 goto free_resources; 1421 1422 dpm_pg0_sz = sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER) + 1423 (sc->max_dpm_entries * sizeof(MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY)); 1424 1425 sc->dpm_pg0 = malloc(dpm_pg0_sz, M_MPT2, M_ZERO|M_NOWAIT); 1426 if (!sc->dpm_pg0) { 1427 printf("%s: memory alloc failed for dpm page; disabling dpm\n", 1428 __func__); 1429 sc->is_dpm_enable = 0; 1430 } 1431 1432 return 0; 1433 1434 free_resources: 1435 free(sc->mapping_table, M_MPT2); 1436 free(sc->removal_table, M_MPT2); 1437 free(sc->enclosure_table, M_MPT2); 1438 free(sc->dpm_entry_used, M_MPT2); 1439 free(sc->dpm_flush_entry, M_MPT2); 1440 free(sc->dpm_pg0, M_MPT2); 1441 printf("%s: device initialization failed due to failure in mapping " 1442 "table memory allocation\n", __func__); 1443 return -1; 1444 } 1445 1446 /** 1447 * mps_mapping_free_memory- frees the memory allocated for mapping tables 1448 * @sc: per adapter object 1449 * 1450 * Returns nothing. 1451 */ 1452 void 1453 mps_mapping_free_memory(struct mps_softc *sc) 1454 { 1455 free(sc->mapping_table, M_MPT2); 1456 free(sc->removal_table, M_MPT2); 1457 free(sc->enclosure_table, M_MPT2); 1458 free(sc->dpm_entry_used, M_MPT2); 1459 free(sc->dpm_flush_entry, M_MPT2); 1460 free(sc->dpm_pg0, M_MPT2); 1461 } 1462 1463 1464 static void 1465 _mapping_process_dpm_pg0(struct mps_softc *sc) 1466 { 1467 u8 missing_cnt, enc_idx; 1468 u16 slot_id, entry_num, num_slots; 1469 u32 map_idx, dev_idx, start_idx, end_idx; 1470 struct dev_mapping_table *mt_entry; 1471 Mpi2DriverMap0Entry_t *dpm_entry; 1472 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 1473 u16 max_num_phy_ids = le16toh(sc->ioc_pg8.MaxNumPhysicalMappedIDs); 1474 struct enc_mapping_table *et_entry; 1475 u64 physical_id; 1476 u32 phy_bits = 0; 1477 1478 if (sc->ir_firmware) 1479 _mapping_get_ir_maprange(sc, &start_idx, &end_idx); 1480 1481 dpm_entry = (Mpi2DriverMap0Entry_t *) ((uint8_t *) sc->dpm_pg0 + 1482 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 1483 for (entry_num = 0; entry_num < sc->max_dpm_entries; entry_num++, 1484 dpm_entry++) { 1485 physical_id = dpm_entry->PhysicalIdentifier.High; 1486 physical_id = (physical_id << 32) | 1487 dpm_entry->PhysicalIdentifier.Low; 1488 if (!physical_id) { 1489 sc->dpm_entry_used[entry_num] = 0; 1490 continue; 1491 } 1492 sc->dpm_entry_used[entry_num] = 1; 1493 dpm_entry->MappingInformation = le16toh(dpm_entry-> 1494 MappingInformation); 1495 missing_cnt = dpm_entry->MappingInformation & 1496 MPI2_DRVMAP0_MAPINFO_MISSING_MASK; 1497 dev_idx = le16toh(dpm_entry->DeviceIndex); 1498 phy_bits = le32toh(dpm_entry->PhysicalBitsMapping); 1499 if (sc->ir_firmware && (dev_idx >= start_idx) && 1500 (dev_idx <= end_idx)) { 1501 mt_entry = &sc->mapping_table[dev_idx]; 1502 mt_entry->physical_id = dpm_entry->PhysicalIdentifier.High; 1503 mt_entry->physical_id = (mt_entry->physical_id << 32) | 1504 dpm_entry->PhysicalIdentifier.Low; 1505 mt_entry->channel = MPS_RAID_CHANNEL; 1506 mt_entry->id = dev_idx; 1507 mt_entry->missing_count = missing_cnt; 1508 mt_entry->dpm_entry_num = entry_num; 1509 mt_entry->device_info = MPS_DEV_RESERVED; 1510 continue; 1511 } 1512 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1513 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 1514 if (dev_idx < (sc->num_rsvd_entries + 1515 max_num_phy_ids)) { 1516 slot_id = 0; 1517 if (ioc_pg8_flags & 1518 MPI2_IOCPAGE8_FLAGS_DA_START_SLOT_1) 1519 slot_id = 1; 1520 num_slots = max_num_phy_ids; 1521 } else { 1522 slot_id = 0; 1523 num_slots = dpm_entry->MappingInformation & 1524 MPI2_DRVMAP0_MAPINFO_SLOT_MASK; 1525 num_slots >>= MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT; 1526 } 1527 enc_idx = sc->num_enc_table_entries; 1528 if (enc_idx >= sc->max_enclosures) { 1529 printf("%s: enclosure entries exceed max " 1530 "enclosures of %d\n", __func__, 1531 sc->max_enclosures); 1532 break; 1533 } 1534 sc->num_enc_table_entries++; 1535 et_entry = &sc->enclosure_table[enc_idx]; 1536 physical_id = dpm_entry->PhysicalIdentifier.High; 1537 et_entry->enclosure_id = (physical_id << 32) | 1538 dpm_entry->PhysicalIdentifier.Low; 1539 et_entry->start_index = dev_idx; 1540 et_entry->dpm_entry_num = entry_num; 1541 et_entry->num_slots = num_slots; 1542 et_entry->start_slot = slot_id; 1543 et_entry->missing_count = missing_cnt; 1544 et_entry->phy_bits = phy_bits; 1545 1546 mt_entry = &sc->mapping_table[dev_idx]; 1547 for (map_idx = dev_idx; map_idx < (dev_idx + num_slots); 1548 map_idx++, mt_entry++) { 1549 if (mt_entry->dpm_entry_num != 1550 MPS_DPM_BAD_IDX) { 1551 printf("%s: conflict in mapping table " 1552 "for enclosure %d\n", __func__, 1553 enc_idx); 1554 break; 1555 } 1556 physical_id = dpm_entry->PhysicalIdentifier.High; 1557 mt_entry->physical_id = (physical_id << 32) | 1558 dpm_entry->PhysicalIdentifier.Low; 1559 mt_entry->phy_bits = phy_bits; 1560 mt_entry->channel = 0; 1561 mt_entry->id = dev_idx; 1562 mt_entry->dpm_entry_num = entry_num; 1563 mt_entry->missing_count = missing_cnt; 1564 mt_entry->device_info = MPS_DEV_RESERVED; 1565 } 1566 } else if ((ioc_pg8_flags & 1567 MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1568 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) { 1569 map_idx = dev_idx; 1570 mt_entry = &sc->mapping_table[map_idx]; 1571 if (mt_entry->dpm_entry_num != MPS_DPM_BAD_IDX) { 1572 printf("%s: conflict in mapping table for " 1573 "device %d\n", __func__, map_idx); 1574 break; 1575 } 1576 physical_id = dpm_entry->PhysicalIdentifier.High; 1577 mt_entry->physical_id = (physical_id << 32) | 1578 dpm_entry->PhysicalIdentifier.Low; 1579 mt_entry->phy_bits = phy_bits; 1580 mt_entry->channel = 0; 1581 mt_entry->id = dev_idx; 1582 mt_entry->missing_count = missing_cnt; 1583 mt_entry->dpm_entry_num = entry_num; 1584 mt_entry->device_info = MPS_DEV_RESERVED; 1585 } 1586 } /*close the loop for DPM table */ 1587 } 1588 1589 /* 1590 * mps_mapping_check_devices - start of the day check for device availabilty 1591 * @sc: per adapter object 1592 * @sleep_flag: Flag indicating whether this function can sleep or not 1593 * 1594 * Returns nothing. 1595 */ 1596 void 1597 mps_mapping_check_devices(struct mps_softc *sc, int sleep_flag) 1598 { 1599 u32 i; 1600 /* u32 cntdn, i; 1601 u32 timeout = 60;*/ 1602 struct dev_mapping_table *mt_entry; 1603 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 1604 struct enc_mapping_table *et_entry; 1605 u32 start_idx, end_idx; 1606 1607 /* We need to ucomment this when this function is called 1608 * from the port enable complete */ 1609 #if 0 1610 sc->track_mapping_events = 0; 1611 cntdn = (sleep_flag == CAN_SLEEP) ? 1000*timeout : 2000*timeout; 1612 do { 1613 if (!sc->pending_map_events) 1614 break; 1615 if (sleep_flag == CAN_SLEEP) 1616 pause("mps_pause", (hz/1000));/* 1msec sleep */ 1617 else 1618 DELAY(500); /* 500 useconds delay */ 1619 } while (--cntdn); 1620 1621 1622 if (!cntdn) 1623 printf("%s: there are %d" 1624 " pending events after %d seconds of delay\n", 1625 __func__, sc->pending_map_events, timeout); 1626 #endif 1627 sc->pending_map_events = 0; 1628 1629 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1630 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 1631 et_entry = sc->enclosure_table; 1632 for (i = 0; i < sc->num_enc_table_entries; i++, et_entry++) { 1633 if (!et_entry->init_complete) { 1634 if (et_entry->missing_count < 1635 MPS_MAX_MISSING_COUNT) { 1636 et_entry->missing_count++; 1637 if (et_entry->dpm_entry_num != 1638 MPS_DPM_BAD_IDX) 1639 _mapping_commit_enc_entry(sc, 1640 et_entry); 1641 } 1642 et_entry->init_complete = 1; 1643 } 1644 } 1645 if (!sc->ir_firmware) 1646 return; 1647 _mapping_get_ir_maprange(sc, &start_idx, &end_idx); 1648 mt_entry = &sc->mapping_table[start_idx]; 1649 for (i = start_idx; i < (end_idx + 1); i++, mt_entry++) { 1650 if (mt_entry->device_info & MPS_DEV_RESERVED 1651 && !mt_entry->physical_id) 1652 mt_entry->init_complete = 1; 1653 else if (mt_entry->device_info & MPS_DEV_RESERVED) { 1654 if (!mt_entry->init_complete) { 1655 if (mt_entry->missing_count < 1656 MPS_MAX_MISSING_COUNT) { 1657 mt_entry->missing_count++; 1658 if (mt_entry->dpm_entry_num != 1659 MPS_DPM_BAD_IDX) 1660 _mapping_commit_map_entry(sc, 1661 mt_entry); 1662 } 1663 mt_entry->init_complete = 1; 1664 } 1665 } 1666 } 1667 } else if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1668 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) { 1669 mt_entry = sc->mapping_table; 1670 for (i = 0; i < sc->max_devices; i++, mt_entry++) { 1671 if (mt_entry->device_info & MPS_DEV_RESERVED 1672 && !mt_entry->physical_id) 1673 mt_entry->init_complete = 1; 1674 else if (mt_entry->device_info & MPS_DEV_RESERVED) { 1675 if (!mt_entry->init_complete) { 1676 if (mt_entry->missing_count < 1677 MPS_MAX_MISSING_COUNT) { 1678 mt_entry->missing_count++; 1679 if (mt_entry->dpm_entry_num != 1680 MPS_DPM_BAD_IDX) 1681 _mapping_commit_map_entry(sc, 1682 mt_entry); 1683 } 1684 mt_entry->init_complete = 1; 1685 } 1686 } 1687 } 1688 } 1689 } 1690 1691 1692 /** 1693 * mps_mapping_is_reinit_required - check whether event replay required 1694 * @sc: per adapter object 1695 * 1696 * Checks the per ioc flags and decide whether reinit of events required 1697 * 1698 * Returns 1 for reinit of ioc 0 for not. 1699 */ 1700 int mps_mapping_is_reinit_required(struct mps_softc *sc) 1701 { 1702 if (!sc->mt_full_retry && sc->mt_add_device_failed) { 1703 sc->mt_full_retry = 1; 1704 sc->mt_add_device_failed = 0; 1705 _mapping_flush_dpm_pages(sc); 1706 return 1; 1707 } 1708 sc->mt_full_retry = 1; 1709 return 0; 1710 } 1711 1712 /** 1713 * mps_mapping_initialize - initialize mapping tables 1714 * @sc: per adapter object 1715 * 1716 * Read controller persitant mapping tables into internal data area. 1717 * 1718 * Return 0 for success or non-zero for failure. 1719 */ 1720 int 1721 mps_mapping_initialize(struct mps_softc *sc) 1722 { 1723 uint16_t volume_mapping_flags, dpm_pg0_sz; 1724 uint32_t i; 1725 Mpi2ConfigReply_t mpi_reply; 1726 int error; 1727 uint8_t retry_count; 1728 uint16_t ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 1729 1730 /* The additional 1 accounts for the virtual enclosure 1731 * created for the controller 1732 */ 1733 sc->max_enclosures = sc->facts->MaxEnclosures + 1; 1734 sc->max_expanders = sc->facts->MaxSasExpanders; 1735 sc->max_volumes = sc->facts->MaxVolumes; 1736 sc->max_devices = sc->facts->MaxTargets + sc->max_volumes; 1737 sc->pending_map_events = 0; 1738 sc->num_enc_table_entries = 0; 1739 sc->num_rsvd_entries = 0; 1740 sc->num_channels = 1; 1741 sc->max_dpm_entries = sc->ioc_pg8.MaxPersistentEntries; 1742 sc->is_dpm_enable = (sc->max_dpm_entries) ? 1 : 0; 1743 sc->track_mapping_events = 0; 1744 1745 if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_DISABLE_PERSISTENT_MAPPING) 1746 sc->is_dpm_enable = 0; 1747 1748 if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0) 1749 sc->num_rsvd_entries = 1; 1750 1751 volume_mapping_flags = sc->ioc_pg8.IRVolumeMappingFlags & 1752 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE; 1753 if (sc->ir_firmware && (volume_mapping_flags == 1754 MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING)) 1755 sc->num_rsvd_entries += sc->max_volumes; 1756 1757 error = mps_mapping_allocate_memory(sc); 1758 if (error) 1759 return (error); 1760 1761 for (i = 0; i < sc->max_devices; i++) 1762 _mapping_clear_map_entry(sc->mapping_table + i); 1763 1764 for (i = 0; i < sc->max_enclosures; i++) 1765 _mapping_clear_enc_entry(sc->enclosure_table + i); 1766 1767 for (i = 0; i < sc->max_devices; i++) { 1768 sc->removal_table[i].dev_handle = 0; 1769 sc->removal_table[i].dpm_entry_num = MPS_DPM_BAD_IDX; 1770 } 1771 1772 memset(sc->dpm_entry_used, 0, sc->max_dpm_entries); 1773 memset(sc->dpm_flush_entry, 0, sc->max_dpm_entries); 1774 1775 if (sc->is_dpm_enable) { 1776 dpm_pg0_sz = sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER) + 1777 (sc->max_dpm_entries * 1778 sizeof(MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY)); 1779 retry_count = 0; 1780 1781 retry_read_dpm: 1782 if (mps_config_get_dpm_pg0(sc, &mpi_reply, sc->dpm_pg0, 1783 dpm_pg0_sz)) { 1784 printf("%s: dpm page read failed; disabling dpm\n", 1785 __func__); 1786 if (retry_count < 3) { 1787 retry_count++; 1788 goto retry_read_dpm; 1789 } 1790 sc->is_dpm_enable = 0; 1791 } 1792 } 1793 1794 if (sc->is_dpm_enable) 1795 _mapping_process_dpm_pg0(sc); 1796 1797 sc->track_mapping_events = 1; 1798 return 0; 1799 } 1800 1801 /** 1802 * mps_mapping_exit - clear mapping table and associated memory 1803 * @sc: per adapter object 1804 * 1805 * Returns nothing. 1806 */ 1807 void 1808 mps_mapping_exit(struct mps_softc *sc) 1809 { 1810 _mapping_flush_dpm_pages(sc); 1811 mps_mapping_free_memory(sc); 1812 } 1813 1814 /** 1815 * mps_mapping_get_sas_id - assign a target id for sas device 1816 * @sc: per adapter object 1817 * @sas_address: sas address of the device 1818 * @handle: device handle 1819 * 1820 * Returns valid ID on success or BAD_ID. 1821 */ 1822 unsigned int 1823 mps_mapping_get_sas_id(struct mps_softc *sc, uint64_t sas_address, u16 handle) 1824 { 1825 u32 map_idx; 1826 struct dev_mapping_table *mt_entry; 1827 1828 for (map_idx = 0; map_idx < sc->max_devices; map_idx++) { 1829 mt_entry = &sc->mapping_table[map_idx]; 1830 if (mt_entry->dev_handle == handle && mt_entry->physical_id == 1831 sas_address) 1832 return mt_entry->id; 1833 } 1834 1835 return MPS_MAP_BAD_ID; 1836 } 1837 1838 /** 1839 * mps_mapping_get_sas_id_from_handle - find a target id in mapping table using 1840 * only the dev handle. This is just a wrapper function for the local function 1841 * _mapping_get_mt_idx_from_handle. 1842 * @sc: per adapter object 1843 * @handle: device handle 1844 * 1845 * Returns valid ID on success or BAD_ID. 1846 */ 1847 unsigned int 1848 mps_mapping_get_sas_id_from_handle(struct mps_softc *sc, u16 handle) 1849 { 1850 return (_mapping_get_mt_idx_from_handle(sc, handle)); 1851 } 1852 1853 /** 1854 * mps_mapping_get_raid_id - assign a target id for raid device 1855 * @sc: per adapter object 1856 * @wwid: world wide identifier for raid volume 1857 * @handle: device handle 1858 * 1859 * Returns valid ID on success or BAD_ID. 1860 */ 1861 unsigned int 1862 mps_mapping_get_raid_id(struct mps_softc *sc, u64 wwid, u16 handle) 1863 { 1864 u32 map_idx; 1865 struct dev_mapping_table *mt_entry; 1866 1867 for (map_idx = 0; map_idx < sc->max_devices; map_idx++) { 1868 mt_entry = &sc->mapping_table[map_idx]; 1869 if (mt_entry->dev_handle == handle && mt_entry->physical_id == 1870 wwid) 1871 return mt_entry->id; 1872 } 1873 1874 return MPS_MAP_BAD_ID; 1875 } 1876 1877 /** 1878 * mps_mapping_get_raid_id_from_handle - find raid device in mapping table 1879 * using only the volume dev handle. This is just a wrapper function for the 1880 * local function _mapping_get_ir_mt_idx_from_handle. 1881 * @sc: per adapter object 1882 * @volHandle: volume device handle 1883 * 1884 * Returns valid ID on success or BAD_ID. 1885 */ 1886 unsigned int 1887 mps_mapping_get_raid_id_from_handle(struct mps_softc *sc, u16 volHandle) 1888 { 1889 return (_mapping_get_ir_mt_idx_from_handle(sc, volHandle)); 1890 } 1891 1892 /** 1893 * mps_mapping_enclosure_dev_status_change_event - handle enclosure events 1894 * @sc: per adapter object 1895 * @event_data: event data payload 1896 * 1897 * Return nothing. 1898 */ 1899 void 1900 mps_mapping_enclosure_dev_status_change_event(struct mps_softc *sc, 1901 Mpi2EventDataSasEnclDevStatusChange_t *event_data) 1902 { 1903 u8 enc_idx, missing_count; 1904 struct enc_mapping_table *et_entry; 1905 Mpi2DriverMap0Entry_t *dpm_entry; 1906 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 1907 u8 map_shift = MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT; 1908 u8 update_phy_bits = 0; 1909 u32 saved_phy_bits; 1910 uint64_t temp64_var; 1911 1912 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) != 1913 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) 1914 goto out; 1915 1916 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *)sc->dpm_pg0 + 1917 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 1918 1919 if (event_data->ReasonCode == MPI2_EVENT_SAS_ENCL_RC_ADDED) { 1920 if (!event_data->NumSlots) { 1921 printf("%s: enclosure with handle = 0x%x reported 0 " 1922 "slots\n", __func__, 1923 le16toh(event_data->EnclosureHandle)); 1924 goto out; 1925 } 1926 temp64_var = event_data->EnclosureLogicalID.High; 1927 temp64_var = (temp64_var << 32) | 1928 event_data->EnclosureLogicalID.Low; 1929 enc_idx = _mapping_get_enc_idx_from_id(sc, temp64_var, 1930 event_data->PhyBits); 1931 if (enc_idx != MPS_ENCTABLE_BAD_IDX) { 1932 et_entry = &sc->enclosure_table[enc_idx]; 1933 if (et_entry->init_complete && 1934 !et_entry->missing_count) { 1935 printf("%s: enclosure %d is already present " 1936 "with handle = 0x%x\n",__func__, enc_idx, 1937 et_entry->enc_handle); 1938 goto out; 1939 } 1940 et_entry->enc_handle = le16toh(event_data-> 1941 EnclosureHandle); 1942 et_entry->start_slot = le16toh(event_data->StartSlot); 1943 saved_phy_bits = et_entry->phy_bits; 1944 et_entry->phy_bits |= le32toh(event_data->PhyBits); 1945 if (saved_phy_bits != et_entry->phy_bits) 1946 update_phy_bits = 1; 1947 if (et_entry->missing_count || update_phy_bits) { 1948 et_entry->missing_count = 0; 1949 if (sc->is_dpm_enable && 1950 et_entry->dpm_entry_num != 1951 MPS_DPM_BAD_IDX) { 1952 dpm_entry += et_entry->dpm_entry_num; 1953 missing_count = 1954 (u8)(dpm_entry->MappingInformation & 1955 MPI2_DRVMAP0_MAPINFO_MISSING_MASK); 1956 if (!et_entry->init_complete && ( 1957 missing_count || update_phy_bits)) { 1958 dpm_entry->MappingInformation 1959 = et_entry->num_slots; 1960 dpm_entry->MappingInformation 1961 <<= map_shift; 1962 dpm_entry->PhysicalBitsMapping 1963 = et_entry->phy_bits; 1964 sc->dpm_flush_entry[et_entry-> 1965 dpm_entry_num] = 1; 1966 } 1967 } 1968 } 1969 } else { 1970 enc_idx = sc->num_enc_table_entries; 1971 if (enc_idx >= sc->max_enclosures) { 1972 printf("%s: enclosure can not be added; " 1973 "mapping table is full\n", __func__); 1974 goto out; 1975 } 1976 sc->num_enc_table_entries++; 1977 et_entry = &sc->enclosure_table[enc_idx]; 1978 et_entry->enc_handle = le16toh(event_data-> 1979 EnclosureHandle); 1980 et_entry->enclosure_id = event_data-> 1981 EnclosureLogicalID.High; 1982 et_entry->enclosure_id = ( et_entry->enclosure_id << 1983 32) | event_data->EnclosureLogicalID.Low; 1984 et_entry->start_index = MPS_MAPTABLE_BAD_IDX; 1985 et_entry->dpm_entry_num = MPS_DPM_BAD_IDX; 1986 et_entry->num_slots = le16toh(event_data->NumSlots); 1987 et_entry->start_slot = le16toh(event_data->StartSlot); 1988 et_entry->phy_bits = le32toh(event_data->PhyBits); 1989 } 1990 et_entry->init_complete = 1; 1991 } else if (event_data->ReasonCode == 1992 MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING) { 1993 enc_idx = _mapping_get_enc_idx_from_handle(sc, 1994 le16toh(event_data->EnclosureHandle)); 1995 if (enc_idx == MPS_ENCTABLE_BAD_IDX) { 1996 printf("%s: cannot unmap enclosure %d because it has " 1997 "already been deleted", __func__, enc_idx); 1998 goto out; 1999 } 2000 et_entry = &sc->enclosure_table[enc_idx]; 2001 if (!et_entry->init_complete) { 2002 if (et_entry->missing_count < MPS_MAX_MISSING_COUNT) 2003 et_entry->missing_count++; 2004 else 2005 et_entry->init_complete = 1; 2006 } 2007 if (!et_entry->missing_count) 2008 et_entry->missing_count++; 2009 if (sc->is_dpm_enable && !et_entry->init_complete && 2010 et_entry->dpm_entry_num != MPS_DPM_BAD_IDX) { 2011 dpm_entry += et_entry->dpm_entry_num; 2012 dpm_entry->MappingInformation = et_entry->num_slots; 2013 dpm_entry->MappingInformation <<= map_shift; 2014 dpm_entry->MappingInformation |= 2015 et_entry->missing_count; 2016 sc->dpm_flush_entry[et_entry->dpm_entry_num] = 1; 2017 } 2018 et_entry->init_complete = 1; 2019 } 2020 2021 out: 2022 _mapping_flush_dpm_pages(sc); 2023 if (sc->pending_map_events) 2024 sc->pending_map_events--; 2025 } 2026 2027 /** 2028 * mps_mapping_topology_change_event - handle topology change events 2029 * @sc: per adapter object 2030 * @event_data: event data payload 2031 * 2032 * Returns nothing. 2033 */ 2034 void 2035 mps_mapping_topology_change_event(struct mps_softc *sc, 2036 Mpi2EventDataSasTopologyChangeList_t *event_data) 2037 { 2038 struct _map_topology_change topo_change; 2039 struct _map_phy_change *phy_change; 2040 Mpi2EventSasTopoPhyEntry_t *event_phy_change; 2041 u8 i, num_entries; 2042 2043 topo_change.enc_handle = le16toh(event_data->EnclosureHandle); 2044 topo_change.exp_handle = le16toh(event_data->ExpanderDevHandle); 2045 num_entries = event_data->NumEntries; 2046 topo_change.num_entries = num_entries; 2047 topo_change.start_phy_num = event_data->StartPhyNum; 2048 topo_change.num_phys = event_data->NumPhys; 2049 topo_change.exp_status = event_data->ExpStatus; 2050 event_phy_change = event_data->PHY; 2051 topo_change.phy_details = NULL; 2052 2053 if (!num_entries) 2054 goto out; 2055 phy_change = malloc(sizeof(struct _map_phy_change) * num_entries, 2056 M_MPT2, M_NOWAIT|M_ZERO); 2057 topo_change.phy_details = phy_change; 2058 if (!phy_change) 2059 goto out; 2060 for (i = 0; i < num_entries; i++, event_phy_change++, phy_change++) { 2061 phy_change->dev_handle = le16toh(event_phy_change-> 2062 AttachedDevHandle); 2063 phy_change->reason = event_phy_change->PhyStatus & 2064 MPI2_EVENT_SAS_TOPO_RC_MASK; 2065 } 2066 _mapping_update_missing_count(sc, &topo_change); 2067 _mapping_get_dev_info(sc, &topo_change); 2068 _mapping_clear_removed_entries(sc); 2069 _mapping_add_new_device(sc, &topo_change); 2070 2071 out: 2072 free(topo_change.phy_details, M_MPT2); 2073 _mapping_flush_dpm_pages(sc); 2074 if (sc->pending_map_events) 2075 sc->pending_map_events--; 2076 } 2077 2078 /** 2079 * _mapping_check_update_ir_mt_idx - Check and update IR map table index 2080 * @sc: per adapter object 2081 * @event_data: event data payload 2082 * @evt_idx: current event index 2083 * @map_idx: current index and the place holder for new map table index 2084 * @wwid_table: world wide name for volumes in the element table 2085 * 2086 * pass through IR events and find whether any events matches and if so 2087 * tries to find new index if not returns failure 2088 * 2089 * Returns 0 on success and 1 on failure 2090 */ 2091 static int 2092 _mapping_check_update_ir_mt_idx(struct mps_softc *sc, 2093 Mpi2EventDataIrConfigChangeList_t *event_data, int evt_idx, u32 *map_idx, 2094 u64 *wwid_table) 2095 { 2096 struct dev_mapping_table *mt_entry; 2097 u32 st_idx, end_idx, mt_idx = *map_idx; 2098 u8 match = 0; 2099 Mpi2EventIrConfigElement_t *element; 2100 u16 element_flags; 2101 int i; 2102 2103 mt_entry = &sc->mapping_table[mt_idx]; 2104 _mapping_get_ir_maprange(sc, &st_idx, &end_idx); 2105 search_again: 2106 match = 0; 2107 for (i = evt_idx + 1; i < event_data->NumElements; i++) { 2108 element = (Mpi2EventIrConfigElement_t *) 2109 &event_data->ConfigElement[i]; 2110 element_flags = le16toh(element->ElementFlags); 2111 if ((element_flags & 2112 MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK) != 2113 MPI2_EVENT_IR_CHANGE_EFLAGS_VOLUME_ELEMENT) 2114 continue; 2115 if (element->ReasonCode == MPI2_EVENT_IR_CHANGE_RC_ADDED || 2116 element->ReasonCode == 2117 MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED) { 2118 if (mt_entry->physical_id == wwid_table[i]) { 2119 match = 1; 2120 break; 2121 } 2122 } 2123 } 2124 2125 if (match) { 2126 do { 2127 mt_idx++; 2128 if (mt_idx > end_idx) 2129 return 1; 2130 mt_entry = &sc->mapping_table[mt_idx]; 2131 } while (mt_entry->device_info & MPS_MAP_IN_USE); 2132 goto search_again; 2133 } 2134 *map_idx = mt_idx; 2135 return 0; 2136 } 2137 2138 /** 2139 * mps_mapping_ir_config_change_event - handle IR config change list events 2140 * @sc: per adapter object 2141 * @event_data: event data payload 2142 * 2143 * Returns nothing. 2144 */ 2145 void 2146 mps_mapping_ir_config_change_event(struct mps_softc *sc, 2147 Mpi2EventDataIrConfigChangeList_t *event_data) 2148 { 2149 Mpi2EventIrConfigElement_t *element; 2150 int i; 2151 u64 *wwid_table; 2152 u32 map_idx, flags; 2153 struct dev_mapping_table *mt_entry; 2154 u16 element_flags; 2155 u8 log_full_error = 0; 2156 2157 wwid_table = malloc(sizeof(u64) * event_data->NumElements, M_MPT2, 2158 M_NOWAIT | M_ZERO); 2159 if (!wwid_table) 2160 goto out; 2161 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; 2162 flags = le32toh(event_data->Flags); 2163 for (i = 0; i < event_data->NumElements; i++, element++) { 2164 element_flags = le16toh(element->ElementFlags); 2165 if ((element->ReasonCode != MPI2_EVENT_IR_CHANGE_RC_ADDED) && 2166 (element->ReasonCode != MPI2_EVENT_IR_CHANGE_RC_REMOVED) && 2167 (element->ReasonCode != MPI2_EVENT_IR_CHANGE_RC_NO_CHANGE) 2168 && (element->ReasonCode != 2169 MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED)) 2170 continue; 2171 if ((element_flags & 2172 MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK) == 2173 MPI2_EVENT_IR_CHANGE_EFLAGS_VOLUME_ELEMENT) { 2174 mps_config_get_volume_wwid(sc, 2175 le16toh(element->VolDevHandle), &wwid_table[i]); 2176 map_idx = _mapping_get_ir_mt_idx_from_wwid(sc, 2177 wwid_table[i]); 2178 if (map_idx != MPS_MAPTABLE_BAD_IDX) { 2179 mt_entry = &sc->mapping_table[map_idx]; 2180 mt_entry->device_info |= MPS_MAP_IN_USE; 2181 } 2182 } 2183 } 2184 if (flags == MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) 2185 goto out; 2186 else { 2187 element = (Mpi2EventIrConfigElement_t *)&event_data-> 2188 ConfigElement[0]; 2189 for (i = 0; i < event_data->NumElements; i++, element++) { 2190 if (element->ReasonCode == 2191 MPI2_EVENT_IR_CHANGE_RC_ADDED || 2192 element->ReasonCode == 2193 MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED) { 2194 map_idx = _mapping_get_ir_mt_idx_from_wwid 2195 (sc, wwid_table[i]); 2196 if (map_idx != MPS_MAPTABLE_BAD_IDX) { 2197 mt_entry = &sc->mapping_table[map_idx]; 2198 mt_entry->channel = MPS_RAID_CHANNEL; 2199 mt_entry->id = map_idx; 2200 mt_entry->dev_handle = le16toh 2201 (element->VolDevHandle); 2202 mt_entry->device_info = 2203 MPS_DEV_RESERVED | MPS_MAP_IN_USE; 2204 _mapping_update_ir_missing_cnt(sc, 2205 map_idx, element, wwid_table[i]); 2206 continue; 2207 } 2208 map_idx = _mapping_get_free_ir_mt_idx(sc); 2209 if (map_idx == MPS_MAPTABLE_BAD_IDX) 2210 log_full_error = 1; 2211 else if (i < (event_data->NumElements - 1)) { 2212 log_full_error = 2213 _mapping_check_update_ir_mt_idx 2214 (sc, event_data, i, &map_idx, 2215 wwid_table); 2216 } 2217 if (log_full_error) { 2218 printf("%s: no space to add the RAID " 2219 "volume with handle 0x%04x in " 2220 "mapping table\n", __func__, le16toh 2221 (element->VolDevHandle)); 2222 continue; 2223 } 2224 mt_entry = &sc->mapping_table[map_idx]; 2225 mt_entry->physical_id = wwid_table[i]; 2226 mt_entry->channel = MPS_RAID_CHANNEL; 2227 mt_entry->id = map_idx; 2228 mt_entry->dev_handle = le16toh(element-> 2229 VolDevHandle); 2230 mt_entry->device_info = MPS_DEV_RESERVED | 2231 MPS_MAP_IN_USE; 2232 mt_entry->init_complete = 0; 2233 _mapping_update_ir_missing_cnt(sc, map_idx, 2234 element, wwid_table[i]); 2235 } else if (element->ReasonCode == 2236 MPI2_EVENT_IR_CHANGE_RC_REMOVED) { 2237 map_idx = _mapping_get_ir_mt_idx_from_wwid(sc, 2238 wwid_table[i]); 2239 if (map_idx == MPS_MAPTABLE_BAD_IDX) { 2240 printf("%s: failed to remove a volume " 2241 "because it has already been " 2242 "removed\n", __func__); 2243 continue; 2244 } 2245 _mapping_update_ir_missing_cnt(sc, map_idx, 2246 element, wwid_table[i]); 2247 } else if (element->ReasonCode == 2248 MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED) { 2249 map_idx = _mapping_get_mt_idx_from_handle(sc, 2250 le16toh(element->VolDevHandle)); 2251 if (map_idx == MPS_MAPTABLE_BAD_IDX) { 2252 printf("%s: failed to remove volume " 2253 "with handle 0x%04x because it has " 2254 "already been removed\n", __func__, 2255 le16toh(element->VolDevHandle)); 2256 continue; 2257 } 2258 mt_entry = &sc->mapping_table[map_idx]; 2259 _mapping_update_ir_missing_cnt(sc, map_idx, 2260 element, mt_entry->physical_id); 2261 } 2262 } 2263 } 2264 2265 out: 2266 _mapping_flush_dpm_pages(sc); 2267 free(wwid_table, M_MPT2); 2268 if (sc->pending_map_events) 2269 sc->pending_map_events--; 2270 } 2271