diff options
author | David Zeuthen <david@fubar.dk> | 2003-12-03 01:52:34 +0000 |
---|---|---|
committer | David Zeuthen <david@fubar.dk> | 2003-12-03 01:52:34 +0000 |
commit | e54922f0b07c8e8bd845ac82445a11e384fe0e79 (patch) | |
tree | 5843bbf5227d5d1e2ad0a643b97e688c7e401a62 /agents | |
parent | 14cf3e928ebd192c89ecbcb7ec0c1fb154dc5f18 (diff) | |
download | hal-e54922f0b07c8e8bd845ac82445a11e384fe0e79.tar.gz |
new directory with tools/hal-device-manager split into many files
Set Capability and Category properties
new function (process_input_proc_info): Set Capability and Category
properties
Set some properties under the volume namespace
Set Capability and Category properties; set MAC address under namespace
ethernet for Ethernet net devices
Set Capability and Category properties (pci_add_caps_from_class): new
function
Set Capability and Category properties (usb_add_caps_from_class): new
function
new function (filter_function): Add call
Convert from d-bus string array. (hal_manager_find_device_string_match):
Convert from d-bus string array. (hal_device_add_capability): new
function (hal_device_query_capability): new function
(hal_find_device_by_capability): new function
Add prototypes
Diffstat (limited to 'agents')
-rw-r--r-- | agents/linux26/sysfs/hal_block.c | 118 | ||||
-rw-r--r-- | agents/linux26/sysfs/hal_input.c | 62 | ||||
-rw-r--r-- | agents/linux26/sysfs/hal_monitor.c | 16 | ||||
-rw-r--r-- | agents/linux26/sysfs/hal_net.c | 108 | ||||
-rw-r--r-- | agents/linux26/sysfs/hal_pci.c | 292 | ||||
-rw-r--r-- | agents/linux26/sysfs/hal_usb.c | 95 | ||||
-rw-r--r-- | agents/linux26/sysfs/main.c | 16 |
7 files changed, 626 insertions, 81 deletions
diff --git a/agents/linux26/sysfs/hal_block.c b/agents/linux26/sysfs/hal_block.c index b33f5817..736dd7e8 100644 --- a/agents/linux26/sysfs/hal_block.c +++ b/agents/linux26/sysfs/hal_block.c @@ -127,6 +127,8 @@ void visit_class_device_block(const char* path, hal_device_set_property_string(d, "Linux.sysfs_path", path); hal_device_set_property_string(d, "Linux.sysfs_path_device", path); + hal_device_add_capability(d, "block"); + dlist_for_each_data(sysfs_get_classdev_attributes(class_device), cur, struct sysfs_attribute) { @@ -160,14 +162,36 @@ void visit_class_device_block(const char* path, } } - if( not_partition ) + hal_device_set_property_bool(d, "block.isVolume", !not_partition); + + hal_device_set_property_string(d, "Parent", parent_udi); + + if( !not_partition ) + { + /* We are a volume */ + find_and_set_physical_device(d); + hal_device_set_property_bool(d, "isVirtual", TRUE); + hal_device_add_capability(d, "volume"); + hal_device_set_property_string(d, "Category", "volume"); + + /* block device that is a partition; e.g. a storage volume */ + + /** @todo Guestimate product name; use volume label */ + hal_device_set_property_string(d, "Product", "Volume"); + } + else { + /* We are a disk; maybe we even offer removable media */ + hal_device_set_property_string(d, "Category", "block"); + if( strcmp(hal_device_get_property_string(parent_udi, "Bus"), "ide")==0 ) { const char* ide_name; char* model; char* media; + dbus_bool_t removable_media; + ide_name = get_last_element(path); @@ -177,57 +201,89 @@ void visit_class_device_block(const char* path, hal_device_set_property_string(d, "block.model", model); hal_device_set_property_string(d, "Product", model); } + + removable_media = FALSE; /* According to the function proc_ide_read_media() in * drivers/ide/ide-proc.c in the Linux sources, media * can only assume "disk", "cdrom", "tape", "floppy", "UNKNOWN" - * - * This is good enough for us. */ + + /** @todo Given media 'cdrom', how do we determine whether + * it's a DVD or a CD-RW or both? Given floppy how + * do we determine it's LS120? + */ + media = read_single_line("/proc/ide/%s/media", ide_name); if( media!=NULL ) { hal_device_set_property_string(d, "block.media", media); + + /* Set for removable media */ + if( strcmp(media, "disk")==0 ) + { + hal_device_add_capability(d, "fixedMedia"); + hal_device_add_capability(d, "fixedMedia.harddisk"); + hal_device_set_property_string(d, "Category", + "fixedMedia.harddisk"); + } + else if( strcmp(media, "cdrom")==0 ) + { + hal_device_add_capability(d, "removableMedia"); + hal_device_add_capability(d, "removableMedia.cdrom"); + hal_device_set_property_string(d, "Category", + "removableMedia.cdrom"); + removable_media = TRUE; + } + else if( strcmp(media, "floppy")==0 ) + { + hal_device_add_capability(d, "removableMedia"); + hal_device_add_capability(d, "removableMedia.floppy"); + hal_device_set_property_string(d, "Category", + "removableMedia.floppy"); + removable_media = TRUE; + } + else if( strcmp(media, "tape")==0 ) + { + hal_device_add_capability(d, "removableMedia"); + hal_device_add_capability(d, "removableMedia.tape"); + hal_device_set_property_string(d, "Category", + "removableMedia.tape"); + removable_media = TRUE; + } + } + + hal_device_set_property_bool(d, "block.removableMedia", + removable_media); - /** @todo Given media 'cdrom', how do we determine whether - * it's a DVD or a CD-RW or both? - */ } else { /** @todo: block device on non-IDE device; how to find the - * name and the media-type? */ + * name and the media-type? Right now we just assume + * that the disk is fixed and of type flash.. This hack + * does 'the right thing' on IDE-systems where the + * user attach a USB storage device. + * + * We should special case for at least SCSI once this + * information is easily accessible in kernel 2.6. + * + */ + + hal_device_set_property_string(d, "block.media", "flash"); + + hal_device_add_capability(d, "fixedMedia"); + hal_device_add_capability(d, "fixedMedia.flash"); + hal_device_set_property_string(d, "Category", + "fixedMedia.flash"); /* guestimate product name */ hal_device_set_property_string(d, "Product", "Disk"); - /* omit block.media */ + /* omit block.media! */ } } - else - { - /* block device that is a partition; e.g. a storage volume */ - - /* guestimate product name */ - hal_device_set_property_string(d, "Product", "Volume"); - } - - hal_device_set_property_bool(d, "block.isVolume", !not_partition); - - hal_device_set_property_string(d, "Parent", parent_udi); - - /* Being a block device and not a partition (volume) we're certainly - * some kind of physical device of our own */ - if( !not_partition ) - { - find_and_set_physical_device(d); - hal_device_set_property_bool(d, "isVirtual", TRUE); - } - else - { - ; - } d = rename_and_maybe_add(d, block_compute_udi, "block"); } diff --git a/agents/linux26/sysfs/hal_input.c b/agents/linux26/sysfs/hal_input.c index 6c519e17..0b168a90 100644 --- a/agents/linux26/sysfs/hal_input.c +++ b/agents/linux26/sysfs/hal_input.c @@ -66,6 +66,35 @@ typedef struct input_proc_info_s struct input_proc_info_s* next; /**< next element or #NULL if last */ } input_proc_info; +/** Allocate and initialize an input_proc_info object + * + * @return Pointer input_proc_info object + */ +static input_proc_info* get_input_proc_cur_info_obj() +{ + input_proc_info* i; + + i = malloc(sizeof(input_proc_info)); + if( i==NULL ) + DIE(("Cannot allocated memory")); + + (i->name)[0] = '\0'; + (i->phys_name)[0] = '\0'; + (i->handlers)[0] = '\0'; + (i->keybit)[0] = '\0'; + i->evbit = 0; + i->ledbit = 0; + i->relbit = 0; + i->absbit = 0; + i->bus = 0; + i->vendor = 0; + i->product = 0; + i->version = 0; + + return i; +} + + /** First element in input proc linked list */ static input_proc_info* input_proc_head = NULL; @@ -198,7 +227,6 @@ static void input_proc_device_done(input_proc_info* info) } - /** Parse a line from /proc/bus/input/devices * * @param s Line from /proc/bus/input/devices @@ -218,15 +246,7 @@ static void input_proc_parse_line(char* s) input_proc_device_done(input_proc_cur_info); } - input_proc_cur_info = malloc(sizeof(input_proc_info)); - - if( input_proc_cur_info==NULL ) - DIE(("Cannot allocated memory")); - - (input_proc_cur_info->name)[0] = '\0'; - (input_proc_cur_info->phys_name)[0] = '\0'; - (input_proc_cur_info->handlers)[0] = '\0'; - (input_proc_cur_info->keybit)[0] = '\0'; + input_proc_cur_info = get_input_proc_cur_info_obj(); input_proc_handle_interface(input_proc_cur_info, s); break; @@ -517,6 +537,24 @@ static void process_input_proc_info(input_proc_info* i) hal_device_set_property_bool(udi, "input.absolute.misc", i->absbit&(1<<ABS_MISC)); } + + /* Either way, we're an input device */ + hal_device_add_capability(udi, "input"); + + /** @todo Figure out if this input device is a mouse, a keyboard or.. + * bzzzttt.. an UPS.. We can wawe our hands a bit because this + * can always be overridden by a .fdi file.. + */ + if( i->relbit!=0 ) + { + hal_device_add_capability(udi, "input.mouse"); + hal_device_set_property_string(udi, "Category", "input.mouse"); + } + else + { + hal_device_add_capability(udi, "input.keyboard"); + hal_device_set_property_string(udi, "Category", "input.keyboard"); + } /** @todo FIXME, is there any other key information we want to * give here? Like major:minor number of device? @@ -545,9 +583,7 @@ void hal_input_handle_hotplug_add() char* s; input_proc_info* i; - i = malloc(sizeof(input_proc_info)); - if( i==NULL ) - DIE(("Cannot allocated memory")); + i = get_input_proc_cur_info_obj(); /** @todo FIXME; parse product (we don't use it yet) */ diff --git a/agents/linux26/sysfs/hal_monitor.c b/agents/linux26/sysfs/hal_monitor.c index 8e5a3225..ec0a7e8e 100644 --- a/agents/linux26/sysfs/hal_monitor.c +++ b/agents/linux26/sysfs/hal_monitor.c @@ -293,13 +293,13 @@ void etc_mtab_process_all_block_devices(dbus_bool_t setup_watcher) mp->fs_type); /* Yay! Found a mount point; set properties accordingly */ - hal_device_set_property_string(udi, "block.device", + hal_device_set_property_string(udi, "volume.device", mp->device); - hal_device_set_property_string(udi, "block.mountPoint", + hal_device_set_property_string(udi, "volume.mountPoint", mp->mount_point); - hal_device_set_property_string(udi, "block.fileSystem", + hal_device_set_property_string(udi, "volume.fileSystem", mp->fs_type); - hal_device_set_property_bool(udi, "block.isMounted", TRUE); + hal_device_set_property_bool(udi, "volume.isMounted", TRUE); found_mount_point = TRUE; } @@ -308,10 +308,10 @@ void etc_mtab_process_all_block_devices(dbus_bool_t setup_watcher) /* No mount point found; (possibly) remove all information */ if( !found_mount_point ) { - hal_device_set_property_bool(udi, "block.isMounted", FALSE); - hal_device_remove_property(udi, "block.mountPoint"); - hal_device_remove_property(udi, "block.fileSystem"); - hal_device_remove_property(udi, "block.device"); + hal_device_set_property_bool(udi, "volume.isMounted", FALSE); + hal_device_remove_property(udi, "volume.mountPoint"); + hal_device_remove_property(udi, "volume.fileSystem"); + hal_device_remove_property(udi, "volume.device"); } } diff --git a/agents/linux26/sysfs/hal_net.c b/agents/linux26/sysfs/hal_net.c index 4f6ab0c2..bc3c1bc3 100644 --- a/agents/linux26/sysfs/hal_net.c +++ b/agents/linux26/sysfs/hal_net.c @@ -53,9 +53,13 @@ void visit_class_device_net(const char* path, struct sysfs_class_device* class_device) { + int i; + int len; char* d; struct sysfs_attribute* cur; char attr_name[SYSFS_NAME_LEN]; + char* addr_store = NULL; + int media_type = 0; if( class_device->sysdevice==NULL ) { @@ -75,6 +79,10 @@ void visit_class_device_net(const char* path, hal_device_set_property_string(d, "net.interface", class_device->name); hal_device_set_property_string(d, "net.linux.sysfs_path", path); + hal_device_add_capability(d, "net"); + + hal_device_set_property_string(d, "Category", "net"); + dlist_for_each_data(sysfs_get_classdev_attributes(class_device), cur, struct sysfs_attribute) { @@ -82,39 +90,101 @@ void visit_class_device_net(const char* path, attr_name, SYSFS_NAME_LEN) != 0 ) continue; - if( strcmp(attr_name, "type")==0 ) + /* strip whitespace */ + len = strlen(cur->value); + for(i=len-1; i>=0 && isspace(cur->value[i]); --i) + cur->value[i] = '\0'; + + if( strcmp(attr_name, "address")==0 ) + { + addr_store = cur->value; + } + else if( strcmp(attr_name, "type")==0 ) { - int type = parse_dec(cur->value); + media_type = parse_dec(cur->value); char* media; /* type is decimal according to net/core/net-sysfs.c and it * assumes values from /usr/include/net/if_arp.h. Either * way we store both the */ - switch(type) + switch(media_type) { - case ARPHRD_NETROM: media="NET/ROM pseudo"; break; - case ARPHRD_ETHER: media="Ethernet"; break; - case ARPHRD_EETHER: media="Experimenal Ethernet"; break; - case ARPHRD_AX25: media="AX.25 Level 2"; break; - case ARPHRD_PRONET: media="PROnet tokenring"; break; - case ARPHRD_CHAOS: media="Chaosnet"; break; - case ARPHRD_IEEE802: media="ATM"; break; - case ARPHRD_ARCNET: media="ARCnet"; break; - case ARPHRD_APPLETLK: media="APPLEtalk"; break; - case ARPHRD_DLCI: media="Frame Relay DLCI"; break; - case ARPHRD_ATM: media="ATM"; break; - case ARPHRD_METRICOM: media="Metricom STRIP (new IANA id)"; break; - case ARPHRD_IEEE1394: media="IEEE1394 IPv4 - RFC 2734"; break; - default: media="Unknown"; break; + case ARPHRD_NETROM: + media="NET/ROM pseudo"; + break; + case ARPHRD_ETHER: + media="Ethernet"; + hal_device_add_capability(d, "net.ethernet"); + break; + case ARPHRD_EETHER: + media="Experimenal Ethernet"; + break; + case ARPHRD_AX25: + media="AX.25 Level 2"; + break; + case ARPHRD_PRONET: + media="PROnet tokenring"; + hal_device_add_capability(d, "net.tokenring"); + break; + case ARPHRD_CHAOS: + media="Chaosnet"; + break; + case ARPHRD_IEEE802: + media="IEEE802"; + break; + case ARPHRD_ARCNET: + media="ARCnet"; + break; + case ARPHRD_APPLETLK: + media="APPLEtalk"; + break; + case ARPHRD_DLCI: + media="Frame Relay DLCI"; + break; + case ARPHRD_ATM: + media="ATM"; + hal_device_add_capability(d, "net.atm"); + break; + case ARPHRD_METRICOM: + media="Metricom STRIP (new IANA id)"; + break; + case ARPHRD_IEEE1394: + media="IEEE1394 IPv4 - RFC 2734"; + break; + default: + media="Unknown"; + break; } hal_device_set_property_string(d, "net.media", media); - hal_device_set_property_int(d, "net.arp_proto_hw_id", - type); + hal_device_set_property_int(d, "net.arpProtoHwId", + media_type); } } + if( addr_store!=NULL && media_type==ARPHRD_ETHER ) + { + unsigned int a5, a4, a3 ,a2, a1, a0; + + hal_device_set_property_string(d, "ethernet.macAddr", addr_store); + + if( sscanf(addr_store, "%x:%x:%x:%x:%x:%x", + &a5, &a4, &a3, &a2, &a1, &a0)==6 ) + { + dbus_uint32_t mac_upper, mac_lower; + + mac_upper = (a5<<8)|a4; + mac_lower = (a3<<24)|(a2<<16)|(a1<<8)|a0; + + hal_device_set_property_int(d, "ethernet.macAddrUpper", + (dbus_int32_t) mac_upper); + hal_device_set_property_int(d, "ethernet.macAddrLower", + (dbus_int32_t) mac_lower); + } + } + + /* check for driver */ if( class_device->driver!=NULL ) { diff --git a/agents/linux26/sysfs/hal_pci.c b/agents/linux26/sysfs/hal_pci.c index 8858688f..99d11055 100644 --- a/agents/linux26/sysfs/hal_pci.c +++ b/agents/linux26/sysfs/hal_pci.c @@ -98,6 +98,7 @@ static dbus_bool_t pci_ids_line_iter_has_more() return pci_ids_iter_pos<pci_ids_len; } + /** Find the names for a PCI device. * * The pointers returned are only valid until the next invocation of this @@ -359,6 +360,286 @@ static char* pci_compute_udi(const char* udi, int append_num) } +/** Set capabilities from PCI class. This is a function from hell, + * maybe some searchable data-structure would be better... + * + * @param udi UDI of HAL device to set caps on + * @param dev_class device class + * @param dev_sub_class device sub class + * @param dev_proto device protocol + */ +static void pci_add_caps_from_class(const char* udi, + int dev_class, + int dev_sub_class, + int dev_proto) +{ + char* cat = "unknown"; + + switch( dev_class ) + { + case 0x01: + cat = "storageController"; + hal_device_add_capability(udi, "storageController"); + switch( dev_sub_class) + { + case 0x00: + hal_device_add_capability(udi, "storageController.scsi"); + break; + case 0x01: + hal_device_add_capability(udi, "storageController.ide"); + break; + case 0x02: + hal_device_add_capability(udi, "storageController.floppy"); + break; + case 0x03: + hal_device_add_capability(udi, "storageController.ipi"); + break; + case 0x04: + hal_device_add_capability(udi, "storageController.raid"); + break; + } + break; + case 0x02: + cat = "net"; + hal_device_add_capability(udi, "net"); + switch( dev_sub_class) + { + case 0x00: + hal_device_add_capability(udi, "net.ethernet"); + break; + case 0x01: + hal_device_add_capability(udi, "net.tokenring"); + break; + case 0x02: + hal_device_add_capability(udi, "net.fddi"); + break; + case 0x03: + hal_device_add_capability(udi, "net.atm"); + break; + case 0x04: + hal_device_add_capability(udi, "net.isdn"); + break; + } + break; + case 0x03: + cat = "video"; + hal_device_add_capability(udi, "video"); + if( dev_sub_class==0x00 && dev_proto==0x00 ) + hal_device_add_capability(udi, "video.vga"); + if( dev_sub_class==0x00 && dev_proto==0x01 ) + hal_device_add_capability(udi, "video.8514"); + else if( dev_sub_class==0x01 ) + hal_device_add_capability(udi, "video.xga"); + else if( dev_sub_class==0x02 ) + hal_device_add_capability(udi, "video.3d"); + break; + case 0x04: + cat = "multimedia"; + hal_device_add_capability(udi, "multimedia"); + switch( dev_sub_class) + { + case 0x00: + hal_device_add_capability(udi, "multimedia.video"); + cat = "multimedia.video"; + break; + case 0x01: + hal_device_add_capability(udi, "multimedia.audio"); + cat = "multimedia.audio"; + break; + case 0x02: + hal_device_add_capability(udi, "multimedia.telephony"); + cat = "multimedia.telephony"; + break; + } + break; + case 0x06: + cat = "bridge"; + hal_device_add_capability(udi, "bridge"); + switch( dev_sub_class) + { + case 0x00: + hal_device_add_capability(udi, "bridge.host"); + break; + case 0x01: + hal_device_add_capability(udi, "bridge.isa"); + break; + case 0x02: + hal_device_add_capability(udi, "bridge.eisa"); + break; + case 0x03: + hal_device_add_capability(udi, "bridge.microChannel"); + break; + case 0x04: + hal_device_add_capability(udi, "bridge.pci"); + break; + case 0x05: + hal_device_add_capability(udi, "bridge.pcmcia"); + break; + case 0x06: + hal_device_add_capability(udi, "bridge.nuBus"); + break; + case 0x07: + cat = "bridge.cardBus"; + hal_device_add_capability(udi, "bridge.cardBus"); + break; + case 0x08: + hal_device_add_capability(udi, "bridge.raceway"); + break; + case 0x09: + hal_device_add_capability(udi, "bridge.semiTransparent"); + break; + case 0x0a: + hal_device_add_capability(udi, "bridge.infiniBand"); + break; + } + break; + case 0x07: + cat = "comm"; + hal_device_add_capability(udi, "comm"); + if( dev_sub_class==0x00 ) + { + cat = "comm.serial"; + hal_device_add_capability(udi, "comm.serial"); + switch( dev_proto) + { + case 0x00: + hal_device_add_capability(udi, "comm.serial.8250"); + break; + case 0x01: + hal_device_add_capability(udi, "comm.serial.16450"); + break; + case 0x02: + hal_device_add_capability(udi, "comm.serial.16550"); + break; + case 0x03: + hal_device_add_capability(udi, "comm.serial.16650"); + break; + case 0x04: + hal_device_add_capability(udi, "comm.serial.16750"); + break; + case 0x05: + hal_device_add_capability(udi, "comm.serial.16850"); + break; + case 0x06: + hal_device_add_capability(udi, "comm.serial.16950"); + break; + } + } + else if( dev_sub_class==0x01 ) + { + cat = "comm.parallel"; + hal_device_add_capability(udi, "comm.parallel"); + switch( dev_proto) + { + case 0x00: + hal_device_add_capability(udi, "comm.parallel.SPP"); + break; + case 0x01: + hal_device_add_capability(udi, "comm.parallel.BiDir"); + break; + case 0x02: + hal_device_add_capability(udi, "comm.parallel.ECP"); + break; + case 0x03: + hal_device_add_capability(udi, "comm.parallel.IEEE1284"); + break; + case 0xfe: + hal_device_add_capability(udi, "comm.parallel.IEEE1284Target"); + break; + } + } + else if( dev_sub_class==0x02 ) + { + cat = "comm.serial"; + hal_device_add_capability(udi, "comm.serial"); + hal_device_add_capability(udi, "comm.serial.multiport"); + } + else if( dev_sub_class==0x03 ) + { + cat = "modem"; + hal_device_add_capability(udi, "modem"); + if( dev_proto>=0x01 && dev_proto<=0x04 ) + hal_device_add_capability(udi, "hayes"); + } + break; + case 0x0c: + cat = "serialController"; + hal_device_add_capability(udi, "serialController"); + switch( dev_sub_class) + { + case 0x00: + cat = "serialController.ieee1394"; + hal_device_add_capability(udi, "serialController.ieee1394"); + if( dev_proto==0x10 ) + hal_device_add_capability(udi, "serialController.ieee1394.ohci"); + break; + case 0x01: + hal_device_add_capability(udi, "serialController.access"); + break; + case 0x02: + hal_device_add_capability(udi, "serialController.ssa"); + break; + case 0x03: + cat = "serialController.usb"; + hal_device_add_capability(udi, "serialController.usb"); + switch( dev_proto ) + { + case 0x00: + hal_device_add_capability(udi, "serialController.usb.uhci"); + break; + case 0x01: + hal_device_add_capability(udi, "serialController.usb.ohci"); + break; + case 0x02: + hal_device_add_capability(udi, "serialController.usb.ehci"); + break; + case 0xfe: + hal_device_add_capability(udi, "serialController.usb.device"); + break; + } + break; + } + break; + case 0x0d: + cat = "wireless"; + hal_device_add_capability(udi, "wireless"); + switch( dev_sub_class) + { + case 0x00: + hal_device_add_capability(udi, "wireless.irda"); + break; + case 0x01: + hal_device_add_capability(udi, "wireless.consumerController"); + break; + case 0x02: + hal_device_add_capability(udi, "wireless.rfController"); + break; + } + break; + case 0x0f: + cat = "satelliteController"; + hal_device_add_capability(udi, "satelliteController"); + switch( dev_sub_class) + { + case 0x00: + hal_device_add_capability(udi, "satelliteController.tv"); + break; + case 0x01: + hal_device_add_capability(udi, "satelliteController.audio"); + break; + case 0x02: + hal_device_add_capability(udi, "satelliteController.video"); + break; + case 0x03: + hal_device_add_capability(udi, "satelliteController.data"); + break; + } + break; + } + + hal_device_set_property_string(udi, "Category", cat); +} + /** Visitor function for PCI device. * * This function parses the attributes present and creates a new HAL @@ -384,6 +665,7 @@ void visit_device_pci(const char* path, struct sysfs_device *device) char* subsys_vendor_name; char* subsys_product_name; const char* driver; + dbus_int32_t cls = 0x00ffffff; char namebuf[512]; /*printf("pci: %s\n", path);*/ @@ -431,11 +713,7 @@ void visit_device_pci(const char* path, struct sysfs_device *device) subsys_vendor_id = parse_hex(cur->value); else if( strcmp(attr_name, "class")==0 ) { - dbus_int32_t cls; cls = parse_hex(cur->value); - hal_device_set_property_int(d, "pci.deviceClass", (cls>>16)&0xff); - hal_device_set_property_int(d, "pci.deviceSubClass",(cls>>8)&0xff); - hal_device_set_property_int(d, "pci.deviceProtocol", cls&0xff); } } @@ -488,6 +766,12 @@ void visit_device_pci(const char* path, struct sysfs_device *device) if( parent_udi!=NULL ) hal_device_set_property_string(d, "Parent", parent_udi); + + hal_device_set_property_int(d, "pci.deviceClass", (cls>>16)&0xff); + hal_device_set_property_int(d, "pci.deviceSubClass",(cls>>8)&0xff); + hal_device_set_property_int(d, "pci.deviceProtocol", cls&0xff); + pci_add_caps_from_class(d, (cls>>16)&0xff, (cls>>8)&0xff, cls&0xff); + /* Compute a proper UDI (unique device id), try to locate a persistent * unplugged device or add it */ diff --git a/agents/linux26/sysfs/hal_usb.c b/agents/linux26/sysfs/hal_usb.c index 68a4d1fd..f4c76c4d 100644 --- a/agents/linux26/sysfs/hal_usb.c +++ b/agents/linux26/sysfs/hal_usb.c @@ -572,6 +572,81 @@ static char* usb_compute_udi(const char* udi, int append_num) return buf; } +/** Set capabilities from interface class. This is a function from hell, + * maybe some searchable data-structure would be better... + * + * @param udi UDI of HAL device to set caps on + * @param if_class Interface class + * @param if_sub_class Interface sub class + * @param if_proto Interface protocol + */ +static void usb_add_caps_from_class(const char* udi, + int if_class, + int if_sub_class, + int if_proto) +{ + char* cat = "unknown"; + + switch( if_class ) + { + case 0x01: + cat = "multimedia.audio"; + hal_device_add_capability(udi, "multimedia.audio"); + break; + case 0x02: + if( if_sub_class==0x06 ) + { + cat = "net"; + hal_device_add_capability(udi, "net"); + hal_device_add_capability(udi, "net.ethernet"); + } + else if( if_sub_class==0x02 && if_proto==0x01 ) + { + cat = "modem"; + hal_device_add_capability(udi, "modem"); + } + break; + case 0x03: + cat = "input"; + hal_device_add_capability(udi, "input"); + if( if_sub_class==0x00 || if_sub_class==0x01 ) + { + if( if_proto==0x01 ) + { + cat = "input.keyboard"; + hal_device_add_capability(udi, "input.keyboard"); + } + else if( if_proto==0x02 ) + { + cat = "input.mouse"; + hal_device_add_capability(udi, "input.mouse"); + } + } + break; + case 0x04: + break; + case 0x05: + break; + case 0x06: + break; + case 0x07: + cat = "printer"; + hal_device_add_capability(udi, "printer"); + break; + case 0x08: + cat = "storage"; + hal_device_add_capability(udi, "storage"); + break; + case 0x09: + cat = "hub"; + hal_device_add_capability(udi, "hub"); + break; + case 0x0a: + break; + } + + hal_device_set_property_string(udi, "Category", cat); +} /** Visitor function for interfaces on a USB device. * @@ -588,6 +663,9 @@ static void visit_device_usb_interface(const char* path, char* pd; const char* driver; char attr_name[SYSFS_NAME_LEN]; + int if_class = -1; + int if_sub_class = -1; + int if_proto = -1; /*printf("usb_interface: path=%s\n", path);*/ @@ -640,19 +718,24 @@ static void visit_device_usb_interface(const char* path, /*printf("attr_name=%s -> '%s'\n", attr_name, cur->value);*/ if( strcmp(attr_name, "bInterfaceClass")==0 ) - hal_device_set_property_int(d, "usbif.bInterfaceClass", - parse_dec(cur->value)); + if_class = parse_dec(cur->value); else if( strcmp(attr_name, "bInterfaceSubClass")==0 ) - hal_device_set_property_int(d, "usbif.bInterfaceSubClass", - parse_dec(cur->value)); + if_sub_class = parse_dec(cur->value); else if( strcmp(attr_name, "bInterfaceProtocol")==0 ) - hal_device_set_property_int(d, "usbif.bInterfaceProtocol", - parse_dec(cur->value)); + if_proto = parse_dec(cur->value); else if( strcmp(attr_name, "bInterfaceNumber")==0 ) hal_device_set_property_int(d, "usbif.number", parse_dec(cur->value)); } + hal_device_set_property_int(d, "usbif.bInterfaceClass", if_class); + hal_device_set_property_int(d, "usbif.bInterfaceSubClass", if_sub_class); + hal_device_set_property_int(d, "usbif.bInterfaceProtocol", if_proto); + + /* We set the caps on the parent device */ + usb_add_caps_from_class(pd, if_class, if_sub_class, if_proto); + + d = rename_and_maybe_add(d, usbif_compute_udi, "usbif"); } diff --git a/agents/linux26/sysfs/main.c b/agents/linux26/sysfs/main.c index 87e2be6b..568d2f92 100644 --- a/agents/linux26/sysfs/main.c +++ b/agents/linux26/sysfs/main.c @@ -1231,6 +1231,22 @@ int main(int argc, char* argv[]) hal_net_init(); hal_input_init(); +/* + { + int i; + int num_devices; + char** devices; + + devices = hal_find_device_by_capability("input", &num_devices); + printf("rc: devices=%x, num_devices=%d\n", devices, num_devices); + for(i=0; i<num_devices; i++) + { + printf("devices[%d] = %s\n", i, devices[i]); + } + return 0; + } +*/ + while(TRUE) { int c; |