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