Skip to content

Conversation

eric-ocasio-nxp
Copy link

@eric-ocasio-nxp eric-ocasio-nxp commented Sep 2, 2025

Add USB device binding for MCTP. Created new USB device class for MCTP, libMCTP binding, and sample application.

Copy link

github-actions bot commented Sep 2, 2025

Hello @eric-ocasio-nxp, and thank you very much for your first pull request to the Zephyr project!
Our Continuous Integration pipeline will execute a series of checks on your Pull Request commit messages and code, and you are expected to address any failures by updating the PR. Please take a look at our commit message guidelines to find out how to format your commit messages, and at our contribution workflow to understand how to update your Pull Request. If you haven't already, please make sure to review the project's Contributor Expectations and update (by amending and force-pushing the commits) your pull request if necessary.
If you are stuck or need help please join us on Discord and ask your question there. Additionally, you can escalate the review when applicable. 😊

@zephyrbot zephyrbot added area: Devicetree area: USB Universal Serial Bus area: PMCI Platform Management Communications Infrastructure area: Samples Samples labels Sep 2, 2025
Copy link

sonarqubecloud bot commented Sep 2, 2025

@@ -0,0 +1,11 @@
.. _usbd_mctp:

MCTP USB device API
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please detail what "MCTP" actually is here.

teburd
teburd previously approved these changes Sep 17, 2025

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(mctp_endpoint)
Copy link
Contributor

@teburd teburd Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

project name could use something more descriptive, I get I'm guilty of probably starting this but perhaps mctp_usb_endpoint would be better

project(mctp_endpoint)

