2 * EISA bus support functions for sysfs.
4 * (C) 2002 Marc Zyngier <maz@wild-wind.fr.eu.org>
6 * This code is released under the GPL version 2.
9 #include <linux/kernel.h>
10 #include <linux/device.h>
11 #include <linux/eisa.h>
12 #include <linux/module.h>
13 #include <linux/init.h>
14 #include <linux/slab.h>
15 #include <linux/ioport.h>
18 #define EISA_DEVINFO(i,s) { .id = { .sig = i }, .name = s }
20 struct eisa_device_info
{
21 struct eisa_device_id id
;
22 char name
[DEVICE_NAME_SIZE
];
25 struct eisa_device_info __initdata eisa_table
[] = {
26 #ifdef CONFIG_EISA_NAMES
31 #define EISA_INFOS (sizeof (eisa_table) / (sizeof (struct eisa_device_info)))
33 static void __init
eisa_name_device (struct eisa_device
*edev
)
37 for (i
= 0; i
< EISA_INFOS
; i
++) {
38 if (!strcmp (edev
->id
.sig
, eisa_table
[i
].id
.sig
)) {
39 strncpy (edev
->dev
.name
,
41 DEVICE_NAME_SIZE
- 1);
46 /* No name was found */
47 sprintf (edev
->dev
.name
, "EISA device %.7s", edev
->id
.sig
);
50 static char __init
*decode_eisa_sig(unsigned long addr
)
52 static char sig_str
[EISA_SIG_LEN
];
62 for (i
= 1; i
< 4; i
++)
63 sig
[i
] = inb (addr
+ i
);
65 sig_str
[0] = ((sig
[0] >> 2) & 0x1f) + ('A' - 1);
66 sig_str
[1] = (((sig
[0] & 3) << 3) | (sig
[1] >> 5)) + ('A' - 1);
67 sig_str
[2] = (sig
[1] & 0x1f) + ('A' - 1);
68 rev
= (sig
[2] << 8) | sig
[3];
69 sprintf(sig_str
+ 3, "%04X", rev
);
74 static int eisa_bus_match (struct device
*dev
, struct device_driver
*drv
)
76 struct eisa_device
*edev
= to_eisa_device (dev
);
77 struct eisa_driver
*edrv
= to_eisa_driver (drv
);
78 const struct eisa_device_id
*eids
= edrv
->id_table
;
83 while (strlen (eids
->sig
)) {
84 if (!strcmp (eids
->sig
, edev
->id
.sig
))
93 struct bus_type eisa_bus_type
= {
95 .match
= eisa_bus_match
,
98 /* The default EISA device parent (virtual root device). */
99 static struct device eisa_bus_root
= {
100 .name
= "EISA Bridge",
104 int eisa_driver_register (struct eisa_driver
*edrv
)
108 edrv
->driver
.bus
= &eisa_bus_type
;
109 if ((r
= driver_register (&edrv
->driver
)) < 0)
115 void eisa_driver_unregister (struct eisa_driver
*edrv
)
117 driver_unregister (&edrv
->driver
);
120 static ssize_t
eisa_show_sig (struct device
*dev
, char *buf
)
122 struct eisa_device
*edev
= to_eisa_device (dev
);
123 return sprintf (buf
,"%s\n", edev
->id
.sig
);
126 static DEVICE_ATTR(signature
, S_IRUGO
, eisa_show_sig
, NULL
);
128 static void __init
eisa_register_device (char *sig
, int slot
)
130 struct eisa_device
*edev
;
132 if (!(edev
= kmalloc (sizeof (*edev
), GFP_KERNEL
)))
135 memset (edev
, 0, sizeof (*edev
));
136 memcpy (edev
->id
.sig
, sig
, 7);
138 edev
->base_addr
= 0x1000 * slot
;
139 eisa_name_device (edev
);
140 edev
->dev
.parent
= &eisa_bus_root
;
141 edev
->dev
.bus
= &eisa_bus_type
;
142 sprintf (edev
->dev
.bus_id
, "00:%02X", slot
);
144 /* Don't register resource for slot 0, since this will surely
148 edev
->res
.name
= edev
->dev
.name
;
149 edev
->res
.start
= edev
->base_addr
;
150 edev
->res
.end
= edev
->res
.start
+ 0xfff;
151 edev
->res
.flags
= IORESOURCE_IO
;
153 if (request_resource (&ioport_resource
, &edev
->res
)) {
154 printk (KERN_WARNING \
155 "Cannot allocate resource for EISA slot %d\n",
162 if (device_register (&edev
->dev
)) {
167 device_create_file (&edev
->dev
, &dev_attr_signature
);
170 static int __init
eisa_probe (void)
174 unsigned long slot_addr
;
176 printk (KERN_INFO
"EISA: Probing bus...\n");
177 for (c
= 0, i
= 0; i
<= EISA_MAX_SLOTS
; i
++) {
178 slot_addr
= (0x1000 * i
) + EISA_VENDOR_ID_OFFSET
;
179 if ((str
= decode_eisa_sig (slot_addr
))) {
181 printk (KERN_INFO
"EISA: Motherboard %s detected\n",
184 printk (KERN_INFO
"EISA: slot %d : %s detected.\n",
190 eisa_register_device (str
, i
);
193 printk (KERN_INFO
"EISA: Detected %d card%s.\n", c
, c
< 2 ? "" : "s");
198 static int __init
eisa_init (void)
202 if ((r
= bus_register (&eisa_bus_type
)))
205 if ((r
= device_register (&eisa_bus_root
))) {
206 bus_unregister (&eisa_bus_type
);
210 printk (KERN_INFO
"EISA bus registered\n");
211 return eisa_probe ();
214 postcore_initcall (eisa_init
);
216 EXPORT_SYMBOL (eisa_bus_type
);
217 EXPORT_SYMBOL (eisa_driver_register
);
218 EXPORT_SYMBOL (eisa_driver_unregister
);