On 3/2/23 13:01, Simon Ser wrote: > On Tuesday, February 28th, 2023 at 16:16, Peter Stuge <peter@xxxxxxxx> wrote: > >> Simon Ser wrote: >> >>>>> Would it be possible to set the PATH connector property based on the >>>>> USB port used by gud? >>>> >>>> Sadly not really easily. >>>> >>>> The physical topology underneath each host controller is stable but >>>> bus numbers (usb1, usb2 etc.) are not. >>> >>> Oh, that's news to me. So if I unplug and replug a USB device, the bus >>> number and bus device number might change? >> >> The bus number is stable as long as the bus (host controller) exists. >> >>> Or does this happen after a power-cycle? Or is this hardware-specific? >> >> Consider a host controller on a plug-in card, like ExpressCard (usb1) >> and perhaps Thunderbolt (usb2) for a more modern example. >> >> The bus on each new host controller gets the next available bus number. >> >> Plug ExpressCard before Thunderbolt to get the order above. Unplug >> both (usb1+usb2 disappear) then plug Thunderbolt back in before >> ExpressCard; now Thunderbolt is usb1 and ExpressCard usb2. > > Hm, right. With a first-come-first-served scheme, there is no way to > have stable identifiers. > > I'm having a look at prior art: udev has similar needs for network > interface names. For USB they use [2] a scheme with > port/config/interface. I have no idea what meaning these have, but > would they be useful for building a PATH KMS property? > > [1]: https://www.freedesktop.org/software/systemd/man/systemd.net-naming-scheme.html > [2]: https://github.com/systemd/systemd/blob/7a67afe33192ce4a55e6825b80554fb4ebbb4b03/src/udev/udev-builtin-net_id.c#L758 > I'm no expert but that looks like a good idea, it has probably been well scrutinized. Maybe we can do something like this, not tested: /* PATH=usb:[[P<domain>]s<slot>[f<function>]]u<usbpath>o<connector-index> */ int drm_connector_set_path_property_usb(struct drm_connector *connector, struct usb_interface *intf) { u8 config = intf->cur_altsetting->desc.bAlternateSetting; u8 ifnum = intf->cur_altsetting->desc.bInterfaceNumber; struct usb_device *usb = interface_to_usbdev(intf); struct device *dev = &intf->dev; char path[255], temp[64]; strlcpy(path, "usb:", sizeof(path)); while (dev = dev->parent) { struct pci_dev *pci; if (dev->bus != &pci_bus_type) continue; pci = to_pci_dev(dev); if (pci_domain_nr(pci->bus)) { snprintf(temp, sizeof(temp), "P%u", pci_domain_nr(pci->bus)); strlcat(path, temp, sizeof(path)); } snprintf(temp, sizeof(temp), "s%u", PCI_SLOT(pci->devfn)); strlcat(path, temp, sizeof(path)); if (pci->multifunction) { snprintf(temp, sizeof(temp), "f%u", PCI_FUNC(pci->devfn)); strlcat(path, temp, sizeof(path)); } break; } snprintf(temp, sizeof(temp), "u%s", usb->devpath); strlcat(path, temp, sizeof(path)); if (config) { snprintf(temp, sizeof(temp), "c%u", config); strlcat(path, temp, sizeof(path)); } if (ifnum) { snprintf(temp, sizeof(temp), "i%u", ifnum); strlcat(path, temp, sizeof(path)); } snprintf(temp, sizeof(temp), "o%s", connector->index); strlcat(path, temp, sizeof(path)); return drm_connector_set_path_property(connector, path); } Noralf.