Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/mpr/mpr_sas_lsi.c
Show First 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | |||||
#include <cam/cam_periph.h> | #include <cam/cam_periph.h> | ||||
#include <cam/scsi/scsi_all.h> | #include <cam/scsi/scsi_all.h> | ||||
#include <cam/scsi/scsi_message.h> | #include <cam/scsi/scsi_message.h> | ||||
#include <dev/mpr/mpi/mpi2_type.h> | #include <dev/mpr/mpi/mpi2_type.h> | ||||
#include <dev/mpr/mpi/mpi2.h> | #include <dev/mpr/mpi/mpi2.h> | ||||
#include <dev/mpr/mpi/mpi2_ioc.h> | #include <dev/mpr/mpi/mpi2_ioc.h> | ||||
#include <dev/mpr/mpi/mpi2_sas.h> | #include <dev/mpr/mpi/mpi2_sas.h> | ||||
#include <dev/mpr/mpi/mpi2_pci.h> | |||||
#include <dev/mpr/mpi/mpi2_cnfg.h> | #include <dev/mpr/mpi/mpi2_cnfg.h> | ||||
#include <dev/mpr/mpi/mpi2_init.h> | #include <dev/mpr/mpi/mpi2_init.h> | ||||
#include <dev/mpr/mpi/mpi2_raid.h> | #include <dev/mpr/mpi/mpi2_raid.h> | ||||
#include <dev/mpr/mpi/mpi2_tool.h> | #include <dev/mpr/mpi/mpi2_tool.h> | ||||
#include <dev/mpr/mpr_ioctl.h> | #include <dev/mpr/mpr_ioctl.h> | ||||
#include <dev/mpr/mprvar.h> | #include <dev/mpr/mprvar.h> | ||||
#include <dev/mpr/mpr_table.h> | #include <dev/mpr/mpr_table.h> | ||||
#include <dev/mpr/mpr_sas.h> | #include <dev/mpr/mpr_sas.h> | ||||
Show All 29 Lines | struct _ata_identify_device_data { | ||||
u16 reserved4[38]; /* 218-255 */ | u16 reserved4[38]; /* 218-255 */ | ||||
}; | }; | ||||
static u32 event_count; | static u32 event_count; | ||||
static void mprsas_fw_work(struct mpr_softc *sc, | static void mprsas_fw_work(struct mpr_softc *sc, | ||||
struct mpr_fw_event_work *fw_event); | struct mpr_fw_event_work *fw_event); | ||||
static void mprsas_fw_event_free(struct mpr_softc *, | static void mprsas_fw_event_free(struct mpr_softc *, | ||||
struct mpr_fw_event_work *); | struct mpr_fw_event_work *); | ||||
static int mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate); | static int mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate); | ||||
static int mprsas_add_pcie_device(struct mpr_softc *sc, u16 handle, | |||||
u8 linkrate); | |||||
static int mprsas_get_sata_identify(struct mpr_softc *sc, u16 handle, | static int mprsas_get_sata_identify(struct mpr_softc *sc, u16 handle, | ||||
Mpi2SataPassthroughReply_t *mpi_reply, char *id_buffer, int sz, | Mpi2SataPassthroughReply_t *mpi_reply, char *id_buffer, int sz, | ||||
u32 devinfo); | u32 devinfo); | ||||
static void mprsas_ata_id_timeout(void *data); | static void mprsas_ata_id_timeout(void *data); | ||||
int mprsas_get_sas_address_for_sata_disk(struct mpr_softc *sc, | int mprsas_get_sas_address_for_sata_disk(struct mpr_softc *sc, | ||||
u64 *sas_address, u16 handle, u32 device_info, u8 *is_SATA_SSD); | u64 *sas_address, u16 handle, u32 device_info, u8 *is_SATA_SSD); | ||||
static int mprsas_volume_add(struct mpr_softc *sc, | static int mprsas_volume_add(struct mpr_softc *sc, | ||||
u16 handle); | u16 handle); | ||||
Show All 24 Lines | if (!fw_event->event_data) { | ||||
printf("%s: allocate failed for event_data\n", __func__); | printf("%s: allocate failed for event_data\n", __func__); | ||||
free(fw_event, M_MPR); | free(fw_event, M_MPR); | ||||
return; | return; | ||||
} | } | ||||
bcopy(event->EventData, fw_event->event_data, sz); | bcopy(event->EventData, fw_event->event_data, sz); | ||||
fw_event->event = event->Event; | fw_event->event = event->Event; | ||||
if ((event->Event == MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST || | if ((event->Event == MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST || | ||||
event->Event == MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST || | |||||
event->Event == MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE || | event->Event == MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE || | ||||
event->Event == MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST) && | event->Event == MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST) && | ||||
sc->track_mapping_events) | sc->track_mapping_events) | ||||
sc->pending_map_events++; | sc->pending_map_events++; | ||||
/* | /* | ||||
* When wait_for_port_enable flag is set, make sure that all the events | * When wait_for_port_enable flag is set, make sure that all the events | ||||
* are processed. Increment the startup_refcount and decrement it after | * are processed. Increment the startup_refcount and decrement it after | ||||
* events are processed. | * events are processed. | ||||
*/ | */ | ||||
if ((event->Event == MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST || | if ((event->Event == MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST || | ||||
event->Event == MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST || | |||||
event->Event == MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST) && | event->Event == MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST) && | ||||
sc->wait_for_port_enable) | sc->wait_for_port_enable) | ||||
mprsas_startup_increment(sc->sassc); | mprsas_startup_increment(sc->sassc); | ||||
TAILQ_INSERT_TAIL(&sc->sassc->ev_queue, fw_event, ev_link); | TAILQ_INSERT_TAIL(&sc->sassc->ev_queue, fw_event, ev_link); | ||||
taskqueue_enqueue(sc->sassc->ev_tq, &sc->sassc->ev_task); | taskqueue_enqueue(sc->sassc->ev_tq, &sc->sassc->ev_task); | ||||
} | } | ||||
static void | static void | ||||
mprsas_fw_event_free(struct mpr_softc *sc, struct mpr_fw_event_work *fw_event) | mprsas_fw_event_free(struct mpr_softc *sc, struct mpr_fw_event_work *fw_event) | ||||
{ | { | ||||
free(fw_event->event_data, M_MPR); | free(fw_event->event_data, M_MPR); | ||||
free(fw_event, M_MPR); | free(fw_event, M_MPR); | ||||
Show All 15 Lines | mprsas_fw_work(struct mpr_softc *sc, struct mpr_fw_event_work *fw_event) | ||||
mpr_dprint(sc, MPR_EVENT, "(%d)->(%s) Working on Event: [%x]\n", | mpr_dprint(sc, MPR_EVENT, "(%d)->(%s) Working on Event: [%x]\n", | ||||
event_count++, __func__, fw_event->event); | event_count++, __func__, fw_event->event); | ||||
switch (fw_event->event) { | switch (fw_event->event) { | ||||
case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: | case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: | ||||
{ | { | ||||
MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *data; | MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *data; | ||||
MPI2_EVENT_SAS_TOPO_PHY_ENTRY *phy; | MPI2_EVENT_SAS_TOPO_PHY_ENTRY *phy; | ||||
int i; | uint8_t i; | ||||
data = (MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *) | data = (MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *) | ||||
fw_event->event_data; | fw_event->event_data; | ||||
mpr_mapping_topology_change_event(sc, fw_event->event_data); | mpr_mapping_topology_change_event(sc, fw_event->event_data); | ||||
for (i = 0; i < data->NumEntries; i++) { | for (i = 0; i < data->NumEntries; i++) { | ||||
phy = &data->PHY[i]; | phy = &data->PHY[i]; | ||||
▲ Show 20 Lines • Show All 452 Lines • ▼ Show 20 Lines | case MPI26_EVENT_ACTIVE_CABLE_DEGRADED: | ||||
"(12 Gb/s rate)\n", ace_event_data->ReceptacleID); | "(12 Gb/s rate)\n", ace_event_data->ReceptacleID); | ||||
break; | break; | ||||
} | } | ||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
break; | break; | ||||
} | } | ||||
case MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST: | |||||
{ | |||||
MPI26_EVENT_DATA_PCIE_TOPOLOGY_CHANGE_LIST *data; | |||||
MPI26_EVENT_PCIE_TOPO_PORT_ENTRY *port_entry; | |||||
uint8_t i, link_rate; | |||||
uint16_t handle; | |||||
data = (MPI26_EVENT_DATA_PCIE_TOPOLOGY_CHANGE_LIST *) | |||||
fw_event->event_data; | |||||
mpr_mapping_pcie_topology_change_event(sc, | |||||
fw_event->event_data); | |||||
for (i = 0; i < data->NumEntries; i++) { | |||||
port_entry = &data->PortEntry[i]; | |||||
handle = le16toh(port_entry->AttachedDevHandle); | |||||
link_rate = port_entry->CurrentPortInfo & | |||||
MPI26_EVENT_PCIE_TOPO_PI_RATE_MASK; | |||||
switch (port_entry->PortStatus) { | |||||
case MPI26_EVENT_PCIE_TOPO_PS_DEV_ADDED: | |||||
if (link_rate < | |||||
MPI26_EVENT_PCIE_TOPO_PI_RATE_2_5) { | |||||
mpr_dprint(sc, MPR_ERROR, "%s: Cannot " | |||||
"add PCIe device with handle 0x%x " | |||||
"with unknown link rate.\n", | |||||
__func__, handle); | |||||
break; | |||||
} | |||||
if (mprsas_add_pcie_device(sc, handle, | |||||
link_rate)) { | |||||
mpr_dprint(sc, MPR_ERROR, "%s: failed " | |||||
"to add PCIe device with handle " | |||||
"0x%x\n", __func__, handle); | |||||
mprsas_prepare_remove(sassc, handle); | |||||
} | |||||
break; | |||||
case MPI26_EVENT_PCIE_TOPO_PS_NOT_RESPONDING: | |||||
mprsas_prepare_remove(sassc, handle); | |||||
break; | |||||
case MPI26_EVENT_PCIE_TOPO_PS_PORT_CHANGED: | |||||
case MPI26_EVENT_PCIE_TOPO_PS_NO_CHANGE: | |||||
case MPI26_EVENT_PCIE_TOPO_PS_DELAY_NOT_RESPONDING: | |||||
default: | |||||
break; | |||||
} | |||||
} | |||||
/* | |||||
* refcount was incremented for this event in | |||||
* mprsas_evt_handler. Decrement it here because the event has | |||||
* been processed. | |||||
*/ | |||||
mprsas_startup_decrement(sassc); | |||||
break; | |||||
} | |||||
case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: | case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: | ||||
case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: | case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: | ||||
default: | default: | ||||
mpr_dprint(sc, MPR_TRACE,"Unhandled event 0x%0X\n", | mpr_dprint(sc, MPR_TRACE,"Unhandled event 0x%0X\n", | ||||
fw_event->event); | fw_event->event); | ||||
break; | break; | ||||
} | } | ||||
Show All 13 Lines | mprsas_firmware_event_work(void *arg, int pending) | ||||
while ((fw_event = TAILQ_FIRST(&sc->sassc->ev_queue)) != NULL) { | while ((fw_event = TAILQ_FIRST(&sc->sassc->ev_queue)) != NULL) { | ||||
TAILQ_REMOVE(&sc->sassc->ev_queue, fw_event, ev_link); | TAILQ_REMOVE(&sc->sassc->ev_queue, fw_event, ev_link); | ||||
mprsas_fw_work(sc, fw_event); | mprsas_fw_work(sc, fw_event); | ||||
} | } | ||||
mpr_unlock(sc); | mpr_unlock(sc); | ||||
} | } | ||||
static int | static int | ||||
mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){ | mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate) | ||||
{ | |||||
char devstring[80]; | char devstring[80]; | ||||
struct mprsas_softc *sassc; | struct mprsas_softc *sassc; | ||||
struct mprsas_target *targ; | struct mprsas_target *targ; | ||||
Mpi2ConfigReply_t mpi_reply; | Mpi2ConfigReply_t mpi_reply; | ||||
Mpi2SasDevicePage0_t config_page; | Mpi2SasDevicePage0_t config_page; | ||||
uint64_t sas_address, parent_sas_address = 0; | uint64_t sas_address, parent_sas_address = 0; | ||||
u32 device_info, parent_devinfo = 0; | u32 device_info, parent_devinfo = 0; | ||||
unsigned int id; | unsigned int id; | ||||
▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate) | ||||
* 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 | ||||
*/ | */ | ||||
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_sas_id(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; | ||||
} | } | ||||
} | } | ||||
Show All 30 Lines | mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate) | ||||
targ->parent_sasaddr = le64toh(parent_sas_address); | targ->parent_sasaddr = le64toh(parent_sas_address); | ||||
targ->parent_devinfo = parent_devinfo; | targ->parent_devinfo = parent_devinfo; | ||||
targ->tid = id; | targ->tid = id; | ||||
targ->linkrate = (linkrate>>4); | targ->linkrate = (linkrate>>4); | ||||
targ->flags = 0; | targ->flags = 0; | ||||
if (is_SATA_SSD) { | if (is_SATA_SSD) { | ||||
targ->flags = MPR_TARGET_IS_SATA_SSD; | targ->flags = MPR_TARGET_IS_SATA_SSD; | ||||
} | } | ||||
if (le16toh(config_page.Flags) & | if ((le16toh(config_page.Flags) & | ||||
MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE) { | MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) && | ||||
(le16toh(config_page.Flags) & | |||||
MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE)) { | |||||
targ->scsi_req_desc_type = | targ->scsi_req_desc_type = | ||||
MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO; | MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO; | ||||
} | } | ||||
if (le16toh(config_page.Flags) & | if (le16toh(config_page.Flags) & | ||||
MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { | MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { | ||||
targ->encl_level_valid = TRUE; | targ->encl_level_valid = TRUE; | ||||
} | } | ||||
TAILQ_INIT(&targ->commands); | TAILQ_INIT(&targ->commands); | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | for (i = 1; i < sc->num_reqs; i++) { | ||||
cm = &sc->commands[i]; | cm = &sc->commands[i]; | ||||
if (cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) { | if (cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) { | ||||
mpr_free_command(sc, cm); | mpr_free_command(sc, cm); | ||||
} | } | ||||
} | } | ||||
mprsas_startup_decrement(sassc); | mprsas_startup_decrement(sassc); | ||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
mprsas_get_sas_address_for_sata_disk(struct mpr_softc *sc, | mprsas_get_sas_address_for_sata_disk(struct mpr_softc *sc, | ||||
u64 *sas_address, u16 handle, u32 device_info, u8 *is_SATA_SSD) | u64 *sas_address, u16 handle, u32 device_info, u8 *is_SATA_SSD) | ||||
{ | { | ||||
Mpi2SataPassthroughReply_t mpi_reply; | Mpi2SataPassthroughReply_t mpi_reply; | ||||
int i, rc, try_count; | int i, rc, try_count; | ||||
u32 *bufferptr; | u32 *bufferptr; | ||||
union _sata_sas_address hash_address; | union _sata_sas_address hash_address; | ||||
▲ Show 20 Lines • Show All 215 Lines • ▼ Show 20 Lines | mprsas_ata_id_timeout(void *data) | ||||
* setting up targets. Instead, the command is flagged so that special | * setting up targets. Instead, the command is flagged so that special | ||||
* handling will be used to send the abort. | * handling will be used to send the abort. | ||||
*/ | */ | ||||
cm->cm_flags |= MPR_CM_FLAGS_SATA_ID_TIMEOUT; | cm->cm_flags |= MPR_CM_FLAGS_SATA_ID_TIMEOUT; | ||||
wakeup(cm); | wakeup(cm); | ||||
} | } | ||||
static int | static int | ||||
mprsas_add_pcie_device(struct mpr_softc *sc, u16 handle, u8 linkrate) | |||||
{ | |||||
char devstring[80]; | |||||
struct mprsas_softc *sassc; | |||||
struct mprsas_target *targ; | |||||
Mpi2ConfigReply_t mpi_reply; | |||||
Mpi26PCIeDevicePage0_t config_page; | |||||
Mpi26PCIeDevicePage2_t config_page2; | |||||
uint64_t pcie_wwid, parent_wwid = 0; | |||||
u32 device_info, parent_devinfo = 0; | |||||
unsigned int id; | |||||
int error = 0; | |||||
struct mprsas_lun *lun; | |||||
sassc = sc->sassc; | |||||
mprsas_startup_increment(sassc); | |||||
if ((mpr_config_get_pcie_device_pg0(sc, &mpi_reply, &config_page, | |||||
MPI26_PCIE_DEVICE_PGAD_FORM_HANDLE, handle))) { | |||||
printf("%s: error reading PCIe device page0\n", __func__); | |||||
error = ENXIO; | |||||
goto out; | |||||
} | |||||
device_info = le32toh(config_page.DeviceInfo); | |||||
if (((device_info & MPI26_PCIE_DEVINFO_PCI_SWITCH) == 0) | |||||
&& (le16toh(config_page.ParentDevHandle) != 0)) { | |||||
Mpi2ConfigReply_t tmp_mpi_reply; | |||||
Mpi26PCIeDevicePage0_t parent_config_page; | |||||
if ((mpr_config_get_pcie_device_pg0(sc, &tmp_mpi_reply, | |||||
&parent_config_page, MPI26_PCIE_DEVICE_PGAD_FORM_HANDLE, | |||||
le16toh(config_page.ParentDevHandle)))) { | |||||
printf("%s: error reading PCIe device %#x page0\n", | |||||
__func__, le16toh(config_page.ParentDevHandle)); | |||||
} else { | |||||
parent_wwid = parent_config_page.WWID.High; | |||||
parent_wwid = (parent_wwid << 32) | | |||||
parent_config_page.WWID.Low; | |||||
parent_devinfo = le32toh(parent_config_page.DeviceInfo); | |||||
} | |||||
} | |||||
/* TODO Check proper endianness */ | |||||
pcie_wwid = config_page.WWID.High; | |||||
pcie_wwid = (pcie_wwid << 32) | config_page.WWID.Low; | |||||
mpr_dprint(sc, MPR_INFO, "PCIe WWID from PCIe device page0 = %jx\n", | |||||
pcie_wwid); | |||||
if ((mpr_config_get_pcie_device_pg2(sc, &mpi_reply, &config_page2, | |||||
MPI26_PCIE_DEVICE_PGAD_FORM_HANDLE, handle))) { | |||||
printf("%s: error reading PCIe device page2\n", __func__); | |||||
error = ENXIO; | |||||
goto out; | |||||
} | |||||
id = mpr_mapping_get_sas_id(sc, pcie_wwid, handle); | |||||
if (id == MPR_MAP_BAD_ID) { | |||||
printf("failure at %s:%d/%s()! Could not get ID for device " | |||||
"with handle 0x%04x\n", __FILE__, __LINE__, __func__, | |||||
handle); | |||||
error = ENXIO; | |||||
goto out; | |||||
} | |||||
if (mprsas_check_id(sassc, id) != 0) { | |||||
device_printf(sc->mpr_dev, "Excluding target id %d\n", id); | |||||
error = ENXIO; | |||||
goto out; | |||||
} | |||||
mpr_dprint(sc, MPR_MAPPING, "WWID from PCIe device page0 = %jx\n", | |||||
pcie_wwid); | |||||
targ = &sassc->targets[id]; | |||||
targ->devinfo = device_info; | |||||
targ->encl_handle = le16toh(config_page.EnclosureHandle); | |||||
targ->encl_slot = le16toh(config_page.Slot); | |||||
targ->encl_level = config_page.EnclosureLevel; | |||||
targ->connector_name[0] = ((char *)&config_page.ConnectorName)[0]; | |||||
targ->connector_name[1] = ((char *)&config_page.ConnectorName)[1]; | |||||
targ->connector_name[2] = ((char *)&config_page.ConnectorName)[2]; | |||||
targ->connector_name[3] = ((char *)&config_page.ConnectorName)[3]; | |||||
targ->is_nvme = device_info & MPI26_PCIE_DEVINFO_NVME; | |||||
targ->MDTS = config_page2.MaximumDataTransferSize; | |||||
/* | |||||
* Assume always TRUE for encl_level_valid because there is no valid | |||||
* flag for PCIe. | |||||
*/ | |||||
targ->encl_level_valid = TRUE; | |||||
targ->handle = handle; | |||||
targ->parent_handle = le16toh(config_page.ParentDevHandle); | |||||
targ->sasaddr = mpr_to_u64(&config_page.WWID); | |||||
targ->parent_sasaddr = le64toh(parent_wwid); | |||||
targ->parent_devinfo = parent_devinfo; | |||||
targ->tid = id; | |||||
targ->linkrate = linkrate; | |||||
targ->flags = 0; | |||||
if ((le16toh(config_page.Flags) & | |||||
MPI26_PCIEDEV0_FLAGS_ENABLED_FAST_PATH) && | |||||
(le16toh(config_page.Flags) & | |||||
MPI26_PCIEDEV0_FLAGS_FAST_PATH_CAPABLE)) { | |||||
targ->scsi_req_desc_type = | |||||
MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO; | |||||
} | |||||
TAILQ_INIT(&targ->commands); | |||||
TAILQ_INIT(&targ->timedout_commands); | |||||
while (!SLIST_EMPTY(&targ->luns)) { | |||||
lun = SLIST_FIRST(&targ->luns); | |||||
SLIST_REMOVE_HEAD(&targ->luns, lun_link); | |||||
free(lun, M_MPR); | |||||
} | |||||
SLIST_INIT(&targ->luns); | |||||
mpr_describe_devinfo(targ->devinfo, devstring, 80); | |||||
mpr_dprint(sc, (MPR_INFO|MPR_MAPPING), "Found PCIe device <%s> <%s> " | |||||
"handle<0x%04x> enclosureHandle<0x%04x> slot %d\n", devstring, | |||||
mpr_describe_table(mpr_pcie_linkrate_names, targ->linkrate), | |||||
targ->handle, targ->encl_handle, targ->encl_slot); | |||||
if (targ->encl_level_valid) { | |||||
mpr_dprint(sc, (MPR_INFO|MPR_MAPPING), "At enclosure level %d " | |||||
"and connector name (%4s)\n", targ->encl_level, | |||||
targ->connector_name); | |||||
} | |||||
#if ((__FreeBSD_version >= 1000000) && (__FreeBSD_version < 1000039)) || \ | |||||
(__FreeBSD_version < 902502) | |||||
if ((sassc->flags & MPRSAS_IN_STARTUP) == 0) | |||||
#endif | |||||
mprsas_rescan_target(sc, targ); | |||||
mpr_dprint(sc, MPR_MAPPING, "Target id 0x%x added\n", targ->tid); | |||||
out: | |||||
mprsas_startup_decrement(sassc); | |||||
return (error); | |||||
} | |||||
static int | |||||
mprsas_volume_add(struct mpr_softc *sc, u16 handle) | mprsas_volume_add(struct mpr_softc *sc, u16 handle) | ||||
{ | { | ||||
struct mprsas_softc *sassc; | struct mprsas_softc *sassc; | ||||
struct mprsas_target *targ; | struct mprsas_target *targ; | ||||
u64 wwid; | u64 wwid; | ||||
unsigned int id; | unsigned int id; | ||||
int error = 0; | int error = 0; | ||||
struct mprsas_lun *lun; | struct mprsas_lun *lun; | ||||
▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | for (targetid = 0; targetid < sc->facts->MaxTargets; targetid++) { | ||||
/* | /* | ||||
* 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. | ||||
*/ | */ | ||||
if (target->stop_at_shutdown) { | if (target->stop_at_shutdown) { | ||||
ccb = xpt_alloc_ccb_nowait(); | ccb = xpt_alloc_ccb_nowait(); | ||||
if (ccb == NULL) { | if (ccb == NULL) { | ||||
mpr_dprint(sc, MPR_FAULT, "Unable to alloc CCB to stop " | mpr_dprint(sc, MPR_FAULT, "Unable to alloc CCB " | ||||
"unit.\n"); | "to stop unit.\n"); | ||||
return; | return; | ||||
} | } | ||||
if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, | if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, | ||||
pathid, targetid, CAM_LUN_WILDCARD) != | pathid, targetid, CAM_LUN_WILDCARD) != | ||||
CAM_REQ_CMP) { | CAM_REQ_CMP) { | ||||
mpr_dprint(sc, MPR_ERROR, "Unable to create " | mpr_dprint(sc, MPR_ERROR, "Unable to create " | ||||
"path to stop unit.\n"); | "path to stop unit.\n"); | ||||
▲ Show 20 Lines • Show All 194 Lines • Show Last 20 Lines |