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