Re-designing the kernel device_manager

That’s the interface in devfs, where you get read, write, and ioctl. It is difficult to get more than this for this part, I think it would require all functions you want to export to be syscalls?

The new-style devices can provide a “device hook” structure with functions that can be called, but only from inside the kernel (from another driver or module usually).

Yes, you are probably right. I still wish for it, but perhaps the devfs approach has never been challenged as all OS’es seems to do it that way.

1 Like

All UNIX-inspired OS, but not necessarily the other ones.

Also, it’s possible to build other things from this base, with parts of the driver running in userspace. For example what we do with accelerants for graphics: the driver is used to map the video hardware in an area that is shared with userspace (this part is set up using an ioctl based communication). Then the accelerant can directly program the hardware, and expose a custom interface to userspace code.

This is a good approach where a complex interface is needed and/or when high performance is desirable, since it largely eliminates the syscall overhead. But there are security concerns on who should be allowed to access the hardware so directly.

1 Like

There was a relevant exchange on Gerrit today regarding USB device exploration which is relevant to the device_manager’s design, so copying it here for posterity:

4 Likes

Another note of something to change: there should probably be a distinction between child device nodes which are “part of” a device, and others which are “attached to” a device.

For example, XHCI on the PCI bus is a device, and it will have USB devices attached to it. But then there will be USB devices with multiple interfaces, and each interface is still “part of” the main device.

Right now, it appears all USB interface attributes are crammed into a single node for a single device. That looks like it could be a problem, then we have a USB device_node with multiple USB class/subclass/protocol attributes! Probably each configuration should have its own node, but since only one interface alternate can be active at a time, we need some way to manage that, too.

1 Like

This is probably a very stupid idea. But why not store the results for all the drivers that are needed?

And then when someone changes hardware you could have an option during boot up that lasts say 3 seconds (while running other things in the background) that you can “hit” and have it search for new/changed hardware.

This way, if anyone that rarely changes their hardware has a very fast boot up every time and the only time you need to look for new hardware is if there is a problem or the person says they have changed their hardware?

As I said, this is probably a very stupid idea. But I personally change my hardware about every 9.1 years (I have it on a spreadsheet where I note when I change my hardware so I have a calculation that gives me 9.1 years).

Other people may change their hardware every three years or ever year. But even so, you would only need to tell it once a year or whatever period of time happens before you change hardware you could tell the system you changed hardware and then it could go through detecting everything.

And what if someone changes the hardware and doesn’t see anything on screen? Well you could have a Yes/No question that you have to ask every time and if someone doesn’t respond after 5 seconds it can assume the person can’t see the question and then look for new hardware.

Something like that. It would drastically speed up boot times if you haven’t changed any hardware. And for when people plug-in USB devices, there is already a mechanism for that.

3 Likes

The problem is that the mechanism for USB devices is (well, now, anyway) the same one as detecting hardware at boot time.

Also, it isn’t just your hardware, but Haiku itself changes, and so that can change hardware compatibility. I agree we should find ways to speed up probing, and @X512 also has a number of ideas, too. There are definitely things we could do to avoid having to load all drivers every boot to detect support.

2 Likes

I hope we can make things faster without adding a Windows-3.11 style “my hardware changed” button that you have to trigger manually.

5 Likes

On OS’es that cached the results, they often got out of sync. So if we want to do caching we need to do a better job at detecting changes to drivers.

To me caches are more of a workaround you use if there is no other way, so I consider that a plan B.

3 Likes

Does ACPI / UEFI compile a list of hardware present, before passing control to the OS ? maybe it could be used as a starting point.

Also, if storing the hardware configuration would cause too much programming trouble, couldn´t we reflect about if we really need to speed up the hardware detection that much ? People don´t keep rebooting the computer just to see things scrolling by . They boot it once and keep it booted for a long time. A couple seconds in that boot process will not compensate for the effort in obtaining them.

1 Like

Yes it does you can walk its tree, both in UEFI and ACPI, I think they are also adopting devicetree to be part of UEFI or ACPI. You can even ask it to bring you partitions by GPT UUID’s.
So for starting a boot, you would just find right partition, and ask what hardware it is attached to, giving you a minimal set of drivers needed for booting. You could do the same with screen or other peripherals you would want to have initiated during boot. Others could be lazily discovered.

For partitions Haiku currently scans all partitions a second time, where we reread partition info. So we can do faster booting there as UEFI already did that, and we would not need to read from disk a second time. As some disks may be slow to read from, this can cause slow boot times.

1 Like

The problem isn’t the hardware detection per se. The problem is that Haiku, like BeOS but unlike even vaguely modern operating systems (like Windows 95) insists on asking every single driver “Hey, um, do you see any hardware that you can drive?”.

