static const struct imsm_orom *find_imsm_hba_orom(enum sys_dev_type hba_id) { unsigned long align; if (hba_id >= SYS_DEV_MAX) return NULL; /* it's static data so we only need to read it once */ if (populated_orom[hba_id]) { dprintf("OROM CAP: %p, pid: %d pop: %d\n", &imsm_orom[hba_id], (int) getpid(), populated_orom[hba_id]); return &imsm_orom[hba_id]; } if (check_env("IMSM_TEST_OROM")) { dprintf("OROM CAP: %p, pid: %d pop: %d\n", &imsm_orom[hba_id], (int) getpid(), populated_orom[hba_id]); return imsm_platform_test(hba_id, &populated_orom[hba_id], &imsm_orom[hba_id]); } /* return empty OROM capabilities in EFI test mode */ if (check_env("IMSM_TEST_AHCI_EFI") || check_env("IMSM_TEST_SCU_EFI")) return NULL; if (intel_devices != NULL) free_sys_dev(&intel_devices); intel_devices = find_intel_devices(); if (intel_devices == NULL) return NULL; /* scan option-rom memory looking for an imsm signature */ if (check_env("IMSM_SAFE_OROM_SCAN")) align = 2048; else align = 512; if (probe_roms_init(align) != 0) return NULL; probe_roms(); /* ignore return value - True is returned if both adapater roms are found */ scan_adapter_roms(scan); probe_roms_exit(); if (intel_devices != NULL) free_sys_dev(&intel_devices); intel_devices = NULL; if (populated_orom[hba_id]) return &imsm_orom[hba_id]; return NULL; }
struct sys_dev *find_driver_devices(const char *bus, const char *driver) { /* search sysfs for devices driven by 'driver' */ char path[292]; char link[256]; char *c; DIR *driver_dir; struct dirent *de; struct sys_dev *head = NULL; struct sys_dev *list = NULL; sprintf(path, "/sys/bus/%s/drivers/%s", bus, driver); driver_dir = opendir(path); if (!driver_dir) return NULL; for (de = readdir(driver_dir); de; de = readdir(driver_dir)) { int n; /* is 'de' a device? check that the 'subsystem' link exists and * that its target matches 'bus' */ sprintf(path, "/sys/bus/%s/drivers/%s/%s/subsystem", bus, driver, de->d_name); n = readlink(path, link, sizeof(link)); if (n < 0 || n >= (int)sizeof(link)) continue; link[n] = '\0'; c = strrchr(link, '/'); if (!c) continue; if (strncmp(bus, c+1, strlen(bus)) != 0) continue; /* start / add list entry */ if (!head) { head = malloc(sizeof(*head)); list = head; } else { list->next = malloc(sizeof(*head)); list = list->next; } if (!list) { free_sys_dev(&head); break; } /* generate canonical path name for the device */ sprintf(path, "/sys/bus/%s/drivers/%s/%s", bus, driver, de->d_name); list->path = canonicalize_file_name(path); list->next = NULL; } closedir(driver_dir); return head; }
static int platform_has_intel_ahci(void) { struct sys_dev *devices = find_driver_devices("pci", "ahci"); struct sys_dev *dev; int ret = 0; for (dev = devices; dev; dev = dev->next) if (devpath_to_vendor(dev->path) == 0x8086) { ret = 1; break; } free_sys_dev(&devices); return ret; }
struct sys_dev *find_driver_devices(const char *bus, const char *driver) { /* search sysfs for devices driven by 'driver' */ char path[292]; char link[256]; char *c; DIR *driver_dir; struct dirent *de; struct sys_dev *head = NULL; struct sys_dev *list = NULL; enum sys_dev_type type; unsigned long long dev_id; if (strcmp(driver, "isci") == 0) type = SYS_DEV_SAS; else if (strcmp(driver, "ahci") == 0) type = SYS_DEV_SATA; else type = SYS_DEV_UNKNOWN; sprintf(path, "/sys/bus/%s/drivers/%s", bus, driver); driver_dir = opendir(path); if (!driver_dir) return NULL; for (de = readdir(driver_dir); de; de = readdir(driver_dir)) { int n; /* is 'de' a device? check that the 'subsystem' link exists and * that its target matches 'bus' */ sprintf(path, "/sys/bus/%s/drivers/%s/%s/subsystem", bus, driver, de->d_name); n = readlink(path, link, sizeof(link)); if (n < 0 || n >= (int)sizeof(link)) continue; link[n] = '\0'; c = strrchr(link, '/'); if (!c) continue; if (strncmp(bus, c+1, strlen(bus)) != 0) continue; sprintf(path, "/sys/bus/%s/drivers/%s/%s", bus, driver, de->d_name); /* if it's not Intel device skip it. */ if (devpath_to_vendor(path) != 0x8086) continue; if (devpath_to_ll(path, "device", &dev_id) != 0) continue; /* start / add list entry */ if (!head) { head = xmalloc(sizeof(*head)); list = head; } else { list->next = xmalloc(sizeof(*head)); list = list->next; } if (!list) { free_sys_dev(&head); break; } list->dev_id = (__u16) dev_id; list->type = type; list->path = canonicalize_file_name(path); list->next = NULL; if ((list->pci_id = strrchr(list->path, '/')) != NULL) list->pci_id++; } closedir(driver_dir); return head; }