1 /*- 2 * Copyright (c) 2011 LSI Corp. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * LSI MPT-Fusion Host Adapter FreeBSD 27 * 28 * $FreeBSD: src/sys/dev/mps/mps_mapping.c,v 1.1 2012/01/26 18:17:21 ken Exp $ 29 */ 30 31 /* TODO Move headers to mpsvar */ 32 #include <sys/types.h> 33 #include <sys/param.h> 34 #include <sys/lock.h> 35 #include <sys/mutex.h> 36 #include <sys/systm.h> 37 #include <sys/kernel.h> 38 #include <sys/malloc.h> 39 #include <sys/kthread.h> 40 #include <sys/taskqueue.h> 41 #include <sys/bus.h> 42 #include <sys/endian.h> 43 #include <sys/sysctl.h> 44 #include <sys/eventhandler.h> 45 #include <sys/uio.h> 46 #include <dev/raid/mps/mpi/mpi2_type.h> 47 #include <dev/raid/mps/mpi/mpi2.h> 48 #include <dev/raid/mps/mpi/mpi2_ioc.h> 49 #include <dev/raid/mps/mpi/mpi2_sas.h> 50 #include <dev/raid/mps/mpi/mpi2_cnfg.h> 51 #include <dev/raid/mps/mpi/mpi2_init.h> 52 #include <dev/raid/mps/mpi/mpi2_tool.h> 53 #include <dev/raid/mps/mps_ioctl.h> 54 #include <dev/raid/mps/mpsvar.h> 55 #include <dev/raid/mps/mps_mapping.h> 56 57 /** 58 * _mapping_clear_entry - Clear a particular mapping entry. 59 * @map_entry: map table entry 60 * 61 * Returns nothing. 62 */ 63 static inline void 64 _mapping_clear_map_entry(struct dev_mapping_table *map_entry) 65 { 66 map_entry->physical_id = 0; 67 map_entry->device_info = 0; 68 map_entry->phy_bits = 0; 69 map_entry->dpm_entry_num = MPS_DPM_BAD_IDX; 70 map_entry->dev_handle = 0; 71 map_entry->channel = -1; 72 map_entry->id = -1; 73 map_entry->missing_count = 0; 74 map_entry->init_complete = 0; 75 map_entry->TLR_bits = (u8)MPI2_SCSIIO_CONTROL_NO_TLR; 76 } 77 78 /** 79 * _mapping_clear_enc_entry - Clear a particular enclosure table entry. 80 * @enc_entry: enclosure table entry 81 * 82 * Returns nothing. 83 */ 84 static inline void 85 _mapping_clear_enc_entry(struct enc_mapping_table *enc_entry) 86 { 87 enc_entry->enclosure_id = 0; 88 enc_entry->start_index = MPS_MAPTABLE_BAD_IDX; 89 enc_entry->phy_bits = 0; 90 enc_entry->dpm_entry_num = MPS_DPM_BAD_IDX; 91 enc_entry->enc_handle = 0; 92 enc_entry->num_slots = 0; 93 enc_entry->start_slot = 0; 94 enc_entry->missing_count = 0; 95 enc_entry->removal_flag = 0; 96 enc_entry->skip_search = 0; 97 enc_entry->init_complete = 0; 98 } 99 100 /** 101 * _mapping_commit_enc_entry - write a particular enc entry in DPM page0. 102 * @sc: per adapter object 103 * @enc_entry: enclosure table entry 104 * 105 * Returns 0 for success, non-zero for failure. 106 */ 107 static int 108 _mapping_commit_enc_entry(struct mps_softc *sc, 109 struct enc_mapping_table *et_entry) 110 { 111 Mpi2DriverMap0Entry_t *dpm_entry; 112 struct dev_mapping_table *mt_entry; 113 Mpi2ConfigReply_t mpi_reply; 114 Mpi2DriverMappingPage0_t config_page; 115 116 if (!sc->is_dpm_enable) 117 return 0; 118 119 memset(&config_page, 0, sizeof(Mpi2DriverMappingPage0_t)); 120 memcpy(&config_page.Header, (u8 *) sc->dpm_pg0, 121 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 122 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *)sc->dpm_pg0 + 123 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 124 dpm_entry += et_entry->dpm_entry_num; 125 dpm_entry->PhysicalIdentifier.Low = 126 ( 0xFFFFFFFF & et_entry->enclosure_id); 127 dpm_entry->PhysicalIdentifier.High = 128 ( et_entry->enclosure_id >> 32); 129 mt_entry = &sc->mapping_table[et_entry->start_index]; 130 dpm_entry->DeviceIndex = htole16(mt_entry->id); 131 dpm_entry->MappingInformation = et_entry->num_slots; 132 dpm_entry->MappingInformation <<= MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT; 133 dpm_entry->MappingInformation |= et_entry->missing_count; 134 dpm_entry->MappingInformation = htole16(dpm_entry->MappingInformation); 135 dpm_entry->PhysicalBitsMapping = htole32(et_entry->phy_bits); 136 dpm_entry->Reserved1 = 0; 137 138 memcpy(&config_page.Entry, (u8 *)dpm_entry, 139 sizeof(Mpi2DriverMap0Entry_t)); 140 if (mps_config_set_dpm_pg0(sc, &mpi_reply, &config_page, 141 et_entry->dpm_entry_num)) { 142 kprintf("%s: write of dpm entry %d for enclosure failed\n", 143 __func__, et_entry->dpm_entry_num); 144 dpm_entry->MappingInformation = le16toh(dpm_entry-> 145 MappingInformation); 146 dpm_entry->DeviceIndex = le16toh(dpm_entry->DeviceIndex); 147 dpm_entry->PhysicalBitsMapping = 148 le32toh(dpm_entry->PhysicalBitsMapping); 149 return -1; 150 } 151 dpm_entry->MappingInformation = le16toh(dpm_entry-> 152 MappingInformation); 153 dpm_entry->DeviceIndex = le16toh(dpm_entry->DeviceIndex); 154 dpm_entry->PhysicalBitsMapping = 155 le32toh(dpm_entry->PhysicalBitsMapping); 156 return 0; 157 } 158 159 /** 160 * _mapping_commit_map_entry - write a particular map table entry in DPM page0. 161 * @sc: per adapter object 162 * @enc_entry: enclosure table entry 163 * 164 * Returns 0 for success, non-zero for failure. 165 */ 166 167 static int 168 _mapping_commit_map_entry(struct mps_softc *sc, 169 struct dev_mapping_table *mt_entry) 170 { 171 Mpi2DriverMap0Entry_t *dpm_entry; 172 Mpi2ConfigReply_t mpi_reply; 173 Mpi2DriverMappingPage0_t config_page; 174 175 if (!sc->is_dpm_enable) 176 return 0; 177 178 memset(&config_page, 0, sizeof(Mpi2DriverMappingPage0_t)); 179 memcpy(&config_page.Header, (u8 *)sc->dpm_pg0, 180 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 181 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *) sc->dpm_pg0 + 182 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 183 dpm_entry = dpm_entry + mt_entry->dpm_entry_num; 184 dpm_entry->PhysicalIdentifier.Low = (0xFFFFFFFF & 185 mt_entry->physical_id); 186 dpm_entry->PhysicalIdentifier.High = (mt_entry->physical_id >> 32); 187 dpm_entry->DeviceIndex = htole16(mt_entry->id); 188 dpm_entry->MappingInformation = htole16(mt_entry->missing_count); 189 dpm_entry->PhysicalBitsMapping = 0; 190 dpm_entry->Reserved1 = 0; 191 dpm_entry->MappingInformation = htole16(dpm_entry->MappingInformation); 192 memcpy(&config_page.Entry, (u8 *)dpm_entry, 193 sizeof(Mpi2DriverMap0Entry_t)); 194 if (mps_config_set_dpm_pg0(sc, &mpi_reply, &config_page, 195 mt_entry->dpm_entry_num)) { 196 kprintf("%s: write of dpm entry %d for device failed\n", 197 __func__, mt_entry->dpm_entry_num); 198 dpm_entry->MappingInformation = le16toh(dpm_entry-> 199 MappingInformation); 200 dpm_entry->DeviceIndex = le16toh(dpm_entry->DeviceIndex); 201 return -1; 202 } 203 204 dpm_entry->MappingInformation = le16toh(dpm_entry->MappingInformation); 205 dpm_entry->DeviceIndex = le16toh(dpm_entry->DeviceIndex); 206 return 0; 207 } 208 209 /** 210 * _mapping_get_ir_maprange - get start and end index for IR map range. 211 * @sc: per adapter object 212 * @start_idx: place holder for start index 213 * @end_idx: place holder for end index 214 * 215 * The IR volumes can be mapped either at start or end of the mapping table 216 * this function gets the detail of where IR volume mapping starts and ends 217 * in the device mapping table 218 * 219 * Returns nothing. 220 */ 221 static void 222 _mapping_get_ir_maprange(struct mps_softc *sc, u32 *start_idx, u32 *end_idx) 223 { 224 u16 volume_mapping_flags; 225 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 226 227 volume_mapping_flags = le16toh(sc->ioc_pg8.IRVolumeMappingFlags) & 228 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE; 229 if (volume_mapping_flags == MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING) { 230 *start_idx = 0; 231 if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0) 232 *start_idx = 1; 233 } else 234 *start_idx = sc->max_devices - sc->max_volumes; 235 *end_idx = *start_idx + sc->max_volumes - 1; 236 } 237 238 /** 239 * _mapping_get_enc_idx_from_id - get enclosure index from enclosure ID 240 * @sc: per adapter object 241 * @enc_id: enclosure logical identifier 242 * 243 * Returns the index of enclosure entry on success or bad index. 244 */ 245 static u8 246 _mapping_get_enc_idx_from_id(struct mps_softc *sc, u64 enc_id, 247 u64 phy_bits) 248 { 249 struct enc_mapping_table *et_entry; 250 u8 enc_idx = 0; 251 252 for (enc_idx = 0; enc_idx < sc->num_enc_table_entries; enc_idx++) { 253 et_entry = &sc->enclosure_table[enc_idx]; 254 if ((et_entry->enclosure_id == le64toh(enc_id)) && 255 (!et_entry->phy_bits || (et_entry->phy_bits & 256 le32toh(phy_bits)))) 257 return enc_idx; 258 } 259 return MPS_ENCTABLE_BAD_IDX; 260 } 261 262 /** 263 * _mapping_get_enc_idx_from_handle - get enclosure index from handle 264 * @sc: per adapter object 265 * @enc_id: enclosure handle 266 * 267 * Returns the index of enclosure entry on success or bad index. 268 */ 269 static u8 270 _mapping_get_enc_idx_from_handle(struct mps_softc *sc, u16 handle) 271 { 272 struct enc_mapping_table *et_entry; 273 u8 enc_idx = 0; 274 275 for (enc_idx = 0; enc_idx < sc->num_enc_table_entries; enc_idx++) { 276 et_entry = &sc->enclosure_table[enc_idx]; 277 if (et_entry->missing_count) 278 continue; 279 if (et_entry->enc_handle == handle) 280 return enc_idx; 281 } 282 return MPS_ENCTABLE_BAD_IDX; 283 } 284 285 /** 286 * _mapping_get_high_missing_et_idx - get missing enclosure index 287 * @sc: per adapter object 288 * 289 * Search through the enclosure table and identifies the enclosure entry 290 * with high missing count and returns it's index 291 * 292 * Returns the index of enclosure entry on success or bad index. 293 */ 294 static u8 295 _mapping_get_high_missing_et_idx(struct mps_softc *sc) 296 { 297 struct enc_mapping_table *et_entry; 298 u8 high_missing_count = 0; 299 u8 enc_idx, high_idx = MPS_ENCTABLE_BAD_IDX; 300 301 for (enc_idx = 0; enc_idx < sc->num_enc_table_entries; enc_idx++) { 302 et_entry = &sc->enclosure_table[enc_idx]; 303 if ((et_entry->missing_count > high_missing_count) && 304 !et_entry->skip_search) { 305 high_missing_count = et_entry->missing_count; 306 high_idx = enc_idx; 307 } 308 } 309 return high_idx; 310 } 311 312 /** 313 * _mapping_get_high_missing_mt_idx - get missing map table index 314 * @sc: per adapter object 315 * 316 * Search through the map table and identifies the device entry 317 * with high missing count and returns it's index 318 * 319 * Returns the index of map table entry on success or bad index. 320 */ 321 static u32 322 _mapping_get_high_missing_mt_idx(struct mps_softc *sc) 323 { 324 u32 map_idx, high_idx = MPS_ENCTABLE_BAD_IDX; 325 u8 high_missing_count = 0; 326 u32 start_idx, end_idx, start_idx_ir, end_idx_ir; 327 struct dev_mapping_table *mt_entry; 328 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 329 330 start_idx = 0; 331 end_idx = sc->max_devices; 332 if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0) 333 start_idx = 1; 334 if (sc->ir_firmware) 335 _mapping_get_ir_maprange(sc, &start_idx_ir, &end_idx_ir); 336 if (start_idx == start_idx_ir) 337 start_idx = end_idx_ir + 1; 338 else 339 end_idx = start_idx_ir; 340 mt_entry = &sc->mapping_table[start_idx]; 341 for (map_idx = start_idx; map_idx < end_idx; map_idx++, mt_entry++) { 342 if (mt_entry->missing_count > high_missing_count) { 343 high_missing_count = mt_entry->missing_count; 344 high_idx = map_idx; 345 } 346 } 347 return high_idx; 348 } 349 350 /** 351 * _mapping_get_ir_mt_idx_from_wwid - get map table index from volume WWID 352 * @sc: per adapter object 353 * @wwid: world wide unique ID of the volume 354 * 355 * Returns the index of map table entry on success or bad index. 356 */ 357 static u32 358 _mapping_get_ir_mt_idx_from_wwid(struct mps_softc *sc, u64 wwid) 359 { 360 u32 start_idx, end_idx, map_idx; 361 struct dev_mapping_table *mt_entry; 362 363 _mapping_get_ir_maprange(sc, &start_idx, &end_idx); 364 mt_entry = &sc->mapping_table[start_idx]; 365 for (map_idx = start_idx; map_idx <= end_idx; map_idx++, mt_entry++) 366 if (mt_entry->physical_id == wwid) 367 return map_idx; 368 369 return MPS_MAPTABLE_BAD_IDX; 370 } 371 372 /** 373 * _mapping_get_mt_idx_from_id - get map table index from a device ID 374 * @sc: per adapter object 375 * @dev_id: device identifer (SAS Address) 376 * 377 * Returns the index of map table entry on success or bad index. 378 */ 379 static u32 380 _mapping_get_mt_idx_from_id(struct mps_softc *sc, u64 dev_id) 381 { 382 u32 map_idx; 383 struct dev_mapping_table *mt_entry; 384 385 for (map_idx = 0; map_idx < sc->max_devices; map_idx++) { 386 mt_entry = &sc->mapping_table[map_idx]; 387 if (mt_entry->physical_id == dev_id) 388 return map_idx; 389 } 390 return MPS_MAPTABLE_BAD_IDX; 391 } 392 393 /** 394 * _mapping_get_ir_mt_idx_from_handle - get map table index from volume handle 395 * @sc: per adapter object 396 * @wwid: volume device handle 397 * 398 * Returns the index of map table entry on success or bad index. 399 */ 400 static u32 401 _mapping_get_ir_mt_idx_from_handle(struct mps_softc *sc, u16 volHandle) 402 { 403 u32 start_idx, end_idx, map_idx; 404 struct dev_mapping_table *mt_entry; 405 406 _mapping_get_ir_maprange(sc, &start_idx, &end_idx); 407 mt_entry = &sc->mapping_table[start_idx]; 408 for (map_idx = start_idx; map_idx <= end_idx; map_idx++, mt_entry++) 409 if (mt_entry->dev_handle == volHandle) 410 return map_idx; 411 412 return MPS_MAPTABLE_BAD_IDX; 413 } 414 415 /** 416 * _mapping_get_mt_idx_from_handle - get map table index from handle 417 * @sc: per adapter object 418 * @dev_id: device handle 419 * 420 * Returns the index of map table entry on success or bad index. 421 */ 422 static u32 423 _mapping_get_mt_idx_from_handle(struct mps_softc *sc, u16 handle) 424 { 425 u32 map_idx; 426 struct dev_mapping_table *mt_entry; 427 428 for (map_idx = 0; map_idx < sc->max_devices; map_idx++) { 429 mt_entry = &sc->mapping_table[map_idx]; 430 if (mt_entry->dev_handle == handle) 431 return map_idx; 432 } 433 return MPS_MAPTABLE_BAD_IDX; 434 } 435 436 /** 437 * _mapping_get_free_ir_mt_idx - get first free index for a volume 438 * @sc: per adapter object 439 * 440 * Search through mapping table for free index for a volume and if no free 441 * index then looks for a volume with high mapping index 442 * 443 * Returns the index of map table entry on success or bad index. 444 */ 445 static u32 446 _mapping_get_free_ir_mt_idx(struct mps_softc *sc) 447 { 448 u8 high_missing_count = 0; 449 u32 start_idx, end_idx, map_idx; 450 u32 high_idx = MPS_MAPTABLE_BAD_IDX; 451 struct dev_mapping_table *mt_entry; 452 453 _mapping_get_ir_maprange(sc, &start_idx, &end_idx); 454 455 mt_entry = &sc->mapping_table[start_idx]; 456 for (map_idx = start_idx; map_idx <= end_idx; map_idx++, mt_entry++) 457 if (!(mt_entry->device_info & MPS_MAP_IN_USE)) 458 return map_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->missing_count > high_missing_count) { 463 high_missing_count = mt_entry->missing_count; 464 high_idx = map_idx; 465 } 466 } 467 return high_idx; 468 } 469 470 /** 471 * _mapping_get_free_mt_idx - get first free index for a device 472 * @sc: per adapter object 473 * @start_idx: offset in the table to start search 474 * 475 * Returns the index of map table entry on success or bad index. 476 */ 477 static u32 478 _mapping_get_free_mt_idx(struct mps_softc *sc, u32 start_idx) 479 { 480 u32 map_idx, max_idx = sc->max_devices; 481 struct dev_mapping_table *mt_entry = &sc->mapping_table[start_idx]; 482 u16 volume_mapping_flags; 483 484 volume_mapping_flags = le16toh(sc->ioc_pg8.IRVolumeMappingFlags) & 485 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE; 486 if (sc->ir_firmware && (volume_mapping_flags == 487 MPI2_IOCPAGE8_IRFLAGS_HIGH_VOLUME_MAPPING)) 488 max_idx -= sc->max_volumes; 489 for (map_idx = start_idx; map_idx < max_idx; map_idx++, mt_entry++) 490 if (!(mt_entry->device_info & (MPS_MAP_IN_USE | 491 MPS_DEV_RESERVED))) 492 return map_idx; 493 494 return MPS_MAPTABLE_BAD_IDX; 495 } 496 497 /** 498 * _mapping_get_dpm_idx_from_id - get DPM index from ID 499 * @sc: per adapter object 500 * @id: volume WWID or enclosure ID or device ID 501 * 502 * Returns the index of DPM entry on success or bad index. 503 */ 504 static u16 505 _mapping_get_dpm_idx_from_id(struct mps_softc *sc, u64 id, u32 phy_bits) 506 { 507 u16 entry_num; 508 uint64_t PhysicalIdentifier; 509 Mpi2DriverMap0Entry_t *dpm_entry; 510 511 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *)sc->dpm_pg0 + 512 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 513 PhysicalIdentifier = dpm_entry->PhysicalIdentifier.High; 514 PhysicalIdentifier = (PhysicalIdentifier << 32) | 515 dpm_entry->PhysicalIdentifier.Low; 516 for (entry_num = 0; entry_num < sc->max_dpm_entries; entry_num++, 517 dpm_entry++) 518 if ((id == PhysicalIdentifier) && 519 (!phy_bits || !dpm_entry->PhysicalBitsMapping || 520 (phy_bits & dpm_entry->PhysicalBitsMapping))) 521 return entry_num; 522 523 return MPS_DPM_BAD_IDX; 524 } 525 526 527 /** 528 * _mapping_get_free_dpm_idx - get first available DPM index 529 * @sc: per adapter object 530 * 531 * Returns the index of DPM entry on success or bad index. 532 */ 533 static u32 534 _mapping_get_free_dpm_idx(struct mps_softc *sc) 535 { 536 u16 entry_num; 537 538 for (entry_num = 0; entry_num < sc->max_dpm_entries; entry_num++) { 539 if (!sc->dpm_entry_used[entry_num]) 540 return entry_num; 541 } 542 return MPS_DPM_BAD_IDX; 543 } 544 545 /** 546 * _mapping_update_ir_missing_cnt - Updates missing count for a volume 547 * @sc: per adapter object 548 * @map_idx: map table index of the volume 549 * @element: IR configuration change element 550 * @wwid: IR volume ID. 551 * 552 * Updates the missing count in the map table and in the DPM entry for a volume 553 * 554 * Returns nothing. 555 */ 556 static void 557 _mapping_update_ir_missing_cnt(struct mps_softc *sc, u32 map_idx, 558 Mpi2EventIrConfigElement_t *element, u64 wwid) 559 { 560 struct dev_mapping_table *mt_entry; 561 u8 missing_cnt, reason = element->ReasonCode; 562 u16 dpm_idx; 563 Mpi2DriverMap0Entry_t *dpm_entry; 564 565 if (!sc->is_dpm_enable) 566 return; 567 mt_entry = &sc->mapping_table[map_idx]; 568 if (reason == MPI2_EVENT_IR_CHANGE_RC_ADDED) { 569 mt_entry->missing_count = 0; 570 } else if (reason == MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED) { 571 mt_entry->missing_count = 0; 572 mt_entry->init_complete = 0; 573 } else if ((reason == MPI2_EVENT_IR_CHANGE_RC_REMOVED) || 574 (reason == MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED)) { 575 if (!mt_entry->init_complete) { 576 if (mt_entry->missing_count < MPS_MAX_MISSING_COUNT) 577 mt_entry->missing_count++; 578 else 579 mt_entry->init_complete = 1; 580 } 581 if (!mt_entry->missing_count) 582 mt_entry->missing_count++; 583 mt_entry->dev_handle = 0; 584 } 585 586 dpm_idx = mt_entry->dpm_entry_num; 587 if (dpm_idx == MPS_DPM_BAD_IDX) { 588 if ((reason == MPI2_EVENT_IR_CHANGE_RC_ADDED) || 589 (reason == MPI2_EVENT_IR_CHANGE_RC_REMOVED)) 590 dpm_idx = _mapping_get_dpm_idx_from_id(sc, 591 mt_entry->physical_id, 0); 592 else if (reason == MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED) 593 return; 594 } 595 if (dpm_idx != MPS_DPM_BAD_IDX) { 596 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *)sc->dpm_pg0 + 597 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 598 dpm_entry += dpm_idx; 599 missing_cnt = dpm_entry->MappingInformation & 600 MPI2_DRVMAP0_MAPINFO_MISSING_MASK; 601 if ((mt_entry->physical_id == 602 le64toh((u64)dpm_entry->PhysicalIdentifier.High | 603 dpm_entry->PhysicalIdentifier.Low)) && (missing_cnt == 604 mt_entry->missing_count)) 605 mt_entry->init_complete = 1; 606 } else { 607 dpm_idx = _mapping_get_free_dpm_idx(sc); 608 mt_entry->init_complete = 0; 609 } 610 611 if ((dpm_idx != MPS_DPM_BAD_IDX) && !mt_entry->init_complete) { 612 mt_entry->init_complete = 1; 613 mt_entry->dpm_entry_num = dpm_idx; 614 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *)sc->dpm_pg0 + 615 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 616 dpm_entry += dpm_idx; 617 dpm_entry->PhysicalIdentifier.Low = 618 (0xFFFFFFFF & mt_entry->physical_id); 619 dpm_entry->PhysicalIdentifier.High = 620 (mt_entry->physical_id >> 32); 621 dpm_entry->DeviceIndex = map_idx; 622 dpm_entry->MappingInformation = mt_entry->missing_count; 623 dpm_entry->PhysicalBitsMapping = 0; 624 dpm_entry->Reserved1 = 0; 625 sc->dpm_flush_entry[dpm_idx] = 1; 626 sc->dpm_entry_used[dpm_idx] = 1; 627 } else if (dpm_idx == MPS_DPM_BAD_IDX) { 628 kprintf("%s: no space to add entry in DPM table\n", __func__); 629 mt_entry->init_complete = 1; 630 } 631 } 632 633 /** 634 * _mapping_add_to_removal_table - mark an entry for removal 635 * @sc: per adapter object 636 * @handle: Handle of enclosures/device/volume 637 * 638 * Adds the handle or DPM entry number in removal table. 639 * 640 * Returns nothing. 641 */ 642 static void 643 _mapping_add_to_removal_table(struct mps_softc *sc, u16 handle, 644 u16 dpm_idx) 645 { 646 struct map_removal_table *remove_entry; 647 u32 i; 648 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 649 650 remove_entry = sc->removal_table; 651 652 for (i = 0; i < sc->max_devices; i++, remove_entry++) { 653 if (remove_entry->dev_handle || remove_entry->dpm_entry_num != 654 MPS_DPM_BAD_IDX) 655 continue; 656 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 657 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 658 if (dpm_idx) 659 remove_entry->dpm_entry_num = dpm_idx; 660 if (remove_entry->dpm_entry_num == MPS_DPM_BAD_IDX) 661 remove_entry->dev_handle = handle; 662 } else if ((ioc_pg8_flags & 663 MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 664 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) 665 remove_entry->dev_handle = handle; 666 break; 667 } 668 669 } 670 671 /** 672 * _mapping_update_missing_count - Update missing count for a device 673 * @sc: per adapter object 674 * @topo_change: Topology change event entry 675 * 676 * Search through the topology change list and if any device is found not 677 * responding it's associated map table entry and DPM entry is updated 678 * 679 * Returns nothing. 680 */ 681 static void 682 _mapping_update_missing_count(struct mps_softc *sc, 683 struct _map_topology_change *topo_change) 684 { 685 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 686 u8 entry; 687 struct _map_phy_change *phy_change; 688 u32 map_idx; 689 struct dev_mapping_table *mt_entry; 690 Mpi2DriverMap0Entry_t *dpm_entry; 691 692 for (entry = 0; entry < topo_change->num_entries; entry++) { 693 phy_change = &topo_change->phy_details[entry]; 694 if (!phy_change->dev_handle || (phy_change->reason != 695 MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)) 696 continue; 697 map_idx = _mapping_get_mt_idx_from_handle(sc, phy_change-> 698 dev_handle); 699 phy_change->is_processed = 1; 700 if (map_idx == MPS_MAPTABLE_BAD_IDX) { 701 kprintf("%s: device is already removed from mapping " 702 "table\n", __func__); 703 continue; 704 } 705 mt_entry = &sc->mapping_table[map_idx]; 706 if (!mt_entry->init_complete) { 707 if (mt_entry->missing_count < MPS_MAX_MISSING_COUNT) 708 mt_entry->missing_count++; 709 else 710 mt_entry->init_complete = 1; 711 } 712 if (!mt_entry->missing_count) 713 mt_entry->missing_count++; 714 _mapping_add_to_removal_table(sc, mt_entry->dev_handle, 0); 715 mt_entry->dev_handle = 0; 716 717 if (((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 718 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) && 719 sc->is_dpm_enable && !mt_entry->init_complete && 720 mt_entry->dpm_entry_num != MPS_DPM_BAD_IDX) { 721 dpm_entry = 722 (Mpi2DriverMap0Entry_t *) ((u8 *)sc->dpm_pg0 + 723 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 724 dpm_entry += mt_entry->dpm_entry_num; 725 dpm_entry->MappingInformation = mt_entry->missing_count; 726 sc->dpm_flush_entry[mt_entry->dpm_entry_num] = 1; 727 } 728 mt_entry->init_complete = 1; 729 } 730 } 731 732 /** 733 * _mapping_find_enc_map_space -find map table entries for enclosure 734 * @sc: per adapter object 735 * @et_entry: enclosure entry 736 * 737 * Search through the mapping table defragment it and provide contiguous 738 * space in map table for a particular enclosure entry 739 * 740 * Returns start index in map table or bad index. 741 */ 742 static u32 743 _mapping_find_enc_map_space(struct mps_softc *sc, 744 struct enc_mapping_table *et_entry) 745 { 746 u16 vol_mapping_flags; 747 u32 skip_count, end_of_table, map_idx, enc_idx; 748 u16 num_found; 749 u32 start_idx = MPS_MAPTABLE_BAD_IDX; 750 struct dev_mapping_table *mt_entry; 751 struct enc_mapping_table *enc_entry; 752 unsigned char done_flag = 0, found_space; 753 u16 max_num_phy_ids = le16toh(sc->ioc_pg8.MaxNumPhysicalMappedIDs); 754 755 skip_count = sc->num_rsvd_entries; 756 num_found = 0; 757 758 vol_mapping_flags = le16toh(sc->ioc_pg8.IRVolumeMappingFlags) & 759 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE; 760 761 if (!sc->ir_firmware) 762 end_of_table = sc->max_devices; 763 else if (vol_mapping_flags == MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING) 764 end_of_table = sc->max_devices; 765 else 766 end_of_table = sc->max_devices - sc->max_volumes; 767 768 for (map_idx = (max_num_phy_ids + skip_count); 769 map_idx < end_of_table; map_idx++) { 770 mt_entry = &sc->mapping_table[map_idx]; 771 if ((et_entry->enclosure_id == mt_entry->physical_id) && 772 (!mt_entry->phy_bits || (mt_entry->phy_bits & 773 et_entry->phy_bits))) { 774 num_found += 1; 775 if (num_found == et_entry->num_slots) { 776 start_idx = (map_idx - num_found) + 1; 777 return start_idx; 778 } 779 } else 780 num_found = 0; 781 } 782 for (map_idx = (max_num_phy_ids + skip_count); 783 map_idx < end_of_table; map_idx++) { 784 mt_entry = &sc->mapping_table[map_idx]; 785 if (!(mt_entry->device_info & MPS_DEV_RESERVED)) { 786 num_found += 1; 787 if (num_found == et_entry->num_slots) { 788 start_idx = (map_idx - num_found) + 1; 789 return start_idx; 790 } 791 } else 792 num_found = 0; 793 } 794 795 while (!done_flag) { 796 enc_idx = _mapping_get_high_missing_et_idx(sc); 797 if (enc_idx == MPS_ENCTABLE_BAD_IDX) 798 return MPS_MAPTABLE_BAD_IDX; 799 enc_entry = &sc->enclosure_table[enc_idx]; 800 /*VSP FIXME*/ 801 enc_entry->skip_search = 1; 802 mt_entry = &sc->mapping_table[enc_entry->start_index]; 803 for (map_idx = enc_entry->start_index; map_idx < 804 (enc_entry->start_index + enc_entry->num_slots); map_idx++, 805 mt_entry++) 806 mt_entry->device_info &= ~MPS_DEV_RESERVED; 807 found_space = 0; 808 for (map_idx = (max_num_phy_ids + 809 skip_count); map_idx < end_of_table; map_idx++) { 810 mt_entry = &sc->mapping_table[map_idx]; 811 if (!(mt_entry->device_info & MPS_DEV_RESERVED)) { 812 num_found += 1; 813 if (num_found == et_entry->num_slots) { 814 start_idx = (map_idx - num_found) + 1; 815 found_space = 1; 816 } 817 } else 818 num_found = 0; 819 } 820 821 if (!found_space) 822 continue; 823 for (map_idx = start_idx; map_idx < (start_idx + num_found); 824 map_idx++) { 825 enc_entry = sc->enclosure_table; 826 for (enc_idx = 0; enc_idx < sc->num_enc_table_entries; 827 enc_idx++, enc_entry++) { 828 if (map_idx < enc_entry->start_index || 829 map_idx > (enc_entry->start_index + 830 enc_entry->num_slots)) 831 continue; 832 if (!enc_entry->removal_flag) { 833 enc_entry->removal_flag = 1; 834 _mapping_add_to_removal_table(sc, 0, 835 enc_entry->dpm_entry_num); 836 } 837 mt_entry = &sc->mapping_table[map_idx]; 838 if (mt_entry->device_info & 839 MPS_MAP_IN_USE) { 840 _mapping_add_to_removal_table(sc, 841 mt_entry->dev_handle, 0); 842 _mapping_clear_map_entry(mt_entry); 843 } 844 if (map_idx == (enc_entry->start_index + 845 enc_entry->num_slots - 1)) 846 _mapping_clear_enc_entry(et_entry); 847 } 848 } 849 enc_entry = sc->enclosure_table; 850 for (enc_idx = 0; enc_idx < sc->num_enc_table_entries; 851 enc_idx++, enc_entry++) { 852 if (!enc_entry->removal_flag) { 853 mt_entry = &sc->mapping_table[enc_entry-> 854 start_index]; 855 for (map_idx = enc_entry->start_index; map_idx < 856 (enc_entry->start_index + 857 enc_entry->num_slots); map_idx++, 858 mt_entry++) 859 mt_entry->device_info |= 860 MPS_DEV_RESERVED; 861 et_entry->skip_search = 0; 862 } 863 } 864 done_flag = 1; 865 } 866 return start_idx; 867 } 868 869 /** 870 * _mapping_get_dev_info -get information about newly added devices 871 * @sc: per adapter object 872 * @topo_change: Topology change event entry 873 * 874 * Search through the topology change event list and issues sas device pg0 875 * requests for the newly added device and reserved entries in tables 876 * 877 * Returns nothing 878 */ 879 static void 880 _mapping_get_dev_info(struct mps_softc *sc, 881 struct _map_topology_change *topo_change) 882 { 883 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 884 Mpi2ConfigReply_t mpi_reply; 885 Mpi2SasDevicePage0_t sas_device_pg0; 886 u8 entry, enc_idx, phy_idx; 887 u32 map_idx, index, device_info; 888 struct _map_phy_change *phy_change, *tmp_phy_change; 889 uint64_t sas_address; 890 struct enc_mapping_table *et_entry; 891 struct dev_mapping_table *mt_entry; 892 u8 add_code = MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED; 893 int rc; 894 895 for (entry = 0; entry < topo_change->num_entries; entry++) { 896 phy_change = &topo_change->phy_details[entry]; 897 if (phy_change->is_processed || !phy_change->dev_handle || 898 phy_change->reason != MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED) 899 continue; 900 if (mps_config_get_sas_device_pg0(sc, &mpi_reply, 901 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, 902 phy_change->dev_handle)) { 903 phy_change->is_processed = 1; 904 continue; 905 } 906 907 device_info = le32toh(sas_device_pg0.DeviceInfo); 908 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 909 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) { 910 if ((device_info & MPI2_SAS_DEVICE_INFO_END_DEVICE) && 911 (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)) { 912 rc = mpssas_get_sas_address_for_sata_disk(sc, 913 &sas_address, phy_change->dev_handle, 914 device_info); 915 if (rc) { 916 kprintf("%s: failed to compute the " 917 "hashed SAS Address for SATA " 918 "device with handle 0x%04x\n", 919 __func__, phy_change->dev_handle); 920 sas_address = 921 sas_device_pg0.SASAddress.High; 922 sas_address = (sas_address << 32) | 923 sas_device_pg0.SASAddress.Low; 924 } 925 mps_dprint(sc, MPS_INFO, "SAS Address for SATA " 926 "device = %jx\n", sas_address); 927 } else { 928 sas_address = 929 sas_device_pg0.SASAddress.High; 930 sas_address = (sas_address << 32) | 931 sas_device_pg0.SASAddress.Low; 932 } 933 } else { 934 sas_address = sas_device_pg0.SASAddress.High; 935 sas_address = (sas_address << 32) | 936 sas_device_pg0.SASAddress.Low; 937 } 938 phy_change->physical_id = sas_address; 939 phy_change->slot = le16toh(sas_device_pg0.Slot); 940 phy_change->device_info = 941 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 kprintf("%s: failed to add the device with " 950 "handle 0x%04x because the enclosure is " 951 "not in the mapping table\n", __func__, 952 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 kprintf("%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 kprintf("%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 kprintf("%s: failed to add the " 1215 "device with handle 0x%04x " 1216 "to persistent table " 1217 "because there is no free " 1218 "space available\n", 1219 __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 kprintf("%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 kprintf("%s: failed to add the " 1317 "device with handle 0x%04x " 1318 "to persistent table " 1319 "because there is no free " 1320 "space available\n", 1321 __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 kprintf("%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 = kmalloc((sizeof(struct dev_mapping_table) * 1393 sc->max_devices), M_MPT2, M_ZERO|M_INTWAIT); 1394 if (!sc->mapping_table) 1395 goto free_resources; 1396 1397 sc->removal_table = kmalloc((sizeof(struct map_removal_table) * 1398 sc->max_devices), M_MPT2, M_ZERO|M_INTWAIT); 1399 if (!sc->removal_table) 1400 goto free_resources; 1401 1402 sc->enclosure_table = kmalloc((sizeof(struct enc_mapping_table) * 1403 sc->max_enclosures), M_MPT2, M_ZERO|M_INTWAIT); 1404 if (!sc->enclosure_table) 1405 goto free_resources; 1406 1407 sc->dpm_entry_used = kmalloc((sizeof(u8) * sc->max_dpm_entries), 1408 M_MPT2, M_ZERO|M_INTWAIT); 1409 if (!sc->dpm_entry_used) 1410 goto free_resources; 1411 1412 sc->dpm_flush_entry = kmalloc((sizeof(u8) * sc->max_dpm_entries), 1413 M_MPT2, M_ZERO|M_INTWAIT); 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 = kmalloc(dpm_pg0_sz, M_MPT2, M_ZERO|M_INTWAIT); 1421 if (!sc->dpm_pg0) { 1422 kprintf("%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 kfree(sc->mapping_table, M_MPT2); 1431 kfree(sc->removal_table, M_MPT2); 1432 kfree(sc->enclosure_table, M_MPT2); 1433 kfree(sc->dpm_entry_used, M_MPT2); 1434 kfree(sc->dpm_flush_entry, M_MPT2); 1435 kfree(sc->dpm_pg0, M_MPT2); 1436 kprintf("%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 kfree(sc->mapping_table, M_MPT2); 1451 kfree(sc->removal_table, M_MPT2); 1452 kfree(sc->enclosure_table, M_MPT2); 1453 kfree(sc->dpm_entry_used, M_MPT2); 1454 kfree(sc->dpm_flush_entry, M_MPT2); 1455 kfree(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 kprintf("%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 kprintf("%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 kprintf("%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 kprintf("%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 kprintf("%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 kprintf("%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 kprintf("%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 kprintf("%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 kprintf("%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 = kmalloc(sizeof(struct _map_phy_change) * num_entries, 2051 M_MPT2, M_INTWAIT|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 kfree(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 = kmalloc(sizeof(u64) * event_data->NumElements, M_MPT2, 2153 M_INTWAIT | 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 kprintf("%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 kprintf("%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 kprintf("%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 kfree(wwid_table, M_MPT2); 2263 if (sc->pending_map_events) 2264 sc->pending_map_events--; 2265 } 2266