[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

hardware detection using libpci



Ive been thinking about hardware detection. I think hardware detection
should be a dependency on the fetch method it applies to.

e.g. the http/ftp/nfs retriever should depend on network and modem
hardware detection.

This way, if a network retriever is to be used, the hardware detection
component of it should have already detected the relevent hardware and
determined what kernel modules are needed to support it.

Say for example im using a weirdo network card that isnt support on the
boot disk due to space constraints,
 and that i want to do a net install, if i can detect what kernel
modules i need then i can use another fetch method (.e.g. floppy
retriever) to fetch that kernel module. 

Splitting detection up like this seems to me to be the most space
efficient way of doing it as well. 

Yesterday i started hacking together a small program that uses libpci to
detect the required ethernet kernel modules, it is attached.

Its really only serves as a demonstration at the moment to get some
feedback,

Its limitations;
1) It only detectes hardware for the following modules, 3c59x.o rtl8139,
ne2k-pci. Its fairly simple to add support for other modules, just a
matter of doing it, no thinking involved.
2) Its obviously limited to PCI devices, seperate programs will have to
be used for ISAPNP, PCMCIA etc

Its good points;
1) its small, looks like that with libdetect the hardware list is a
significant proportion os its total size, ive just ignore things like
the cards name, just care about the card PCI id and the kernel module
that it needs. Focusing on detecting the hardware required for specific
kernel modules, rather than detcting evberything and then mapping it to
kernel modules should make it more modular and smaller.

2) libpci is from pci-utilities, its fairly portable, can either use
/proc to get pci ids or probe hardware directly, the later making it
portable to other OS's

What do you think?


Glenn
/*
 *
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "pci.h"

typedef struct pci_ids_s {
	u32 vendor;
	u32 device;
} pci_ids_t;

typedef struct module_list_s {
	char *name;
	pci_ids_t *id;	
} module_list_t;

pci_ids_t com3_pci_ids[] = {
	{ 0x10b7, 0x5900 },
        { 0x10b7, 0x5950 },
        { 0x10b7, 0x5951 },
        { 0x10b7, 0x5952 },
        { 0x10b7, 0x9000 },
        { 0x10b7, 0x9001 },
        { 0x10b7, 0x9004 },
        { 0x10b7, 0x9005 },
        { 0x10b7, 0x9006 },
        { 0x10b7, 0x900a },
        { 0x10b7, 0x9050 },
        { 0x10b7, 0x9051 },
        { 0x10b7, 0x9055 },
        { 0x10b7, 0x9058 },
        { 0x10b7, 0x905a },
	{ 0x10b7, 0x9200 },
	{ 0x10b7, 0x9800 },
	{ 0x10b7, 0x7646 },
	{ 0x10b7, 0x5055 },
	{ 0x10b7, 0x6055 },
	{ 0x10b7, 0x5057 },
	{ 0x10b7, 0x5157 },
	{ 0x10b7, 0x5257 },
	{ 0x10b7, 0x6560 },
	{ 0x10b7, 0x6562 },
	{ 0x10b7, 0x6564 },
	{ 0x10b7, 0x4500 },
	{ 0, 0 }
};

pci_ids_t rtl8139_pci_ids[] = {
	{ 0x10ec, 0x8129 },
	{ 0x10ec, 0x8138 },
	{ 0x10ec, 0x8139 },
	{ 0x1113, 0x1211 },
	{ 0, 0 }
};

pci_ids_t ne2k_pci_ids[] = { 
	{ 0x10ec, 0x8029 },
	{ 0x1050, 0x0940 },
	{ 0x1050, 0x5a5a },
	{ 0x8e2e, 0x3000 },
	{ 0x4a14, 0x5000 },
	{ 0x1106, 0x0926 },
	{ 0x10bd, 0x0e34 },
	{ 0x12c3, 0x0058 },
	{ 0x12c3, 0x5598 },
	{ 0, 0 }
};

static module_list_t net_list[] = {
        { "3c59x", com3_pci_ids },
	{ "rtl8139", rtl8139_pci_ids },
	{ "ne2k-pci", ne2k_pci_ids }, 
};

int find_module(struct pci_dev *dev, module_list_t *module_list)
{
	int i=0, j;

	while (module_list[i].name != NULL) { 
		j=0;
		while (module_list[i].id[j].vendor != 0) {
			if ( (dev->vendor_id == module_list[i].id[j].vendor) &&
				( dev->device_id == module_list[i].id[j].device)) { 
				printf("match %s\n",module_list[i].name);
				printf("vendor %x, device %x\n", module_list[i].id[j].vendor, module_list[i].id[j].device);
			}
			j++;
		}
		i++;
	}
	return(0);
}

int main(void)
{
	struct pci_access *pacc;
	struct pci_dev *dev;

	pacc = pci_alloc();		/* Get the pci_access structure */
	/* Set all options you want -- here we stick with the defaults */
	pci_init(pacc);		/* Initialize the PCI library */
	pci_scan_bus(pacc);		/* We want to get the list of devices */

	/* Iterate over all devices */
	for(dev=pacc->devices; dev; dev=dev->next) {
		/* Fillin header info we need */
		pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES);
		find_module(dev, net_list);	
//		printf("vendor=%04x device=%04x\n",
//			dev->vendor_id, dev->device_id);
	}
	pci_cleanup(pacc);		/* Close everything */
	return(0);
}

Reply to: