^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) ===========
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) ISA Drivers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) ===========
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) The following text is adapted from the commit message of the initial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) commit of the ISA bus driver authored by Rene Herman.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) During the recent "isa drivers using platform devices" discussion it was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) pointed out that (ALSA) ISA drivers ran into the problem of not having
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) the option to fail driver load (device registration rather) upon not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) finding their hardware due to a probe() error not being passed up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) through the driver model. In the course of that, I suggested a separate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) ISA bus might be best; Russell King agreed and suggested this bus could
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) use the .match() method for the actual device discovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) The attached does this. For this old non (generically) discoverable ISA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) hardware only the driver itself can do discovery so as a difference with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) the platform_bus, this isa_bus also distributes match() up to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) As another difference: these devices only exist in the driver model due
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) to the driver creating them because it might want to drive them, meaning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) that all device creation has been made internal as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) The usage model this provides is nice, and has been acked from the ALSA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) side by Takashi Iwai and Jaroslav Kysela. The ALSA driver module_init's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) now (for oldisa-only drivers) become::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static int __init alsa_card_foo_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) return isa_register_driver(&snd_foo_isa_driver, SNDRV_CARDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static void __exit alsa_card_foo_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) isa_unregister_driver(&snd_foo_isa_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) Quite like the other bus models therefore. This removes a lot of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) duplicated init code from the ALSA ISA drivers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) The passed in isa_driver struct is the regular driver struct embedding a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct device_driver, the normal probe/remove/shutdown/suspend/resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) callbacks, and as indicated that .match callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) The "SNDRV_CARDS" you see being passed in is a "unsigned int ndev"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) parameter, indicating how many devices to create and call our methods
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) with.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) The platform_driver callbacks are called with a platform_device param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) the isa_driver callbacks are being called with a ``struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) unsigned int id`` pair directly -- with the device creation completely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) internal to the bus it's much cleaner to not leak isa_dev's by passing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) them in at all. The id is the only thing we ever want other then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct device anyways, and it makes for nicer code in the callbacks as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) With this additional .match() callback ISA drivers have all options. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) ALSA would want to keep the old non-load behaviour, it could stick all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) of the old .probe in .match, which would only keep them registered after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) everything was found to be present and accounted for. If it wanted the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) behaviour of always loading as it inadvertently did for a bit after the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) changeover to platform devices, it could just not provide a .match() and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) do everything in .probe() as before.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) If it, as Takashi Iwai already suggested earlier as a way of following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) the model from saner buses more closely, wants to load when a later bind
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) could conceivably succeed, it could use .match() for the prerequisites
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) (such as checking the user wants the card enabled and that port/irq/dma
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) values have been passed in) and .probe() for everything else. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) the nicest model.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) To the code...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) This exports only two functions; isa_{,un}register_driver().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) isa_register_driver() register's the struct device_driver, and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) loops over the passed in ndev creating devices and registering them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) This causes the bus match method to be called for them, which is::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) int isa_bus_match(struct device *dev, struct device_driver *driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct isa_driver *isa_driver = to_isa_driver(driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (dev->platform_data == isa_driver) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (!isa_driver->match ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) isa_driver->match(dev, to_isa_dev(dev)->id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) dev->platform_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) The first thing this does is check if this device is in fact one of this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) driver's devices by seeing if the device's platform_data pointer is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) to this driver. Platform devices compare strings, but we don't need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) do that with everything being internal, so isa_register_driver() abuses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) dev->platform_data as a isa_driver pointer which we can then check here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) I believe platform_data is available for this, but if rather not, moving
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) the isa_driver pointer to the private struct isa_dev is ofcourse fine as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) Then, if the the driver did not provide a .match, it matches. If it did,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) the driver match() method is called to determine a match.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) If it did **not** match, dev->platform_data is reset to indicate this to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) isa_register_driver which can then unregister the device again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) If during all this, there's any error, or no devices matched at all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) everything is backed out again and the error, or -ENODEV, is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) isa_unregister_driver() just unregisters the matched devices and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) driver itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) module_isa_driver is a helper macro for ISA drivers which do not do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) anything special in module init/exit. This eliminates a lot of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) boilerplate code. Each module may only use this macro once, and calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) it replaces module_init and module_exit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) max_num_isa_dev is a macro to determine the maximum possible number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) ISA devices which may be registered in the I/O port address space given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) the address extent of the ISA devices.