updated pci probing scheme: stop compile in pci ids form now,

separate map file /modules/modules.map used instead and parsed
at runtime. see related changes in mar module also.
This commit is contained in:
Sergey Bolshakov 2004-12-15 20:43:02 +00:00
parent 68463187b0
commit 1ec038fd23
4 changed files with 111 additions and 58 deletions

View File

@ -56,7 +56,6 @@ include Makefile.common
STAGE1BINS = $(METHODS:%=stage1-%) STAGE1BINS = $(METHODS:%=stage1-%)
BINS = init $(STAGE1BINS) BINS = init $(STAGE1BINS)
DIRS += pci-resource usb-resource
DEFS = -DENABLE_USB DEFS = -DENABLE_USB
ifneq ($(WITH_SHELL),) ifneq ($(WITH_SHELL),)
DEFS += -DSPAWN_SHELL DEFS += -DSPAWN_SHELL
@ -137,12 +136,7 @@ endif
endif endif
all: version.h dirs $(BINS) all: version.h $(BINS)
dirs:
@for n in . $(DIRS); do \
[ "$$n" = "." ] || make -C $$n ;\
done
init: $(INITOBJS) $(INIT_LIBC) init: $(INITOBJS) $(INIT_LIBC)
$(CC) -o $@ $^ $(LDFLAGS_INIT) $(CC) -o $@ $^ $(LDFLAGS_INIT)
@ -180,11 +174,7 @@ version.h: /etc/altlinux-release
echo \\#define VERSION \\"\2\\";echo \\#define DISTRIB_NAME \\"ALT Linux\2\1 \\(\3\\)\\"|' < $^ |sh > $@ echo \\#define VERSION \\"\2\\";echo \\#define DISTRIB_NAME \\"ALT Linux\2\1 \\(\3\\)\\"|' < $^ |sh > $@
clean: clean:
@for n in $(DIRS); do \ rm -f *.o .depend $(BINS) version.h
(cd $$n; make clean) \
done
rm -f *.o .depend *.rdz *.img $(BINS)
rm -f version.h
.depend: .depend:
$(CPP) $(CFLAGS) -M $(ALLSRC) > .depend $(CPP) $(CFLAGS) -M $(ALLSRC) > .depend

142
probing.c
View File

