1 /*- 2 * Copyright (c) 2011-2015 LSI Corp. 3 * Copyright (c) 2013-2016 Avago Technologies 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD 28 * 29 * $FreeBSD: head/sys/dev/mpr/mpr_mapping.c 328218 2018-01-21 15:42:36Z pfg $ 30 */ 31 32 /* TODO Move headers to mprvar */ 33 #include <sys/types.h> 34 #include <sys/param.h> 35 #include <sys/lock.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/mpr/mpi/mpi2_type.h> 47 #include <dev/raid/mpr/mpi/mpi2.h> 48 #include <dev/raid/mpr/mpi/mpi2_ioc.h> 49 #include <dev/raid/mpr/mpi/mpi2_sas.h> 50 #include <dev/raid/mpr/mpi/mpi2_pci.h> 51 #include <dev/raid/mpr/mpi/mpi2_cnfg.h> 52 #include <dev/raid/mpr/mpi/mpi2_init.h> 53 #include <dev/raid/mpr/mpi/mpi2_tool.h> 54 #include <dev/raid/mpr/mpr_ioctl.h> 55 #include <dev/raid/mpr/mprvar.h> 56 #include <dev/raid/mpr/mpr_mapping.h> 57 58 /** 59 * _mapping_clear_map_entry - Clear a particular mapping entry. 60 * @map_entry: map table entry 61 * 62 * Returns nothing. 63 */ 64 static inline void 65 _mapping_clear_map_entry(struct dev_mapping_table *map_entry) 66 { 67 map_entry->physical_id = 0; 68 map_entry->device_info = 0; 69 map_entry->phy_bits = 0; 70 map_entry->dpm_entry_num = MPR_DPM_BAD_IDX; 71 map_entry->dev_handle = 0; 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 = MPR_MAPTABLE_BAD_IDX; 89 enc_entry->phy_bits = 0; 90 enc_entry->dpm_entry_num = MPR_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 mpr_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 mpr_dprint(sc, MPR_MAPPING, "%s: Writing DPM entry %d for enclosure.\n", 139 __func__, et_entry->dpm_entry_num); 140 memcpy(&config_page.Entry, (u8 *)dpm_entry, 141 sizeof(Mpi2DriverMap0Entry_t)); 142 if (mpr_config_set_dpm_pg0(sc, &mpi_reply, &config_page, 143 et_entry->dpm_entry_num)) { 144 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: Write of DPM " 145 "entry %d for enclosure failed.\n", __func__, 146 et_entry->dpm_entry_num); 147 dpm_entry->MappingInformation = le16toh(dpm_entry-> 148 MappingInformation); 149 dpm_entry->DeviceIndex = le16toh(dpm_entry->DeviceIndex); 150 dpm_entry->PhysicalBitsMapping = 151 le32toh(dpm_entry->PhysicalBitsMapping); 152 return -1; 153 } 154 dpm_entry->MappingInformation = le16toh(dpm_entry-> 155 MappingInformation); 156 dpm_entry->DeviceIndex = le16toh(dpm_entry->DeviceIndex); 157 dpm_entry->PhysicalBitsMapping = 158 le32toh(dpm_entry->PhysicalBitsMapping); 159 return 0; 160 } 161 162 /** 163 * _mapping_commit_map_entry - write a particular map table entry in DPM page0. 164 * @sc: per adapter object 165 * @mt_entry: mapping table entry 166 * 167 * Returns 0 for success, non-zero for failure. 168 */ 169 170 static int 171 _mapping_commit_map_entry(struct mpr_softc *sc, 172 struct dev_mapping_table *mt_entry) 173 { 174 Mpi2DriverMap0Entry_t *dpm_entry; 175 Mpi2ConfigReply_t mpi_reply; 176 Mpi2DriverMappingPage0_t config_page; 177 178 if (!sc->is_dpm_enable) 179 return 0; 180 181 /* 182 * It's possible that this Map Entry points to a BAD DPM index. This 183 * can happen if the Map Entry is a for a missing device and the DPM 184 * entry that was being used by this device is now being used by some 185 * new device. So, check for a BAD DPM index and just return if so. 186 */ 187 if (mt_entry->dpm_entry_num == MPR_DPM_BAD_IDX) { 188 mpr_dprint(sc, MPR_MAPPING, "%s: DPM entry location for target " 189 "%d is invalid. DPM will not be written.\n", __func__, 190 mt_entry->id); 191 return 0; 192 } 193 194 memset(&config_page, 0, sizeof(Mpi2DriverMappingPage0_t)); 195 memcpy(&config_page.Header, (u8 *)sc->dpm_pg0, 196 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 197 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *) sc->dpm_pg0 + 198 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 199 dpm_entry = dpm_entry + mt_entry->dpm_entry_num; 200 dpm_entry->PhysicalIdentifier.Low = (0xFFFFFFFF & 201 mt_entry->physical_id); 202 dpm_entry->PhysicalIdentifier.High = (mt_entry->physical_id >> 32); 203 dpm_entry->DeviceIndex = htole16(mt_entry->id); 204 dpm_entry->MappingInformation = htole16(mt_entry->missing_count); 205 dpm_entry->PhysicalBitsMapping = 0; 206 dpm_entry->Reserved1 = 0; 207 memcpy(&config_page.Entry, (u8 *)dpm_entry, 208 sizeof(Mpi2DriverMap0Entry_t)); 209 210 mpr_dprint(sc, MPR_MAPPING, "%s: Writing DPM entry %d for target %d.\n", 211 __func__, mt_entry->dpm_entry_num, mt_entry->id); 212 if (mpr_config_set_dpm_pg0(sc, &mpi_reply, &config_page, 213 mt_entry->dpm_entry_num)) { 214 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: Write of DPM " 215 "entry %d for target %d failed.\n", __func__, 216 mt_entry->dpm_entry_num, mt_entry->id); 217 dpm_entry->MappingInformation = le16toh(dpm_entry-> 218 MappingInformation); 219 dpm_entry->DeviceIndex = le16toh(dpm_entry->DeviceIndex); 220 return -1; 221 } 222 223 dpm_entry->MappingInformation = le16toh(dpm_entry->MappingInformation); 224 dpm_entry->DeviceIndex = le16toh(dpm_entry->DeviceIndex); 225 return 0; 226 } 227 228 /** 229 * _mapping_get_ir_maprange - get start and end index for IR map range. 230 * @sc: per adapter object 231 * @start_idx: place holder for start index 232 * @end_idx: place holder for end index 233 * 234 * The IR volumes can be mapped either at start or end of the mapping table 235 * this function gets the detail of where IR volume mapping starts and ends 236 * in the device mapping table 237 * 238 * Returns nothing. 239 */ 240 static void 241 _mapping_get_ir_maprange(struct mpr_softc *sc, u32 *start_idx, u32 *end_idx) 242 { 243 u16 volume_mapping_flags; 244 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 245 246 volume_mapping_flags = le16toh(sc->ioc_pg8.IRVolumeMappingFlags) & 247 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE; 248 if (volume_mapping_flags == MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING) { 249 *start_idx = 0; 250 if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0) 251 *start_idx = 1; 252 } else 253 *start_idx = sc->max_devices - sc->max_volumes; 254 *end_idx = *start_idx + sc->max_volumes - 1; 255 } 256 257 /** 258 * _mapping_get_enc_idx_from_id - get enclosure index from enclosure ID 259 * @sc: per adapter object 260 * @enc_id: enclosure logical identifier 261 * 262 * Returns the index of enclosure entry on success or bad index. 263 */ 264 static u8 265 _mapping_get_enc_idx_from_id(struct mpr_softc *sc, u64 enc_id, 266 u64 phy_bits) 267 { 268 struct enc_mapping_table *et_entry; 269 u8 enc_idx = 0; 270 271 for (enc_idx = 0; enc_idx < sc->num_enc_table_entries; enc_idx++) { 272 et_entry = &sc->enclosure_table[enc_idx]; 273 if ((et_entry->enclosure_id == le64toh(enc_id)) && 274 (!et_entry->phy_bits || (et_entry->phy_bits & 275 le32toh(phy_bits)))) 276 return enc_idx; 277 } 278 return MPR_ENCTABLE_BAD_IDX; 279 } 280 281 /** 282 * _mapping_get_enc_idx_from_handle - get enclosure index from handle 283 * @sc: per adapter object 284 * @enc_id: enclosure handle 285 * 286 * Returns the index of enclosure entry on success or bad index. 287 */ 288 static u8 289 _mapping_get_enc_idx_from_handle(struct mpr_softc *sc, u16 handle) 290 { 291 struct enc_mapping_table *et_entry; 292 u8 enc_idx = 0; 293 294 for (enc_idx = 0; enc_idx < sc->num_enc_table_entries; enc_idx++) { 295 et_entry = &sc->enclosure_table[enc_idx]; 296 if (et_entry->missing_count) 297 continue; 298 if (et_entry->enc_handle == handle) 299 return enc_idx; 300 } 301 return MPR_ENCTABLE_BAD_IDX; 302 } 303 304 /** 305 * _mapping_get_high_missing_et_idx - get missing enclosure index 306 * @sc: per adapter object 307 * 308 * Search through the enclosure table and identifies the enclosure entry 309 * with high missing count and returns it's index 310 * 311 * Returns the index of enclosure entry on success or bad index. 312 */ 313 static u8 314 _mapping_get_high_missing_et_idx(struct mpr_softc *sc) 315 { 316 struct enc_mapping_table *et_entry; 317 u8 high_missing_count = 0; 318 u8 enc_idx, high_idx = MPR_ENCTABLE_BAD_IDX; 319 320 for (enc_idx = 0; enc_idx < sc->num_enc_table_entries; enc_idx++) { 321 et_entry = &sc->enclosure_table[enc_idx]; 322 if ((et_entry->missing_count > high_missing_count) && 323 !et_entry->skip_search) { 324 high_missing_count = et_entry->missing_count; 325 high_idx = enc_idx; 326 } 327 } 328 return high_idx; 329 } 330 331 /** 332 * _mapping_get_high_missing_mt_idx - get missing map table index 333 * @sc: per adapter object 334 * 335 * Search through the map table and identifies the device entry 336 * with high missing count and returns it's index 337 * 338 * Returns the index of map table entry on success or bad index. 339 */ 340 static u32 341 _mapping_get_high_missing_mt_idx(struct mpr_softc *sc) 342 { 343 u32 map_idx, high_idx = MPR_MAPTABLE_BAD_IDX; 344 u8 high_missing_count = 0; 345 u32 start_idx, end_idx, start_idx_ir, end_idx_ir; 346 struct dev_mapping_table *mt_entry; 347 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 348 349 start_idx = 0; 350 start_idx_ir = 0; 351 end_idx_ir = 0; 352 end_idx = sc->max_devices; 353 if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0) 354 start_idx = 1; 355 if (sc->ir_firmware) { 356 _mapping_get_ir_maprange(sc, &start_idx_ir, &end_idx_ir); 357 if (start_idx == start_idx_ir) 358 start_idx = end_idx_ir + 1; 359 else 360 end_idx = start_idx_ir; 361 } 362 mt_entry = &sc->mapping_table[start_idx]; 363 for (map_idx = start_idx; map_idx < end_idx; map_idx++, mt_entry++) { 364 if (mt_entry->missing_count > high_missing_count) { 365 high_missing_count = mt_entry->missing_count; 366 high_idx = map_idx; 367 } 368 } 369 return high_idx; 370 } 371 372 /** 373 * _mapping_get_ir_mt_idx_from_wwid - get map table index from volume WWID 374 * @sc: per adapter object 375 * @wwid: world wide unique ID of the volume 376 * 377 * Returns the index of map table entry on success or bad index. 378 */ 379 static u32 380 _mapping_get_ir_mt_idx_from_wwid(struct mpr_softc *sc, u64 wwid) 381 { 382 u32 start_idx, end_idx, map_idx; 383 struct dev_mapping_table *mt_entry; 384 385 _mapping_get_ir_maprange(sc, &start_idx, &end_idx); 386 mt_entry = &sc->mapping_table[start_idx]; 387 for (map_idx = start_idx; map_idx <= end_idx; map_idx++, mt_entry++) 388 if (mt_entry->physical_id == wwid) 389 return map_idx; 390 391 return MPR_MAPTABLE_BAD_IDX; 392 } 393 394 /** 395 * _mapping_get_mt_idx_from_id - get map table index from a device ID 396 * @sc: per adapter object 397 * @dev_id: device identifer (SAS Address) 398 * 399 * Returns the index of map table entry on success or bad index. 400 */ 401 static u32 402 _mapping_get_mt_idx_from_id(struct mpr_softc *sc, u64 dev_id) 403 { 404 u32 map_idx; 405 struct dev_mapping_table *mt_entry; 406 407 for (map_idx = 0; map_idx < sc->max_devices; map_idx++) { 408 mt_entry = &sc->mapping_table[map_idx]; 409 if (mt_entry->physical_id == dev_id) 410 return map_idx; 411 } 412 return MPR_MAPTABLE_BAD_IDX; 413 } 414 415 /** 416 * _mapping_get_ir_mt_idx_from_handle - get map table index from volume handle 417 * @sc: per adapter object 418 * @wwid: volume device handle 419 * 420 * Returns the index of map table entry on success or bad index. 421 */ 422 static u32 423 _mapping_get_ir_mt_idx_from_handle(struct mpr_softc *sc, u16 volHandle) 424 { 425 u32 start_idx, end_idx, map_idx; 426 struct dev_mapping_table *mt_entry; 427 428 _mapping_get_ir_maprange(sc, &start_idx, &end_idx); 429 mt_entry = &sc->mapping_table[start_idx]; 430 for (map_idx = start_idx; map_idx <= end_idx; map_idx++, mt_entry++) 431 if (mt_entry->dev_handle == volHandle) 432 return map_idx; 433 434 return MPR_MAPTABLE_BAD_IDX; 435 } 436 437 /** 438 * _mapping_get_mt_idx_from_handle - get map table index from handle 439 * @sc: per adapter object 440 * @dev_id: device handle 441 * 442 * Returns the index of map table entry on success or bad index. 443 */ 444 static u32 445 _mapping_get_mt_idx_from_handle(struct mpr_softc *sc, u16 handle) 446 { 447 u32 map_idx; 448 struct dev_mapping_table *mt_entry; 449 450 for (map_idx = 0; map_idx < sc->max_devices; map_idx++) { 451 mt_entry = &sc->mapping_table[map_idx]; 452 if (mt_entry->dev_handle == handle) 453 return map_idx; 454 } 455 return MPR_MAPTABLE_BAD_IDX; 456 } 457 458 /** 459 * _mapping_get_free_ir_mt_idx - get first free index for a volume 460 * @sc: per adapter object 461 * 462 * Search through mapping table for free index for a volume and if no free 463 * index then looks for a volume with high mapping index 464 * 465 * Returns the index of map table entry on success or bad index. 466 */ 467 static u32 468 _mapping_get_free_ir_mt_idx(struct mpr_softc *sc) 469 { 470 u8 high_missing_count = 0; 471 u32 start_idx, end_idx, map_idx; 472 u32 high_idx = MPR_MAPTABLE_BAD_IDX; 473 struct dev_mapping_table *mt_entry; 474 475 /* 476 * The IN_USE flag should be clear if the entry is available to use. 477 * This flag is cleared on initialization and and when a volume is 478 * deleted. All other times this flag should be set. If, for some 479 * reason, a free entry cannot be found, look for the entry with the 480 * highest missing count just in case there is one. 481 */ 482 _mapping_get_ir_maprange(sc, &start_idx, &end_idx); 483 mt_entry = &sc->mapping_table[start_idx]; 484 for (map_idx = start_idx; map_idx <= end_idx; map_idx++, mt_entry++) { 485 if (!(mt_entry->device_info & MPR_MAP_IN_USE)) 486 return map_idx; 487 488 if (mt_entry->missing_count > high_missing_count) { 489 high_missing_count = mt_entry->missing_count; 490 high_idx = map_idx; 491 } 492 } 493 494 if (high_idx == MPR_MAPTABLE_BAD_IDX) { 495 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: Could not find a " 496 "free entry in the mapping table for a Volume. The mapping " 497 "table is probably corrupt.\n", __func__); 498 } 499 500 return high_idx; 501 } 502 503 /** 504 * _mapping_get_free_mt_idx - get first free index for a device 505 * @sc: per adapter object 506 * @start_idx: offset in the table to start search 507 * 508 * Returns the index of map table entry on success or bad index. 509 */ 510 static u32 511 _mapping_get_free_mt_idx(struct mpr_softc *sc, u32 start_idx) 512 { 513 u32 map_idx, max_idx = sc->max_devices; 514 struct dev_mapping_table *mt_entry = &sc->mapping_table[start_idx]; 515 u16 volume_mapping_flags; 516 517 volume_mapping_flags = le16toh(sc->ioc_pg8.IRVolumeMappingFlags) & 518 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE; 519 if (sc->ir_firmware && (volume_mapping_flags == 520 MPI2_IOCPAGE8_IRFLAGS_HIGH_VOLUME_MAPPING)) 521 max_idx -= sc->max_volumes; 522 523 for (map_idx = start_idx; map_idx < max_idx; map_idx++, mt_entry++) 524 if (!(mt_entry->device_info & (MPR_MAP_IN_USE | 525 MPR_DEV_RESERVED))) 526 return map_idx; 527 528 return MPR_MAPTABLE_BAD_IDX; 529 } 530 531 /** 532 * _mapping_get_dpm_idx_from_id - get DPM index from ID 533 * @sc: per adapter object 534 * @id: volume WWID or enclosure ID or device ID 535 * 536 * Returns the index of DPM entry on success or bad index. 537 */ 538 static u16 539 _mapping_get_dpm_idx_from_id(struct mpr_softc *sc, u64 id, u32 phy_bits) 540 { 541 u16 entry_num; 542 uint64_t PhysicalIdentifier; 543 Mpi2DriverMap0Entry_t *dpm_entry; 544 545 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *)sc->dpm_pg0 + 546 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 547 PhysicalIdentifier = dpm_entry->PhysicalIdentifier.High; 548 PhysicalIdentifier = (PhysicalIdentifier << 32) | 549 dpm_entry->PhysicalIdentifier.Low; 550 for (entry_num = 0; entry_num < sc->max_dpm_entries; entry_num++, 551 dpm_entry++) 552 if ((id == PhysicalIdentifier) && 553 (!phy_bits || !dpm_entry->PhysicalBitsMapping || 554 (phy_bits & dpm_entry->PhysicalBitsMapping))) 555 return entry_num; 556 557 return MPR_DPM_BAD_IDX; 558 } 559 560 561 /** 562 * _mapping_get_free_dpm_idx - get first available DPM index 563 * @sc: per adapter object 564 * 565 * Returns the index of DPM entry on success or bad index. 566 */ 567 static u32 568 _mapping_get_free_dpm_idx(struct mpr_softc *sc) 569 { 570 u16 entry_num; 571 Mpi2DriverMap0Entry_t *dpm_entry; 572 u16 current_entry = MPR_DPM_BAD_IDX, missing_cnt, high_missing_cnt = 0; 573 u64 physical_id; 574 struct dev_mapping_table *mt_entry; 575 u32 map_idx; 576 577 for (entry_num = 0; entry_num < sc->max_dpm_entries; entry_num++) { 578 dpm_entry = (Mpi2DriverMap0Entry_t *) ((u8 *)sc->dpm_pg0 + 579 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 580 dpm_entry += entry_num; 581 missing_cnt = dpm_entry->MappingInformation & 582 MPI2_DRVMAP0_MAPINFO_MISSING_MASK; 583 584 /* 585 * If entry is used and not missing, then this entry can't be 586 * used. Look at next one. 587 */ 588 if (sc->dpm_entry_used[entry_num] && !missing_cnt) 589 continue; 590 591 /* 592 * If this entry is not used at all, then the missing count 593 * doesn't matter. Just use this one. Otherwise, keep looking 594 * and make sure the entry with the highest missing count is 595 * used. 596 */ 597 if (!sc->dpm_entry_used[entry_num]) { 598 current_entry = entry_num; 599 break; 600 } 601 if ((current_entry == MPR_DPM_BAD_IDX) || 602 (missing_cnt > high_missing_cnt)) { 603 current_entry = entry_num; 604 high_missing_cnt = missing_cnt; 605 } 606 } 607 608 /* 609 * If an entry has been found to use and it's already marked as used 610 * it means that some device was already using this entry but it's 611 * missing, and that means that the connection between the missing 612 * device's DPM entry and the mapping table needs to be cleared. To do 613 * this, use the Physical ID of the old device still in the DPM entry 614 * to find its mapping table entry, then mark its DPM entry as BAD. 615 */ 616 if ((current_entry != MPR_DPM_BAD_IDX) && 617 sc->dpm_entry_used[current_entry]) { 618 dpm_entry = (Mpi2DriverMap0Entry_t *) ((u8 *)sc->dpm_pg0 + 619 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 620 dpm_entry += current_entry; 621 physical_id = dpm_entry->PhysicalIdentifier.High; 622 physical_id = (physical_id << 32) | 623 dpm_entry->PhysicalIdentifier.Low; 624 map_idx = _mapping_get_mt_idx_from_id(sc, physical_id); 625 if (map_idx != MPR_MAPTABLE_BAD_IDX) { 626 mt_entry = &sc->mapping_table[map_idx]; 627 mt_entry->dpm_entry_num = MPR_DPM_BAD_IDX; 628 } 629 } 630 return current_entry; 631 } 632 633 /** 634 * _mapping_update_ir_missing_cnt - Updates missing count for a volume 635 * @sc: per adapter object 636 * @map_idx: map table index of the volume 637 * @element: IR configuration change element 638 * @wwid: IR volume ID. 639 * 640 * Updates the missing count in the map table and in the DPM entry for a volume 641 * 642 * Returns nothing. 643 */ 644 static void 645 _mapping_update_ir_missing_cnt(struct mpr_softc *sc, u32 map_idx, 646 Mpi2EventIrConfigElement_t *element, u64 wwid) 647 { 648 struct dev_mapping_table *mt_entry; 649 u8 missing_cnt, reason = element->ReasonCode, update_dpm = 1; 650 u16 dpm_idx; 651 Mpi2DriverMap0Entry_t *dpm_entry; 652 653 /* 654 * Depending on the reason code, update the missing count. Always set 655 * the init_complete flag when here, so just do it first. That flag is 656 * used for volumes to make sure that the DPM entry has been updated. 657 * When a volume is deleted, clear the map entry's IN_USE flag so that 658 * the entry can be used again if another volume is created. Also clear 659 * its dev_handle entry so that other functions can't find this volume 660 * by the handle, since it's not defined any longer. 661 */ 662 mt_entry = &sc->mapping_table[map_idx]; 663 mt_entry->init_complete = 1; 664 if ((reason == MPI2_EVENT_IR_CHANGE_RC_ADDED) || 665 (reason == MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED)) { 666 mt_entry->missing_count = 0; 667 } else if (reason == MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED) { 668 if (mt_entry->missing_count < MPR_MAX_MISSING_COUNT) 669 mt_entry->missing_count++; 670 671 mt_entry->device_info &= ~MPR_MAP_IN_USE; 672 mt_entry->dev_handle = 0; 673 } 674 675 /* 676 * If persistent mapping is enabled, update the DPM with the new missing 677 * count for the volume. If the DPM index is bad, get a free one. If 678 * it's bad for a volume that's being deleted do nothing because that 679 * volume doesn't have a DPM entry. 680 */ 681 if (!sc->is_dpm_enable) 682 return; 683 dpm_idx = mt_entry->dpm_entry_num; 684 if (dpm_idx == MPR_DPM_BAD_IDX) { 685 if (reason == MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED) 686 { 687 mpr_dprint(sc, MPR_MAPPING, "%s: Volume being deleted " 688 "is not in DPM so DPM missing count will not be " 689 "updated.\n", __func__); 690 return; 691 } 692 } 693 if (dpm_idx == MPR_DPM_BAD_IDX) 694 dpm_idx = _mapping_get_free_dpm_idx(sc); 695 696 /* 697 * Got the DPM entry for the volume or found a free DPM entry if this is 698 * a new volume. Check if the current information is outdated. 699 */ 700 if (dpm_idx != MPR_DPM_BAD_IDX) { 701 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *)sc->dpm_pg0 + 702 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 703 dpm_entry += dpm_idx; 704 missing_cnt = dpm_entry->MappingInformation & 705 MPI2_DRVMAP0_MAPINFO_MISSING_MASK; 706 if ((mt_entry->physical_id == 707 le64toh(((u64)dpm_entry->PhysicalIdentifier.High << 32) | 708 (u64)dpm_entry->PhysicalIdentifier.Low)) && (missing_cnt == 709 mt_entry->missing_count)) { 710 mpr_dprint(sc, MPR_MAPPING, "%s: DPM entry for volume " 711 "with target ID %d does not require an update.\n", 712 __func__, mt_entry->id); 713 update_dpm = 0; 714 } 715 } 716 717 /* 718 * Update the volume's persistent info if it's new or the ID or missing 719 * count has changed. If a good DPM index has not been found by now, 720 * there is no space left in the DPM table. 721 */ 722 if ((dpm_idx != MPR_DPM_BAD_IDX) && update_dpm) { 723 mpr_dprint(sc, MPR_MAPPING, "%s: Update DPM entry for volume " 724 "with target ID %d.\n", __func__, mt_entry->id); 725 mt_entry->dpm_entry_num = dpm_idx; 726 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *)sc->dpm_pg0 + 727 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 728 dpm_entry += dpm_idx; 729 dpm_entry->PhysicalIdentifier.Low = 730 (0xFFFFFFFF & mt_entry->physical_id); 731 dpm_entry->PhysicalIdentifier.High = 732 (mt_entry->physical_id >> 32); 733 dpm_entry->DeviceIndex = map_idx; 734 dpm_entry->MappingInformation = mt_entry->missing_count; 735 dpm_entry->PhysicalBitsMapping = 0; 736 dpm_entry->Reserved1 = 0; 737 sc->dpm_flush_entry[dpm_idx] = 1; 738 sc->dpm_entry_used[dpm_idx] = 1; 739 } else if (dpm_idx == MPR_DPM_BAD_IDX) { 740 mpr_dprint(sc, MPR_INFO | MPR_MAPPING, "%s: No space to add an " 741 "entry in the DPM table for volume with target ID %d.\n", 742 __func__, mt_entry->id); 743 } 744 } 745 746 /** 747 * _mapping_add_to_removal_table - add DPM index to the removal table 748 * @sc: per adapter object 749 * @dpm_idx: Index of DPM entry to remove 750 * 751 * Adds a DPM entry number to the removal table. 752 * 753 * Returns nothing. 754 */ 755 static void 756 _mapping_add_to_removal_table(struct mpr_softc *sc, u16 dpm_idx) 757 { 758 struct map_removal_table *remove_entry; 759 u32 i; 760 761 /* 762 * This is only used to remove entries from the DPM in the controller. 763 * If DPM is not enabled, just return. 764 */ 765 if (!sc->is_dpm_enable) 766 return; 767 768 /* 769 * Find the first available removal_table entry and add the new entry 770 * there. 771 */ 772 remove_entry = sc->removal_table; 773 for (i = 0; i < sc->max_devices; i++, remove_entry++) { 774 if (remove_entry->dpm_entry_num != MPR_DPM_BAD_IDX) 775 continue; 776 777 mpr_dprint(sc, MPR_MAPPING, "%s: Adding DPM entry %d to table " 778 "for removal.\n", __func__, dpm_idx); 779 remove_entry->dpm_entry_num = dpm_idx; 780 break; 781 } 782 783 } 784 785 /** 786 * _mapping_inc_missing_count 787 * @sc: per adapter object 788 * @map_idx: index into the mapping table for the device that is missing 789 * 790 * Increment the missing count in the mapping table for a SAS, SATA, or PCIe 791 * device that is not responding. If Persitent Mapping is used, increment the 792 * DPM entry as well. Currently, this function is only called if the target 793 * goes missing, so after initialization has completed. This means that the 794 * missing count can only go from 0 to 1 here. The missing count is incremented 795 * during initialization as well, so that's where a target's missing count can 796 * go past 1. 797 * 798 * Returns nothing. 799 */ 800 static void 801 _mapping_inc_missing_count(struct mpr_softc *sc, u32 map_idx) 802 { 803 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 804 struct dev_mapping_table *mt_entry; 805 Mpi2DriverMap0Entry_t *dpm_entry; 806 807 if (map_idx == MPR_MAPTABLE_BAD_IDX) { 808 mpr_dprint(sc, MPR_INFO | MPR_MAPPING, "%s: device is already " 809 "removed from mapping table\n", __func__); 810 return; 811 } 812 mt_entry = &sc->mapping_table[map_idx]; 813 if (mt_entry->missing_count < MPR_MAX_MISSING_COUNT) 814 mt_entry->missing_count++; 815 816 /* 817 * When using Enc/Slot mapping, when a device is removed, it's mapping 818 * table information should be cleared. Otherwise, the target ID will 819 * be incorrect if this same device is re-added to a different slot. 820 */ 821 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 822 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 823 _mapping_clear_map_entry(mt_entry); 824 } 825 826 /* 827 * When using device mapping, update the missing count in the DPM entry, 828 * but only if the missing count has changed. 829 */ 830 if (((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 831 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) && 832 sc->is_dpm_enable && 833 mt_entry->dpm_entry_num != MPR_DPM_BAD_IDX) { 834 dpm_entry = (Mpi2DriverMap0Entry_t *) ((u8 *)sc->dpm_pg0 + 835 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 836 dpm_entry += mt_entry->dpm_entry_num; 837 if (dpm_entry->MappingInformation != mt_entry->missing_count) { 838 dpm_entry->MappingInformation = mt_entry->missing_count; 839 sc->dpm_flush_entry[mt_entry->dpm_entry_num] = 1; 840 } 841 } 842 } 843 844 /** 845 * _mapping_update_missing_count - Update missing count for a device 846 * @sc: per adapter object 847 * @topo_change: Topology change event entry 848 * 849 * Search through the topology change list and if any device is found not 850 * responding it's associated map table entry and DPM entry is updated 851 * 852 * Returns nothing. 853 */ 854 static void 855 _mapping_update_missing_count(struct mpr_softc *sc, 856 struct _map_topology_change *topo_change) 857 { 858 u8 entry; 859 struct _map_phy_change *phy_change; 860 u32 map_idx; 861 862 for (entry = 0; entry < topo_change->num_entries; entry++) { 863 phy_change = &topo_change->phy_details[entry]; 864 if (!phy_change->dev_handle || (phy_change->reason != 865 MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)) 866 continue; 867 map_idx = _mapping_get_mt_idx_from_handle(sc, phy_change-> 868 dev_handle); 869 phy_change->is_processed = 1; 870 _mapping_inc_missing_count(sc, map_idx); 871 } 872 } 873 874 /** 875 * _mapping_update_pcie_missing_count - Update missing count for a PCIe device 876 * @sc: per adapter object 877 * @topo_change: Topology change event entry 878 * 879 * Search through the PCIe topology change list and if any device is found not 880 * responding it's associated map table entry and DPM entry is updated 881 * 882 * Returns nothing. 883 */ 884 static void 885 _mapping_update_pcie_missing_count(struct mpr_softc *sc, 886 struct _map_pcie_topology_change *topo_change) 887 { 888 u8 entry; 889 struct _map_port_change *port_change; 890 u32 map_idx; 891 892 for (entry = 0; entry < topo_change->num_entries; entry++) { 893 port_change = &topo_change->port_details[entry]; 894 if (!port_change->dev_handle || (port_change->reason != 895 MPI26_EVENT_PCIE_TOPO_PS_NOT_RESPONDING)) 896 continue; 897 map_idx = _mapping_get_mt_idx_from_handle(sc, port_change-> 898 dev_handle); 899 port_change->is_processed = 1; 900 _mapping_inc_missing_count(sc, map_idx); 901 } 902 } 903 904 /** 905 * _mapping_find_enc_map_space -find map table entries for enclosure 906 * @sc: per adapter object 907 * @et_entry: enclosure entry 908 * 909 * Search through the mapping table defragment it and provide contiguous 910 * space in map table for a particular enclosure entry 911 * 912 * Returns start index in map table or bad index. 913 */ 914 static u32 915 _mapping_find_enc_map_space(struct mpr_softc *sc, 916 struct enc_mapping_table *et_entry) 917 { 918 u16 vol_mapping_flags; 919 u32 skip_count, end_of_table, map_idx, enc_idx; 920 u16 num_found; 921 u32 start_idx = MPR_MAPTABLE_BAD_IDX; 922 struct dev_mapping_table *mt_entry; 923 struct enc_mapping_table *enc_entry; 924 unsigned char done_flag = 0, found_space; 925 u16 max_num_phy_ids = le16toh(sc->ioc_pg8.MaxNumPhysicalMappedIDs); 926 927 skip_count = sc->num_rsvd_entries; 928 num_found = 0; 929 930 vol_mapping_flags = le16toh(sc->ioc_pg8.IRVolumeMappingFlags) & 931 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE; 932 933 /* 934 * The end of the mapping table depends on where volumes are kept, if 935 * IR is enabled. 936 */ 937 if (!sc->ir_firmware) 938 end_of_table = sc->max_devices; 939 else if (vol_mapping_flags == MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING) 940 end_of_table = sc->max_devices; 941 else 942 end_of_table = sc->max_devices - sc->max_volumes; 943 944 /* 945 * The skip_count is the number of entries that are reserved at the 946 * beginning of the mapping table. But, it does not include the number 947 * of Physical IDs that are reserved for direct attached devices. Look 948 * through the mapping table after these reserved entries to see if 949 * the devices for this enclosure are already mapped. The PHY bit check 950 * is used to make sure that at least one PHY bit is common between the 951 * enclosure and the device that is already mapped. 952 */ 953 mpr_dprint(sc, MPR_MAPPING, "%s: Looking for space in the mapping " 954 "table for added enclosure.\n", __func__); 955 for (map_idx = (max_num_phy_ids + skip_count); 956 map_idx < end_of_table; map_idx++) { 957 mt_entry = &sc->mapping_table[map_idx]; 958 if ((et_entry->enclosure_id == mt_entry->physical_id) && 959 (!mt_entry->phy_bits || (mt_entry->phy_bits & 960 et_entry->phy_bits))) { 961 num_found += 1; 962 if (num_found == et_entry->num_slots) { 963 start_idx = (map_idx - num_found) + 1; 964 mpr_dprint(sc, MPR_MAPPING, "%s: Found space " 965 "in the mapping for enclosure at map index " 966 "%d.\n", __func__, start_idx); 967 return start_idx; 968 } 969 } else 970 num_found = 0; 971 } 972 973 /* 974 * If the enclosure's devices are not mapped already, look for 975 * contiguous entries in the mapping table that are not reserved. If 976 * enough entries are found, return the starting index for that space. 977 */ 978 num_found = 0; 979 for (map_idx = (max_num_phy_ids + skip_count); 980 map_idx < end_of_table; map_idx++) { 981 mt_entry = &sc->mapping_table[map_idx]; 982 if (!(mt_entry->device_info & MPR_DEV_RESERVED)) { 983 num_found += 1; 984 if (num_found == et_entry->num_slots) { 985 start_idx = (map_idx - num_found) + 1; 986 mpr_dprint(sc, MPR_MAPPING, "%s: Found space " 987 "in the mapping for enclosure at map index " 988 "%d.\n", __func__, start_idx); 989 return start_idx; 990 } 991 } else 992 num_found = 0; 993 } 994 995 /* 996 * If here, it means that not enough space in the mapping table was 997 * found to support this enclosure, so go through the enclosure table to 998 * see if any enclosure entries have a missing count. If so, get the 999 * enclosure with the highest missing count and check it to see if there 1000 * is enough space for the new enclosure. 1001 */ 1002 while (!done_flag) { 1003 enc_idx = _mapping_get_high_missing_et_idx(sc); 1004 if (enc_idx == MPR_ENCTABLE_BAD_IDX) { 1005 mpr_dprint(sc, MPR_MAPPING, "%s: Not enough space was " 1006 "found in the mapping for the added enclosure.\n", 1007 __func__); 1008 return MPR_MAPTABLE_BAD_IDX; 1009 } 1010 1011 /* 1012 * Found a missing enclosure. Set the skip_search flag so this 1013 * enclosure is not checked again for a high missing count if 1014 * the loop continues. This way, all missing enclosures can 1015 * have their space added together to find enough space in the 1016 * mapping table for the added enclosure. The space must be 1017 * contiguous. 1018 */ 1019 mpr_dprint(sc, MPR_MAPPING, "%s: Space from a missing " 1020 "enclosure was found.\n", __func__); 1021 enc_entry = &sc->enclosure_table[enc_idx]; 1022 enc_entry->skip_search = 1; 1023 1024 /* 1025 * Unmark all of the missing enclosure's device's reserved 1026 * space. These will be remarked as reserved if this missing 1027 * enclosure's space is not used. 1028 */ 1029 mpr_dprint(sc, MPR_MAPPING, "%s: Clear the reserved flag for " 1030 "all of the map entries for the enclosure.\n", __func__); 1031 mt_entry = &sc->mapping_table[enc_entry->start_index]; 1032 for (map_idx = enc_entry->start_index; map_idx < 1033 (enc_entry->start_index + enc_entry->num_slots); map_idx++, 1034 mt_entry++) 1035 mt_entry->device_info &= ~MPR_DEV_RESERVED; 1036 1037 /* 1038 * Now that space has been unreserved, check again to see if 1039 * enough space is available for the new enclosure. 1040 */ 1041 mpr_dprint(sc, MPR_MAPPING, "%s: Check if new mapping space is " 1042 "enough for the new enclosure.\n", __func__); 1043 found_space = 0; 1044 num_found = 0; 1045 for (map_idx = (max_num_phy_ids + skip_count); 1046 map_idx < end_of_table; map_idx++) { 1047 mt_entry = &sc->mapping_table[map_idx]; 1048 if (!(mt_entry->device_info & MPR_DEV_RESERVED)) { 1049 num_found += 1; 1050 if (num_found == et_entry->num_slots) { 1051 start_idx = (map_idx - num_found) + 1; 1052 found_space = 1; 1053 break; 1054 } 1055 } else 1056 num_found = 0; 1057 } 1058 if (!found_space) 1059 continue; 1060 1061 /* 1062 * If enough space was found, all of the missing enclosures that 1063 * will be used for the new enclosure must be added to the 1064 * removal table. Then all mappings for the enclosure's devices 1065 * and for the enclosure itself need to be cleared. There may be 1066 * more than one enclosure to add to the removal table and 1067 * clear. 1068 */ 1069 mpr_dprint(sc, MPR_MAPPING, "%s: Found space in the mapping " 1070 "for enclosure at map index %d.\n", __func__, start_idx); 1071 for (map_idx = start_idx; map_idx < (start_idx + num_found); 1072 map_idx++) { 1073 enc_entry = sc->enclosure_table; 1074 for (enc_idx = 0; enc_idx < sc->num_enc_table_entries; 1075 enc_idx++, enc_entry++) { 1076 if (map_idx < enc_entry->start_index || 1077 map_idx > (enc_entry->start_index + 1078 enc_entry->num_slots)) 1079 continue; 1080 if (!enc_entry->removal_flag) { 1081 mpr_dprint(sc, MPR_MAPPING, "%s: " 1082 "Enclosure %d will be removed from " 1083 "the mapping table.\n", __func__, 1084 enc_idx); 1085 enc_entry->removal_flag = 1; 1086 _mapping_add_to_removal_table(sc, 1087 enc_entry->dpm_entry_num); 1088 } 1089 mt_entry = &sc->mapping_table[map_idx]; 1090 _mapping_clear_map_entry(mt_entry); 1091 if (map_idx == (enc_entry->start_index + 1092 enc_entry->num_slots - 1)) 1093 _mapping_clear_enc_entry(et_entry); 1094 } 1095 } 1096 1097 /* 1098 * During the search for space for this enclosure, some entries 1099 * in the mapping table may have been unreserved. Go back and 1100 * change all of these to reserved again. Only the enclosures 1101 * with the removal_flag set should be left as unreserved. The 1102 * skip_search flag needs to be cleared as well so that the 1103 * enclosure's space will be looked at the next time space is 1104 * needed. 1105 */ 1106 enc_entry = sc->enclosure_table; 1107 for (enc_idx = 0; enc_idx < sc->num_enc_table_entries; 1108 enc_idx++, enc_entry++) { 1109 if (!enc_entry->removal_flag) { 1110 mpr_dprint(sc, MPR_MAPPING, "%s: Reset the " 1111 "reserved flag for all of the map entries " 1112 "for enclosure %d.\n", __func__, enc_idx); 1113 mt_entry = &sc->mapping_table[enc_entry-> 1114 start_index]; 1115 for (map_idx = enc_entry->start_index; map_idx < 1116 (enc_entry->start_index + 1117 enc_entry->num_slots); map_idx++, 1118 mt_entry++) 1119 mt_entry->device_info |= 1120 MPR_DEV_RESERVED; 1121 et_entry->skip_search = 0; 1122 } 1123 } 1124 done_flag = 1; 1125 } 1126 return start_idx; 1127 } 1128 1129 /** 1130 * _mapping_get_dev_info -get information about newly added devices 1131 * @sc: per adapter object 1132 * @topo_change: Topology change event entry 1133 * 1134 * Search through the topology change event list and issues sas device pg0 1135 * requests for the newly added device and reserved entries in tables 1136 * 1137 * Returns nothing 1138 */ 1139 static void 1140 _mapping_get_dev_info(struct mpr_softc *sc, 1141 struct _map_topology_change *topo_change) 1142 { 1143 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 1144 Mpi2ConfigReply_t mpi_reply; 1145 Mpi2SasDevicePage0_t sas_device_pg0; 1146 u8 entry, enc_idx, phy_idx; 1147 u32 map_idx, index, device_info; 1148 struct _map_phy_change *phy_change, *tmp_phy_change; 1149 uint64_t sas_address; 1150 struct enc_mapping_table *et_entry; 1151 struct dev_mapping_table *mt_entry; 1152 u8 add_code = MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED; 1153 int rc = 1; 1154 1155 for (entry = 0; entry < topo_change->num_entries; entry++) { 1156 phy_change = &topo_change->phy_details[entry]; 1157 if (phy_change->is_processed || !phy_change->dev_handle || 1158 phy_change->reason != MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED) 1159 continue; 1160 1161 if (mpr_config_get_sas_device_pg0(sc, &mpi_reply, 1162 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, 1163 phy_change->dev_handle)) { 1164 phy_change->is_processed = 1; 1165 continue; 1166 } 1167 1168 /* 1169 * Always get SATA Identify information because this is used 1170 * to determine if Start/Stop Unit should be sent to the drive 1171 * when the system is shutdown. 1172 */ 1173 device_info = le32toh(sas_device_pg0.DeviceInfo); 1174 sas_address = le32toh(sas_device_pg0.SASAddress.High); 1175 sas_address = (sas_address << 32) | 1176 le32toh(sas_device_pg0.SASAddress.Low); 1177 if ((device_info & MPI2_SAS_DEVICE_INFO_END_DEVICE) && 1178 (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)) { 1179 rc = mprsas_get_sas_address_for_sata_disk(sc, 1180 &sas_address, phy_change->dev_handle, device_info, 1181 &phy_change->is_SATA_SSD); 1182 if (rc) { 1183 mpr_dprint(sc, MPR_ERROR, "%s: failed to get " 1184 "disk type (SSD or HDD) and SAS Address " 1185 "for SATA device with handle 0x%04x\n", 1186 __func__, phy_change->dev_handle); 1187 } 1188 } 1189 1190 phy_change->physical_id = sas_address; 1191 phy_change->slot = le16toh(sas_device_pg0.Slot); 1192 phy_change->device_info = device_info; 1193 1194 /* 1195 * When using Enc/Slot mapping, if this device is an enclosure 1196 * make sure that all of its slots can fit into the mapping 1197 * table. 1198 */ 1199 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1200 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 1201 /* 1202 * The enclosure should already be in the enclosure 1203 * table due to the Enclosure Add event. If not, just 1204 * continue, nothing can be done. 1205 */ 1206 enc_idx = _mapping_get_enc_idx_from_handle(sc, 1207 topo_change->enc_handle); 1208 if (enc_idx == MPR_ENCTABLE_BAD_IDX) { 1209 phy_change->is_processed = 1; 1210 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: " 1211 "failed to add the device with handle " 1212 "0x%04x because the enclosure is not in " 1213 "the mapping table\n", __func__, 1214 phy_change->dev_handle); 1215 continue; 1216 } 1217 if (!((phy_change->device_info & 1218 MPI2_SAS_DEVICE_INFO_END_DEVICE) && 1219 (phy_change->device_info & 1220 (MPI2_SAS_DEVICE_INFO_SSP_TARGET | 1221 MPI2_SAS_DEVICE_INFO_STP_TARGET | 1222 MPI2_SAS_DEVICE_INFO_SATA_DEVICE)))) { 1223 phy_change->is_processed = 1; 1224 continue; 1225 } 1226 et_entry = &sc->enclosure_table[enc_idx]; 1227 1228 /* 1229 * If the enclosure already has a start_index, it's been 1230 * mapped, so go to the next Topo change. 1231 */ 1232 if (et_entry->start_index != MPR_MAPTABLE_BAD_IDX) 1233 continue; 1234 1235 /* 1236 * If the Expander Handle is 0, the devices are direct 1237 * attached. In that case, the start_index must be just 1238 * after the reserved entries. Otherwise, find space in 1239 * the mapping table for the enclosure's devices. 1240 */ 1241 if (!topo_change->exp_handle) { 1242 map_idx = sc->num_rsvd_entries; 1243 et_entry->start_index = map_idx; 1244 } else { 1245 map_idx = _mapping_find_enc_map_space(sc, 1246 et_entry); 1247 et_entry->start_index = map_idx; 1248 1249 /* 1250 * If space cannot be found to hold all of the 1251 * enclosure's devices in the mapping table, 1252 * there's no need to continue checking the 1253 * other devices in this event. Set all of the 1254 * phy_details for this event (if the change is 1255 * for an add) as already processed because none 1256 * of these devices can be added to the mapping 1257 * table. 1258 */ 1259 if (et_entry->start_index == 1260 MPR_MAPTABLE_BAD_IDX) { 1261 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, 1262 "%s: failed to add the enclosure " 1263 "with ID 0x%016jx because there is " 1264 "no free space available in the " 1265 "mapping table for all of the " 1266 "enclosure's devices.\n", __func__, 1267 (uintmax_t)et_entry->enclosure_id); 1268 phy_change->is_processed = 1; 1269 for (phy_idx = 0; phy_idx < 1270 topo_change->num_entries; 1271 phy_idx++) { 1272 tmp_phy_change = 1273 &topo_change->phy_details 1274 [phy_idx]; 1275 if (tmp_phy_change->reason == 1276 add_code) 1277 tmp_phy_change-> 1278 is_processed = 1; 1279 } 1280 break; 1281 } 1282 } 1283 1284 /* 1285 * Found space in the mapping table for this enclosure. 1286 * Initialize each mapping table entry for the 1287 * enclosure. 1288 */ 1289 mpr_dprint(sc, MPR_MAPPING, "%s: Initialize %d map " 1290 "entries for the enclosure, starting at map index " 1291 " %d.\n", __func__, et_entry->num_slots, map_idx); 1292 mt_entry = &sc->mapping_table[map_idx]; 1293 for (index = map_idx; index < (et_entry->num_slots 1294 + map_idx); index++, mt_entry++) { 1295 mt_entry->device_info = MPR_DEV_RESERVED; 1296 mt_entry->physical_id = et_entry->enclosure_id; 1297 mt_entry->phy_bits = et_entry->phy_bits; 1298 mt_entry->missing_count = 0; 1299 } 1300 } 1301 } 1302 } 1303 1304 /** 1305 * _mapping_get_pcie_dev_info -get information about newly added PCIe devices 1306 * @sc: per adapter object 1307 * @topo_change: Topology change event entry 1308 * 1309 * Searches through the PCIe topology change event list and issues PCIe device 1310 * pg0 requests for the newly added PCIe device. If the device is in an 1311 * enclosure, search for available space in the enclosure mapping table for the 1312 * device and reserve that space. 1313 * 1314 * Returns nothing 1315 */ 1316 static void 1317 _mapping_get_pcie_dev_info(struct mpr_softc *sc, 1318 struct _map_pcie_topology_change *topo_change) 1319 { 1320 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 1321 Mpi2ConfigReply_t mpi_reply; 1322 Mpi26PCIeDevicePage0_t pcie_device_pg0; 1323 u8 entry, enc_idx, port_idx; 1324 u32 map_idx, index; 1325 struct _map_port_change *port_change, *tmp_port_change; 1326 uint64_t pcie_wwid; 1327 struct enc_mapping_table *et_entry; 1328 struct dev_mapping_table *mt_entry; 1329 u8 add_code = MPI26_EVENT_PCIE_TOPO_PS_DEV_ADDED; 1330 1331 for (entry = 0; entry < topo_change->num_entries; entry++) { 1332 port_change = &topo_change->port_details[entry]; 1333 if (port_change->is_processed || !port_change->dev_handle || 1334 port_change->reason != MPI26_EVENT_PCIE_TOPO_PS_DEV_ADDED) 1335 continue; 1336 if (mpr_config_get_pcie_device_pg0(sc, &mpi_reply, 1337 &pcie_device_pg0, MPI26_PCIE_DEVICE_PGAD_FORM_HANDLE, 1338 port_change->dev_handle)) { 1339 port_change->is_processed = 1; 1340 continue; 1341 } 1342 1343 pcie_wwid = pcie_device_pg0.WWID.High; 1344 pcie_wwid = (pcie_wwid << 32) | pcie_device_pg0.WWID.Low; 1345 port_change->physical_id = pcie_wwid; 1346 port_change->slot = le16toh(pcie_device_pg0.Slot); 1347 port_change->device_info = le32toh(pcie_device_pg0.DeviceInfo); 1348 1349 /* 1350 * When using Enc/Slot mapping, if this device is an enclosure 1351 * make sure that all of its slots can fit into the mapping 1352 * table. 1353 */ 1354 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1355 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 1356 /* 1357 * The enclosure should already be in the enclosure 1358 * table due to the Enclosure Add event. If not, just 1359 * continue, nothing can be done. 1360 */ 1361 enc_idx = _mapping_get_enc_idx_from_handle(sc, 1362 topo_change->enc_handle); 1363 if (enc_idx == MPR_ENCTABLE_BAD_IDX) { 1364 port_change->is_processed = 1; 1365 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: " 1366 "failed to add the device with handle " 1367 "0x%04x because the enclosure is not in " 1368 "the mapping table\n", __func__, 1369 port_change->dev_handle); 1370 continue; 1371 } 1372 if (!(port_change->device_info & 1373 MPI26_PCIE_DEVINFO_NVME)) { 1374 port_change->is_processed = 1; 1375 continue; 1376 } 1377 et_entry = &sc->enclosure_table[enc_idx]; 1378 1379 /* 1380 * If the enclosure already has a start_index, it's been 1381 * mapped, so go to the next Topo change. 1382 */ 1383 if (et_entry->start_index != MPR_MAPTABLE_BAD_IDX) 1384 continue; 1385 1386 /* 1387 * If the Switch Handle is 0, the devices are direct 1388 * attached. In that case, the start_index must be just 1389 * after the reserved entries. Otherwise, find space in 1390 * the mapping table for the enclosure's devices. 1391 */ 1392 if (!topo_change->switch_dev_handle) { 1393 map_idx = sc->num_rsvd_entries; 1394 et_entry->start_index = map_idx; 1395 } else { 1396 map_idx = _mapping_find_enc_map_space(sc, 1397 et_entry); 1398 et_entry->start_index = map_idx; 1399 1400 /* 1401 * If space cannot be found to hold all of the 1402 * enclosure's devices in the mapping table, 1403 * there's no need to continue checking the 1404 * other devices in this event. Set all of the 1405 * port_details for this event (if the change is 1406 * for an add) as already processed because none 1407 * of these devices can be added to the mapping 1408 * table. 1409 */ 1410 if (et_entry->start_index == 1411 MPR_MAPTABLE_BAD_IDX) { 1412 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, 1413 "%s: failed to add the enclosure " 1414 "with ID 0x%016jx because there is " 1415 "no free space available in the " 1416 "mapping table for all of the " 1417 "enclosure's devices.\n", __func__, 1418 (uintmax_t)et_entry->enclosure_id); 1419 port_change->is_processed = 1; 1420 for (port_idx = 0; port_idx < 1421 topo_change->num_entries; 1422 port_idx++) { 1423 tmp_port_change = 1424 &topo_change->port_details 1425 [port_idx]; 1426 if (tmp_port_change->reason == 1427 add_code) 1428 tmp_port_change-> 1429 is_processed = 1; 1430 } 1431 break; 1432 } 1433 } 1434 1435 /* 1436 * Found space in the mapping table for this enclosure. 1437 * Initialize each mapping table entry for the 1438 * enclosure. 1439 */ 1440 mpr_dprint(sc, MPR_MAPPING, "%s: Initialize %d map " 1441 "entries for the enclosure, starting at map index " 1442 " %d.\n", __func__, et_entry->num_slots, map_idx); 1443 mt_entry = &sc->mapping_table[map_idx]; 1444 for (index = map_idx; index < (et_entry->num_slots 1445 + map_idx); index++, mt_entry++) { 1446 mt_entry->device_info = MPR_DEV_RESERVED; 1447 mt_entry->physical_id = et_entry->enclosure_id; 1448 mt_entry->phy_bits = et_entry->phy_bits; 1449 mt_entry->missing_count = 0; 1450 } 1451 } 1452 } 1453 } 1454 1455 /** 1456 * _mapping_set_mid_to_eid -set map table data from enclosure table 1457 * @sc: per adapter object 1458 * @et_entry: enclosure entry 1459 * 1460 * Returns nothing 1461 */ 1462 static inline void 1463 _mapping_set_mid_to_eid(struct mpr_softc *sc, 1464 struct enc_mapping_table *et_entry) 1465 { 1466 struct dev_mapping_table *mt_entry; 1467 u16 slots = et_entry->num_slots, map_idx; 1468 u32 start_idx = et_entry->start_index; 1469 1470 if (start_idx != MPR_MAPTABLE_BAD_IDX) { 1471 mt_entry = &sc->mapping_table[start_idx]; 1472 for (map_idx = 0; map_idx < slots; map_idx++, mt_entry++) 1473 mt_entry->physical_id = et_entry->enclosure_id; 1474 } 1475 } 1476 1477 /** 1478 * _mapping_clear_removed_entries - mark the entries to be cleared 1479 * @sc: per adapter object 1480 * 1481 * Search through the removal table and mark the entries which needs to be 1482 * flushed to DPM and also updates the map table and enclosure table by 1483 * clearing the corresponding entries. 1484 * 1485 * Returns nothing 1486 */ 1487 static void 1488 _mapping_clear_removed_entries(struct mpr_softc *sc) 1489 { 1490 u32 remove_idx; 1491 struct map_removal_table *remove_entry; 1492 Mpi2DriverMap0Entry_t *dpm_entry; 1493 u8 done_flag = 0, num_entries, m, i; 1494 struct enc_mapping_table *et_entry, *from, *to; 1495 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 1496 1497 if (sc->is_dpm_enable) { 1498 remove_entry = sc->removal_table; 1499 for (remove_idx = 0; remove_idx < sc->max_devices; 1500 remove_idx++, remove_entry++) { 1501 if (remove_entry->dpm_entry_num != MPR_DPM_BAD_IDX) { 1502 dpm_entry = (Mpi2DriverMap0Entry_t *) 1503 ((u8 *) sc->dpm_pg0 + 1504 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 1505 dpm_entry += remove_entry->dpm_entry_num; 1506 dpm_entry->PhysicalIdentifier.Low = 0; 1507 dpm_entry->PhysicalIdentifier.High = 0; 1508 dpm_entry->DeviceIndex = 0; 1509 dpm_entry->MappingInformation = 0; 1510 dpm_entry->PhysicalBitsMapping = 0; 1511 sc->dpm_flush_entry[remove_entry-> 1512 dpm_entry_num] = 1; 1513 sc->dpm_entry_used[remove_entry->dpm_entry_num] 1514 = 0; 1515 remove_entry->dpm_entry_num = MPR_DPM_BAD_IDX; 1516 } 1517 } 1518 } 1519 1520 /* 1521 * When using Enc/Slot mapping, if a new enclosure was added and old 1522 * enclosure space was needed, the enclosure table may now have gaps 1523 * that need to be closed. All enclosure mappings need to be contiguous 1524 * so that space can be reused correctly if available. 1525 */ 1526 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1527 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 1528 num_entries = sc->num_enc_table_entries; 1529 while (!done_flag) { 1530 done_flag = 1; 1531 et_entry = sc->enclosure_table; 1532 for (i = 0; i < num_entries; i++, et_entry++) { 1533 if (!et_entry->enc_handle && et_entry-> 1534 init_complete) { 1535 done_flag = 0; 1536 if (i != (num_entries - 1)) { 1537 from = &sc->enclosure_table 1538 [i+1]; 1539 to = &sc->enclosure_table[i]; 1540 for (m = i; m < (num_entries - 1541 1); m++, from++, to++) { 1542 _mapping_set_mid_to_eid 1543 (sc, to); 1544 *to = *from; 1545 } 1546 _mapping_clear_enc_entry(to); 1547 sc->num_enc_table_entries--; 1548 num_entries = 1549 sc->num_enc_table_entries; 1550 } else { 1551 _mapping_clear_enc_entry 1552 (et_entry); 1553 sc->num_enc_table_entries--; 1554 num_entries = 1555 sc->num_enc_table_entries; 1556 } 1557 } 1558 } 1559 } 1560 } 1561 } 1562 1563 /** 1564 * _mapping_add_new_device -Add the new device into mapping table 1565 * @sc: per adapter object 1566 * @topo_change: Topology change event entry 1567 * 1568 * Search through the topology change event list and update map table, 1569 * enclosure table and DPM pages for the newly added devices. 1570 * 1571 * Returns nothing 1572 */ 1573 static void 1574 _mapping_add_new_device(struct mpr_softc *sc, 1575 struct _map_topology_change *topo_change) 1576 { 1577 u8 enc_idx, missing_cnt, is_removed = 0; 1578 u16 dpm_idx; 1579 u32 search_idx, map_idx; 1580 u32 entry; 1581 struct dev_mapping_table *mt_entry; 1582 struct enc_mapping_table *et_entry; 1583 struct _map_phy_change *phy_change; 1584 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 1585 Mpi2DriverMap0Entry_t *dpm_entry; 1586 uint64_t temp64_var; 1587 u8 map_shift = MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT; 1588 u8 hdr_sz = sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER); 1589 u16 max_num_phy_ids = le16toh(sc->ioc_pg8.MaxNumPhysicalMappedIDs); 1590 1591 for (entry = 0; entry < topo_change->num_entries; entry++) { 1592 phy_change = &topo_change->phy_details[entry]; 1593 if (phy_change->is_processed) 1594 continue; 1595 if (phy_change->reason != MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED || 1596 !phy_change->dev_handle) { 1597 phy_change->is_processed = 1; 1598 continue; 1599 } 1600 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1601 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 1602 enc_idx = _mapping_get_enc_idx_from_handle 1603 (sc, topo_change->enc_handle); 1604 if (enc_idx == MPR_ENCTABLE_BAD_IDX) { 1605 phy_change->is_processed = 1; 1606 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: " 1607 "failed to add the device with handle " 1608 "0x%04x because the enclosure is not in " 1609 "the mapping table\n", __func__, 1610 phy_change->dev_handle); 1611 continue; 1612 } 1613 1614 /* 1615 * If the enclosure's start_index is BAD here, it means 1616 * that there is no room in the mapping table to cover 1617 * all of the devices that could be in the enclosure. 1618 * There's no reason to process any of the devices for 1619 * this enclosure since they can't be mapped. 1620 */ 1621 et_entry = &sc->enclosure_table[enc_idx]; 1622 if (et_entry->start_index == MPR_MAPTABLE_BAD_IDX) { 1623 phy_change->is_processed = 1; 1624 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: " 1625 "failed to add the device with handle " 1626 "0x%04x because there is no free space " 1627 "available in the mapping table\n", 1628 __func__, phy_change->dev_handle); 1629 continue; 1630 } 1631 1632 /* 1633 * Add this device to the mapping table at the correct 1634 * offset where space was found to map the enclosure. 1635 * Then setup the DPM entry information if being used. 1636 */ 1637 map_idx = et_entry->start_index + phy_change->slot - 1638 et_entry->start_slot; 1639 mt_entry = &sc->mapping_table[map_idx]; 1640 mt_entry->physical_id = phy_change->physical_id; 1641 mt_entry->id = map_idx; 1642 mt_entry->dev_handle = phy_change->dev_handle; 1643 mt_entry->missing_count = 0; 1644 mt_entry->dpm_entry_num = et_entry->dpm_entry_num; 1645 mt_entry->device_info = phy_change->device_info | 1646 (MPR_DEV_RESERVED | MPR_MAP_IN_USE); 1647 if (sc->is_dpm_enable) { 1648 dpm_idx = et_entry->dpm_entry_num; 1649 if (dpm_idx == MPR_DPM_BAD_IDX) 1650 dpm_idx = _mapping_get_dpm_idx_from_id 1651 (sc, et_entry->enclosure_id, 1652 et_entry->phy_bits); 1653 if (dpm_idx == MPR_DPM_BAD_IDX) { 1654 dpm_idx = _mapping_get_free_dpm_idx(sc); 1655 if (dpm_idx != MPR_DPM_BAD_IDX) { 1656 dpm_entry = 1657 (Mpi2DriverMap0Entry_t *) 1658 ((u8 *) sc->dpm_pg0 + 1659 hdr_sz); 1660 dpm_entry += dpm_idx; 1661 dpm_entry-> 1662 PhysicalIdentifier.Low = 1663 (0xFFFFFFFF & 1664 et_entry->enclosure_id); 1665 dpm_entry-> 1666 PhysicalIdentifier.High = 1667 (et_entry->enclosure_id 1668 >> 32); 1669 dpm_entry->DeviceIndex = 1670 (U16)et_entry->start_index; 1671 dpm_entry->MappingInformation = 1672 et_entry->num_slots; 1673 dpm_entry->MappingInformation 1674 <<= map_shift; 1675 dpm_entry->PhysicalBitsMapping 1676 = et_entry->phy_bits; 1677 et_entry->dpm_entry_num = 1678 dpm_idx; 1679 sc->dpm_entry_used[dpm_idx] = 1; 1680 sc->dpm_flush_entry[dpm_idx] = 1681 1; 1682 phy_change->is_processed = 1; 1683 } else { 1684 phy_change->is_processed = 1; 1685 mpr_dprint(sc, MPR_ERROR | 1686 MPR_MAPPING, "%s: failed " 1687 "to add the device with " 1688 "handle 0x%04x to " 1689 "persistent table because " 1690 "there is no free space " 1691 "available\n", __func__, 1692 phy_change->dev_handle); 1693 } 1694 } else { 1695 et_entry->dpm_entry_num = dpm_idx; 1696 mt_entry->dpm_entry_num = dpm_idx; 1697 } 1698 } 1699 et_entry->init_complete = 1; 1700 } else if ((ioc_pg8_flags & 1701 MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1702 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) { 1703 1704 /* 1705 * Get the mapping table index for this device. If it's 1706 * not in the mapping table yet, find a free entry if 1707 * one is available. If there are no free entries, look 1708 * for the entry that has the highest missing count. If 1709 * none of that works to find an entry in the mapping 1710 * table, there is a problem. Log a message and just 1711 * continue on. 1712 */ 1713 map_idx = _mapping_get_mt_idx_from_id 1714 (sc, phy_change->physical_id); 1715 if (map_idx == MPR_MAPTABLE_BAD_IDX) { 1716 search_idx = sc->num_rsvd_entries; 1717 if (topo_change->exp_handle) 1718 search_idx += max_num_phy_ids; 1719 map_idx = _mapping_get_free_mt_idx(sc, 1720 search_idx); 1721 } 1722 1723 /* 1724 * If an entry will be used that has a missing device, 1725 * clear its entry from the DPM in the controller. 1726 */ 1727 if (map_idx == MPR_MAPTABLE_BAD_IDX) { 1728 map_idx = _mapping_get_high_missing_mt_idx(sc); 1729 if (map_idx != MPR_MAPTABLE_BAD_IDX) { 1730 mt_entry = &sc->mapping_table[map_idx]; 1731 _mapping_add_to_removal_table(sc, 1732 mt_entry->dpm_entry_num); 1733 is_removed = 1; 1734 mt_entry->init_complete = 0; 1735 } 1736 } 1737 if (map_idx != MPR_MAPTABLE_BAD_IDX) { 1738 mt_entry = &sc->mapping_table[map_idx]; 1739 mt_entry->physical_id = phy_change->physical_id; 1740 mt_entry->id = map_idx; 1741 mt_entry->dev_handle = phy_change->dev_handle; 1742 mt_entry->missing_count = 0; 1743 mt_entry->device_info = phy_change->device_info 1744 | (MPR_DEV_RESERVED | MPR_MAP_IN_USE); 1745 } else { 1746 phy_change->is_processed = 1; 1747 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: " 1748 "failed to add the device with handle " 1749 "0x%04x because there is no free space " 1750 "available in the mapping table\n", 1751 __func__, phy_change->dev_handle); 1752 continue; 1753 } 1754 if (sc->is_dpm_enable) { 1755 if (mt_entry->dpm_entry_num != 1756 MPR_DPM_BAD_IDX) { 1757 dpm_idx = mt_entry->dpm_entry_num; 1758 dpm_entry = (Mpi2DriverMap0Entry_t *) 1759 ((u8 *)sc->dpm_pg0 + hdr_sz); 1760 dpm_entry += dpm_idx; 1761 missing_cnt = dpm_entry-> 1762 MappingInformation & 1763 MPI2_DRVMAP0_MAPINFO_MISSING_MASK; 1764 temp64_var = dpm_entry-> 1765 PhysicalIdentifier.High; 1766 temp64_var = (temp64_var << 32) | 1767 dpm_entry->PhysicalIdentifier.Low; 1768 1769 /* 1770 * If the Mapping Table's info is not 1771 * the same as the DPM entry, clear the 1772 * init_complete flag so that it's 1773 * updated. 1774 */ 1775 if ((mt_entry->physical_id == 1776 temp64_var) && !missing_cnt) 1777 mt_entry->init_complete = 1; 1778 else 1779 mt_entry->init_complete = 0; 1780 } else { 1781 dpm_idx = _mapping_get_free_dpm_idx(sc); 1782 mt_entry->init_complete = 0; 1783 } 1784 if (dpm_idx != MPR_DPM_BAD_IDX && 1785 !mt_entry->init_complete) { 1786 mt_entry->dpm_entry_num = dpm_idx; 1787 dpm_entry = (Mpi2DriverMap0Entry_t *) 1788 ((u8 *)sc->dpm_pg0 + hdr_sz); 1789 dpm_entry += dpm_idx; 1790 dpm_entry->PhysicalIdentifier.Low = 1791 (0xFFFFFFFF & 1792 mt_entry->physical_id); 1793 dpm_entry->PhysicalIdentifier.High = 1794 (mt_entry->physical_id >> 32); 1795 dpm_entry->DeviceIndex = (U16) map_idx; 1796 dpm_entry->MappingInformation = 0; 1797 dpm_entry->PhysicalBitsMapping = 0; 1798 sc->dpm_entry_used[dpm_idx] = 1; 1799 sc->dpm_flush_entry[dpm_idx] = 1; 1800 phy_change->is_processed = 1; 1801 } else if (dpm_idx == MPR_DPM_BAD_IDX) { 1802 phy_change->is_processed = 1; 1803 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, 1804 "%s: failed to add the device with " 1805 "handle 0x%04x to persistent table " 1806 "because there is no free space " 1807 "available\n", __func__, 1808 phy_change->dev_handle); 1809 } 1810 } 1811 mt_entry->init_complete = 1; 1812 } 1813 1814 phy_change->is_processed = 1; 1815 } 1816 if (is_removed) 1817 _mapping_clear_removed_entries(sc); 1818 } 1819 1820 /** 1821 * _mapping_add_new_pcie_device -Add the new PCIe device into mapping table 1822 * @sc: per adapter object 1823 * @topo_change: Topology change event entry 1824 * 1825 * Search through the PCIe topology change event list and update map table, 1826 * enclosure table and DPM pages for the newly added devices. 1827 * 1828 * Returns nothing 1829 */ 1830 static void 1831 _mapping_add_new_pcie_device(struct mpr_softc *sc, 1832 struct _map_pcie_topology_change *topo_change) 1833 { 1834 u8 enc_idx, missing_cnt, is_removed = 0; 1835 u16 dpm_idx; 1836 u32 search_idx, map_idx; 1837 u32 entry; 1838 struct dev_mapping_table *mt_entry; 1839 struct enc_mapping_table *et_entry; 1840 struct _map_port_change *port_change; 1841 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 1842 Mpi2DriverMap0Entry_t *dpm_entry; 1843 uint64_t temp64_var; 1844 u8 map_shift = MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT; 1845 u8 hdr_sz = sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER); 1846 u16 max_num_phy_ids = le16toh(sc->ioc_pg8.MaxNumPhysicalMappedIDs); 1847 1848 for (entry = 0; entry < topo_change->num_entries; entry++) { 1849 port_change = &topo_change->port_details[entry]; 1850 if (port_change->is_processed) 1851 continue; 1852 if (port_change->reason != MPI26_EVENT_PCIE_TOPO_PS_DEV_ADDED || 1853 !port_change->dev_handle) { 1854 port_change->is_processed = 1; 1855 continue; 1856 } 1857 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1858 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 1859 enc_idx = _mapping_get_enc_idx_from_handle 1860 (sc, topo_change->enc_handle); 1861 if (enc_idx == MPR_ENCTABLE_BAD_IDX) { 1862 port_change->is_processed = 1; 1863 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: " 1864 "failed to add the device with handle " 1865 "0x%04x because the enclosure is not in " 1866 "the mapping table\n", __func__, 1867 port_change->dev_handle); 1868 continue; 1869 } 1870 1871 /* 1872 * If the enclosure's start_index is BAD here, it means 1873 * that there is no room in the mapping table to cover 1874 * all of the devices that could be in the enclosure. 1875 * There's no reason to process any of the devices for 1876 * this enclosure since they can't be mapped. 1877 */ 1878 et_entry = &sc->enclosure_table[enc_idx]; 1879 if (et_entry->start_index == MPR_MAPTABLE_BAD_IDX) { 1880 port_change->is_processed = 1; 1881 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: " 1882 "failed to add the device with handle " 1883 "0x%04x because there is no free space " 1884 "available in the mapping table\n", 1885 __func__, port_change->dev_handle); 1886 continue; 1887 } 1888 1889 /* 1890 * Add this device to the mapping table at the correct 1891 * offset where space was found to map the enclosure. 1892 * Then setup the DPM entry information if being used. 1893 */ 1894 map_idx = et_entry->start_index + port_change->slot - 1895 et_entry->start_slot; 1896 mt_entry = &sc->mapping_table[map_idx]; 1897 mt_entry->physical_id = port_change->physical_id; 1898 mt_entry->id = map_idx; 1899 mt_entry->dev_handle = port_change->dev_handle; 1900 mt_entry->missing_count = 0; 1901 mt_entry->dpm_entry_num = et_entry->dpm_entry_num; 1902 mt_entry->device_info = port_change->device_info | 1903 (MPR_DEV_RESERVED | MPR_MAP_IN_USE); 1904 if (sc->is_dpm_enable) { 1905 dpm_idx = et_entry->dpm_entry_num; 1906 if (dpm_idx == MPR_DPM_BAD_IDX) 1907 dpm_idx = _mapping_get_dpm_idx_from_id 1908 (sc, et_entry->enclosure_id, 1909 et_entry->phy_bits); 1910 if (dpm_idx == MPR_DPM_BAD_IDX) { 1911 dpm_idx = _mapping_get_free_dpm_idx(sc); 1912 if (dpm_idx != MPR_DPM_BAD_IDX) { 1913 dpm_entry = 1914 (Mpi2DriverMap0Entry_t *) 1915 ((u8 *) sc->dpm_pg0 + 1916 hdr_sz); 1917 dpm_entry += dpm_idx; 1918 dpm_entry-> 1919 PhysicalIdentifier.Low = 1920 (0xFFFFFFFF & 1921 et_entry->enclosure_id); 1922 dpm_entry-> 1923 PhysicalIdentifier.High = 1924 (et_entry->enclosure_id 1925 >> 32); 1926 dpm_entry->DeviceIndex = 1927 (U16)et_entry->start_index; 1928 dpm_entry->MappingInformation = 1929 et_entry->num_slots; 1930 dpm_entry->MappingInformation 1931 <<= map_shift; 1932 dpm_entry->PhysicalBitsMapping 1933 = et_entry->phy_bits; 1934 et_entry->dpm_entry_num = 1935 dpm_idx; 1936 sc->dpm_entry_used[dpm_idx] = 1; 1937 sc->dpm_flush_entry[dpm_idx] = 1938 1; 1939 port_change->is_processed = 1; 1940 } else { 1941 port_change->is_processed = 1; 1942 mpr_dprint(sc, MPR_ERROR | 1943 MPR_MAPPING, "%s: failed " 1944 "to add the device with " 1945 "handle 0x%04x to " 1946 "persistent table because " 1947 "there is no free space " 1948 "available\n", __func__, 1949 port_change->dev_handle); 1950 } 1951 } else { 1952 et_entry->dpm_entry_num = dpm_idx; 1953 mt_entry->dpm_entry_num = dpm_idx; 1954 } 1955 } 1956 et_entry->init_complete = 1; 1957 } else if ((ioc_pg8_flags & 1958 MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 1959 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) { 1960 1961 /* 1962 * Get the mapping table index for this device. If it's 1963 * not in the mapping table yet, find a free entry if 1964 * one is available. If there are no free entries, look 1965 * for the entry that has the highest missing count. If 1966 * none of that works to find an entry in the mapping 1967 * table, there is a problem. Log a message and just 1968 * continue on. 1969 */ 1970 map_idx = _mapping_get_mt_idx_from_id 1971 (sc, port_change->physical_id); 1972 if (map_idx == MPR_MAPTABLE_BAD_IDX) { 1973 search_idx = sc->num_rsvd_entries; 1974 if (topo_change->switch_dev_handle) 1975 search_idx += max_num_phy_ids; 1976 map_idx = _mapping_get_free_mt_idx(sc, 1977 search_idx); 1978 } 1979 1980 /* 1981 * If an entry will be used that has a missing device, 1982 * clear its entry from the DPM in the controller. 1983 */ 1984 if (map_idx == MPR_MAPTABLE_BAD_IDX) { 1985 map_idx = _mapping_get_high_missing_mt_idx(sc); 1986 if (map_idx != MPR_MAPTABLE_BAD_IDX) { 1987 mt_entry = &sc->mapping_table[map_idx]; 1988 _mapping_add_to_removal_table(sc, 1989 mt_entry->dpm_entry_num); 1990 is_removed = 1; 1991 mt_entry->init_complete = 0; 1992 } 1993 } 1994 if (map_idx != MPR_MAPTABLE_BAD_IDX) { 1995 mt_entry = &sc->mapping_table[map_idx]; 1996 mt_entry->physical_id = 1997 port_change->physical_id; 1998 mt_entry->id = map_idx; 1999 mt_entry->dev_handle = port_change->dev_handle; 2000 mt_entry->missing_count = 0; 2001 mt_entry->device_info = 2002 port_change->device_info | 2003 (MPR_DEV_RESERVED | MPR_MAP_IN_USE); 2004 } else { 2005 port_change->is_processed = 1; 2006 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: " 2007 "failed to add the device with handle " 2008 "0x%04x because there is no free space " 2009 "available in the mapping table\n", 2010 __func__, port_change->dev_handle); 2011 continue; 2012 } 2013 if (sc->is_dpm_enable) { 2014 if (mt_entry->dpm_entry_num != 2015 MPR_DPM_BAD_IDX) { 2016 dpm_idx = mt_entry->dpm_entry_num; 2017 dpm_entry = (Mpi2DriverMap0Entry_t *) 2018 ((u8 *)sc->dpm_pg0 + hdr_sz); 2019 dpm_entry += dpm_idx; 2020 missing_cnt = dpm_entry-> 2021 MappingInformation & 2022 MPI2_DRVMAP0_MAPINFO_MISSING_MASK; 2023 temp64_var = dpm_entry-> 2024 PhysicalIdentifier.High; 2025 temp64_var = (temp64_var << 32) | 2026 dpm_entry->PhysicalIdentifier.Low; 2027 2028 /* 2029 * If the Mapping Table's info is not 2030 * the same as the DPM entry, clear the 2031 * init_complete flag so that it's 2032 * updated. 2033 */ 2034 if ((mt_entry->physical_id == 2035 temp64_var) && !missing_cnt) 2036 mt_entry->init_complete = 1; 2037 else 2038 mt_entry->init_complete = 0; 2039 } else { 2040 dpm_idx = _mapping_get_free_dpm_idx(sc); 2041 mt_entry->init_complete = 0; 2042 } 2043 if (dpm_idx != MPR_DPM_BAD_IDX && 2044 !mt_entry->init_complete) { 2045 mt_entry->dpm_entry_num = dpm_idx; 2046 dpm_entry = (Mpi2DriverMap0Entry_t *) 2047 ((u8 *)sc->dpm_pg0 + hdr_sz); 2048 dpm_entry += dpm_idx; 2049 dpm_entry->PhysicalIdentifier.Low = 2050 (0xFFFFFFFF & 2051 mt_entry->physical_id); 2052 dpm_entry->PhysicalIdentifier.High = 2053 (mt_entry->physical_id >> 32); 2054 dpm_entry->DeviceIndex = (U16) map_idx; 2055 dpm_entry->MappingInformation = 0; 2056 dpm_entry->PhysicalBitsMapping = 0; 2057 sc->dpm_entry_used[dpm_idx] = 1; 2058 sc->dpm_flush_entry[dpm_idx] = 1; 2059 port_change->is_processed = 1; 2060 } else if (dpm_idx == MPR_DPM_BAD_IDX) { 2061 port_change->is_processed = 1; 2062 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, 2063 "%s: failed to add the device with " 2064 "handle 0x%04x to persistent table " 2065 "because there is no free space " 2066 "available\n", __func__, 2067 port_change->dev_handle); 2068 } 2069 } 2070 mt_entry->init_complete = 1; 2071 } 2072 2073 port_change->is_processed = 1; 2074 } 2075 if (is_removed) 2076 _mapping_clear_removed_entries(sc); 2077 } 2078 2079 /** 2080 * _mapping_flush_dpm_pages -Flush the DPM pages to NVRAM 2081 * @sc: per adapter object 2082 * 2083 * Returns nothing 2084 */ 2085 static void 2086 _mapping_flush_dpm_pages(struct mpr_softc *sc) 2087 { 2088 Mpi2DriverMap0Entry_t *dpm_entry; 2089 Mpi2ConfigReply_t mpi_reply; 2090 Mpi2DriverMappingPage0_t config_page; 2091 u16 entry_num; 2092 2093 for (entry_num = 0; entry_num < sc->max_dpm_entries; entry_num++) { 2094 if (!sc->dpm_flush_entry[entry_num]) 2095 continue; 2096 memset(&config_page, 0, sizeof(Mpi2DriverMappingPage0_t)); 2097 memcpy(&config_page.Header, (u8 *)sc->dpm_pg0, 2098 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 2099 dpm_entry = (Mpi2DriverMap0Entry_t *) ((u8 *)sc->dpm_pg0 + 2100 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 2101 dpm_entry += entry_num; 2102 dpm_entry->MappingInformation = htole16(dpm_entry-> 2103 MappingInformation); 2104 dpm_entry->DeviceIndex = htole16(dpm_entry->DeviceIndex); 2105 dpm_entry->PhysicalBitsMapping = htole32(dpm_entry-> 2106 PhysicalBitsMapping); 2107 memcpy(&config_page.Entry, (u8 *)dpm_entry, 2108 sizeof(Mpi2DriverMap0Entry_t)); 2109 /* TODO-How to handle failed writes? */ 2110 mpr_dprint(sc, MPR_MAPPING, "%s: Flushing DPM entry %d.\n", 2111 __func__, entry_num); 2112 if (mpr_config_set_dpm_pg0(sc, &mpi_reply, &config_page, 2113 entry_num)) { 2114 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: Flush of " 2115 "DPM entry %d for device failed\n", __func__, 2116 entry_num); 2117 } else 2118 sc->dpm_flush_entry[entry_num] = 0; 2119 dpm_entry->MappingInformation = le16toh(dpm_entry-> 2120 MappingInformation); 2121 dpm_entry->DeviceIndex = le16toh(dpm_entry->DeviceIndex); 2122 dpm_entry->PhysicalBitsMapping = le32toh(dpm_entry-> 2123 PhysicalBitsMapping); 2124 } 2125 } 2126 2127 /** 2128 * _mapping_allocate_memory- allocates the memory required for mapping tables 2129 * @sc: per adapter object 2130 * 2131 * Allocates the memory for all the tables required for host mapping 2132 * 2133 * Return 0 on success or non-zero on failure. 2134 */ 2135 int 2136 mpr_mapping_allocate_memory(struct mpr_softc *sc) 2137 { 2138 uint32_t dpm_pg0_sz; 2139 2140 sc->mapping_table = kmalloc((sizeof(struct dev_mapping_table) * 2141 sc->max_devices), M_MPR, M_ZERO|M_NOWAIT); 2142 if (!sc->mapping_table) 2143 goto free_resources; 2144 2145 sc->removal_table = kmalloc((sizeof(struct map_removal_table) * 2146 sc->max_devices), M_MPR, M_ZERO|M_NOWAIT); 2147 if (!sc->removal_table) 2148 goto free_resources; 2149 2150 sc->enclosure_table = kmalloc((sizeof(struct enc_mapping_table) * 2151 sc->max_enclosures), M_MPR, M_ZERO|M_NOWAIT); 2152 if (!sc->enclosure_table) 2153 goto free_resources; 2154 2155 sc->dpm_entry_used = kmalloc((sizeof(u8) * sc->max_dpm_entries), 2156 M_MPR, M_ZERO|M_NOWAIT); 2157 if (!sc->dpm_entry_used) 2158 goto free_resources; 2159 2160 sc->dpm_flush_entry = kmalloc((sizeof(u8) * sc->max_dpm_entries), 2161 M_MPR, M_ZERO|M_NOWAIT); 2162 if (!sc->dpm_flush_entry) 2163 goto free_resources; 2164 2165 dpm_pg0_sz = sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER) + 2166 (sc->max_dpm_entries * sizeof(MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY)); 2167 2168 sc->dpm_pg0 = kmalloc(dpm_pg0_sz, M_MPR, M_ZERO|M_NOWAIT); 2169 if (!sc->dpm_pg0) { 2170 kprintf("%s: memory alloc failed for dpm page; disabling dpm\n", 2171 __func__); 2172 sc->is_dpm_enable = 0; 2173 } 2174 2175 return 0; 2176 2177 free_resources: 2178 kfree(sc->mapping_table, M_MPR); 2179 kfree(sc->removal_table, M_MPR); 2180 kfree(sc->enclosure_table, M_MPR); 2181 kfree(sc->dpm_entry_used, M_MPR); 2182 kfree(sc->dpm_flush_entry, M_MPR); 2183 kfree(sc->dpm_pg0, M_MPR); 2184 kprintf("%s: device initialization failed due to failure in mapping " 2185 "table memory allocation\n", __func__); 2186 return -1; 2187 } 2188 2189 /** 2190 * mpr_mapping_free_memory- frees the memory allocated for mapping tables 2191 * @sc: per adapter object 2192 * 2193 * Returns nothing. 2194 */ 2195 void 2196 mpr_mapping_free_memory(struct mpr_softc *sc) 2197 { 2198 kfree(sc->mapping_table, M_MPR); 2199 kfree(sc->removal_table, M_MPR); 2200 kfree(sc->enclosure_table, M_MPR); 2201 kfree(sc->dpm_entry_used, M_MPR); 2202 kfree(sc->dpm_flush_entry, M_MPR); 2203 kfree(sc->dpm_pg0, M_MPR); 2204 } 2205 2206 static bool 2207 _mapping_process_dpm_pg0(struct mpr_softc *sc) 2208 { 2209 u8 missing_cnt, enc_idx; 2210 u16 slot_id, entry_num, num_slots; 2211 u32 map_idx, dev_idx; 2212 u32 start_idx = 0, end_idx = 0; /* XXX swildner: warning fix */ 2213 struct dev_mapping_table *mt_entry; 2214 Mpi2DriverMap0Entry_t *dpm_entry; 2215 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 2216 u16 max_num_phy_ids = le16toh(sc->ioc_pg8.MaxNumPhysicalMappedIDs); 2217 struct enc_mapping_table *et_entry; 2218 u64 physical_id; 2219 u32 phy_bits = 0; 2220 2221 /* 2222 * start_idx and end_idx are only used for IR. 2223 */ 2224 if (sc->ir_firmware) 2225 _mapping_get_ir_maprange(sc, &start_idx, &end_idx); 2226 2227 /* 2228 * Look through all of the DPM entries that were read from the 2229 * controller and copy them over to the driver's internal table if they 2230 * have a non-zero ID. At this point, any ID with a value of 0 would be 2231 * invalid, so don't copy it. 2232 */ 2233 mpr_dprint(sc, MPR_MAPPING, "%s: Start copy of %d DPM entries into the " 2234 "mapping table.\n", __func__, sc->max_dpm_entries); 2235 dpm_entry = (Mpi2DriverMap0Entry_t *) ((uint8_t *) sc->dpm_pg0 + 2236 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 2237 for (entry_num = 0; entry_num < sc->max_dpm_entries; entry_num++, 2238 dpm_entry++) { 2239 physical_id = dpm_entry->PhysicalIdentifier.High; 2240 physical_id = (physical_id << 32) | 2241 dpm_entry->PhysicalIdentifier.Low; 2242 if (!physical_id) { 2243 sc->dpm_entry_used[entry_num] = 0; 2244 continue; 2245 } 2246 sc->dpm_entry_used[entry_num] = 1; 2247 dpm_entry->MappingInformation = le16toh(dpm_entry-> 2248 MappingInformation); 2249 missing_cnt = dpm_entry->MappingInformation & 2250 MPI2_DRVMAP0_MAPINFO_MISSING_MASK; 2251 dev_idx = le16toh(dpm_entry->DeviceIndex); 2252 phy_bits = le32toh(dpm_entry->PhysicalBitsMapping); 2253 2254 /* 2255 * Volumes are at special locations in the mapping table so 2256 * account for that. Volume mapping table entries do not depend 2257 * on the type of mapping, so continue the loop after adding 2258 * volumes to the mapping table. 2259 */ 2260 if (sc->ir_firmware && (dev_idx >= start_idx) && 2261 (dev_idx <= end_idx)) { 2262 mt_entry = &sc->mapping_table[dev_idx]; 2263 mt_entry->physical_id = 2264 dpm_entry->PhysicalIdentifier.High; 2265 mt_entry->physical_id = (mt_entry->physical_id << 32) | 2266 dpm_entry->PhysicalIdentifier.Low; 2267 mt_entry->id = dev_idx; 2268 mt_entry->missing_count = missing_cnt; 2269 mt_entry->dpm_entry_num = entry_num; 2270 mt_entry->device_info = MPR_DEV_RESERVED; 2271 continue; 2272 } 2273 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 2274 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 2275 2276 /* 2277 * The dev_idx for an enclosure is the start index. If 2278 * the start index is within the controller's default 2279 * enclosure area, set the number of slots for this 2280 * enclosure to the max allowed. Otherwise, it should be 2281 * a normal enclosure and the number of slots is in the 2282 * DPM entry's Mapping Information. 2283 */ 2284 if (dev_idx < (sc->num_rsvd_entries + 2285 max_num_phy_ids)) { 2286 slot_id = 0; 2287 if (ioc_pg8_flags & 2288 MPI2_IOCPAGE8_FLAGS_DA_START_SLOT_1) 2289 slot_id = 1; 2290 num_slots = max_num_phy_ids; 2291 } else { 2292 slot_id = 0; 2293 num_slots = dpm_entry->MappingInformation & 2294 MPI2_DRVMAP0_MAPINFO_SLOT_MASK; 2295 num_slots >>= MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT; 2296 } 2297 enc_idx = sc->num_enc_table_entries; 2298 if (enc_idx >= sc->max_enclosures) { 2299 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: " 2300 "Number of enclosure entries in DPM exceed " 2301 "the max allowed of %d.\n", __func__, 2302 sc->max_enclosures); 2303 break; 2304 } 2305 sc->num_enc_table_entries++; 2306 et_entry = &sc->enclosure_table[enc_idx]; 2307 physical_id = dpm_entry->PhysicalIdentifier.High; 2308 et_entry->enclosure_id = (physical_id << 32) | 2309 dpm_entry->PhysicalIdentifier.Low; 2310 et_entry->start_index = dev_idx; 2311 et_entry->dpm_entry_num = entry_num; 2312 et_entry->num_slots = num_slots; 2313 et_entry->start_slot = slot_id; 2314 et_entry->missing_count = missing_cnt; 2315 et_entry->phy_bits = phy_bits; 2316 2317 /* 2318 * Initialize all entries for this enclosure in the 2319 * mapping table and mark them as reserved. The actual 2320 * devices have not been processed yet but when they are 2321 * they will use these entries. If an entry is found 2322 * that already has a valid DPM index, the mapping table 2323 * is corrupt. This can happen if the mapping type is 2324 * changed without clearing all of the DPM entries in 2325 * the controller. 2326 */ 2327 mt_entry = &sc->mapping_table[dev_idx]; 2328 for (map_idx = dev_idx; map_idx < (dev_idx + num_slots); 2329 map_idx++, mt_entry++) { 2330 if (mt_entry->dpm_entry_num != 2331 MPR_DPM_BAD_IDX) { 2332 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, 2333 "%s: Conflict in mapping table for " 2334 " enclosure %d\n", __func__, 2335 enc_idx); 2336 goto fail; 2337 } 2338 physical_id = 2339 dpm_entry->PhysicalIdentifier.High; 2340 mt_entry->physical_id = (physical_id << 32) | 2341 dpm_entry->PhysicalIdentifier.Low; 2342 mt_entry->phy_bits = phy_bits; 2343 mt_entry->id = dev_idx; 2344 mt_entry->dpm_entry_num = entry_num; 2345 mt_entry->missing_count = missing_cnt; 2346 mt_entry->device_info = MPR_DEV_RESERVED; 2347 } 2348 } else if ((ioc_pg8_flags & 2349 MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 2350 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) { 2351 2352 /* 2353 * Device mapping, so simply copy the DPM entries to the 2354 * mapping table, but check for a corrupt mapping table 2355 * (as described above in Enc/Slot mapping). 2356 */ 2357 map_idx = dev_idx; 2358 mt_entry = &sc->mapping_table[map_idx]; 2359 if (mt_entry->dpm_entry_num != MPR_DPM_BAD_IDX) { 2360 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: " 2361 "Conflict in mapping table for device %d\n", 2362 __func__, map_idx); 2363 goto fail; 2364 } 2365 physical_id = dpm_entry->PhysicalIdentifier.High; 2366 mt_entry->physical_id = (physical_id << 32) | 2367 dpm_entry->PhysicalIdentifier.Low; 2368 mt_entry->phy_bits = phy_bits; 2369 mt_entry->id = dev_idx; 2370 mt_entry->missing_count = missing_cnt; 2371 mt_entry->dpm_entry_num = entry_num; 2372 mt_entry->device_info = MPR_DEV_RESERVED; 2373 } 2374 } /*close the loop for DPM table */ 2375 return (true); 2376 2377 fail: 2378 for (entry_num = 0; entry_num < sc->max_dpm_entries; entry_num++) { 2379 sc->dpm_entry_used[entry_num] = 0; 2380 /* 2381 * for IR firmware, it may be necessary to wipe out 2382 * sc->mapping_table volumes tooi 2383 */ 2384 } 2385 sc->num_enc_table_entries = 0; 2386 return (false); 2387 } 2388 2389 /* 2390 * mpr_mapping_check_devices - start of the day check for device availabilty 2391 * @sc: per adapter object 2392 * 2393 * Returns nothing. 2394 */ 2395 void 2396 mpr_mapping_check_devices(void *data) 2397 { 2398 u32 i; 2399 struct dev_mapping_table *mt_entry; 2400 struct mpr_softc *sc = (struct mpr_softc *)data; 2401 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 2402 struct enc_mapping_table *et_entry; 2403 u32 start_idx = 0, end_idx = 0; 2404 u8 stop_device_checks = 0; 2405 2406 MPR_FUNCTRACE(sc); 2407 2408 /* 2409 * Clear this flag so that this function is never called again except 2410 * within this function if the check needs to be done again. The 2411 * purpose is to check for missing devices that are currently in the 2412 * mapping table so do this only at driver init after discovery. 2413 */ 2414 sc->track_mapping_events = 0; 2415 2416 /* 2417 * callout synchronization 2418 * This is used to prevent race conditions for the callout. 2419 */ 2420 mpr_dprint(sc, MPR_MAPPING, "%s: Start check for missing devices.\n", 2421 __func__); 2422 KKASSERT(lockowned(&sc->mpr_lock)); 2423 if ((callout_pending(&sc->device_check_callout)) || 2424 (!callout_active(&sc->device_check_callout))) { 2425 mpr_dprint(sc, MPR_MAPPING, "%s: Device Check Callout is " 2426 "already pending or not active.\n", __func__); 2427 return; 2428 } 2429 callout_deactivate(&sc->device_check_callout); 2430 2431 /* 2432 * Use callout to check if any devices in the mapping table have been 2433 * processed yet. If ALL devices are marked as not init_complete, no 2434 * devices have been processed and mapped. Until devices are mapped 2435 * there's no reason to mark them as missing. Continue resetting this 2436 * callout until devices have been mapped. 2437 */ 2438 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 2439 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 2440 et_entry = sc->enclosure_table; 2441 for (i = 0; i < sc->num_enc_table_entries; i++, et_entry++) { 2442 if (et_entry->init_complete) { 2443 stop_device_checks = 1; 2444 break; 2445 } 2446 } 2447 } else if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 2448 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) { 2449 mt_entry = sc->mapping_table; 2450 for (i = 0; i < sc->max_devices; i++, mt_entry++) { 2451 if (mt_entry->init_complete) { 2452 stop_device_checks = 1; 2453 break; 2454 } 2455 } 2456 } 2457 2458 /* 2459 * Setup another callout check after a delay. Keep doing this until 2460 * devices are mapped. 2461 */ 2462 if (!stop_device_checks) { 2463 mpr_dprint(sc, MPR_MAPPING, "%s: No devices have been mapped. " 2464 "Reset callout to check again after a %d second delay.\n", 2465 __func__, MPR_MISSING_CHECK_DELAY); 2466 callout_reset(&sc->device_check_callout, 2467 MPR_MISSING_CHECK_DELAY * hz, mpr_mapping_check_devices, 2468 sc); 2469 return; 2470 } 2471 mpr_dprint(sc, MPR_MAPPING, "%s: Device check complete.\n", __func__); 2472 2473 /* 2474 * Depending on the mapping type, check if devices have been processed 2475 * and update their missing counts if not processed. 2476 */ 2477 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 2478 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { 2479 et_entry = sc->enclosure_table; 2480 for (i = 0; i < sc->num_enc_table_entries; i++, et_entry++) { 2481 if (!et_entry->init_complete) { 2482 if (et_entry->missing_count < 2483 MPR_MAX_MISSING_COUNT) { 2484 mpr_dprint(sc, MPR_MAPPING, "%s: " 2485 "Enclosure %d is missing from the " 2486 "topology. Update its missing " 2487 "count.\n", __func__, i); 2488 et_entry->missing_count++; 2489 if (et_entry->dpm_entry_num != 2490 MPR_DPM_BAD_IDX) { 2491 _mapping_commit_enc_entry(sc, 2492 et_entry); 2493 } 2494 } 2495 et_entry->init_complete = 1; 2496 } 2497 } 2498 if (!sc->ir_firmware) 2499 return; 2500 _mapping_get_ir_maprange(sc, &start_idx, &end_idx); 2501 mt_entry = &sc->mapping_table[start_idx]; 2502 } else if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == 2503 MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) { 2504 start_idx = 0; 2505 end_idx = sc->max_devices - 1; 2506 mt_entry = sc->mapping_table; 2507 } 2508 2509 /* 2510 * The start and end indices have been set above according to the 2511 * mapping type. Go through these mappings and update any entries that 2512 * do not have the init_complete flag set, which means they are missing. 2513 */ 2514 if (end_idx == 0) 2515 return; 2516 for (i = start_idx; i < (end_idx + 1); i++, mt_entry++) { 2517 if (mt_entry->device_info & MPR_DEV_RESERVED 2518 && !mt_entry->physical_id) 2519 mt_entry->init_complete = 1; 2520 else if (mt_entry->device_info & MPR_DEV_RESERVED) { 2521 if (!mt_entry->init_complete) { 2522 mpr_dprint(sc, MPR_MAPPING, "%s: Device in " 2523 "mapping table at index %d is missing from " 2524 "topology. Update its missing count.\n", 2525 __func__, i); 2526 if (mt_entry->missing_count < 2527 MPR_MAX_MISSING_COUNT) { 2528 mt_entry->missing_count++; 2529 if (mt_entry->dpm_entry_num != 2530 MPR_DPM_BAD_IDX) { 2531 _mapping_commit_map_entry(sc, 2532 mt_entry); 2533 } 2534 } 2535 mt_entry->init_complete = 1; 2536 } 2537 } 2538 } 2539 } 2540 2541 /** 2542 * mpr_mapping_initialize - initialize mapping tables 2543 * @sc: per adapter object 2544 * 2545 * Read controller persitant mapping tables into internal data area. 2546 * 2547 * Return 0 for success or non-zero for failure. 2548 */ 2549 int 2550 mpr_mapping_initialize(struct mpr_softc *sc) 2551 { 2552 uint16_t volume_mapping_flags, dpm_pg0_sz; 2553 uint32_t i; 2554 Mpi2ConfigReply_t mpi_reply; 2555 int error; 2556 uint8_t retry_count; 2557 uint16_t ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 2558 2559 /* The additional 1 accounts for the virtual enclosure 2560 * created for the controller 2561 */ 2562 sc->max_enclosures = sc->facts->MaxEnclosures + 1; 2563 sc->max_expanders = sc->facts->MaxSasExpanders; 2564 sc->max_volumes = sc->facts->MaxVolumes; 2565 sc->max_devices = sc->facts->MaxTargets + sc->max_volumes; 2566 sc->pending_map_events = 0; 2567 sc->num_enc_table_entries = 0; 2568 sc->num_rsvd_entries = 0; 2569 sc->max_dpm_entries = sc->ioc_pg8.MaxPersistentEntries; 2570 sc->is_dpm_enable = (sc->max_dpm_entries) ? 1 : 0; 2571 sc->track_mapping_events = 0; 2572 2573 mpr_dprint(sc, MPR_MAPPING, "%s: Mapping table has a max of %d entries " 2574 "and DPM has a max of %d entries.\n", __func__, sc->max_devices, 2575 sc->max_dpm_entries); 2576 2577 if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_DISABLE_PERSISTENT_MAPPING) 2578 sc->is_dpm_enable = 0; 2579 2580 if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0) 2581 sc->num_rsvd_entries = 1; 2582 2583 volume_mapping_flags = sc->ioc_pg8.IRVolumeMappingFlags & 2584 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE; 2585 if (sc->ir_firmware && (volume_mapping_flags == 2586 MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING)) 2587 sc->num_rsvd_entries += sc->max_volumes; 2588 2589 error = mpr_mapping_allocate_memory(sc); 2590 if (error) 2591 return (error); 2592 2593 for (i = 0; i < sc->max_devices; i++) 2594 _mapping_clear_map_entry(sc->mapping_table + i); 2595 2596 for (i = 0; i < sc->max_enclosures; i++) 2597 _mapping_clear_enc_entry(sc->enclosure_table + i); 2598 2599 for (i = 0; i < sc->max_devices; i++) { 2600 sc->removal_table[i].dev_handle = 0; 2601 sc->removal_table[i].dpm_entry_num = MPR_DPM_BAD_IDX; 2602 } 2603 2604 memset(sc->dpm_entry_used, 0, sc->max_dpm_entries); 2605 memset(sc->dpm_flush_entry, 0, sc->max_dpm_entries); 2606 2607 if (sc->is_dpm_enable) { 2608 dpm_pg0_sz = sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER) + 2609 (sc->max_dpm_entries * 2610 sizeof(MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY)); 2611 retry_count = 0; 2612 2613 retry_read_dpm: 2614 if (mpr_config_get_dpm_pg0(sc, &mpi_reply, sc->dpm_pg0, 2615 dpm_pg0_sz)) { 2616 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: DPM page " 2617 "read failed.\n", __func__); 2618 if (retry_count < 3) { 2619 retry_count++; 2620 goto retry_read_dpm; 2621 } 2622 sc->is_dpm_enable = 0; 2623 } 2624 } 2625 2626 if (sc->is_dpm_enable) { 2627 if (!_mapping_process_dpm_pg0(sc)) 2628 sc->is_dpm_enable = 0; 2629 } 2630 if (! sc->is_dpm_enable) { 2631 mpr_dprint(sc, MPR_MAPPING, "%s: DPM processing is disabled. " 2632 "Device mappings will not persist across reboots or " 2633 "resets.\n", __func__); 2634 } 2635 2636 sc->track_mapping_events = 1; 2637 return 0; 2638 } 2639 2640 /** 2641 * mpr_mapping_exit - clear mapping table and associated memory 2642 * @sc: per adapter object 2643 * 2644 * Returns nothing. 2645 */ 2646 void 2647 mpr_mapping_exit(struct mpr_softc *sc) 2648 { 2649 _mapping_flush_dpm_pages(sc); 2650 mpr_mapping_free_memory(sc); 2651 } 2652 2653 /** 2654 * mpr_mapping_get_tid - return the target id for sas device and handle 2655 * @sc: per adapter object 2656 * @sas_address: sas address of the device 2657 * @handle: device handle 2658 * 2659 * Returns valid target ID on success or BAD_ID. 2660 */ 2661 unsigned int 2662 mpr_mapping_get_tid(struct mpr_softc *sc, uint64_t sas_address, u16 handle) 2663 { 2664 u32 map_idx; 2665 struct dev_mapping_table *mt_entry; 2666 2667 for (map_idx = 0; map_idx < sc->max_devices; map_idx++) { 2668 mt_entry = &sc->mapping_table[map_idx]; 2669 if (mt_entry->dev_handle == handle && mt_entry->physical_id == 2670 sas_address) 2671 return mt_entry->id; 2672 } 2673 2674 return MPR_MAP_BAD_ID; 2675 } 2676 2677 /** 2678 * mpr_mapping_get_tid_from_handle - find a target id in mapping table using 2679 * only the dev handle. This is just a wrapper function for the local function 2680 * _mapping_get_mt_idx_from_handle. 2681 * @sc: per adapter object 2682 * @handle: device handle 2683 * 2684 * Returns valid target ID on success or BAD_ID. 2685 */ 2686 unsigned int 2687 mpr_mapping_get_tid_from_handle(struct mpr_softc *sc, u16 handle) 2688 { 2689 return (_mapping_get_mt_idx_from_handle(sc, handle)); 2690 } 2691 2692 /** 2693 * mpr_mapping_get_raid_tid - return the target id for raid device 2694 * @sc: per adapter object 2695 * @wwid: world wide identifier for raid volume 2696 * @volHandle: volume device handle 2697 * 2698 * Returns valid target ID on success or BAD_ID. 2699 */ 2700 unsigned int 2701 mpr_mapping_get_raid_tid(struct mpr_softc *sc, u64 wwid, u16 volHandle) 2702 { 2703 u32 start_idx, end_idx, map_idx; 2704 struct dev_mapping_table *mt_entry; 2705 2706 _mapping_get_ir_maprange(sc, &start_idx, &end_idx); 2707 mt_entry = &sc->mapping_table[start_idx]; 2708 for (map_idx = start_idx; map_idx <= end_idx; map_idx++, mt_entry++) { 2709 if (mt_entry->dev_handle == volHandle && 2710 mt_entry->physical_id == wwid) 2711 return mt_entry->id; 2712 } 2713 2714 return MPR_MAP_BAD_ID; 2715 } 2716 2717 /** 2718 * mpr_mapping_get_raid_tid_from_handle - find raid device in mapping table 2719 * using only the volume dev handle. This is just a wrapper function for the 2720 * local function _mapping_get_ir_mt_idx_from_handle. 2721 * @sc: per adapter object 2722 * @volHandle: volume device handle 2723 * 2724 * Returns valid target ID on success or BAD_ID. 2725 */ 2726 unsigned int 2727 mpr_mapping_get_raid_tid_from_handle(struct mpr_softc *sc, u16 volHandle) 2728 { 2729 return (_mapping_get_ir_mt_idx_from_handle(sc, volHandle)); 2730 } 2731 2732 /** 2733 * mpr_mapping_enclosure_dev_status_change_event - handle enclosure events 2734 * @sc: per adapter object 2735 * @event_data: event data payload 2736 * 2737 * Return nothing. 2738 */ 2739 void 2740 mpr_mapping_enclosure_dev_status_change_event(struct mpr_softc *sc, 2741 Mpi2EventDataSasEnclDevStatusChange_t *event_data) 2742 { 2743 u8 enc_idx, missing_count; 2744 struct enc_mapping_table *et_entry; 2745 Mpi2DriverMap0Entry_t *dpm_entry; 2746 u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); 2747 u8 map_shift = MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT; 2748 u8 update_phy_bits = 0; 2749 u32 saved_phy_bits; 2750 uint64_t temp64_var; 2751 2752 if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) != 2753 MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) 2754 goto out; 2755 2756 dpm_entry = (Mpi2DriverMap0Entry_t *)((u8 *)sc->dpm_pg0 + 2757 sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER)); 2758 2759 if (event_data->ReasonCode == MPI2_EVENT_SAS_ENCL_RC_ADDED) { 2760 if (!event_data->NumSlots) { 2761 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: Enclosure " 2762 "with handle = 0x%x reported 0 slots.\n", __func__, 2763 le16toh(event_data->EnclosureHandle)); 2764 goto out; 2765 } 2766 temp64_var = event_data->EnclosureLogicalID.High; 2767 temp64_var = (temp64_var << 32) | 2768 event_data->EnclosureLogicalID.Low; 2769 enc_idx = _mapping_get_enc_idx_from_id(sc, temp64_var, 2770 event_data->PhyBits); 2771 2772 /* 2773 * If the Added enclosure is already in the Enclosure Table, 2774 * make sure that all the the enclosure info is up to date. If 2775 * the enclosure was missing and has just been added back, or if 2776 * the enclosure's Phy Bits have changed, clear the missing 2777 * count and update the Phy Bits in the mapping table and in the 2778 * DPM, if it's being used. 2779 */ 2780 if (enc_idx != MPR_ENCTABLE_BAD_IDX) { 2781 et_entry = &sc->enclosure_table[enc_idx]; 2782 if (et_entry->init_complete && 2783 !et_entry->missing_count) { 2784 mpr_dprint(sc, MPR_MAPPING, "%s: Enclosure %d " 2785 "is already present with handle = 0x%x\n", 2786 __func__, enc_idx, et_entry->enc_handle); 2787 goto out; 2788 } 2789 et_entry->enc_handle = le16toh(event_data-> 2790 EnclosureHandle); 2791 et_entry->start_slot = le16toh(event_data->StartSlot); 2792 saved_phy_bits = et_entry->phy_bits; 2793 et_entry->phy_bits |= le32toh(event_data->PhyBits); 2794 if (saved_phy_bits != et_entry->phy_bits) 2795 update_phy_bits = 1; 2796 if (et_entry->missing_count || update_phy_bits) { 2797 et_entry->missing_count = 0; 2798 if (sc->is_dpm_enable && 2799 et_entry->dpm_entry_num != 2800 MPR_DPM_BAD_IDX) { 2801 dpm_entry += et_entry->dpm_entry_num; 2802 missing_count = 2803 (u8)(dpm_entry->MappingInformation & 2804 MPI2_DRVMAP0_MAPINFO_MISSING_MASK); 2805 if (missing_count || update_phy_bits) { 2806 dpm_entry->MappingInformation 2807 = et_entry->num_slots; 2808 dpm_entry->MappingInformation 2809 <<= map_shift; 2810 dpm_entry->PhysicalBitsMapping 2811 = et_entry->phy_bits; 2812 sc->dpm_flush_entry[et_entry-> 2813 dpm_entry_num] = 1; 2814 } 2815 } 2816 } 2817 } else { 2818 /* 2819 * This is a new enclosure that is being added. 2820 * Initialize the Enclosure Table entry. It will be 2821 * finalized when a device is added for the enclosure 2822 * and the enclosure has enough space in the Mapping 2823 * Table to map its devices. 2824 */ 2825 enc_idx = sc->num_enc_table_entries; 2826 if (enc_idx >= sc->max_enclosures) { 2827 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: " 2828 "Enclosure cannot be added to mapping " 2829 "table because it's full.\n", __func__); 2830 goto out; 2831 } 2832 sc->num_enc_table_entries++; 2833 et_entry = &sc->enclosure_table[enc_idx]; 2834 et_entry->enc_handle = le16toh(event_data-> 2835 EnclosureHandle); 2836 et_entry->enclosure_id = le64toh(event_data-> 2837 EnclosureLogicalID.High); 2838 et_entry->enclosure_id = 2839 ((et_entry->enclosure_id << 32) | 2840 le64toh(event_data->EnclosureLogicalID.Low)); 2841 et_entry->start_index = MPR_MAPTABLE_BAD_IDX; 2842 et_entry->dpm_entry_num = MPR_DPM_BAD_IDX; 2843 et_entry->num_slots = le16toh(event_data->NumSlots); 2844 et_entry->start_slot = le16toh(event_data->StartSlot); 2845 et_entry->phy_bits = le32toh(event_data->PhyBits); 2846 } 2847 et_entry->init_complete = 1; 2848 } else if (event_data->ReasonCode == 2849 MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING) { 2850 /* 2851 * An enclosure was removed. Update its missing count and then 2852 * update the DPM entry with the new missing count for the 2853 * enclosure. 2854 */ 2855 enc_idx = _mapping_get_enc_idx_from_handle(sc, 2856 le16toh(event_data->EnclosureHandle)); 2857 if (enc_idx == MPR_ENCTABLE_BAD_IDX) { 2858 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: Cannot " 2859 "unmap enclosure %d because it has already been " 2860 "deleted.\n", __func__, enc_idx); 2861 goto out; 2862 } 2863 et_entry = &sc->enclosure_table[enc_idx]; 2864 if (et_entry->missing_count < MPR_MAX_MISSING_COUNT) 2865 et_entry->missing_count++; 2866 if (sc->is_dpm_enable && 2867 et_entry->dpm_entry_num != MPR_DPM_BAD_IDX) { 2868 dpm_entry += et_entry->dpm_entry_num; 2869 dpm_entry->MappingInformation = et_entry->num_slots; 2870 dpm_entry->MappingInformation <<= map_shift; 2871 dpm_entry->MappingInformation |= 2872 et_entry->missing_count; 2873 sc->dpm_flush_entry[et_entry->dpm_entry_num] = 1; 2874 } 2875 et_entry->init_complete = 1; 2876 } 2877 2878 out: 2879 _mapping_flush_dpm_pages(sc); 2880 if (sc->pending_map_events) 2881 sc->pending_map_events--; 2882 } 2883 2884 /** 2885 * mpr_mapping_topology_change_event - handle topology change events 2886 * @sc: per adapter object 2887 * @event_data: event data payload 2888 * 2889 * Returns nothing. 2890 */ 2891 void 2892 mpr_mapping_topology_change_event(struct mpr_softc *sc, 2893 Mpi2EventDataSasTopologyChangeList_t *event_data) 2894 { 2895 struct _map_topology_change topo_change; 2896 struct _map_phy_change *phy_change; 2897 Mpi2EventSasTopoPhyEntry_t *event_phy_change; 2898 u8 i, num_entries; 2899 2900 topo_change.enc_handle = le16toh(event_data->EnclosureHandle); 2901 topo_change.exp_handle = le16toh(event_data->ExpanderDevHandle); 2902 num_entries = event_data->NumEntries; 2903 topo_change.num_entries = num_entries; 2904 topo_change.start_phy_num = event_data->StartPhyNum; 2905 topo_change.num_phys = event_data->NumPhys; 2906 topo_change.exp_status = event_data->ExpStatus; 2907 event_phy_change = event_data->PHY; 2908 topo_change.phy_details = NULL; 2909 2910 if (!num_entries) 2911 goto out; 2912 phy_change = kmalloc(sizeof(struct _map_phy_change) * num_entries, 2913 M_MPR, M_NOWAIT|M_ZERO); 2914 topo_change.phy_details = phy_change; 2915 if (!phy_change) 2916 goto out; 2917 for (i = 0; i < num_entries; i++, event_phy_change++, phy_change++) { 2918 phy_change->dev_handle = le16toh(event_phy_change-> 2919 AttachedDevHandle); 2920 phy_change->reason = event_phy_change->PhyStatus & 2921 MPI2_EVENT_SAS_TOPO_RC_MASK; 2922 } 2923 _mapping_update_missing_count(sc, &topo_change); 2924 _mapping_get_dev_info(sc, &topo_change); 2925 _mapping_clear_removed_entries(sc); 2926 _mapping_add_new_device(sc, &topo_change); 2927 2928 out: 2929 kfree(topo_change.phy_details, M_MPR); 2930 _mapping_flush_dpm_pages(sc); 2931 if (sc->pending_map_events) 2932 sc->pending_map_events--; 2933 } 2934 2935 /** 2936 * mpr_mapping_pcie_topology_change_event - handle PCIe topology change events 2937 * @sc: per adapter object 2938 * @event_data: event data payload 2939 * 2940 * Returns nothing. 2941 */ 2942 void 2943 mpr_mapping_pcie_topology_change_event(struct mpr_softc *sc, 2944 Mpi26EventDataPCIeTopologyChangeList_t *event_data) 2945 { 2946 struct _map_pcie_topology_change topo_change; 2947 struct _map_port_change *port_change; 2948 Mpi26EventPCIeTopoPortEntry_t *event_port_change; 2949 u8 i, num_entries; 2950 2951 topo_change.switch_dev_handle = le16toh(event_data->SwitchDevHandle); 2952 topo_change.enc_handle = le16toh(event_data->EnclosureHandle); 2953 num_entries = event_data->NumEntries; 2954 topo_change.num_entries = num_entries; 2955 topo_change.start_port_num = event_data->StartPortNum; 2956 topo_change.num_ports = event_data->NumPorts; 2957 topo_change.switch_status = event_data->SwitchStatus; 2958 event_port_change = event_data->PortEntry; 2959 topo_change.port_details = NULL; 2960 2961 if (!num_entries) 2962 goto out; 2963 port_change = kmalloc(sizeof(struct _map_port_change) * num_entries, 2964 M_MPR, M_NOWAIT|M_ZERO); 2965 topo_change.port_details = port_change; 2966 if (!port_change) 2967 goto out; 2968 for (i = 0; i < num_entries; i++, event_port_change++, port_change++) { 2969 port_change->dev_handle = le16toh(event_port_change-> 2970 AttachedDevHandle); 2971 port_change->reason = event_port_change->PortStatus; 2972 } 2973 _mapping_update_pcie_missing_count(sc, &topo_change); 2974 _mapping_get_pcie_dev_info(sc, &topo_change); 2975 _mapping_clear_removed_entries(sc); 2976 _mapping_add_new_pcie_device(sc, &topo_change); 2977 2978 out: 2979 kfree(topo_change.port_details, M_MPR); 2980 _mapping_flush_dpm_pages(sc); 2981 if (sc->pending_map_events) 2982 sc->pending_map_events--; 2983 } 2984 2985 /** 2986 * mpr_mapping_ir_config_change_event - handle IR config change list events 2987 * @sc: per adapter object 2988 * @event_data: event data payload 2989 * 2990 * Returns nothing. 2991 */ 2992 void 2993 mpr_mapping_ir_config_change_event(struct mpr_softc *sc, 2994 Mpi2EventDataIrConfigChangeList_t *event_data) 2995 { 2996 Mpi2EventIrConfigElement_t *element; 2997 int i; 2998 u64 *wwid_table; 2999 u32 map_idx, flags; 3000 struct dev_mapping_table *mt_entry; 3001 u16 element_flags; 3002 3003 wwid_table = kmalloc(sizeof(u64) * event_data->NumElements, M_MPR, 3004 M_NOWAIT | M_ZERO); 3005 if (!wwid_table) 3006 goto out; 3007 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; 3008 flags = le32toh(event_data->Flags); 3009 3010 /* 3011 * For volume changes, get the WWID for the volume and put it in a 3012 * table to be used in the processing of the IR change event. 3013 */ 3014 for (i = 0; i < event_data->NumElements; i++, element++) { 3015 element_flags = le16toh(element->ElementFlags); 3016 if ((element->ReasonCode != MPI2_EVENT_IR_CHANGE_RC_ADDED) && 3017 (element->ReasonCode != MPI2_EVENT_IR_CHANGE_RC_REMOVED) && 3018 (element->ReasonCode != MPI2_EVENT_IR_CHANGE_RC_NO_CHANGE) 3019 && (element->ReasonCode != 3020 MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED)) 3021 continue; 3022 if ((element_flags & 3023 MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK) == 3024 MPI2_EVENT_IR_CHANGE_EFLAGS_VOLUME_ELEMENT) { 3025 mpr_config_get_volume_wwid(sc, 3026 le16toh(element->VolDevHandle), &wwid_table[i]); 3027 } 3028 } 3029 3030 /* 3031 * Check the ReasonCode for each element in the IR event and Add/Remove 3032 * Volumes or Physical Disks of Volumes to/from the mapping table. Use 3033 * the WWIDs gotten above in wwid_table. 3034 */ 3035 if (flags == MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) 3036 goto out; 3037 else { 3038 element = (Mpi2EventIrConfigElement_t *)&event_data-> 3039 ConfigElement[0]; 3040 for (i = 0; i < event_data->NumElements; i++, element++) { 3041 if (element->ReasonCode == 3042 MPI2_EVENT_IR_CHANGE_RC_ADDED || 3043 element->ReasonCode == 3044 MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED) { 3045 map_idx = _mapping_get_ir_mt_idx_from_wwid 3046 (sc, wwid_table[i]); 3047 if (map_idx != MPR_MAPTABLE_BAD_IDX) { 3048 /* 3049 * The volume is already in the mapping 3050 * table. Just update it's info. 3051 */ 3052 mt_entry = &sc->mapping_table[map_idx]; 3053 mt_entry->id = map_idx; 3054 mt_entry->dev_handle = le16toh 3055 (element->VolDevHandle); 3056 mt_entry->device_info = 3057 MPR_DEV_RESERVED | MPR_MAP_IN_USE; 3058 _mapping_update_ir_missing_cnt(sc, 3059 map_idx, element, wwid_table[i]); 3060 continue; 3061 } 3062 3063 /* 3064 * Volume is not in mapping table yet. Find a 3065 * free entry in the mapping table at the 3066 * volume mapping locations. If no entries are 3067 * available, this is an error because it means 3068 * there are more volumes than can be mapped 3069 * and that should never happen for volumes. 3070 */ 3071 map_idx = _mapping_get_free_ir_mt_idx(sc); 3072 if (map_idx == MPR_MAPTABLE_BAD_IDX) 3073 { 3074 mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, 3075 "%s: failed to add the volume with " 3076 "handle 0x%04x because there is no " 3077 "free space available in the " 3078 "mapping table\n", __func__, 3079 le16toh(element->VolDevHandle)); 3080 continue; 3081 } 3082 mt_entry = &sc->mapping_table[map_idx]; 3083 mt_entry->physical_id = wwid_table[i]; 3084 mt_entry->id = map_idx; 3085 mt_entry->dev_handle = le16toh(element-> 3086 VolDevHandle); 3087 mt_entry->device_info = MPR_DEV_RESERVED | 3088 MPR_MAP_IN_USE; 3089 _mapping_update_ir_missing_cnt(sc, map_idx, 3090 element, wwid_table[i]); 3091 } else if (element->ReasonCode == 3092 MPI2_EVENT_IR_CHANGE_RC_REMOVED) { 3093 map_idx = _mapping_get_ir_mt_idx_from_wwid(sc, 3094 wwid_table[i]); 3095 if (map_idx == MPR_MAPTABLE_BAD_IDX) { 3096 mpr_dprint(sc, MPR_MAPPING,"%s: Failed " 3097 "to remove a volume because it has " 3098 "already been removed.\n", 3099 __func__); 3100 continue; 3101 } 3102 _mapping_update_ir_missing_cnt(sc, map_idx, 3103 element, wwid_table[i]); 3104 } else if (element->ReasonCode == 3105 MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED) { 3106 map_idx = _mapping_get_mt_idx_from_handle(sc, 3107 le16toh(element->VolDevHandle)); 3108 if (map_idx == MPR_MAPTABLE_BAD_IDX) { 3109 mpr_dprint(sc, MPR_MAPPING,"%s: Failed " 3110 "to remove volume with handle " 3111 "0x%04x because it has already " 3112 "been removed.\n", __func__, 3113 le16toh(element->VolDevHandle)); 3114 continue; 3115 } 3116 mt_entry = &sc->mapping_table[map_idx]; 3117 _mapping_update_ir_missing_cnt(sc, map_idx, 3118 element, mt_entry->physical_id); 3119 } 3120 } 3121 } 3122 3123 out: 3124 _mapping_flush_dpm_pages(sc); 3125 kfree(wwid_table, M_MPR); 3126 if (sc->pending_map_events) 3127 sc->pending_map_events--; 3128 } 3129