Esempio n. 1
0
/*
 * Go through serial mouse data and add hd entries.
 */
void add_serial_mouse(hd_data_t *hd_data)
{
  hd_t *hd;
  char buf[4];
  ser_device_t *sm;

  for(sm = hd_data->ser_mouse; sm; sm = sm->next) {
    if(sm->is_mouse) {
      hd = add_hd_entry(hd_data, __LINE__, 0);
      hd->base_class.id = bc_mouse;
      hd->sub_class.id = sc_mou_ser;
      hd->bus.id = bus_serial;
      hd->unix_dev_name = new_str(sm->dev_name);
      hd->attached_to = sm->hd_idx;
      if(*sm->pnp_id) {
        strncpy(buf, sm->pnp_id, 3);
        buf[3] = 0;
        hd->vendor.id = name2eisa_id(buf);
        if(!hd->vendor.id) {	/* in case it's a really strange one... */
          hd->vendor.name = new_str(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) {
          free_mem(hd->vendor.name);
          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);
            }
          }
        }
      }
      else {
        hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x0200);
        hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0003);
      }
    }
  }
}
Esempio n. 2
0
void hd_scan_veth(hd_data_t *hd_data)
{
  unsigned u;
  hd_t *hd;
  DIR *dir;
  struct dirent *de;

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

  hd_data->module = mod_veth;

  /* some clean-up */
  remove_hd_entries(hd_data);

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

  if((dir = opendir(PROC_ISERIES_VETH))) {
    while((de = readdir(dir))) {
      if(sscanf(de->d_name, "veth%u", &u) == 1) {
        hd = add_hd_entry(hd_data, __LINE__, 0);
        hd->base_class.id = bc_network;
        hd->slot = u;
        hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x6001);	// IBM
        hd->device.id = MAKE_ID(TAG_SPECIAL, 0x1000);
        str_printf(&hd->device.name, 0, "Virtual Ethernet card %d", hd->slot);
      }
    }
    closedir(dir);
    return;
  }
  if((dir = opendir(PROC_ISERIES))) {
    hd = add_hd_entry(hd_data, __LINE__, 0);
    hd->base_class.id = bc_network;
    hd->slot = 0;
    hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x6001);	// IBM
    hd->device.id = MAKE_ID(TAG_SPECIAL, 0x1000);
    str_printf(&hd->device.name, 0, "Virtual Ethernet card %d", hd->slot);
  }

}
Esempio n. 3
0
static void get_sunmouse(hd_data_t *hd_data)
{
  hd_t *hd;
  int fd;
  int found;

  found = 0;

  /* Only search for Sun mouse if we have a Sun keyboard */
  for(hd = hd_data->hd; hd; hd = hd->next)
    {
      if(hd->base_class.id == bc_keyboard &&
	 hd->sub_class.id == sc_keyboard_kbd &&
	 ID_TAG(hd->vendor.id) == TAG_SPECIAL && ID_VALUE(hd->vendor.id) == 0x0202)
	found = 1;
    }

  if (found)
    {
      if ((fd = open(DEV_SUNMOUSE, O_RDONLY)) != -1)
	{
	  /* FIXME: Should probably talk to the mouse to see
	     if the connector is not empty. */
	  close (fd);

	  PROGRESS(1, 1, "Sun Mouse");

	  hd = add_hd_entry (hd_data, __LINE__, 0);
	  hd->base_class.id = bc_mouse;
	  hd->sub_class.id = sc_mou_sun;
	  hd->bus.id = bus_serial;
	  hd->unix_dev_name = new_str(DEV_SUNMOUSE);

	  hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x0202);
	  hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0000);
	}
    }
}
Esempio n. 4
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);
  }