@ -45,20 +45,38 @@
#include "log.h" #include "log.h"
#include "frontend.h" #include "frontend.h"
#include "modules.h" #include "modules.h"
#include "pci-resource/pci-ids.h"
#ifdef ENABLE_USB
#include "usb-resource/usb-ids.h"
#endif
#include "probing.h" #include "probing.h"
struct media_info { struct media_info {
char * name; char * name;
char * model; char * model;
enum media_type type; enum media_type type;
}; };
struct pci_module_map {
unsigned short vendor; /* PCI vendor id */
unsigned short device; /* PCI device id */
char * module; /* module to load */
struct pci_module_map * next;
};
#ifndef DISABLE_USB
struct usb_module_map {
unsigned short vendor; /* PCI vendor id */
unsigned short device; /* PCI device id */
char * module; /* module to load */
struct usb_module_map * next;
};
char *usb_hcd[] = {
"uhci-hcd",
"ohci-hcd",
"ehci-hcd",
};
#define HCD_NUM (sizeof(usb_hcd) / sizeof(char *))
#endif
static void warning_insmod_failed(enum insmod_return r) static void warning_insmod_failed(enum insmod_return r)
{ {
@ -120,6 +138,42 @@ char * get_net_intf_description(char * intf_name)
} }
#endif #endif
static struct pci_module_map * get_pci_ids()
{
static struct pci_module_map * pcidb = NULL;
struct pci_module_map * last, *new;
char buf[50];
int v, d;
FILE *f;
if (pcidb) return pcidb;
log_message("loading pcimap file");
if (!(f = fopen("/modules/modules.map", "rb"))) {
log_message("couldn't open pcimap file");
return NULL;
}
while (3 == (fscanf(f, "%x %x %48s", &v, &d, buf))) {
new = (struct pci_module_map *)malloc(sizeof(*pcidb));
new->vendor = v;
new->device = d;
new->module = strdup(buf);
new->next = NULL;
if (!pcidb) {
pcidb = last = new;
} else {
last->next = new;
last = new;
}
}
fclose(f);
return pcidb;
}
static void probe_that_type(enum driver_type type) static void probe_that_type(enum driver_type type)
{ {
if (IS_EXPERT) { if (IS_EXPERT) {
@ -130,11 +184,13 @@ static void probe_that_type(enum driver_type type)
/* ---- PCI probe ---------------------------------------------- */ /* ---- PCI probe ---------------------------------------------- */
{ {
FILE * f; FILE * f;
int n, len = 0; int n;
char buf[200]; char buf[200];
char devname[22]; char devname[22];
u_int8_t devdata[48]; u_int8_t devdata[48];
struct pci_module_map * pcidb = NULL; struct pci_module_map * pci_ids = NULL;
int that_class;
#ifdef ENABLE_USB #ifdef ENABLE_USB
static int need_usb_hcd[HCD_NUM]; static int need_usb_hcd[HCD_NUM];
#endif #endif
@ -142,37 +198,38 @@ static void probe_that_type(enum driver_type type)
switch (type) { switch (type) {
#ifndef DISABLE_MEDIAS #ifndef DISABLE_MEDIAS
case SCSI_ADAPTERS: case SCSI_ADAPTERS:
pcidb = medias_pci_ids; that_class = PCI_CLASS_STORAGE_SCSI << 8;
len = medias_num_ids;
break; break;
#endif #endif
#ifndef DISABLE_NETWORK #ifndef DISABLE_NETWORK
#ifndef DISABLE_PCINET #ifndef DISABLE_PCINET
case NETWORK_DEVICES: case NETWORK_DEVICES:
pcidb = network_pci_ids; that_class = PCI_CLASS_NETWORK_ETHERNET << 8;
len = network_num_ids;
break; break;
#endif #endif
#endif #endif
#ifdef ENABLE_USB #ifdef ENABLE_USB
case USB_CONTROLLERS: case USB_CONTROLLERS:
pcidb = usb_pci_ids; that_class = PCI_CLASS_SERIAL_USB << 8;
len = usb_num_ids;
break; break;
#endif #endif
default: default:
goto end_pci_probe; goto end_pci_probe;
} }
if (NULL == (pci_ids = get_pci_ids())) {
log_message("PCI: could not get pci ids");
goto end_pci_probe;
}
if (!(f = fopen("/proc/bus/pci/devices", "rb"))) { if (!(f = fopen("/proc/bus/pci/devices", "rb"))) {
log_message("PCI: could not open proc file"); log_message("PCI: could not open proc file");
goto end_pci_probe; goto end_pci_probe;
} }
log_message("PCI: XXX probing %d XXX", type);
while (1) { while (1) {
int i, j, dfn, vendor, device, class, subv, subid; int i, dfn, vendor, device, class, subv, subid;
struct pci_module_map * pcidb;
if (!fgets(buf, sizeof(buf), f)) break; if (!fgets(buf, sizeof(buf), f)) break;
@ -197,19 +254,20 @@ static void probe_that_type(enum driver_type type)
log_message("found pci device: %04x %04x %06x %04x %04x", log_message("found pci device: %04x %04x %06x %04x %04x",
vendor, device, class, subv, subid); vendor, device, class, subv, subid);
for (i = 0; i < len; i++) { for (pcidb = pci_ids; pcidb; pcidb = pcidb->next) {
if (pcidb[i].vendor == vendor && pcidb[i].device == device) { if (that_class == (class & 0xffff00) &&
log_message("module is \"%s\" (%s)", pcidb[i].name, pcidb[i].module); pcidb->vendor == vendor && pcidb->device == device) {
log_message("module is \"%s\"", pcidb->module);
#ifndef DISABLE_MEDIAS #ifndef DISABLE_MEDIAS
if (type == SCSI_ADAPTERS) { if (type == SCSI_ADAPTERS) {
int wait_msg = 0; int wait_msg = 0;
enum insmod_return failed; enum insmod_return failed;
if (IS_AUTOMATIC) { if (IS_AUTOMATIC) {
wait_message("Loading driver for SCSI adapter:\n \n%s", pcidb[i].name); wait_message("Loading driver for SCSI adapter:\n \n%s", pcidb->module);
wait_msg = 1; wait_msg = 1;
} else } else
stg1_info_message("About to load driver for SCSI adapter:\n \n%s", pcidb[i].name); stg1_info_message("About to load driver for SCSI adapter:\n \n%s", pcidb->module);
failed = my_insmod(pcidb[i].module, SCSI_ADAPTERS, NULL); failed = my_insmod(pcidb->module, SCSI_ADAPTERS, NULL);
if (wait_msg) if (wait_msg)
remove_wait_message(); remove_wait_message();
warning_insmod_failed(failed); warning_insmod_failed(failed);
@ -217,9 +275,9 @@ static void probe_that_type(enum driver_type type)
#endif /* DISABLE_MEDIAS */ #endif /* DISABLE_MEDIAS */
#ifndef DISABLE_NETWORK #ifndef DISABLE_NETWORK
if (type == NETWORK_DEVICES) { if (type == NETWORK_DEVICES) {
stg1_info_message("About to load driver for network device:\n \n%s", pcidb[i].name); stg1_info_message("About to load driver for network device:\n \n%s", pcidb->module);
prepare_intf_descr(pcidb[i].name); prepare_intf_descr(pcidb->module);
warning_insmod_failed(my_insmod(pcidb[i].module, NETWORK_DEVICES, NULL)); warning_insmod_failed(my_insmod(pcidb->module, NETWORK_DEVICES, NULL));
if (intf_descr_for_discover) /* for modules providing more than one net intf */ if (intf_descr_for_discover) /* for modules providing more than one net intf */
net_discovered_interface(NULL); net_discovered_interface(NULL);
} }
@ -227,10 +285,10 @@ static void probe_that_type(enum driver_type type)
#ifdef ENABLE_USB #ifdef ENABLE_USB
if (type == USB_CONTROLLERS) { if (type == USB_CONTROLLERS) {
/* found explicitly declared module */ /* found explicitly declared module */
for (j=0; j < HCD_NUM; j++) { for (i=0; i < HCD_NUM; i++) {
if(ptr_begins_static_str(pcidb[i].module, usb_hcd[j])) { if(ptr_begins_static_str(pcidb->module, usb_hcd[i])) {
log_message("found explicit %s", usb_hcd[j]); log_message("found explicit %s", usb_hcd[i]);
need_usb_hcd[j] = 1; need_usb_hcd[i] = 1;
break; break;
} }
} }
@ -277,23 +335,20 @@ static void probe_that_type(enum driver_type type)
static int already_mounted_usbdev = 0; static int already_mounted_usbdev = 0;
FILE * f; FILE * f;
int len = 0;
char buf[200]; char buf[200];
struct usb_module_map * usbdb = NULL; static struct usb_module_map * usb_ids = NULL;
switch (type) { switch (type) {
#ifdef ENABLE_USBNET #ifdef ENABLE_USBNET
case NETWORK_DEVICES: case NETWORK_DEVICES:
/* /*
usbdb = usbnet_usb_ids; usbdb = usbnet_usb_ids;
len = usbnet_usb_num_ids;
*/ */
break; break;
#endif #endif
case SCSI_ADAPTERS: case SCSI_ADAPTERS:
/* /*
usbdb = usbstorage_usb_ids; usbdb = usbstorage_usb_ids;
len = usbstorage_usb_num_ids;
*/ */
break; break;
default: default:
@ -328,7 +383,8 @@ static void probe_that_type(enum driver_type type)
} }
while (1) { while (1) {
int i, vendor, id; int vendor, device;
struct usb_module_map * usbdb;
if (!fgets(buf, sizeof(buf), f)) break; if (!fgets(buf, sizeof(buf), f)) break;
@ -337,17 +393,17 @@ static void probe_that_type(enum driver_type type)
my_insmod("keybdev", ANY_DRIVER_TYPE, NULL); my_insmod("keybdev", ANY_DRIVER_TYPE, NULL);
} }
if (sscanf(buf, "P: Vendor=%x ProdID=%x", &vendor, &id) != 2) if (sscanf(buf, "P: Vendor=%x ProdID=%x", &vendor, &device) != 2)
continue; continue;
for (i = 0; i < len; i++) { for (usbdb = usb_ids; usbdb; usbdb = usbdb->next) {
if (usbdb[i].vendor == vendor && usbdb[i].id == id) { if (usbdb->vendor == vendor && usbdb->device == device) {
log_message("USB: device %04x %04x is \"%s\" (%s)", vendor, id, usbdb[i].name, usbdb[i].module); log_message("USB: device %04x %04x is \"%s\" (%s)", vendor, device, usbdb->module);
#ifdef ENABLE_USBNET #ifdef ENABLE_USBNET
if (type == NETWORK_DEVICES) { if (type == NETWORK_DEVICES) {
stg1_info_message("About to load driver for usb network device:\n \n%s", usbdb[i].name); stg1_info_message("About to load driver for usb network device:\n \n%s", usbdb->module);
prepare_intf_descr(usbdb[i].name); prepare_intf_descr(usbdb->module);
warning_insmod_failed(my_insmod(usbdb[i].module, NETWORK_DEVICES, NULL)); warning_insmod_failed(my_insmod(usbdb->module, NETWORK_DEVICES, NULL));
if (intf_descr_for_discover) /* for modules providing more than one net intf */ if (intf_descr_for_discover) /* for modules providing more than one net intf */
net_discovered_interface(NULL); net_discovered_interface(NULL);
} }

View File

@ -40,4 +40,13 @@ void prepare_intf_descr(const char * intf_descr);
#define PCI_FUNC(devfn) ((devfn) & 0x07) #define PCI_FUNC(devfn) ((devfn) & 0x07)
#endif #endif
/*
extract from linux/pci_ids.h
*/
#define PCI_CLASS_STORAGE_SCSI 0x0100
#define PCI_CLASS_NETWORK_ETHERNET 0x0200
#define PCI_CLASS_SERIAL_FIREWIRE 0x0c00
#define PCI_CLASS_SERIAL_USB 0x0c03
#endif #endif

View File

@ -15,11 +15,9 @@
# #
#***************************************************************************** #*****************************************************************************
VPATH = $(MODDIR)
all: usb-ids.h all: usb-ids.h
usb-ids.h: medias/modules.mar network/modules.mar update-usb-ids.sh usb-ids.h: update-usb-ids.sh
./update-usb-ids.sh $^ > $@ || rm -f $@ ./update-usb-ids.sh $^ > $@ || rm -f $@
clean: clean: