Exemplo n.º 1
0
/* IOCTL */
static ssize_t esif_file_ipc(
	struct file *fp,
	char __user *buf,
	size_t count,
	loff_t *ppos
	)
{
	u32 len = 0;
	struct esif_ipc *ipc_req_ptr = esif_ipc_user_to_kernel(
			(struct esif_ipc *)buf);
	struct esif_ipc *ipc_rsp_ptr = NULL;

	if (count < sizeof(struct esif_ipc))
		return -EINVAL;

	if (NULL == ipc_req_ptr)
		return -ENOMEM;

	ESIF_TRACE_DYN_IPC("linux_%s: user %p kernel %p count %d\n",
			   __func__, buf, ipc_req_ptr, (int)count);

	ipc_rsp_ptr = esif_ipc_process(ipc_req_ptr);

	if (NULL != ipc_rsp_ptr) {
		len = esif_ipc_kernel_to_user((struct esif_ipc *)buf,
						ipc_rsp_ptr);
		ESIF_TRACE_DYN_IPC("linux_%s: user %p kernel %p count = %d\n",
				   __func__, buf, ipc_rsp_ptr, (int)count);

		if (ipc_req_ptr != ipc_rsp_ptr)
			esif_ipc_free(ipc_rsp_ptr);
	}
	esif_ccb_free(ipc_req_ptr);
	return len;
}
Exemplo n.º 2
0
/* IOCTL */
static int esif_ipc_ioctl(struct esif_ipc *ipc_user_ptr)
{
	int rc = 0;
	struct esif_ipc *ipc_req_ptr = esif_ipc_user_to_kernel(ipc_user_ptr);
	struct esif_ipc *ipc_rsp_ptr = NULL;

	if (NULL == ipc_req_ptr)
		return -ENOMEM;

	ESIF_TRACE_DYN_IPC("linux_%s: user %p kernel %p\n",
			   __func__,
			   ipc_user_ptr,
			   ipc_req_ptr);
	ipc_rsp_ptr = esif_ipc_process(ipc_req_ptr);

	if (NULL != ipc_rsp_ptr) {
		esif_ipc_kernel_to_user((struct esif_ipc *)ipc_user_ptr,
					ipc_rsp_ptr);
		ESIF_TRACE_DYN_IPC("linux_%s: user %p kernel %p\n",
				   __func__,
				   ipc_user_ptr,
				   ipc_rsp_ptr);
		if (ipc_req_ptr != ipc_rsp_ptr)
			esif_ipc_free(ipc_rsp_ptr);
	} else {
		rc = -EINVAL;
	}
	esif_ccb_free(ipc_req_ptr);
	return rc;
}
Exemplo n.º 3
0
// Dispatch An Event
void EsifEvent_GetAndSignalIpcEvent()
{
#ifdef ESIF_FEAT_OPT_ACTION_SYSFS
	// NOOP
#else
	int r_bytes     = 0;
	int data_len    = 1024;	/* TODO: Change from "magic number" */
	enum esif_rc rc = ESIF_OK;
	struct esif_ipc *ipc_ptr = NULL;
	struct esif_ipc_event *event_ptr = NULL;

	ipc_ptr = esif_ipc_alloc_event(&event_ptr, data_len);
	if (NULL == ipc_ptr) {
		ESIF_TRACE_ERROR("Fail to allocate esif_ipc\n");
		return;
	}

//
// TODO:  This needs to be in an OS abstraction layer
//
#ifdef ESIF_ATTR_OS_LINUX
	r_bytes = read(g_ipc_handle, ipc_ptr, data_len);
#endif
#ifdef ESIF_ATTR_OS_WINDOWS

	rc = ipc_execute(ipc_ptr);
	//
	// TODO:  The return size check is a W/A until a better solution is developed to determine if an event was returned.
	// (The current LF code does not change the original data_len or fail the request if there are not events.)
	//
	r_bytes = 0;
	if ((ESIF_OK == rc) && (ipc_ptr->data_len != (u32)data_len)) {
		r_bytes = ipc_ptr->data_len;
	}
#endif

	// Have Event?
	if (r_bytes > 0) {
		ESIF_TRACE_DEBUG("IPC version=%d, type=%d, len = %d, data_len=%d\n",
			ipc_ptr->version,
			ipc_ptr->type,
			r_bytes,
			ipc_ptr->data_len);

		EsifEvent_SignalIpcEvent(event_ptr);
	}
	esif_ipc_free(ipc_ptr);
#endif
}
Exemplo n.º 4
0
// 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;
}
Exemplo n.º 5
0
/* Will sync any existing lower framework participatnts */
enum esif_rc sync_lf_participants()
{
	eEsifError rc = ESIF_OK;
	struct esif_command_get_participants *data_ptr = NULL;
	const UInt32 data_len = sizeof(struct esif_command_get_participants);
	struct esif_ipc_command *command_ptr = NULL;
	UInt8 i = 0;
	UInt32 count = 0;
	struct esif_ipc *ipc_ptr = NULL;
	