Notice: Not “What can you drive?” which is a static property which could be interrogated and stored asynchronously. Nor even “How would I, a competent operating system, determine if you can drive something?” which is fancier but still pragmatic. No, Haiku asks the drivers to take a look and decide for themselves.

In the 1980s, when perhaps some of the BeOS people were learning their craft, this was very normal. You wake up, you fumble around, is this VGA graphics? Let’s try prodding some registers to check. But it’s not how people were doing this in the systems born at the same time as BeOS, like NT and Linux, because the hardware from that period was increasingly intelligent - making the “probe” step pointless.

With an intelligent bus, you collect up knowledge about what your drivers can drive into a central “database” (it can be a simple text file, this isn’t hard) and then you use the intelligent bus to make a list of what you have, and you check it against that database and load drivers as necessary. If the drivers reveal more intelligent buses, or if more devices are added later by some other means, you just consult the list. If you get more drivers, updated drivers, whatever, you update the database.

Simple and effective and more than a quarter of a century old.

1 Like

Fixing that problem is one of the things we have been discussing in this thread and the linked tickets. Your constant use of a demeaning tone is not helpful to anyone or anything.

8 Likes

It’s great that you live in a perfect world where all hardware makes sense and is designed cleanly. Unfortunately, I don’t. For example, there are several devices that use the same USB IDs but are completely different. For example there are those using this specification: v-usb/usbdrv/USB-IDs-for-free.txt at master · obdev/v-usb · GitHub

The solution in Linux and Windows is to use libusb and write drivers in userspace to workaround the problem.

And this is just an example, there are many cases like that. Things that pretend to be USB HID or mass storage, but that accept special commands. In Linux you end up with manually configured udev rules, and in Windows you have to mess with uninstalling and installing drivers in device manager or even installing 3rd party tools like Zadig to manage your USB drivers.

Sure, if you want to ignore that complexity or let users handle it manually, the existing systems are good enough. But we can do better, simply by letting each driver have a chance to run some code to check if the device is really supported.

Then there is the question of caching the results so we don’t have to probe everything everytime. As tqh said, we will consider this as a plan B, because of the risk that the cache gets out of sync with reality. I want to say “we will see if the probing we are discussing here will be fast enough”, but really, it already is, and the changes we are discussing here will only make it even faster.

7 Likes

Saying again to be sure that in my definition driven attribute matching approach driver still have a chance to run probe code before driver will be attached to device. Attribute matching acts as filter that greatly reduce number of drivers needed to probe. Because attribute matching filter is guaranteed to be working, driver may have no probe function defined if attribute matching is already enough, no need to duplicate device detection code in probe function.

It works in this sequence:

  1. Lookup drivers in driver roster that match attributes of target device.
  2. Sort matched drivers descending by score defined in driver compatible hardware definition resources.
  3. Load first driver and call probe function. If probe function fails, load second driver and so on.

For some strange devices that use USB mass storage class, but actually completely different, it is possible to define driver with higher score and detect device manually in probe function.

It will be also needed to define a convention for assigning score value, for example assign 0.6 for generic drivers, 0.8 for per vendor drivers, 0.9 for strange hardware overrides etc…

7 Likes

Reading ticket #18333 has been enlightening.

Yes, that is clear and understood, and it fits into what I called “caching the results” (maybe that is not the best naming, since your solution would be in a more static and declarative way, instead of actual caching of the probe function).

Until now we have done it in the opposite way: adding exceptions in the “generic” driver so it rejects devices for which we know there is a more specific driver. But this only works when all the drivers are in the same project (handled by Haiku developers) and doesn’t work well for 3rd party drivers.

The convention is not strictly needed because the numbers are floating point so it should almost always be possible to fit between two existing drivers by adding more decimals to the numbers. But it wouldn’t hurt to have some general guidelines on what values to use as a starting point as you suggest (I think it can’t be a strict convention as there will always be some corner case).

2 Likes

And reserve some “significative” baluesto use by the OS, like to force one driver to be used. If the values are stored as attributes to the files, also the OS could adjust them when fine-tuning or optimizing things …

One of good things to do with new device manager API is making it C++ based, not C. It will allow to simplify C++ drivers and reduce boiler-plate code. If ability to write pure C drivers is needed, it can be achieved by declaring C++ interfaces pure abstract like COM so it will be possible to declare equivalent ABI-compatible vtable in C.

4 Likes

C interface is not really needed, we can do it all in C++. It would certainly make it easier to explain how to implement new drivers. “just subclass this class and implement the virtual functions” is easier than the current thing where you have to declare an array of hooks and other things manually.

The only thing is we’ll have to migrate the existing drivers to that new system. We currently have the “old” and “new” style drivers, and I don’t think we should add a 3rd variant without removing one of these two at the same time?

7 Likes