Esempio n. 5
0
void hd_scan_manual(hd_data_t *hd_data)
{
  DIR *dir;
  struct dirent *de;
  int i, j;
  hd_t *hd, *hd1, *next, *hdm, **next2;
  char *s;
  char *udi_dir[] = { "/org/freedesktop/Hal/devices", "", "" };

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

  hd_data->module = mod_manual;

  /* some clean-up */
  remove_hd_entries(hd_data);

  for(hd = hd_data->manual; hd; hd = next) {
    next = hd->next; 
    hd->next = NULL;
    hd_free_hd_list(hd);
  }
  hd_data->manual = NULL;

  next2 = &hd_data->manual;

  s = NULL;
  for(j = 0; j < sizeof udi_dir / sizeof *udi_dir; j++) {
    str_printf(&s, 0, "%s%s", j == 2 ? "unique-keys" : "udi", udi_dir[j]);
    if((dir = opendir(hd_get_hddb_path(s)))) {
      i = 0;
      while((de = readdir(dir))) {
        if(*de->d_name == '.') continue;
        PROGRESS(1, ++i, "read");
        str_printf(&s, 0, "%s%s%s", udi_dir[j], *udi_dir[j] ? "/" : "", de->d_name);
        if((hd = hd_read_config(hd_data, s))) {
          if(hd->status.available != status_unknown) hd->status.available = status_no;
          ADD2LOG("  got %s\n", hd->unique_id);
          *next2 = hd;
          next2 = &hd->next;
        }
      }
      closedir(dir);
    }
  }
  s = free_mem(s);

  hd_data->flags.keep_kmods = 1;
  for(hdm = hd_data->manual; hdm; hdm = next) {
    next = hdm->next;

    for(hd = hd_data->hd; hd; hd = hd->next) {
      if(hd->unique_id && hdm->unique_id && !strcmp(hd->unique_id, hdm->unique_id)) break;
    }

    if(hd) {
      /* just update config status */
      hd->status = hdm->status;
      if(hd->status.available != status_unknown) hd->status.available = status_yes;

      if(hdm->config_string) hd->config_string = new_str(hdm->config_string);

      if(hdm->persistent_prop) {
        hd->persistent_prop = hdm->persistent_prop;
        hdm->persistent_prop = NULL;
      }
    }
    else {
      /* add new entry */
      hd = add_hd_entry(hd_data, __LINE__, 0);
      *hd = *hdm;
      hd->next = NULL;
      hd->tag.freeit = 0;

      hdm->tag.remove = 1;

      if(hd->status.available != status_unknown) hd->status.available = status_no;

      // FIXME: do it really here?
      if(hd->parent_id) {
        for(hd1 = hd_data->hd; hd1; hd1 = hd1->next) {
          if(hd1->unique_id && !strcmp(hd1->unique_id, hd->parent_id)) {
            hd->attached_to = hd1->idx;
            break;
          }
        }
      }
    }
  }
  hd_data->flags.keep_kmods = 0;

  for(hd = hd_data->manual; hd; hd = next) {
    next = hd->next;
    hd->next = NULL;
    if(!hd->tag.remove) {
      hd_free_hd_list(hd);
    }
    else {
      free_mem(hd);
    }
  }
  hd_data->manual = NULL;

}
Esempio n. 6
0
static void
prom_parse (int node, int sbus, int ebus, hd_data_t *hd_data)
{
  hd_t *hd;
  char buf1[OPROMMAXPARAM], buf2[OPROMMAXPARAM];
  int nextnode;
  int len, nsbus = sbus, nebus = ebus;
  char *prop1 = prom_getproperty ("device_type", &len, buf1);

  if (strcmp (prop1, "network") == 0)
    {
      char *prop2 = prom_getproperty ("name", &len, buf2);
      if (prop2 && len >= 0)
	{
	  if (strcmp (prop2, "hme") == 0)
	    {
	      ADD2LOG ("NETWORK: type=Sun Happy Meal Ethernet, module=sunhme\n");
	      hd = add_hd_entry (hd_data, __LINE__, 0);
	      hd->base_class.id = bc_network;
	      hd->sub_class.id = 0x00;
	      hd->bus.id = bus_sbus;

	      hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x4001);
	      hd->device.id = MAKE_ID(TAG_SPECIAL, 0x3001);
	    }
	  else if (strcmp (prop2, "le") == 0)
	    {
	      ADD2LOG ("NETWORK: type=Sun Lance Ethernet, module=ignore\n");
	      hd = add_hd_entry (hd_data, __LINE__, 0);
	      hd->base_class.id = bc_network;
	      hd->sub_class.id = 0x00;
	      hd->bus.id = bus_sbus;

	      hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x4001);
	      hd->device.id = MAKE_ID(TAG_SPECIAL, 0x3002);
	    }
	  else if (strcmp (prop2, "qe") == 0)
	    {
	      prop2 = prom_getproperty("channel#", &len, buf2);
	      if (prop2 && len == 4 && *(int *)prop2 == 0)
		{
		  ADD2LOG ("NETWORK: type=Sun Quad Ethernet, module=sunqe\n");
		  hd = add_hd_entry (hd_data, __LINE__, 0);
		  hd->base_class.id = bc_network;
		  hd->sub_class.id = 0x00;
		  hd->bus.id = bus_sbus;

		  hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x4001);
		  hd->device.id = MAKE_ID(TAG_SPECIAL, 0x3003);
		}
	    }
          else if (strcmp (prop2, "qfe") == 0)
            {
              ADD2LOG ("NETWORK: type=Sun Quad Ethernet (qfe), module=sunhme\n");
              hd = add_hd_entry (hd_data, __LINE__, 0);
              hd->base_class.id = bc_network;
              hd->sub_class.id = 0x00;
              hd->bus.id = bus_sbus;

              hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x4001);
              hd->device.id = MAKE_ID(TAG_SPECIAL, 0x3001);
            }
	  else if (strcmp (prop2, "mlanai") == 0 || strcmp (prop2, "myri") == 0)
	    {
	      ADD2LOG ("NETWORK: type=MyriCOM MyriNET Gigabit Ethernet, module=myri_sbus\n");
	      hd = add_hd_entry (hd_data, __LINE__, 0);
	      hd->base_class.id = bc_network;
	      hd->sub_class.id = 0x00;
	      hd->bus.id = bus_sbus;

	      hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x4001);
	      hd->device.id = MAKE_ID(TAG_SPECIAL, 0x3004);
	    }
	  else
	    ADD2LOG ("NETWORK: Unknown device \"%s\"\n", prop2);
	}
    }
  else if (strcmp (prop1, "scsi") == 0)
    {
      char *prop2 = prom_getproperty ("name", &len, buf2);
      if (prop2 && len >= 0)
	{
	  if (sbus)
	    {
	      if (strcmp (prop2, "esp") == 0)
		{
		  ADD2LOG ("SCSI: type=Sun Enhanced SCSI Processor (ESP), module=ignore\n");
		  hd = add_hd_entry (hd_data, __LINE__, 0);
		  hd->base_class.id = bc_storage;
		  hd->sub_class.id = sc_sto_scsi;
		  hd->bus.id = bus_sbus;

		  hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x4001);
		  hd->device.id = MAKE_ID(TAG_SPECIAL, 0x1001);
		}
	      else if (strcmp (prop2, "soc") == 0)
		{
		  ADD2LOG ("SCSI: type=Sun SPARCStorage Array, module=fc4:soc:pluto\n");
		  hd = add_hd_entry (hd_data, __LINE__, 0);
		  hd->base_class.id = bc_storage;
		  hd->sub_class.id = sc_sto_scsi;
		  hd->bus.id = bus_sbus;

		  hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x4001);
		  hd->device.id = MAKE_ID(TAG_SPECIAL, 0x1101);
		}
	      else if (strcmp (prop2, "socal") == 0)
		{
		  ADD2LOG ("SCSI: type=Sun Enterprise Network Array, module=fc4:socal:fcal\n");
		  hd = add_hd_entry (hd_data, __LINE__, 0);
		  hd->base_class.id = bc_storage;
		  hd->sub_class.id = sc_sto_scsi;
		  hd->bus.id = bus_sbus;

		  hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x4001);
		  hd->device.id = MAKE_ID(TAG_SPECIAL, 0x1102);
		}
	      else if (strcmp (prop2, "fas") == 0)
		{
		  ADD2LOG ("SCSI: type=Sun Swift (ESP), module=ignore\n");
		  hd = add_hd_entry (hd_data, __LINE__, 0);
		  hd->base_class.id = bc_storage;
		  hd->sub_class.id = sc_sto_scsi;
		  hd->bus.id = bus_sbus;

		  hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x4001);
		  hd->device.id = MAKE_ID(TAG_SPECIAL, 0x1002);
		}
	      else if (strcmp (prop2, "ptisp") == 0)
		{
		  ADD2LOG ("SCSI: type=Performance Technologies ISP, module=qlogicpti\n");
		  hd = add_hd_entry (hd_data, __LINE__, 0);
		  hd->base_class.id = bc_storage;
		  hd->sub_class.id = sc_sto_scsi;
		  hd->bus.id = bus_sbus;

		  hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x4001);
		  hd->device.id = MAKE_ID(TAG_SPECIAL, 0x1003);
		}
	      else if (strcmp (prop2, "isp") == 0)
		{
		  ADD2LOG ("SCSI: type=QLogic ISP, module=qlogicpti\n");
		  hd = add_hd_entry (hd_data, __LINE__, 0);
		  hd->base_class.id = bc_storage;
		  hd->sub_class.id = sc_sto_scsi;
		  hd->bus.id = bus_sbus;

		  hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x4001);
		  hd->device.id = MAKE_ID(TAG_SPECIAL, 0x1004);
		}
	      else
		ADD2LOG ("SCSI: Unknown SBUS device \"%s\"\n", prop2);
	    }
	  else
	    ADD2LOG ("SCSI: Unknown device \"%s\"\n", prop2);
	}
    }
  else if (strcmp (prop1, "display") == 0)
    {
      char *prop2 = prom_getproperty ("name", &len, buf2);
      if (prop2 && len >= 0)
	if (sbus || strcmp (prop2, "ffb") == 0 ||
	    strcmp (prop2, "afb") == 0 || strcmp (prop2, "cgfourteen") == 0)
	  {
	    if (strcmp (prop2, "bwtwo") == 0)
	      {
		ADD2LOG ("DISPLAY: Sun|Monochrome (bwtwo), depth=1\n");
		hd = add_hd_entry (hd_data, __LINE__, 0);
		hd->base_class.id = bc_display;
		hd->sub_class.id = sc_dis_vga;
		hd->bus.id = bus_sbus;

		hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x4001);
		hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0001);
	      }
	    else if (strcmp (prop2, "cgthree") == 0)
	      {
		ADD2LOG ("DISPLAY: Sun|Color3 (cgthree), depth=8\n");
		hd = add_hd_entry (hd_data, __LINE__, 0);
		hd->base_class.id = bc_display;
		hd->sub_class.id = sc_dis_vga;
		hd->bus.id = bus_sbus;

		hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x4001);
		hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0002);
	      }
	    else if (strcmp (prop2, "cgeight") == 0)
	      {
		ADD2LOG ("DISPLAY: Sun|CG8/RasterOps, depth=8\n");
		hd = add_hd_entry (hd_data, __LINE__, 0);
		hd->base_class.id = bc_display;
		hd->sub_class.id = sc_dis_vga;
		hd->bus.id = bus_sbus;

		hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x4001);
		hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0003);
	      }
	    else if (strcmp (prop2, "cgtwelve") == 0)
	      {
		ADD2LOG ("DISPLAY: Sun|GS (cgtwelve), depth=24\n");
		hd = add_hd_entry (hd_data, __LINE__, 0);
		hd->base_class.id = bc_display;
		hd->sub_class.id = sc_dis_vga;
		hd->bus.id = bus_sbus;

		hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x4001);
		hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0004);
	      }
	    else if (strcmp (prop2, "gt") == 0)
	      {
		ADD2LOG ("DISPLAY: Sun|Graphics Tower (gt), depth=24\n");
		hd = add_hd_entry (hd_data, __LINE__, 0);
		hd->base_class.id = bc_display;
		hd->sub_class.id = sc_dis_vga;
		hd->bus.id = bus_sbus;

		hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x4001);
		hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0005);
	      }
	    else if (strcmp (prop2, "mgx") == 0)
	      {
		hd = add_hd_entry (hd_data, __LINE__, 0);
		hd->base_class.id = bc_display;
		hd->sub_class.id = sc_dis_vga;
		hd->bus.id = bus_sbus;
		hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x4001);
		prop2 = prom_getproperty ("fb_size", &len, buf2);
		if (prop2 && len == 4 && *(int *)prop2 == 0x400000)
		  {
		    ADD2LOG ("DISPLAY: Quantum 3D MGXplus with 4M VRAM (mgx), depth=24\n");
		    hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0006);
		  }
		else
		  {
		    ADD2LOG ("DISPLAY: Quantum 3D MGXplus (mgx), depth=24\n");
		    hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0007);
		  }
	      }
	    else if (strcmp (prop2, "cgsix") == 0)
	      {
		int chiprev = 0;
		int vmsize = 0;

		hd = add_hd_entry (hd_data, __LINE__, 0);
		hd->base_class.id = bc_display;
		hd->sub_class.id = sc_dis_vga;
		hd->bus.id = bus_sbus;
		hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x4001);

		prop2 = prom_getproperty("chiprev", &len, buf2);
		if (prop2 && len == 4)
		  chiprev = *(int *)prop2;
		prop2 = prom_getproperty("vmsize", &len, buf2);
		if (prop2 && len == 4)
		  vmsize = *(int *)prop2;
		switch (chiprev)
		  {
		  case 1 ... 4:
		    ADD2LOG ("DISPLAY: Sun|Double width GX (cgsix), depth=8\n");
		    hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0008);
		    break;
		  case 5 ... 9:
		    ADD2LOG ("DISPLAY: Sun|Single width GX (cgsix), depth=8\n");
		    hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0009);
		    break;
		  case 11:
		    switch (vmsize)
		      {
		      case 2:
			ADD2LOG ("DISPLAY: Sun|Turbo GX with 1M VSIMM (cgsix), depth=8\n");
			hd->device.id = MAKE_ID(TAG_SPECIAL, 0x000a);
			break;
		      case 4:
			ADD2LOG ("DISPLAY: Sun|Turbo GX Plus (cgsix), depth=8\n");
			hd->device.id = MAKE_ID(TAG_SPECIAL, 0x000b);
			break;
		      default:
			ADD2LOG ("DISPLAY: Sun|Turbo GX (cgsix), depth=8\n");
			hd->device.id = MAKE_ID(TAG_SPECIAL, 0x000c);
			break;
		      }
		    break;
		  default:
		    ADD2LOG ("DISPLAY: Sun|Unknown GX (cgsix), depth=8\n");
		    hd->device.id = MAKE_ID(TAG_SPECIAL, 0x000d);
		    break;
		  }
	      }
	    else if (strcmp (prop2, "cgfourteen") == 0)
