summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/probing.c
diff options
context:
space:
mode:
authorOlivier Blin <oblin@mandriva.org>2006-02-09 11:12:25 +0000
committerOlivier Blin <oblin@mandriva.org>2006-02-09 11:12:25 +0000
commit38e85ac42ac6483781f24bc920fe67e4e12431cf (patch)
tree03173f673079006983f429e79ea8db99ed7145a5 /mdk-stage1/probing.c
parentc10291702388dbb4325b6e8ac3626c856a99e8bc (diff)
downloaddrakx-backup-do-not-use-38e85ac42ac6483781f24bc920fe67e4e12431cf.tar
drakx-backup-do-not-use-38e85ac42ac6483781f24bc920fe67e4e12431cf.tar.gz
drakx-backup-do-not-use-38e85ac42ac6483781f24bc920fe67e4e12431cf.tar.bz2
drakx-backup-do-not-use-38e85ac42ac6483781f24bc920fe67e4e12431cf.tar.xz
drakx-backup-do-not-use-38e85ac42ac6483781f24bc920fe67e4e12431cf.zip
backport thirdparty support
Diffstat (limited to 'mdk-stage1/probing.c')
-rw-r--r--mdk-stage1/probing.c152
1 files changed, 132 insertions, 20 deletions
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;