include(${ZEPHYR_BASE}/samples/subsys/usb/common/common.cmake)
FILE(GLOB app_sources src/*.c)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please don't glob here


An example script to test this interface is provided below.

.. code-block:: python
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly probably better to put this into scripts or into the sample directory itself as a python script with requirements.txt and all rather than pushing users to copy/paste, and figure out how to get the python deps installed.

Can always include whole code files into the docs like this with literalinclude

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. I moved it to a script within the sample folder with a requirements.txt and instructions in the README.

@teburd
Copy link
Contributor

teburd commented Sep 17, 2025

Non-blocking comments obviously, but would be good to see improvements.

@jfischer-no jfischer-no changed the title Feature/add mctp usb binding Add MCTP over USB Binding support Sep 17, 2025
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to support the USB binding for libMCTP, we must first add a device
class for MCTP. MCTP is one of the base classes in the USB specification.

Well no, it is specified by the "DMTF association", https://www.dmtf.org/sites/default/files/standards/documents/DSP0283_1.0.0.pdf

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's base class 0x14 in the USB spec, so I'm not sure what you mean here.

https://www.usb.org/defined-class-codes

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+-----------------------------------+-------------------------+-------------------------+
| USB Video Class (UVC) | Video device | :samp:`uvc_{n}` |
+-----------------------------------+-------------------------+-------------------------+
| USB MCTP over USB Endpoint | :ref:`usbd_mctp` | :samp:`mctp_{n}` |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/USB MCTP over USB Endpoint/MCTP over USB Binding


* :zephyr:code-sample:`usb-hid-mouse`

* :zephyr:code-sample:`mctp-usb-endpoint`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* :zephyr:code-sample:mctp-usb-binding`` Anyway, you cannot add it in this commit, this sample does not exist yet.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you suggest that I just update this file in a commit with the sample application, or do one 'super commit' with all of these feature/MCTP changes? I did it this way for human readability, but didn't fully understand the need for every commit to build.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Commits in a pull request should represent clear, logical units of change that are easy to review and maintain bisectability." https://docs.zephyrproject.org/latest/contribute/contributor_expectations.html#pr-requirements


/**
* @file
* @brief USB MCTP over USB Protocol Endpoint Device Class (MCTP) public header
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@brief MCTP over USB Binding implementation

* @brief USB MCTP over USB Protocol Endpoint Device Class (MCTP) public header
*
* This header describes MCTP class interactions desgined to be used by libMCTP.
* The MCTP device itself is modelled with devicetree zephyr,mctp-usb compatible.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what that means, but usually devicetree is used to describe and instantiate a device. Whether it makes sense here or not is disputable.

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(usbd_mctp, CONFIG_USBD_MCTP_LOG_LEVEL);

#define DT_DRV_COMPAT zephyr_mctp_usb
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you thing it should model a device and use DT for instantiation. You do not have to follow usbd_hid approach. This looks more like a backend implementation, and for that you could provide hooks and instantiation macro, please take a look at new USB DFU device implementation.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did it this way because there exists the possibility of having multiple MCTP buses/bindings. If the application requires more than one MCTP endpoint, a USB composite device could be used with more than one instance of USBD MCTP. Is there a way to accomplish this without DT?


config MCTP_USB
bool "MCTP USB Binding"
depends on USB_DEVICE_STACK_NEXT
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

redundant, USBD_MCTP_CLASS already depends on USB_DEVICE_STACK_NEXT.

Comment on lines 56 to 61
.name = STRINGIFY(_name), .version = 1, \
.pkt_size = \
MCTP_PACKET_SIZE(MCTP_USB_MAX_PACKET_LENGTH), \
.pkt_header = 0, .pkt_trailer = 0, \
.start = mctp_usb_start, .tx = mctp_usb_tx, \
}, \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Broken style.

* @param _name Symbolic name of the bus binding variable
* @param _dev DeviceTree Node containing the configuration of this MCTP binding
*/
#define MCTP_USB_DT_DEFINE(_name, _dev) \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not get the purpose of this macro and the mctp_usb.c, you already have implemented instantiation and support for this function in the previous commit, what it that and why does it have to be divided?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not following. This macro was created based on the other libmctp binding implementations. What do you mean by it being divided?

@@ -0,0 +1,9 @@
# Copyright (c) 2023 Nordic Semiconductor ASA
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am confused, is PMCI/MCTP not part of the Zephyr but an external module? If so then I do not think you can add any dependency on it to the USB subsystem.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way I looked at it is that MCTP is called out as a base class on usb.org, so the device class implementation can exists in Zephyr, even if the higher-level MCTP protocol management comes from an external module. Right now it comes from libmctp (https://github.com/openbmc/libmctp).

I understand this concern. Is there something you think would create such a dependency? Again, I'm new to Zephyr, so maybe I don't fully understand something.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am confused, is PMCI/MCTP not part of the Zephyr but an external module?

mctp is not an external module, it is part of the main manifest and there are dependencies on it already.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am confused, is PMCI/MCTP not part of the Zephyr but an external module?

mctp is not an external module, it is part of the main manifest and there are dependencies on it already.

Anyway, the implementation cannot be part of subsys/usb, and has to go to the modules.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fact that MCTP is listed on usb.org doesn't matter then?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@teburd ok, I'll explore this.

Regarding dependency in general, I want to clarify something since it may not be clear from this initial PR. The re-worked PR I have locally has cleaner lines of separation...

Besides the reference to the MCTP sample in usb_device.rst, the USB device class has no dependency on libmctp. Yes, libmctp uses it, but any other MCTP implementation can as well. You can remove libmctp and the device class stands on its own.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you post the re-worked PR? Would that come as separate PR or a force-push here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I'll try to find some time to get it done today. The plan was for force push.

Copy link
Member

@nashif nashif Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jfischer-no

What in Zephyr depends on libmctp?

 git grep  libmctp.h subsys/ include/
include/zephyr/pmci/mctp/mctp_i2c_gpio_controller.h:#include <libmctp.h>
include/zephyr/pmci/mctp/mctp_i2c_gpio_target.h:#include <libmctp.h>
include/zephyr/pmci/mctp/mctp_uart.h:#include <libmctp.h>
subsys/pmci/mctp/mctp_memory.c:#include <libmctp.h>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even MCTP samples are only located in samples/modules.

is this your issue? really? #96995

…nding

Add support for MCTP over USB by providing a new USBD class, device tree
binding and sample application. The USB binding for libmctp follows
existing design from other transports.

The USBD class is a basic implementation, as defined in the DMTF spec, and
is solely providing transmit and receive data pipes for a higher-level MCTP
transport and protocol manager. The USB-specific wrapping of MCTP data is
added and parsed to/from the raw USB data in the MCTP USB binding (libmctp
in this case), not in the USBD class. The goal of this design is to provide
flexibility for alternative MCTP implementations.

Signed-off-by: Eric Ocasio <[email protected]>
Add license header to usb_host_tester.py, fix typo in usbd_mctp.h and rogue
space in usbd_mctp.h.

Signed-off-by: Eric Ocasio <[email protected]>
Copy link

sonarqubecloud bot commented Oct 4, 2025

@dleach02
Copy link
Member

dleach02 commented Oct 8, 2025

@jfischer-no, @eric-ocasio-nxp, @teburd, @nashif

Would it be helpful to move this to the arch WG call (@carlescufi) so we can collectively discuss what is needed to get this PR to move? It is unclear to me what the specific request is that will satisfy @jfischer-no change request and the back-and-forth in this PR doesn't seem to be productive?

@dleach02 dleach02 added the Architecture Review Discussion in the Architecture WG required label Oct 8, 2025
@carlescufi
Copy link
Member

@jfischer-no, @eric-ocasio-nxp, @teburd, @nashif

Would it be helpful to move this to the arch WG call (@carlescufi) so we can collectively discuss what is needed to get this PR to move? It is unclear to me what the specific request is that will satisfy @jfischer-no change request and the back-and-forth in this PR doesn't seem to be productive?

Yes, I will schedule it for next Tuesday (CC @henrikbrixandersen)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Architecture Review Discussion in the Architecture WG required area: Boards/SoCs area: Devicetree Bindings area: Devicetree area: PMCI Platform Management Communications Infrastructure area: Samples Samples area: USB Universal Serial Bus

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

10 participants