	ESIF_TRACE_ENTRY_INFO();
	
	ipc_ptr = esif_ipc_alloc_command(&command_ptr, data_len);
	if (NULL == ipc_ptr || NULL == command_ptr) {
		ESIF_TRACE_ERROR("Fail to allocate esif_ipc/esif_ipc_command\n");
		rc = ESIF_E_NO_MEMORY;
		goto exit;
	}

	command_ptr->type = ESIF_COMMAND_TYPE_GET_PARTICIPANTS;
	command_ptr->req_data_type   = ESIF_DATA_VOID;
	command_ptr->req_data_offset = 0;
	command_ptr->req_data_len    = 0;
	command_ptr->rsp_data_type   = ESIF_DATA_STRUCTURE;
	command_ptr->rsp_data_offset = 0;
	command_ptr->rsp_data_len    = data_len;

	rc = ipc_execute(ipc_ptr);
	if (ESIF_OK != rc) {
		goto exit;
	}

	if (ESIF_OK != ipc_ptr->return_code) {
		rc = ipc_ptr->return_code;
		ESIF_TRACE_WARN("ipc_ptr return_code failure - %s\n", esif_rc_str(rc));
		goto exit;
	}

	if (ESIF_OK != command_ptr->return_code) {
		rc = command_ptr->return_code;
		ESIF_TRACE_WARN("command_ptr return_code failure - %s\n", esif_rc_str(rc));
		goto exit;
	}

	/* Participant Data */
	data_ptr = (struct esif_command_get_participants *)(command_ptr + 1);
	count    = data_ptr->count;

	for (i = 0; i < count; i++) {
		struct esif_ipc_event_data_create_participant participantData;
		EsifData esifParticipantData = {ESIF_DATA_BINARY, &participantData, sizeof(participantData), sizeof(participantData)};

		rc = get_participant_data(&participantData, i);
		if (ESIF_OK != rc) {
			rc = ESIF_OK; /* Ignore RC for get_participant_data */
			continue;
		}
		EsifEventMgr_SignalEvent(0, EVENT_MGR_DOMAIN_D0, ESIF_EVENT_PARTICIPANT_CREATE, &esifParticipantData);
	}
exit:
	ESIF_TRACE_INFO("rc = %s(%u)", esif_rc_str(rc), rc);

	if (NULL != ipc_ptr) {
		esif_ipc_free(ipc_ptr);
	}

