On 3/2/23 13:01, Simon Ser wrote:
> On Tuesday, February 28th, 2023 at 16:16, Peter Stuge <pe...@stuge.se> 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.

Reply via email to