iPXE
mca.c File Reference
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ipxe/io.h>
#include <ipxe/mca.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (BSD2)
static void mcabus_remove (struct root_device *rootdev)
 Remove MCA root bus.
static int mca_probe (struct mca_device *mca)
 Probe an MCA device.
static void mca_remove (struct mca_device *mca)
 Remove an MCA device.
static int mcabus_probe (struct root_device *rootdev)
 Probe MCA root bus.

Variables

static struct root_driver mca_root_driver
 MCA bus root device driver.
struct root_device mca_root_device __root_device
 MCA bus root device.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( BSD2 )

◆ mcabus_remove()

void mcabus_remove ( struct root_device * rootdev)
static

Remove MCA root bus.

Parameters
rootdevMCA bus root device

Definition at line 155 of file mca.c.

155 {
156 struct mca_device *mca;
157 struct mca_device *tmp;
158
159 list_for_each_entry_safe ( mca, tmp, &rootdev->dev.children,
160 dev.siblings ) {
161 mca_remove ( mca );
162 list_del ( &mca->dev.siblings );
163 free ( mca );
164 }
165}
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
static void mca_remove(struct mca_device *mca)
Remove an MCA device.
Definition mca.c:66
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
struct list_head children
Devices attached to this device.
Definition device.h:87
struct list_head siblings
Devices on the same bus.
Definition device.h:85
An MCA device.
Definition mca.h:38
struct device dev
Generic device.
Definition mca.h:40
struct device dev
Device chain.
Definition device.h:103

References device::children, mca_device::dev, root_device::dev, free, list_del, list_for_each_entry_safe, mca_remove(), device::siblings, and tmp.

Referenced by mcabus_probe().

◆ mca_probe()

int mca_probe ( struct mca_device * mca)
static

Probe an MCA device.

Parameters
mcaMCA device
Return values
rcReturn status code

Searches for a driver for the MCA device. If a driver is found, its probe() routine is called.

Definition at line 29 of file mca.c.

29 {
30 struct mca_driver *driver;
31 struct mca_device_id *id;
32 unsigned int i;
33 int rc;
34
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] );
40
42 for ( i = 0 ; i < driver->id_count ; i++ ) {
43 id = &driver->ids[i];
44 if ( id->id != MCA_ID ( mca ) )
45 continue;
46 mca->driver = driver;
47 mca->dev.driver_name = id->name;
48 DBG ( "...using driver %s\n", mca->dev.driver_name );
49 if ( ( rc = driver->probe ( mca, id ) ) != 0 ) {
50 DBG ( "......probe failed\n" );
51 continue;
52 }
53 return 0;
54 }
55 }
56
57 DBG ( "...no driver found\n" );
58 return -ENOTTY;
59}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
uint8_t id
Request identifier.
Definition ena.h:1
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:595
#define MCA_DRIVERS
MCA driver table.
Definition mca.h:81
#define MCA_ID(mca)
Definition mca.h:55
const char * driver_name
Driver name.
Definition device.h:81
An MCA device ID list entry.
Definition mca.h:30
unsigned char pos[8]
POS register values.
Definition mca.h:44
unsigned int slot
Slot number.
Definition mca.h:42
struct mca_driver * driver
Driver for this device.
Definition mca.h:46
An MCA driver.
Definition mca.h:58
struct mca_device_id * ids
MCA ID table.
Definition mca.h:60
int(* probe)(struct mca_device *mca, const struct mca_device_id *id)
Probe device.
Definition mca.h:70
unsigned int id_count
Number of entries in MCA ID table.
Definition mca.h:62
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386

References DBG, mca_device::dev, mca_device::driver, device::driver_name, ENOTTY, for_each_table_entry, id, mca_driver::id_count, mca_driver::ids, MCA_DRIVERS, MCA_ID, mca_device::pos, mca_driver::probe, rc, and mca_device::slot.

Referenced by mcabus_probe().

◆ mca_remove()

void mca_remove ( struct mca_device * mca)
static

Remove an MCA device.

Parameters
mcaMCA device

Definition at line 66 of file mca.c.

66 {
67 mca->driver->remove ( mca );
68 DBG ( "Removed MCA device %02x\n", mca->slot );
69}
void(* remove)(struct mca_device *mca)
Remove device.
Definition mca.h:77

References DBG, mca_device::driver, mca_driver::remove, and mca_device::slot.

Referenced by mcabus_remove().

◆ mcabus_probe()

int mcabus_probe ( struct root_device * rootdev)
static

Probe MCA root bus.

Parameters
rootdevMCA bus root device

Scans the MCA bus for devices and registers all devices it can find.

Definition at line 79 of file mca.c.

