STRUCT DRM_MODE_GET_CONNECTOR(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’– struct drm_mode_get_connector β€” GET CONNECTOR METADATA πŸ’–

okay bestie so this is a page out of the Kernel API Manual, and it's all about struct drm_mode_get_connector β€” literally the struct you use to get connector metadata. no cap, it's the main character of the GETCONNECTOR ioctl. let's get into it 🫢


✨ SYNOPSIS ✨

like, here's the whole struct in all its glory β€” every field, exactly as it lives:

struct drm_mode_get_connector {
    __u64 encoders_ptr;
    __u64 modes_ptr;
    __u64 props_ptr;
    __u64 prop_values_ptr;
    __u32 count_modes;
    __u32 count_props;
    __u32 count_encoders;
    __u32 encoder_id;
    __u32 connector_id;
    __u32 connector_type;
    __u32 connector_type_id;
    __u32 connection;
    __u32 mm_width;
    __u32 mm_height;
    __u32 subpixel;
    __u32 pad;
 };

she's structured, she's specific, she's iconic. periodt πŸ’…


πŸŽ€ MEMBERS πŸŽ€

every single field, bestie, no skips:

  • encoders_ptr β€” pointer to a `__u32` array of object IDs. that's it, that's the vibe.
  • modes_ptr β€” pointer to a struct drm_mode_modeinfo array. modes live here ✨
  • props_ptr β€” pointer to a `__u32` array of property IDs.
  • prop_values_ptr β€” pointer to a `__u64` array of property values. note the width difference, iykyk πŸ‘€
  • count_modes β€” number of modes.
  • count_props β€” number of properties.
  • count_encoders β€” number of encoders.
  • encoder_id β€” object ID of the current encoder.
  • connector_id β€” object ID of the connector. the one true ID fr fr.
  • connector_type β€” type of the connector β€” see the DRM_MODE_CONNECTOR_* defines for the actual values.
  • connector_type_id β€” type-specific connector number. and like, read this part carefully bestie: this is not an object ID. it's a per-type connector number. each (type, type_id) combination is unique across all connectors of a DRM device.

butβ€”plot twist πŸ˜­β€”the (type, type_id) combination is not a stable identifier: the type_id can change depending on the driver probe order. so don't you dare cache it and expect it to hold. πŸ™ˆ

  • connection β€” status of the connector. see enum drm_connector_status.
  • mm_width β€” width of the connected sink in millimeters.
  • mm_height β€” height of the connected sink in millimeters.
  • subpixel β€” subpixel order of the connected sink. see enum subpixel_order.
  • pad β€” padding, and it must be zero. like, literally zero. don't be weird about it πŸ’€

🌸 DESCRIPTION 🌸

so here's the whole situation: user-space can perform a GETCONNECTOR ioctl to retrieve information about a connector. and the way you do it is a whole two-step dance, because you can't just grab everything in one go, that would be too easy πŸ¦‹

user-space is expected to retrieve encoders, modes and properties by performing this ioctl at least twice:

  1. the first time β€” to retrieve the number of elements.
  2. the second time β€” to retrieve the elements themselves.

step one, get the counts β€” set count_props and count_encoders to zero, set count_modes to 1, and set modes_ptr to a temporary struct drm_mode_modeinfo element. that's the ritual, don't skip steps πŸ”₯

step two, get the actual stuff β€” allocate arrays for encoders_ptr, modes_ptr, props_ptr and prop_values_ptr, then set count_modes, count_props and count_encoders to their capacity.

⚠️ real talk: performing the ioctl only twice may be racy β€” the number of elements may have changed with a hotplug event in-between the two ioctls. so user-space is expected to retry the last ioctl until the number of elements stabilizes. and know this: the kernel won't fill any array which doesn't have the expected length. so if your lengths are off, you get nothing. not a partial fill, nothing. 😭

πŸ’… Force-probing a connector

okay this is the juiciest part, listen up:

if the count_modes field is set to zero and the DRM client is the current DRM master, the kernel will perform a forced probe on the connector to refresh the connector status, modes and EDID.

🚨 but heads up: a forced-probe can be slow, might cause flickering, and the ioctl will block. it's giving "worth it but at what cost" πŸ’€

so when do you actually do it? user-space needs to force-probe connectors to ensure their metadata is up-to-date at startup and after receiving a hot-plug event. user-space may perform a forced-probe when the user explicitly requests it. and user-space shouldn't perform a forced-probe in other situations. that's the whole rule, no notes πŸ‘‘


πŸ¦‹ SEE ALSO πŸ¦‹

the whole friend group, in order, no one left out 🫢

Kernel file ./include/uapi/drm/drm_mode.h overview(9), struct drm_mode_modeinfo(9), struct drm_mode_get_plane(9), struct drm_mode_property_enum(9), struct drm_mode_get_property(9), struct drm_mode_fb_cmd2(9), enum drm_colorop_type(9), enum drm_colorop_lut3d_interpolation_type(9), enum drm_colorop_lut1d_interpolation_type(9), struct drm_plane_size_hint(9), struct hdr_metadata_infoframe(9), struct hdr_output_metadata(9), DRM_MODE_PAGE_FLIP_EVENT(9), DRM_MODE_PAGE_FLIP_ASYNC(9), DRM_MODE_PAGE_FLIP_FLAGS(9), struct drm_mode_create_dumb(9), DRM_MODE_ATOMIC_TEST_ONLY(9), DRM_MODE_ATOMIC_NONBLOCK(9), DRM_MODE_ATOMIC_ALLOW_MODESET(9), DRM_MODE_ATOMIC_FLAGS(9), struct drm_mode_create_blob(9), struct drm_mode_destroy_blob(9), struct drm_mode_create_lease(9), struct drm_mode_list_lessees(9), struct drm_mode_get_lease(9), struct drm_mode_revoke_lease(9), struct drm_mode_rect(9), struct drm_mode_closefb(9)


and that's the page, bestie πŸ’œ this one lives in ./include/uapi/drm, dated October 2026 β€” go off, go read it again, and go force-probe responsibly. mwah πŸŽ€βœ¨

πŸ“¦ where this page comes from