Esempio n. 7
0
			ADD2LOG ("DISPLAY: Sun|Turbo GX (cgsix), depth=8\n");
			hd->device.id = MAKE_ID(TAG_SPECIAL, 0x000c);
			break;
		      }
		    break;
		  default:
		    ADD2LOG ("DISPLAY: Sun|Unknown GX (cgsix), depth=8\n");
		    hd->device.id = MAKE_ID(TAG_SPECIAL, 0x000d);
		    break;
		  }
	      }
	    else if (strcmp (prop2, "cgfourteen") == 0)
	      {
		int size = 0;

		hd = add_hd_entry (hd_data, __LINE__, 0);
		hd->base_class.id = bc_display;
		hd->sub_class.id = sc_dis_vga;
		hd->bus.id = bus_sbus;
		hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x4001);

		prop2 = prom_getproperty ("reg", &len, buf2);
		if (prop2 && !(len % 12) && len > 0)
		  size = *(int *)(prop2 + len - 4);
		switch (size)
		  {
		  case 0x400000:
		    ADD2LOG ("DISPLAY: Sun|SX with 4M VSIMM (cgfourteen), depth=24\n");
		    hd->device.id = MAKE_ID(TAG_SPECIAL, 0x000e);
		    break;
		  case 0x800000:
Esempio n. 8
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);
  }
}
Esempio n. 9
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
}
Esempio n. 10
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);
        }
      }
    }
  }
}
Esempio n. 11
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;
    }
  }
}
Esempio n. 12
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);
}
Esempio n. 13
0
static void get_ps2_mouse(hd_data_t *hd_data)
{
  hd_t *hd, *hd1;
  hd_res_t *res;
  int fd;
  fd_set set;
  struct timeval tv;
  unsigned char cmd_mouse_info = 0xe9;	/* read mouse info (3 bytes) */
  unsigned char cmd_mouse_id = 0xf2;	/* read mouse id (1 byte) */
  unsigned char buf[100];
  unsigned mouse_id = -1;
  static unsigned char intelli_init[] = { 0xf3, 200, 0xf3, 100, 0xf3, 80 };
  int buf_len = 0;
#ifdef __PPC__
  int always_ps2_mouse = 0;
#endif

  for(hd1 = hd_data->hd; hd1; hd1 = hd1->next) {
    /* look for a PS/2 controller entry... */
    if(hd1->base_class.id == bc_ps2) {
      /* ...and see if there were irq events... */
      for(res = hd1->res; res; res = res->next) {
        if(res->irq.type == res_irq && res->irq.triggered) break;
      }

#ifdef __PPC__
      /*
       * On PReP & CHRP, assume a PS/2 mouse to be attached.
       * There seems to be no way to actually *detect* it.
       */
      if(!res) {
        hd_t *hd;
        sys_info_t *st;

        if((hd = hd_list(hd_data, hw_sys, 0, NULL))) {
          if(
            hd->detail &&
            hd->detail->type == hd_detail_sys &&
            (st = hd->detail->sys.data) &&
            (
              !strcmp(st->system_type, "PReP") ||
              strstr(st->system_type, "CHRP") == st->system_type	/* CHRP && CHRP64 */
            )
          ) {
            always_ps2_mouse = 1;
          }
        }
      }
#endif

      PROGRESS(1, 1, "ps/2");

      /* open the mouse device... */
      if(hd_timeout(test_ps2_open, NULL, 2) > 0) {
        ADD2LOG("ps/2: open(%s) timed out\n", DEV_PSAUX);
        fd = -2;
      }
      else {
        fd = open(DEV_PSAUX, O_RDWR | O_NONBLOCK);
      }

      PROGRESS(1, 2, "ps/2");

      if(fd >= 0) {
        /* ...write the id command... */

        PROGRESS(1, 3, "ps/2");

        write(fd, intelli_init, sizeof intelli_init);
        usleep(25000);
        read_data(hd_data, fd, buf, sizeof buf);

        if(write(fd, &cmd_mouse_id, 1) == 1) {

          PROGRESS(1, 4, "ps/2");
          usleep(50000);        /* ...give it a chance to react... */

          /* ...read the response... */
          buf_len = read_data(hd_data, fd, buf, sizeof buf);

          if(buf_len >= 1) mouse_id = buf[buf_len - 1];

          // if we didn't get any response, try this
          if(buf_len == 0 || (hd_data->debug & HD_DEB_MOUSE)) {
            PROGRESS(1, 5, "ps/2");
            if(write(fd, &cmd_mouse_info, 1) == 1) {
              usleep(50000);
              buf_len = read_data(hd_data, fd, buf, sizeof buf);
              /*
               * Assume a mouse to be attached if at least 2 bytes are
               * returned.
               */
              if(mouse_id == -1u && buf_len >= 2) mouse_id = 0;
            }
          }

          PROGRESS(1, 6, "ps/2");
        }
        close(fd);

        PROGRESS(1, 7, "ps/2");

        /*
         * The following code is apparently necessary on some board/mouse
         * combinations. Otherwise the PS/2 mouse won't work.
         */
        if((fd = open(DEV_PSAUX, O_RDONLY | O_NONBLOCK)) >= 0) {
          PROGRESS(1, 8, "ps/2");

          FD_ZERO(&set);
          FD_SET(fd, &set);
          tv.tv_sec = 0; tv.tv_usec = 1;
          if(select(fd + 1, &set, NULL, NULL, &tv) == 1) {
            PROGRESS(1, 9, "ps/2");

            read(fd, buf, sizeof buf);

            PROGRESS(1, 10, "ps/2");
          }
          PROGRESS(1, 11, "ps/2");

          close(fd);

          PROGRESS(1, 12, "ps/2");
        }
      }
      else {
        ADD2LOG("open(" DEV_PSAUX "): %s\n", fd == -1 ? strerror(errno) : "timeout");
      }

      if(mouse_id == -1u) {

        /*
         * Assume a PS/2 mouse is attached if the ps/2 controller has
         * genetrated some events.
         */

        if(
          res
#ifdef __PPC__
          || always_ps2_mouse
#endif
        ) {
          PROGRESS(1, 13, "ps/2");
          mouse_id = 0;
        }
      }

      if(mouse_id != -1u) {
        PROGRESS(1, 14, "ps/2");

        hd = add_hd_entry(hd_data, __LINE__, 0);
        hd->base_class.id = bc_mouse;
        hd->sub_class.id = sc_mou_ps2;
        hd->bus.id = bus_ps2;
        hd->unix_dev_name = new_str(DEV_MICE);
        hd->attached_to = hd1->idx;

        hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x0200);
        switch(mouse_id) {
          case 3:		/* 3 buttons + wheel */
            hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0004);
            break;

          case 4:		/* 5 buttons + wheel */
            hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0005);
            break;

          default:	/* 0 */
            hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0002);
        }
      }

      /* there can only be one... */
      break;
    }
  }
}
Esempio n. 14
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;
      }
    }
  }
}
Esempio n. 15
0
void get_input_devices(hd_data_t *hd_data)
{
  hd_t *hd;
  str_list_t *input, *sl, *sl1;
  char *s;
  unsigned ok, u, is_mouse, is_joystick;
  unsigned bus, vendor, product, version;
  unsigned mouse_buttons, mouse_wheels;
  char *name = NULL, *handlers = NULL, *key = NULL, *rel = NULL, *abso = NULL;
  size_t len;
  str_list_t *handler_list;
  hd_dev_num_t dev_num = { type: 'c', range: 1 };

  input = read_file("/proc/bus/input/devices", 0, 0);

  ADD2LOG("----- /proc/bus/input/devices -----\n");
  for(sl = input; sl; sl = sl->next) {
    ADD2LOG("  %s", sl->str);
  }
  ADD2LOG("----- /proc/bus/input/devices end -----\n");

  for(ok = 0, sl = input; sl; sl = sl->next) {
    if(*sl->str == '\n') {
      ADD2LOG("bus = %u, name = %s\n", bus, name);
      if(handlers) ADD2LOG("  handlers = %s\n", handlers);
      if(key) ADD2LOG("  key = %s\n", key);
      if(rel) ADD2LOG("  rel = %s\n", rel);
      if(abso) ADD2LOG("  abs = %s\n", abso);

      mouse_buttons = 0;
      if(key) {
        for(u = BTN_MOUSE; u < BTN_MOUSE + 8; u++) {
          if(test_bit(key, u)) mouse_buttons++;
        }
      }
      ADD2LOG("  mouse buttons = %u\n", mouse_buttons);

      mouse_wheels = 0;
      if(rel) {
        for(u = REL_HWHEEL; u <= REL_MAX; u++) {
          if(test_bit(rel, u)) mouse_wheels++;
        }
      }
      ADD2LOG("  mouse wheels = %u\n", mouse_wheels);

      if(ok && handlers) {
        handler_list = hd_split(' ', handlers);

        is_mouse = strstr(handlers, "mouse") ? 1 : 0;
        is_joystick = strstr(handlers, "js") ? 1 : 0;

        if(	// HP Virtual Management Device
          vendor == 0x03f0 &&
          product == 0x1126 &&
          mouse_buttons >= 3
        ) is_mouse = 1;

        ADD2LOG("  is_mouse = %u\n", is_mouse);
        ADD2LOG("  is_joystick = %u\n", is_joystick);

        if(bus == BUS_USB) {
          s = NULL;
          for(sl1 = handler_list; sl1; sl1 = sl1->next) {
            if(sscanf(sl1->str, "mouse%u", &u) == 1) {
              str_printf(&s, 0, "/dev/input/mouse%u", u);
              break;
            }
          }

          if(!s && (is_mouse || is_joystick)) for(sl1 = handler_list; sl1; sl1 = sl1->next) {
            if(sscanf(sl1->str, "event%u", &u) == 1) {
              str_printf(&s, 0, "/dev/input/event%u", u);
              break;
            }
          }

          if(s) {
            for(hd = hd_data->hd; hd; hd = hd->next) {
              if(
                (hd->unix_dev_name2 && !strcmp(hd->unix_dev_name2, s)) ||
                (hd->unix_dev_name && !strcmp(hd->unix_dev_name, s))
              ) {
                if(!hd->base_class.id) {
		  if (is_mouse)
		  {
		    hd->base_class.id = bc_mouse;
		    hd->sub_class.id = sc_mou_usb;
		  }
		  else if (is_joystick)
		  {
		    hd->base_class.id = bc_joystick;
		  }
                }

		if (is_mouse)
		{
		  hd_set_hw_class(hd, hw_mouse);
                  hd->compat_vendor.id = MAKE_ID(TAG_SPECIAL, 0x0210);
                  hd->compat_device.id = MAKE_ID(TAG_SPECIAL, (mouse_wheels << 4) + mouse_buttons);
		}
		else if (is_joystick)
		{
		  hd_set_hw_class(hd, hw_joystick);

		  /* add buttons and axis details */
		  add_joystick_details(hd_data, hd, key, abso);
		}

                if(hd->unix_dev_name) add_str_list(&hd->unix_dev_names, hd->unix_dev_name);
                if(hd->unix_dev_name2) add_str_list(&hd->unix_dev_names, hd->unix_dev_name2);

                for(sl1 = handler_list; sl1; sl1 = sl1->next) {
                  if(sscanf(sl1->str, "event%u", &u) == 1) {
                    str_printf(&s, 0, "/dev/input/event%u", u);
                    if(!search_str_list(hd->unix_dev_names, s)) add_str_list(&hd->unix_dev_names, s);
                    s = free_mem(s);
                  }
		  /* add /dev/input/jsN joystick device name */
		  else if (is_joystick)
		  {
		    if(sscanf(sl1->str, "js%u", &u) == 1) {
		      str_printf(&s, 0, "/dev/input/js%u", u);
		      if(!search_str_list(hd->unix_dev_names, s)) add_str_list(&hd->unix_dev_names, s);
		      if(!hd->unix_dev_name2) hd->unix_dev_name2 = new_str(s);
		      s = free_mem(s);
		    }
		  }
                }

                break;
              }
            }
          }

          s = free_mem(s);

        }
        else {
	  // keyboard
          if(search_str_list(handler_list, "kbd") && test_bit(key, KEY_1)) {
            hd = add_hd_entry(hd_data, __LINE__, 0);
            hd->base_class.id = bc_keyboard;
            hd->sub_class.id = sc_keyboard_kbd;
            hd->bus.id = bus_ps2;

            hd->vendor.id = MAKE_ID(0, vendor);
            hd->device.id = MAKE_ID(0, product);
            hd->compat_vendor.id = MAKE_ID(TAG_SPECIAL, 0x0211);
            hd->compat_device.id = MAKE_ID(TAG_SPECIAL, 0x0001);
            hd->device.name = new_str(name);

            for(sl1 = handler_list; sl1; sl1 = sl1->next) {
              if(sscanf(sl1->str, "event%u", &u) == 1) {
                str_printf(&hd->unix_dev_name, 0, "/dev/input/event%u", u);
                dev_num.major = 13;
                dev_num.minor = 64 + u;
                hd->unix_dev_num = dev_num;
                break;
              }
            }
          }
	  // mouse
          else if(is_mouse) {
            hd = add_hd_entry(hd_data, __LINE__, 0);

            hd->vendor.id = MAKE_ID(0, vendor);
            hd->device.id = MAKE_ID(0, product);

            hd->compat_vendor.id = MAKE_ID(TAG_SPECIAL, 0x0210);
            hd->compat_device.id = MAKE_ID(TAG_SPECIAL, (mouse_wheels << 4) + mouse_buttons);

            hd->base_class.id = bc_mouse;
            if(bus == BUS_ADB) {
              hd->sub_class.id = sc_mou_bus;
              hd->bus.id = bus_adb;
            }
            else {
              hd->sub_class.id = sc_mou_ps2;
              hd->bus.id = bus_ps2;
            }

            hd->device.name = new_str(name);

#if 0
            /* Synaptics/Alps TouchPad */
            if(
              vendor == 2 &&
              (product == 7 || product == 8) &&
              test_bit(abso, ABS_X) &&
              test_bit(abso, ABS_Y) &&
              test_bit(abso, ABS_PRESSURE) &&
              test_bit(key, BTN_TOOL_FINGER)
            ) {
            }
#endif

            hd->unix_dev_name = new_str(DEV_MICE);
            dev_num.major = 13;
            dev_num.minor = 63;
            hd->unix_dev_num = dev_num;

            for(sl1 = handler_list; sl1; sl1 = sl1->next) {
              if(sscanf(sl1->str, "mouse%u", &u) == 1) {
                str_printf(&hd->unix_dev_name2, 0, "/dev/input/mouse%u", u);
                dev_num.major = 13;
                dev_num.minor = 32 + u;
                hd->unix_dev_num2 = dev_num;
                break;
              }
            }

            add_str_list(&hd->unix_dev_names, hd->unix_dev_name);
            add_str_list(&hd->unix_dev_names, hd->unix_dev_name2);

            for(sl1 = handler_list; sl1; sl1 = sl1->next) {
              if(sscanf(sl1->str, "event%u", &u) == 1) {
                s = NULL;
                str_printf(&s, 0, "/dev/input/event%u", u);
                add_str_list(&hd->unix_dev_names, s);
                s = free_mem(s);
                break;
              }
            }
          }
	  // joystick
          else if(is_joystick) {
            hd = add_hd_entry(hd_data, __LINE__, 0);

            hd->vendor.id = MAKE_ID(0, vendor);
            hd->device.id = MAKE_ID(0, product);

	    hd_set_hw_class(hd, hw_joystick);
            hd->base_class.id = bc_joystick;
            hd->device.name = new_str(name);

	    // gameport? (see <linux/input.h>)
	    if (bus == BUS_GAMEPORT) hd->bus.id = bus_gameport;

	    /* add buttons and axis details */
	    add_joystick_details(hd_data, hd, key, abso);

	    // add eventX device
            for(sl1 = handler_list; sl1; sl1 = sl1->next) {
              if(sscanf(sl1->str, "event%u", &u) == 1) {
                str_printf(&hd->unix_dev_name, 0, "/dev/input/event%u", u);
                dev_num.major = 13;
                dev_num.minor = 64 + u;
                hd->unix_dev_num = dev_num;
                break;
              }
            }

	    // add jsX device
            for(sl1 = handler_list; sl1; sl1 = sl1->next) {
              if(sscanf(sl1->str, "js%u", &u) == 1) {
                str_printf(&hd->unix_dev_name2, 0, "/dev/input/js%u", u);
                break;
              }
            }

            add_str_list(&hd->unix_dev_names, hd->unix_dev_name);
            add_str_list(&hd->unix_dev_names, hd->unix_dev_name2);
	  }
	  else
	  {
	    ADD2LOG("unknown non-USB input device\n");
	  }
        }

        handler_list = free_str_list(handler_list);
      }

      ok = 0;

      name = free_mem(name);
      handlers = free_mem(handlers);
      key = free_mem(key);
      rel = free_mem(rel);
      abso = free_mem(abso);
    }

    if(sscanf(sl->str, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x", &bus, &vendor, &product, &version) == 4) {
      ok = 1;
      continue;
    }

    if(!strncmp(sl->str, INP_NAME, sizeof INP_NAME - 1)) {
      s = sl->str + sizeof INP_NAME;
      len = strlen(s);
      if(len > 2) {
        name = canon_str(s, len - 2);
      }
      continue;
    }

    if(!strncmp(sl->str, INP_HANDLERS, sizeof INP_HANDLERS - 1)) {
      s = sl->str + sizeof INP_HANDLERS - 1;
      handlers = canon_str(s, strlen(s));
      continue;
    }

    if(!strncmp(sl->str, INP_KEY, sizeof INP_KEY - 1)) {
      s = sl->str + sizeof INP_KEY - 1;
      key = canon_str(s, strlen(s));
      key = all_bits(key);
      continue;
    }

    if(!strncmp(sl->str, INP_REL, sizeof INP_REL - 1)) {
      s = sl->str + sizeof INP_REL - 1;
      rel = canon_str(s, strlen(s));
      rel = all_bits(rel);
      continue;
    }

    if(!strncmp(sl->str, INP_ABS, sizeof INP_ABS - 1)) {
      s = sl->str + sizeof INP_ABS - 1;
      abso = canon_str(s, strlen(s));
      abso = all_bits(abso);
      continue;
    }
  }

  free_str_list(input);

}


char *all_bits(char *str)
{
  str_list_t *sl, *sl0;
  char *s = NULL;
  unsigned long u;

  if(!str) return NULL;

  sl = sl0 = hd_split(' ', str);
  for(; sl; sl = sl->next) {
    u = strtoul(sl->str, NULL, 16);
    str_printf(&s, -1, "%0*lx", (int) sizeof (unsigned long) * 2, u);
  }
  free_str_list(sl0);
  free_mem(str);

  return s;
}
Esempio n. 16
0
void pcmcia_read_data(hd_data_t *hd_data)
{
  hd_t *hd, *hd2;
  unsigned u0, u1, func_id;
  uint64_t ul0;
  char *s, *t;
  char *prod1, *prod2, *prod3, *prod4;
  str_list_t *sl;
  str_list_t *sf_bus, *sf_bus_e;
  char *sf_dev;

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

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

  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/pcmcia/devices", sf_bus_e->str));

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

    if(sscanf(sf_bus_e->str, "%x.%x", &u0, &u1) != 2) continue;

    hd = add_hd_entry(hd_data, __LINE__, 0);

    hd->sysfs_id = new_str(hd_sysfs_id(sf_dev));
    hd->sysfs_bus_id = new_str(sf_bus_e->str);
    hd->bus.id = bus_pcmcia;

    hd->slot = u0;
    hd->func = u1;
    hd->hotplug_slot = u0 + 1;
    hd->hotplug = hp_pcmcia;

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

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

    if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "manf_id"), &ul0, 0)) {
      ADD2LOG("    manf_id = 0x%04x\n", (unsigned) ul0);
      hd->vendor.id = MAKE_ID(TAG_PCMCIA, ul0);
    }

    if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "card_id"), &ul0, 0)) {
      ADD2LOG("    card_id = 0x%04x\n", (unsigned) ul0);
      hd->device.id = MAKE_ID(TAG_PCMCIA, ul0);
    }

    /*
     * "multifunction", "memory", "serial", "parallel",
     * "fixed disk", "video", "network", "AIMS",
     * "SCSI"
     */
    func_id = 0;
    if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "func_id"), &ul0, 0)) {
      func_id = ul0;
      ADD2LOG("    func_id = 0x%04x\n", func_id);
    }

    prod1 = NULL;
    if((s = get_sysfs_attr_by_path(sf_dev, "prod_id1"))) {
      prod1 = canon_str(s, strlen(s));
      ADD2LOG("    prod_id1 = \"%s\"\n", prod1);
    }

    prod2 = NULL;
    if((s = get_sysfs_attr_by_path(sf_dev, "prod_id2"))) {
      prod2 = canon_str(s, strlen(s));
      ADD2LOG("    prod_id2 = \"%s\"\n", prod2);
    }

    prod3 = NULL;
    if((s = get_sysfs_attr_by_path(sf_dev, "prod_id3"))) {
      prod3 = canon_str(s, strlen(s));
      ADD2LOG("    prod_id3 = \"%s\"\n", prod3);
    }

    prod4 = NULL;
    if((s = get_sysfs_attr_by_path(sf_dev, "prod_id4"))) {
      prod4 = canon_str(s, strlen(s));
      ADD2LOG("    prod_id4 = \"%s\"\n", prod4);
    }

    if(func_id == 6) {
      hd->base_class.id = bc_network;
      hd->sub_class.id = 0x80;		/* other */
    }

    if(prod1 && *prod1) {
      add_str_list(&hd->extra_info, prod1);
      hd->vendor.name = prod1;
      prod1 = NULL;
    }
    if(prod2 && *prod2) {
      add_str_list(&hd->extra_info, prod2);
      hd->device.name = prod2;
      prod2 = NULL;
    }
    if(prod3 && *prod3) add_str_list(&hd->extra_info, prod3);
    if(prod4 && *prod4) add_str_list(&hd->extra_info, prod4);

    for(sl = hd->extra_info; sl ; sl = sl->next) {
      if(strstr(sl->str, "Ethernet")) hd->sub_class.id = 0;	/* ethernet */
      if(
        !hd->revision.name &&
        !sl->next &&
        (
          !strncasecmp(sl->str, "rev.", sizeof "rev." - 1) ||
          (
            (sl->str[0] == 'V' || sl->str[0] == 'v') &&
            (sl->str[1] >= '0' && sl->str[1] <= '9')
          )
        )
      ) {
        hd->revision.name = new_str(sl->str);
      }
    }

    prod1 = free_mem(prod1);
    prod2 = free_mem(prod2);
    prod3 = free_mem(prod3);
    prod4 = free_mem(prod4);

    s = new_str(hd->sysfs_id);

    if((t = strrchr(s, '/'))) {
      *t = 0;
      if((hd2 = hd_find_sysfs_id(hd_data, s))) {
        hd->attached_to = hd2->idx;
      }
    }
    free_mem(s);

    free_mem(sf_dev);
  }

  free_str_list(sf_bus);
}