samples/mei/mei-amt-version.c

Source file repositories/reference/linux-study-clean/samples/mei/mei-amt-version.c

File Facts

System
Linux kernel
Corpus path
samples/mei/mei-amt-version.c
Extension
.c
Size
13421 bytes
Lines
489
Domain
Support Tooling And Documentation
Bucket
samples
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct mei {
	uuid_le guid;
	bool initialized;
	bool verbose;
	unsigned int buf_size;
	unsigned char prot_ver;
	int fd;
};

static void mei_deinit(struct mei *cl)
{
	if (cl->fd != -1)
		close(cl->fd);
	cl->fd = -1;
	cl->buf_size = 0;
	cl->prot_ver = 0;
	cl->initialized = false;
}

static bool mei_init(struct mei *me, const uuid_le *guid,
		unsigned char req_protocol_version, bool verbose)
{
	int result;
	struct mei_client *cl;
	struct mei_connect_client_data data;

	me->verbose = verbose;

	me->fd = open("/dev/mei0", O_RDWR);
	if (me->fd == -1) {
		mei_err(me, "Cannot establish a handle to the Intel MEI driver\n");
		goto err;
	}
	memcpy(&me->guid, guid, sizeof(*guid));
	memset(&data, 0, sizeof(data));
	me->initialized = true;

	memcpy(&data.in_client_uuid, &me->guid, sizeof(me->guid));
	result = ioctl(me->fd, IOCTL_MEI_CONNECT_CLIENT, &data);
	if (result) {
		mei_err(me, "IOCTL_MEI_CONNECT_CLIENT receive message. err=%d\n", result);
		goto err;
	}
	cl = &data.out_client_properties;
	mei_msg(me, "max_message_length %d\n", cl->max_msg_length);
	mei_msg(me, "protocol_version %d\n", cl->protocol_version);

	if ((req_protocol_version > 0) &&
	     (cl->protocol_version != req_protocol_version)) {
		mei_err(me, "Intel MEI protocol version not supported\n");
		goto err;
	}

	me->buf_size = cl->max_msg_length;
	me->prot_ver = cl->protocol_version;

	return true;
err:
	mei_deinit(me);
	return false;
}

static ssize_t mei_recv_msg(struct mei *me, unsigned char *buffer,
			ssize_t len, unsigned long timeout)
{
	struct timeval tv;
	fd_set set;
	ssize_t rc;

	tv.tv_sec = timeout / 1000;
	tv.tv_usec = (timeout % 1000) * 1000000;

	mei_msg(me, "call read length = %zd\n", len);

	FD_ZERO(&set);
	FD_SET(me->fd, &set);
	rc = select(me->fd + 1, &set, NULL, NULL, &tv);
	if (rc > 0 && FD_ISSET(me->fd, &set)) {
		mei_msg(me, "have reply\n");
	} else if (rc == 0) {
		rc = -1;
		mei_err(me, "read failed on timeout\n");
		goto out;
	} else { /* rc < 0 */
		rc = errno;
		mei_err(me, "read failed on select with status %zd %s\n",
			rc, strerror(errno));
		goto out;
	}

Annotation

Implementation Notes