From 38e85ac42ac6483781f24bc920fe67e4e12431cf Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Thu, 9 Feb 2006 11:12:25 +0000 Subject: backport thirdparty support --- mdk-stage1/probing.c | 152 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 132 insertions(+), 20 deletions(-) (limited to 'mdk-stage1/probing.c') diff --git a/mdk-stage1/probing.c b/mdk-stage1/probing.c index aed9862c4..259937027 100644 --- a/mdk-stage1/probing.c +++ b/mdk-stage1/probing.c @@ -121,31 +121,144 @@ char * get_net_intf_description(char * intf_name) } #endif +struct pcitable_entry detected_devices[50]; +int detected_devices_len = 0; + +/* FIXME: factorize with probe_that_type() */ + +static void add_detected_device(unsigned short vendor, unsigned short device, const char *name, const char *module) +{ + struct pcitable_entry *dev = &detected_devices[detected_devices_len++]; + dev->vendor = vendor; + dev->device = device; + strncpy(dev->module, module, 19); + dev->module[19] = '\0'; + strncpy(dev->description, name, 99); + dev->description[99] = '\0'; + log_message("detected device (%x, %x, %s, %s)", vendor, device, name, module); +} + +static int check_device_full(struct pci_module_map_full * pcidb_full, unsigned int len_full, + unsigned short vendor, unsigned short device, + unsigned short subvendor, unsigned short subdevice) +{ + int i; + for (i = 0; i < len_full; i++) + if (pcidb_full[i].vendor == vendor && pcidb_full[i].device == device) { + if (pcidb_full[i].subvendor == subvendor && pcidb_full[i].subdevice == subdevice) { + add_detected_device(pcidb_full[i].vendor, pcidb_full[i].device, + pcidb_full[i].name, pcidb_full[i].module); + return 1; + } + } + return 0; +} + +static int check_device(struct pci_module_map * pcidb, unsigned int len, + unsigned short vendor, unsigned short device) { + int i; + for (i = 0; i < len; i++) + if (pcidb[i].vendor == vendor && pcidb[i].device == device) { + add_detected_device(pcidb[i].vendor, pcidb[i].device, + pcidb[i].name, pcidb[i].module); + return 1; + } + return 0; +} + +void probing_detect_devices() +{ + FILE * f = NULL; + char buf[200]; + static int already_detected_devices = 0; + + if (already_detected_devices) + return; + + if (!(f = fopen("/proc/bus/pci/devices", "rb"))) { + log_message("PCI: could not open proc file"); + return; + } + + while (1) { + unsigned int i; + unsigned short vendor, device, subvendor, subdevice, devbusfn; + if (!fgets(buf, sizeof(buf), f)) break; + sscanf(buf, "%hx %x", &devbusfn, &i); + device = i; + vendor = i >> 16; + { + int bus = devbusfn >> 8; + int device_p = (devbusfn & 0xff) >> 3; + int function = (devbusfn & 0xff) & 0x07; + char file[100]; + int sf; + sprintf(file, "/proc/bus/pci/%02x/%02x.%d", bus, device_p, function); + if ((sf = open(file, O_RDONLY)) == -1) { + log_message("PCI: could not open file for full probe (%s)", file); + continue; + } + if (read(sf, buf, 48) == -1) { + log_message("PCI: could not read 48 bytes from %s", file); + close(sf); + continue; + } + close(sf); + memcpy(&subvendor, buf+44, 2); + memcpy(&subdevice, buf+46, 2); + } + + +#ifndef DISABLE_PCIADAPTERS +#ifndef DISABLE_MEDIAS + if (check_device_full(medias_pci_ids_full, medias_num_ids_full, vendor, device, subvendor, subdevice)) + continue; + if (check_device(medias_pci_ids, medias_num_ids, vendor, device)) + continue; +#endif + +#ifndef DISABLE_NETWORK + if (check_device_full(network_pci_ids_full, network_num_ids_full, vendor, device, subvendor, subdevice)) + continue; + if (check_device(network_pci_ids, network_num_ids, vendor, device)) + continue; +#endif +#endif + +#ifdef ENABLE_USB + if (check_device(usb_pci_ids, usb_num_ids, vendor, device)) + continue; +#endif + + /* device can't be found in built-in pcitables, but keep it */ + add_detected_device(vendor, device, "", ""); + } + + fclose(f); + already_detected_devices = 1; +} + void discovered_device(enum driver_type type, unsigned short vendor, unsigned short device, unsigned short subvendor, unsigned short subdevice, const char * description, const char * driver) { + enum insmod_return failed = INSMOD_FAILED; log_message("PCI: device %04x %04x %04x %04x is \"%s\", driver is %s", vendor, device, subvendor, subdevice, description, driver); #ifndef DISABLE_MEDIAS if (type == SCSI_ADAPTERS) { - int wait_msg = 0; - enum insmod_return failed; - if (IS_AUTOMATIC) { - wait_message("Loading driver for SCSI adapter:\n \n%s", description); - wait_msg = 1; - } else - stg1_info_message("About to load driver for SCSI adapter:\n \n%s", description); + wait_message("Loading driver for SCSI adapter:\n \n%s", description); failed = my_insmod(driver, SCSI_ADAPTERS, NULL, 1); - if (wait_msg) - remove_wait_message(); + remove_wait_message(); warning_insmod_failed(failed); } #endif #ifndef DISABLE_NETWORK if (type == NETWORK_DEVICES) { - stg1_info_message("About to load driver for network device:\n \n%s", description); + wait_message("Loading driver for network device:\n \n%s", description); prepare_intf_descr(description); - warning_insmod_failed(my_insmod(driver, NETWORK_DEVICES, NULL, 1)); + failed = my_insmod(driver, NETWORK_DEVICES, NULL, 1); + warning_insmod_failed(failed); + remove_wait_message(); if (intf_descr_for_discover) /* for modules providing more than one net intf */ net_discovered_interface(NULL); } @@ -153,7 +266,7 @@ void discovered_device(enum driver_type type, #ifdef ENABLE_USB if (type == USB_CONTROLLERS) /* we can't allow additional modules floppy since we need usbkbd for keystrokes of usb keyboards */ - my_insmod(driver, USB_CONTROLLERS, NULL, 0); + failed = my_insmod(driver, USB_CONTROLLERS, NULL, 0); #endif } @@ -212,11 +325,6 @@ void probe_that_type(enum driver_type type, enum media_bus bus __attribute__ ((u goto end_pci_probe; } - if (IS_EXPERT && type != USB_CONTROLLERS) { - ask_insmod(type); - return; - } - if (!(f = fopen("/proc/bus/pci/devices", "rb"))) { log_message("PCI: could not open proc file"); goto end_pci_probe; @@ -385,6 +493,9 @@ void probe_that_type(enum driver_type type, enum media_bus bus __attribute__ ((u my_insmod("usb-storage", SCSI_ADAPTERS, NULL, 0); if (module_already_present("ieee1394")) my_insmod("sbp2", SCSI_ADAPTERS, NULL, 0); + wait_message("Detecting USB mass-storage devices."); + sleep(10); /* sucking background work */ + remove_wait_message(); } } @@ -402,9 +513,10 @@ static void find_media(enum media_bus bus) if (medias) free(medias); /* that does not free the strings, by the way */ - if (bus == BUS_SCSI || bus == BUS_USB || bus == BUS_ANY) - probe_that_type(SCSI_ADAPTERS, bus); - + if (bus == BUS_SCSI || bus == BUS_USB || bus == BUS_ANY) { + log_message("looking for SCSI adapters"); + probe_that_type(SCSI_ADAPTERS, bus); + } /* ----------------------------------------------- */ if (bus != BUS_IDE && bus != BUS_ANY) goto find_media_after_ide; -- cgit v1.2.1