void int_bios(hd_data_t *hd_data) { hd_t *hd, *hd_boot; int i, start, bios = 0x80; int ide_1st; char ide_name[] = "/dev/hda"; char scsi_name[] = "/dev/sda"; char *s; hd_boot = hd_get_device_by_idx(hd_data, hd_boot_disk(hd_data, &i)); if(hd_boot) { free_mem(hd_boot->rom_id); hd_boot->rom_id = new_str("0x80"); } if(!hd_boot || i != 1) return; if(strstr(hd_boot->unix_dev_name, "/dev/sd") == hd_boot->unix_dev_name) { ide_1st = 0; start = hd_boot->unix_dev_name[sizeof "/dev/sd" - 1] - 'a'; } else if(strstr(hd_boot->unix_dev_name, "/dev/hd") == hd_boot->unix_dev_name) { ide_1st = 1; start = hd_boot->unix_dev_name[sizeof "/dev/hd" - 1] - 'a'; } else { return; } if(start < 0) return; for(hd = hd_data->hd; hd; hd = hd->next) { if( hd->base_class.id == bc_storage_device && hd->sub_class.id == sc_sdev_disk ) { hd->rom_id = free_mem(hd->rom_id); } } s = ide_1st ? ide_name : scsi_name; for(i = start; i < 26; i++) { s[strlen(s) - 1] = 'a' + i; bios += set_bios_id(hd_data, s, bios); } for(i = 0; i < start; i++) { s[strlen(s) - 1] = 'a' + i; bios += set_bios_id(hd_data, s, bios); } s = ide_1st ? scsi_name : ide_name; for(i = 0; i < 26; i++) { s[strlen(s) - 1] = 'a' + i; bios += set_bios_id(hd_data, s, bios); } }
void int_bios(hd_data_t *hd_data) { hd_t *hd, *hd_boot; unsigned *sctrl, *sctrl2; int sctrl_len, i, j; int bios_id, list_sorted; /* don't do anything if there is useful edd info */ if(hd_data->flags.edd_used) return; for(i = 0, hd = hd_data->hd; hd; hd = hd->next) { if( hd->base_class.id == bc_storage_device && hd->sub_class.id == sc_sdev_disk ) { i++; } } if(!i) return; sctrl = new_mem(i * sizeof *sctrl); /* sctrl: list of storage controllers with disks */ for(sctrl_len = 0, hd = hd_data->hd; hd; hd = hd->next) { if( hd->base_class.id == bc_storage_device && hd->sub_class.id == sc_sdev_disk ) { for(i = 0; i < sctrl_len; i++) { if(sctrl[i] == hd->attached_to) break; } if(i == sctrl_len) sctrl[sctrl_len++] = hd->attached_to; } } /* sort list, if possible */ list_sorted = bios_ctrl_order(hd_data, sctrl, sctrl_len); hd_boot = hd_get_device_by_idx(hd_data, hd_boot_disk(hd_data, &i)); /* if we know the boot device, make this controller the first */ if(hd_boot && hd_boot->attached_to && i == 1) { for(i = 0; i < sctrl_len; i++) { if(sctrl[i] == hd_boot->attached_to) break; } if(i < sctrl_len) { sctrl2 = new_mem(sctrl_len * sizeof *sctrl2); *sctrl2 = hd_boot->attached_to; for(i = 0, j = 1; i < sctrl_len; i++) { if(sctrl[i] != hd_boot->attached_to) sctrl2[j++] = sctrl[i]; } free_mem(sctrl); sctrl = sctrl2; } } else { hd_boot = NULL; } if(hd_boot) ADD2LOG(" bios boot dev: %d\n", hd_boot->idx); for(i = 0; i < sctrl_len; i++) { ADD2LOG(" bios ctrl %d: %d\n", i, sctrl[i]); } /* remove existing entries */ for(hd = hd_data->hd; hd; hd = hd->next) { if( hd->base_class.id == bc_storage_device && hd->sub_class.id == sc_sdev_disk ) { hd->rom_id = free_mem(hd->rom_id); } } if(!list_sorted && !hd_boot && sctrl_len > 1) { /* we have no info at all */ sctrl_len = 0; } else if(!list_sorted && hd_boot && sctrl_len > 2) { /* we know which controller has the boot device */ sctrl_len = 1; } bios_id = 0x80; /* rely on it */ if(hd_boot) { bios_id += set_bios_id(hd_data, hd_boot, bios_id); } /* assign all the others */ for(i = 0; i < sctrl_len; i++) { for(hd = hd_data->hd; hd; hd = hd->next) { if( hd->base_class.id == bc_storage_device && hd->sub_class.id == sc_sdev_disk && hd->attached_to == sctrl[i] && !hd->rom_id ) { bios_id += set_bios_id(hd_data, hd, bios_id); } } } free_mem(sctrl); }
void add_serial_modem(hd_data_t *hd_data) { hd_t *hd; char buf[4]; ser_device_t *sm; hd_res_t *res; for(sm = hd_data->ser_modem; sm; sm = sm->next) { if(!sm->is_modem) continue; hd = hd_get_device_by_idx(hd_data, sm->hd_idx); if(hd && hd->base_class.id == bc_modem) { /* just *add* info */ } else { hd = add_hd_entry(hd_data, __LINE__, 0); hd->base_class.id = bc_modem; hd->bus.id = bus_serial; hd->unix_dev_name = new_str(sm->dev_name); hd->attached_to = sm->hd_idx; res = add_res_entry(&hd->res, new_mem(sizeof *res)); res->baud.type = res_baud; res->baud.speed = sm->max_baud; if(sm->pppd_option) { res = add_res_entry(&hd->res, new_mem(sizeof *res)); res->pppd_option.type = res_pppd_option; res->pppd_option.option = new_str(sm->pppd_option); } if(*sm->pnp_id) { strncpy(buf, sm->pnp_id, 3); buf[3] = 0; hd->vendor.id = name2eisa_id(buf); hd->device.id = MAKE_ID(TAG_EISA, strtol(sm->pnp_id + 3, NULL, 16)); } hd->serial = new_str(sm->serial); if(sm->user_name) hd->device.name = new_str(sm->user_name); if(sm->vend) hd->vendor.name = new_str(sm->vend); if(sm->dev_id && strlen(sm->dev_id) >= 7) { char buf[5], *s; unsigned u1, u2; u1 = name2eisa_id(sm->dev_id); if(u1) { strncpy(buf, sm->dev_id + 3, 4); buf[4] = 0; u2 = strtol(sm->dev_id + 3, &s, 16); if(!*s) { hd->compat_vendor.id = u1; hd->compat_device.id = MAKE_ID(TAG_EISA, u2); } } } if(!(hd->device.id || hd->device.name || hd->vendor.id || hd->vendor.name)) { hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x2000); hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0001); } } res = add_res_entry(&hd->res, new_mem(sizeof *res)); res->init_strings.type = res_init_strings; res->init_strings.init1 = new_str(sm->init_string1); res->init_strings.init2 = new_str(sm->init_string2); } }
static int ntfs_device_get_geo(struct ntfs_device *dev) { int err; if (!dev) { errno = EINVAL; return -1; } err = EOPNOTSUPP; #ifdef ENABLE_HD { hd_data_t *hddata; hd_t *hd, *devlist, *partlist = NULL; str_list_t *names; hd_res_t *res; const int d_name_len = strlen(dev->d_name) + 1; int done = 0; hddata = calloc(1, sizeof(*hddata)); if (!hddata) { err = ENOMEM; goto skip_hd; } /* List all "disk" class devices on the system. */ devlist = hd_list(hddata, hw_disk, 1, NULL); if (!devlist) { free(hddata); err = ENOMEM; goto skip_hd; } /* * Loop over each disk device looking for the device with the * same unix name as @dev. */ for (hd = devlist; hd; hd = hd->next) { if (hd->unix_dev_name && !strncmp(dev->d_name, hd->unix_dev_name, d_name_len)) goto got_hd; if (hd->unix_dev_name2 && !strncmp(dev->d_name, hd->unix_dev_name2, d_name_len)) goto got_hd; for (names = hd->unix_dev_names; names; names = names->next) { if (names->str && !strncmp(dev->d_name, names->str, d_name_len)) goto got_hd; } } /* * Device was not a whole disk device. Unless it is a file it * is likely to be a partition device. List all "partition" * class devices on the system. */ partlist = hd_list(hddata, hw_partition, 1, NULL); for (hd = partlist; hd; hd = hd->next) { if (hd->unix_dev_name && !strncmp(dev->d_name, hd->unix_dev_name, d_name_len)) goto got_part_hd; if (hd->unix_dev_name2 && !strncmp(dev->d_name, hd->unix_dev_name2, d_name_len)) goto got_part_hd; for (names = hd->unix_dev_names; names; names = names->next) { if (names->str && !strncmp(dev->d_name, names->str, d_name_len)) goto got_part_hd; } } /* Failed to find the device. Stop trying and clean up. */ goto end_hd; got_part_hd: /* Get the whole block device the partition device is on. */ hd = hd_get_device_by_idx(hddata, hd->attached_to); if (!hd) goto end_hd; got_hd: /* * @hd is now the whole block device either being formatted or * that the partition being formatted is on. * * Loop over each resource of the disk device looking for the * BIOS legacy geometry obtained from EDD which is what Windows * needs to boot. */ for (res = hd->res; res; res = res->next) { /* geotype 3 is BIOS legacy. */ if (res->any.type != res_disk_geo || res->disk_geo.geotype != 3) continue; dev->d_heads = res->disk_geo.heads; dev->d_sectors_per_track = res->disk_geo.sectors; done = 1; } end_hd: if (partlist) hd_free_hd_list(partlist); hd_free_hd_list(devlist); hd_free_hd_data(hddata); free(hddata); if (done) { ntfs_log_debug("EDD/BIOD legacy heads = %u, sectors " "per track = %u\n", dev->d_heads, dev->d_sectors_per_track); return 0; } } skip_hd: #endif #ifdef HDIO_GETGEO { struct hd_geometry geo; if (!dev->d_ops->ioctl(dev, HDIO_GETGEO, &geo)) { dev->d_heads = geo.heads; dev->d_sectors_per_track = geo.sectors; ntfs_log_debug("HDIO_GETGEO heads = %u, sectors per " "track = %u\n", dev->d_heads, dev->d_sectors_per_track); return 0; } err = errno; } #endif errno = err; return -1; }
void hd_scan_net(hd_data_t *hd_data) { unsigned u; int if_type, if_carrier; hd_t *hd, *hd_card; char *s, *t, *hw_addr; hd_res_t *res, *res1, *res2; uint64_t ul0; str_list_t *sf_class, *sf_class_e; char *sf_cdev = NULL, *sf_dev = NULL; char *sf_drv_name, *sf_drv; if(!hd_probe_feature(hd_data, pr_net)) return; hd_data->module = mod_net; /* some clean-up */ remove_hd_entries(hd_data); hd_data->net = free_str_list(hd_data->net); PROGRESS(1, 0, "get network data"); sf_class = read_dir("/sys/class/net", 'l'); if(!sf_class) sf_class = read_dir("/sys/class/net", 'd'); if(!sf_class) { ADD2LOG("sysfs: no such class: net\n"); return; } for(sf_class_e = sf_class; sf_class_e; sf_class_e = sf_class_e->next) { str_printf(&sf_cdev, 0, "/sys/class/net/%s", sf_class_e->str); hd_card = NULL; ADD2LOG( " net interface: name = %s, path = %s\n", sf_class_e->str, hd_sysfs_id(sf_cdev) ); if_type = -1; if(hd_attr_uint(get_sysfs_attr_by_path(sf_cdev, "type"), &ul0, 0)) { if_type = ul0; ADD2LOG(" type = %d\n", if_type); } if_carrier = -1; if(hd_attr_uint(get_sysfs_attr_by_path(sf_cdev, "carrier"), &ul0, 0)) { if_carrier = ul0; ADD2LOG(" carrier = %d\n", if_carrier); } hw_addr = NULL; if((s = get_sysfs_attr_by_path(sf_cdev, "address"))) { hw_addr = canon_str(s, strlen(s)); ADD2LOG(" hw_addr = %s\n", hw_addr); } sf_dev = new_str(hd_read_sysfs_link(sf_cdev, "device")); if(sf_dev) { ADD2LOG(" net device: path = %s\n", hd_sysfs_id(sf_dev)); } sf_drv_name = NULL; sf_drv = hd_read_sysfs_link(sf_dev, "driver"); if(sf_drv) { sf_drv_name = strrchr(sf_drv, '/'); if(sf_drv_name) sf_drv_name++; ADD2LOG( " net driver: name = %s, path = %s\n", sf_drv_name, hd_sysfs_id(sf_drv) ); } hd = add_hd_entry(hd_data, __LINE__, 0); hd->base_class.id = bc_network_interface; hd->sub_class.id = sc_nif_other; res1 = NULL; if(hw_addr && strspn(hw_addr, "0:") != strlen(hw_addr)) { res1 = new_mem(sizeof *res1); res1->hwaddr.type = res_hwaddr; res1->hwaddr.addr = new_str(hw_addr); add_res_entry(&hd->res, res1); } res2 = NULL; if(if_carrier >= 0) { res = new_mem(sizeof *res); res->link.type = res_link; res->link.state = if_carrier ? 1 : 0; add_res_entry(&hd->res, res); } hd->unix_dev_name = new_str(sf_class_e->str); hd->sysfs_id = new_str(hd_sysfs_id(sf_cdev)); if(sf_drv_name) { add_str_list(&hd->drivers, sf_drv_name); } else if(hd->res) { get_driverinfo(hd_data, hd); } switch(if_type) { case ARPHRD_ETHER: /* eth */ hd->sub_class.id = sc_nif_ethernet; break; case ARPHRD_LOOPBACK: /* lo */ hd->sub_class.id = sc_nif_loopback; break; case ARPHRD_SIT: /* sit */ hd->sub_class.id = sc_nif_sit; break; case ARPHRD_FDDI: /* fddi */ hd->sub_class.id = sc_nif_fddi; break; case ARPHRD_IEEE802_TR: /* tr */ hd->sub_class.id = sc_nif_tokenring; break; #if 0 case ARPHRD_IEEE802: /* fc */ hd->sub_class.id = sc_nif_fc; break; #endif default: hd->sub_class.id = sc_nif_other; } if(!strcmp(hd->unix_dev_name, "lo")) { hd->sub_class.id = sc_nif_loopback; } else if(sscanf(hd->unix_dev_name, "eth%u", &u) == 1) { hd->sub_class.id = sc_nif_ethernet; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "tr%u", &u) == 1) { hd->sub_class.id = sc_nif_tokenring; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "fddi%u", &u) == 1) { hd->sub_class.id = sc_nif_fddi; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "ctc%u", &u) == 1) { hd->sub_class.id = sc_nif_ctc; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "iucv%u", &u) == 1) { hd->sub_class.id = sc_nif_iucv; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "hsi%u", &u) == 1) { hd->sub_class.id = sc_nif_hsi; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "qeth%u", &u) == 1) { hd->sub_class.id = sc_nif_qeth; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "escon%u", &u) == 1) { hd->sub_class.id = sc_nif_escon; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "myri%u", &u) == 1) { hd->sub_class.id = sc_nif_myrinet; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "sit%u", &u) == 1) { hd->sub_class.id = sc_nif_sit; /* ipv6 over ipv4 tunnel */ hd->slot = u; } else if(sscanf(hd->unix_dev_name, "wlan%u", &u) == 1) { hd->sub_class.id = sc_nif_wlan; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "xp%u", &u) == 1) { hd->sub_class.id = sc_nif_xp; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "usb%u", &u) == 1) { hd->sub_class.id = sc_nif_usb; hd->slot = u; } /* ##### add more interface names here */ else { for(s = hd->unix_dev_name; *s; s++) if(isdigit(*s)) break; if(*s && (u = strtoul(s, &s, 10), !*s)) { hd->slot = u; } } hd->bus.id = bus_none; hd_card = NULL; if(sf_dev) { s = new_str(hd_sysfs_id(sf_dev)); hd->sysfs_device_link = new_str(s); hd_card = hd_find_sysfs_id(hd_data, s); // try one above, if not found if(!hd_card) { t = strrchr(s, '/'); if(t) { *t = 0; hd_card = hd_find_sysfs_id(hd_data, s); } } /* if one card has several interfaces (as with PS3), check interface names, too */ if( hd_card && hd_card->unix_dev_name && hd->unix_dev_name && strcmp(hd->unix_dev_name, hd_card->unix_dev_name) ) { hd_card = hd_find_sysfs_id_devname(hd_data, s, hd->unix_dev_name); } s = free_mem(s); if(hd_card) { hd->attached_to = hd_card->idx; /* for cards with strange pci classes */ hd_set_hw_class(hd_card, hw_network_ctrl); /* add hw addr to network card */ if(res1) { u = 0; for(res = hd_card->res; res; res = res->next) { if( res->any.type == res_hwaddr && !strcmp(res->hwaddr.addr, res1->hwaddr.addr) ) { u = 1; break; } } if(!u) { res = new_mem(sizeof *res); res->hwaddr.type = res_hwaddr; res->hwaddr.addr = new_str(res1->hwaddr.addr); add_res_entry(&hd_card->res, res); } } /* * add interface names... * but not wmasterX (bnc #441778) */ if(if_type != 801) add_if_name(hd_card, hd); } } if(!hd_card && hw_addr) { /* try to find card based on hwaddr (for prom-based cards) */ for(hd_card = hd_data->hd; hd_card; hd_card = hd_card->next) { if( hd_card->base_class.id != bc_network || hd_card->sub_class.id != 0 ) continue; for(res = hd_card->res; res; res = res->next) { if( res->any.type == res_hwaddr && !strcmp(hw_addr, res->hwaddr.addr) ) break; } if(res) { hd->attached_to = hd_card->idx; break; } } } hw_addr = free_mem(hw_addr); /* fix card type */ if(hd_card) { if( (hd_card->base_class.id == 0 && hd_card->sub_class.id == 0) || (hd_card->base_class.id == bc_network && hd_card->sub_class.id == 0x80) ) { switch(hd->sub_class.id) { case sc_nif_ethernet: hd_card->base_class.id = bc_network; hd_card->sub_class.id = 0; break; case sc_nif_usb: hd_card->base_class.id = bc_network; hd_card->sub_class.id = 0x91; break; } } } sf_dev = free_mem(sf_dev); } sf_cdev = free_mem(sf_cdev); sf_class = free_str_list(sf_class); if(hd_is_sgi_altix(hd_data)) add_xpnet(hd_data); add_uml(hd_data); add_kma(hd_data); /* add link status info & dump eeprom */ for(hd = hd_data->hd ; hd; hd = hd->next) { if( hd->module == hd_data->module && hd->base_class.id == bc_network_interface ) { char *buf = NULL; str_list_t *sl0, *sl; if(hd_probe_feature(hd_data, pr_net_eeprom) && hd->unix_dev_name) { PROGRESS(2, 0, "eeprom dump"); str_printf(&buf, 0, "|/usr/sbin/ethtool -e %s 2>/dev/null", hd->unix_dev_name); if((sl0 = read_file(buf, 0, 0))) { ADD2LOG("----- %s %s -----\n", hd->unix_dev_name, "EEPROM dump"); for(sl = sl0; sl; sl = sl->next) { ADD2LOG("%s", sl->str); } ADD2LOG("----- %s end -----\n", "EEPROM dump"); free_str_list(sl0); } free(buf); } for(res = hd->res; res; res = res->next) { if(res->any.type == res_link) break; } if(!res) get_linkstate(hd_data, hd); if(!(hd_card = hd_get_device_by_idx(hd_data, hd->attached_to))) continue; for(res = hd->res; res; res = res->next) { if(res->any.type == res_link) break; } if(res) { for(res1 = hd_card->res; res1; res1 = res1->next) { if(res1->any.type == res_link) break; } if(res && !res1) { res1 = new_mem(sizeof *res1); res1->link.type = res_link; res1->link.state = res->link.state; add_res_entry(&hd_card->res, res1); } } } } }
void pcmcia_ctrl_read_data(hd_data_t *hd_data) { hd_t *hd, *bridge_hd; char *s; unsigned u; unsigned sockets[16 /* just large enough */] = { }; str_list_t *sf_class, *sf_class_e; char *sf_cdev = NULL, *sf_dev; sf_class = reverse_str_list(read_dir("/sys/class/pcmcia_socket", 'd')); if(!sf_class) { ADD2LOG("sysfs: no such class: pcmcia_socket\n"); } else { for(sf_class_e = sf_class; sf_class_e; sf_class_e = sf_class_e->next) { str_printf(&sf_cdev, 0, "/sys/class/pcmcia_socket/%s", sf_class_e->str); sf_dev = new_str(hd_read_sysfs_link(sf_cdev, "device")); if( sf_dev && sscanf(sf_class_e->str, "pcmcia_socket%u", &u) == 1 ) { s = hd_sysfs_id(sf_dev); hd = hd_find_sysfs_id(hd_data, s); if(hd && u < sizeof sockets / sizeof *sockets) sockets[u] = hd->idx; ADD2LOG(" pcmcia socket %u: %s\n", u, s); } free_mem(sf_dev); } sf_cdev = free_mem(sf_cdev); } sf_class = free_str_list(sf_class); /* find card bus devices & assign them socket numbers */ for(hd = hd_data->hd; hd; hd = hd->next) { if(hd->bus.id != bus_pcmcia) continue; if((bridge_hd = hd_get_device_by_idx(hd_data, hd->attached_to))) { if( bridge_hd->base_class.id == bc_bridge && bridge_hd->sub_class.id == sc_bridge_cardbus ) { hd->hotplug = hp_cardbus; } else if( bridge_hd->base_class.id == bc_bridge && bridge_hd->sub_class.id == sc_bridge_pcmcia ) { hd->hotplug = hp_pcmcia; } for(u = 0; u < sizeof sockets / sizeof *sockets; u++) { if(sockets[u] == bridge_hd->idx) { hd->hotplug_slot = u + 1; } } } } }