	ESIF_TRACE_EXIT_INFO_W_STATUS(rc);
	return rc;
}
Exemplo n.º 6
0
/* Work Around */
static enum esif_rc get_participant_data(
	struct esif_ipc_event_data_create_participant *pi_ptr,
	UInt8 participantId
	)
{
	eEsifError rc = ESIF_OK;

	struct esif_command_get_part_detail *data_ptr = NULL;
	struct esif_ipc_command *command_ptr = NULL;
	struct esif_ipc *ipc_ptr = NULL;
	const u32 data_len = sizeof(struct esif_command_get_part_detail);

	ipc_ptr = esif_ipc_alloc_command(&command_ptr, data_len);
	if (NULL == ipc_ptr || NULL == command_ptr) {
		ESIF_TRACE_ERROR("Fail to allocate esif_ipc/esif_ipc_command\n");
		rc = ESIF_E_NO_MEMORY;
		goto exit;
	}

	command_ptr->type = ESIF_COMMAND_TYPE_GET_PARTICIPANT_DETAIL;
	command_ptr->req_data_type   = ESIF_DATA_UINT32;
	command_ptr->req_data_offset = 0;
	command_ptr->req_data_len    = 4;
	command_ptr->rsp_data_type   = ESIF_DATA_STRUCTURE;
	command_ptr->rsp_data_offset = 0;
	command_ptr->rsp_data_len    = data_len;

	// ID For Command
	*(u32 *)(command_ptr + 1) = participantId;
	rc = ipc_execute(ipc_ptr);

	if (ESIF_OK != rc) {
		goto exit;
	}

	if (ESIF_OK != ipc_ptr->return_code) {
		rc = ipc_ptr->return_code;
		ESIF_TRACE_WARN("ipc_ptr return_code failure - %s\n", esif_rc_str(rc));
		goto exit;
	}

	if (ESIF_OK != command_ptr->return_code) {
		rc = command_ptr->return_code;
		ESIF_TRACE_WARN("command_ptr return_code failure - %s\n", esif_rc_str(rc));
		goto exit;
	}

	// our data
	data_ptr = (struct esif_command_get_part_detail *)(command_ptr + 1);
	if (0 == data_ptr->version) {
		ESIF_TRACE_ERROR("Participant version is 0\n");
		goto exit;
	}

	pi_ptr->id = (u8)data_ptr->id;
	pi_ptr->version = data_ptr->version;
	esif_ccb_memcpy(pi_ptr->class_guid, data_ptr->class_guid, ESIF_GUID_LEN);

	pi_ptr->enumerator = data_ptr->enumerator;
	pi_ptr->flags = data_ptr->flags;

	esif_ccb_strcpy(pi_ptr->name, data_ptr->name, ESIF_NAME_LEN);
	esif_ccb_strcpy(pi_ptr->desc, data_ptr->desc, ESIF_DESC_LEN);
	esif_ccb_strcpy(pi_ptr->driver_name, data_ptr->driver_name, ESIF_NAME_LEN);
	esif_ccb_strcpy(pi_ptr->device_name, data_ptr->device_name, ESIF_NAME_LEN);
	esif_ccb_strcpy(pi_ptr->device_path, data_ptr->device_path, ESIF_NAME_LEN);

	/* ACPI */
	esif_ccb_strcpy(pi_ptr->acpi_device, data_ptr->acpi_device, ESIF_NAME_LEN);
	esif_ccb_strcpy(pi_ptr->acpi_scope, data_ptr->acpi_scope, ESIF_SCOPE_LEN);
	esif_ccb_strcpy(pi_ptr->acpi_uid, data_ptr->acpi_uid, sizeof(pi_ptr->acpi_uid));
	pi_ptr->acpi_type = data_ptr->acpi_type;

	/* PCI */
	pi_ptr->pci_vendor     = data_ptr->pci_vendor;
	pi_ptr->pci_device     = data_ptr->pci_device;
	pi_ptr->pci_bus        = data_ptr->pci_bus;
	pi_ptr->pci_bus_device = data_ptr->pci_bus_device;
	pi_ptr->pci_function   = data_ptr->pci_function;
	pi_ptr->pci_revision   = data_ptr->pci_revision;
	pi_ptr->pci_class      = data_ptr->pci_class;
	pi_ptr->pci_sub_class  = data_ptr->pci_sub_class;
	pi_ptr->pci_prog_if    = data_ptr->pci_prog_if;

exit:

	if (NULL != ipc_ptr) {
		esif_ipc_free(ipc_ptr);
	}
	return rc;
}