--- trunk/src/device.c 2007/10/08 16:19:16 19 +++ trunk/src/device.c 2007/10/08 16:19:23 20 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: device.c,v 1.16 2005/08/10 22:25:50 debug Exp $ + * $Id: device.c,v 1.20 2005/11/22 16:26:35 debug Exp $ * * Device registry framework. */ @@ -35,6 +35,7 @@ #include #include "device.h" +#include "memory.h" #include "misc.h" @@ -43,6 +44,9 @@ static int n_device_entries = 0; static int device_exit_on_error = 1; +static struct pci_entry *pci_entries = NULL; +static int n_pci_entries = 0; + /* * device_entry_compar(): @@ -105,6 +109,57 @@ /* + * pci_register(): + * + * Registers a pci device. The pci device is added to the pci_entries array. + * + * Return value is 1 if the pci device was registered. If it was not + * added, this function does not return. + */ +int pci_register(char *name, void (*initf)(struct machine *, struct memory *, + struct pci_device *)) +{ + pci_entries = realloc(pci_entries, sizeof(struct pci_entry) + * (n_pci_entries + 1)); + if (pci_entries == NULL) { + fprintf(stderr, "pci_register(): out of memory\n"); + exit(1); + } + + memset(&pci_entries[n_pci_entries], 0, sizeof(struct pci_entry)); + + pci_entries[n_pci_entries].name = strdup(name); + pci_entries[n_pci_entries].initf = initf; + n_pci_entries ++; + return 1; +} + + +/* + * pci_lookup_initf(): + * + * Find a pci device init function by scanning the pci_entries array. + * + * Return value is a function pointer, or NULL if the name was not found. + */ +void (*pci_lookup_initf(char *name))(struct machine *machine, + struct memory *mem, struct pci_device *pd) +{ + int i; + + if (name == NULL) { + fprintf(stderr, "pci_lookup_initf(): name = NULL\n"); + exit(1); + } + + for (i=0; i= n_device_entries) - i = n_device_entries - 1; + while (lo <= hi) { + int r, i = (lo + hi) / 2; - /* printf("device_lookup(): i=%i step=%i\n", i, step); + /* printf("device_lookup(): i=%i (lo=%i hi=%i)\n", i, lo, hi); printf(" name='%s', '%s'\n", name, device_entries[i].name); */ r = strcmp(name, device_entries[i].name); - - if (r < 0) { - /* Go left: */ - i -= step; - if (step == 0) - i --; - } else if (r > 0) { - /* Go right: */ - i += step; - if (step == 0) - i ++; - } else { + if (r == 0) { /* Found it! */ return &device_entries[i]; } - if (do_return) - return NULL; - - if (step == 0) - do_return = 1; - - if (step & 1) - step = (step/2) + 1; - else - step /= 2; + /* Try left or right half: */ + if (r < 0) + hi = i - 1; + if (r > 0) + lo = i + 1; } + + return NULL; } @@ -285,10 +322,22 @@ if (strncmp(s2, "addr=", 5) == 0) { devinit.addr = mystrtoull(s3, NULL, 0); + } else if (strncmp(s2, "addr2=", 6) == 0) { + devinit.addr2 = mystrtoull(s3, NULL, 0); } else if (strncmp(s2, "len=", 4) == 0) { devinit.len = mystrtoull(s3, NULL, 0); } else if (strncmp(s2, "addr_mult=", 10) == 0) { devinit.addr_mult = mystrtoull(s3, NULL, 0); + } else if (strncmp(s2, "pci_little_endian=", 18) == 0) { + devinit.pci_little_endian = mystrtoull(s3, NULL, 0); + switch (devinit.pci_little_endian) { + case 0: break; + case 1: devinit.pci_little_endian = + MEM_PCI_LITTLE_ENDIAN; + break; + default:fatal("Bad pci_little_endian value.\n"); + exit(1); + } } else if (strncmp(s2, "irq=", 4) == 0) { devinit.irq_nr = mystrtoull(s3, NULL, 0); } else if (strncmp(s2, "in_use=", 7) == 0) {