diff --git a/CHANGELOG.md b/CHANGELOG.md index 64e274d..d549f4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## [1.6.4] + +### Added + - add device kind api + ## [1.6.3] ### Fixed diff --git a/VERSION b/VERSION index 266146b..9edc58b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.6.3 +1.6.4 diff --git a/libmei.h b/libmei.h index 1d2b99c..de9f3a7 100644 --- a/libmei.h +++ b/libmei.h @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: BSD-3-Clause * - * Copyright(c) 2013 - 2024 Intel Corporation. All rights reserved. + * Copyright(c) 2013 - 2025 Intel Corporation. All rights reserved. * * Intel Management Engine Interface (Intel MEI) Library */ @@ -256,6 +256,16 @@ int mei_fwstatus(struct mei *me, uint32_t fwsts_num, uint32_t *fwsts); */ int mei_gettrc(struct mei *me, uint32_t *trc_val); +/*! Obtains device kind + * + * \param me The mei handle + * \param kind buffer to fill with device kind null terminated string, may be NULL. + * \param kind_size Pointer to kind buffer size in bytes, updated to number of bytes filled in buffer, including null character, on out. + * If buffer is NULL, required size is returned anyway. + * \return 0 if successful, otherwise error code + */ +int mei_getkind(struct mei *me, char *kind, size_t *kind_size); + /*! Set log level * * \param me The mei handle diff --git a/mei.c b/mei.c index 2b81db4..70192af 100644 --- a/mei.c +++ b/mei.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: BSD-3-Clause * - * Copyright(c) 2013 - 2024 Intel Corporation. All rights reserved. + * Copyright(c) 2013 - 2025 Intel Corporation. All rights reserved. * * Intel Management Engine Interface (Intel MEI) Library */ @@ -337,6 +337,50 @@ static inline int __mei_gettrc(struct mei *me, const char *device, uint32_t *trc #undef CONV_BASE } +static inline int __mei_getkind(struct mei *me, const char *device, char *kind, size_t *kind_size) +{ +#define KIND_FILENAME_LEN 34 +#define KIND_LEN 16 + char path[KIND_FILENAME_LEN]; + char buf[KIND_LEN] = { 0 }; + int fd; + ssize_t len; + + if (snprintf(path, KIND_FILENAME_LEN, + "/sys/class/mei/%s/kind", device) < 0) + return -EINVAL; + path[KIND_FILENAME_LEN - 1] = '\0'; + + errno = 0; + fd = open(path, O_CLOEXEC, O_RDONLY); + if (fd == -1) { + me->last_err = errno; + return -me->last_err; + } + + errno = 0; + len = pread(fd, buf, KIND_LEN, 0); + if (len == -1) { + me->last_err = errno; + close(fd); + return -me->last_err; + } + + close(fd); + if ((size_t)len > *kind_size || !kind) { + me->last_err = ENOSPC; + mei_err(me, "Insufficient buffer %zu %zd\n", *kind_size, len); + *kind_size = (size_t)len; + return -me->last_err; + } + *kind_size = (size_t)len; + memcpy(kind, buf, (size_t)len); + + return 0; +#undef KIND_FILENAME_LEN +#undef KIND_LEN +} + int mei_init_with_log(struct mei *me, const char *device, const uuid_le *guid, unsigned char req_protocol_version, bool verbose, mei_log_callback log_callback) @@ -736,6 +780,35 @@ int mei_gettrc(struct mei *me, uint32_t *trc_val) return 0; } +int mei_getkind(struct mei *me, char *kind, size_t *kind_size) +{ + char *device; + int rc; + + if (!me || !kind_size) + return -EINVAL; + + if (me->device) { + device = strstr(me->device, MEI_DEFAULT_DEVICE_PREFIX); + if (!device) { + mei_err(me, "Device does not start with '%s'\n", + MEI_DEFAULT_DEVICE_PREFIX); + return -EINVAL; + } + device += strlen(MEI_DEFAULT_DEVICE_PREFIX); + } else { + device = MEI_DEFAULT_DEVICE_NAME; + } + rc = __mei_getkind(me, device, kind, kind_size); + if (rc < 0) { + mei_err(me, "Cannot get kind value [%d]:%s\n", + rc, strerror(-rc)); + return rc; + } + + return 0; +} + unsigned int mei_get_api_version(void) { return LIBMEI_API_VERSION;