Index: sys/dev/mpr/mpr_sas_lsi.c =================================================================== --- sys/dev/mpr/mpr_sas_lsi.c +++ sys/dev/mpr/mpr_sas_lsi.c @@ -839,23 +839,30 @@ /* * use_phynum: - * 1 - use the PhyNum field as a fallback to the mapping logic + * 1 - use the PhyNum (and other) fields as fallback to the mapping logic * 0 - never use the PhyNum field * -1 - only use the PhyNum field * - * Note that using the Phy number to map a device can cause device adds - * to fail if multiple enclosures/expanders are in the topology. For - * example, if two devices are in the same slot number in two different - * enclosures within the topology, only one of those devices will be - * added. PhyNum mapping should not be used if multiple enclosures are - * in the topology. + * Note that the fallback logic is falliable, and should only be used + * if the mapping logic isn't working. It will fail in the following + * situations: + * - A single enclosure has more than 128 slots + * - More than 8 enclosures are present on one bus + * - The SEP assigns the same slot number to multiple drives */ id = MPR_MAP_BAD_ID; if (sc->use_phynum != -1) id = mpr_mapping_get_tid(sc, sas_address, handle); if (id == MPR_MAP_BAD_ID) { - if ((sc->use_phynum == 0) || - ((id = config_page.PhyNum) > sassc->maxtargets)) { + /* + * No mapping table. Generate an id based on the + * EnclosureHandle and Slot. We can't use PhyNum alone because + * there may be multiple expanders on a single bus. Ditto for + * Slot. And we can't use EnclosureHandle + Phynum because some + * enclosures legitimately contain multiple expanders + */ + id = ((config_page.EnclosureHandle - 1) << 7) | config_page.Slot; + if ((sc->use_phynum == 0) || (id > sassc->maxtargets)) { mpr_dprint(sc, MPR_INFO, "failure at %s:%d/%s()! " "Could not get ID for device with handle 0x%04x\n", __FILE__, __LINE__, __func__, handle);