// // Remove the unit device ID from the list // BOOL CNdasLogicalDevice::RemoveUnitDevice(CNdasUnitDevice& unitDevice) { ximeta::CAutoLock autolock(this); DWORD ldSequence = unitDevice.GetLDSequence(); _ASSERTE(ldSequence < m_logicalDeviceGroup.nUnitDevices); if (ldSequence >= m_logicalDeviceGroup.nUnitDevices) { DBGPRT_ERR(_FT("Invalid sequence (%d) of the unit device.\n"), ldSequence); return FALSE; } _ASSERTE(&unitDevice == m_pUnitDevices[ldSequence]); if (&unitDevice != m_pUnitDevices[ldSequence]) { DBGPRT_ERR(_FT("Unit device in sequence (%d) is not occupied.\n"), ldSequence); return FALSE; } m_pUnitDevices[ldSequence]->Release(); m_pUnitDevices[ldSequence] = NULL; // // Workaround for Fault-tolerant Mode // -> Even if the logical device is incomplete, // Mounted Logical Device Location should be intact // if it is mounted // if (NDAS_LOGICALDEVICE_STATUS_MOUNT_PENDING == GetStatus() || NDAS_LOGICALDEVICE_STATUS_MOUNTED == GetStatus() || NDAS_LOGICALDEVICE_STATUS_UNMOUNT_PENDING == GetStatus()) { --m_nUnitDeviceInstances; return TRUE; } if (IsComplete()) { CNdasLogicalDeviceManager* pLdm = pGetNdasLogicalDeviceManager(); pLdm->UnregisterNdasScsiLocation(m_NdasScsiLocation); } --m_nUnitDeviceInstances; // // Deallocation NDAS SCSI Location when the fist unit device is removed // if (0 == ldSequence) { cpDeallocateNdasScsiLocation(); } // // Publish Event // CNdasEventPublisher* pEventPublisher = pGetNdasEventPublisher(); (VOID) pEventPublisher->LogicalDeviceRelationChanged(m_logicalDeviceId); // // Set Device Error // SetLastDeviceError(NDAS_LOGICALDEVICE_ERROR_MISSING_MEMBER); return TRUE; }
// // Set the unit device ID at a sequence // to a unit device member ID list // BOOL CNdasLogicalDevice::AddUnitDevice(CNdasUnitDevice& unitDevice) { ximeta::CAutoLock autolock(this); BOOL fSuccess; DWORD ldSequence = unitDevice.GetLDSequence(); _ASSERTE(ldSequence < m_logicalDeviceGroup.nUnitDevices); if (ldSequence >= m_logicalDeviceGroup.nUnitDevices) { DBGPRT_ERR(_FT("Invalid sequence (%d) of the unit device.\n"), ldSequence); return FALSE; } _ASSERTE(NULL == m_pUnitDevices[ldSequence]); if (NULL != m_pUnitDevices[ldSequence]) { DBGPRT_ERR(_FT("Sequence (%d) is already occupied.\n"), ldSequence); return FALSE; } _ASSERTE(NULL == m_pUnitDevices[ldSequence]); m_pUnitDevices[ldSequence] = &unitDevice; m_pUnitDevices[ldSequence]->AddRef(); ++m_nUnitDeviceInstances; _ASSERTE( m_nUnitDeviceInstances >= 0 && m_nUnitDeviceInstances <= GetUnitDeviceCount() ); if (m_nUnitDeviceInstances < GetUnitDeviceCount()) { SetLastDeviceError(NDAS_LOGICALDEVICE_ERROR_MISSING_MEMBER); } else { SetLastDeviceError(NDAS_LOGICALDEVICE_ERROR_NONE); } // // Allocate NDAS SCSI Location when the first unit device is // available // if (0 == ldSequence) { cpAllocateNdasScsiLocation(); } if (IsComplete()) { CNdasLogicalDeviceManager* pLdm = pGetNdasLogicalDeviceManager(); pLdm->RegisterNdasScsiLocation(m_NdasScsiLocation, *this); } if (IsComplete()) { // // Reconciliation Support // BOOL bAlive, bAdapterError; fSuccess = ::LsBusCtlQueryNodeAlive( m_NdasScsiLocation.SlotNo, &bAlive, &bAdapterError); // // Reconciliation // if (fSuccess && bAlive) { ReconcileFromNdasBus(); } } else if (IsComplete() && m_fMountOnReady) { // // Boot-time Plug In Support // if ((m_mountOnReadyAccess & GetAllowingAccess()) == m_mountOnReadyAccess) { (VOID) PlugIn(m_mountOnReadyAccess); } else if ((GENERIC_READ & GetAllowingAccess()) && m_fReducedMountOnReadyAccess) { (VOID) PlugIn(GENERIC_READ); } } DBGPRT_INFO(_FT("Added %s to Logical Device %s\n"), unitDevice.ToString(), this->ToString()); CNdasEventPublisher* pEventPublisher = pGetNdasEventPublisher(); (VOID) pEventPublisher->LogicalDeviceRelationChanged(m_logicalDeviceId); return TRUE; }