Beispiel #1
0
void int_legacy_geo(hd_data_t *hd_data)
{
  hd_t *hd;
  hd_res_t *res;
  int id;
  char *s;
  edd_info_t *ei;

  if(!hd_data->edd) 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
    ) {
      id = strtol(hd->rom_id, &s, 0) - 0x80;
      if(*s || id < 0 || id >= sizeof hd_data->edd / sizeof *hd_data->edd) continue;

      ei = hd_data->edd + id;

      if(ei->edd.cyls) {
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
        res->disk_geo.type = res_disk_geo;
        res->disk_geo.cyls = ei->edd.cyls;
        res->disk_geo.heads = ei->edd.heads;
        res->disk_geo.sectors = ei->edd.sectors;
        res->disk_geo.size = ei->sectors;
        res->disk_geo.geotype = geo_bios_edd;
      }

      if(ei->legacy.cyls) {
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
        res->disk_geo.type = res_disk_geo;
        res->disk_geo.cyls = ei->legacy.cyls;
        res->disk_geo.heads = ei->legacy.heads;
        res->disk_geo.sectors = ei->legacy.sectors;
        res->disk_geo.geotype = geo_bios_legacy;
      }

    }
  }
}
Beispiel #2
0
/*
 * Remove usb entries that are handled by usb-storage.
 */
void int_fix_usb_scsi(hd_data_t *hd_data)
{
  hd_t *hd_scsi, *hd_usb;

  for(hd_usb = hd_data->hd; hd_usb; hd_usb= hd_usb->next) {
    if(
      hd_usb->bus.id == bus_usb &&
      hd_usb->sysfs_id &&
      search_str_list(hd_usb->drivers, "usb-storage")
    ) {
      for(hd_scsi = hd_data->hd; hd_scsi; hd_scsi = hd_scsi->next) {
        if(
          hd_scsi->bus.id == bus_scsi &&
          hd_scsi->sysfs_device_link &&
          search_str_list(hd_scsi->drivers, "usb-storage")
        ) {
          if(!strncmp(hd_scsi->sysfs_device_link, hd_usb->sysfs_id, strlen(hd_usb->sysfs_id))) {
            hd_set_hw_class(hd_scsi, hw_usb);

            free_mem(hd_scsi->unique_id);
            hd_scsi->unique_id = hd_usb->unique_id;
            hd_usb->unique_id = NULL;

            add_res_entry(&hd_scsi->res, hd_usb->res);
            hd_usb->res = NULL;

            if(!hd_scsi->modalias) {
              hd_scsi->modalias = hd_usb->modalias;
              hd_usb->modalias = NULL;
            }

            if(!hd_scsi->vendor.id) hd_scsi->vendor.id = hd_usb->vendor.id;
            if(!hd_scsi->device.id) hd_scsi->device.id = hd_usb->device.id;

            if(!hd_scsi->serial) {
              hd_scsi->serial = hd_usb->serial;
              hd_usb->serial = NULL;
            }

            if(!hd_scsi->driver_info) {
              hd_scsi->driver_info = hd_usb->driver_info;
              hd_usb->driver_info = NULL;
            }

            new_id(hd_data, hd_scsi);

            hd_usb->tag.remove = 1;
          }
        }
      }
    }
  }

  remove_tagged_hd_entries(hd_data);
}
Beispiel #3
0
void get_usb_devs(hd_data_t *hd_data)
{
  uint64_t ul0;
  unsigned u1, u2, u3;
  hd_t *hd, *hd1;
  usb_t *usb;
  str_list_t *sl, *usb_devs = NULL;
  char *s, *s1, *t;
  hd_res_t *res;
  size_t l;
  str_list_t *sf_bus, *sf_bus_e;
  char *sf_dev, *sf_dev_2;

  sf_bus = read_dir("/sys/bus/usb/devices", 'l');

  if(!sf_bus) {
    ADD2LOG("sysfs: no such bus: usb\n");
    return;
  }

  for(sf_bus_e = sf_bus; sf_bus_e; sf_bus_e = sf_bus_e->next) {
    sf_dev = hd_read_sysfs_link("/sys/bus/usb/devices", sf_bus_e->str);

    if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "bNumInterfaces"), &ul0, 0)) {
      add_str_list(&usb_devs, sf_dev);
      ADD2LOG("  usb dev: %s\n", hd_sysfs_id(sf_dev));
    }
  }

  for(sf_bus_e = sf_bus; sf_bus_e; sf_bus_e = sf_bus_e->next) {
    sf_dev = new_str(hd_read_sysfs_link("/sys/bus/usb/devices", sf_bus_e->str));

    ADD2LOG(
      "  usb device: name = %s\n    path = %s\n",
      sf_bus_e->str,
      hd_sysfs_id(sf_dev)
    );

    if(
      hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "bInterfaceNumber"), &ul0, 16)
    ) {
      hd = add_hd_entry(hd_data, __LINE__, 0);

      hd->detail = new_mem(sizeof *hd->detail);
      hd->detail->type = hd_detail_usb;
      hd->detail->usb.data = usb = new_mem(sizeof *usb);

      hd->sysfs_id = new_str(hd_sysfs_id(sf_dev));
      hd->sysfs_bus_id = new_str(sf_bus_e->str);

      hd->bus.id = bus_usb;
      hd->func = ul0;

      usb->ifdescr = ul0;

      if((s = get_sysfs_attr_by_path(sf_dev, "modalias"))) {
        s = canon_str(s, strlen(s));
        ADD2LOG("    modalias = \"%s\"\n", s);
        if(s && *s) {
          hd->modalias = s;
          s = NULL;
        }
        s = free_mem(s);
      }

      ADD2LOG("    bInterfaceNumber = %u\n", hd->func);

      if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "bInterfaceClass"), &ul0, 16)) {
        usb->i_cls = ul0;
        ADD2LOG("    bInterfaceClass = %u\n", usb->i_cls);
      }

      if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "bInterfaceSubClass"), &ul0, 16)) {
        usb->i_sub = ul0;
        ADD2LOG("    bInterfaceSubClass = %u\n", usb->i_sub);
      }

      if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "bInterfaceProtocol"), &ul0, 16)) {
        usb->i_prot = ul0;
        ADD2LOG("    bInterfaceProtocol = %u\n", usb->i_prot);
      }

      /* device has longest matching sysfs id */
      u2 = strlen(sf_dev);
      s = NULL;
      for(u3 = 0, sl = usb_devs; sl; sl = sl->next) {
        u1 = strlen(sl->str);
        if(u1 > u3 && u1 <= u2 && !strncmp(sf_dev, sl->str, u1)) {
          u3 = u1;
          s = sl->str;
        }
      }

      if(s) {
        ADD2LOG("    if: %s @ %s\n", hd->sysfs_bus_id, hd_sysfs_id(s));
        sf_dev_2 = new_str(s);
        if(sf_dev_2) {

          if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev_2, "bDeviceClass"), &ul0, 16)) {
            usb->d_cls = ul0;
            ADD2LOG("    bDeviceClass = %u\n", usb->d_cls);
          }

          if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev_2, "bDeviceSubClass"), &ul0, 16)) {
            usb->d_sub = ul0;
            ADD2LOG("    bDeviceSubClass = %u\n", usb->d_sub);
          }

          if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev_2, "bDeviceProtocol"), &ul0, 16)) {
            usb->d_prot = ul0;
            ADD2LOG("    bDeviceProtocol = %u\n", usb->d_prot);
          }

          if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev_2, "idVendor"), &ul0, 16)) {
            usb->vendor = ul0;
            ADD2LOG("    idVendor = 0x%04x\n", usb->vendor);
          }

          if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev_2, "idProduct"), &ul0, 16)) {
            usb->device = ul0;
            ADD2LOG("    idProduct = 0x%04x\n", usb->device);
          }

          if((s = get_sysfs_attr_by_path(sf_dev_2, "manufacturer"))) {
            usb->manufact = canon_str(s, strlen(s));
            ADD2LOG("    manufacturer = \"%s\"\n", usb->manufact);
          }

          if((s = get_sysfs_attr_by_path(sf_dev_2, "product"))) {
            usb->product = canon_str(s, strlen(s));
            ADD2LOG("    product = \"%s\"\n", usb->product);
          }

          if((s = get_sysfs_attr_by_path(sf_dev_2, "serial"))) {
            usb->serial = canon_str(s, strlen(s));
            ADD2LOG("    serial = \"%s\"\n", usb->serial);
          }

          if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev_2, "bcdDevice"), &ul0, 16)) {
            usb->rev = ul0;
            ADD2LOG("    bcdDevice = %04x\n", usb->rev);
          }

          if((s = get_sysfs_attr_by_path(sf_dev_2, "speed"))) {
            s = canon_str(s, strlen(s));
            if(!strcmp(s, "1.5")) usb->speed = 15*100000;
            else if(!strcmp(s, "12")) usb->speed = 12*1000000;
            else if(!strcmp(s, "480")) usb->speed = 480*1000000;
            ADD2LOG("    speed = \"%s\"\n", s);
            s = free_mem(s);
          }

          sf_dev_2 = free_mem(sf_dev_2);
        }
      }

      if(usb->vendor || usb->device) {
        hd->vendor.id = MAKE_ID(TAG_USB, usb->vendor);
        hd->device.id = MAKE_ID(TAG_USB, usb->device);
      }

      if(usb->manufact) hd->vendor.name = new_str(usb->manufact);
      if(usb->product) hd->device.name = new_str(usb->product);
      if(usb->serial) hd->serial = new_str(usb->serial);

      if(usb->rev) str_printf(&hd->revision.name, 0, "%x.%02x", usb->rev >> 8, usb->rev & 0xff);

      if(usb->speed) {
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
        res->baud.type = res_baud;
        res->baud.speed = usb->speed;
      }

      s = hd_sysfs_find_driver(hd_data, hd->sysfs_id, 1);
      if(s) add_str_list(&hd->drivers, s);

      set_class_entries(hd_data, hd, usb);

      if(!hd_data->scanner_db) {
        hd_data->scanner_db = hd_module_list(hd_data, 1);
      }

      if(
        hd->drivers &&
        search_str_list(hd_data->scanner_db, hd->drivers->str)
      ) {
        hd->base_class.id = bc_scanner;
      }

      // ###### FIXME
      if(hd->base_class.id == bc_modem) {
        hd->unix_dev_name = new_str("/dev/ttyACM0");
      }
    }

    sf_dev = free_mem(sf_dev);
  }
