summaryrefslogtreecommitdiff
path: root/libddekit
diff options
context:
space:
mode:
authorZheng Da <zhengda1936@gmail.com>2010-01-26 08:54:41 +0100
committerZheng Da <zhengda1936@gmail.com>2010-01-26 08:54:41 +0100
commited60ecf7abdade8ee7b63f7621b3920ca9c42912 (patch)
treea31265588de7b534a21e69d682d5e12aee68a07e /libddekit
parentd3d72c7fc48e54f9da4ebcfa57f5949b18f5d717 (diff)
ddekit: support multiple pci buses in the system.
Diffstat (limited to 'libddekit')
-rw-r--r--libddekit/pci.c106
1 files changed, 65 insertions, 41 deletions
diff --git a/libddekit/pci.c b/libddekit/pci.c
index 5c0c0ae2..ca16b6f9 100644
--- a/libddekit/pci.c
+++ b/libddekit/pci.c
@@ -1,5 +1,6 @@
#include <stdlib.h>
#include <error.h>
+#include <string.h>
#include <pciaccess.h>
#include "ddekit/assert.h"
@@ -9,22 +10,26 @@
#define dbg_this 0
-#define MAX_PCI_DEVS 32
-
/** PCI descriptor */
typedef struct ddekit_pci_dev {
- int bus; /**< bus ID */
- int slot; /**< slot ID */
- int func; /**< function */
struct pci_device *dev;
- struct ddekit_pci_dev *next; /**< chaining info */
} ddekit_pci_dev_t;
-static ddekit_pci_dev_t ddekit_pci_bus[MAX_PCI_DEVS];
+typedef struct ddekit_pci_bus {
+ struct {
+ ddekit_pci_dev_t funs[8];
+ } devs[32];
+} ddekit_pci_bus_t;
+
+#define MAX_NUM_BUSES 256
+
+static int num_pci_devs;
+static ddekit_pci_dev_t *ddekit_pci_devs;
+static ddekit_pci_bus_t *ddekit_pci_buses[MAX_NUM_BUSES];
static inline int invalid_device(ddekit_pci_dev_t *d)
{
- return d->slot == -1;
+ return d->dev == NULL;
}
@@ -37,7 +42,6 @@ static inline int invalid_device(ddekit_pci_dev_t *d)
void ddekit_pci_init(void)
{
int slots_found = 0;
- int i;
int err;
struct pci_device *pci_dev;
struct pci_device_iterator *dev_iter;
@@ -46,25 +50,35 @@ void ddekit_pci_init(void)
if (err)
error (2, err, "pci_system_init");
- /* Init device list */
- for (i = 0; i < MAX_PCI_DEVS; i++)
- ddekit_pci_bus[i].slot = -1;
-
+ num_pci_devs = 32;
+ ddekit_pci_devs = malloc (sizeof (ddekit_pci_devs[0]) * num_pci_devs);
+ memset (ddekit_pci_devs, 0,
+ sizeof (ddekit_pci_devs[0]) * num_pci_devs);
dev_iter = pci_slot_match_iterator_create (NULL);
while ((pci_dev = pci_device_next (dev_iter)) != NULL) {
- if (slots_found == MAX_PCI_DEVS) {
- ddekit_printf ("find more than %d pci devices",
- slots_found);
- break;
+ /* store the device in the structured array. */
+ if (ddekit_pci_buses[pci_dev->bus] == NULL) {
+ ddekit_pci_buses[pci_dev->bus] = calloc (1, sizeof (**ddekit_pci_buses));
+ assert(ddekit_pci_buses[pci_dev->bus] != NULL);
}
- /* Pretend all our devices are chained to exactly one bus. */
- ddekit_pci_bus[slots_found].bus = 0; /*l4dev.bus;*/
- ddekit_pci_bus[slots_found].slot = slots_found;
- ddekit_pci_bus[slots_found].func = 0;
- ddekit_pci_bus[slots_found].dev = pci_dev;
-
+ ddekit_pci_buses[pci_dev->bus]->devs[pci_dev->dev].funs[pci_dev->func].dev = pci_dev;
+
+ /* We also put the device in the flat array.
+ * The array is increased dynamically. */
+ if (slots_found >= num_pci_devs) {
+ num_pci_devs *= 2;
+ ddekit_pci_devs = realloc (ddekit_pci_devs,
+ sizeof (ddekit_pci_devs[0])
+ * num_pci_devs);
+ assert (ddekit_pci_devs != NULL);
+ memset (&ddekit_pci_devs[slots_found], 0,
+ (num_pci_devs - slots_found)
+ * sizeof (ddekit_pci_devs[0]));
+ }
+ ddekit_pci_devs[slots_found].dev = pci_dev;
++slots_found;
}
+ num_pci_devs = slots_found;
pci_iterator_destroy (dev_iter);
}
@@ -80,11 +94,12 @@ int ddekit_pci_get_device(int nr, int *bus, int *slot, int *func)
ddekit_printf ("searching for dev #%d", nr);
- if (nr >= 0 && nr < MAX_PCI_DEVS && !invalid_device(&ddekit_pci_bus[nr])) {
- dev = &ddekit_pci_bus[nr];
- *bus = dev->bus;
- *slot = dev->slot;
- *func = dev->func;
+ if (nr >= 0 && nr < num_pci_devs
+ && !invalid_device(&ddekit_pci_devs[nr])) {
+ dev = &ddekit_pci_devs[nr];
+ *bus = dev->dev->bus;
+ *slot = dev->dev->dev;
+ *func = dev->dev->func;
return 0;
}
@@ -99,19 +114,17 @@ ddekit_pci_dev_t *ddekit_pci_find_device(int *bus, int *slot, int *func,
Assert(slot);
Assert(func);
- ddekit_printf ("start %p (slot %d)",
- start, start ? start->slot : -1);
- int idx = start ? start->slot + 1 : 0;
+ int idx = start ? start->dev->dev + 1 : 0;
- for ( ; idx < MAX_PCI_DEVS; ++idx) {
- ddekit_pci_dev_t *dev = &ddekit_pci_bus[idx];
+ for ( ; idx < num_pci_devs; ++idx) {
+ ddekit_pci_dev_t *dev = &ddekit_pci_devs[idx];
if (!invalid_device(dev) &&
- (*bus == DDEKIT_PCI_ANY_ID || dev->bus == *bus) &&
- (*slot == DDEKIT_PCI_ANY_ID || dev->slot == *slot) &&
- (*func == DDEKIT_PCI_ANY_ID || dev->func == *func)) {
- *bus = dev->bus;
- *slot = dev->slot;
- *func = dev->func;
+ (*bus == DDEKIT_PCI_ANY_ID || dev->dev->bus == *bus) &&
+ (*slot == DDEKIT_PCI_ANY_ID || dev->dev->dev == *slot) &&
+ (*func == DDEKIT_PCI_ANY_ID || dev->dev->func == *func)) {
+ *bus = dev->dev->bus;
+ *slot = dev->dev->dev;
+ *func = dev->dev->func;
return dev;
}
}
@@ -160,7 +173,16 @@ int ddekit_pci_write(int bus, int slot, int func, int pos, int len, ddekit_uint3
*/
static inline ddekit_pci_dev_t *ddekit_pci_find_device_fixed(int bus, int slot, int func)
{
- return &ddekit_pci_bus[slot];
+ ddekit_pci_dev_t *dev;
+
+ /* If the bus doesn't exist. */
+ if (ddekit_pci_buses[bus] == NULL)
+ return NULL;
+
+ dev = &ddekit_pci_buses[bus]->devs[slot].funs[func];
+ if (dev && dev->dev)
+ return dev;
+ return NULL;
}
@@ -187,8 +209,10 @@ int ddekit_pci_readw (int bus, int slot, int func, int pos, ddekit_uint16_t *val
int ddekit_pci_readl (int bus, int slot, int func, int pos, ddekit_uint32_t *val)
{
ddekit_pci_dev_t *dev = ddekit_pci_find_device_fixed(bus, slot, func);
- if (dev)
+ if (dev) {
+ assert (dev->dev != NULL);
return pci_device_cfg_read_u32 (dev->dev, val, pos);
+ }
else
return -1;
}