Esempio n. 1
0
DataVaultPtr DataBank_OpenNameSpace (
	DataBankPtr self,
	esif_string nameSpace
	)
{
	DataVaultPtr DB = NULL;
	UInt32 ns;

	// Exit if NameSpace already exists
	// TODO: Change this to a linked list or array of pointers so each DataVaultPtr is static
	esif_ccb_read_lock(&self->lock);
	for (ns = 0; ns < self->size; ns++) {
		if (esif_ccb_stricmp(nameSpace, self->elements[ns].name) == 0) {
			DB = &self->elements[ns];
			break;
		}
	}
	esif_ccb_read_unlock(&self->lock);
	if (DB != NULL || ns >= ESIF_MAX_NAME_SPACES) {
		return DB;
	}

	// Not Found. Create NameSpace
	esif_ccb_write_lock(&self->lock);
	DB = &self->elements[self->size++];
	DataVault_ctor(DB);
	esif_ccb_strcpy(DB->name, nameSpace, ESIF_NAME_LEN);
	esif_ccb_strlwr(DB->name, sizeof(DB->name));
	esif_ccb_write_unlock(&self->lock);
	return DB;
}
Esempio n. 2
0
/* Map a participant handle to  */
eEsifError EsifUpManagerMapLpidToPartHandle(
	const UInt8 lpInstance,
	void *participantHandle
	)
{
	eEsifError rc    = ESIF_E_INVALID_HANDLE;
	UInt8 i = 0;

	/* Validate parameters */
	if (NULL == participantHandle) {
		ESIF_TRACE_ERROR("The participant handle pointer is NULL\n");
		rc = ESIF_E_PARAMETER_IS_NULL;
		goto exit;
	}

	esif_ccb_read_lock(&g_uppMgr.fLock);

	for (i = 0; i < MAX_PARTICIPANT_ENTRY; i++) {
		if (g_uppMgr.fEntries[i].fUpPtr && (g_uppMgr.fEntries[i].fUpPtr->fLpInstance == lpInstance)) {
			break;
		}
	}

	esif_ccb_read_unlock(&g_uppMgr.fLock);

	if (i >= MAX_PARTICIPANT_ENTRY) {
		goto exit;
	}

	*(UInt8 *)participantHandle = i;
	rc = ESIF_OK;

exit:
	return rc;
}
Esempio n. 3
0
void EsifActMgrExit()
{
	u8 i = 0;
	EsifActPtr a_act_ptr = NULL;

	ESIF_TRACE_ENTRY_INFO();

	/* Call before destroying action manager */
	EsifActExit();

	if (NULL != g_actMgr.fActTypes) {
		esif_link_list_destroy(g_actMgr.fActTypes);
		g_actMgr.fActTypes = NULL;  //set to null so that it will be caught if mid-execution
	}

	esif_ccb_read_lock(&g_actMgr.fLock);
	for (i = 0; i < ESIF_MAX_ACTIONS; i++) {
		a_act_ptr = &g_actMgr.fEnrtries[i];
		esif_ccb_free(a_act_ptr->fLibNamePtr);
		esif_ccb_library_unload(a_act_ptr->fLibHandle);
		esif_ccb_memset(a_act_ptr, 0, sizeof(*a_act_ptr));
	}
	esif_ccb_read_unlock(&g_actMgr.fLock);

	esif_ccb_lock_uninit(&g_actMgr.fLock);

	ESIF_TRACE_EXIT_INFO();
}
Esempio n. 4
0
/* Get By Instance From ID */
EsifUpPtr EsifUpManagerGetAvailableParticipantByInstance (
	const UInt8 id
	)
{
	EsifUpPtr up_ptr = NULL;
	ESIF_TRACE_DEBUG("%s: instance %d\n", ESIF_FUNC, id);

	if (id >= MAX_PARTICIPANT_ENTRY) {
		ESIF_TRACE_ERROR("Instance id %d is out of range\n", id);
		ESIF_ASSERT(0);
		goto exit;
	}

	/* Lock manager */
	esif_ccb_read_lock(&g_uppMgr.fLock);

	if (g_uppMgr.fEntries[id].fState > ESIF_PM_PARTICIPANT_REMOVED) {
		up_ptr = g_uppMgr.fEntries[id].fUpPtr;
	}

	/* Unlock Manager */
	esif_ccb_read_unlock(&g_uppMgr.fLock);

exit:

	if (NULL == up_ptr) {
		ESIF_TRACE_DEBUG("%s: instance %d NOT found or OUT OF BOUNDS\n",
						 ESIF_FUNC, id);
	}
	return up_ptr;
}
Esempio n. 5
0
void EsifAppMgrExit()
{
	u8 i = 0;
	EsifAppPtr a_app_ptr = NULL;

	ESIF_TRACE_ENTRY_INFO();

	EsifEventMgr_UnregisterEventByType(ESIF_EVENT_PARTICIPANT_SUSPEND, EVENT_MGR_MATCH_ANY, EVENT_MGR_DOMAIN_D0, EsifAppMgr_EventCallback, NULL);
	EsifEventMgr_UnregisterEventByType(ESIF_EVENT_PARTICIPANT_RESUME, EVENT_MGR_MATCH_ANY, EVENT_MGR_DOMAIN_D0, EsifAppMgr_EventCallback, NULL);

	EsifAppExit();
	ESIF_TRACE_DEBUG("Exit Action Manager (APPMGR)");

	esif_ccb_read_lock(&g_appMgr.fLock);
	for (i = 0; i < ESIF_MAX_APPS; i++) {
		a_app_ptr = &g_appMgr.fEntries[i];

		// Attempt to gracefully shutdown App before forcing library unload
		if (a_app_ptr->fLibNamePtr != NULL) {
			EsifAppStop(a_app_ptr);
		}
		if (a_app_ptr->fLibNamePtr != NULL) {
			esif_ccb_library_unload(a_app_ptr->fLibHandle);
			esif_ccb_free(a_app_ptr->fLibNamePtr);
			esif_ccb_memset(a_app_ptr, 0, sizeof(*a_app_ptr));
		}
	}
	esif_ccb_read_unlock(&g_appMgr.fLock);

	esif_ccb_lock_uninit(&g_appMgr.fLock);

	ESIF_TRACE_EXIT_INFO();
}
Esempio n. 6
0
/* Check if a participant already exists by the name */
Bool EsifUpManagerDoesAvailableParticipantExistByName (
	char *participantName
	)
{
	Bool bRet = ESIF_FALSE;
	EsifUpPtr up_ptr = NULL;
	UInt8 i;

	if (NULL == participantName) {
		ESIF_TRACE_ERROR("The participant name pointer is NULL\n");
		goto exit;
	}

	esif_ccb_read_lock(&g_uppMgr.fLock);

	for (i = 0; i < MAX_PARTICIPANT_ENTRY; i++) {
		up_ptr = EsifUpManagerGetAvailableParticipantByInstance(i);

		if (NULL == up_ptr) {
			continue;
		}

		if ((g_uppMgr.fEntries[i].fState > ESIF_PM_PARTICIPANT_REMOVED) && !strcmp(up_ptr->fMetadata.fName, participantName)) {
			bRet = ESIF_TRUE;
			break;
		}
	}
	esif_ccb_read_unlock(&g_uppMgr.fLock);
exit:
	return bRet;
}
Esempio n. 7
0
/* Removes a participant from each running application */
eEsifError EsifAppMgrDestroyParticipantInAllApps(const EsifUpPtr upPtr)
{
	eEsifError rc = ESIF_OK;
	EsifAppPtr app_ptr = NULL;
	UInt8 i;

	if (NULL == upPtr) {
		ESIF_TRACE_ERROR("The participant data pointer is NULL\n");
		rc = ESIF_E_PARAMETER_IS_NULL;
		goto exit;
	}

	esif_ccb_read_lock(&g_appMgr.fLock);

	for (i = 0; i < ESIF_MAX_APPS; i++) {
		app_ptr = &g_appMgr.fEntries[i];

		if (NULL != app_ptr->fHandle) {
			EsifAppDestroyParticipant(app_ptr, upPtr);
		}
	}

	esif_ccb_read_unlock(&g_appMgr.fLock);
exit:
	return rc;
}
Esempio n. 8
0
EsifUpPtr EsifUpManagerGetAvailableParticipantByName (
	char *participantName
	)
{
	EsifUpPtr up_ptr = NULL;
	UInt8 i;

	if (NULL == participantName) {
		ESIF_TRACE_ERROR("The participant name pointer is NULL\n");
		goto exit;
	}

	esif_ccb_read_lock(&g_uppMgr.fLock);

	for (i = 0; i < MAX_PARTICIPANT_ENTRY; i++) {
		up_ptr = EsifUpManagerGetAvailableParticipantByInstance(i);

		if (NULL == up_ptr) {
			continue;
		}
		if (!strcmp(participantName, up_ptr->fMetadata.fName)) {
			break;
		}
		up_ptr = NULL;
	}

	esif_ccb_read_unlock(&g_uppMgr.fLock);
exit:
	return up_ptr;
}
Esempio n. 9
0
eEsifError EsifUpManagerRegisterParticipantsWithApp(EsifAppPtr aAppPtr)
{
	eEsifError rc = ESIF_OK;
	UInt8 i = 0;

	if (NULL == aAppPtr) {
		ESIF_TRACE_ERROR("Esif app pointer is NULL\n");
		return ESIF_E_PARAMETER_IS_NULL;
	}

	esif_ccb_read_lock(&g_uppMgr.fLock);

	/* Skip 0 ESIF treats this as a participant no one else does :) */
	for (i = 1; i < MAX_PARTICIPANT_ENTRY; i++) {
		EsifUpPtr up_ptr = g_uppMgr.fEntries[i].fUpPtr;
		if ((NULL != up_ptr) && (g_uppMgr.fEntries[i].fState > ESIF_PM_PARTICIPANT_REMOVED)) {
			rc = EsifAppCreateParticipant(aAppPtr, up_ptr);
			if (ESIF_OK != rc) {
				break;
			}
		}
	}

	esif_ccb_read_unlock(&g_uppMgr.fLock);

	ESIF_TRACE_INFO("Register participants with App, status = %s\n", esif_rc_str(rc));
	return rc;
}
Esempio n. 10
0
int EsifLogFile_IsOpen(EsifLogType type)
{
	int rc=0;
	esif_ccb_read_lock(&g_EsifLogFile[type].lock);
	rc = (g_EsifLogFile[type].handle != NULL);
	esif_ccb_read_unlock(&g_EsifLogFile[type].lock);
	return rc;
}
Esempio n. 11
0
// Does specified Key exist in the given nameSpace?
int DataBank_KeyExists (
	DataBankPtr self,
	StringPtr nameSpace, // NULL == Default Namespace
	StringPtr keyName
	)
{
	DataVaultPtr DB = NULL;
	int result = ESIF_FALSE;

	esif_ccb_read_lock(&self->lock);
	DB = DataBank_GetNameSpace(self, nameSpace);
	if (NULL != DB && DataCache_GetValue(DB->cache, keyName) != NULL) {
		result = ESIF_TRUE;
	}
	esif_ccb_read_unlock(&self->lock);
	return result;
}
Esempio n. 12
0
eEsifError EsifUpManagerDestroyParticipantsInApp(EsifAppPtr aAppPtr)
{
	UInt8 i = 0;

	esif_ccb_read_lock(&g_uppMgr.fLock);

	for (i = 0; i < MAX_PARTICIPANT_ENTRY; i++) {
		EsifUpPtr up_ptr = g_uppMgr.fEntries[i].fUpPtr;
		if ((NULL != up_ptr) && (g_uppMgr.fEntries[i].fState > ESIF_PM_PARTICIPANT_REMOVED)) {
			EsifAppDestroyParticipant(aAppPtr, up_ptr);
		}
	}

	esif_ccb_read_unlock(&g_uppMgr.fLock);

	ESIF_TRACE_INFO("Destroy participants in App\n");
	return ESIF_OK;
}
Esempio n. 13
0
// backwards compatibility
eEsifError EsifConfigGetItem(
	EsifDataPtr nameSpace,
	EsifDataPtr path,
	EsifDataPtr value,
	esif_flags_t *flagsPtr
	)
{
	eEsifError rc = ESIF_OK;
	DataVaultPtr DB = DataBank_GetNameSpace(g_DataBankMgr, (StringPtr)(nameSpace->buf_ptr));
	if (DB) {
		esif_ccb_read_lock(&DB->lock);
		rc = DataVault_GetValue(DB, path, value, flagsPtr);
		esif_ccb_read_unlock(&DB->lock);
	}
	else {
		rc = ESIF_E_NOT_FOUND;
	}
	return rc;
}
Esempio n. 14
0
void EsifCnjMgrExit()
{
    u8 i = 0;
    EsifCnjPtr a_conjure_ptr = NULL;

    EsifCnjExit();
    ESIF_TRACE_DEBUG("%s: Exit Action Manager (CNJMGR)", ESIF_FUNC);

    esif_ccb_read_lock(&g_cnjMgr.fLock);
    for (i = 0; i < ESIF_MAX_CONJURES; i++) {
        a_conjure_ptr = &g_cnjMgr.fEnrtries[i];
        esif_ccb_free(a_conjure_ptr->fLibNamePtr);
        esif_ccb_library_unload(a_conjure_ptr->fLibHandle);
        esif_ccb_memset(a_conjure_ptr, 0, sizeof(*a_conjure_ptr));
    }
    esif_ccb_read_unlock(&g_cnjMgr.fLock);

    esif_ccb_lock_uninit(&g_cnjMgr.fLock);

    ESIF_TRACE_EXIT_INFO();
}
Esempio n. 15
0
Bool EsifEventMgr_IsEventRegistered(
	eEsifEventType eventType,
	void *key,
	UInt8 participantId,
	UInt16 domainId
	)
{
	Bool bRet = ESIF_FALSE;
	EsifLinkListPtr listPtr = NULL;
	EsifLinkListNodePtr nodePtr = NULL;
	EventMgrEntryPtr entryPtr = NULL;

	esif_ccb_read_lock(&g_EsifEventMgr.listLock);
	listPtr = g_EsifEventMgr.observerLists[eventType % NUM_EVENT_LISTS];
	if (NULL == listPtr) {
		goto exit;
	}
	nodePtr = listPtr->head_ptr;
	while(NULL != nodePtr) {
		entryPtr = (EventMgrEntryPtr)nodePtr->data_ptr;
		ESIF_ASSERT(entryPtr != NULL);

		if((eventType == entryPtr->fpcEvent.esif_event) &&
			(entryPtr->contextPtr == key) && 
			((entryPtr->participantId == participantId) || (entryPtr->participantId == EVENT_MGR_MATCH_ANY)) &&
			((entryPtr->domainId == domainId) || (entryPtr->domainId == EVENT_MGR_MATCH_ANY) || (domainId == EVENT_MGR_DOMAIN_NA)) &&
			(entryPtr->refCount > 0)) {

			bRet = ESIF_TRUE;
			break;
		}

		nodePtr = nodePtr->next_ptr;
	}
exit:
	esif_ccb_read_unlock(&g_EsifEventMgr.listLock);
	return bRet;
}
Esempio n. 16
0
// Return NameSpace in the Configuration Manager or NULL if it doesn't exist
DataVaultPtr DataBank_GetNameSpace (
	DataBankPtr self,
	StringPtr nameSpace
	)
{
	DataVaultPtr result = NULL;
	UInt32 ns;

	if (NULL == nameSpace) {
		nameSpace = g_DataVaultDefault;
	}
	if (NULL != nameSpace) {
		esif_ccb_read_lock(&self->lock);
		for (ns = 0; ns < self->size; ns++) {
			if (esif_ccb_stricmp(nameSpace, self->elements[ns].name) == 0) {
				result = &self->elements[ns];
				break;
			}
		}
		esif_ccb_read_unlock(&self->lock);
	}
	return result;
}
Esempio n. 17
0
EsifString EsifDspMgr_SelectDsp(
	EsifDspQuery query
	)
{
	int i = 0;							// Loop index for DSP table.
	int weight = 0;						// Total weight of DSP query
	int primaryWeight = 0;				// Weight of items sufficient for selection.
	int secondaryWeight = 0;			// Weight of items allowed to sway results, but cannot stand alone.
	int heaviest = -1;					// Heaviest Row Found.
	EsifString dspNamePtr = NULL;		// DSP Name/Code To Use.
	int best = 0;						// Best Weight Possible.
	char *defaultDsp = GetDSPFromList(query.participantName); // Default DSP based on Participant Name

	/*
	** Query table for weighted match highest score wins. It is
	** unlikely that the table would change but we lock it just
	** to be sure it can't.
	*/
	
	// LOCK
	esif_ccb_read_lock(&g_dm.lock);

	for (i = 0; i < g_dm.dme_count; i++) {
		EsifDspPtr dspPtr = g_dm.dme[i].dsp_ptr;
		char busEnum[ENUM_TO_STRING_LEN] = { 0 };

		if (dspPtr == NULL) {
			continue;
		}

		esif_ccb_sprintf(ENUM_TO_STRING_LEN, busEnum, "%d", *dspPtr->bus_enum);
		
		// Primary weight indicates items that can result in a match
		primaryWeight =
			compare_and_weight_minterm(dspPtr->device_id, query.deviceId, PCI_DEVICE_ID_WEIGHT) +
			compare_and_weight_minterm(dspPtr->acpi_device, query.hid, ACPI_HID_WEIGHT) +
			compare_and_weight_minterm(dspPtr->acpi_type, query.ptype, ACPI_PTYPE_WEIGHT) +
			compare_and_weight_minterm(dspPtr->code_ptr, defaultDsp, PARTICIPANT_NAME_WEIGHT);

		// Secondary items can contribute only if at least one primary match is found
		secondaryWeight = 
			compare_and_weight_minterm(dspPtr->acpi_uid, query.uid, ACPI_UID_WEIGHT) +
			compare_and_weight_minterm(dspPtr->vendor_id, query.vendorId, PCI_VENDOR_ID_WEIGHT) +
			compare_and_weight_minterm(busEnum, query.enumerator, ENUMERATOR_TYPE_WEIGHT);

		// Items in secondary can weigh in on the results but cannot be the sole factor
		if (primaryWeight < MIN_VIABLE_DSP_WEIGHT) {
			weight = primaryWeight;
		}
		else {
			weight = primaryWeight + secondaryWeight;
		}

		ESIF_TRACE_DEBUG("DSP: %s Weight: %d\n", (esif_string) dspPtr->code_ptr, weight);

		//Keep track of row with most weight.  
		if (weight > heaviest) {
			heaviest = weight;
			dspNamePtr = dspPtr->code_ptr;
		}
	}

	// UNLOCK
	esif_ccb_read_unlock(&g_dm.lock);

	if (dspNamePtr != NULL) {
		ESIF_TRACE_DEBUG("Selected DSP: %s Score: %d of %d\n", dspNamePtr, heaviest, best);
	}
	else {
		ESIF_TRACE_ERROR("No DSP selected for %s. \n", query.participantName);
	}

	return dspNamePtr;
}
Esempio n. 18
0
// Find Next path in nameSpace
eEsifError EsifConfigFindNext(
	EsifDataPtr nameSpace,
	EsifDataPtr path,
	EsifDataPtr value,
	EsifConfigFindContextPtr context
	)
{
	eEsifError rc = ESIF_E_NOT_FOUND;
	DataVaultPtr DB = 0;

	ESIF_ASSERT(nameSpace && path && context);
	DB = DataBank_GetNameSpace(g_DataBankMgr, (StringPtr)(nameSpace->buf_ptr));
	if (DB) {
		UInt32 item = 0;

		esif_ccb_read_lock(&DB->lock);

		for (item = 0; item < DB->cache->size; item++) {
			if (*context == NULL || esif_ccb_stricmp(DB->cache->elements[item].key.buf_ptr, *context) > 0) {
				break;
			}
		}

		// Find next matching key
		while (item < DB->cache->size && EsifConfigKeyMatch(path, &DB->cache->elements[item].key) != ESIF_TRUE) {
			item++;
		}

		// Return matching item, if any
		if (item < DB->cache->size) {
			esif_ccb_free(*context);
			*context = esif_ccb_strdup(DB->cache->elements[item].key.buf_ptr);
			
			if (path->buf_len && path->buf_len < DB->cache->elements[item].key.data_len) {
				rc = ESIF_E_NEED_LARGER_BUFFER;
			}
			else {
				EsifData_Set(path, 
							 ESIF_DATA_STRING,
							 esif_ccb_strdup((char*)DB->cache->elements[item].key.buf_ptr),
							 DB->cache->elements[item].key.data_len,
							 DB->cache->elements[item].key.data_len);

				// If no value buffer for result, just return next matching key
				if (NULL == value)
					rc = ESIF_OK;
				else
					rc = EsifConfigGet(nameSpace, path, value);
			}
		}
		else if (*context != NULL) {
			rc = ESIF_E_ITERATION_DONE;
		}
		esif_ccb_read_unlock(&DB->lock);
	}

	if (rc != ESIF_OK) {
		EsifConfigFindClose(context);
	}
	return rc;
}
Esempio n. 19
0
/* Get Kernel Information */
static void esif_execute_ipc_command_get_memory_stats(
	struct esif_ipc_command *command_ptr
	)
{
	/* Sanity Check */
	if (ESIF_DATA_STRUCTURE == command_ptr->rsp_data_type &&
	    0 == command_ptr->rsp_data_offset &&
	    sizeof(struct esif_command_get_memory_stats) ==
	    command_ptr->rsp_data_len) {

		struct esif_command_get_memory_stats *data_ptr =
			(struct esif_command_get_memory_stats *)
			(command_ptr + 1);
		u32 reset = *(u32 *)data_ptr;

		if (reset) {
			esif_ccb_memset(&data_ptr->stats, 0,
					sizeof(struct esif_memory_stats));

			esif_ccb_write_lock(&g_memstat_lock);
			esif_ccb_memset(&g_memstat, 0,
					sizeof(struct esif_memory_stats));
			esif_ccb_write_unlock(&g_memstat_lock);
		} else {
			int i = 0;

			esif_ccb_read_lock(&g_memstat_lock);
			esif_ccb_memcpy(&data_ptr->stats, &g_memstat,
					sizeof(struct esif_memory_stats));
			esif_ccb_read_unlock(&g_memstat_lock);

			esif_ccb_read_lock(&g_mempool_lock);
			for (i = 0; i < ESIF_MEMPOOL_TYPE_MAX; i++) {
				if (NULL == g_mempool[i])
					continue;	/* Skip Unused */

				esif_ccb_strcpy(data_ptr->mempool_stat[i].name,
						g_mempool[i]->name_ptr,
						ESIF_NAME_LEN);
				data_ptr->mempool_stat[i].pool_tag    =
					g_mempool[i]->pool_tag;
				data_ptr->mempool_stat[i].object_size =
					g_mempool[i]->object_size;
				data_ptr->mempool_stat[i].alloc_count =
					g_mempool[i]->alloc_count;
				data_ptr->mempool_stat[i].free_count  =
					g_mempool[i]->free_count;
			}
			esif_ccb_read_unlock(&g_mempool_lock);

			esif_ccb_read_lock(&g_memtype_lock);
			for (i = 0; i < ESIF_MEMTYPE_TYPE_MAX; i++) {
				if (NULL == g_memtype[i])
					continue;	/* Skip Unused */

				esif_ccb_strcpy(data_ptr->memtype_stat[i].name,
						g_memtype[i]->name_ptr,
						ESIF_NAME_LEN);
				data_ptr->memtype_stat[i].pool_tag    =
					g_memtype[i]->type_tag;
				data_ptr->memtype_stat[i].alloc_count =
					g_memtype[i]->alloc_count;
				data_ptr->memtype_stat[i].free_count  =
					g_memtype[i]->free_count;
			}
			esif_ccb_read_unlock(&g_memtype_lock);
		}

		ESIF_TRACE_DYN_COMMAND(
			"%s: ESIF_COMMAND_TYPE_GET_MEMORY_STATS reset %d\n",
			ESIF_FUNC,
			reset);

		command_ptr->return_code = ESIF_OK;
	}
}
Esempio n. 20
0
/* Get */
enum esif_rc esif_get_action_mmio(
	const struct esif_lp *lp_ptr,
	const struct esif_lp_primitive *primitive_ptr,
	const struct esif_lp_action *action_ptr,
	struct esif_data *req_data_ptr,
	struct esif_data *rsp_data_ptr
	)
{
	enum esif_rc rc = ESIF_OK;
	void __iomem *base_addr = NULL;
	u32 offset;
	u8 bit_from;
	u8 bit_to;
	int i = 0;		/* Loop Counter                            */
	u32 val = 0;		/* Temporary MMIO Value MMIO Always 32 Bit */
	u32 bit_mask = 0;	/* Bit Mask For MMIO Value                 */

	UNREFERENCED_PARAMETER(primitive_ptr);
	UNREFERENCED_PARAMETER(req_data_ptr);

	if ((NULL == lp_ptr) || (NULL == action_ptr) ||
	    (NULL == rsp_data_ptr)) {
		rc = ESIF_E_PARAMETER_IS_NULL;
		goto exit;
	}

	base_addr = lp_ptr->pi_ptr->mem_base;
	if (NULL == base_addr) {
		rc = ESIF_E_NO_MMIO_SUPPORT;
		goto exit;
	}

	offset = action_ptr->get_p1_u32(action_ptr);
	bit_from = (u8)action_ptr->get_p3_u32(action_ptr);
	bit_to  = (u8)action_ptr->get_p2_u32(action_ptr);

#ifdef ESIF_ATTR_OS_WINDOWS
	if ((offset + MMIO_ACCESS_SIZE) > lp_ptr->pi_ptr->mem_size) {
		rc = ESIF_E_PARAMETER_IS_OUT_OF_BOUNDS;
		goto exit;
	}
#endif

	/* Read MMIO 32-Bit Always */
	esif_ccb_read_lock(&g_esif_action_mmio_lock);
	esif_ccb_mmio_read(base_addr, offset, &val);
	esif_ccb_read_unlock(&g_esif_action_mmio_lock);

	/* Mask Bits */
	for (bit_mask = 0, i = bit_from; i <= bit_to; i++)
		bit_mask |= (1 << i);

	val = val & bit_mask;
	val = val >> bit_from;

	ESIF_TRACE_DYN_GET("Base %p offset 0x%x[%d:%d] = 0x%x\n",
			   base_addr, offset, bit_to, bit_from, val);

	switch (rsp_data_ptr->type) {
	case ESIF_DATA_UINT8:
		rsp_data_ptr->data_len = sizeof(u8);
		if (rsp_data_ptr->buf_len >= sizeof(u8))
			*((u8 *)rsp_data_ptr->buf_ptr) = (u8)val;
		else
			rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
		break;

	case ESIF_DATA_UINT16:
		rsp_data_ptr->data_len = sizeof(u16);
		if (rsp_data_ptr->buf_len >= sizeof(u16))
			*((u16 *)rsp_data_ptr->buf_ptr) = (u16)val;
		else
			rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
		break;

	case ESIF_DATA_UINT32:
	case ESIF_DATA_TIME:
		rsp_data_ptr->data_len = sizeof(u32);
		if (rsp_data_ptr->buf_len >= sizeof(u32))
			*((u32 *)rsp_data_ptr->buf_ptr) = (u32)val;
		else
			rc = ESIF_E_OVERFLOWED_RESULT_TYPE;
		break;

	default:
		rc = ESIF_E_UNSUPPORTED_RESULT_DATA_TYPE;
		break;
	}
exit:
	ESIF_TRACE_DYN_GET("RC: %s(%d)\n", esif_rc_str(rc), rc);
	return rc;
}