Beispiel #4
0
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);
  }
}
Beispiel #5
0
void prop2hd(hd_data_t *hd_data, hd_t *hd, int status_only)
{
  hal_prop_t *prop, *list;
  hd_res_t *res;
  int i;
  unsigned u, u0, u1, u2, u3, u4;
  char *s;
  uint64_t u64_0, u64_1;
  str_list_t *sl;

  list = hd->persistent_prop;

  hd->config_string = prop2hd_str(list, "hwinfo.configstring");

  if((prop = hal_get_str(list, "hwinfo.configured"))) {
    hd->status.configured = value2key(status_names, prop->val.str);
  }

  if((prop = hal_get_str(list, "hwinfo.available"))) {
    hd->status.available_orig =
    hd->status.available = value2key(status_names, prop->val.str);
  }

  if((prop = hal_get_str(list, "hwinfo.needed"))) {
    hd->status.needed = value2key(status_names, prop->val.str);
  }

  if((prop = hal_get_str(list, "hwinfo.active"))) {
    hd->status.active = value2key(status_names, prop->val.str);
  }

  /*
   * if the status info is completely missing, fake some:
   * new hardware, autodetectable, not needed
   */
  if(
    !hd->status.configured &&
    !hd->status.available &&
    !hd->status.needed &&
    !hd->status.invalid
  ) {
    hd->status.configured = status_new;
    hd->status.available = status_yes;
    hd->status.needed = status_no;
  }
  if(!hd->status.active) hd->status.active = status_unknown;

  if(status_only || !list) return;

  hd->udi = prop2hd_str(list, "info.udi");
  hd->unique_id = prop2hd_str(list, "hwinfo.uniqueid");
  hd->parent_id = prop2hd_str(list, "hwinfo.parentid");
  hd->child_ids = prop2hd_list(list, "hwinfo.childids");
  hd->model = prop2hd_str(list, "hwinfo.model");

  if((prop = hal_get_str(list, "hwinfo.hwclass"))) {
    hd->hw_class = value2key(hw_items, prop->val.str);
  }

  hd->broken = prop2hd_int32(list, "hwinfo.broken");

  hd->bus.id = prop2hd_int32(list, "hwinfo.busid");
  hd->slot = prop2hd_int32(list, "hwinfo.slot");
  hd->func = prop2hd_int32(list, "hwinfo.func");

  hd->base_class.id = prop2hd_int32(list, "hwinfo.baseclass");
  hd->sub_class.id = prop2hd_int32(list, "hwinfo.subclass");
  hd->prog_if.id = prop2hd_int32(list, "hwinfo.progif");

  hd->revision.id = prop2hd_int32(list, "hwinfo.revisionid");
  hd->revision.name = prop2hd_str(list, "hwinfo.revisionname");

  hd->vendor.id = prop2hd_int32(list, "hwinfo.vendorid");
  hd->vendor.name = prop2hd_str(list, "hwinfo.vendorname");

  hd->device.id = prop2hd_int32(list, "hwinfo.deviceid");
  hd->device.name = prop2hd_str(list, "hwinfo.devicename");

  hd->sub_vendor.id = prop2hd_int32(list, "hwinfo.subvendorid");
  hd->sub_vendor.name = prop2hd_str(list, "hwinfo.subvendorname");

  hd->sub_device.id = prop2hd_int32(list, "hwinfo.subdeviceid");
  hd->sub_device.name = prop2hd_str(list, "hwinfo.subdevicename");

  hd->compat_device.id = prop2hd_int32(list, "hwinfo.compatdeviceid");
  hd->compat_device.name = prop2hd_str(list, "hwinfo.compatdevicename");

  hd->serial = prop2hd_str(list, "hwinfo.serial");
  hd->unix_dev_name = prop2hd_str(list, "hwinfo.unixdevice");
  hd->unix_dev_name2 = prop2hd_str(list, "hwinfo.unixdevicealt");

  hd->unix_dev_names = prop2hd_list(list, "hwinfo.unixdevicelist");
  hd->drivers = prop2hd_list(list, "hwinfo.drivers");

  hd->sysfs_id = prop2hd_str(list, "hwinfo.sysfsid");
  hd->sysfs_bus_id = prop2hd_str(list, "hwinfo.sysfsbusid");
  hd->sysfs_device_link = prop2hd_str(list, "hwinfo.sysfslink");
  hd->rom_id = prop2hd_str(list, "hwinfo.romid");
  hd->usb_guid = prop2hd_str(list, "hwinfo.usbguid");
  hd->hotplug = prop2hd_int32(list, "hwinfo.hotplug");

  if((s = hal_get_useful_str(list, "hwinfo.hwclasslist"))) {
    for(u = 0; u < sizeof hd->hw_class_list / sizeof *hd->hw_class_list; u++) {
      if(*s && s[1] && (i = hex(s, 2)) >= 0) {
        hd->hw_class_list[u] = i;
        s += 2;
      }
      else {
        break;
      }
    }
  }

  u = prop2hd_int32(list, "hwinfo.features");
  if(u & (1 << 0)) hd->is.agp = 1;
  if(u & (1 << 1)) hd->is.isapnp = 1;
  if(u & (1 << 2)) hd->is.softraiddisk = 1;
  if(u & (1 << 3)) hd->is.zip = 1;
  if(u & (1 << 4)) hd->is.cdr = 1;
  if(u & (1 << 5)) hd->is.cdrw = 1;
  if(u & (1 << 6)) hd->is.dvd = 1;
  if(u & (1 << 7)) hd->is.dvdr = 1;
  if(u & (1 << 8)) hd->is.dvdram = 1;
  if(u & (1 << 9)) hd->is.pppoe = 1;
  if(u & (1 << 10)) hd->is.wlan = 1;


  if((prop = hal_get_list(list, "hwinfo.res.memory"))) {
    for(sl = prop->val.list; sl; sl = sl->next) {
      if(sscanf(sl->str, "0x%"SCNx64",0x%"SCNx64",%u,%u,%u", &u64_0, &u64_1, &u0, &u1, &u2) == 5) {
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
        res->any.type = res_mem;
        res->mem.base = u64_0;
        res->mem.range = u64_1;
        res->mem.enabled = u0;
        res->mem.access = u1;
        res->mem.prefetch = u2;
      }
    }
  }

  if((prop = hal_get_list(list, "hwinfo.res.physmemory"))) {
    for(sl = prop->val.list; sl; sl = sl->next) {
      if(sscanf(sl->str, "0x%"SCNx64"", &u64_0) == 1) {
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
        res->any.type = res_phys_mem;
        res->phys_mem.range = u64_0;
      }
    }
  }

  if((prop = hal_get_list(list, "hwinfo.res.io"))) {
    for(sl = prop->val.list; sl; sl = sl->next) {
      if(sscanf(sl->str, "0x%"SCNx64",0x%"SCNx64",%u,%u", &u64_0, &u64_1, &u0, &u1) == 4) {
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
        res->any.type = res_io;
        res->io.base = u64_0;
        res->io.range = u64_1;
        res->io.enabled = u0;
        res->io.access = u1;
      }
    }
  }

  if((prop = hal_get_list(list, "hwinfo.res.interrupts"))) {
    for(sl = prop->val.list; sl; sl = sl->next) {
      if(sscanf(sl->str, "%u,%u,%u", &u0, &u1, &u2) == 3) {
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
        res->any.type = res_irq;
        res->irq.base = u0;
        res->irq.triggered = u1;
        res->irq.enabled = u2;
      }
    }
  }

  if((prop = hal_get_list(list, "hwinfo.res.dma"))) {
    for(sl = prop->val.list; sl; sl = sl->next) {
      if(sscanf(sl->str, "%u,%u", &u0, &u1) == 2) {
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
        res->any.type = res_dma;
        res->dma.base = u0;
        res->dma.enabled = u1;
      }
    }
  }

  if((prop = hal_get_list(list, "hwinfo.res.size"))) {
    for(sl = prop->val.list; sl; sl = sl->next) {
      if(sscanf(sl->str, "%u,%u,%u", &u0, &u1, &u2) == 3) {
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
        res->any.type = res_size;
        res->size.unit = u0;
        res->size.val1 = u1;
        res->size.val2 = u2;
      }
    }
  }

  if((prop = hal_get_list(list, "hwinfo.res.baud"))) {
    for(sl = prop->val.list; sl; sl = sl->next) {
      if(sscanf(sl->str, "%u,%u,%u,%u,%u", &u0, &u1, &u2, &u3, &u4) == 5) {
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
        res->any.type = res_baud;
        res->baud.speed = u0;
        res->baud.bits = u1;
        res->baud.stopbits = u2;
        res->baud.parity = (char) u3;
        res->baud.handshake = (char) u4;
      }
    }
  }

  if((prop = hal_get_list(list, "hwinfo.res.cache"))) {
    for(sl = prop->val.list; sl; sl = sl->next) {
      if(sscanf(sl->str, "%u", &u0) == 1) {
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
        res->any.type = res_cache;
        res->cache.size = u0;
      }
    }
  }

  if((prop = hal_get_list(list, "hwinfo.res.diskgeometry"))) {
    for(sl = prop->val.list; sl; sl = sl->next) {
      if(sscanf(sl->str, "%u,%u,%u,%u", &u0, &u1, &u2, &u3) == 4) {
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
        res->any.type = res_disk_geo;
        res->disk_geo.cyls = u0;
        res->disk_geo.heads = u1;
        res->disk_geo.sectors = u2;
        res->disk_geo.geotype = u3;
      }
    }
  }

  if((prop = hal_get_list(list, "hwinfo.res.monitor"))) {
    for(sl = prop->val.list; sl; sl = sl->next) {
      if(sscanf(sl->str, "%u,%u,%u,%u", &u0, &u1, &u2, &u3) == 4) {
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
        res->any.type = res_monitor;
        res->monitor.width = u0;
        res->monitor.height = u1;
        res->monitor.vfreq = u2;
        res->monitor.interlaced = u3;
      }
    }
  }

  if((prop = hal_get_list(list, "hwinfo.res.framebuffer"))) {
    for(sl = prop->val.list; sl; sl = sl->next) {
      if(sscanf(sl->str, "%u,%u,%u,%u,%u", &u0, &u1, &u2, &u3, &u4) == 5) {
        res = add_res_entry(&hd->res, new_mem(sizeof *res));
        res->any.type = res_framebuffer;
        res->framebuffer.width = u0;
        res->framebuffer.height = u1;
        res->framebuffer.bytes_p_line = u2;
        res->framebuffer.colorbits = u3;
        res->framebuffer.mode = u4;
      }
    }
  }

  hddb_add_info(hd_data, hd);

}
Beispiel #6
0
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);
        }
      }
    }
  }
}
Beispiel #7
0
void hd_scan_serial(hd_data_t *hd_data)
{
  hd_t *hd, *hd2;
  serial_t *ser, *next;
  hd_res_t *res, *res2;
  int i;
  char buf[4], *skip_dev[16];
  str_list_t *sl, *cmd;
  unsigned skip_devs = 0;

  if(!hd_probe_feature(hd_data, pr_serial)) return;

  hd_data->module = mod_serial;

  /* some clean-up */
  remove_hd_entries(hd_data);
  hd_data->serial = NULL;

  PROGRESS(1, 0, "read info");

  get_serial_info(hd_data);
  if((hd_data->debug & HD_DEB_SERIAL)) dump_serial_data(hd_data);

  for(i = 0; i < 2; i++) {
    cmd = get_cmdline(hd_data, i == 0 ? "yast2ser" : "console");
    for(sl = cmd; sl; sl = sl->next) {
      if(sscanf(sl->str, "tty%3[^,]", buf) == 1) {
        if(buf[1] == 0) {
          switch(*buf) {
            case 'a': strcpy(buf, "S0"); break;
            case 'b': strcpy(buf, "S1"); break;
          }
        }
        if(skip_devs < sizeof skip_dev / sizeof *skip_dev) {
          skip_dev[skip_devs] = NULL;
          str_printf(&skip_dev[skip_devs++], 0, "/dev/tty%s", buf);
        }
      }
    }
    free_str_list(cmd);
  }

  PROGRESS(2, 0, "build list");

  for(ser = hd_data->serial; ser; ser = ser->next) {
    hd = add_hd_entry(hd_data, __LINE__, 0);
    hd->base_class.id = bc_comm;
    hd->sub_class.id = sc_com_ser;
    hd->prog_if.id = 0x80;
    for(i = 0; (unsigned) i < sizeof ser_names / sizeof *ser_names; i++) {
      if(strstr(ser->name, ser_names[i])) hd->prog_if.id = i;
    }
    hd->device.name = new_str(ser->name);
    hd->func = ser->line;
    if(ser->name && !strcmp(ser->name, "AgereModem")) {
      str_printf(&hd->unix_dev_name, 0, "/dev/ttyAGS%u", ser->line);
    }
    else {
      str_printf(&hd->unix_dev_name, 0, "/dev/ttyS%u", ser->line);
    }
    for(i = 0; i < (int) skip_devs; i++) {
      if(!strcmp(skip_dev[i], hd->unix_dev_name)) {
        hd->tag.skip_mouse = hd->tag.skip_modem = hd->tag.skip_braille = 1;
        break;
      }
    }
    if(ser->device) {
      if(strstr(ser->device, "modem-printer")) {
        hd->tag.ser_device = 1;
      }
      else if(strstr(ser->device, "infrared")) {
         hd->tag.ser_device = 2;
      }
      else if(strstr(ser->device, "modem")) {
         hd->tag.ser_device = 3;
      }
    }
    if(ser->baud) {
      res = add_res_entry(&hd->res, new_mem(sizeof *res));
      res->baud.type = res_baud;
      res->baud.speed = ser->baud;
    }
    res = add_res_entry(&hd->res, new_mem(sizeof *res));
    res->io.type = res_io;
    res->io.enabled = 1;
    res->io.base = ser->port;
    res->io.access = acc_rw;

    res = add_res_entry(&hd->res, new_mem(sizeof *res));
    res->irq.type = res_irq;
    res->irq.enabled = 1;
    res->irq.base = ser->irq;

    /* skip Dell Remote Access Cards - bug #145051 */
    for(hd2 = hd_data->hd; hd2; hd2 = hd2->next) {
      if(
        hd2->vendor.id == MAKE_ID(TAG_PCI, 0x1028) && /* Dell */
        hd2->device.id >= MAKE_ID(TAG_PCI, 0x07) &&
        hd2->device.id <= MAKE_ID(TAG_PCI, 0x12) /* range that covers DRACs */
      ) {
        for(res2 = hd2->res; res2; res2 = res2->next) {
          if(
            res2->any.type == res_io &&
            ser->port >= res2->io.base &&
            ser->port < res2->io.base + res2->io.range
          ) {
            hd->tag.skip_mouse = hd->tag.skip_modem = hd->tag.skip_braille = 1;
          }
        }
      }
    }
  }

  for(ser = hd_data->serial; ser; ser = next) {
    next = ser->next;

    free_mem(ser->name);
    free_mem(ser->device);
    free_mem(ser);
  }
  hd_data->serial = NULL;

#if 0
  if(hd_module_is_active(hd_data, "irda")) {
    hd = add_hd_entry(hd_data, __LINE__, 0); 
    hd->base_class.id = bc_comm;
    hd->sub_class.id = sc_com_ser;
    hd->prog_if.id = 0x80;
    hd->device.name = new_str("IrDA Serial");
    hd->unix_dev_name = new_str("/dev/ircomm0");
  }
#endif
}
Beispiel #8
0
/*
 * read /proc/interrupts
 *
 * This is somewhat more tricky, as the irq event counts are done separately
 * per cpu *and* there may be irq sharing.
 */
