Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) ================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) EISA bus support
^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) :Author: Marc Zyngier <maz@wild-wind.fr.eu.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) This document groups random notes about porting EISA drivers to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) new EISA/sysfs API.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) Starting from version 2.5.59, the EISA bus is almost given the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) status as other much more mainstream busses such as PCI or USB. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) has been possible through sysfs, which defines a nice enough set of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) abstractions to manage busses, devices and drivers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) Although the new API is quite simple to use, converting existing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) drivers to the new infrastructure is not an easy task (mostly because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) detection code is generally also used to probe ISA cards). Moreover,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) most EISA drivers are among the oldest Linux drivers so, as you can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) imagine, some dust has settled here over the years.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) The EISA infrastructure is made up of three parts:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)     - The bus code implements most of the generic code. It is shared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)       among all the architectures that the EISA code runs on. It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)       implements bus probing (detecting EISA cards available on the bus),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)       allocates I/O resources, allows fancy naming through sysfs, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)       offers interfaces for driver to register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)     - The bus root driver implements the glue between the bus hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)       and the generic bus code. It is responsible for discovering the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)       device implementing the bus, and setting it up to be latter probed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)       by the bus code. This can go from something as simple as reserving
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)       an I/O region on x86, to the rather more complex, like the hppa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)       EISA code. This is the part to implement in order to have EISA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)       running on an "new" platform.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)     - The driver offers the bus a list of devices that it manages, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)       implements the necessary callbacks to probe and release devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)       whenever told to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) Every function/structure below lives in <linux/eisa.h>, which depends
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) heavily on <linux/device.h>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) Bus root driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) ===============
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	int eisa_root_register (struct eisa_root_device *root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) The eisa_root_register function is used to declare a device as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) root of an EISA bus. The eisa_root_device structure holds a reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) to this device, as well as some parameters for probing purposes::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	struct eisa_root_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		struct device   *dev;	 /* Pointer to bridge device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		unsigned long    bus_base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		int		 slots;  /* Max slot number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		int		 force_probe; /* Probe even when no slot 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		u64		 dma_mask; /* from bridge device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		int              bus_nr; /* Set by eisa_root_register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		struct resource  eisa_root_res;	/* ditto */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) ============= ======================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) node          used for eisa_root_register internal purpose
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) dev           pointer to the root device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) res           root device I/O resource
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) bus_base_addr slot 0 address on this bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) slots	      max slot number to probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) force_probe   Probe even when slot 0 is empty (no EISA mainboard)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) dma_mask      Default DMA mask. Usually the bridge device dma_mask.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) bus_nr	      unique bus id, set by eisa_root_register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) ============= ======================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) ======
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	int eisa_driver_register (struct eisa_driver *edrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	void eisa_driver_unregister (struct eisa_driver *edrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) Clear enough ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	struct eisa_device_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		char sig[EISA_SIG_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		unsigned long driver_data;
^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) 	struct eisa_driver {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		const struct eisa_device_id *id_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		struct device_driver         driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) =============== ====================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) id_table	an array of NULL terminated EISA id strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		followed by an empty string. Each string can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		optionally be paired with a driver-dependent value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		(driver_data).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) driver		a generic driver, such as described in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		Documentation/driver-api/driver-model/driver.rst. Only .name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		.probe and .remove members are mandatory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) =============== ====================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) An example is the 3c59x driver::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	static struct eisa_device_id vortex_eisa_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		{ "TCM5920", EISA_3C592_OFFSET },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		{ "TCM5970", EISA_3C597_OFFSET },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		{ "" }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	static struct eisa_driver vortex_eisa_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		.id_table = vortex_eisa_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		.driver   = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 			.name    = "3c59x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 			.probe   = vortex_eisa_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 			.remove  = vortex_eisa_remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) Device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) ======
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) The sysfs framework calls .probe and .remove functions upon device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) discovery and removal (note that the .remove function is only called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) when driver is built as a module).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) Both functions are passed a pointer to a 'struct device', which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) encapsulated in a 'struct eisa_device' described as follows::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	struct eisa_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		struct eisa_device_id id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		int                   slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		int                   state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		unsigned long         base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		struct resource       res[EISA_MAX_RESOURCES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		u64                   dma_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		struct device         dev; /* generic device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ======== ============================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) id	 EISA id, as read from device. id.driver_data is set from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	 matching driver EISA id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) slot	 slot number which the device was detected on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) state    set of flags indicating the state of the device. Current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	 flags are EISA_CONFIG_ENABLED and EISA_CONFIG_FORCED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) res	 set of four 256 bytes I/O regions allocated to this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) dma_mask DMA mask set from the parent device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) dev	 generic device (see Documentation/driver-api/driver-model/device.rst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ======== ============================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) You can get the 'struct eisa_device' from 'struct device' using the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 'to_eisa_device' macro.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) Misc stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ==========
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	void eisa_set_drvdata (struct eisa_device *edev, void *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) Stores data into the device's driver_data area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	void *eisa_get_drvdata (struct eisa_device *edev):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) Gets the pointer previously stored into the device's driver_data area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	int eisa_get_region_index (void *addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) Returns the region number (0 <= x < EISA_MAX_RESOURCES) of a given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) Kernel parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) =================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) eisa_bus.enable_dev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	A comma-separated list of slots to be enabled, even if the firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	set the card as disabled. The driver must be able to properly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	initialize the device in such conditions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) eisa_bus.disable_dev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	A comma-separated list of slots to be enabled, even if the firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	set the card as enabled. The driver won't be called to handle this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) virtual_root.force_probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	Force the probing code to probe EISA slots even when it cannot find an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	EISA compliant mainboard (nothing appears on slot 0). Defaults to 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	(don't force), and set to 1 (force probing) when either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	CONFIG_ALPHA_JENSEN or CONFIG_EISA_VLB_PRIMING are set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) Random notes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ============
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) Converting an EISA driver to the new API mostly involves *deleting*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) code (since probing is now in the core EISA code). Unfortunately, most
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) drivers share their probing routine between ISA, and EISA. Special
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) care must be taken when ripping out the EISA code, so other busses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) won't suffer from these surgical strikes...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) You *must not* expect any EISA device to be detected when returning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) from eisa_driver_register, since the chances are that the bus has not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) yet been probed. In fact, that's what happens most of the time (the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) bus root driver usually kicks in rather late in the boot process).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) Unfortunately, most drivers are doing the probing by themselves, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) expect to have explored the whole machine when they exit their probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) For example, switching your favorite EISA SCSI card to the "hotplug"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) model is "the right thing"(tm).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) Thanks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ======
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) I'd like to thank the following people for their help:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) - Xavier Benigni for lending me a wonderful Alpha Jensen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) - James Bottomley, Jeff Garzik for getting this stuff into the kernel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) - Andries Brouwer for contributing numerous EISA ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) - Catrin Jones for coping with far too many machines at home.