4 * Abstracted from 3c509.c.
18 static void mcabus_remove ( struct root_device
*rootdev
);
24 * @ret rc Return status code
26 * Searches for a driver for the MCA device. If a driver is found,
27 * its probe() routine is called.
29 static int mca_probe ( struct mca_device
*mca
) {
30 struct mca_driver
*driver
;
31 struct mca_device_id
*id
;
35 DBG ( "Adding MCA slot %02x (ID %04x POS "
36 "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x)\n",
37 mca
->slot
, MCA_ID ( mca
),
38 mca
->pos
[0], mca
->pos
[1], mca
->pos
[2], mca
->pos
[3],
39 mca
->pos
[4], mca
->pos
[5], mca
->pos
[6], mca
->pos
[7] );
41 for_each_table_entry ( driver
, MCA_DRIVERS
) {
42 for ( i
= 0 ; i
< driver
->id_count
; i
++ ) {
44 if ( id
->id
!= MCA_ID ( mca
) )
47 mca
->driver_name
= id
->name
;
48 DBG ( "...using driver %s\n", mca
->driver_name
);
49 if ( ( rc
= driver
->probe ( mca
, id
) ) != 0 ) {
50 DBG ( "......probe failed\n" );
57 DBG ( "...no driver found\n" );
62 * Remove an MCA device
66 static void mca_remove ( struct mca_device
*mca
) {
67 mca
->driver
->remove ( mca
);
68 DBG ( "Removed MCA device %02x\n", mca
->slot
);
74 * @v rootdev MCA bus root device
76 * Scans the MCA bus for devices and registers all devices it can
79 static int mcabus_probe ( struct root_device
*rootdev
) {
80 struct mca_device
*mca
= NULL
;
86 for ( slot
= 0 ; slot
<= MCA_MAX_SLOT_NR
; slot
++ ) {
87 /* Allocate struct mca_device */
89 mca
= malloc ( sizeof ( *mca
) );
94 memset ( mca
, 0, sizeof ( *mca
) );
97 /* Make sure motherboard setup is off */
98 outb_p ( 0xff, MCA_MOTHERBOARD_SETUP_REG
);
100 /* Select the slot */
101 outb_p ( 0x8 | ( mca
->slot
& 0xf ), MCA_ADAPTER_SETUP_REG
);
103 /* Read the POS registers */
105 for ( i
= 0 ; i
< ( sizeof ( mca
->pos
) /
106 sizeof ( mca
->pos
[0] ) ) ; i
++ ) {
107 mca
->pos
[i
] = inb_p ( MCA_POS_REG ( i
) );
108 if ( mca
->pos
[i
] != 0xff )
112 /* Kill all setup modes */
113 outb_p ( 0, MCA_ADAPTER_SETUP_REG
);
115 /* If all POS registers are 0xff, this means there's no device
121 /* Add to device hierarchy */
122 snprintf ( mca
->dev
.name
, sizeof ( mca
->dev
.name
),
124 mca
->dev
.desc
.bus_type
= BUS_TYPE_MCA
;
125 mca
->dev
.desc
.vendor
= GENERIC_MCA_VENDOR
;
126 mca
->dev
.desc
.device
= MCA_ID ( mca
);
127 mca
->dev
.parent
= &rootdev
->dev
;
128 list_add ( &mca
->dev
.siblings
, &rootdev
->dev
.children
);
129 INIT_LIST_HEAD ( &mca
->dev
.children
);
131 /* Look for a driver */
132 if ( mca_probe ( mca
) == 0 ) {
133 /* mcadev registered, we can drop our ref */
136 /* Not registered; re-use struct */
137 list_del ( &mca
->dev
.siblings
);
146 mcabus_remove ( rootdev
);
151 * Remove MCA root bus
153 * @v rootdev MCA bus root device
155 static void mcabus_remove ( struct root_device
*rootdev
) {
156 struct mca_device
*mca
;
157 struct mca_device
*tmp
;
159 list_for_each_entry_safe ( mca
, tmp
, &rootdev
->dev
.children
,
162 list_del ( &mca
->dev
.siblings
);
167 /** MCA bus root device driver */
168 static struct root_driver mca_root_driver
= {
169 .probe
= mcabus_probe
,
170 .remove
= mcabus_remove
,
173 /** MCA bus root device */
174 struct root_device mca_root_device __root_device
= {
175 .dev
= { .name
= "MCA" },
176 .driver
= &mca_root_driver
,