// Find Next path in nameSpace eEsifError EsifConfigFindNext ( EsifDataPtr nameSpace, EsifDataPtr path, EsifDataPtr value, UInt32 *context ) { eEsifError rc = ESIF_E_NOT_FOUND; DataVaultPtr DB = 0; ASSERT(nameSpace && path && value && context); DB = DataBank_GetNameSpace(g_DataBankMgr, (StringPtr)(nameSpace->buf_ptr)); if (DB) { UInt32 item = *context; if (item >= DB->cache->size) { return rc; } (*context)++; if (path->buf_len && path->buf_len < DB->cache->elements[item].value.data_len) { return ESIF_E_NEED_LARGER_BUFFER; } 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); return EsifConfigGet(nameSpace, path, value); } return rc; }
static eEsifError ESIF_CALLCONV ActionConfigGet( esif_context_t actCtx, EsifUpPtr upPtr, const EsifFpcPrimitivePtr primitivePtr, const EsifFpcActionPtr fpcActionPtr, const EsifDataPtr requestPtr, const EsifDataPtr responsePtr ) { eEsifError rc = ESIF_OK; EsifData params[2] = {0}; EsifString replacedStrs[2] = {0}; EsifString replacedStr = NULL; UInt8 i; UNREFERENCED_PARAMETER(actCtx); UNREFERENCED_PARAMETER(requestPtr); ESIF_ASSERT(NULL != responsePtr); ESIF_ASSERT(NULL != responsePtr->buf_ptr); rc = EsifFpcAction_GetParams(fpcActionPtr, params, sizeof(params)/sizeof(*params)); if (ESIF_OK != rc) { goto exit; } for (i = 0; i < sizeof(replacedStrs) / sizeof(*replacedStrs); i++) { replacedStr = EsifUp_CreateTokenReplacedParamString(upPtr, primitivePtr, params[i].buf_ptr); if (replacedStr != NULL) { params[i].buf_ptr = replacedStr; replacedStrs[i] = replacedStr; } } ESIF_ASSERT(NULL != params[0].buf_ptr); ESIF_ASSERT(ESIF_DATA_STRING == params[0].type); rc = EsifConfigGet(¶ms[0], ¶ms[1], responsePtr); exit: for (i = 0; i < sizeof(replacedStrs) / sizeof(*replacedStrs); i++) { esif_ccb_free(replacedStrs[i]); } return rc; }
// Send DSP enum esif_rc esif_send_dsp( char *filename, u8 dstId ) { enum esif_rc rc = ESIF_OK; int edpSize = 512; int cmdSize = 0; struct esif_ipc *ipcPtr = NULL; struct esif_ipc_command *commandPtr = NULL; struct esif_command_send_dsp *dspCommandPtr = NULL; struct edp_dir edpDir; size_t bytesRead; char *edpName = 0; IOStreamPtr ioPtr = IOStream_Create(); EsifDataPtr nameSpace = 0; EsifDataPtr key = 0; EsifDataPtr value = 0; if (ioPtr == NULL) { ESIF_TRACE_ERROR("Fail to create IOStream\n"); rc = ESIF_E_NO_MEMORY; goto exit; } // // If we have a filename provided use the contents of the file as the CPC // note this is opaque it is up to the receiver to verify that this is in fact // a CPC. // if (NULL == filename) { ESIF_TRACE_ERROR("Filename is null\n"); rc = ESIF_E_PARAMETER_IS_NULL; goto exit; } // Use name portion of filename for the DataVault key (C:\path\file.edp = file.edp) edpName = strrchr(filename, *ESIF_PATH_SEP); edpName = (edpName ? ++edpName : filename); nameSpace = EsifData_CreateAs(ESIF_DATA_STRING, ESIF_DSP_NAMESPACE, 0, ESIFAUTOLEN); key = EsifData_CreateAs(ESIF_DATA_STRING, edpName, 0, ESIFAUTOLEN); value = EsifData_CreateAs(ESIF_DATA_AUTO, NULL, ESIF_DATA_ALLOCATE, 0); if (nameSpace == NULL || key == NULL || value == NULL) { rc = ESIF_E_NO_MEMORY; goto exit; } // Look for EDP file on disk first then DataVault (static or file) if (!esif_ccb_file_exists(filename) && EsifConfigGet(nameSpace, key, value) == ESIF_OK) { filename = edpName; IOStream_SetMemory(ioPtr, (BytePtr)value->buf_ptr, value->data_len); } else { IOStream_SetFile(ioPtr, filename, (char *)"rb"); } /* FIND CPC within EDP file */ if (IOStream_Open(ioPtr) != 0) { ESIF_TRACE_ERROR("File not found (%s)\n", filename); rc = ESIF_E_IO_OPEN_FAILED; goto exit; } bytesRead = IOStream_Read(ioPtr, &edpDir, sizeof(struct edp_dir)); if (!esif_verify_edp(&edpDir, bytesRead)) { ESIF_TRACE_ERROR("Invalid EDP Header: Signature=%4.4s Version=%d\n", (char *)&edpDir.signature, edpDir.version); rc = ESIF_E_NOT_SUPPORTED; goto exit; } edpSize = edpDir.fpc_offset - edpDir.cpc_offset; IOStream_Seek(ioPtr, edpDir.cpc_offset, SEEK_SET); if (edpSize > MAX_EDP_SIZE) { ESIF_TRACE_ERROR("The edp size %d is larger than maximum edp size\n", edpSize); rc = -ESIF_E_UNSPECIFIED; goto exit; } cmdSize = edpSize + sizeof(*dspCommandPtr); ipcPtr = esif_ipc_alloc_command(&commandPtr, cmdSize); if (NULL == ipcPtr || NULL == commandPtr) { ESIF_TRACE_ERROR("Fail to allocate esif_ipc/esif_ipc_command\n"); rc = ESIF_E_NO_MEMORY; goto exit; } commandPtr->type = ESIF_COMMAND_TYPE_SEND_DSP; commandPtr->req_data_type = ESIF_DATA_STRUCTURE; commandPtr->req_data_offset = 0; commandPtr->req_data_len = cmdSize; commandPtr->rsp_data_type = ESIF_DATA_VOID; commandPtr->rsp_data_offset = 0; commandPtr->rsp_data_len = 0; dspCommandPtr = (struct esif_command_send_dsp *)(commandPtr + 1); dspCommandPtr->id = dstId; dspCommandPtr->data_len = edpSize; bytesRead = IOStream_Read(ioPtr, dspCommandPtr + 1, edpSize); ESIF_TRACE_DEBUG("loaded file %s bytes %d\n", filename, (int)bytesRead); ESIF_TRACE_INFO("CPC file %s(%d) sent to participant %d\n", filename, edpSize, dstId); ipc_execute(ipcPtr); if (ESIF_OK != ipcPtr->return_code) { ESIF_TRACE_ERROR("ipc error code = %s(%d)\n", esif_rc_str(ipcPtr->return_code), ipcPtr->return_code); rc = ipcPtr->return_code; goto exit; } rc = commandPtr->return_code; if ((rc != ESIF_OK) && (rc != ESIF_E_DSP_ALREADY_LOADED)) { ESIF_TRACE_ERROR("primitive error code = %s(%d)\n", esif_rc_str(commandPtr->return_code), commandPtr->return_code); goto exit; } exit: if (NULL != ipcPtr) { esif_ipc_free(ipcPtr); } if (NULL != ioPtr) { IOStream_Close(ioPtr); IOStream_Destroy(ioPtr); } EsifData_Destroy(nameSpace); EsifData_Destroy(key); EsifData_Destroy(value); return rc; }
/* Add DSP Entry */ static eEsifError esif_dsp_entry_create(struct esif_ccb_file *file_ptr) { eEsifError rc = ESIF_E_UNSPECIFIED; EsifDspPtr dspPtr = NULL; EsifFpcPtr fpcPtr = NULL; UInt32 fpcIsStatic = ESIF_FALSE; UInt8 i = 0; char path[MAX_PATH]={0}; UInt32 fpcSize = 0; UInt32 edpSize = 0; size_t numFpcBytesRead = 0; struct edp_dir edp_dir; EsifDataPtr nameSpace = 0; EsifDataPtr key = 0; EsifDataPtr value = 0; IOStreamPtr ioPtr = IOStream_Create(); if ((NULL == file_ptr) || (NULL == ioPtr)) { ESIF_TRACE_ERROR("The file pointer or IO stream is NULL\n"); goto exit; } nameSpace = EsifData_CreateAs(ESIF_DATA_STRING, ESIF_DSP_NAMESPACE, 0, ESIFAUTOLEN); key = EsifData_CreateAs(ESIF_DATA_STRING, file_ptr->filename, 0, ESIFAUTOLEN); value = EsifData_CreateAs(ESIF_DATA_AUTO, NULL, ESIF_DATA_ALLOCATE, 0); if (nameSpace == NULL || key == NULL || value == NULL) { rc = ESIF_E_NO_MEMORY; goto exit; } ESIF_TRACE_DEBUG("Filename: %s", file_ptr->filename); dspPtr = esif_dsp_create(); if (NULL == dspPtr) { ESIF_TRACE_ERROR("Fail to allocate dsp entry\n"); goto exit; } // Look for EDP file on disk first then in DataVault (static or file) esif_build_path(path, sizeof(path), ESIF_PATHTYPE_DSP, file_ptr->filename, NULL); if (!esif_ccb_file_exists(path) && EsifConfigGet(nameSpace, key, value) == ESIF_OK) { esif_ccb_strcpy(path, file_ptr->filename, MAX_PATH); IOStream_SetMemory(ioPtr, StoreReadOnly, (BytePtr)value->buf_ptr, value->data_len); } else { IOStream_SetFile(ioPtr, StoreReadOnly, path, "rb"); } ESIF_TRACE_DEBUG("Fullpath: %s", path); if (IOStream_Open(ioPtr) != 0) { ESIF_TRACE_ERROR("File not found (%s)", path); goto exit; } /* Read FPC From EDP File */ if (esif_ccb_strstr(&path[0], ".edp")) { /* EDP - Only Read The FPC Part */ edpSize = (UInt32)IOStream_GetSize(ioPtr); if (!edpSize) { goto exit; } numFpcBytesRead = IOStream_Read(ioPtr, &edp_dir, sizeof(edp_dir)); if (!esif_verify_edp(&edp_dir, numFpcBytesRead)) { ESIF_TRACE_ERROR("Invalid EDP Header: Signature=%4.4s Version=%d\n", (char *)&edp_dir.signature, edp_dir.version); goto exit; } if (edpSize > MAX_EDP_SIZE || edp_dir.fpc_offset > MAX_FPC_SIZE || edp_dir.fpc_offset > edpSize) { ESIF_TRACE_ERROR("The edp or fpc file size is larger than maximum\n"); goto exit; } fpcSize = edpSize - edp_dir.fpc_offset; IOStream_Seek(ioPtr, edp_dir.fpc_offset, SEEK_SET); ESIF_TRACE_DEBUG("File found (%s) size %u, FPC size %u from offset %u", path, edpSize, fpcSize, edp_dir.fpc_offset); } else { ESIF_TRACE_DEBUG("File %s does not have .fpc and .edp format!", path); } // use static DataVault buffer (if available), otherwise allocate space for our FPC file contents (which will not be freed) if (IOStream_GetType(ioPtr) == StreamMemory && value->buf_len == 0) { fpcPtr = (EsifFpcPtr)IOStream_GetMemoryBuffer(ioPtr); if (NULL == fpcPtr) { ESIF_TRACE_ERROR("NULL buffer"); goto exit; } fpcPtr = (EsifFpcPtr) (((BytePtr) fpcPtr) + IOStream_GetOffset(ioPtr)); numFpcBytesRead = fpcSize; ESIF_TRACE_DEBUG("Static vault size %u buf_ptr=0x%p\n", (int)numFpcBytesRead, fpcPtr); fpcIsStatic = ESIF_TRUE; } else { fpcPtr = (EsifFpcPtr)esif_ccb_malloc(fpcSize); if (NULL == fpcPtr) { ESIF_TRACE_ERROR("malloc failed to allocate %u bytes\n", fpcSize); goto exit; } ESIF_TRACE_DEBUG("File malloc size %u", fpcSize); // read file contents numFpcBytesRead = IOStream_Read(ioPtr, fpcPtr, fpcSize); if (numFpcBytesRead < fpcSize) { ESIF_TRACE_ERROR("Read short received %u of %u bytes\n", (int)numFpcBytesRead, fpcSize); goto exit; } ESIF_TRACE_DEBUG("File read size %u", (int)numFpcBytesRead); } ESIF_TRACE_DEBUG("\nDecode Length: %u", fpcPtr->size); ESIF_TRACE_DEBUG("Code: %s", fpcPtr->header.code); ESIF_TRACE_DEBUG("Ver Major: %u", fpcPtr->header.ver_major); ESIF_TRACE_DEBUG("Ver Minor: %u", fpcPtr->header.ver_minor); ESIF_TRACE_DEBUG("Name: %s", fpcPtr->header.name); ESIF_TRACE_DEBUG("Description: %s", fpcPtr->header.description); ESIF_TRACE_DEBUG("Type: %s", fpcPtr->header.type); ESIF_TRACE_DEBUG("Bus Enumerator: %u", fpcPtr->header.bus_enum); ESIF_TRACE_DEBUG("ACPI Device: %s", fpcPtr->header.acpi_device); ESIF_TRACE_DEBUG("ACPI Scope: %s", fpcPtr->header.acpi_scope); ESIF_TRACE_DEBUG("ACPI Type: %s", fpcPtr->header.acpi_type); ESIF_TRACE_DEBUG("ACPI UID: %s", fpcPtr->header.acpi_UID); ESIF_TRACE_DEBUG("PCI Vendor ID: %s", fpcPtr->header.pci_vendor_id); ESIF_TRACE_DEBUG("PCI Device ID: %s", fpcPtr->header.pci_device_id); ESIF_TRACE_DEBUG("PCI Bus: %s", fpcPtr->header.pci_bus); ESIF_TRACE_DEBUG("PCI Device: %s", fpcPtr->header.pci_device); ESIF_TRACE_DEBUG("PCI Function: %s", fpcPtr->header.pci_function); dspPtr->code_ptr = (EsifString)fpcPtr->header.name; dspPtr->bus_enum = (UInt8 *)&fpcPtr->header.bus_enum; dspPtr->type = (EsifString)fpcPtr->header.type; dspPtr->ver_major_ptr = (UInt8 *)&fpcPtr->header.ver_major; dspPtr->ver_minor_ptr = (UInt8 *)&fpcPtr->header.ver_minor; dspPtr->acpi_device = (EsifString)fpcPtr->header.acpi_device; dspPtr->acpi_scope = (EsifString)fpcPtr->header.acpi_scope; dspPtr->acpi_type = (EsifString)fpcPtr->header.acpi_type; dspPtr->acpi_uid = (EsifString)fpcPtr->header.acpi_UID; dspPtr->vendor_id = (EsifString)fpcPtr->header.pci_vendor_id; dspPtr->device_id = (EsifString)fpcPtr->header.pci_device_id; dspPtr->pci_bus = (EsifString)&fpcPtr->header.pci_bus; dspPtr->pci_bus_device = (EsifString)&fpcPtr->header.pci_device; dspPtr->pci_function = (EsifString)&fpcPtr->header.pci_function; /* Assign Function Pointers */ dspPtr->get_code = get_code; dspPtr->get_ver_minor = get_ver_minor; dspPtr->get_ver_major = get_ver_major; dspPtr->get_temp_tc1 = get_temp_c1; dspPtr->get_percent_xform = get_percent_xform; dspPtr->insert_primitive = insert_primitive; dspPtr->insert_algorithm = insert_algorithm; dspPtr->insert_domain = insert_domain; dspPtr->insert_event = insert_event; dspPtr->get_primitive = get_primitive; dspPtr->get_action = get_action; dspPtr->get_algorithm = get_algorithm; dspPtr->get_domain = get_domain; dspPtr->get_event_by_type = get_event_by_type; dspPtr->get_event_by_guid = get_event_by_guid; dspPtr->init_fpc_iterator = init_fpc_iterator; dspPtr->get_next_fpc_domain = get_next_fpc_domain; dspPtr->get_domain_count = get_domain_count; rc = esif_fpc_load(fpcPtr, dspPtr); if (ESIF_OK == rc) { ESIF_TRACE_DEBUG("FPC %s load successfully", path); } else { ESIF_TRACE_DEBUG("Unable to load FPC %s, rc %s", path, esif_rc_str(rc)); goto exit; } /* Lock DSP Manager */ esif_ccb_write_lock(&g_dm.lock); /* Simple Table Lookup For Now. Scan Table And Find First Empty Slot */ /* Empty slot indicated by AVAILABLE state */ for (i = 0; i < MAX_DSP_MANAGER_ENTRY; i++) { if (NULL == g_dm.dme[i].dsp_ptr) { break; } } /* If No Available Slots Return */ if (i >= MAX_DSP_MANAGER_ENTRY) { esif_ccb_write_unlock(&g_dm.lock); ESIF_TRACE_ERROR("No free dsp manager entry is available for %s\n", file_ptr->filename); goto exit; } /* ** Take Slot */ g_dm.dme[i].dsp_ptr = dspPtr; g_dm.dme[i].file_ptr = file_ptr; g_dm.dme[i].fpc_ptr = (fpcIsStatic ? 0 : fpcPtr); g_dm.dme_count++; dspPtr = NULL; // Prevent deallocate on exit fpcPtr = NULL; // Prevent deallocate on exit esif_ccb_write_unlock(&g_dm.lock); rc = ESIF_OK; ESIF_TRACE_INFO("Create entry in dsp manager successfully for %s\n", file_ptr->filename); exit: IOStream_Destroy(ioPtr); EsifData_Destroy(nameSpace); EsifData_Destroy(key); EsifData_Destroy(value); esif_dsp_destroy(dspPtr); if (!fpcIsStatic) { esif_ccb_free(fpcPtr); } return rc; }
/* Copy/Merge Keys from one NameSpace to Another */ eEsifError EsifConfigCopy( EsifDataPtr nameSpaceFrom, // Source DV EsifDataPtr nameSpaceTo, // Target DV EsifDataPtr keyspecs, // Tab-separated Keyspec List (wildcards OK) esif_flags_t flags, // Item Flags Bool replaceKeys, // TRUE=COPY Keys (Replace if exists), FALSE=MERGE Keys (Do Not Replace) UInt32 *keycount) // Optional pointer to variable to hold Key Count copied/merged { eEsifError rc = ESIF_OK; EsifConfigFindContext context = NULL; EsifDataPtr data_key = NULL; EsifDataPtr data_value = NULL; esif_string keylist = NULL; esif_string keyspec = NULL; esif_string keyspec_context = NULL; char **keyset = NULL; size_t keyset_count = 0; UInt32 exported = 0; esif_context_t qsort_ctx = 0; size_t key = 0; ESIF_ASSERT(nameSpaceFrom && nameSpaceTo && keyspecs && nameSpaceFrom->buf_ptr && nameSpaceTo->buf_ptr && keyspecs->buf_ptr); // Parse Key List (optionally Tab-separated) keylist = esif_ccb_strdup((esif_string)keyspecs->buf_ptr); if (keylist == NULL) { rc = ESIF_E_NO_MEMORY; goto exit; } // Create sorted keyset with exclude keyspecs ("!keyspec") listed first keyspec = esif_ccb_strtok(keylist, "\t", &keyspec_context); while (keyspec != NULL) { char **new_keyset = (char **)esif_ccb_realloc(keyset, sizeof(char *) * (keyset_count + 1)); if (new_keyset == NULL) { rc = ESIF_E_NO_MEMORY; goto exit; } keyset = new_keyset; keyset[keyset_count++] = keyspec; keyspec = esif_ccb_strtok(NULL, "\t", &keyspec_context); } esif_ccb_qsort(keyset, keyset_count, sizeof(char *), esif_ccb_qsort_stricmp, qsort_ctx); // Enumerate Each Matching keyspec for (key = 0; (rc == ESIF_OK && key < keyset_count); key++) { // Skip excludes for now so we can compare to each maching keyspec later if (keyset[key][0] == '!') { continue; } EsifData_Destroy(data_key); data_key = EsifData_CreateAs(ESIF_DATA_STRING, keyset[key], 0, ESIFAUTOLEN); if (data_key == NULL) { rc = ESIF_E_NO_MEMORY; goto exit; } if ((rc = EsifConfigFindFirst(nameSpaceFrom, data_key, NULL, &context)) == ESIF_OK) { do { // Skip if matching key matches any exclude keyspecs Bool skip_key = ESIF_FALSE; size_t ex = 0; for (ex = 0; (ex < key && keyset[ex][0] == '!'); ex++) { if (esif_ccb_strmatch((esif_string)data_key->buf_ptr, &keyset[ex][1])) { skip_key = ESIF_TRUE; break; } } // copy = always replace existing key in target if it already exists // merge = never replace existing key in target if it already exists if ((skip_key == ESIF_FALSE) && (replaceKeys == ESIF_TRUE || DataBank_KeyExists(g_DataBankMgr, (esif_string)nameSpaceTo->buf_ptr, (esif_string)data_key->buf_ptr) == ESIF_FALSE)) { EsifData_Destroy(data_value); data_value = EsifData_CreateAs(ESIF_DATA_AUTO, NULL, ESIF_DATA_ALLOCATE, 0); if (data_value == NULL) { rc = ESIF_E_NO_MEMORY; break; } rc = EsifConfigGet(nameSpaceFrom, data_key, data_value); if (rc != ESIF_OK) { break; } rc = EsifConfigSet(nameSpaceTo, data_key, flags, data_value); if (rc != ESIF_OK) { break; } ESIF_TRACE_DEBUG("DV %s: @%s => @%s [%s] {%s, %u bytes}\n", (replaceKeys ? "Copy" : "Merge"), (esif_string)nameSpaceFrom->buf_ptr, (esif_string)nameSpaceTo->buf_ptr, (esif_string)data_key->buf_ptr, esif_data_type_str(data_value->type), data_value->data_len); exported++; } // Reset Key for next search EsifData_Set(data_key, ESIF_DATA_STRING, keyset[key], 0, ESIFAUTOLEN); } while ((rc = EsifConfigFindNext(nameSpaceFrom, data_key, NULL, &context)) == ESIF_OK); EsifConfigFindClose(&context); } if (rc == ESIF_E_ITERATION_DONE || rc == ESIF_E_NOT_FOUND) { rc = ESIF_OK; } } exit: if (rc == ESIF_OK && keycount != NULL) { *keycount = exported; } EsifData_Destroy(data_key); EsifData_Destroy(data_value); esif_ccb_free(keylist); esif_ccb_free(keyset); return rc; }
// 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; }