From 456380bb272d3a301c887eee513a3937cc1f48e1 Mon Sep 17 00:00:00 2001 From: "Jason M. Bills" Date: Tue, 22 Oct 2019 14:01:54 -0700 Subject: Update to internal 10-22-19 Signed-off-by: Jason M. Bills --- .../0001-Add-smbus-support-to-Cmake-Lists.patch | 36 --- .../libmctp/0001-Smbus-changes-for-libmctp.patch | 148 +++++++++++ .../recipes-core/interfaces/libmctp/crc32c.h | 7 + .../interfaces/libmctp/libmctp-smbus.h | 9 + .../recipes-core/interfaces/libmctp/smbus.c | 280 ++++++++++++++------- 5 files changed, 354 insertions(+), 126 deletions(-) delete mode 100644 meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp/0001-Add-smbus-support-to-Cmake-Lists.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp/0001-Smbus-changes-for-libmctp.patch (limited to 'meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp') diff --git a/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp/0001-Add-smbus-support-to-Cmake-Lists.patch b/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp/0001-Add-smbus-support-to-Cmake-Lists.patch deleted file mode 100644 index 8bb9ce485..000000000 --- a/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp/0001-Add-smbus-support-to-Cmake-Lists.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 21f2f29129a7eba8aecdf07875004bafc6a74269 Mon Sep 17 00:00:00 2001 -From: James Feist -Date: Thu, 20 Jun 2019 08:58:44 -0700 -Subject: [PATCH] Add smbus support to Cmake Lists - -This adds smbus changes needed for libmctp. - -Change-Id: I06fc950337e6f3d5b1cef0fb445be2d448d49e44 -Signed-off-by: James Feist ---- - CMakeLists.txt | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index a5b1042..04c4bdf 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -3,7 +3,7 @@ cmake_minimum_required (VERSION 3.5 FATAL_ERROR) - add_definitions (-DMCTP_LOG_STDERR) - add_definitions (-DMCTP_FILEIO) - --add_library (libmctp STATIC alloc.c core.c log.c libmctp.h serial.c) -+add_library (libmctp STATIC alloc.c core.c log.c libmctp.h serial.c smbus.c) - - target_include_directories (libmctp PUBLIC - $ -@@ -18,5 +18,5 @@ add_executable (test_seq tests/test_seq.c tests/test-utils.c) - target_link_libraries (test_seq libmctp) - - install (TARGETS libmctp DESTINATION lib) --install (FILES libmctp.h DESTINATION include) -+install (FILES libmctp.h libmctp-smbus.h libmctp-serial.h DESTINATION include) - --- -2.17.1 - diff --git a/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp/0001-Smbus-changes-for-libmctp.patch b/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp/0001-Smbus-changes-for-libmctp.patch new file mode 100644 index 000000000..e456c10ad --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp/0001-Smbus-changes-for-libmctp.patch @@ -0,0 +1,148 @@ +From cb330f4bf1f519032ee50d60f473c28df7b772d8 Mon Sep 17 00:00:00 2001 +From: Nikhil Potade +Date: Tue, 19 Feb 2019 14:16:20 +0800 +Subject: [PATCH] Smbus changes for libmctp + +--- + CMakeLists.txt | 6 ++++-- + core.c | 2 ++ + libmctp.h | 40 ++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 46 insertions(+), 2 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index a5b1042..249b12b 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -2,8 +2,9 @@ cmake_minimum_required (VERSION 3.5 FATAL_ERROR) + + add_definitions (-DMCTP_LOG_STDERR) + add_definitions (-DMCTP_FILEIO) ++add_definitions (-DMCTP_DEFAULT_ALLOC) + +-add_library (libmctp STATIC alloc.c core.c log.c libmctp.h serial.c) ++add_library (libmctp STATIC alloc.c core.c log.c libmctp.h serial.c smbus.c crc32c.c) + + target_include_directories (libmctp PUBLIC + $ +@@ -18,5 +19,6 @@ add_executable (test_seq tests/test_seq.c tests/test-utils.c) + target_link_libraries (test_seq libmctp) + + install (TARGETS libmctp DESTINATION lib) +-install (FILES libmctp.h DESTINATION include) ++install (FILES libmctp.h libmctp-smbus.h libmctp-serial.h crc32c.h DESTINATION ++ include) + +diff --git a/core.c b/core.c +index b855ced..8be7407 100644 +--- a/core.c ++++ b/core.c +@@ -17,6 +17,7 @@ + + /* Internal data structures */ + ++/* clang-format off */ + struct mctp_bus { + mctp_eid_t eid; + struct mctp_binding *binding; +@@ -50,6 +51,7 @@ struct mctp { + */ + struct mctp_msg_ctx msg_ctxs[16]; + }; ++/* clang-format on */ + + #ifndef BUILD_ASSERT + #define BUILD_ASSERT(x) \ +diff --git a/libmctp.h b/libmctp.h +index f0633e3..cec7c00 100644 +--- a/libmctp.h ++++ b/libmctp.h +@@ -15,6 +15,7 @@ extern "C" { + typedef uint8_t mctp_eid_t; + + /* MCTP packet definitions */ ++/* clang-format off */ + struct mctp_hdr { + uint8_t ver; + uint8_t dest; +@@ -30,12 +31,47 @@ struct mctp_hdr { + #define MCTP_HDR_SEQ_MASK (0x3) + #define MCTP_HDR_TAG_SHIFT (0) + #define MCTP_HDR_TAG_MASK (0x7) ++/* clang-format on */ + + /* Maximum size of *payload* data in a MCTP packet + * @todo: dynamic sixing based on channel implementation. + */ + #define MCTP_MTU 64 + ++#define MCTP_CONTROL_MESSAGE_TYPE 0x00 ++ ++enum MCTP_COMMAND_CODE { ++ MCTP_COMMAND_CODE_SET_EID = 0x01, ++ MCTP_COMMAND_CODE_GET_EID = 0x02, ++ MCTP_COMMAND_CODE_GET_ENDPOINT_UUID = 0x03, ++ MCTP_COMMAND_CODE_GET_MCTP_VERSION_SUPPORT = 0x04, ++ MCTP_COMMAND_CODE_GET_MESSAGE_TYPE_SUPPORT = 0x05, ++ MCTP_COMMAND_CODE_GET_VENDOR_DEFINED_MSG_SUPPORT= 0x06, ++ MCTP_COMMAND_CODE_RESOLVE_ENDPOINT_ID = 0x07, ++ MCTP_COMMAND_CODE_ALLOCATE_ENDPOINT_IDS = 0x08, ++ MCTP_COMMAND_CODE_ROUTING_INFORMATION_UPDATE = 0x09, ++ MCTP_COMMAND_CODE_GET_ROUTING_TABLE_ENTRIES = 0x0A, ++ MCTP_COMMAND_CODE_PREPARE_FOR_ENDPOINT_DISCOVERY= 0x0B, ++ MCTP_COMMAND_CODE_ENDPOINT_DISCOVERY = 0x0C, ++ MCTP_COMMAND_CODE_DISCOVERY_NOTIFY = 0x0D, ++ MCTP_COMMAND_CODE_GET_NETWORK_ID = 0x0E, ++ MCTP_COMMAND_CODE_QUERY_HOP = 0x0F, ++ MCTP_COMMAND_CODE_RESOLVE_UUID = 0x10, ++ MCTP_COMMAND_CODE_QUERY_RATE_LIMIT = 0x11, ++ MCTP_COMMAND_CODE_REQUEST_TX_RATE_LIMIT = 0x12, ++ MCTP_COMMAND_CODE_UPDATE_RATE_LIMIT = 0x13, ++ MCTP_COMMAND_CODE_QUERY_SUPPORTED_INTERFACES = 0x14 ++}; ++ ++enum MCTP_CONTROL_MSG_COMPLETION_CODE { ++ MCTP_CONTROL_MSG_STATUS_SUCCESS = 0x00, ++ MCTP_CONTROL_MSG_STATUS_ERROR = 0x01, ++ MCTP_CONTROL_MSG_STATUS_ERROR_INVALID_DATA = 0x02, ++ MCTP_CONTROL_MSG_STATUS_ERROR_INVALID_LENGTH = 0x03, ++ MCTP_CONTROL_MSG_STATUS_ERROR_NOT_READY = 0x04, ++ MCTP_CONTROL_MSG_STATUS_ERROR_UNSUPPORTED_CMD = 0x05 ++}; ++ + /* packet buffers */ + + /* Allow a little space before the MCTP header in the packet, for bindings that +@@ -46,12 +82,14 @@ struct mctp_hdr { + #define MCTP_PKTBUF_SIZE (MCTP_PKTBUF_BINDING_PAD + \ + (sizeof(struct mctp_hdr) + MCTP_MTU)) + ++/* clang-format off */ + struct mctp_pktbuf { + unsigned char data[MCTP_PKTBUF_SIZE]; + uint8_t start, end; + uint8_t mctp_hdr_off; + struct mctp_pktbuf *next; + }; ++/* clang-format on */ + + struct mctp_pktbuf *mctp_pktbuf_alloc(uint8_t len); + void mctp_pktbuf_free(struct mctp_pktbuf *pkt); +@@ -85,6 +123,7 @@ int mctp_message_tx(struct mctp *mctp, mctp_eid_t eid, + void *msg, size_t msg_len); + + /* hardware bindings */ ++/* clang-format off */ + struct mctp_binding { + const char *name; + uint8_t version; +@@ -93,6 +132,7 @@ struct mctp_binding { + int (*tx)(struct mctp_binding *binding, + struct mctp_pktbuf *pkt); + }; ++/* clang-format on */ + + void mctp_binding_set_tx_enabled(struct mctp_binding *binding, bool enable); + +-- +2.17.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp/crc32c.h b/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp/crc32c.h index d6b1d11e2..4586547e6 100644 --- a/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp/crc32c.h +++ b/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp/crc32c.h @@ -1,9 +1,16 @@ #ifndef CRC32C_H #define CRC32C_H +#ifdef __cplusplus +extern "C" { +#endif + #include #include uint32_t crc32c(uint8_t *buf, int len); +#ifdef __cplusplus +} +#endif #endif /* CRC32C_H */ diff --git a/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp/libmctp-smbus.h b/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp/libmctp-smbus.h index b3beadb0c..5ecaa6b74 100644 --- a/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp/libmctp-smbus.h +++ b/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp/libmctp-smbus.h @@ -3,6 +3,10 @@ #ifndef _LIBMCTP_SMBUS_H #define _LIBMCTP_SMBUS_H +#ifdef __cplusplus +extern "C" { +#endif + #include "libmctp.h" struct mctp_binding_smbus; @@ -15,4 +19,9 @@ void mctp_smbus_register_bus(struct mctp_binding_smbus *smbus, int mctp_smbus_read(struct mctp_binding_smbus *smbus); int mctp_smbus_open_bus(struct mctp_binding_smbus *smbus, int out_bus_num, int root_bus_num); +void mctp_smbus_free(struct mctp_binding_smbus *smbus); + +#ifdef __cplusplus +} +#endif #endif /* _LIBMCTP_SMBUS_H */ diff --git a/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp/smbus.c b/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp/smbus.c index 8679a5185..d7c396444 100644 --- a/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp/smbus.c +++ b/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp/smbus.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -24,7 +25,6 @@ struct mctp_binding_smbus { struct mctp_binding binding; - struct mctp *mctp; int out_fd; int in_fd; @@ -50,6 +50,8 @@ struct mctp_binding_smbus { #define MCTP_SOURCE_SLAVE_ADDRESS 0x21 #define SMBUS_PEC_BYTE_SIZE 1 +#define SMBUS_COMMAND_CODE_SIZE 1 +#define SMBUS_LENGTH_FIELD_SIZE 1 struct mctp_smbus_header_tx { uint8_t source_slave_address; @@ -62,54 +64,133 @@ struct mctp_smbus_header_rx { uint8_t source_slave_address; }; +#define POLYCHECK (0x1070U << 3) +static uint8_t crc8_calculate(uint16_t d) +{ + int i; + + for (i = 0; i < 8; i++) { + if (d & 0x8000) { + d = d ^ POLYCHECK; + } + d = d << 1; + } + + return (uint8_t)(d >> 8); +} + +/* Incremental CRC8 over count bytes in the array pointed to by p */ +static uint8_t pec_calculate(uint8_t crc, uint8_t *p, size_t count) +{ + int i; + + for (i = 0; i < count; i++) { + crc = crc8_calculate((crc ^ p[i]) << 8); + } + + return crc; +} + +static uint8_t calculate_pec_byte(uint8_t *buf, size_t len, uint8_t address, + uint16_t flags) +{ + uint8_t addr = (address << 1) | (flags & I2C_M_RD ? 1 : 0); + uint8_t pec = pec_calculate(0, &addr, 1); + pec = pec_calculate(pec, buf, len); + + return pec; +} + +static int mctp_smbus_tx(struct mctp_binding_smbus *smbus, uint8_t len) +{ + +#ifdef I2C_M_HOLD + /* Hold message */ + static uint16_t holdtimeout = 1000; // timeout in ms. + struct i2c_msg msg[2] = +#else // !I2C_M_HOLD + struct i2c_msg msg[1] = +#endif // I2C_M_HOLD + {{.addr = MCTP_SLAVE_ADDRESS, + .flags = 0, + .len = len, + .buf = (__uint8_t *)smbus->txbuf} +#ifdef I2C_M_HOLD + , + {.addr = 0, + .flags = I2C_M_HOLD, + .len = sizeof(holdtimeout), + .buf = (__uint8_t *)&holdtimeout} +#endif // I2C_M_HOLD + }; + +#ifdef I2C_M_HOLD + struct i2c_rdwr_ioctl_data msgrdwr = {&msg, 2}; +#else // !I2C_M_HOLD + struct i2c_rdwr_ioctl_data msgrdwr = {&msg, 1}; +#endif // I2C_M_HOLD + + return ioctl(smbus->out_fd, I2C_RDWR, &msgrdwr); +} + +#ifdef I2C_M_HOLD +static int mctp_smbus_unhold_bus(struct mctp_binding_smbus *smbus) +{ + /* Unhold message */ + static uint16_t holdtimeout = 0; // unhold + struct i2c_msg holdmsg = {0, I2C_M_HOLD, sizeof(holdtimeout), + (__uint8_t *)&holdtimeout}; + + struct i2c_rdwr_ioctl_data msgrdwr = {&holdmsg, 1}; + + return ioctl(smbus->out_fd, I2C_RDWR, &msgrdwr); +} +#endif // I2C_M_HOLD + static int mctp_binding_smbus_tx(struct mctp_binding *b, struct mctp_pktbuf *pkt) { struct mctp_binding_smbus *smbus = binding_to_smbus(b); struct mctp_smbus_header_tx *hdr; - uint8_t *buf; - size_t len; - int r; - struct i2c_msg msg; - struct i2c_rdwr_ioctl_data data; + size_t pkt_length; - data.msgs = &msg; - data.nmsgs = 1; + uint8_t i2c_message_buf[256]; + uint8_t *buf_ptr; + uint8_t i2c_message_len; uint16_t timeout = 1000; - int i; /* the length field in the header excludes smbus framing * and escape sequences */ - len = mctp_pktbuf_size(pkt); + pkt_length = mctp_pktbuf_size(pkt); - hdr = (void *)smbus->txbuf; + buf_ptr = (void *)smbus->txbuf; + *buf_ptr = MCTP_COMMAND_CODE; + buf_ptr++; + *buf_ptr = pkt_length + sizeof(*hdr); + buf_ptr++; - // hdr->len = len + 1; // +1 for PET byte + hdr = (void *)buf_ptr; hdr->source_slave_address = MCTP_SOURCE_SLAVE_ADDRESS; + buf_ptr = (buf_ptr + sizeof(*hdr)); + memcpy(buf_ptr, &pkt->data[pkt->start], pkt_length); + buf_ptr = buf_ptr + pkt_length; - buf = (void *)(hdr + sizeof(*hdr)); + uint8_t pec_byte = calculate_pec_byte( + smbus->txbuf, + SMBUS_COMMAND_CODE_SIZE + SMBUS_LENGTH_FIELD_SIZE + sizeof(*hdr) + + pkt_length, + MCTP_SLAVE_ADDRESS, 0); - if (len + sizeof(*hdr) > sizeof(smbus->txbuf)) - return -1; - - memcpy(buf, &pkt->data[pkt->start], len); + *buf_ptr = pec_byte; - buf += len; + i2c_message_len = SMBUS_COMMAND_CODE_SIZE + SMBUS_LENGTH_FIELD_SIZE + + sizeof(*hdr) + pkt_length + + SMBUS_PEC_BYTE_SIZE; // command code, length, + // header, data, pec byte - if (ioctl(smbus->out_fd, I2C_SLAVE, MCTP_SLAVE_ADDRESS) < 0) { - mctp_prerr("Can't set slave"); - return -1; - } - if (ioctl(smbus->out_fd, I2C_PEC, 1) < 0) { - mctp_prerr("Cant set PEC byte"); - return -1; - } - - if (i2c_smbus_write_block_data(smbus->out_fd, MCTP_COMMAND_CODE, - sizeof(*hdr) + len, (void *)smbus->txbuf) - < 0) { - mctp_prerr("Failed to send"); + if (mctp_smbus_tx(smbus, i2c_message_len)) { + mctp_prerr("Can't hold mux"); return -1; } @@ -119,64 +200,83 @@ static int mctp_binding_smbus_tx(struct mctp_binding *b, #ifdef MCTP_FILEIO int mctp_smbus_read(struct mctp_binding_smbus *smbus) { - ssize_t len; - int r; + ssize_t len = 0; struct mctp_smbus_header_rx *hdr; + int ret = 0; - r = lseek(smbus->in_fd, 0, SEEK_SET); - if (r < 0) { - mctp_prerr("Failed to seek"); - return -1; - } - len = read(smbus->in_fd, smbus->rxbuf, sizeof(smbus->rxbuf)); - if (len < sizeof(*hdr)) { - // TODO Don't return an error here, as it seems to happen from - // time to time, even with a properly written poll loop, - // although it's not clear why. - return 0; - } + do { + ret = lseek(smbus->in_fd, 0, SEEK_SET); + if (ret < 0) { + mctp_prerr("Failed to seek"); + ret = -1; + } - hdr = (void *)smbus->rxbuf; - if (hdr->destination_slave_address - != (MCTP_SOURCE_SLAVE_ADDRESS & ~1)) { - mctp_prerr("Got bad slave address %d", - hdr->destination_slave_address); - return 0; - } - if (hdr->command_code != MCTP_COMMAND_CODE) { - mctp_prerr("Got bad command code %d", hdr->command_code); - // Not a payload intended for us - return 0; - } + len = read(smbus->in_fd, smbus->rxbuf, sizeof(smbus->rxbuf)); + if (len < sizeof(*hdr)) { + // This condition hits from from time to time, even with + // a properly written poll loop, although it's not clear + // why. Return an error so that the upper layer can + // retry. + ret = 0; + break; + } - if (hdr->byte_count != (len - sizeof(*hdr))) { - // Got an incorrectly sized payload - mctp_prerr("Got smbus payload sized %d, expecting %d", - hdr->byte_count, len - sizeof(*hdr)); - return 0; - } + hdr = (void *)smbus->rxbuf; + if (hdr->destination_slave_address + != (MCTP_SOURCE_SLAVE_ADDRESS & ~1)) { + mctp_prerr("Got bad slave address %d", + hdr->destination_slave_address); + ret = 0; + break; + } + if (hdr->command_code != MCTP_COMMAND_CODE) { + mctp_prerr("Got bad command code %d", + hdr->command_code); + // Not a payload intended for us + ret = 0; + break; + } - if (len < 0) { - mctp_prerr("can't read from smbus device: %m"); - return -1; - } + if (hdr->byte_count != (len - sizeof(*hdr))) { + // Got an incorrectly sized payload + mctp_prerr("Got smbus payload sized %d, expecting %d", + hdr->byte_count, len - sizeof(*hdr)); + ret = 0; + break; + } - smbus->rx_pkt = mctp_pktbuf_alloc(0); - assert(smbus->rx_pkt); + if (len < 0) { + mctp_prerr("can't read from smbus device: %m"); + ret = -1; + break; + } - if (mctp_pktbuf_push(smbus->rx_pkt, &smbus->rxbuf[sizeof(*hdr)], - len - sizeof(*hdr) - SMBUS_PEC_BYTE_SIZE) - != 0) { - mctp_prerr("Can't push tok pktbuf: %m"); - return -1; - } + smbus->rx_pkt = mctp_pktbuf_alloc(0); + assert(smbus->rx_pkt); + + if (mctp_pktbuf_push(smbus->rx_pkt, &smbus->rxbuf[sizeof(*hdr)], + len - sizeof(*hdr) - SMBUS_PEC_BYTE_SIZE) + != 0) { + mctp_prerr("Can't push tok pktbuf: %m"); + ret = -1; + break; + } - mctp_bus_rx(&(smbus->binding), smbus->rx_pkt); + mctp_bus_rx(&(smbus->binding), smbus->rx_pkt); - mctp_pktbuf_free(smbus->rx_pkt); - smbus->rx_pkt = NULL; + mctp_pktbuf_free(smbus->rx_pkt); + smbus->rx_pkt = NULL; - return 0; + } while (0); + +#ifdef I2C_M_HOLD + if (mctp_smbus_unhold_bus(smbus)) { + mctp_prerr("Can't hold mux"); + ret = -1; + } +#endif // I2C_M_HOLD + + return ret; } int mctp_smbus_get_in_fd(struct mctp_binding_smbus *smbus) @@ -193,17 +293,13 @@ int mctp_smbus_open_bus(struct mctp_binding_smbus *smbus, int out_bus_num, int root_bus_num) { char filename[60]; - size_t filename_size; + size_t filename_size = 0; char slave_mqueue[20]; - size_t mqueue_size; - - int fd; - - size_t size; - int address_7_bit; + size_t mqueue_size = 0; + int fd = 0; + size_t size = sizeof(filename); + int address_7_bit = MCTP_SOURCE_SLAVE_ADDRESS >> 1; - address_7_bit = MCTP_SOURCE_SLAVE_ADDRESS >> 1; - size = sizeof(filename); snprintf(filename, size, "/sys/bus/i2c/devices/i2c-%d/%d-%04x/slave-mqueue", root_bus_num, root_bus_num, @@ -263,7 +359,6 @@ int mctp_smbus_open_bus(struct mctp_binding_smbus *smbus, int out_bus_num, return 0; } - #endif void mctp_smbus_register_bus(struct mctp_binding_smbus *smbus, @@ -271,8 +366,8 @@ void mctp_smbus_register_bus(struct mctp_binding_smbus *smbus, { assert(smbus->out_fd >= 0); assert(smbus->in_fd >= 0); - smbus->mctp = mctp; smbus->bus_id = mctp_register_bus(mctp, &smbus->binding, eid); + mctp_binding_set_tx_enabled(&smbus->binding, true); } struct mctp_binding_smbus *mctp_smbus_init(void) @@ -291,3 +386,8 @@ struct mctp_binding_smbus *mctp_smbus_init(void) return smbus; } + +void mctp_smbus_free(struct mctp_binding_smbus *smbus) +{ + __mctp_free(smbus); +} \ No newline at end of file -- cgit v1.2.3