void read_irqs(misc_t *m)
{
  char buf[100], buf2[100], *s;
  misc_irq_t *ir;
  int i, j;
  unsigned u, v, k;
  str_list_t *sl;

  if(!(m->proc_irq = read_file(PROC_INTERRUPTS, 1, 0))) return;

  for(sl = m->proc_irq; sl; sl = sl->next) {
    /* irq */
    i = 0;
    if(sscanf(sl->str, " %u: %n", &u, &i) < 1) continue;
    v = 0;
    j = i;
    /* add up all event counters */
    while(j < (int) strlen(sl->str) && sscanf(sl->str + j, " %u %n", &k, &i) >= 1) {
      if(!i) break;
      v += k;
      j += i;
    }
    /* device driver name string */
#if defined(__PPC__)
    if(
      sscanf(sl->str + j, " %*s Edge %99[^\n]", buf) == 1 ||
      sscanf(sl->str + j, " %*s Level %99[^\n]", buf) == 1 ||
      sscanf(sl->str + j, " %*s %99[^\n]", buf) == 1
    ) {
#else
#if defined(__alpha__) || defined(__sparc__)
    if(sscanf(sl->str + j, " %99[^\n]", buf) == 1) {
#else	/* __i386__ || __x86_64__ || __ia64__ */
    if(sscanf(sl->str + j, " %*s %99[^\n]", buf) == 1) {
#endif
#endif
      m->irq = add_mem(m->irq, sizeof *m->irq, m->irq_len);
      ir = m->irq + m->irq_len++;
      ir->irq = u;
      ir->events = v;

      /* split device driver names (separated by ',') */
      s = buf;
      while(*s && sscanf(s, " %99[^,] %n", buf2, &j) >= 1) {
        ir->dev = add_mem(ir->dev, sizeof *ir->dev, ir->devs);
        ir->dev[ir->devs++] = new_str(buf2);
        s += j;
        if(*s) s++;	/* skip ',' */
      }
    }
  }
}

void gather_resources(misc_t *m, hd_res_t **r, char *name, unsigned which)
{
  int i, j;
  hd_res_t *res;

  if(!m) return;

  if(!which) which = W_IO | W_DMA | W_IRQ;

  if((which & W_IO)) for(i = 0; (unsigned) i < m->io_len; i++) {
    if(!strcmp(name, m->io[i].dev)) {
      res = add_res_entry(r, new_mem(sizeof **r));
      res->io.type = res_io;
      res->io.enabled = 1;
      res->io.base = m->io[i].addr;
      res->io.range = m->io[i].size;
      res->io.access = acc_rw;
      m->io[i].tag++;
    }
  }

  if((which & W_DMA)) for(i = 0; (unsigned) i < m->dma_len; i++) {
    if(!strcmp(name, m->dma[i].dev)) {
      res = add_res_entry(r, new_mem(sizeof **r));
      res->dma.type = res_dma;
      res->dma.enabled = 1;
      res->dma.base = m->dma[i].channel;
      m->dma[i].tag++;
    }
  }

  if((which & W_IRQ)) for(i = 0; (unsigned) i < m->irq_len; i++) {
    for(j = 0; j <  m->irq[i].devs; j++) {
      if(!strcmp(name, m->irq[i].dev[j])) {
        res = add_res_entry(r, new_mem(sizeof **r));
        res->irq.type = res_irq;
        res->irq.enabled = 1;
        res->irq.base = m->irq[i].irq;
        res->irq.triggered = m->irq[i].events;
        m->irq[i].tag++;
      }
    }
  }
}


int active_vga_card(hd_t *hd)
{
  hd_res_t *res;

  if(hd->bus.id != bus_pci) return 1;

  for(res = hd->res; res; res = res->next) {
    if(
      (res->mem.type == res_mem && res->mem.enabled) ||
      (res->io.type == res_io && res->io.enabled)
    ) return 1;
  }

  return 0;
}
Beispiel #9
0
void hd_scan_misc(hd_data_t *hd_data)
{
  hd_t *hd;
  hd_res_t *res;
  int fd, i;
  char *s = NULL;
  bios_info_t *bt = NULL;
  char par[] = "parport0";
  int fd_ser0, fd_ser1;

  if(!hd_probe_feature(hd_data, pr_misc)) return;

  hd_data->module = mod_misc;

  /* some clean-up */
  remove_hd_entries(hd_data);
  hd_data->misc = free_misc(hd_data->misc);

  PROGRESS(9, 0, "kernel log");
  read_klog(hd_data);
  if((hd_data->debug & HD_DEB_MISC)) dump_klog(hd_data);

  PROGRESS(1, 0, "misc data");
  hd_data->misc = new_mem(sizeof *hd_data->misc);

  /* this is enough to load the module */
  fd_ser0 = fd_ser1 = -1;

#if !defined(__sparc__)
  /* On sparc, the close needs too long */
  if(hd_probe_feature(hd_data, pr_misc_serial)) {
    PROGRESS(1, 1, "open serial");
    fd_ser0 = open("/dev/ttyS0", O_RDONLY | O_NONBLOCK);
    fd_ser1 = open("/dev/ttyS1", O_RDONLY | O_NONBLOCK);
    /* keep the devices open until the resources have been read */
  }
#endif

  /* this is enough to load the module */
  if(!hd_data->flags.no_parport && hd_probe_feature(hd_data, pr_misc_par)) {
    PROGRESS(1, 2, "open parallel");
    /* what can the BIOS tell us? */
    for(hd = hd_data->hd; hd; hd = hd->next) {
      if(
        hd->base_class.id == bc_internal &&
        hd->sub_class.id == sc_int_bios &&
        hd->detail &&
        hd->detail->type == hd_detail_bios &&
        hd->detail->bios.data
      ) break;
    }
    if(hd) {
      bt = hd->detail->bios.data;
      if(bt->par_port0) {
        str_printf(&s, 0, "io=0x%x", bt->par_port0);
        if(bt->par_port1) {
          str_printf(&s, -1, ",0x%x", bt->par_port1);
          if(bt->par_port2) str_printf(&s, -1, ",0x%x", bt->par_port2);
        }
	str_printf(&s, -1, " irq=none,none,none");
      }
      unload_module(hd_data, "parport_probe");
      unload_module(hd_data, "lp");
      unload_module(hd_data, "parport_pc");
      unload_module(hd_data, "parport");

      /* now load it with the right io */
      load_module(hd_data, "parport");
      load_module_with_params(hd_data, "parport_pc", s);
      free_mem(s);
    }
    /* now load the rest of the modules */
    fd = open("/dev/lp0", O_RDONLY | O_NONBLOCK);
    if(fd >= 0) close(fd);
  }

  /*
   * floppy driver resources are allocated only temporarily,
   * so we access it just before we read the resources
   */
  if(hd_probe_feature(hd_data, pr_misc_floppy)) {
    /* look for a floppy *device* entry... */
    for(hd = hd_data->hd; hd; hd = hd->next) {
      if(
        hd->base_class.id == bc_storage_device &&
        hd->sub_class.id == sc_sdev_floppy &&
        hd->unix_dev_name &&
        !strncmp(hd->unix_dev_name, "/dev/fd", sizeof "/dev/fd" - 1)
      ) {

        PROGRESS(1, 3, "read floppy");
        i = 5;
        hd->block0 = read_block0(hd_data, hd->unix_dev_name, &i);
        hd->is.notready = hd->block0 ? 0 : 1;
        if(i < 0) {
          hd->tag.remove = 1;
          ADD2LOG("misc.floppy: removing floppy entry %u (timed out)\n", hd->idx);
        }

        if(!hd->is.notready) {
          struct hd_geometry geo;
          int fd;
          unsigned size, blk_size = 0x200;

          fd = open(hd->unix_dev_name, O_RDONLY | O_NONBLOCK);
          if(fd >= 0) {
            if(!ioctl(fd, HDIO_GETGEO, &geo)) {
              ADD2LOG("floppy ioctl(geo) ok\n");
              res = add_res_entry(&hd->res, new_mem(sizeof *res));
              res->disk_geo.type = res_disk_geo;
              res->disk_geo.cyls = geo.cylinders;
              res->disk_geo.heads = geo.heads;
              res->disk_geo.sectors = geo.sectors;
              res->disk_geo.geotype = geo_logical;
              size = geo.cylinders * geo.heads * geo.sectors;
              for(res = hd->res; res; res = res->next) {
                if(res->any.type == res_size && res->size.unit == size_unit_sectors) {
                  res->size.val1 = size; res->size.val2 = blk_size;
                  break;
                }
              }
              if(!res) {
                res = add_res_entry(&hd->res, new_mem(sizeof *res));
                res->size.type = res_size;
                res->size.unit = size_unit_sectors;
                res->size.val1 = size; res->size.val2 = blk_size;
              }
            }
            close(fd);
          }
        }

        break;
      }
    }
    remove_tagged_hd_entries(hd_data);
  }

  PROGRESS(2, 1, "io");
  read_ioports(hd_data->misc);

  PROGRESS(2, 2, "dma");
  read_dmas(hd_data->misc);

  PROGRESS(2, 3, "irq");
  read_irqs(hd_data->misc);

  if((hd_data->debug & HD_DEB_MISC)) dump_misc_proc_data(hd_data);

  if(fd_ser0 >= 0) close(fd_ser0);
  if(fd_ser1 >= 0) close(fd_ser1);

  /* now create some system generic entries */

  /* FPU */
  PROGRESS(3, 0, "FPU");
  res = NULL;
  gather_resources(hd_data->misc, &res, "fpu", 0);
  if(res) {
    hd = add_hd_entry(hd_data, __LINE__, 0);
    hd->base_class.id = bc_internal;
    hd->sub_class.id = sc_int_fpu;
    hd->res = res;
  }

  /* DMA */
  PROGRESS(3, 1, "DMA");
  res = NULL;
  gather_resources(hd_data->misc, &res, "dma1", 0);
  gather_resources(hd_data->misc, &res, "dma2", 0);
  gather_resources(hd_data->misc, &res, "dma page reg", 0);
  gather_resources(hd_data->misc, &res, "cascade", W_DMA);
  if(res) {
    hd = add_hd_entry(hd_data, __LINE__, 0);
    hd->base_class.id = bc_system;
    hd->sub_class.id = sc_sys_dma;
    hd->res = res;
  }

  /* PIC */
  PROGRESS(3, 2, "PIC");
  res = NULL;
  gather_resources(hd_data->misc, &res, "pic1", 0);
  gather_resources(hd_data->misc, &res, "pic2", 0);
  gather_resources(hd_data->misc, &res, "cascade", W_IRQ);
  if(res) {
    hd = add_hd_entry(hd_data, __LINE__, 0);
    hd->base_class.id = bc_system;
    hd->sub_class.id = sc_sys_pic;
    hd->res = res;
  }

  /* timer */
  PROGRESS(3, 3, "timer");
  res = NULL;
  gather_resources(hd_data->misc, &res, "timer", 0);
  if(res) {
    hd = add_hd_entry(hd_data, __LINE__, 0);
    hd->base_class.id = bc_system;
    hd->sub_class.id = sc_sys_timer;
    hd->res = res;
  }

  /* real time clock */
  PROGRESS(3, 4, "RTC");
  res = NULL;
  gather_resources(hd_data->misc, &res, "rtc", 0);
  if(res) {
    hd = add_hd_entry(hd_data, __LINE__, 0);
    hd->base_class.id = bc_system;
    hd->sub_class.id = sc_sys_rtc;
    hd->res = res;
  }

  /* keyboard */
  res = NULL;
  gather_resources(hd_data->misc, &res, "keyboard", 0);
  if(res) {
    hd = add_hd_entry(hd_data, __LINE__, 0);
    hd->base_class.id = bc_input;
    hd->sub_class.id = sc_inp_keyb;
    hd->res = res;
  }

  /* parallel ports */
  for(i = 0; i < 1; i++, par[sizeof par - 2]++) {
    res = NULL;
    gather_resources(hd_data->misc, &res, par, 0);
    if(res) {
      hd = add_hd_entry(hd_data, __LINE__, 0);
      hd->base_class.id = bc_comm;
      hd->sub_class.id = sc_com_par;
      str_printf(&hd->unix_dev_name, 0, "/dev/lp%d", i);
      hd->res = res;
    }
  }

  /* floppy controller */
  res = NULL;
  gather_resources(hd_data->misc, &res, "floppy", 0);
  gather_resources(hd_data->misc, &res, "floppy DIR", 0);
  if(res) {
    /* look for an existing entry */
    for(hd = hd_data->hd; hd; hd = hd->next) {
      if(hd->base_class.id == bc_storage && hd->sub_class.id == sc_sto_floppy) break;
    }

    /* missing, so create one */
    if(!hd) {
      hd = add_hd_entry(hd_data, __LINE__, 0);
      hd->base_class.id = bc_storage;
      hd->sub_class.id = sc_sto_floppy;
    }

    hd->res = res;
  }

  /*
   * look for PS/2 port
   *
   * The catch is, that sometimes /dev/psaux is accessible only for root,
   * so the open() may fail but there are irq events registered.
   *
   */
  fd = open(DEV_PSAUX, O_RDONLY | O_NONBLOCK);
  if(fd >= 0) close(fd);

  res = NULL;
  gather_resources(hd_data->misc, &res, "PS/2 Mouse", 0);

  if(res || fd >= 0) {
    hd = add_hd_entry(hd_data, __LINE__, 0);
    hd->base_class.id = bc_ps2;

    if(res) {
      hd->res = res;
    }
  }
}
Beispiel #10
0
void hd_scan_misc2(hd_data_t *hd_data)
{
  hd_t *hd, *hd1;
  misc_t *m;
  hd_res_t *res, *res1, *res2;
  int i;

  if(!hd_probe_feature(hd_data, pr_misc)) return;

  hd_data->module = mod_misc;

  PROGRESS(5, 0, "misc data");

  /* create some more system generic entries */

  /* IDE */

// ###### add special ide detail to hd_t!!!
  res = NULL;
  gather_resources(hd_data->misc, &res, "ide0", 0);
  gather_resources(hd_data->misc, &res, "ide1", 0);
  gather_resources(hd_data->misc, &res, "ide2", 0);
  gather_resources(hd_data->misc, &res, "ide3", 0);
  if(res) {
    for(hd = hd_data->hd; hd; hd = hd->next) {
      if(
        hd->base_class.id == bc_storage &&
        hd->sub_class.id == sc_sto_ide &&
        have_common_res(hd->res, res)
      ) break;
    }
    if(!hd) {
      /* eg. non-PCI IDE controller */
      hd = add_hd_entry(hd_data, __LINE__, 0);
      hd->base_class.id = bc_storage;
      hd->sub_class.id = sc_sto_ide;
      hd->compat_vendor.id = MAKE_ID(TAG_SPECIAL, 0x3000);
      hd->compat_device.id = MAKE_ID(TAG_SPECIAL, 0x1000);
      /* use join_res to join the i/o ranges of ide0/1 */
      join_res_io(&hd->res, res);
      join_res_irq(&hd->res, res);
      join_res_dma(&hd->res, res);
      free_res_list(res);
    }
    else {
      /* eg. PCI IDE controller, add resources */
      join_res_io(&hd->res, res);
      join_res_irq(&hd->res, res);
      join_res_dma(&hd->res, res);
      free_res_list(res);
    }
  }

  /* VGA */
  res = NULL;
  gather_resources(hd_data->misc, &res, "vga+", 0);
  gather_resources(hd_data->misc, &res, "vesafb", 0);
  if(res) {
    for(i = 0, hd1 = NULL, hd = hd_data->hd; hd; hd = hd->next) {
      if(hd->base_class.id == bc_display && hd->sub_class.id == sc_dis_vga) {
        i++;
        hd1 = hd;
      }
    }
    if(i == 0) {
      /* non-PCI VGA card ??? - really, we shouldn't care... */
      /* FIX THIS !!! ############### */
#ifdef __alpha__
      free_res_list(res);
#else
      hd = add_hd_entry(hd_data, __LINE__, 0);
      hd->base_class.id = bc_display;
      hd->sub_class.id = sc_dis_vga;
      hd->res = res;
#endif
    }
    else if(i == 1) {
      /* 1 PCI vga card, add resources */
      join_res_io(&hd1->res, res);
      join_res_irq(&hd1->res, res);
      join_res_dma(&hd1->res, res);
      free_res_list(res);
      hd_data->display = hd1->idx;
    }
    else {
      /* more than 1: look again, now only 'active' cards */
      for(i = 0, hd1 = NULL, hd = hd_data->hd; hd; hd = hd->next) {
        if(
          hd->base_class.id == bc_display &&
          hd->sub_class.id == sc_dis_vga &&
          active_vga_card(hd)
        ) {
          i++;
          hd1 = hd;
        }
      }
      if(i == 1) {
        /* 'the' active PCI vga card, add resources */
        join_res_io(&hd1->res, res);
        join_res_irq(&hd1->res, res);
        join_res_dma(&hd1->res, res);
        hd_data->display = hd1->idx;
      }
      else {
       /* now, what??? */
       ADD2LOG("Oopy, could not figure out *the* active display adapter!\n");
      }
      free_res_list(res);
    }
  }

  /* serial ports */
  res = NULL;
  gather_resources(hd_data->misc, &res, "serial(auto)", 0);
  gather_resources(hd_data->misc, &res, "serial(set)", 0);
  gather_resources(hd_data->misc, &res, "serial", 0);
  for(hd = hd_data->hd; hd; hd = hd->next) {
    if(hd->base_class.id == bc_comm && hd->sub_class.id == sc_com_ser) {
      for(res1 = hd->res; res1; res1 = res1->next) {
        for(res2 = res; res2; res2 = res2->next) {
          if(res1->any.type == res2->any.type) {
            switch(res1->any.type) {
              case res_irq:
                if(res1->irq.base == res2->irq.base) {
                  res2->any.type = res_any;
                }
                break;
              case res_io:
                if(
                  res1->io.base == res2->io.base &&
                  (!res1->io.range || res1->io.range == res2->io.range)
                ) {
                  res1->io.range = res2->io.range;
                  res2->any.type = res_any;
                }
                break;
              default:		/* gcc -Wall */
		break;
            }
          }
        }
      }
    }
  }

  /* if any of the serial resources are unaccounted for, make an extra entry */
  for(res2 = res; res2; res2 = res2->next) {
    if(res2->any.type != res_any) {
      hd = add_hd_entry(hd_data, __LINE__, 0);
      hd->base_class.id = bc_comm;
      hd->sub_class.id = sc_com_ser;
      hd->prog_if.id = 0x80;
      for(; res2; res2 = res2->next) {
        if(res2->any.type != res_any) {
          res1 = add_res_entry(&hd->res, new_mem(sizeof *res));
          *res1 = *res2;
          res1->next = NULL;
        }
      }
      break;
    }
  }
  free_res_list(res);

  /* go through our list and assign event counts to irq entries */
  m = hd_data->misc;
  for(hd = hd_data->hd; hd; hd = hd->next) {
    for(res = hd->res; res; res = res->next) {
      if(res->irq.type == res_irq) {
        for(i = 0; (unsigned) i < m->irq_len; i++) {
          if(res->irq.base == m->irq[i].irq) {
            res->irq.triggered = m->irq[i].events;
            break;
          }
        }
      }
    }
  }

  /* look for entries with matching start address */
  m = hd_data->misc;
  for(hd = hd_data->hd; hd; hd = hd->next) {
    for(res = hd->res; res; res = res->next) {
      if(res->io.type == res_io) {
        for(i = 0; (unsigned) i < m->io_len; i++) {
          if(res->io.base == m->io[i].addr && res->io.range < m->io[i].size) {
            res->io.range = m->io[i].size;
            break;
          }
        }
      }
    }
  }

  if((hd_data->debug & HD_DEB_MISC)) dump_misc_data(hd_data);
}
Beispiel #11
0
void hd_scan_wlan(hd_data_t *hd_data)
{
  hd_t *hd;
  hd_res_t *res;
  struct iw_range range;
  int k;
  int skfd;
  struct wpa_driver_ops *wpa_drv=NULL;

  if(!hd_probe_feature(hd_data, pr_wlan)) return;

  hd_data->module = mod_wlan;

  PROGRESS(1, 0, "detecting wlan features");

  if ((skfd = iw_sockets_open()) < 0) {
    ADD2LOG( "could not open socket, wlan feature query failed\n" );
    return;
  }

  for(hd = hd_data->hd; hd; hd = hd->next) {
    if(
      hd->base_class.id == bc_network &&
      hd->unix_dev_name ) {
      /* Get list of frequencies / channels */
      if(iw_get_range_info(skfd, hd->unix_dev_name, &range) < 0) {
	/* this failed, maybe device does not support wireless extensions */
	continue;
      }
      ADD2LOG("*** device %s is wireless ***\n", hd->unix_dev_name);
      hd->is.wlan = 1;

      hd->sub_class.id = 0x82;		/* wlan */

      res = new_mem(sizeof *res);
      res->any.type = res_wlan;

      if(range.num_frequency > 0) {
	char buff[20];
	for(k = 0; k < range.num_frequency; k++) {
	  snprintf(buff, 19, "%i", range.freq[k].i);
	  add_str_list(&res->wlan.channels, buff);
	  snprintf(buff, 19, "%g", (float)iw_freq2float(&(range.freq[k]))/1000000000);
	  add_str_list(&res->wlan.frequencies, buff);
	}
	for(k = 0; k < range.num_bitrates; k++) {
	  snprintf(buff, 19, "%g", (float)range.bitrate[k]/1000000);
	  add_str_list(&res->wlan.bitrates, buff);
	}
	for(k = 0; k < range.num_encoding_sizes; k++) {
	  snprintf(buff, 19, "WEP%i", range.encoding_size[k]*8);
	  add_str_list(&res->wlan.enc_modes, buff);
	}

	/* open mode is always supported */
	add_str_list(&res->wlan.auth_modes, "open");
	/* if WEP is supported, be assume shared key auth support */
	if(range.num_encoding_sizes) {
	  add_str_list(&res->wlan.auth_modes, "sharedkey");
	}

	/* detect WPA capabilities */
	if (!hd_data->flags.nowpa && hd->drivers) {
	  if (search_str_list(hd->drivers, "ath_pci"))
	    wpa_drv = &wpa_driver_madwifi_ops;
	  else if (strncmp(hd->drivers->str, "at76", 4)==0)
	    wpa_drv = &wpa_driver_atmel_ops;
	  else 
	    wpa_drv = &wpa_driver_wext_ops;
	}
	
	if (wpa_drv) {
	  if (wpa_drv->set_wpa(hd->unix_dev_name, 1) == 0) {
	    add_str_list(&res->wlan.auth_modes, "wpa-psk");
	    add_str_list(&res->wlan.auth_modes, "wpa-eap");
	    if (wpa_drv->set_auth_alg && 
		wpa_drv->set_auth_alg(hd->unix_dev_name, AUTH_ALG_LEAP)==0)
	      add_str_list(&res->wlan.auth_modes, "wpa-leap");
	    if (wpa_drv->set_key(hd->unix_dev_name, WPA_ALG_TKIP, "ff:ff:ff:ff:ff:ff",
				 0, 0, 0, 0,
				 "00000000000000000000000000000000", 32) ==0)
	      add_str_list(&res->wlan.enc_modes, "TKIP");
	    if (wpa_drv->set_key(hd->unix_dev_name, WPA_ALG_CCMP, "ff:ff:ff:ff:ff:ff",
				 0, 0, 0, 0, 
				 "0000000000000000", 16) ==0)
	      add_str_list(&res->wlan.enc_modes, "CCMP");
	    wpa_drv->set_wpa(hd->unix_dev_name, 0);
	  }
	}
      }
      add_res_entry(&hd->res, res);
    }
  }
}
Beispiel #12
0
void hd_scan_floppy(hd_data_t *hd_data)
{
  hd_t *hd;
  char b0[10], b1[10], c;
  unsigned u;
  int fd, i, floppy_ctrls = 0, floppy_ctrl_idx = 0;
  str_list_t *sl;
  hd_res_t *res;
  int floppy_stat[2] = { 1, 1 };
  unsigned floppy_created = 0;

  if(!hd_probe_feature(hd_data, pr_floppy)) return;

  hd_data->module = mod_floppy;

   /* some clean-up */
  remove_hd_entries(hd_data);
  hd_data->floppy = free_str_list(hd_data->floppy);

  PROGRESS(1, 0, "get nvram");

  /*
   * Look for existing floppy controller entries (typically there will be
   * *none*).
   */
  for(hd = hd_data->hd; hd; hd = hd->next) {
    if(hd->base_class.id == bc_storage && hd->sub_class.id == sc_sto_floppy) {
      floppy_ctrls++;
      floppy_ctrl_idx = hd->idx;
    }
  }

  /*
   * Is enough to load the nvram module.
   *
   * Note: although you must be root to access /dev/nvram, every
   * user can read /proc/nvram.
   */
  fd = open(DEV_NVRAM, O_RDONLY | O_NONBLOCK);
  if(fd >= 0) close(fd);

  if(
    !(hd_data->floppy = read_file(PROC_NVRAM_24, 0, 0)) &&
    !(hd_data->floppy = read_file(PROC_NVRAM_22, 0, 0))
  );

  if(hd_data->floppy && (hd_data->debug & HD_DEB_FLOPPY)) dump_floppy_data(hd_data);

  if(!hd_data->klog) read_klog(hd_data);

  for(sl = hd_data->klog; sl; sl = sl->next) {
    if(sscanf(sl->str, "<4>floppy%u: no floppy controllers foun%c", &u, &c) == 2) {
      if(u < sizeof floppy_stat / sizeof *floppy_stat) {
        floppy_stat[u] = 0;
      }
    }
  }

  if(hd_data->floppy) {
    PROGRESS(2, 0, "nvram info");
    sl = hd_data->floppy;
  }
  else {
    PROGRESS(2, 0, "klog info");
    sl = hd_data->klog;
  }

  for(; sl; sl = sl->next) {
    if(hd_data->floppy) {
      i = sscanf(sl->str, " Floppy %u type : %8[0-9.]'' %8[0-9.]%c", &u, b0, b1, &c) == 4;
    }
    else {
      i = sscanf(sl->str, "<6>Floppy drive(s): fd%u is %8[0-9.]%c", &u, b1, &c) == 3;
      *b0 = 0;
    }

    if(i) {
      if(
        !floppy_ctrls &&
        u < sizeof floppy_stat / sizeof *floppy_stat &&
        floppy_stat[u]
      ) {
        /* create one, if missing (there's no floppy without a controller...) */
        hd = add_hd_entry(hd_data, __LINE__, 0);
        hd->base_class.id = bc_storage;
        hd->sub_class.id = sc_sto_floppy;
        floppy_ctrl_idx = hd->idx;
        floppy_ctrls++;
      }

      if(floppy_ctrls && !(floppy_created & (1 << u))) {
        hd = add_hd_entry(hd_data, __LINE__, 0);
        hd->base_class.id = bc_storage_device;
        hd->sub_class.id = sc_sdev_floppy;
        hd->bus.id = bus_floppy;
        hd->slot = u;
        str_printf(&hd->unix_dev_name, 0, "/dev/fd%u", u);

        floppy_created |= 1 << u;

        if(*b0) {
          res = add_res_entry(&hd->res, new_mem(sizeof *res));
          res->size.type = res_size;
          res->size.val1 = str2float(b0, 2);
          res->size.unit = size_unit_cinch;
        }

        /* 'k' or 'M' */
        i = c == 'M' ? str2float(b1, 3) : str2float(b1, 0);

        res = add_res_entry(&hd->res, new_mem(sizeof *res));
        res->size.type = res_size;
        res->size.val1 = i << 1;
        res->size.val2 = 0x200;
        res->size.unit = size_unit_sectors;

        /* the only choice... */
        if(floppy_ctrls == 1) hd->attached_to = floppy_ctrl_idx;
      }
    }
  }
}