@@ -147,8 +147,12 @@ struct link {
147147 char * path ;
148148 sd_bus_slot * slot_iface ;
149149 sd_bus_slot * slot_busowner ;
150+ sd_bus_slot * slot_endpoint ;
150151 sd_event_source * role_defer ;
151152
153+ /* Physical address of the bus owner, set via SetBusOwner. */
154+ dest_phys bus_owner ;
155+
152156 struct ctx * ctx ;
153157};
154158
@@ -385,6 +389,7 @@ static const sd_bus_vtable bus_endpoint_obmc_vtable[];
385389static const sd_bus_vtable bus_endpoint_cc_vtable [];
386390static const sd_bus_vtable bus_endpoint_bridge [];
387391static const sd_bus_vtable bus_endpoint_uuid_vtable [];
392+ static const sd_bus_vtable bus_link_endpoint_vtable [];
388393
389394__attribute__((format (printf , 1 , 2 ))) static void bug_warn (const char * fmt , ...)
390395{
@@ -1658,7 +1663,7 @@ static int mctp_ctrl_validate_response(struct mctp_ctrl_cmd *cmd,
16581663{
16591664 struct mctp_ctrl_resp * rsp ;
16601665
1661- if (exp_size <= sizeof (* rsp )) {
1666+ if (exp_size < sizeof (* rsp )) {
16621667 warnx ("invalid expected response size!" );
16631668 return - EINVAL ;
16641669 }
@@ -4017,6 +4022,94 @@ static int method_register_vdm_type_support(sd_bus_message *call, void *data,
40174022 return rc ;
40184023}
40194024
4025+ static int method_set_bus_owner (sd_bus_message * call , void * data ,
4026+ sd_bus_error * berr )
4027+ {
4028+ struct link * link = data ;
4029+ struct ctx * ctx = link -> ctx ;
4030+ dest_phys dest = { 0 };
4031+ int rc ;
4032+
4033+ dest .ifindex = link -> ifindex ;
4034+ if (dest .ifindex <= 0 )
4035+ return sd_bus_error_setf (berr , SD_BUS_ERROR_INVALID_ARGS ,
4036+ "Unknown MCTP interface" );
4037+
4038+ rc = message_read_hwaddr (call , & dest );
4039+ if (rc < 0 ) {
4040+ set_berr (ctx , rc , berr );
4041+ return rc ;
4042+ }
4043+
4044+ rc = validate_dest_phys (ctx , & dest );
4045+ if (rc < 0 )
4046+ return sd_bus_error_setf (berr , SD_BUS_ERROR_INVALID_ARGS ,
4047+ "Bad physaddr" );
4048+
4049+ link -> bus_owner = dest ;
4050+ return sd_bus_reply_method_return (call , "" );
4051+ }
4052+
4053+ static int method_attempt_discovery_notify (sd_bus_message * call , void * data ,
4054+ sd_bus_error * berr )
4055+ {
4056+ struct mctp_ctrl_resp_discovery_notify * resp = NULL ;
4057+ struct mctp_ctrl_cmd_discovery_notify req = { 0 };
4058+ struct mctp_ctrl_cmd cmd = { 0 };
4059+ struct link * link = data ;
4060+ struct ctx * ctx = link -> ctx ;
4061+ unsigned int retry ;
4062+ uint8_t iid ;
4063+ int rc ;
4064+
4065+ if (link -> bus_owner .hwaddr_len == 0 )
4066+ return sd_bus_error_setf (berr , SD_BUS_ERROR_INVALID_ARGS ,
4067+ "Bus owner address not set" );
4068+
4069+ for (retry = 0 ; retry < 4 ; retry ++ ) {
4070+ iid = mctp_next_iid (ctx );
4071+ mctp_ctrl_msg_hdr_init_req (& req .ctrl_hdr , iid ,
4072+ MCTP_CTRL_CMD_DISCOVERY_NOTIFY );
4073+ mctp_ctrl_cmd_init_from_req_type (& cmd , req );
4074+
4075+ rc = endpoint_query_phys (ctx , & link -> bus_owner , & cmd );
4076+ if (rc < 0 ) {
4077+ mctp_ctrl_cmd_free (& cmd );
4078+ break ;
4079+ }
4080+
4081+ rc = mctp_ctrl_validate_response (
4082+ & cmd , sizeof (* resp ), dest_phys_tostr (& link -> bus_owner ),
4083+ iid , MCTP_CTRL_CMD_DISCOVERY_NOTIFY );
4084+ mctp_ctrl_cmd_free (& cmd );
4085+ if (rc == 0 )
4086+ return sd_bus_reply_method_return (call , "" );
4087+ /* retry on non-fatal completion code errors */
4088+ if (rc != - EBUSY )
4089+ break ;
4090+ }
4091+
4092+ set_berr (ctx , rc , berr );
4093+ return rc ;
4094+ }
4095+
4096+ // clang-format off
4097+ static const sd_bus_vtable bus_link_endpoint_vtable [] = {
4098+ SD_BUS_VTABLE_START (0 ),
4099+ SD_BUS_METHOD_WITH_ARGS ("SetBusOwner" ,
4100+ SD_BUS_ARGS ("ay" , physaddr ),
4101+ SD_BUS_NO_RESULT ,
4102+ method_set_bus_owner ,
4103+ 0 ),
4104+ SD_BUS_METHOD_WITH_ARGS ("AttemptDiscoveryNotify" ,
4105+ SD_BUS_NO_ARGS ,
4106+ SD_BUS_NO_RESULT ,
4107+ method_attempt_discovery_notify ,
4108+ 0 ),
4109+ SD_BUS_VTABLE_END ,
4110+ };
4111+ // clang-format on
4112+
40204113// clang-format off
40214114static const sd_bus_vtable bus_link_owner_vtable [] = {
40224115 SD_BUS_VTABLE_START (0 ),
@@ -4214,14 +4307,21 @@ static int link_set_role(sd_event_source *ev, void *userdata)
42144307 sd_event_source_unref (link -> role_defer );
42154308 link -> role_defer = NULL ;
42164309
4217- if (link -> role != ENDPOINT_ROLE_BUS_OWNER )
4218- return 0 ;
4219-
4220- rc = sd_bus_add_object_vtable (link -> ctx -> bus , & link -> slot_busowner ,
4221- link -> path , CC_MCTP_DBUS_IFACE_BUSOWNER ,
4222- bus_link_owner_vtable , link );
4223- if (rc )
4224- warnx ("adding link owner vtable failed: %d" , rc );
4310+ if (link -> role == ENDPOINT_ROLE_BUS_OWNER ) {
4311+ rc = sd_bus_add_object_vtable (link -> ctx -> bus ,
4312+ & link -> slot_busowner , link -> path ,
4313+ CC_MCTP_DBUS_IFACE_BUSOWNER ,
4314+ bus_link_owner_vtable , link );
4315+ if (rc )
4316+ warnx ("adding link owner vtable failed: %d" , rc );
4317+ } else if (link -> role == ENDPOINT_ROLE_ENDPOINT ) {
4318+ rc = sd_bus_add_object_vtable (link -> ctx -> bus ,
4319+ & link -> slot_endpoint , link -> path ,
4320+ CC_MCTP_DBUS_IFACE_ENDPOINT ,
4321+ bus_link_endpoint_vtable , link );
4322+ if (rc )
4323+ warnx ("adding link endpoint vtable failed: %d" , rc );
4324+ }
42254325
42264326 return 0 ;
42274327}
@@ -4712,6 +4812,7 @@ static void free_link(struct link *link)
47124812 sd_event_source_disable_unref (link -> role_defer );
47134813 sd_bus_slot_unref (link -> slot_iface );
47144814 sd_bus_slot_unref (link -> slot_busowner );
4815+ sd_bus_slot_unref (link -> slot_endpoint );
47154816 free (link -> path );
47164817 free (link -> sysfs_path );
47174818 free (link );
@@ -4781,6 +4882,8 @@ static int rename_interface(struct ctx *ctx, struct link *link, int ifindex)
47814882 link -> slot_iface = NULL ;
47824883 sd_bus_slot_unref (link -> slot_busowner );
47834884 link -> slot_busowner = NULL ;
4885+ sd_bus_slot_unref (link -> slot_endpoint );
4886+ link -> slot_endpoint = NULL ;
47844887 free (link -> path );
47854888
47864889 /* set new path and re-add */
@@ -4794,6 +4897,11 @@ static int rename_interface(struct ctx *ctx, struct link *link, int ifindex)
47944897 link -> path ,
47954898 CC_MCTP_DBUS_IFACE_BUSOWNER ,
47964899 bus_link_owner_vtable , link );
4900+ } else if (link -> role == ENDPOINT_ROLE_ENDPOINT ) {
4901+ sd_bus_add_object_vtable (link -> ctx -> bus , & link -> slot_endpoint ,
4902+ link -> path ,
4903+ CC_MCTP_DBUS_IFACE_ENDPOINT ,
4904+ bus_link_endpoint_vtable , link );
47974905 }
47984906
47994907 emit_interface_added (link );
@@ -5167,6 +5275,11 @@ static int add_interface(struct ctx *ctx, int ifindex)
51675275 link -> path ,
51685276 CC_MCTP_DBUS_IFACE_BUSOWNER ,
51695277 bus_link_owner_vtable , link );
5278+ } else if (link -> role == ENDPOINT_ROLE_ENDPOINT ) {
5279+ sd_bus_add_object_vtable (link -> ctx -> bus , & link -> slot_endpoint ,
5280+ link -> path ,
5281+ CC_MCTP_DBUS_IFACE_ENDPOINT ,
5282+ bus_link_endpoint_vtable , link );
51705283 }
51715284
51725285 if (link -> phys_binding == MCTP_PHYS_BINDING_PCIE_VDM ) {
0 commit comments