/* * 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); } } } }
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); } }
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); } } }
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); }
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; }
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)
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:
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); } }
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 }
void hd_scan_net(hd_data_t *hd_data) { unsigned u; int if_type, if_carrier; hd_t *hd, *hd_card; char *s, *t, *hw_addr; hd_res_t *res, *res1, *res2; uint64_t ul0; str_list_t *sf_class, *sf_class_e; char *sf_cdev = NULL, *sf_dev = NULL; char *sf_drv_name, *sf_drv; if(!hd_probe_feature(hd_data, pr_net)) return; hd_data->module = mod_net; /* some clean-up */ remove_hd_entries(hd_data); hd_data->net = free_str_list(hd_data->net); PROGRESS(1, 0, "get network data"); sf_class = read_dir("/sys/class/net", 'l'); if(!sf_class) sf_class = read_dir("/sys/class/net", 'd'); if(!sf_class) { ADD2LOG("sysfs: no such class: net\n"); return; } for(sf_class_e = sf_class; sf_class_e; sf_class_e = sf_class_e->next) { str_printf(&sf_cdev, 0, "/sys/class/net/%s", sf_class_e->str); hd_card = NULL; ADD2LOG( " net interface: name = %s, path = %s\n", sf_class_e->str, hd_sysfs_id(sf_cdev) ); if_type = -1; if(hd_attr_uint(get_sysfs_attr_by_path(sf_cdev, "type"), &ul0, 0)) { if_type = ul0; ADD2LOG(" type = %d\n", if_type); } if_carrier = -1; if(hd_attr_uint(get_sysfs_attr_by_path(sf_cdev, "carrier"), &ul0, 0)) { if_carrier = ul0; ADD2LOG(" carrier = %d\n", if_carrier); } hw_addr = NULL; if((s = get_sysfs_attr_by_path(sf_cdev, "address"))) { hw_addr = canon_str(s, strlen(s)); ADD2LOG(" hw_addr = %s\n", hw_addr); } sf_dev = new_str(hd_read_sysfs_link(sf_cdev, "device")); if(sf_dev) { ADD2LOG(" net device: path = %s\n", hd_sysfs_id(sf_dev)); } sf_drv_name = NULL; sf_drv = hd_read_sysfs_link(sf_dev, "driver"); if(sf_drv) { sf_drv_name = strrchr(sf_drv, '/'); if(sf_drv_name) sf_drv_name++; ADD2LOG( " net driver: name = %s, path = %s\n", sf_drv_name, hd_sysfs_id(sf_drv) ); } hd = add_hd_entry(hd_data, __LINE__, 0); hd->base_class.id = bc_network_interface; hd->sub_class.id = sc_nif_other; res1 = NULL; if(hw_addr && strspn(hw_addr, "0:") != strlen(hw_addr)) { res1 = new_mem(sizeof *res1); res1->hwaddr.type = res_hwaddr; res1->hwaddr.addr = new_str(hw_addr); add_res_entry(&hd->res, res1); } res2 = NULL; if(if_carrier >= 0) { res = new_mem(sizeof *res); res->link.type = res_link; res->link.state = if_carrier ? 1 : 0; add_res_entry(&hd->res, res); } hd->unix_dev_name = new_str(sf_class_e->str); hd->sysfs_id = new_str(hd_sysfs_id(sf_cdev)); if(sf_drv_name) { add_str_list(&hd->drivers, sf_drv_name); } else if(hd->res) { get_driverinfo(hd_data, hd); } switch(if_type) { case ARPHRD_ETHER: /* eth */ hd->sub_class.id = sc_nif_ethernet; break; case ARPHRD_LOOPBACK: /* lo */ hd->sub_class.id = sc_nif_loopback; break; case ARPHRD_SIT: /* sit */ hd->sub_class.id = sc_nif_sit; break; case ARPHRD_FDDI: /* fddi */ hd->sub_class.id = sc_nif_fddi; break; case ARPHRD_IEEE802_TR: /* tr */ hd->sub_class.id = sc_nif_tokenring; break; #if 0 case ARPHRD_IEEE802: /* fc */ hd->sub_class.id = sc_nif_fc; break; #endif default: hd->sub_class.id = sc_nif_other; } if(!strcmp(hd->unix_dev_name, "lo")) { hd->sub_class.id = sc_nif_loopback; } else if(sscanf(hd->unix_dev_name, "eth%u", &u) == 1) { hd->sub_class.id = sc_nif_ethernet; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "tr%u", &u) == 1) { hd->sub_class.id = sc_nif_tokenring; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "fddi%u", &u) == 1) { hd->sub_class.id = sc_nif_fddi; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "ctc%u", &u) == 1) { hd->sub_class.id = sc_nif_ctc; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "iucv%u", &u) == 1) { hd->sub_class.id = sc_nif_iucv; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "hsi%u", &u) == 1) { hd->sub_class.id = sc_nif_hsi; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "qeth%u", &u) == 1) { hd->sub_class.id = sc_nif_qeth; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "escon%u", &u) == 1) { hd->sub_class.id = sc_nif_escon; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "myri%u", &u) == 1) { hd->sub_class.id = sc_nif_myrinet; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "sit%u", &u) == 1) { hd->sub_class.id = sc_nif_sit; /* ipv6 over ipv4 tunnel */ hd->slot = u; } else if(sscanf(hd->unix_dev_name, "wlan%u", &u) == 1) { hd->sub_class.id = sc_nif_wlan; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "xp%u", &u) == 1) { hd->sub_class.id = sc_nif_xp; hd->slot = u; } else if(sscanf(hd->unix_dev_name, "usb%u", &u) == 1) { hd->sub_class.id = sc_nif_usb; hd->slot = u; } /* ##### add more interface names here */ else { for(s = hd->unix_dev_name; *s; s++) if(isdigit(*s)) break; if(*s && (u = strtoul(s, &s, 10), !*s)) { hd->slot = u; } } hd->bus.id = bus_none; hd_card = NULL; if(sf_dev) { s = new_str(hd_sysfs_id(sf_dev)); hd->sysfs_device_link = new_str(s); hd_card = hd_find_sysfs_id(hd_data, s); // try one above, if not found if(!hd_card) { t = strrchr(s, '/'); if(t) { *t = 0; hd_card = hd_find_sysfs_id(hd_data, s); } } /* if one card has several interfaces (as with PS3), check interface names, too */ if( hd_card && hd_card->unix_dev_name && hd->unix_dev_name && strcmp(hd->unix_dev_name, hd_card->unix_dev_name) ) { hd_card = hd_find_sysfs_id_devname(hd_data, s, hd->unix_dev_name); } s = free_mem(s); if(hd_card) { hd->attached_to = hd_card->idx; /* for cards with strange pci classes */ hd_set_hw_class(hd_card, hw_network_ctrl); /* add hw addr to network card */ if(res1) { u = 0; for(res = hd_card->res; res; res = res->next) { if( res->any.type == res_hwaddr && !strcmp(res->hwaddr.addr, res1->hwaddr.addr) ) { u = 1; break; } } if(!u) { res = new_mem(sizeof *res); res->hwaddr.type = res_hwaddr; res->hwaddr.addr = new_str(res1->hwaddr.addr); add_res_entry(&hd_card->res, res); } } /* * add interface names... * but not wmasterX (bnc #441778) */ if(if_type != 801) add_if_name(hd_card, hd); } } if(!hd_card && hw_addr) { /* try to find card based on hwaddr (for prom-based cards) */ for(hd_card = hd_data->hd; hd_card; hd_card = hd_card->next) { if( hd_card->base_class.id != bc_network || hd_card->sub_class.id != 0 ) continue; for(res = hd_card->res; res; res = res->next) { if( res->any.type == res_hwaddr && !strcmp(hw_addr, res->hwaddr.addr) ) break; } if(res) { hd->attached_to = hd_card->idx; break; } } } hw_addr = free_mem(hw_addr); /* fix card type */ if(hd_card) { if( (hd_card->base_class.id == 0 && hd_card->sub_class.id == 0) || (hd_card->base_class.id == bc_network && hd_card->sub_class.id == 0x80) ) { switch(hd->sub_class.id) { case sc_nif_ethernet: hd_card->base_class.id = bc_network; hd_card->sub_class.id = 0; break; case sc_nif_usb: hd_card->base_class.id = bc_network; hd_card->sub_class.id = 0x91; break; } } } sf_dev = free_mem(sf_dev); } sf_cdev = free_mem(sf_cdev); sf_class = free_str_list(sf_class); if(hd_is_sgi_altix(hd_data)) add_xpnet(hd_data); add_uml(hd_data); add_kma(hd_data); /* add link status info & dump eeprom */ for(hd = hd_data->hd ; hd; hd = hd->next) { if( hd->module == hd_data->module && hd->base_class.id == bc_network_interface ) { char *buf = NULL; str_list_t *sl0, *sl; if(hd_probe_feature(hd_data, pr_net_eeprom) && hd->unix_dev_name) { PROGRESS(2, 0, "eeprom dump"); str_printf(&buf, 0, "|/usr/sbin/ethtool -e %s 2>/dev/null", hd->unix_dev_name); if((sl0 = read_file(buf, 0, 0))) { ADD2LOG("----- %s %s -----\n", hd->unix_dev_name, "EEPROM dump"); for(sl = sl0; sl; sl = sl->next) { ADD2LOG("%s", sl->str); } ADD2LOG("----- %s end -----\n", "EEPROM dump"); free_str_list(sl0); } free(buf); } for(res = hd->res; res; res = res->next) { if(res->any.type == res_link) break; } if(!res) get_linkstate(hd_data, hd); if(!(hd_card = hd_get_device_by_idx(hd_data, hd->attached_to))) continue; for(res = hd->res; res; res = res->next) { if(res->any.type == res_link) break; } if(res) { for(res1 = hd_card->res; res1; res1 = res1->next) { if(res1->any.type == res_link) break; } if(res && !res1) { res1 = new_mem(sizeof *res1); res1->link.type = res_link; res1->link.state = res->link.state; add_res_entry(&hd_card->res, res1); } } } } }
void 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; } } }
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); }
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; } } }
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; } } } }
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; }
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); }