79 {
80 struct mca_device *mca = NULL;
81 unsigned int slot;
82 int seen_non_ff;
83 unsigned int i;
84 int rc;
85
86 for ( slot = 0 ; slot <= MCA_MAX_SLOT_NR ; slot++ ) {
87 /* Allocate struct mca_device */
88 if ( ! mca )
89 mca = malloc ( sizeof ( *mca ) );
90 if ( ! mca ) {
91 rc = -ENOMEM;
92 goto err;
93 }
94 memset ( mca, 0, sizeof ( *mca ) );
95 mca->slot = slot;
96
97 /* Make sure motherboard setup is off */
99
100 /* Select the slot */
101 outb_p ( 0x8 | ( mca->slot & 0xf ), MCA_ADAPTER_SETUP_REG );
102
103 /* Read the POS registers */
104 seen_non_ff = 0;
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 )
109 seen_non_ff = 1;
110 }
111
112 /* Kill all setup modes */
114
115 /* If all POS registers are 0xff, this means there's no device
116 * present
117 */
118 if ( ! seen_non_ff )
119 continue;
120
121 /* Add to device hierarchy */
122 snprintf ( mca->dev.name, sizeof ( mca->dev.name ),
123 "MCA%02x", slot );
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 );
130
131 /* Look for a driver */
132 if ( mca_probe ( mca ) == 0 ) {
133 /* mcadev registered, we can drop our ref */
134 mca = NULL;
135 } else {
136 /* Not registered; re-use struct */
137 list_del ( &mca->dev.siblings );
138 }
139 }
140
141 free ( mca );
142 return 0;
143
144 err:
145 free ( mca );
146 mcabus_remove ( rootdev );
147 return rc;
148}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define BUS_TYPE_MCA
MCA bus type.
Definition device.h:53
uint8_t slot
Slot.
Definition edd.h:3
#define ENOMEM
Not enough space.
Definition errno.h:535
#define inb_p(io_addr)
Read byte from I/O-mapped device.
Definition io.h:486
#define outb_p(data, io_addr)
Write byte to I/O-mapped device, slowly.
Definition io.h:522
void * memset(void *dest, int character, size_t len) __nonnull
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
static void mcabus_remove(struct root_device *rootdev)
Remove MCA root bus.
Definition mca.c:155
static int mca_probe(struct mca_device *mca)
Probe an MCA device.
Definition mca.c:29
#define MCA_ADAPTER_SETUP_REG
Definition mca.h:22
#define GENERIC_MCA_VENDOR
Definition mca.h:27
#define MCA_MAX_SLOT_NR
Definition mca.h:23
#define MCA_MOTHERBOARD_SETUP_REG
Definition mca.h:21
#define MCA_POS_REG(n)
Definition mca.h:24
unsigned int bus_type
Bus type.
Definition device.h:25
unsigned int device
Device ID.
Definition device.h:34
unsigned int vendor
Vendor ID.
Definition device.h:32
struct device_description desc
Device description.
Definition device.h:83
struct device * parent
Bus device.
Definition device.h:89
char name[40]
Name.
Definition device.h:79
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383

References device_description::bus_type, BUS_TYPE_MCA, device::children, device::desc, mca_device::dev, root_device::dev, device_description::device, ENOMEM, free, GENERIC_MCA_VENDOR, inb_p, INIT_LIST_HEAD, list_add, list_del, malloc(), MCA_ADAPTER_SETUP_REG, MCA_ID, MCA_MAX_SLOT_NR, MCA_MOTHERBOARD_SETUP_REG, MCA_POS_REG, mca_probe(), mcabus_remove(), memset(), device::name, NULL, outb_p, device::parent, mca_device::pos, rc, device::siblings, mca_device::slot, slot, snprintf(), and device_description::vendor.

Variable Documentation

◆ mca_root_driver

struct root_driver mca_root_driver
static
Initial value:
= {
.probe = mcabus_probe,
.remove = mcabus_remove,
}
static int mcabus_probe(struct root_device *rootdev)
Probe MCA root bus.
Definition mca.c:79

MCA bus root device driver.

Definition at line 168 of file mca.c.

168 {
169 .probe = mcabus_probe,
170 .remove = mcabus_remove,
171};

◆ __root_device

struct root_device mca_root_device __root_device
Initial value:
= {
.dev = { .name = "MCA" },
.driver = &mca_root_driver,
}
static struct root_driver mca_root_driver
MCA bus root device driver.
Definition mca.c:168

MCA bus root device.

Definition at line 174 of file mca.c.

174 {
175 .dev = { .name = "MCA" },
176 .driver = &mca_root_driver,
177};