Пример #1
0
void
CNdasEventMonitor::OnLogicalDeviceAlarmedByPnP(
	__in INdasLogicalUnit* pNdasLogicalUnit, 
	__in ULONG NewAdapterStatus)
{
	NDAS_LOCATION ndasLocation;
	COMVERIFY(pNdasLogicalUnit->get_Id(&ndasLocation));

	XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION,
		"Alarm Event, ndasLocation=%08X, logicalUnit=%p\n", 
		ndasLocation, pNdasLogicalUnit);

	if (0 == ndasLocation) 
	{
		XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_ERROR,
			"Invalid SCSI Location\n");
		XTLASSERT(FALSE);
		return;
	}

	XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION,
		"Logical device alarmed by PnP, ndasLocation=%08X, adapterStatus=%08X.\n", 
		ndasLocation, NewAdapterStatus);

	// Determine whether an alarm will be issued.
	// Only viable alarm will be published
	ULONG currentAdapterStatus;
	COMVERIFY(pNdasLogicalUnit->get_AdapterStatus(&currentAdapterStatus));

	if (pIsViableAlarmStatus(currentAdapterStatus, NewAdapterStatus))
	{
		CNdasEventPublisher& epub = pGetNdasEventPublisher();

		if (ADAPTERINFO_ISSTATUS(NewAdapterStatus, NDASSCSI_ADAPTER_STATUS_STOPPED) &&
			ADAPTERINFO_ISSTATUSFLAG(NewAdapterStatus, NDAS_DEVICE_ALARM_STATUSFLAG_ABNORMAL_TERMINAT))
		{
			//
			// Notify abnormal removal of the LU device.
			//
			OnLogicalDeviceDisconnected(pNdasLogicalUnit);
		}
		else
		{
			NDAS_LOGICALDEVICE_ID logicalUnitId;
			COMVERIFY(pNdasLogicalUnit->get_Id(&logicalUnitId));
			(void) epub.LogicalDeviceAlarmed(
				logicalUnitId, 
				pGetSignificantAlarm(currentAdapterStatus, NewAdapterStatus));
		}
	}

	COMVERIFY(pNdasLogicalUnit->put_AdapterStatus(NewAdapterStatus));
}
Пример #2
0
void
CNdasEventMonitor::OnLogicalDeviceAlarmed(INdasLogicalUnit* pNdasLogicalUnit)
{
	NDAS_LOCATION ndasLocation;
	COMVERIFY(pNdasLogicalUnit->get_Id(&ndasLocation));

	NDAS_LOGICALUNIT_ADDRESS ndasLogicalUnitAddress;
	COMVERIFY(pNdasLogicalUnit->get_LogicalUnitAddress(&ndasLogicalUnitAddress));

	XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION,
		"Alarm Event, ndasLocation=%d, logicalUnit=%p\n", 
		ndasLocation, pNdasLogicalUnit);

	if (0 == ndasLocation) 
	{
		XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_ERROR,
			"Invalid SCSI Location\n");
		XTLASSERT(FALSE);
		return;
	}

	ULONG newAdapterStatus;

	while(TRUE)
	{
		BOOL success = ::NdasBusCtlQueryEvent(
			ndasLocation,
			&newAdapterStatus);

		if (!success) 
		{
			if (::GetLastError() == ERROR_NO_MORE_ITEMS) 
			{
				XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION,
					"No more events, ignored, ndasLocation=%d\n", 
					ndasLocation);
			} 
			else 
			{
				XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_ERROR,
					"Query status failed on alarm, ignored, ndasLocation=%d\n", 
					ndasLocation);
			}
			return;
		}

		XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION,
			"Logical device alarmed, ndasLocation=%d, adapterStatus=%08X.\n", 
			ndasLocation, newAdapterStatus);

		// Determine whether an alarm will be issued.
		// Only viable alarm will be published
		ULONG currentAdapterStatus;
		COMVERIFY(pNdasLogicalUnit->get_AdapterStatus(&currentAdapterStatus));

		if (pIsViableAlarmStatus(currentAdapterStatus, newAdapterStatus))
		{
			CNdasEventPublisher& epub = pGetNdasEventPublisher();
			NDAS_LOGICALDEVICE_ID logicalUnitId;
			COMVERIFY(pNdasLogicalUnit->get_Id(&logicalUnitId));
			(void) epub.LogicalDeviceAlarmed(
				logicalUnitId, 
				pGetSignificantAlarm(currentAdapterStatus, newAdapterStatus));
		}

		COMVERIFY(pNdasLogicalUnit->put_AdapterStatus(newAdapterStatus));

		if (!ADAPTERINFO_ISSTATUSFLAG(
			newAdapterStatus, 
			NDASSCSI_ADAPTER_STATUSFLAG_NEXT_EVENT_EXIST)) 
		{
			break;
		}
	}
}
Пример #3
0
BOOL 
CNdasEventMonitor::OnLogicalDeviceAlarmed(DWORD nWaitIndex)
{
	ximeta::CAutoLock autolock(this);

	CNdasLogicalDevice* pLogDevice = NULL;

	if (nWaitIndex < m_vLogDevices.size()) {
		pLogDevice = m_vLogDevices[nWaitIndex];
	} else {
		_ASSERTE(FALSE);
		return FALSE;
	}

	if (NULL == pLogDevice) {
		_ASSERTE(FALSE);
		return FALSE;
	}

	CNdasScsiLocation ndasScsiLocation = pLogDevice->GetNdasScsiLocation();

	DBGPRT_INFO(_FT("Alarm Event from %s: %s\n"),
		ndasScsiLocation.ToString(),
		pLogDevice->ToString());

	if (ndasScsiLocation.IsInvalid()) {
		DBGPRT_ERR(_FT("Invalid SCSI Location\n"));
		_ASSERTE(FALSE);
		return FALSE;
	}

	//
	// reset the event to prevent consecutive same event pulse
	//
	// should return TRUE
	BOOL fSuccess = ::ResetEvent(pLogDevice->GetAlarmEvent());
	_ASSERTE(fSuccess);

	ULONG ulAdapterStatus;

	fSuccess = ::LsBusCtlQueryStatus(
		ndasScsiLocation.SlotNo,
		&ulAdapterStatus);

	if (!fSuccess) {
		DBGPRT_ERR_EX(_FT("(%s) query status failed on alarm, ignored: "), 
			ndasScsiLocation.ToString());
		return TRUE;
	}

	DBGPRT_INFO(_FT("(%s) alarmed %08X.\n"), 
		ndasScsiLocation.ToString(), ulAdapterStatus);

	// Determine whether an alarm will be issued.
	// Only viable alarm will be published
	if(pIsViableAlarmStatus(pLogDevice->GetAdapterStatus(), ulAdapterStatus))
	{
		CNdasEventPublisher* pEventPublisher = pGetNdasEventPublisher();
		(VOID) pEventPublisher->LogicalDeviceAlarmed(
			pLogDevice->GetLogicalDeviceId(), pGetSignificatAlarm(pLogDevice->GetAdapterStatus(), ulAdapterStatus));
	}

	pLogDevice->SetAdapterStatus(ulAdapterStatus);

	return TRUE;
}