Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/mpr/mpr_sas_lsi.c
Show First 20 Lines • Show All 217 Lines • ▼ Show 20 Lines | case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: | ||||
for (i = 0; i < data->NumEntries; i++) { | for (i = 0; i < data->NumEntries; i++) { | ||||
phy = &data->PHY[i]; | phy = &data->PHY[i]; | ||||
switch (phy->PhyStatus & MPI2_EVENT_SAS_TOPO_RC_MASK) { | switch (phy->PhyStatus & MPI2_EVENT_SAS_TOPO_RC_MASK) { | ||||
case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: | case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: | ||||
if (mprsas_add_device(sc, | if (mprsas_add_device(sc, | ||||
le16toh(phy->AttachedDevHandle), | le16toh(phy->AttachedDevHandle), | ||||
phy->LinkRate)) { | phy->LinkRate)) { | ||||
printf("%s: failed to add device with " | mpr_dprint(sc, MPR_ERROR, "%s: " | ||||
"handle 0x%x\n", __func__, | "failed to add device with handle " | ||||
"0x%x\n", __func__, | |||||
le16toh(phy->AttachedDevHandle)); | le16toh(phy->AttachedDevHandle)); | ||||
mprsas_prepare_remove(sassc, le16toh( | mprsas_prepare_remove(sassc, le16toh( | ||||
phy->AttachedDevHandle)); | phy->AttachedDevHandle)); | ||||
} | } | ||||
break; | break; | ||||
case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: | case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: | ||||
mprsas_prepare_remove(sassc, le16toh( | mprsas_prepare_remove(sassc, le16toh( | ||||
phy->AttachedDevHandle)); | phy->AttachedDevHandle)); | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: | ||||
unsigned int id; | unsigned int id; | ||||
event_data = fw_event->event_data; | event_data = fw_event->event_data; | ||||
foreign_config = (le32toh(event_data->Flags) & | foreign_config = (le32toh(event_data->Flags) & | ||||
MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0; | MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0; | ||||
element = | element = | ||||
(Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; | (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; | ||||
id = mpr_mapping_get_raid_id_from_handle(sc, | id = mpr_mapping_get_raid_tid_from_handle(sc, | ||||
element->VolDevHandle); | element->VolDevHandle); | ||||
mpr_mapping_ir_config_change_event(sc, event_data); | mpr_mapping_ir_config_change_event(sc, event_data); | ||||
for (i = 0; i < event_data->NumElements; i++, element++) { | for (i = 0; i < event_data->NumElements; i++, element++) { | ||||
reason = element->ReasonCode; | reason = element->ReasonCode; | ||||
elementType = le16toh(element->ElementFlags) & | elementType = le16toh(element->ElementFlags) & | ||||
MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK; | MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK; | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 527 Lines • ▼ Show 20 Lines | if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) { | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* use_phynum: | * use_phynum: | ||||
* 1 - use the PhyNum field as a fallback to the mapping logic | * 1 - use the PhyNum field as a fallback to the mapping logic | ||||
* 0 - never use the PhyNum field | * 0 - never use the PhyNum field | ||||
* -1 - only 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. | |||||
*/ | */ | ||||
id = MPR_MAP_BAD_ID; | id = MPR_MAP_BAD_ID; | ||||
if (sc->use_phynum != -1) | if (sc->use_phynum != -1) | ||||
id = mpr_mapping_get_sas_id(sc, sas_address, handle); | id = mpr_mapping_get_tid(sc, sas_address, handle); | ||||
if (id == MPR_MAP_BAD_ID) { | if (id == MPR_MAP_BAD_ID) { | ||||
if ((sc->use_phynum == 0) || | if ((sc->use_phynum == 0) || | ||||
((id = config_page.PhyNum) > sassc->maxtargets)) { | ((id = config_page.PhyNum) > sassc->maxtargets)) { | ||||
mpr_dprint(sc, MPR_INFO, "failure at %s:%d/%s()! " | mpr_dprint(sc, MPR_INFO, "failure at %s:%d/%s()! " | ||||
"Could not get ID for device with handle 0x%04x\n", | "Could not get ID for device with handle 0x%04x\n", | ||||
__FILE__, __LINE__, __func__, handle); | __FILE__, __LINE__, __func__, handle); | ||||
error = ENXIO; | error = ENXIO; | ||||
goto out; | goto out; | ||||
} | } | ||||
} | } | ||||
mpr_dprint(sc, MPR_MAPPING, "%s: Target ID for added device is %d.\n", | |||||
__func__, id); | |||||
/* | |||||
* Only do the ID check and reuse check if the target is not from a | |||||
* RAID Component. For Physical Disks of a Volume, the ID will be reused | |||||
* when a volume is deleted because the mapping entry for the PD will | |||||
* still be in the mapping table. The ID check should not be done here | |||||
* either since this PD is already being used. | |||||
*/ | |||||
targ = &sassc->targets[id]; | |||||
if (!(targ->flags & MPR_TARGET_FLAGS_RAID_COMPONENT)) { | |||||
if (mprsas_check_id(sassc, id) != 0) { | if (mprsas_check_id(sassc, id) != 0) { | ||||
device_printf(sc->mpr_dev, "Excluding target id %d\n", id); | device_printf(sc->mpr_dev, "Excluding target id %d\n", | ||||
id); | |||||
error = ENXIO; | error = ENXIO; | ||||
goto out; | goto out; | ||||
} | } | ||||
targ = &sassc->targets[id]; | |||||
if (targ->handle != 0x0) { | if (targ->handle != 0x0) { | ||||
mpr_dprint(sc, MPR_MAPPING, "Attempting to reuse target id " | mpr_dprint(sc, MPR_MAPPING, "Attempting to reuse " | ||||
"%d handle 0x%04x\n", id, targ->handle); | "target id %d handle 0x%04x\n", id, targ->handle); | ||||
error = ENXIO; | error = ENXIO; | ||||
goto out; | goto out; | ||||
} | } | ||||
} | |||||
mpr_dprint(sc, MPR_MAPPING, "SAS Address from SAS device page0 = %jx\n", | mpr_dprint(sc, MPR_MAPPING, "SAS Address from SAS device page0 = %jx\n", | ||||
sas_address); | sas_address); | ||||
targ->devinfo = device_info; | targ->devinfo = device_info; | ||||
targ->devname = le32toh(config_page.DeviceName.High); | targ->devname = le32toh(config_page.DeviceName.High); | ||||
targ->devname = (targ->devname << 32) | | targ->devname = (targ->devname << 32) | | ||||
le32toh(config_page.DeviceName.Low); | le32toh(config_page.DeviceName.Low); | ||||
targ->encl_handle = le16toh(config_page.EnclosureHandle); | targ->encl_handle = le16toh(config_page.EnclosureHandle); | ||||
▲ Show 20 Lines • Show All 379 Lines • ▼ Show 20 Lines | mprsas_add_pcie_device(struct mpr_softc *sc, u16 handle, u8 linkrate) | ||||
if ((mpr_config_get_pcie_device_pg2(sc, &mpi_reply, &config_page2, | if ((mpr_config_get_pcie_device_pg2(sc, &mpi_reply, &config_page2, | ||||
MPI26_PCIE_DEVICE_PGAD_FORM_HANDLE, handle))) { | MPI26_PCIE_DEVICE_PGAD_FORM_HANDLE, handle))) { | ||||
printf("%s: error reading PCIe device page2\n", __func__); | printf("%s: error reading PCIe device page2\n", __func__); | ||||
error = ENXIO; | error = ENXIO; | ||||
goto out; | goto out; | ||||
} | } | ||||
id = mpr_mapping_get_sas_id(sc, pcie_wwid, handle); | id = mpr_mapping_get_tid(sc, pcie_wwid, handle); | ||||
if (id == MPR_MAP_BAD_ID) { | if (id == MPR_MAP_BAD_ID) { | ||||
printf("failure at %s:%d/%s()! Could not get ID for device " | mpr_dprint(sc, MPR_ERROR | MPR_INFO, "failure at %s:%d/%s()! " | ||||
"with handle 0x%04x\n", __FILE__, __LINE__, __func__, | "Could not get ID for device with handle 0x%04x\n", | ||||
handle); | __FILE__, __LINE__, __func__, handle); | ||||
error = ENXIO; | error = ENXIO; | ||||
goto out; | goto out; | ||||
} | } | ||||
mpr_dprint(sc, MPR_MAPPING, "%s: Target ID for added device is %d.\n", | |||||
__func__, id); | |||||
if (mprsas_check_id(sassc, id) != 0) { | if (mprsas_check_id(sassc, id) != 0) { | ||||
device_printf(sc->mpr_dev, "Excluding target id %d\n", id); | device_printf(sc->mpr_dev, "Excluding target id %d\n", id); | ||||
error = ENXIO; | error = ENXIO; | ||||
goto out; | goto out; | ||||
} | } | ||||
mpr_dprint(sc, MPR_MAPPING, "WWID from PCIe device page0 = %jx\n", | mpr_dprint(sc, MPR_MAPPING, "WWID from PCIe device page0 = %jx\n", | ||||
▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | mprsas_volume_add(struct mpr_softc *sc, u16 handle) | ||||
mpr_config_get_volume_wwid(sc, handle, &wwid); | mpr_config_get_volume_wwid(sc, handle, &wwid); | ||||
if (!wwid) { | if (!wwid) { | ||||
printf("%s: invalid WWID; cannot add volume to mapping table\n", | printf("%s: invalid WWID; cannot add volume to mapping table\n", | ||||
__func__); | __func__); | ||||
error = ENXIO; | error = ENXIO; | ||||
goto out; | goto out; | ||||
} | } | ||||
id = mpr_mapping_get_raid_id(sc, wwid, handle); | id = mpr_mapping_get_raid_tid(sc, wwid, handle); | ||||
if (id == MPR_MAP_BAD_ID) { | if (id == MPR_MAP_BAD_ID) { | ||||
printf("%s: could not get ID for volume with handle 0x%04x and " | printf("%s: could not get ID for volume with handle 0x%04x and " | ||||
"WWID 0x%016llx\n", __func__, handle, | "WWID 0x%016llx\n", __func__, handle, | ||||
(unsigned long long)wwid); | (unsigned long long)wwid); | ||||
error = ENXIO; | error = ENXIO; | ||||
goto out; | goto out; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | mprsas_SSU_to_SATA_devices(struct mpr_softc *sc) | ||||
mpr_lock(sc); | mpr_lock(sc); | ||||
/* | /* | ||||
* For each target, issue a StartStopUnit command to stop the device. | * For each target, issue a StartStopUnit command to stop the device. | ||||
*/ | */ | ||||
sc->SSU_started = TRUE; | sc->SSU_started = TRUE; | ||||
sc->SSU_refcount = 0; | sc->SSU_refcount = 0; | ||||
for (targetid = 0; targetid < sc->facts->MaxTargets; targetid++) { | for (targetid = 0; targetid < sc->max_devices; targetid++) { | ||||
target = &sassc->targets[targetid]; | target = &sassc->targets[targetid]; | ||||
if (target->handle == 0x0) { | if (target->handle == 0x0) { | ||||
continue; | continue; | ||||
} | } | ||||
/* | /* | ||||
* The stop_at_shutdown flag will be set if this device is | * The stop_at_shutdown flag will be set if this device is | ||||
* a SATA direct-access end device. | * a SATA direct-access end device. | ||||
▲ Show 20 Lines • Show All 167 Lines • ▼ Show 20 Lines | out: | ||||
* | * | ||||
* The possible values for the 'enable_ssu' variable are: | * The possible values for the 'enable_ssu' variable are: | ||||
* 0: disable to SSD and HDD | * 0: disable to SSD and HDD | ||||
* 1: disable only to HDD (default) | * 1: disable only to HDD (default) | ||||
* 2: disable only to SSD | * 2: disable only to SSD | ||||
* 3: enable to SSD and HDD | * 3: enable to SSD and HDD | ||||
* anything else will default to 1. | * anything else will default to 1. | ||||
*/ | */ | ||||
for (targetid = 0; targetid < sc->facts->MaxTargets; targetid++) { | for (targetid = 0; targetid < sc->max_devices; targetid++) { | ||||
target = &sc->sassc->targets[targetid]; | target = &sc->sassc->targets[targetid]; | ||||
if (target->handle == 0x0) { | if (target->handle == 0x0) { | ||||
continue; | continue; | ||||
} | } | ||||
if (target->supports_SSU) { | if (target->supports_SSU) { | ||||
switch (sc->enable_ssu) { | switch (sc->enable_ssu) { | ||||
case MPR_SSU_DISABLE_SSD_DISABLE_HDD: | case MPR_SSU_DISABLE_SSD_DISABLE_HDD: | ||||
Show All 24 Lines |