DRVCTL(4)

πŸ“¦ version 11.0, in nixpkgs unstable

✨ DRVCTL(4) ✨ β€” the driver control device, explained bestie-style πŸ’…

okay so this is the drvctl manual page, from the Kernel Interfaces Manual β€” it's lowkey the whole scoop on the driver control device and honestly it ate πŸŽ€


🌸 NAME 🌸

drvctl β€” the driver control device. that's it, that's the vibe πŸ’–

πŸ¦‹ SYNOPSIS πŸ¦‹

pseudo-device drvctl

bestie it's a pseudo-device, you just declare it like that ✨

πŸ’œ DESCRIPTION πŸ’œ

so the drvctl driver lets you control some autoconf(9) operations from userland β€” like, from regular old userspace, no kernel hacking required 🫢 β€” and it does that through the /dev/drvctl device plus the drvctl(8) command.

the driver supports the following ioctl(2) operations. buckle up, there's a few πŸ‘‘

  • DRVSUSPENDDEV / DRVRESUMEDEV β€” these invoke the power management functions for a named driver that has registered itself with the pmf(9) framework. the ioctl argument specifies the driver name as:
struct devpmargs {
        char devname[16];
        uint32_t flags;
};

and the DEVPM_F_SUBTREE flag lets the function recurse over all children of that driver β€” like, it goes down the whole family tree, no cap 🌳

  • DRVLISTDEV β€” returns a list of child devices attached to the named driver. the ioctl argument specifies the driver name as:
struct devlistargs {
        char l_devname[16];
        char (*l_childname)[16];
        size_t l_children;
};

the names for up to l_children child devices are copied into the l_childname array. if there's no error, the ioctl returns the total number of children. normally you'd call DRVLISTDEV once with l_children set to zero, allocate a buffer for enough 16-character strings, and then call DRVLISTDEV again to fill the buffer β€” classic two-pass move, iykyk 😌

  • DRVDETACHDEV β€” detaches the named driver and all its autoconfigured children. the ioctl argument specifies the driver name as:
struct devdetachargs {
        char devname[16];
};

like, it's taking the whole squad with it πŸ’€

  • DRVSCANBUS β€” invokes the rescan method of the named driver to locate child devices. the ioctl argument specifies the driver name as:
struct devrescanargs {
        char busname[16];
        char ifattr[16];
        unsigned int numlocators;
        int *locators;
};

some device drivers attach children to specific interface attributes, and a zero length ifattr represents that no interface attribute should be used. the rescan can also be limited to driver-specific locators β€” very customizable, we love to see it ✨

  • DRVCTLCOMMAND β€” sends a command formatted as a property list. the property list includes all arguments like the driver name, and the result is again a property list. currently the only supported command is "get-properties", and the property list is constructed like this:
const char *device = "sd0";
const char *command = "get-properties";

prop_string_t s;
prop_dictionary_t c, a;

c = prop_dictionary_create();
a = prop_dictionary_create();

s = prop_string_create_cstring_nocopy(command);
prop_dictionary_set(c, "drvctl-command", s);
prop_object_release(s);

s = prop_string_create_cstring(device);
prop_dictionary_set(a, "device-name", s);
prop_object_release(s);

prop_dictionary_set(c, "drvctl-arguments", a);
prop_object_release(a);

the command must be sent with prop_dictionary_sendrecv_ioctl(3) β€” that's not optional, bestie, it's the rule πŸ™ˆ the resulting property list contains the numeric attribute drvctl-error, which corresponds to an errno value, and the dictionary drvctl-result-data. the contents of that dictionary depends on the queried driver.

  • DRVGETEVENT β€” returns the next queued autoconfig event formatted as a property list. the request needs to be sent with prop_dictionary_recv_ioctl(3). the resulting property list contains the string attributes event, device and parent. currently the events "device-attach" and "device-detach" are generated by the autoconf(9) framework.
ok important caveat 🚨: if /dev/drvctl was opened with O_NONBLOCK and there is no event queued, the call returns immediately with EWOULDBLOCK. otherwise it waits for the next event. so like, it will just sit there being patient. main character patience πŸ’…

all names used in the ioctl arguments are zero-terminated strings. and a driver name is the name of a driver instance with the appended unit number, like sd0, atabus3, ... β€” that's the format, periodt 🌈


πŸŽ€ FILES πŸŽ€

  • /dev/drvctl β€” the drvctl access device. literally the door to all of this πŸšͺ

🧚 SEE ALSO 🧚

ioctl(2), prop_send_ioctl(3), proplib(3), devpubd(8), drvctl(8), autoconf(9)

go read those if you want the full lore, bestie πŸ“š

πŸ‘‘ HISTORY πŸ‘‘

the /dev/drvctl device appeared in NetBSD 3.0 but was only added to the GENERIC configuration in NetBSD 5.0 β€” so it was out here existing before it was officially in the lineup, iconic behavior fr fr πŸ’€βœ¨


and that's the whole page!! 🫢 this lovely piece of documentation is from the Debian build, dated May 13, 2015, and it's DRVCTL(4) β€” drink water, read your man pages, and slay the day bestie πŸ’–πŸŽ€πŸ¦‹

πŸ“¦ where this page comes from