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