コード例 #1
0
ファイル: mps_table.c プロジェクト: edgar-pek/PerspicuOS
void
mps_print_sasdev0(struct mps_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
{
	MPS_PRINTFIELD_START(sc, "SAS Device Page 0");
	MPS_PRINTFIELD(sc, buf, Slot, %d);
	MPS_PRINTFIELD(sc, buf, EnclosureHandle, 0x%x);
	mps_dprint_field(sc, MPS_INFO, "SASAddress: 0x%jx\n",
	    mps_to_u64(&buf->SASAddress));
	MPS_PRINTFIELD(sc, buf, ParentDevHandle, 0x%x);
	MPS_PRINTFIELD(sc, buf, PhyNum, %d);
	MPS_PRINTFIELD(sc, buf, AccessStatus, 0x%x);
	MPS_PRINTFIELD(sc, buf, DevHandle, 0x%x);
	MPS_PRINTFIELD(sc, buf, AttachedPhyIdentifier, 0x%x);
	MPS_PRINTFIELD(sc, buf, ZoneGroup, %d);
	mps_dprint_field(sc, MPS_INFO, "DeviceInfo: %b,%s\n", buf->DeviceInfo,
	    "\20" "\4SataHost" "\5SmpInit" "\6StpInit" "\7SspInit"
	    "\10SataDev" "\11SmpTarg" "\12StpTarg" "\13SspTarg" "\14Direct"
	    "\15LsiDev" "\16AtapiDev" "\17SepDev",
	    mps_describe_table(mps_sasdev0_devtype, buf->DeviceInfo & 0x03));
	MPS_PRINTFIELD(sc, buf, Flags, 0x%x);
	MPS_PRINTFIELD(sc, buf, PhysicalPort, %d);
	MPS_PRINTFIELD(sc, buf, MaxPortConnections, %d);
	mps_dprint_field(sc, MPS_INFO, "DeviceName: 0x%jx\n",
	    mps_to_u64(&buf->DeviceName));
	MPS_PRINTFIELD(sc, buf, PortGroups, %d);
	MPS_PRINTFIELD(sc, buf, DmaGroup, %d);
	MPS_PRINTFIELD(sc, buf, ControlGroup, %d);
}
コード例 #2
0
ファイル: mps_debug.c プロジェクト: derekmarcotte/freebsd
static void
print_sgl(char *buf, int offset, int numframes)
{
	MPI2_SGE_SIMPLE64 *sge;
	MPI2_SGE_CHAIN_UNION *sgc;
	MPI2_REQUEST_HEADER *req;
	u_int i = 0, flags;
	char *frame, tmpbuf[128];

	req = (MPI2_REQUEST_HEADER *)buf;
	frame = (char *)buf;
	sge = (MPI2_SGE_SIMPLE64 *)&frame[offset * 4];
	printf("SGL for command\n");

	hexdump(frame, MPS_FRAME_LEN, NULL, 0);
	while (frame != NULL) {
		flags = sge->FlagsLength >> MPI2_SGE_FLAGS_SHIFT;
		bzero(tmpbuf, sizeof(tmpbuf));
		mps_parse_flags(flags, SGL_FLAGS, tmpbuf, sizeof(tmpbuf));
		printf("seg%d flags=%x %s len= 0x%06x addr=0x%016jx\n", i,
		    flags, tmpbuf, sge->FlagsLength & 0xffffff,
		    mps_to_u64(&sge->Address));
		if (flags & (MPI2_SGE_FLAGS_END_OF_LIST |
		    MPI2_SGE_FLAGS_END_OF_BUFFER))
			break;
		sge++;
		i++;
		if (flags & MPI2_SGE_FLAGS_LAST_ELEMENT) {
			sgc = (MPI2_SGE_CHAIN_UNION *)sge;
			if ((sgc->Flags & MPI2_SGE_FLAGS_CHAIN_ELEMENT) == 0) {
				printf("Invalid chain element\n");
				break;
			}
			bzero(tmpbuf, sizeof(tmpbuf));
			mps_parse_flags(sgc->Flags, SGL_FLAGS, tmpbuf,
			    sizeof(tmpbuf));
			if (sgc->Flags & MPI2_SGE_FLAGS_64_BIT_ADDRESSING)
				printf("chain64 flags=0x%x %s len=0x%x "
				    "Offset=0x%x addr=0x%016jx\n", sgc->Flags,
				    tmpbuf, sgc->Length, sgc->NextChainOffset,
				    mps_to_u64(&sgc->u.Address64));
			else
				printf("chain32 flags=0x%x %s len=0x%x "
				    "Offset=0x%x addr=0x%08x\n", sgc->Flags,
				    tmpbuf, sgc->Length, sgc->NextChainOffset,
				    sgc->u.Address32);
			if (--numframes <= 0)
				break;
			frame += MPS_FRAME_LEN;
			sge = (MPI2_SGE_SIMPLE64 *)frame;
			hexdump(frame, MPS_FRAME_LEN, NULL, 0);
		}
	}
}
コード例 #3
0
ファイル: mps_table.c プロジェクト: edgar-pek/PerspicuOS
void
mps_print_sgl(struct mps_softc *sc, struct mps_command *cm, int offset)
{
	MPI2_SGE_SIMPLE64 *sge;
	MPI2_SGE_CHAIN32 *sgc;
	MPI2_REQUEST_HEADER *req;
	struct mps_chain *chain = NULL;
	char *frame;
	u_int i = 0, flags;

	req = (MPI2_REQUEST_HEADER *)cm->cm_req;
	frame = (char *)cm->cm_req;
	sge = (MPI2_SGE_SIMPLE64 *)&frame[offset * 4];
	printf("SGL for command %p\n", cm);

	while (frame != NULL) {
		flags = sge->FlagsLength >> MPI2_SGE_FLAGS_SHIFT;
		printf("seg%d flags=0x%x len=0x%x addr=0x%jx\n", i, flags,
		    sge->FlagsLength & 0xffffff, mps_to_u64(&sge->Address));
		if (flags & (MPI2_SGE_FLAGS_END_OF_LIST |
		    MPI2_SGE_FLAGS_END_OF_BUFFER))
			break;
		sge++;
		i++;
		if (flags & MPI2_SGE_FLAGS_LAST_ELEMENT) {
			sgc = (MPI2_SGE_CHAIN32 *)sge;
			printf("chain flags=0x%x len=0x%x Offset=0x%x "
			    "Address=0x%x\n", sgc->Flags, sgc->Length,
			    sgc->NextChainOffset, sgc->Address);
			if (chain == NULL)
				chain = TAILQ_FIRST(&cm->cm_chain_list);
			else
				chain = TAILQ_NEXT(chain, chain_link);
			frame = (char *)chain->chain;
			sge = (MPI2_SGE_SIMPLE64 *)frame;
			hexdump(frame, 128, NULL, 0);
		}
	}
}
コード例 #4
0
ファイル: mps_table.c プロジェクト: edgar-pek/PerspicuOS
void
mps_print_evt_sas(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
{

	mps_print_event(sc, event);

	switch(event->Event) {
	case MPI2_EVENT_SAS_DISCOVERY:
	{
		MPI2_EVENT_DATA_SAS_DISCOVERY *data;

		data = (MPI2_EVENT_DATA_SAS_DISCOVERY *)&event->EventData;
		mps_dprint_field(sc, MPS_EVENT, "Flags: %b\n", data->Flags,
		    "\20" "\1InProgress" "\2DeviceChange");
		mps_dprint_field(sc, MPS_EVENT, "ReasonCode: %s\n",
		    mps_describe_table(mps_sasdisc_reason, data->ReasonCode));
		MPS_EVENTFIELD(sc, data, PhysicalPort, %d);
		mps_dprint_field(sc, MPS_EVENT, "DiscoveryStatus: %b\n",
		    data->DiscoveryStatus,  "\20"
		    "\1Loop" "\2UnaddressableDev" "\3DupSasAddr" "\5SmpTimeout"
		    "\6ExpRouteFull" "\7RouteIndexError" "\10SmpFailed"
		    "\11SmpCrcError" "\12SubSubLink" "\13TableTableLink"
		    "\14UnsupDevice" "\15TableSubLink" "\16MultiDomain"
		    "\17MultiSub" "\20MultiSubSub" "\34DownstreamInit"
		    "\35MaxPhys" "\36MaxTargs" "\37MaxExpanders"
		    "\40MaxEnclosures");
		break;
	}
	case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
	{
		MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *data;
		MPI2_EVENT_SAS_TOPO_PHY_ENTRY *phy;
		int i, phynum;

		data = (MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *)
		    &event->EventData;
		MPS_EVENTFIELD(sc, data, EnclosureHandle, 0x%x);
		MPS_EVENTFIELD(sc, data, ExpanderDevHandle, 0x%x);
		MPS_EVENTFIELD(sc, data, NumPhys, %d);
		MPS_EVENTFIELD(sc, data, NumEntries, %d);
		MPS_EVENTFIELD(sc, data, StartPhyNum, %d);
		mps_dprint_field(sc, MPS_EVENT, "ExpStatus: %s (0x%x)\n",
		    mps_describe_table(mps_sastopo_exp, data->ExpStatus),
		    data->ExpStatus);
		MPS_EVENTFIELD(sc, data, PhysicalPort, %d);
		for (i = 0; i < data->NumEntries; i++) {
			phy = &data->PHY[i];
			phynum = data->StartPhyNum + i;
			mps_dprint_field(sc, MPS_EVENT,
			    "PHY[%d].AttachedDevHandle: 0x%04x\n", phynum,
			    phy->AttachedDevHandle);
			mps_dprint_field(sc, MPS_EVENT,
			    "PHY[%d].LinkRate: %s (0x%x)\n", phynum,
			    mps_describe_table(mps_linkrate_names,
			    (phy->LinkRate >> 4) & 0xf), phy->LinkRate);
			mps_dprint_field(sc,MPS_EVENT,"PHY[%d].PhyStatus: %s\n",
			    phynum, mps_describe_table(mps_phystatus_names,
			    phy->PhyStatus));
		}
		break;
	}
	case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
	{
		MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE *data;

		data = (MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE *)
		    &event->EventData;
		MPS_EVENTFIELD(sc, data, EnclosureHandle, 0x%x);
		mps_dprint_field(sc, MPS_EVENT, "ReasonCode: %s\n",
		    mps_describe_table(mps_sastopo_exp, data->ReasonCode));
		MPS_EVENTFIELD(sc, data, PhysicalPort, %d);
		MPS_EVENTFIELD(sc, data, NumSlots, %d);
		MPS_EVENTFIELD(sc, data, StartSlot, %d);
		MPS_EVENTFIELD(sc, data, PhyBits, 0x%x);
		break;
	}
	case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
	{
		MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *data;

		data = (MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)
		    &event->EventData;
		MPS_EVENTFIELD(sc, data, TaskTag, 0x%x);
		mps_dprint_field(sc, MPS_EVENT, "ReasonCode: %s\n",
		    mps_describe_table(mps_sasdev_reason, data->ReasonCode));
		MPS_EVENTFIELD(sc, data, ASC, 0x%x);
		MPS_EVENTFIELD(sc, data, ASCQ, 0x%x);
		MPS_EVENTFIELD(sc, data, DevHandle, 0x%x);
		mps_dprint_field(sc, MPS_EVENT, "SASAddress: 0x%jx\n",
		    mps_to_u64(&data->SASAddress));
	}
	default:
		break;
	}
}
コード例 #5
0
static int
mpssas_add_device(struct mps_softc *sc, u16 handle, u8 linkrate){
	char devstring[80];
	struct mpssas_softc *sassc;
	struct mpssas_target *targ;
	Mpi2ConfigReply_t mpi_reply;
	Mpi2SasDevicePage0_t config_page;
	uint64_t sas_address, sata_sas_address;
	uint64_t parent_sas_address = 0;
	u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
	u32 device_info, parent_devinfo = 0;
	unsigned int id;
	int ret;
	int error = 0;

	sassc = sc->sassc;
	mpssas_startup_increment(sassc);
	if ((mps_config_get_sas_device_pg0(sc, &mpi_reply, &config_page,
	     MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
		kprintf("%s: error reading SAS device page0\n", __func__);
		error = ENXIO;
		goto out;
	}

	device_info = le32toh(config_page.DeviceInfo);

	if (((device_info & MPI2_SAS_DEVICE_INFO_SMP_TARGET) == 0)
	 && (config_page.ParentDevHandle != 0)) {
		Mpi2ConfigReply_t tmp_mpi_reply;
		Mpi2SasDevicePage0_t parent_config_page;

		if ((mps_config_get_sas_device_pg0(sc, &tmp_mpi_reply,
		     &parent_config_page, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
		     le16toh(config_page.ParentDevHandle)))) {
			kprintf("%s: error reading SAS device %#x page0\n",
			       __func__, le16toh(config_page.ParentDevHandle));
		} else {
			parent_sas_address = parent_config_page.SASAddress.High;
			parent_sas_address = (parent_sas_address << 32) |
				parent_config_page.SASAddress.Low;
			parent_devinfo = le32toh(parent_config_page.DeviceInfo);
		}
	}
	/* TODO Check proper endianess */
	sas_address = config_page.SASAddress.High;
	sas_address = (sas_address << 32) |
	    config_page.SASAddress.Low;

	if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE)
		    == MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) {
		if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) {
			ret = mpssas_get_sas_address_for_sata_disk(sc,
			    &sata_sas_address, handle, device_info);
			if (!ret)
				id = mps_mapping_get_sas_id(sc,
				    sata_sas_address, handle);
			else
				id = mps_mapping_get_sas_id(sc,
				    sas_address, handle);
		} else
			id = mps_mapping_get_sas_id(sc, sas_address,
			    handle);
	} else
		id = mps_mapping_get_sas_id(sc, sas_address, handle);

	if (id == MPS_MAP_BAD_ID) {
		kprintf("failure at %s:%d/%s()! Could not get ID for device "
		    "with handle 0x%04x\n", __FILE__, __LINE__, __func__,
		    handle);
		error = ENXIO;
		goto out;
	}
	mps_vprintf(sc, "SAS Address from SAS device page0 = %jx\n",
	    sas_address);
	targ = &sassc->targets[id];
	targ->devinfo = device_info;
	targ->devname = le32toh(config_page.DeviceName.High);
	targ->devname = (targ->devname << 32) |
	    le32toh(config_page.DeviceName.Low);
	targ->encl_handle = le16toh(config_page.EnclosureHandle);
	targ->encl_slot = le16toh(config_page.Slot);
	targ->handle = handle;
	targ->parent_handle = le16toh(config_page.ParentDevHandle);
	targ->sasaddr = mps_to_u64(&config_page.SASAddress);
	targ->parent_sasaddr = le64toh(parent_sas_address);
	targ->parent_devinfo = parent_devinfo;
	targ->tid = id;
	targ->linkrate = (linkrate>>4);
	targ->flags = 0;
	TAILQ_INIT(&targ->commands);
	TAILQ_INIT(&targ->timedout_commands);
	SLIST_INIT(&targ->luns);
	mps_describe_devinfo(targ->devinfo, devstring, 80);
	mps_vprintf(sc, "Found device <%s> <%s> <0x%04x> <%d/%d>\n", devstring,
	    mps_describe_table(mps_linkrate_names, targ->linkrate),
	    targ->handle, targ->encl_handle, targ->encl_slot);
	if ((sassc->flags & MPSSAS_IN_STARTUP) == 0)
		mpssas_rescan_target(sc, targ);
	mps_vprintf(sc, "Target id 0x%x added\n", targ->tid);
out:
	mpssas_startup_decrement(sassc);
	return (error);

}
コード例 #6
0
ファイル: mps_sas_lsi.c プロジェクト: coyizumi/cs111
static int
mpssas_add_device(struct mps_softc *sc, u16 handle, u8 linkrate){
	char devstring[80];
	struct mpssas_softc *sassc;
	struct mpssas_target *targ;
	Mpi2ConfigReply_t mpi_reply;
	Mpi2SasDevicePage0_t config_page;
	uint64_t sas_address;
	uint64_t parent_sas_address = 0;
	u32 device_info, parent_devinfo = 0;
	unsigned int id;
	int ret = 1, error = 0, i;
	struct mpssas_lun *lun;
	u8 is_SATA_SSD = 0;
	struct mps_command *cm;

	sassc = sc->sassc;
	mpssas_startup_increment(sassc);
	if ((mps_config_get_sas_device_pg0(sc, &mpi_reply, &config_page,
	     MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
		printf("%s: error reading SAS device page0\n", __func__);
		error = ENXIO;
		goto out;
	}

	device_info = le32toh(config_page.DeviceInfo);

	if (((device_info & MPI2_SAS_DEVICE_INFO_SMP_TARGET) == 0)
	 && (le16toh(config_page.ParentDevHandle) != 0)) {
		Mpi2ConfigReply_t tmp_mpi_reply;
		Mpi2SasDevicePage0_t parent_config_page;

		if ((mps_config_get_sas_device_pg0(sc, &tmp_mpi_reply,
		     &parent_config_page, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
		     le16toh(config_page.ParentDevHandle)))) {
			printf("%s: error reading SAS device %#x page0\n",
			       __func__, le16toh(config_page.ParentDevHandle));
		} else {
			parent_sas_address = parent_config_page.SASAddress.High;
			parent_sas_address = (parent_sas_address << 32) |
				parent_config_page.SASAddress.Low;
			parent_devinfo = le32toh(parent_config_page.DeviceInfo);
		}
	}
	/* TODO Check proper endianess */
	sas_address = config_page.SASAddress.High;
	sas_address = (sas_address << 32) | config_page.SASAddress.Low;

	/*
	 * Always get SATA Identify information because this is used to
	 * determine if Start/Stop Unit should be sent to the drive when the
	 * system is shutdown.
	 */
	if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) {
		ret = mpssas_get_sas_address_for_sata_disk(sc, &sas_address,
		    handle, device_info, &is_SATA_SSD);
		if (ret) {
			mps_dprint(sc, MPS_INFO, "%s: failed to get disk type "
			    "(SSD or HDD) for SATA device with handle 0x%04x\n",
			    __func__, handle);
		} else {
			mps_dprint(sc, MPS_INFO, "SAS Address from SATA "
			    "device = %jx\n", sas_address);
		}
	}

	id = mps_mapping_get_sas_id(sc, sas_address, handle);
	if (id == MPS_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 (mpssas_check_id(sassc, id) != 0) {
		device_printf(sc->mps_dev, "Excluding target id %d\n", id);
		error = ENXIO;
		goto out;
	}

	mps_dprint(sc, MPS_MAPPING, "SAS Address from SAS device page0 = %jx\n",
	    sas_address);
	targ = &sassc->targets[id];
	targ->devinfo = device_info;
	targ->devname = le32toh(config_page.DeviceName.High);
	targ->devname = (targ->devname << 32) | 
	    le32toh(config_page.DeviceName.Low);
	targ->encl_handle = le16toh(config_page.EnclosureHandle);
	targ->encl_slot = le16toh(config_page.Slot);
	targ->handle = handle;
	targ->parent_handle = le16toh(config_page.ParentDevHandle);
	targ->sasaddr = mps_to_u64(&config_page.SASAddress);
	targ->parent_sasaddr = le64toh(parent_sas_address);
	targ->parent_devinfo = parent_devinfo;
	targ->tid = id;
	targ->linkrate = (linkrate>>4);
	targ->flags = 0;
	if (is_SATA_SSD) {
		targ->flags = MPS_TARGET_IS_SATA_SSD;
	}
	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_MPT2);
	}
	SLIST_INIT(&targ->luns);

	mps_describe_devinfo(targ->devinfo, devstring, 80);
	mps_dprint(sc, MPS_MAPPING, "Found device <%s> <%s> <0x%04x> <%d/%d>\n",
	    devstring, mps_describe_table(mps_linkrate_names, targ->linkrate),
	    targ->handle, targ->encl_handle, targ->encl_slot);

#if __FreeBSD_version < 1000039
	if ((sassc->flags & MPSSAS_IN_STARTUP) == 0)
#endif
		mpssas_rescan_target(sc, targ);
	mps_dprint(sc, MPS_MAPPING, "Target id 0x%x added\n", targ->tid);

	/*
	 * Check all commands to see if the SATA_ID_TIMEOUT flag has been set.
	 * If so, send a Target Reset TM to the target that was just created.
	 * An Abort Task TM should be used instead of a Target Reset, but that
	 * would be much more difficult because targets have not been fully
	 * discovered yet, and LUN's haven't been setup.  So, just reset the
	 * target instead of the LUN.
	 */
	for (i = 1; i < sc->num_reqs; i++) {
		cm = &sc->commands[i];
		if (cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) {
			targ->timeouts++;
			cm->cm_state = MPS_CM_STATE_TIMEDOUT;

			if ((targ->tm = mpssas_alloc_tm(sc)) != NULL) {
				mps_dprint(sc, MPS_INFO, "%s: sending Target "
				    "Reset for stuck SATA identify command "
				    "(cm = %p)\n", __func__, cm);
				targ->tm->cm_targ = targ;
				mpssas_send_reset(sc, targ->tm,
				    MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET);
			} else {
				mps_dprint(sc, MPS_ERROR, "Failed to allocate "
				    "tm for Target Reset after SATA ID command "
				    "timed out (cm %p)\n", cm);
			}
			/*
			 * No need to check for more since the target is
			 * already being reset.
			 */
			break;
		}
	}
out:
	/*
	 * Free the commands that may not have been freed from the SATA ID call
	 */
	for (i = 1; i < sc->num_reqs; i++) {
		cm = &sc->commands[i];
		if (cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) {
			mps_free_command(sc, cm);
		}
	}
	mpssas_startup_decrement(sassc);
	return (error);
	
}